123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- //
- // spritegen.c: generates a .spr file from a series of .lbm frame files.
- // Result is stored in /raid/quake/id1/sprites/<scriptname>.spr.
- //
- #define INCLUDELIBS
- #ifdef NeXT
- #include <libc.h>
- #endif
- #include "spritegn.h"
- #define MAX_BUFFER_SIZE 0x100000
- #define MAX_FRAMES 1000
- dsprite_t sprite;
- byte *byteimage, *lbmpalette;
- int byteimagewidth, byteimageheight;
- byte *lumpbuffer, *plump;
- char spritedir[1024];
- char spriteoutname[1024];
- int framesmaxs[2];
- int framecount;
- typedef struct {
- spriteframetype_t type; // single frame or group of frames
- void *pdata; // either a dspriteframe_t or group info
- float interval; // only used for frames in groups
- int numgroupframes; // only used by group headers
- } spritepackage_t;
- spritepackage_t frames[MAX_FRAMES];
- void FinishSprite (void);
- void Cmd_Spritename (void);
- /*
- ============
- WriteFrame
- ============
- */
- void WriteFrame (FILE *spriteouthandle, int framenum)
- {
- dspriteframe_t *pframe;
- dspriteframe_t frametemp;
- pframe = (dspriteframe_t *)frames[framenum].pdata;
- frametemp.origin[0] = LittleLong (pframe->origin[0]);
- frametemp.origin[1] = LittleLong (pframe->origin[1]);
- frametemp.width = LittleLong (pframe->width);
- frametemp.height = LittleLong (pframe->height);
- SafeWrite (spriteouthandle, &frametemp, sizeof (frametemp));
- SafeWrite (spriteouthandle,
- (byte *)(pframe + 1),
- pframe->height * pframe->width);
- }
- /*
- ============
- WriteSprite
- ============
- */
- void WriteSprite (FILE *spriteouthandle)
- {
- int i, groupframe, curframe;
- dsprite_t spritetemp;
- sprite.boundingradius = sqrt (((framesmaxs[0] >> 1) *
- (framesmaxs[0] >> 1)) +
- ((framesmaxs[1] >> 1) *
- (framesmaxs[1] >> 1)));
- //
- // write out the sprite header
- //
- spritetemp.type = LittleLong (sprite.type);
- spritetemp.boundingradius = LittleFloat (sprite.boundingradius);
- spritetemp.width = LittleLong (framesmaxs[0]);
- spritetemp.height = LittleLong (framesmaxs[1]);
- spritetemp.numframes = LittleLong (sprite.numframes);
- spritetemp.beamlength = LittleFloat (sprite.beamlength);
- spritetemp.synctype = LittleFloat (sprite.synctype);
- spritetemp.version = LittleLong (SPRITE_VERSION);
- spritetemp.ident = LittleLong (IDSPRITEHEADER);
- SafeWrite (spriteouthandle, &spritetemp, sizeof(spritetemp));
- //
- // write out the frames
- //
- curframe = 0;
- for (i=0 ; i<sprite.numframes ; i++)
- {
- SafeWrite (spriteouthandle, &frames[curframe].type,
- sizeof(frames[curframe].type));
- if (frames[curframe].type == SPR_SINGLE)
- {
- //
- // single (non-grouped) frame
- //
- WriteFrame (spriteouthandle, curframe);
- curframe++;
- }
- else
- {
- int j, numframes;
- dspritegroup_t dsgroup;
- float totinterval;
- groupframe = curframe;
- curframe++;
- numframes = frames[groupframe].numgroupframes;
- //
- // set and write the group header
- //
- dsgroup.numframes = LittleLong (numframes);
- SafeWrite (spriteouthandle, &dsgroup, sizeof(dsgroup));
- //
- // write the interval array
- //
- totinterval = 0.0;
- for (j=0 ; j<numframes ; j++)
- {
- dspriteinterval_t temp;
- totinterval += frames[groupframe+1+j].interval;
- temp.interval = LittleFloat (totinterval);
- SafeWrite (spriteouthandle, &temp, sizeof(temp));
- }
- for (j=0 ; j<numframes ; j++)
- {
- WriteFrame (spriteouthandle, curframe);
- curframe++;
- }
- }
- }
- }
- /*
- ============
- ExecCommand
- ============
- */
- int cmdsrun;
- void ExecCommand (char *cmd, ...)
- {
- int ret;
- char cmdline[1024];
- va_list argptr;
-
- cmdsrun++;
-
- va_start (argptr, cmd);
- vsprintf (cmdline,cmd,argptr);
- va_end (argptr);
-
- // printf ("=============================================================\n");
- // printf ("spritegen: %s\n",cmdline);
- fflush (stdout);
- ret = system (cmdline);
- // printf ("=============================================================\n");
-
- if (ret)
- Error ("spritegen: exiting due to error");
- }
- /*
- ==============
- LoadScreen
- ==============
- */
- void LoadScreen (char *name)
- {
- printf ("grabbing from %s...\n",name);
- LoadLBM (name, &byteimage, &lbmpalette);
- byteimagewidth = bmhd.w;
- byteimageheight = bmhd.h;
- }
- /*
- ===============
- Cmd_Type
- ===============
- */
- void Cmd_Type (void)
- {
- GetToken (false);
- if (!strcmp (token, "vp_parallel_upright"))
- sprite.type = SPR_VP_PARALLEL_UPRIGHT;
- else if (!strcmp (token, "facing_upright"))
- sprite.type = SPR_FACING_UPRIGHT;
- else if (!strcmp (token, "vp_parallel"))
- sprite.type = SPR_VP_PARALLEL;
- else if (!strcmp (token, "oriented"))
- sprite.type = SPR_ORIENTED;
- else if (!strcmp (token, "vp_parallel_oriented"))
- sprite.type = SPR_VP_PARALLEL_ORIENTED;
- else
- Error ("Bad sprite type\n");
- }
- /*
- ===============
- Cmd_Beamlength
- ===============
- */
- void Cmd_Beamlength ()
- {
- GetToken (false);
- sprite.beamlength = atof (token);
- }
- /*
- ===============
- Cmd_Load
- ===============
- */
- void Cmd_Load (void)
- {
- GetToken (false);
- LoadScreen (ExpandPathAndArchive(token));
- }
- /*
- ===============
- Cmd_Frame
- ===============
- */
- void Cmd_Frame ()
- {
- int x,y,xl,yl,xh,yh,w,h;
- byte *screen_p, *source;
- int linedelta;
- dspriteframe_t *pframe;
- int pix;
-
- GetToken (false);
- xl = atoi (token);
- GetToken (false);
- yl = atoi (token);
- GetToken (false);
- w = atoi (token);
- GetToken (false);
- h = atoi (token);
- if ((xl & 0x07) || (yl & 0x07) || (w & 0x07) || (h & 0x07))
- Error ("Sprite dimensions not multiples of 8\n");
- if ((w > 255) || (h > 255))
- Error ("Sprite has a dimension longer than 255");
- xh = xl+w;
- yh = yl+h;
- pframe = (dspriteframe_t *)plump;
- frames[framecount].pdata = pframe;
- frames[framecount].type = SPR_SINGLE;
- if (TokenAvailable ())
- {
- GetToken (false);
- frames[framecount].interval = atof (token);
- if (frames[framecount].interval <= 0.0)
- Error ("Non-positive interval");
- }
- else
- {
- frames[framecount].interval = 0.1;
- }
-
- if (TokenAvailable ())
- {
- GetToken (false);
- pframe->origin[0] = -atoi (token);
- GetToken (false);
- pframe->origin[1] = atoi (token);
- }
- else
- {
- pframe->origin[0] = -(w >> 1);
- pframe->origin[1] = h >> 1;
- }
- pframe->width = w;
- pframe->height = h;
- if (w > framesmaxs[0])
- framesmaxs[0] = w;
-
- if (h > framesmaxs[1])
- framesmaxs[1] = h;
-
- plump = (byte *)(pframe + 1);
- screen_p = byteimage + yl*byteimagewidth + xl;
- linedelta = byteimagewidth - w;
- source = plump;
- for (y=yl ; y<yh ; y++)
- {
- for (x=xl ; x<xh ; x++)
- {
- pix = *screen_p;
- *screen_p++ = 0;
- // if (pix == 255)
- // pix = 0;
- *plump++ = pix;
- }
- screen_p += linedelta;
- }
- framecount++;
- if (framecount >= MAX_FRAMES)
- Error ("Too many frames; increase MAX_FRAMES\n");
- }
- /*
- ===============
- Cmd_GroupStart
- ===============
- */
- void Cmd_GroupStart (void)
- {
- int groupframe;
- groupframe = framecount++;
- frames[groupframe].type = SPR_GROUP;
- frames[groupframe].numgroupframes = 0;
- while (1)
- {
- GetToken (true);
- if (endofscript)
- Error ("End of file during group");
- if (!strcmp (token, "$frame"))
- {
- Cmd_Frame ();
- frames[groupframe].numgroupframes++;
- }
- else if (!strcmp (token, "$load"))
- {
- Cmd_Load ();
- }
- else if (!strcmp (token, "$groupend"))
- {
- break;
- }
- else
- {
- Error ("$frame, $load, or $groupend expected\n");
- }
- }
- if (frames[groupframe].numgroupframes == 0)
- Error ("Empty group\n");
- }
- /*
- ===============
- ParseScript
- ===============
- */
- void ParseScript (void)
- {
- while (1)
- {
- GetToken (true);
- if (endofscript)
- break;
-
- if (!strcmp (token, "$load"))
- {
- Cmd_Load ();
- }
- if (!strcmp (token, "$spritename"))
- {
- Cmd_Spritename ();
- }
- else if (!strcmp (token, "$type"))
- {
- Cmd_Type ();
- }
- else if (!strcmp (token, "$beamlength"))
- {
- Cmd_Beamlength ();
- }
- else if (!strcmp (token, "$sync"))
- {
- sprite.synctype = ST_SYNC;
- }
- else if (!strcmp (token, "$frame"))
- {
- Cmd_Frame ();
- sprite.numframes++;
- }
- else if (!strcmp (token, "$load"))
- {
- Cmd_Load ();
- }
- else if (!strcmp (token, "$groupstart"))
- {
- Cmd_GroupStart ();
- sprite.numframes++;
- }
- }
- }
- /*
- ==============
- Cmd_Spritename
- ==============
- */
- void Cmd_Spritename (void)
- {
- if (sprite.numframes)
- FinishSprite ();
- GetToken (false);
- sprintf (spriteoutname, "%s%s.spr", spritedir, token);
- memset (&sprite, 0, sizeof(sprite));
- framecount = 0;
- framesmaxs[0] = -9999999;
- framesmaxs[1] = -9999999;
- lumpbuffer = malloc (MAX_BUFFER_SIZE * 2); // *2 for padding
- if (!lumpbuffer)
- Error ("Couldn't get buffer memory");
- plump = lumpbuffer;
- sprite.synctype = ST_RAND; // default
- }
- /*
- ==============
- FinishSprite
- ==============
- */
- void FinishSprite (void)
- {
- FILE *spriteouthandle;
- if (sprite.numframes == 0)
- Error ("no frames\n");
- if (!strlen(spriteoutname))
- Error ("Didn't name sprite file");
-
- if ((plump - lumpbuffer) > MAX_BUFFER_SIZE)
- Error ("Sprite package too big; increase MAX_BUFFER_SIZE");
- spriteouthandle = SafeOpenWrite (spriteoutname);
- printf ("saving in %s\n", spriteoutname);
- WriteSprite (spriteouthandle);
- fclose (spriteouthandle);
-
- printf ("spritegen: successful\n");
- printf ("%d frame(s)\n", sprite.numframes);
- printf ("%d ungrouped frame(s), including group headers\n", framecount);
-
- spriteoutname[0] = 0; // clear for a new sprite
- }
- /*
- ==============
- main
-
- ==============
- */
- int main (int argc, char **argv)
- {
- int i;
- if (argc != 2 && argc != 4)
- Error ("usage: spritegen [-archive directory] file.qc");
-
- if (!strcmp(argv[1], "-archive"))
- {
- archive = true;
- strcpy (archivedir, argv[2]);
- printf ("Archiving source to: %s\n", archivedir);
- i = 3;
- }
- else
- i = 1;
- SetQdirFromPath (argv[i]);
- ExtractFilePath (argv[i], spritedir); // chop the filename
- //
- // load the script
- //
- LoadScriptFile (argv[i]);
-
- ParseScript ();
- FinishSprite ();
- return 0;
- }
|