home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / sharewar / quake106 / utils / sprgen / sprgen.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  10KB  |  527 lines

  1. //
  2. // spritegen.c: generates a .spr file from a series of .lbm frame files.
  3. // Result is stored in /raid/quake/id1/sprites/<scriptname>.spr.
  4. //
  5.  
  6. #define INCLUDELIBS
  7.  
  8.  
  9. #ifdef NeXT
  10. #include <libc.h>
  11. #endif
  12.  
  13. #include "spritegn.h"
  14.  
  15. #define MAX_BUFFER_SIZE        0x100000
  16. #define MAX_FRAMES            1000
  17.  
  18. dsprite_t        sprite;
  19. byte            *byteimage, *lbmpalette;
  20. int                byteimagewidth, byteimageheight;
  21. byte            *lumpbuffer, *plump;
  22. char            spritedir[1024];
  23. char            spriteoutname[1024];
  24. int                framesmaxs[2];
  25. int                framecount;
  26.  
  27. typedef struct {
  28.     spriteframetype_t    type;        // single frame or group of frames
  29.     void                *pdata;        // either a dspriteframe_t or group info
  30.     float                interval;    // only used for frames in groups
  31.     int                    numgroupframes;    // only used by group headers
  32. } spritepackage_t;
  33.  
  34. spritepackage_t    frames[MAX_FRAMES];
  35.  
  36. void FinishSprite (void);
  37. void Cmd_Spritename (void);
  38.  
  39.  
  40. /*
  41. ============
  42. WriteFrame
  43. ============
  44. */
  45. void WriteFrame (FILE *spriteouthandle, int framenum)
  46. {
  47.     dspriteframe_t    *pframe;
  48.     dspriteframe_t    frametemp;
  49.  
  50.     pframe = (dspriteframe_t *)frames[framenum].pdata;
  51.     frametemp.origin[0] = LittleLong (pframe->origin[0]);
  52.     frametemp.origin[1] = LittleLong (pframe->origin[1]);
  53.     frametemp.width = LittleLong (pframe->width);
  54.     frametemp.height = LittleLong (pframe->height);
  55.  
  56.     SafeWrite (spriteouthandle, &frametemp, sizeof (frametemp));
  57.     SafeWrite (spriteouthandle,
  58.                (byte *)(pframe + 1),
  59.                pframe->height * pframe->width);
  60. }
  61.  
  62.  
  63. /*
  64. ============
  65. WriteSprite
  66. ============
  67. */
  68. void WriteSprite (FILE *spriteouthandle)
  69. {
  70.     int            i, groupframe, curframe;
  71.     dsprite_t    spritetemp;
  72.  
  73.     sprite.boundingradius = sqrt (((framesmaxs[0] >> 1) *
  74.                                    (framesmaxs[0] >> 1)) +
  75.                                   ((framesmaxs[1] >> 1) *
  76.                                    (framesmaxs[1] >> 1)));
  77.  
  78. //
  79. // write out the sprite header
  80. //
  81.     spritetemp.type = LittleLong (sprite.type);
  82.     spritetemp.boundingradius = LittleFloat (sprite.boundingradius);
  83.     spritetemp.width = LittleLong (framesmaxs[0]);
  84.     spritetemp.height = LittleLong (framesmaxs[1]);
  85.     spritetemp.numframes = LittleLong (sprite.numframes);
  86.     spritetemp.beamlength = LittleFloat (sprite.beamlength);
  87.     spritetemp.synctype = LittleFloat (sprite.synctype);
  88.     spritetemp.version = LittleLong (SPRITE_VERSION);
  89.     spritetemp.ident = LittleLong (IDSPRITEHEADER);
  90.  
  91.     SafeWrite (spriteouthandle, &spritetemp, sizeof(spritetemp));
  92.  
  93. //
  94. // write out the frames
  95. //
  96.     curframe = 0;
  97.  
  98.     for (i=0 ; i<sprite.numframes ; i++)
  99.     {
  100.         SafeWrite (spriteouthandle, &frames[curframe].type,
  101.                    sizeof(frames[curframe].type));
  102.  
  103.         if (frames[curframe].type == SPR_SINGLE)
  104.         {
  105.         //
  106.         // single (non-grouped) frame
  107.         //
  108.             WriteFrame (spriteouthandle, curframe);
  109.             curframe++;
  110.         }
  111.         else
  112.         {
  113.             int                    j, numframes;
  114.             dspritegroup_t        dsgroup;
  115.             float                totinterval;
  116.  
  117.             groupframe = curframe;
  118.             curframe++;
  119.             numframes = frames[groupframe].numgroupframes;
  120.  
  121.         //
  122.         // set and write the group header
  123.         //
  124.             dsgroup.numframes = LittleLong (numframes);
  125.  
  126.             SafeWrite (spriteouthandle, &dsgroup, sizeof(dsgroup));
  127.  
  128.         //
  129.         // write the interval array
  130.         //
  131.             totinterval = 0.0;
  132.  
  133.             for (j=0 ; j<numframes ; j++)
  134.             {
  135.                 dspriteinterval_t    temp;
  136.  
  137.                 totinterval += frames[groupframe+1+j].interval;
  138.                 temp.interval = LittleFloat (totinterval);
  139.  
  140.                 SafeWrite (spriteouthandle, &temp, sizeof(temp));
  141.             }
  142.  
  143.             for (j=0 ; j<numframes ; j++)
  144.             {
  145.                 WriteFrame (spriteouthandle, curframe);
  146.                 curframe++;
  147.             }
  148.         }
  149.     }
  150. }
  151.  
  152.  
  153. /*
  154. ============
  155. ExecCommand
  156. ============
  157. */
  158. int    cmdsrun;
  159.  
  160. void ExecCommand (char *cmd, ...)
  161. {
  162.     int        ret;
  163.     char    cmdline[1024];
  164.     va_list    argptr;
  165.     
  166.     cmdsrun++;
  167.     
  168.     va_start (argptr, cmd);
  169.     vsprintf (cmdline,cmd,argptr);
  170.     va_end (argptr);
  171.     
  172. //    printf ("=============================================================\n");
  173. //    printf ("spritegen: %s\n",cmdline);
  174.     fflush (stdout);
  175.     ret = system (cmdline);
  176. //    printf ("=============================================================\n");
  177.     
  178.     if (ret)
  179.         Error ("spritegen: exiting due to error");
  180. }
  181.  
  182. /*
  183. ==============
  184. LoadScreen
  185. ==============
  186. */
  187. void LoadScreen (char *name)
  188. {
  189.     printf ("grabbing from %s...\n",name);
  190.     LoadLBM (name, &byteimage, &lbmpalette);
  191.  
  192.     byteimagewidth = bmhd.w;
  193.     byteimageheight = bmhd.h;
  194. }
  195.  
  196.  
  197. /*
  198. ===============
  199. Cmd_Type
  200. ===============
  201. */
  202. void Cmd_Type (void)
  203. {
  204.     GetToken (false);
  205.     if (!strcmp (token, "vp_parallel_upright"))
  206.         sprite.type = SPR_VP_PARALLEL_UPRIGHT;
  207.     else if (!strcmp (token, "facing_upright"))
  208.         sprite.type = SPR_FACING_UPRIGHT;
  209.     else if (!strcmp (token, "vp_parallel"))
  210.         sprite.type = SPR_VP_PARALLEL;
  211.     else if (!strcmp (token, "oriented"))
  212.         sprite.type = SPR_ORIENTED;
  213.     else if (!strcmp (token, "vp_parallel_oriented"))
  214.         sprite.type = SPR_VP_PARALLEL_ORIENTED;
  215.     else
  216.         Error ("Bad sprite type\n");
  217. }
  218.  
  219.  
  220. /*
  221. ===============
  222. Cmd_Beamlength
  223. ===============
  224. */
  225. void Cmd_Beamlength ()
  226. {
  227.     GetToken (false);
  228.     sprite.beamlength = atof (token);
  229. }
  230.  
  231.  
  232. /*
  233. ===============
  234. Cmd_Load
  235. ===============
  236. */
  237. void Cmd_Load (void)
  238. {
  239.     GetToken (false);
  240.     LoadScreen (ExpandPathAndArchive(token));
  241. }
  242.  
  243.  
  244. /*
  245. ===============
  246. Cmd_Frame
  247. ===============
  248. */
  249. void Cmd_Frame ()
  250. {
  251.     int             x,y,xl,yl,xh,yh,w,h;
  252.     byte            *screen_p, *source;
  253.     int             linedelta;
  254.     dspriteframe_t    *pframe;
  255.     int                pix;
  256.     
  257.     GetToken (false);
  258.     xl = atoi (token);
  259.     GetToken (false);
  260.     yl = atoi (token);
  261.     GetToken (false);
  262.     w = atoi (token);
  263.     GetToken (false);
  264.     h = atoi (token);
  265.  
  266.     if ((xl & 0x07) || (yl & 0x07) || (w & 0x07) || (h & 0x07))
  267.         Error ("Sprite dimensions not multiples of 8\n");
  268.  
  269.     if ((w > 255) || (h > 255))
  270.         Error ("Sprite has a dimension longer than 255");
  271.  
  272.     xh = xl+w;
  273.     yh = yl+h;
  274.  
  275.     pframe = (dspriteframe_t *)plump;
  276.     frames[framecount].pdata = pframe;
  277.     frames[framecount].type = SPR_SINGLE;
  278.  
  279.     if (TokenAvailable ())
  280.     {
  281.         GetToken (false);
  282.         frames[framecount].interval = atof (token);
  283.         if (frames[framecount].interval <= 0.0)
  284.             Error ("Non-positive interval");
  285.     }
  286.     else
  287.     {
  288.         frames[framecount].interval = 0.1;
  289.     }
  290.     
  291.     if (TokenAvailable ())
  292.     {
  293.         GetToken (false);
  294.         pframe->origin[0] = -atoi (token);
  295.         GetToken (false);
  296.         pframe->origin[1] = atoi (token);
  297.     }
  298.     else
  299.     {
  300.         pframe->origin[0] = -(w >> 1);
  301.         pframe->origin[1] = h >> 1;
  302.     }
  303.  
  304.     pframe->width = w;
  305.     pframe->height = h;
  306.  
  307.     if (w > framesmaxs[0])
  308.         framesmaxs[0] = w;
  309.     
  310.     if (h > framesmaxs[1])
  311.         framesmaxs[1] = h;
  312.     
  313.     plump = (byte *)(pframe + 1);
  314.  
  315.     screen_p = byteimage + yl*byteimagewidth + xl;
  316.     linedelta = byteimagewidth - w;
  317.  
  318.     source = plump;
  319.  
  320.     for (y=yl ; y<yh ; y++)
  321.     {
  322.         for (x=xl ; x<xh ; x++)
  323.         {
  324.             pix = *screen_p;
  325.             *screen_p++ = 0;
  326. //            if (pix == 255)
  327. //                pix = 0;
  328.             *plump++ = pix;
  329.         }
  330.         screen_p += linedelta;
  331.     }
  332.  
  333.     framecount++;
  334.     if (framecount >= MAX_FRAMES)
  335.         Error ("Too many frames; increase MAX_FRAMES\n");
  336. }
  337.  
  338.  
  339. /*
  340. ===============
  341. Cmd_GroupStart    
  342. ===============
  343. */
  344. void Cmd_GroupStart (void)
  345. {
  346.     int            groupframe;
  347.  
  348.     groupframe = framecount++;
  349.  
  350.     frames[groupframe].type = SPR_GROUP;
  351.     frames[groupframe].numgroupframes = 0;
  352.  
  353.     while (1)
  354.     {
  355.         GetToken (true);
  356.         if (endofscript)
  357.             Error ("End of file during group");
  358.  
  359.         if (!strcmp (token, "$frame"))
  360.         {
  361.             Cmd_Frame ();
  362.             frames[groupframe].numgroupframes++;
  363.         }
  364.         else if (!strcmp (token, "$load"))
  365.         {
  366.             Cmd_Load ();
  367.         }
  368.         else if (!strcmp (token, "$groupend"))
  369.         {
  370.             break;
  371.         }
  372.         else
  373.         {
  374.             Error ("$frame, $load, or $groupend expected\n");
  375.         }
  376.  
  377.     }
  378.  
  379.     if (frames[groupframe].numgroupframes == 0)
  380.         Error ("Empty group\n");
  381. }
  382.  
  383.  
  384. /*
  385. ===============
  386. ParseScript    
  387. ===============
  388. */
  389. void ParseScript (void)
  390. {
  391.     while (1)
  392.     {
  393.         GetToken (true);
  394.         if (endofscript)
  395.             break;
  396.     
  397.         if (!strcmp (token, "$load"))
  398.         {
  399.             Cmd_Load ();
  400.         }
  401.         if (!strcmp (token, "$spritename"))
  402.         {
  403.             Cmd_Spritename ();
  404.         }
  405.         else if (!strcmp (token, "$type"))
  406.         {
  407.             Cmd_Type ();
  408.         }
  409.         else if (!strcmp (token, "$beamlength"))
  410.         {
  411.             Cmd_Beamlength ();
  412.         }
  413.         else if (!strcmp (token, "$sync"))
  414.         {
  415.             sprite.synctype = ST_SYNC;
  416.         }
  417.         else if (!strcmp (token, "$frame"))
  418.         {
  419.             Cmd_Frame ();
  420.             sprite.numframes++;
  421.         }        
  422.         else if (!strcmp (token, "$load"))
  423.         {
  424.             Cmd_Load ();
  425.         }
  426.         else if (!strcmp (token, "$groupstart"))
  427.         {
  428.             Cmd_GroupStart ();
  429.             sprite.numframes++;
  430.         }
  431.     }
  432. }
  433.  
  434. /*
  435. ==============
  436. Cmd_Spritename
  437. ==============
  438. */
  439. void Cmd_Spritename (void)
  440. {
  441.     if (sprite.numframes)
  442.         FinishSprite ();
  443.  
  444.     GetToken (false);
  445.     sprintf (spriteoutname, "%s%s.spr", spritedir, token);
  446.     memset (&sprite, 0, sizeof(sprite));
  447.     framecount = 0;
  448.  
  449.     framesmaxs[0] = -9999999;
  450.     framesmaxs[1] = -9999999;
  451.  
  452.     lumpbuffer = malloc (MAX_BUFFER_SIZE * 2);    // *2 for padding
  453.     if (!lumpbuffer)
  454.         Error ("Couldn't get buffer memory");
  455.  
  456.     plump = lumpbuffer;
  457.     sprite.synctype = ST_RAND;    // default
  458. }
  459.  
  460. /*
  461. ==============
  462. FinishSprite    
  463. ==============
  464. */
  465. void FinishSprite (void)
  466. {
  467.     FILE    *spriteouthandle;
  468.  
  469.     if (sprite.numframes == 0)
  470.         Error ("no frames\n");
  471.  
  472.     if (!strlen(spriteoutname))
  473.         Error ("Didn't name sprite file");
  474.         
  475.     if ((plump - lumpbuffer) > MAX_BUFFER_SIZE)
  476.         Error ("Sprite package too big; increase MAX_BUFFER_SIZE");
  477.  
  478.     spriteouthandle = SafeOpenWrite (spriteoutname);
  479.     printf ("saving in %s\n", spriteoutname);
  480.     WriteSprite (spriteouthandle);
  481.     fclose (spriteouthandle);
  482.     
  483.     printf ("spritegen: successful\n");
  484.     printf ("%d frame(s)\n", sprite.numframes);
  485.     printf ("%d ungrouped frame(s), including group headers\n", framecount);
  486.     
  487.     spriteoutname[0] = 0;        // clear for a new sprite
  488. }
  489.  
  490. /*
  491. ==============
  492. main
  493.     
  494. ==============
  495. */
  496. int main (int argc, char **argv)
  497. {
  498.     int        i;
  499.  
  500.     if (argc != 2 && argc != 4)
  501.         Error ("usage: spritegen [-archive directory] file.qc");
  502.         
  503.     if (!strcmp(argv[1], "-archive"))
  504.     {
  505.         archive = true;
  506.         strcpy (archivedir, argv[2]);
  507.         printf ("Archiving source to: %s\n", archivedir);
  508.         i = 3;
  509.     }
  510.     else
  511.         i = 1;
  512.  
  513.     SetQdirFromPath (argv[i]);
  514.     ExtractFilePath (argv[i], spritedir);    // chop the filename
  515.  
  516. //
  517. // load the script
  518. //
  519.     LoadScriptFile (argv[i]);
  520.     
  521.     ParseScript ();
  522.     FinishSprite ();
  523.  
  524.     return 0;
  525. }
  526.  
  527.