123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305 |
- /*******************************************************************************
- FILE: QAVEDIT.CPP
- DESCRIPTION: Allows editing of 2D animation sequences
- AUTHOR: Peter M. Freese
- CREATED: 02-26-95
- COPYRIGHT: Copyright (c) 1995 Q Studios Corporation
- *******************************************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include <helix.h>
- #include <string.h>
- #include <io.h>
- #include <fcntl.h>
- #include <dos.h>
- #include "typedefs.h"
- #include "engine.h"
- #include "key.h"
- #include "misc.h"
- #include "gameutil.h"
- #include "gfx.h"
- #include "bstub.h"
- #include "globals.h"
- #include "debug4g.h"
- #include "error.h"
- #include "gui.h"
- #include "tile.h"
- #include "qav.h"
- #include "screen.h"
- #include "textio.h"
- #include "inifile.h"
- #include "options.h"
- #include "timer.h"
- #include "mouse.h"
- #include "trig.h"
- #include "getopt.h"
- #define kMaxFrames 1024
- #define kAttrTitle (kColorGreen * 16 + kColorWhite)
- struct FRAME1
- {
- long timeStart;
- long timeStop;
- int type;
- int id;
- int flags;
- union
- {
- // type = kQFrameTile
- struct
- {
- int x, y;
- int layer;
- int shade;
- int pal;
- };
- // type = kQFrameSound
- struct
- {
- int priority;
- int volume;
- int soundID;
- };
- // type = kQFrameTrigger
- struct {
- int trigger;
- };
- };
- };
- struct QAV1
- {
- char signature[4];
- short version;
- char dummy[2];
- int frames;
- long duration;
- int backTile;
- Point origin;
- FRAME1 frame[1];
- };
- struct EditQAV : public QAV
- {
- void ClipTileFrame( TILE_FRAME *f );
- void SetOrigin( int x, int y );
- void DrawOrigin( int nColor );
- void HighlightFrame( TILE_FRAME *f );
- };
- char gQAVName[128] = "";
- int lastTile = 2052;
- char buffer[256];
- EditQAV *gQAV = NULL;
- static BOOL isModified;
- EHF prevErrorHandler;
- void faketimerhandler( void )
- { }
- struct FNODE
- {
- FNODE *next;
- char name[1];
- };
- FNODE head = { &head, "" };
- FNODE *tail = &head;
- /*******************************************************************************
- FUNCTION: ShowBanner()
- DESCRIPTION: Show application banner
- *******************************************************************************/
- void ShowBanner( void )
- {
- printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
- printf(" QAV Editor Version 2.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: QAVEDIT [options] files[.qav]\n");
- printf("-c Batch convert files to current verson\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);
- }
- /***********************************************************************
- * EditorErrorHandler()
- *
- * Terminate from error condition, displaying a message in text mode.
- *
- **********************************************************************/
- ErrorResult EditorErrorHandler( const Error& error )
- {
- uninitengine();
- keyRemove();
- setvmode(gOldDisplayMode);
- // chain to the default error handler
- return prevErrorHandler(error);
- };
- /***********************************************************************
- * Ensure that the tile location isn't off the screen
- **********************************************************************/
- void EditQAV::ClipTileFrame( TILE_FRAME *f )
- {
- int xOffset, yOffset;
- if ( f->flags & kQFrameCorner )
- xOffset = yOffset = 0;
- else
- {
- xOffset = picanm[f->id].xcenter + tilesizx[f->id] / 2 - origin.x;
- yOffset = picanm[f->id].ycenter + tilesizy[f->id] / 2 - origin.y;
- }
- if (f->x < xOffset - tilesizx[f->id] + 1)
- f->x = xOffset - tilesizx[f->id] + 1;
- if (f->x > 319 + xOffset)
- f->x = 319 + xOffset;
- if (f->y < yOffset - tilesizy[f->id] + 1)
- f->y = yOffset - tilesizy[f->id] + 1;
- if (f->y > 199 + yOffset)
- f->y = 199 + yOffset;
- }
- void EditQAV::SetOrigin( int x, int y )
- {
- if (keystatus[KEY_LCTRL] || keystatus[KEY_RCTRL])
- {
- x = ClipRange(x, 0, 319);
- y = ClipRange(y, 0, 199);
- int dx = x - origin.x;
- int dy = y - origin.y;
- for (int i = 0; i < nFrames; i++)
- {
- for (int j = 0; j < kMaxLayers; j++)
- {
- frame[i].layer[j].x -= dx;
- frame[i].layer[j].y -= dy;
- }
- }
- origin.x = x;
- origin.y = y;
- }
- else
- {
- origin.x = ClipRange(x, 0, 319);
- origin.y = ClipRange(y, 0, 199);
- // ensure that no frame are offscreen
- for (int i = 0; i < nFrames; i++)
- {
- for (int j = 0; j < kMaxLayers; j++)
- {
- ClipTileFrame(&frame[i].layer[j]);
- }
- }
- }
- }
- void EditQAV::DrawOrigin( int nColor )
- {
- Video.SetColor(nColor);
- gfxHLine(origin.y << 1, origin.x - 6 << 1, origin.x - 1 << 1);
- gfxHLine(origin.y << 1, origin.x + 1 << 1, origin.x + 6 << 1);
- gfxVLine(origin.x << 1, origin.y - 5 << 1, origin.y - 1 << 1);
- gfxVLine(origin.x << 1, origin.y + 1 << 1, origin.y + 5 << 1);
- }
- void EditQAV::HighlightFrame( TILE_FRAME *f )
- {
- int xOffset, yOffset;
- dassert(f->id > 0);
- if ( f->flags & kQFrameCorner )
- xOffset = yOffset = 0;
- else
- {
- xOffset = picanm[f->id].xcenter + tilesizx[f->id] / 2;
- yOffset = picanm[f->id].ycenter + tilesizy[f->id] / 2;
- }
- int x0 = (origin.x + f->x - mulscale16(xOffset, f->zoom) << 1) - 1;
- int y0 = (origin.y + f->y - mulscale16(yOffset, f->zoom) << 1) - 1;
- int x1 = x0 + (mulscale16(tilesizx[f->id], f->zoom) << 1) + 1;
- int y1 = y0 + (mulscale16(tilesizy[f->id], f->zoom) << 1) + 1;
- Video.SetColor(gStdColor[8]);
- gfxHLine(y0, x0, x1);
- gfxHLine(y1, x0, x1);
- gfxVLine(x0, y0, y1);
- gfxVLine(x1, y0, y1);
- }
- void SaveQAV( void )
- {
- char filename[128];
- int hFile;
- strcpy(filename, gQAVName);
- ChangeExtension(filename, ".QAV");
- // see if file exists
- if ( access(filename, F_OK) == 0 )
- {
- char bakname[_MAX_PATH];
- strcpy(bakname, filename);
- ChangeExtension(bakname, ".BAK");
- unlink(bakname);
- rename(filename, bakname);
- }
- hFile = open(filename, O_CREAT | O_WRONLY | O_BINARY | O_TRUNC, S_IWUSR);
- if ( hFile == -1 )
- ThrowError("Error creating QAV file", ES_ERROR);
- memcpy(gQAV->signature, kQAVSig, sizeof(gQAV->signature));
- gQAV->version = kQAVVersion;
- gQAV->duration = gQAV->nFrames * gQAV->ticksPerFrame;
- if ( !FileWrite(hFile, gQAV, sizeof(QAV) + (gQAV->nFrames) * sizeof(FRAME)) )
- goto WriteError;
- close(hFile);
- isModified = FALSE;
- scrSetMessage("QAV saved.");
- return;
- WriteError:
- close(hFile);
- ThrowError("Error writing QAV file", ES_ERROR);
- }
- BOOL LoadQAV( void )
- {
- char filename[128];
- int hFile;
- int nSize;
- strcpy(filename, gQAVName);
- ChangeExtension(filename, ".QAV");
- hFile = open(filename, O_RDONLY | O_BINARY);
- if ( hFile == -1 )
- return FALSE;
- nSize = filelength(hFile);
- QAV *pTemp = (QAV *)Resource::Alloc(nSize);
- if ( !FileRead(hFile, pTemp, nSize) )
- goto ReadError;
- close(hFile);
- if (memcmp(pTemp->signature, kQAVSig, sizeof(pTemp->signature)) != 0)
- {
- close(hFile);
- ThrowError("QAV file corrupted", ES_ERROR);
- }
- gQAV->nFrames = 0;
- gQAV->ticksPerFrame = 5;
- gQAV->duration = 0;
- gQAV->origin.x = 160;
- gQAV->origin.y = 100;
- memset(&gQAV->frame[0], 0, sizeof(FRAME) * kMaxFrames);
- switch ( pTemp->version >> 8 )
- {
- case 1:
- {
- QAV1 *pQAV1 = (QAV1 *)pTemp;
- gQAV->nFrames = pQAV1->duration / 5;
- gQAV->ticksPerFrame = 5;
- gQAV->duration = pQAV1->duration;
- gQAV->origin = pQAV1->origin;
- FRAME1 *pFrame1 = &pQAV1->frame[0];
- for (int i = 0; i < pQAV1->frames; i++, pFrame1++)
- {
- if ( pFrame1->type != 0 )
- continue;
- int j = pFrame1->timeStart / 5;
- FRAME *pFrame = &gQAV->frame[j];
- int nLayer = kMaxLayers - 1;
- // find highest used layer
- while ( nLayer >= 0 && pFrame->layer[nLayer].id == 0 )
- nLayer--;
- // use next layer up
- nLayer++;
- if ( nLayer == kMaxLayers )
- {
- dprintf("Out of layers at time index %d\n", pFrame1->timeStart);
- nLayer = 0;
- }
- for ( ; j < pFrame1->timeStop / 5; j++, pFrame++)
- {
- pFrame->layer[nLayer].id = pFrame1->id;
- pFrame->layer[nLayer].x = pFrame1->x;
- pFrame->layer[nLayer].y = pFrame1->y;
- pFrame->layer[nLayer].zoom = 0x10000;
- pFrame->layer[nLayer].flags = pFrame1->flags;
- pFrame->layer[nLayer].shade = (schar)pFrame1->shade;
- pFrame->layer[nLayer].pal = (uchar)pFrame1->pal;
- pFrame->layer[nLayer].angle = 0;
- }
- }
- break;
- }
- case 2:
- memcpy(gQAV, pTemp, nSize);
- break;
- }
- isModified = FALSE;
- return TRUE;
- ReadError:
- close(hFile);
- ThrowError("Error reading QAV file", ES_ERROR);
- return FALSE;
- }
- BOOL SaveAs( void )
- {
- if ( GetStringBox("Save As", gQAVName) )
- {
- // load it if it seems valid
- if (strlen(gQAVName) > 0)
- {
- SaveQAV();
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL LoadAs( void )
- {
- if ( GetStringBox("Load QAV", gQAVName) )
- {
- // load it if it seems valid
- if (strlen(gQAVName) > 0)
- {
- LoadQAV();
- return TRUE;
- }
- }
- return FALSE;
- }
- /*******************************************************************************
- ** ChangeAcknowledge()
- **
- ** Returns TRUE if the YES/NO selected, or FALSE if aborted or escape pressed.
- *******************************************************************************/
- BOOL ChangeAcknowledge(void)
- {
- // create the dialog
- Window dialog(59, 80, 202, 46, "Save Changes?");
- TextButton *pbYes = new TextButton( 4, 4, 60, 20, "&Yes", mrYes );
- TextButton *pbNo = new TextButton( 68, 4, 60, 20, "&No", mrNo );
- TextButton *pbCancel = new TextButton( 132, 4, 60, 20, "&Cancel", mrCancel );
- dialog.Insert(pbYes);
- dialog.Insert(pbNo);
- dialog.Insert(pbCancel);
- ShowModal(&dialog);
- switch ( dialog.endState )
- {
- case mrCancel:
- return FALSE;
- case mrOk:
- case mrYes:
- return SaveAs();
- }
- return TRUE;
- }
- void PlayIt( BOOL looping )
- {
- ulong timeBase = gGameClock;
- ulong t = 0;
- int timeFactor;
- gQAV->duration = gQAV->nFrames * gQAV->ticksPerFrame;
- while (1)
- {
- BYTE key = keyGet();
- BYTE shift = keystatus[KEY_LSHIFT] | keystatus[KEY_RSHIFT];
- BYTE ctrl = keystatus[KEY_LCTRL] | keystatus[KEY_RCTRL];
- switch (key)
- {
- case KEY_ESC:
- keystatus[KEY_ESC] = 0;
- return;
- case KEY_PLUS:
- gQAV->ticksPerFrame++;
- gQAV->duration = gQAV->nFrames * gQAV->ticksPerFrame;
- isModified = TRUE;
- break;
- case KEY_MINUS:
- gQAV->ticksPerFrame = ClipLow(gQAV->ticksPerFrame - 1, 1);
- gQAV->duration = gQAV->nFrames * gQAV->ticksPerFrame;
- isModified = TRUE;
- break;
- }
- if ((t >> 16) >= gQAV->duration)
- {
- if (!looping)
- break;
- t -= (gQAV->duration << 16);
- continue;
- }
- clearview(0);
- gQAV->Draw(t >> 16, 0, kQFrameScale);
- sprintf(buffer, "%2d:%03d TPF=%2d",
- (t >> 16) / kTimerRate, (t >> 16) % kTimerRate, gQAV->ticksPerFrame);
- gfxDrawText(512, 8, gStdColor[15], buffer);
- if (vidoption != 1)
- WaitVSync();
- scrNextPage();
- gFrameTicks = gGameClock - gFrameClock;
- gFrameClock += gFrameTicks;
- timeFactor = 16;
- if ( ctrl )
- timeFactor = 15;
- if ( shift )
- timeFactor = 14;
- t += gFrameTicks << timeFactor;
- }
- }
- void DrawEditFrame( FRAME *f )
- {
- // show the trigger info
- TRIGGER_FRAME *tf = &f->trigger;
- if ( tf->id > 0 )
- {
- sprintf( buffer, "Trigger: %6i", tf->id );
- gfxDrawText(0, 16, gStdColor[15], buffer);
- }
- // show the sound info
- SOUND_FRAME *sf = &f->sound;
- if ( sf->id > 0 )
- {
- sprintf(buffer, "Snd: %6d Vol: %4d Pri: %4d", sf->id, sf->volume, sf->priority );
- gfxDrawText(400, 16, gStdColor[15], buffer);
- }
- }
- void EditLoop( void )
- {
- int nbuttons;
- static int obuttons = 0;
- char buffer[256];
- int nFrame = 0;
- int nLayer = 0;
- while (1)
- {
- FRAME *pFrame = &gQAV->frame[nFrame];
- TILE_FRAME *pTFrame = &pFrame->layer[nLayer];
- gFrameTicks = gGameClock - gFrameClock;
- gFrameClock += gFrameTicks;
- UpdateBlinkClock(gFrameTicks);
- gQAV->duration = gQAV->nFrames * gQAV->ticksPerFrame;
- clearview(0);
- if ( nFrame < gQAV->nFrames )
- gQAV->Draw(nFrame * gQAV->ticksPerFrame, 0, kQFrameScale);
- DrawEditFrame(pFrame);
- sprintf(buffer,"%2d/%2d Layer=%d TPF=%2d",
- nFrame, gQAV->nFrames, nLayer, gQAV->ticksPerFrame);
- gfxDrawText(464, 8, gStdColor[15], buffer);
- if (keystatus[KEY_O])
- {
- gQAV->DrawOrigin(gStdColor[15]);
- sprintf(buffer,"%3i,%3i", gQAV->origin.x, gQAV->origin.y);
- gfxDrawText(0, 8, gStdColor[15], buffer);
- }
- else
- {
- gQAV->DrawOrigin(gStdColor[8]);
- if ( pTFrame->id > 0 )
- {
- if ( IsBlinkOn() )
- gQAV->HighlightFrame(pTFrame);
- sprintf(buffer,"Tile=%4d %+4d,%+4d Sh=%+4d Pal=%2d Zoom=%8X Ang=%4d",
- pTFrame->id,
- pTFrame->x,
- pTFrame->y,
- pTFrame->shade,
- pTFrame->pal,
- pTFrame->zoom,
- pTFrame->angle
- );
- gfxDrawText(0, 8, gStdColor[15], buffer);
- }
- }
- scrDisplayMessage(gStdColor[kColorWhite]);
- if (vidoption != 1)
- WaitVSync();
- scrNextPage();
- BYTE key = keyGet();
- BYTE shift = keystatus[KEY_LSHIFT] | keystatus[KEY_RSHIFT];
- BYTE ctrl = keystatus[KEY_LCTRL] | keystatus[KEY_RCTRL];
- BYTE alt = keystatus[KEY_LALT] | keystatus[KEY_RALT];
- BYTE pad5 = keystatus[KEY_PAD5];
- switch (key)
- {
- case KEY_ESC:
- keystatus[KEY_ESC] = 0;
- if (!isModified || ChangeAcknowledge())
- {
- free(gQAV);
- gQAV = NULL;
- return;
- }
- break;
- case KEY_SPACE:
- PlayIt(FALSE);
- break;
- case KEY_ENTER:
- PlayIt(TRUE);
- break;
- case KEY_F2:
- if (keystatus[KEY_LCTRL] || keystatus[KEY_RCTRL] || strlen(gQAVName) == 0)
- SaveAs();
- else
- SaveQAV();
- break;
- case KEY_F3:
- if (!isModified || ChangeAcknowledge())
- {
- LoadAs();
- nFrame = 0;
- nLayer = 0;
- }
- break;
- case KEY_2:
- SetBlinkOn();
- nFrame = ClipHigh(nFrame + 1, gQAV->nFrames);
- break;
- case KEY_1:
- SetBlinkOn();
- nFrame = ClipLow(nFrame - 1, 0);
- break;
- case KEY_HOME:
- SetBlinkOn();
- nFrame = 0;
- break;
- case KEY_END:
- SetBlinkOn();
- nFrame = gQAV->nFrames;
- break;
- case KEY_PLUS:
- gQAV->ticksPerFrame++;
- isModified = TRUE;
- break;
- case KEY_MINUS:
- gQAV->ticksPerFrame = ClipLow(gQAV->ticksPerFrame - 1, 1);
- isModified = TRUE;
- break;
- case KEY_INSERT:
- {
- if ( ctrl )
- {
- // insert a layer
- for (int i = 0; i < gQAV->nFrames; i++)
- {
- for (int j = kMaxLayers - 1; j > nLayer; j--)
- {
- gQAV->frame[i].layer[j] = gQAV->frame[i].layer[j - 1];
- }
- memset(&gQAV->frame[i].layer[j], 0, sizeof(TILE_FRAME));
- }
- isModified = TRUE;
- break;
- }
- if ( alt )
- {
- // insert a frame
- memmove(pFrame + 1, pFrame, (gQAV->nFrames - nFrame) * sizeof(FRAME));
- memset(pFrame, 0, sizeof(FRAME));
- gQAV->nFrames++;
- isModified = TRUE;
- break;
- }
- // just duplicate a tile
- if ( pTFrame->id <= 0 && nFrame > 0 )
- {
- *pTFrame = gQAV->frame[nFrame - 1].layer[nLayer];
- isModified = TRUE;
- if ( nFrame == gQAV->nFrames )
- gQAV->nFrames++;
- break;
- }
- break;
- }
- case KEY_DELETE:
- if ( ctrl )
- {
- // delete a layer
- for (int i = 0; i < gQAV->nFrames; i++)
- {
- for (int j = nLayer; j < kMaxLayers - 1; j++)
- {
- gQAV->frame[i].layer[j] = gQAV->frame[i].layer[j + 1];
- }
- memset(&gQAV->frame[i].layer[j], 0, sizeof(TILE_FRAME));
- }
- isModified = TRUE;
- break;
- }
- if ( alt )
- {
- // delete a frame
- if ( nFrame < gQAV->nFrames )
- {
- gQAV->nFrames--;
- memmove(pFrame, pFrame + 1, (gQAV->nFrames - nFrame) * sizeof(FRAME));
- memset(&gQAV->frame[gQAV->nFrames], 0, sizeof(FRAME));
- isModified = TRUE;
- }
- break;
- }
- // just delete a tile
- if ( pTFrame->id > 0 )
- {
- memset(pTFrame, 0, sizeof(TILE_FRAME));
- isModified = TRUE;
- break;
- }
- break;
- case KEY_PAGEUP:
- SetBlinkOn();
- if ( nLayer < kMaxLayers - 1 )
- {
- if ( shift )
- {
- if ( ctrl )
- {
- // raise entire layer
- for (int i = 0; i < gQAV->nFrames; i++)
- {
- TILE_FRAME temp = gQAV->frame[i].layer[nLayer];
- gQAV->frame[i].layer[nLayer] = gQAV->frame[i].layer[nLayer + 1];
- gQAV->frame[i].layer[nLayer + 1] = temp;
- }
- nLayer++;
- isModified = TRUE;
- break;
- }
- // raise tile
- TILE_FRAME temp = *pTFrame;
- *pTFrame = pFrame->layer[nLayer + 1];
- pFrame->layer[nLayer + 1] = temp;
- nLayer++;
- isModified = TRUE;
- break;
- }
- nLayer++;
- }
- break;
- case KEY_PAGEDN:
- SetBlinkOn();
- if ( nLayer > 0 )
- {
- if ( shift )
- {
- if ( ctrl )
- {
- // lower entire layer
- for (int i = 0; i < gQAV->nFrames; i++)
- {
- TILE_FRAME temp = gQAV->frame[i].layer[nLayer];
- gQAV->frame[i].layer[nLayer] = gQAV->frame[i].layer[nLayer - 1];
- gQAV->frame[i].layer[nLayer - 1] = temp;
- }
- nLayer--;
- isModified = TRUE;
- break;
- }
- // lower tile
- TILE_FRAME temp = *pTFrame;
- *pTFrame = pFrame->layer[nLayer - 1];
- pFrame->layer[nLayer - 1] = temp;
- nLayer--;
- isModified = TRUE;
- break;
- }
- nLayer--;
- }
- break;
- case KEY_F:
- pFrame->trigger.id = GetNumberBox("Trigger Id", pFrame->trigger.id, pFrame->trigger.id);
- if ( pFrame->trigger.id == 0 )
- break;
- if ( nFrame == gQAV->nFrames )
- gQAV->nFrames++;
- isModified = TRUE;
- break;
- case KEY_P:
- if ( pTFrame->id > 0 )
- {
- // set the palette for the highlighted tile frame
- if ( alt )
- pTFrame->pal = (uchar)GetNumberBox("Palookup", pTFrame->pal, pTFrame->pal );
- else
- pTFrame->pal = (uchar)IncRotate(pTFrame->pal, kMaxPLU);
- isModified = TRUE;
- }
- break;
- case KEY_R:
- if ( pTFrame->id > 0 )
- {
- pTFrame->flags ^= kQFrameCorner;
- isModified = TRUE;
- }
- break;
- case KEY_T:
- if ( pTFrame->id > 0 )
- {
- // set translucency flags for the highlighted tile frame
- int flags = pTFrame->flags;
- int level = 0;
- if ( flags & kQFrameTranslucent )
- {
- level = 1;
- if ( flags & kQFrameTranslucentR )
- level = 2;
- }
- level = IncRotate(level, 3);
- switch ( level )
- {
- case 0:
- flags &= ~kQFrameTranslucent & ~kQFrameTranslucentR;
- break;
- case 1:
- flags &= ~kQFrameTranslucentR;
- flags |= kQFrameTranslucent;
- break;
- case 2:
- flags |= kQFrameTranslucent | kQFrameTranslucentR;
- break;
- }
- pTFrame->flags = flags;
- isModified = TRUE;
- }
- break;
- case KEY_V:
- {
- int nTile = pTFrame->id;
- if ( nTile == 0 )
- {
- if ( nFrame > 0 )
- {
- *pTFrame = gQAV->frame[nFrame - 1].layer[nLayer];
- nTile = pTFrame->id;
- pTFrame->id = 0;
- }
- else
- pTFrame->zoom = 0x10000;
- }
- pTFrame->id = tilePick(nTile, pTFrame->id, SS_ALL);
- if ( pTFrame->id == 0 )
- break;
- if ( nFrame == gQAV->nFrames )
- gQAV->nFrames++;
- isModified = TRUE;
- break;
- }
- case KEY_X:
- if ( pTFrame->id > 0 )
- {
- pTFrame->flags ^= kQFrameXFlip;
- isModified = TRUE;
- }
- break;
- case KEY_Y:
- if ( pTFrame->id > 0 )
- {
- pTFrame->flags ^= kQFrameYFlip;
- isModified = TRUE;
- }
- break;
- case KEY_COMMA:
- if ( pTFrame->id > 0 )
- {
- int step = shift ? 4 : 128;
- pTFrame->angle = (short)(DecNext(pTFrame->angle, step) & kAngleMask);
- isModified = TRUE;
- }
- break;
- case KEY_PERIOD:
- if ( pTFrame->id > 0 )
- {
- int step = shift ? 4 : 128;
- pTFrame->angle = (short)(IncNext(pTFrame->angle, step) & kAngleMask);
- isModified = TRUE;
- }
- break;
- case KEY_PADSLASH:
- if ( pTFrame->id > 0 )
- {
- int step = shift ? 0x100 : 0x1000;
- pTFrame->zoom = pTFrame->zoom + step;
- isModified = TRUE;
- }
- break;
- case KEY_PADSTAR:
- if ( pTFrame->id > 0 )
- {
- int step = shift ? 0x100 : 0x1000;
- pTFrame->zoom = ClipLow(pTFrame->zoom - step, step);
- isModified = TRUE;
- }
- break;
- case KEY_PADPLUS:
- if ( pTFrame->id > 0 )
- {
- if ( ctrl )
- pTFrame->shade = -128;
- else
- pTFrame->shade = (schar)ClipLow( pTFrame->shade - 1, -128 );
- isModified = TRUE;
- }
- break;
- case KEY_PADMINUS:
- if ( pTFrame->id > 0 )
- {
- if ( ctrl )
- pTFrame->shade = 127;
- else
- pTFrame->shade = (schar)ClipHigh( pTFrame->shade + 1, 127 );
- isModified = TRUE;
- }
- break;
- case KEY_PAD0:
- if ( pTFrame->id > 0 )
- {
- pTFrame->shade = 0;
- isModified = TRUE;
- }
- break;
- case KEY_UP:
- SetBlinkOff();
- if ( keystatus[KEY_O] )
- {
- gQAV->SetOrigin(gQAV->origin.x, gQAV->origin.y - 1);
- isModified = TRUE;
- break;
- }
- if ( pTFrame->id > 0 )
- {
- pTFrame->y--;
- isModified = TRUE;
- }
- break;
- case KEY_DOWN:
- SetBlinkOff();
- if ( keystatus[KEY_O] )
- {
- gQAV->SetOrigin(gQAV->origin.x, gQAV->origin.y + 1);
- isModified = TRUE;
- break;
- }
- if ( pTFrame->id > 0 )
- {
- pTFrame->y++;
- isModified = TRUE;
- }
- break;
- case KEY_LEFT:
- SetBlinkOff();
- if ( keystatus[KEY_O] )
- {
- gQAV->SetOrigin(gQAV->origin.x - 1, gQAV->origin.y);
- isModified = TRUE;
- break;
- }
- if ( pTFrame->id > 0 )
- {
- pTFrame->x--;
- isModified = TRUE;
- }
- break;
- case KEY_RIGHT:
- SetBlinkOff();
- if ( keystatus[KEY_O] )
- {
- gQAV->SetOrigin(gQAV->origin.x + 1, gQAV->origin.y);
- isModified = TRUE;
- break;
- }
- if ( pTFrame->id > 0 )
- {
- pTFrame->x++;
- isModified = TRUE;
- }
- break;
- }
- Mouse::Read(gFrameTicks);
- // which buttons just got pressed
- nbuttons = (short)(~obuttons & Mouse::buttons);
- obuttons = Mouse::buttons;
- if ( Mouse::buttons & 1 )
- {
- if ( keystatus[KEY_O] )
- {
- gQAV->SetOrigin(gQAV->origin.x + Mouse::dX2, gQAV->origin.y + Mouse::dY2);
- isModified = TRUE;
- }
- else
- {
- SetBlinkOff();
- if ( pTFrame->id > 0 )
- {
- pTFrame->x += Mouse::dX2;
- pTFrame->y += Mouse::dY2;
- isModified = TRUE;
- }
- }
- }
- // make sure x and y don't cause the tile to go off screen
- if ( pTFrame->id > 0 )
- gQAV->ClipTileFrame(pTFrame);
- }
- }
- 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 ConvertWildcards(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 the file list
- for (FNODE *n = head.next; n != &head; n = n->next)
- {
- strcpy(gQAVName, n->name);
- printf("Converting: %s\n", n->name);
- LoadQAV();
- SaveQAV();
- }
- }
- /***********************************************************************
- * Process command line arguments
- **********************************************************************/
- void ParseOptions( void )
- {
- enum {
- kSwitchHelp,
- kSwitchConvert,
- };
- static SWITCH switches[] = {
- { "?", kSwitchHelp, FALSE },
- { "C", kSwitchConvert, TRUE },
- { NULL, 0, FALSE },
- };
- int r;
- while ( (r = GetOptions(switches)) != GO_EOF )
- {
- switch (r)
- {
- case GO_INVALID:
- QuitMessage("Invalid argument: %s", OptArgument);
- case GO_FULL:
- strcpy(gQAVName, OptArgument);
- break;
- case kSwitchHelp:
- ShowUsage();
- break;
- case kSwitchConvert:
- ConvertWildcards(OptArgument);
- exit(0);
- }
- }
- }
- void main( void )
- {
- ShowBanner();
- gOldDisplayMode = getvmode();
- if ( _grow_handles(kRequiredFiles) < kRequiredFiles )
- ThrowError("Not enough file handles available", ES_ERROR);
- gGamma = BloodINI.GetKeyInt("View", "Gamma", 0);
- Resource::heap = new QHeap(dpmiDetermineMaxRealAlloc());
- gQAV = (EditQAV *)Resource::Alloc(sizeof(EditQAV) + kMaxFrames * sizeof(FRAME));
- dassert(gQAV != NULL);
- ParseOptions();
- gSysRes.Init("BLOOD.RFF", "*.*");
- gGuiRes.Init("GUI.RFF", NULL);
- if ( !initmouse() )
- QuitMessage("Mouse not detected");
- // install our error handler
- prevErrorHandler = errSetHandler(EditorErrorHandler);
- InitEngine(1, 640, 400);
- Mouse::SetRange(xdim, ydim);
- if (tileInit() == 0)
- ThrowError("ART files not found", ES_ERROR);
- scrInit();
- keyInstall();
- scrCreateStdColors();
- timerRegisterClient(ClockStrobe, kTimerRate);
- timerInstall();
- scrSetGameMode();
- scrSetGamma(gGamma);
- scrSetDac(0);
- isModified = FALSE;
- if ( strlen(gQAVName) > 0 )
- LoadQAV();
- else
- {
- gQAV->nFrames = 0;
- gQAV->ticksPerFrame = 5;
- gQAV->duration = 0;
- gQAV->origin.x = 160;
- gQAV->origin.y = 100;
- memset(&gQAV->frame[0], 0, sizeof(FRAME) * kMaxFrames);
- }
- EditLoop();
- setvmode(gOldDisplayMode);
- dprintf("Removing timer\n");
- timerRemove();
- dprintf("uninitengine()\n");
- uninitengine();
- dprintf("All subsystems shut down. Processing exit functions\n");
- errSetHandler(prevErrorHandler);
- }
|