123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <dos.h>
- #include <io.h>
- #include <fcntl.h>
- #include "getopt.h"
- #include "misc.h"
- #include "typedefs.h"
- #include "seq.h"
- #include "debug4g.h"
- #define kMaxFrames 1024
- struct SEQFRAME1
- {
- unsigned nTile : 16;
- signed shade : 8;
- unsigned translucent : 1;
- unsigned blocking : 1;
- unsigned hitscan : 1;
- unsigned pal : 4;
- };
- struct Seq1
- {
- char signature[4];
- short version;
- short nFrames; // sequence length
- short ticksPerFrame; // inverted play rate
- short keyFrame;
- uchar flags;
- char pad[3];
- SEQFRAME1 frame[1];
- };
- struct SEQFRAME2
- {
- unsigned nTile : 12;
- unsigned reserved1 : 3;
- unsigned translucentR : 1;
- signed shade : 8;
- unsigned translucent : 1;
- unsigned blocking : 1;
- unsigned hitscan : 1;
- unsigned pal : 5;
- unsigned xrepeat : 8;
- unsigned yrepeat : 8;
- unsigned reserved2 : 16;
- };
- struct Seq2
- {
- char signature[4];
- short version;
- short nFrames; // sequence length
- short ticksPerFrame; // inverted play rate
- short keyFrame;
- uchar flags;
- char pad[3];
- SEQFRAME2 frame[1];
- };
- struct FNODE
- {
- FNODE *next;
- char name[1];
- };
- FNODE head = { &head, "" };
- FNODE *tail = &head;
- BOOL bForcePal = FALSE;
- uchar nPal;
- BOOL bForceShade = FALSE;
- char nShade;
- BOOL bForceXRepeat = FALSE;
- uchar xrepeat;
- BOOL bForceYRepeat = FALSE;
- uchar yrepeat;
- BOOL bForceTranslucent = FALSE;
- BOOL bIsTranslucent;
- BOOL bIsTranslucentR;
- Seq *pSeq = NULL;
- /*******************************************************************************
- FUNCTION: ShowBanner()
- DESCRIPTION: Show application banner
- *******************************************************************************/
- void ShowBanner( void )
- {
- printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
- printf("SEQ Loathing Update Tool Version 3.0 Copyright (c) 1995 Q Studios Corporation\n");
- printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
- }
- /*******************************************************************************
- FUNCTION: ShowUsage()
- DESCRIPTION: Display command-line parameter usage, then exit
- *******************************************************************************/
- void ShowUsage(void)
- {
- printf("Syntax: SLUT [options] files[.seq]\n");
- printf("-pN force all palookups to N\n");
- printf("-sN force all shade values to N\n");
- printf("-t[0|1|2] force translucency level\n");
- printf("-xN force all x repeats to N\n");
- printf("-yN force all y repeats to N\n");
- printf("-? This help\n");
- exit(0);
- }
- /*******************************************************************************
- FUNCTION: QuitMessage()
- DESCRIPTION: Display a printf() style message, the exit with code 1
- *******************************************************************************/
- void QuitMessage(char * fmt, ...)
- {
- char msg[80];
- va_list argptr;
- va_start( argptr, fmt );
- vsprintf( msg, fmt, argptr );
- va_end(argptr);
- printf(msg);
- exit(1);
- }
- void ProcessFile(char *filename)
- {
- char bakname[_MAX_PATH], tempname[_MAX_PATH];
- int i, hFile, nSize;
- strcpy(bakname, filename);
- ChangeExtension(bakname, ".BAK");
- tmpnam(tempname);
- printf("%s: ", filename);
- hFile = open(filename, O_RDONLY | O_BINARY);
- if ( hFile == -1 )
- QuitMessage("Couldn't open file %s, errno=%d\n", filename, errno);
- nSize = filelength(hFile);
- Seq *pTempSeq = (Seq *)malloc(nSize);
- dassert(pTempSeq != NULL);
- if ( !FileRead(hFile, pTempSeq, nSize) )
- {
- close(hFile);
- QuitMessage("Error reading SEQ file");
- }
- close(hFile);
- memcpy(pSeq, pTempSeq, nSize);
- if (memcmp(pSeq->signature, kSEQSig, sizeof(pSeq->signature)) != 0)
- QuitMessage("SEQ file corrupted");
- switch ( pTempSeq->version >> 8 )
- {
- case 3:
- break; // current version
- case 2:
- {
- // convert old sequence format
- Seq2 *pSeq2 = (Seq2 *)pTempSeq;
- memset(pSeq, 0, sizeof(Seq));
- pSeq->nFrames = pSeq2->nFrames;
- pSeq->ticksPerFrame = pSeq2->ticksPerFrame;
- // check version 2 minor version
- switch ( pTempSeq->version & 0xFF )
- {
- case 2:
- pSeq->flags = pSeq2->flags;
- for (i = 0; i < pSeq2->nFrames; i++)
- {
- memset(&pSeq->frame[i], 0, sizeof(SEQFRAME));
- pSeq->frame[i].nTile = pSeq2->frame[i].nTile;
- pSeq->frame[i].translucent = pSeq2->frame[i].translucent;
- pSeq->frame[i].translucentR = pSeq2->frame[i].translucentR;
- pSeq->frame[i].blocking = pSeq2->frame[i].blocking;
- pSeq->frame[i].hitscan = pSeq2->frame[i].hitscan;
- pSeq->frame[i].xrepeat = pSeq2->frame[i].xrepeat;
- pSeq->frame[i].yrepeat = pSeq2->frame[i].yrepeat;;
- pSeq->frame[i].shade = pSeq2->frame[i].shade;
- pSeq->frame[i].pal = pSeq2->frame[i].pal;
- }
- break;
- case 1:
- pSeq->flags = pSeq2->flags;
- for (i = 0; i < pSeq2->nFrames; i++)
- {
- memset(&pSeq->frame[i], 0, sizeof(SEQFRAME));
- pSeq->frame[i].nTile = pSeq2->frame[i].nTile;
- pSeq->frame[i].translucent = pSeq2->frame[i].translucent;
- pSeq->frame[i].translucentR = 0;
- pSeq->frame[i].blocking = pSeq2->frame[i].blocking;
- pSeq->frame[i].hitscan = pSeq2->frame[i].hitscan;
- pSeq->frame[i].xrepeat = pSeq2->frame[i].xrepeat;
- pSeq->frame[i].yrepeat = pSeq2->frame[i].yrepeat;;
- pSeq->frame[i].shade = pSeq2->frame[i].shade;
- pSeq->frame[i].pal = pSeq2->frame[i].pal;
- }
- break;
- case 0:
- pSeq->flags = 0;
- for (i = 0; i < pSeq2->nFrames; i++)
- {
- memset(&pSeq->frame[i], 0, sizeof(SEQFRAME));
- pSeq->frame[i].nTile = pSeq2->frame[i].nTile;
- pSeq->frame[i].translucent = pSeq2->frame[i].translucent;
- pSeq->frame[i].translucentR = 0;
- pSeq->frame[i].blocking = pSeq2->frame[i].blocking;
- pSeq->frame[i].hitscan = pSeq2->frame[i].hitscan;
- pSeq->frame[i].xrepeat = pSeq2->frame[i].xrepeat;
- pSeq->frame[i].yrepeat = pSeq2->frame[i].yrepeat;;
- pSeq->frame[i].shade = pSeq2->frame[i].shade;
- pSeq->frame[i].pal = pSeq2->frame[i].pal;
- }
- break;
- }
- break;
- }
- case 1:
- {
- // convert old sequence format
- Seq1 *pSeq1 = (Seq1 *)pTempSeq;
- memset(pSeq, 0, sizeof(Seq));
- pSeq->nFrames = pSeq1->nFrames;
- pSeq->ticksPerFrame = pSeq1->ticksPerFrame;
- for (i = 0; i < pSeq1->nFrames; i++)
- {
- memset(&pSeq->frame[i], 0, sizeof(SEQFRAME));
- pSeq->frame[i].nTile = pSeq1->frame[i].nTile;
- pSeq->frame[i].translucent = pSeq1->frame[i].translucent;
- pSeq->frame[i].blocking = pSeq1->frame[i].blocking;
- pSeq->frame[i].hitscan = pSeq1->frame[i].hitscan;
- pSeq->frame[i].xrepeat = 64;
- pSeq->frame[i].yrepeat = 64;
- pSeq->frame[i].shade = pSeq1->frame[i].shade;
- pSeq->frame[i].pal = pSeq1->frame[i].pal;
- }
- break;
- }
- default:
- QuitMessage("Obsolete SEQ version");
- }
- free(pTempSeq);
- // set forced frame attributes
- for (i = 0; i < pSeq->nFrames; i++)
- {
- if ( bForcePal )
- pSeq->frame[i].pal = nPal;
- if ( bForceShade )
- pSeq->frame[i].shade = nShade;
- if ( bForceTranslucent )
- {
- if (bIsTranslucent)
- pSeq->frame[i].translucent = 1;
- else
- pSeq->frame[i].translucent = 0;
- if (bIsTranslucentR)
- pSeq->frame[i].translucentR = 1;
- else
- pSeq->frame[i].translucentR = 0;
- }
- if ( bForceXRepeat )
- pSeq->frame[i].xrepeat = xrepeat;
- if ( bForceYRepeat )
- pSeq->frame[i].yrepeat = yrepeat;
- }
- hFile = open(tempname, O_CREAT | O_WRONLY | O_BINARY | O_TRUNC, S_IWUSR);
- if ( hFile == -1 )
- QuitMessage("Error creating temporary file");
- memcpy(pSeq->signature, kSEQSig, sizeof(pSeq->signature));
- pSeq->version = kSEQVersion;
- if ( !FileWrite(hFile, pSeq, sizeof(Seq) + pSeq->nFrames * sizeof(SEQFRAME)) )
- {
- close(hFile);
- QuitMessage("Error writing temporary file");
- }
- close(hFile);
- // backup the existing sequence
- unlink(bakname);
- rename(filename, bakname);
- rename(tempname, filename);
- printf("done.\n");
- }
- void InsertFilename( char *fname )
- {
- FNODE *n = (FNODE *)malloc(sizeof(FNODE) + strlen(fname));
- strcpy(n->name, fname);
- // insert the node at the tail, so it stays in order
- n->next = tail->next;
- tail->next = n;
- tail = n;
- }
- void ProcessArgument(char *s)
- {
- char filespec[_MAX_PATH];
- char buffer[_MAX_PATH2];
- char path[_MAX_PATH];
- strcpy(filespec, s);
- AddExtension(filespec, ".SEQ");
- char *drive, *dir;
- // separate the path from the filespec
- _splitpath2(s, buffer, &drive, &dir, NULL, NULL);
- _makepath(path, drive, dir, NULL, NULL);
- struct find_t fileinfo;
- unsigned r = _dos_findfirst(s, _A_NORMAL, &fileinfo);
- if (r != 0)
- printf("%s not found\n", s);
- while ( r == 0 )
- {
- strcpy(filespec, path);
- strcat(filespec, fileinfo.name);
- InsertFilename(filespec);
- r = _dos_findnext( &fileinfo );
- }
- _dos_findclose(&fileinfo);
- }
- /***********************************************************************
- * Process command line arguments
- **********************************************************************/
- void ParseOptions( void )
- {
- enum {
- kSwitchHelp,
- kSwitchForcePal,
- kSwitchForceShade,
- kSwitchForceTrans,
- kSwitchXRepeat,
- kSwitchYRepeat,
- };
- static SWITCH switches[] = {
- { "?", kSwitchHelp, FALSE },
- { "P", kSwitchForcePal, TRUE },
- { "S", kSwitchForceShade, TRUE },
- { "T", kSwitchForceTrans, TRUE },
- { "X", kSwitchXRepeat, TRUE },
- { "Y", kSwitchYRepeat, TRUE },
- { NULL, 0, FALSE },
- };
- int value;
- int r;
- while ( (r = GetOptions(switches)) != GO_EOF )
- {
- switch (r)
- {
- case GO_INVALID:
- QuitMessage("Invalid argument: %s", OptArgument);
- case GO_FULL:
- ProcessArgument(OptArgument);
- break;
- case kSwitchForcePal:
- value = strtol(OptArgument, NULL, 0);
- bForcePal = TRUE;
- nPal = (uchar)value;
- break;
- case kSwitchForceShade:
- value = strtol(OptArgument, NULL, 0);
- bForceShade = TRUE;
- nShade = (char)value;
- break;
- case kSwitchForceTrans:
- value = strtol(OptArgument, NULL, 0);
- bForceTranslucent = TRUE;
- switch(value)
- {
- case 0:
- bIsTranslucent = bIsTranslucentR = FALSE;
- break;
- case 1:
- bIsTranslucent = TRUE;
- bIsTranslucentR = FALSE;
- break;
- case 2:
- bIsTranslucent = bIsTranslucentR = TRUE;
- break;
- default:
- QuitMessage("Invalid translucency argument: %s", OptArgument);
- break;
- }
- break;
- case kSwitchXRepeat:
- value = strtol(OptArgument, NULL, 0);
- bForceXRepeat = TRUE;
- xrepeat = (uchar)value;
- break;
- case kSwitchYRepeat:
- value = strtol(OptArgument, NULL, 0);
- bForceYRepeat = TRUE;
- yrepeat = (uchar)value;
- break;
- }
- }
- }
- void main( int argc )
- {
- ShowBanner();
- pSeq = (Seq *)malloc(sizeof(Seq) + kMaxFrames * sizeof(SEQFRAME));
- dassert(pSeq != NULL);
- if (argc < 2) ShowUsage();
- ParseOptions();
- // process the file list
- for (FNODE *n = head.next; n != &head; n = n->next)
- ProcessFile(n->name);
- }
|