home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol1 / gfx / createsprite < prev    next >
Text File  |  1990-01-26  |  12KB  |  323 lines

  1. (c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.                       Creating Sprites in C
  8.                     from the Intuition Pointer
  9.  
  10.                           by Adam Levin 
  11.  
  12.  
  13. The Amiga's sprite hardware makes it easy to display and move sprites. 
  14. The hardest part of using Amiga sprites is creating the sprite image
  15. itself using C statements.  Getting the sprite to look exactly as you want 
  16. by manipulating hexadecimal numbers to alter pixels is tedious and error-prone.
  17. What is needed is a sprite editor that will create the C code automatically.
  18. You can use the Preferences pointer-editor and the p2sprite program listed
  19. below to do the job.
  20.  
  21.  
  22. A Sprite Editor
  23. ---------------
  24.  
  25. The Amiga comes with its own sprite editor built-in though you may not be 
  26. aware of it.  The small red arrow used as the Intuition pointer is a sprite.
  27. So the Preferences pointer-editor is actually a sprite editor.  All that we 
  28. need is a way to convert the sprite shape and color data into C statements.
  29.  
  30. The p2sprite ("pointer to sprite") program will read the current Preferences 
  31. pointer image from your Amiga's memory and automatically create the data 
  32. arrays needed to use an identical-looking sprite in a 'C' program.  If you 
  33. have a Preferences information file, which Preferences saves as
  34. "devs:system-configuration", p2sprite can extract the pointer data from the 
  35. file instead.
  36.  
  37. To create the C code for a sprite follow these steps.  First, in Preferences,
  38. edit the pointer and its colors to your liking.  The transparent background 
  39. color of the pointer will also be transparent for your C sprite.  When
  40. you're done select "OK" to exit.
  41.  
  42. Next select either "Save" or "Use" from the main Preferences screen.  If you 
  43. select "Save", all the Preferences information will be written out to the 
  44. file "devs:system-configuration".  You may want to save a copy of your
  45. original system-configuration file before doing this so that you can easily
  46. restore it later.  Use "copy devs:system-configuration to devs:temp-config"
  47. to save it, and "copy devs:temp-config to devs:system-configuration" to 
  48. restore it later.
  49.  
  50. To convert the sprite that you see on the screen to C statements just type
  51. "p2sprite".  P2sprite will get the pointer data from the active Preferences
  52. setting and display it on the standard output device as C code.  To save it 
  53. to a file type "p2sprite >outfile".
  54.  
  55. To have p2sprite get the pointer data from the Preferences information file, 
  56. type "p2sprite filename" where "filename" is the name of the file, in this
  57. case, "devs:system-configuration".  The equivalent C code will be displayed
  58. on the standard output device.  To save the pointer as a file of C statements,
  59. use "p2sprite >outfile filename".
  60.  
  61.  
  62. Sprite Data in C
  63. ----------------
  64.  
  65. Using the sprite data in your C  program is simple.  First, insert the sprite
  66. file into your source code with your editor.  P2sprite creates two arrays of 
  67. USHORT data, one for the sprite colors and one for the sprite shape.  Next,
  68. add code to your program to make sure the sprite data appears in chip memory.
  69. You can use the TypeOfMem() routine to do this.  If the sprite data is not 
  70. in chip RAM, then use AllocMem() to get some chip RAM and use CopyMem() to
  71. copy the sprite data into it.  Second, initialize a SimpleSprite structure 
  72. with the GetSprite() routine.  Finally, call ChangeSprite() with the sprite 
  73. array as the spriteImage.  Here is a code fragment:
  74.  
  75. =========  LAUREN, CODE STARTS HERE!=================
  76.  
  77.       USHORT sprite[] =...  /* def'n of sprite[] from p2sprite.  */
  78.  
  79.       struct ViewPort *viewport;
  80.       struct SimpleSprite *simplesprite;
  81.  
  82.           /*  Get address of viewport from screen and 
  83.               initialize simplesprite with GetSprite().  */
  84.  
  85.       ChangeSprite(viewport, simplesprite, sprite);
  86.  
  87. ========== LAUREN, CODE ENDS HERE! ===================
  88.  
  89. Data created by p2sprite can be used for both hardware and virtual sprites.
  90. Note however that the set-up described here pertains to hardware sprites.  
  91. Also note that sprites edited with the pointer-editor are limited to a 
  92. height of 16 pixels.  There is no such limit in the Amiga hardware; an 
  93. Amiga sprite can be abitrarily tall.
  94.  
  95.  
  96. Making a Tall Sprite
  97. --------------------
  98.  
  99. To make a sprite taller than 16 pixels, create the sprite in sections with
  100. the pointer editor and then join together the resulting C data to define the 
  101. full sprite.  To join two or more sprites together, strip off the first two 
  102. words from each sprite definition except for the first sprite.  The first two 
  103. words in a sprite definition are position control data. 
  104.  
  105. Next strip off the last two words from each sprite definition except for the 
  106. last sprite.  The last two words in a sprite definition are "reserved data."
  107. For example, the two small sprite definitions shown below could be joined
  108. as follows: 
  109.  
  110. ============ LAUREN, EXAMPLE STARTS HERE! ==================
  111.  
  112.    USHORT spriteA[] =         and          USHORT spriteB[] =
  113.    {                                       {
  114.      0x0000, 0x0000,                         0x0000, 0x0000,
  115.      0x0000, 0xfc00,                         0xa0c0, 0x0c0a,
  116.      0x7c00, 0xfe00,                         0xbb00, 0xbb00,
  117.      0xaa00, 0xaa00,                         0x0000, 0x0000
  118.      0x0000, 0x0000                        };
  119.     };
  120.  
  121.  
  122.  
  123. could be joined like this -
  124.  
  125.    USHORT spriteAB[] =
  126.    {                          
  127.      0x0000, 0x0000,      /* Make sure commas appear between each word  */
  128.      0x0000, 0xfc00,      /* but not before the first or after the last */ 
  129.      0x7c00, 0xfe00,
  130.      0xaa00, 0xaa00,
  131.      0xa0c0, 0x0c0a,
  132.      0xbb00, 0xbb00,
  133.      0x0000, 0x0000
  134.    };
  135.  
  136. ================= LAUREN, EXAMPLE ENDS HERE! =================
  137.  
  138. In addition to the image definition for the pointer, your application must
  139. handle the colors as well.  Here is a routine to set the colors of a sprite, 
  140. given a color array such as the one returned by p2sprite:
  141.  
  142. ========== LAUREN, CODE STARTS HERE =====================
  143.  
  144.    /*  setSpriteColors
  145.        Sets a sprite's color-registers in the ViewPort's ColorTable.
  146.    */
  147.  
  148.    BOOL setSpriteColors(viewPort, spriteNum, colors)
  149.    struct ViewPort *viewPort;
  150.    int spriteNum;    /*  0 <= spriteNum <= 7  */
  151.  
  152.    USHORT *colors;   /*  As returned by p2sprite.  */
  153.  
  154.    {
  155.    int index;
  156.    ULONG colorRegister;
  157.    /*  Each pair of sprites share a set of four consecutive color registers
  158.        (e.g. Sprites 0 & 1 share 16, 17, 18 and 19).  The color in the first
  159.        of these registers will always be transparent for sprites.
  160.        The array "spriteSecondColor[]" holds the value of the second
  161.        register for each set of four.
  162.    */
  163.    static ULONG spriteSecondColor[] = { 17L, 21L, 25L, 29L };
  164.  
  165.      if (spriteNum >= 0 && spriteNum <= 7)
  166.      {
  167.         colorRegister = spriteSecondColor[spriteNum >> 1];
  168.  
  169.         for (index=0; index<3; index++)
  170.             SetRGB4(viewPort, colorRegister + (long)index,
  171.                 (long)(0x0f00 & colors[index]) >> 8,
  172.                 (long)(0x00f0 & colors[index]) >> 4,
  173.                 (long)(0x000f & colors[index]));  
  174.  
  175.         return(TRUE);
  176.      }
  177.      else
  178.         return(FALSE);
  179.    }
  180.  
  181. ============== LAUREN, CODE ENDS HERE!===========================
  182.  
  183. Using p2sprite and the Preferences pointer-editor, you will be able to create 
  184. sprites more quickly for your applications.  The method described above is 
  185. designed to work with V1.3 of the Amiga operating system.  Future revisions 
  186. of the OS may change the layout of Preferences information, so use caution
  187. with versions of the operating system beyond V1.3.
  188.  
  189.  
  190.  
  191. ============== LAUREN, MAIN LISTING STARTS HERE===========================
  192.  
  193. /*  p2sprite
  194.     Creates a 'C' code sprite definition for the current Intuition pointer.
  195.     If a filename is given, extracts the pointer information
  196.     from that (system-configuration format) file.
  197.     Adam Levin   Commodore-Amiga
  198.     Manx: Compile with "cc p2sprite.c +L"; Link with "ln p2sprite.o -lc32"
  199. */
  200.  
  201. #include <exec/types.h>
  202. #include <libraries/dos.h>
  203. #include <intuition/preferences.h>
  204. #include <stdio.h>
  205.  
  206. #define INTUIT_LIB "intuition.library"
  207. struct IntuitionBase *IntuitionBase;
  208.  
  209.  
  210. /*   A buffer is needed to receive a partial copy of the Preferences
  211.      information.  A structure is defined which contains the same definitions
  212.      as the Preferences structure, up to the last needed item: color19.
  213. */
  214. struct Bit_O_Prefs
  215. {
  216.     BYTE FontHeight;
  217.     UBYTE PrinterPort;
  218.     USHORT BaudRate;
  219.     struct timeval KeyRptSpeed;
  220.     struct timeval KeyRptDelay;
  221.     struct timeval DoubleClick;
  222.     USHORT PointerMatrix[POINTERSIZE];
  223.     BYTE XOffset;
  224.     BYTE YOffset;
  225.     USHORT color17;
  226.     USHORT color18;
  227.     USHORT color19;
  228. } bit_o_prefs;
  229.  
  230.  
  231. main(argc, argv)
  232. int argc;
  233. char *argv[];
  234. {
  235. int p;
  236. long actual;
  237. struct FileHandle *fileHandle;
  238. void printf(), puts(), fprintf(), fputs(), GetPrefs();
  239.  
  240.     /*  Run only from CLI.  */
  241.     if (argc == 0)
  242.         return(RETURN_WARN);
  243.     else
  244.     {
  245.         /*  Usage  */
  246.         if (argc > 2 || (argc == 2 && argv[1][0] == '?'))
  247.         {
  248.             fprintf(stderr, "\nUsage: %s [filename]\n", argv[0]);
  249.             fputs("Creates a 'C' code sprite definition for the\n", stderr);
  250.             fputs("current Intuition pointer.  If a filename is\n", stderr);
  251.             fputs("given, extracts the pointer information from\n", stderr);
  252.             fputs("that (system-configuration format) file.\n\n", stderr);
  253.             exit(RETURN_WARN);
  254.         }
  255.  
  256.         if (argc == 2)
  257.         /*  A filename was given; extract the information from the file. */
  258.         {
  259.             if ((fileHandle = Open(argv[1], MODE_OLDFILE)) == NULL)
  260.             {
  261.                 fprintf(stderr, "%s: Unable to read from \"%s\".\n",
  262.                     argv[0], argv[1]);
  263.                 exit(RETURN_ERROR);
  264.             }
  265.  
  266.             /*  Read as much of the (system-configuration format) file
  267.                 as will fit in the Bit_O_Prefs structure.
  268.             */
  269.             actual = Read(fileHandle, &bit_o_prefs,
  270.                 sizeof(struct Bit_O_Prefs));
  271.             Close(fileHandle);
  272.  
  273.             /*  Read error.  */
  274.             if (actual != sizeof(struct Bit_O_Prefs))
  275.             {
  276.                     fprintf(stderr, "%s: Error reading from \"%s\".\n",
  277.                         argv[0], argv[1]);
  278.                     fputs("It must be of the format created by\n", stderr);
  279.                     fputs("\"Save\"-ing from Preferences.\n", stderr);
  280.                 exit(RETURN_FAIL);
  281.             }
  282.         }
  283.         else
  284.         /*  Get pointer information from active Preferences.  */
  285.         {
  286.             /* Open Intuition */
  287.             IntuitionBase = (struct IntuitionBase *)
  288.                 OpenLibrary(INTUIT_LIB, LIBRARY_VERSION);
  289.             if (IntuitionBase == NULL)
  290.             {
  291.                 fprintf(stderr, "%s: Unable to open \"%s\".\n",
  292.                     argv[0], INTUIT_LIB);
  293.                 exit(RETURN_FAIL);
  294.             }
  295.  
  296.             /*  Copy as much of the Preferences structure as will
  297.                 fit in the Bit_O_Prefs structure.
  298.             */
  299.             GetPrefs(&bit_o_prefs, sizeof(struct Bit_O_Prefs));
  300.  
  301.             CloseLibrary(IntuitionBase);
  302.         }
  303.  
  304.         /*  Print the information to stdout.  */
  305.         puts("/*  Sprite color data:  */\n");
  306.         puts("USHORT colors[] =\n{\n");
  307.         printf("    0x%04x,\n", bit_o_prefs.color17);
  308.         printf("    0x%04x,\n", bit_o_prefs.color18);
  309.         printf("    0x%04x\n};\n\n", bit_o_prefs.color19);
  310.  
  311.         puts("/*  Sprite shape data:  */\n");
  312.         puts("USHORT sprite[] =\n{\n");
  313.         for (p=0; p<POINTERSIZE; p+=2)
  314.             printf("     0x%04x, 0x%04x%s",
  315.                 bit_o_prefs.PointerMatrix[p], bit_o_prefs.PointerMatrix[p+1],
  316.                     (p < POINTERSIZE-2) ? ",\n" : "\n};\n");
  317.     }
  318.     return(RETURN_OK);
  319. }
  320.  
  321.  
  322.  
  323.