diff options
-rw-r--r-- | kyra/kyra.cpp | 30 | ||||
-rw-r--r-- | kyra/kyra.h | 25 | ||||
-rw-r--r-- | kyra/script_v1.cpp | 49 | ||||
-rwxr-xr-x | kyra/seqplayer.cpp | 30 | ||||
-rwxr-xr-x | kyra/seqplayer.h | 2 | ||||
-rw-r--r-- | kyra/wsamovie.cpp | 166 | ||||
-rw-r--r-- | kyra/wsamovie.h | 66 |
7 files changed, 219 insertions, 149 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index b4b58a2880..ca90fa940f 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -339,7 +339,10 @@ int KyraEngine::init(GameDetector &detector) { _debugger = new Debugger(this); assert(_debugger); memset(_shapes, 0, sizeof(_shapes)); - memset(_wsaObjects, 0, sizeof(_wsaObjects)); + + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + _movieObjects[i] = createWSAMovie(); + } memset(_flagsTable, 0, sizeof(_flagsTable)); @@ -407,6 +410,9 @@ int KyraEngine::init(GameDetector &detector) { } KyraEngine::~KyraEngine() { + _scriptInterpreter->unloadScript(_npcScriptData); + _scriptInterpreter->unloadScript(_scriptClickData); + delete _debugger; delete _sprites; delete _screen; @@ -437,6 +443,7 @@ KyraEngine::~KyraEngine() { for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { if (_shapes[i] != 0) { free(_shapes[i]); + _shapes[i] = 0; for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { if (_shapes[i2] == _shapes[i] && i2 != i) { _shapes[i2] = 0; @@ -695,8 +702,11 @@ void KyraEngine::mainLoop() { void KyraEngine::quitGame() { res_unloadResources(); - for (int i = 0; i < 10; i++) - wsa_close(_wsaObjects[i]); + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + _movieObjects[i]->close(); + delete _movieObjects[i]; + _movieObjects[i] = 0; + } _system->quit(); } @@ -708,9 +718,9 @@ void KyraEngine::loadPalette(const char *filename, uint8 *palData) { if (palData && fileSize) { debug(9, "Loading a palette of size %i from '%s'", fileSize, filename); - memcpy(palData, srcData, fileSize); + memcpy(palData, srcData, fileSize); } - delete[] srcData; + delete [] srcData; } void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) { @@ -1887,9 +1897,8 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int moveCharacterToPos(0, facing, xpos, ypos); } - for (int i = 0; i < 10; ++i) { - wsa_close(_wsaObjects[i]); - _wsaObjects[i] = 0; + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + _movieObjects[i]->close(); } if (!brandonAlive) { @@ -4837,6 +4846,11 @@ AnimObject *KyraEngine::objectQueue(AnimObject *queue, AnimObject *add) { #pragma mark - Misc stuff #pragma mark - +Movie *KyraEngine::createWSAMovie() { + // for kyra2 here could be added then WSAMovieV2 + return new WSAMovieV1(this); +} + int16 KyraEngine::fetchAnimWidth(const uint8 *shape, int16 mult) { debug(9, "fetchAnimWidth(0x%X, %d)", shape, mult); if (_features & GF_TALKIE) diff --git a/kyra/kyra.h b/kyra/kyra.h index 57d621ab85..6cdf4a1116 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -131,7 +131,7 @@ struct SceneExits { uint8 westYPos; }; -struct WSAMovieV1; +class Movie; class MusicPlayer; class SeqPlayer; @@ -202,6 +202,7 @@ public: Resource *resource() { return _res; } Screen *screen() { return _screen; } MusicPlayer *midi() { return _midi; } + Movie *createWSAMovie(); uint8 game() const { return _game; } uint32 features() const { return _features; } @@ -215,13 +216,13 @@ public: typedef void (KyraEngine::*IntroProc)(); typedef int (KyraEngine::*OpcodeProc)(ScriptState *script); - const char **seqWSATable() { return (const char **)_seq_WSATable; } - const char **seqCPSTable() { return (const char **)_seq_CPSTable; } - const char **seqCOLTable() { return (const char **)_seq_COLTable; } - const char **seqTextsTable() { return (const char **)_seq_textsTable; } + const char **seqWSATable() { return const_cast<const char **>(_seq_WSATable); } + const char **seqCPSTable() { return const_cast<const char **>(_seq_CPSTable); } + const char **seqCOLTable() { return const_cast<const char **>(_seq_COLTable); } + const char **seqTextsTable() { return const_cast<const char **>(_seq_textsTable); } - const uint8 **palTable1() { return (const uint8 **)&_specialPalettes[0]; } - const uint8 **palTable2() { return (const uint8 **)&_specialPalettes[29]; } + const uint8 **palTable1() { return const_cast<const uint8 **>(&_specialPalettes[0]); } + const uint8 **palTable2() { return const_cast<const uint8 **>(&_specialPalettes[29]); } bool seq_skipSequence() const; void quitGame(); @@ -247,11 +248,6 @@ public: void enableTimer(uint8 timer); void disableTimer(uint8 timer); - WSAMovieV1 *wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf); - void wsa_close(WSAMovieV1 *wsa); - uint16 wsa_getNumFrames(WSAMovieV1 *wsa) const; - void wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum); - void waitTicks(int ticks); void delayWithTicks(int ticks); void updateAllObjectShapes(); @@ -576,8 +572,6 @@ protected: void seq_fillFlaskWithWater(int item, int type); void seq_playDrinkPotionAnim(int unk1, int unk2, int flags); - void wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst); - void snd_startTrack(); void snd_haltTrack(); void snd_setSoundEffectFile(int file); @@ -669,7 +663,8 @@ protected: int _brandonAnimSeqSizeWidth; int _brandonAnimSeqSizeHeight; - WSAMovieV1 *_wsaObjects[10]; + Movie *_movieObjects[10]; + uint16 _entranceMouseCursorTracks[8]; uint16 _walkBlockNorth; uint16 _walkBlockEast; diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp index d9906dc06b..e8c078faf0 100644 --- a/kyra/script_v1.cpp +++ b/kyra/script_v1.cpp @@ -24,6 +24,7 @@ #include "kyra/script.h" #include "kyra/screen.h" #include "kyra/sprites.h" +#include "kyra/wsamovie.h" #include "common/system.h" namespace Kyra { @@ -678,8 +679,8 @@ int KyraEngine::cmd_openWSAFile(ScriptState *script) { char *filename = stackPosString(0); int wsaIndex = stackPos(1); - _wsaObjects[wsaIndex] = wsa_open(filename, 1, 0); - assert(_wsaObjects[wsaIndex]); + _movieObjects[wsaIndex]->open(filename, 1, 0); + assert(_movieObjects[wsaIndex]->opened()); return 0; } @@ -688,9 +689,8 @@ int KyraEngine::cmd_closeWSAFile(ScriptState *script) { debug(3, "cmd_closeWSAFile(0x%X) (%d)", script, stackPos(0)); int wsaIndex = stackPos(0); - if (_wsaObjects[wsaIndex]) { - wsa_close(_wsaObjects[wsaIndex]); - _wsaObjects[wsaIndex] = 0; + if (_movieObjects[wsaIndex]) { + _movieObjects[wsaIndex]->close(); } return 0; @@ -710,10 +710,13 @@ int KyraEngine::cmd_runWSAFromBeginningToEnd(ScriptState *script) { int worldUpdate = stackPos(4); int wsaFrame = 0; + _movieObjects[wsaIndex]->_x = xpos; + _movieObjects[wsaIndex]->_y = ypos; + _movieObjects[wsaIndex]->_drawPage = 0; while (running) { - wsa_play(_wsaObjects[wsaIndex], wsaFrame++, xpos, ypos, 0); + _movieObjects[wsaIndex]->displayFrame(wsaFrame++); _updateScreen = true; - if (wsaFrame >= wsa_getNumFrames(_wsaObjects[wsaIndex])) + if (wsaFrame >= _movieObjects[wsaIndex]->frames()) running = false; uint32 continueTime = waitTime * _tickLength + _system->getMillis(); @@ -741,7 +744,10 @@ int KyraEngine::cmd_displayWSAFrame(ScriptState *script) { int waitTime = stackPos(3); int wsaIndex = stackPos(4); _screen->hideMouse(); - wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0); + _movieObjects[wsaIndex]->_x = xpos; + _movieObjects[wsaIndex]->_y = ypos; + _movieObjects[wsaIndex]->_drawPage = 0; + _movieObjects[wsaIndex]->displayFrame(frame); uint32 continueTime = waitTime * _tickLength + _system->getMillis(); while (_system->getMillis() < continueTime) { _sprites->updateSceneAnims(); @@ -944,7 +950,10 @@ int KyraEngine::cmd_displayWSAFrameOnHidPage(ScriptState *script) { int wsaIndex = stackPos(4); _screen->hideMouse(); - wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 2); + _movieObjects[wsaIndex]->_x = xpos; + _movieObjects[wsaIndex]->_y = ypos; + _movieObjects[wsaIndex]->_drawPage = 2; + _movieObjects[wsaIndex]->displayFrame(frame); uint32 continueTime = waitTime * _tickLength + _system->getMillis(); while (_system->getMillis() < continueTime) { _sprites->updateSceneAnims(); @@ -967,14 +976,18 @@ int KyraEngine::cmd_displayWSASequentialFrames(ScriptState *script) { int maxTime = stackPos(6); if (maxTime - 1 <= 0) maxTime = 1; - + + _movieObjects[wsaIndex]->_x = xpos; + _movieObjects[wsaIndex]->_y = ypos; + _movieObjects[wsaIndex]->_drawPage = 0; + int curTime = 0; _screen->hideMouse(); while (curTime < maxTime) { if (endFrame >= startFrame) { int frame = startFrame; while (endFrame >= frame) { - wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0); + _movieObjects[wsaIndex]->displayFrame(frame); _updateScreen = true; uint32 continueTime = waitTime * _tickLength + _system->getMillis(); while (_system->getMillis() < continueTime) { @@ -988,7 +1001,7 @@ int KyraEngine::cmd_displayWSASequentialFrames(ScriptState *script) { } else { int frame = startFrame; while (endFrame <= frame) { - wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0); + _movieObjects[wsaIndex]->displayFrame(frame); _updateScreen = true; uint32 continueTime = waitTime * _tickLength + _system->getMillis(); while (_system->getMillis() < continueTime) { @@ -1448,8 +1461,12 @@ int KyraEngine::cmd_drinkPotionAnimation(ScriptState *script) { int KyraEngine::cmd_makeAmuletAppear(ScriptState *script) { debug(3, "cmd_makeAmuletAppear(0x%X) ()", script); - WSAMovieV1 *amulet = wsa_open("AMULET.WSA", 1, 0); - if (amulet) { + WSAMovieV1 amulet(this); + amulet.open("AMULET.WSA", 1, 0); + amulet._drawPage = 0; + amulet._x = 224; + amulet._y = 152; + if (amulet.opened()) { assert(_amuleteAnim); _screen->hideMouse(); // snd_kyraPlaySound(0x70); @@ -1470,7 +1487,8 @@ int KyraEngine::cmd_makeAmuletAppear(ScriptState *script) { // snd_kyraPlaySound(0x73); } - wsa_play(amulet, code, 224, 152, 0); + + amulet.displayFrame(code); _updateScreen = true; while (_system->getMillis() < nextTime) { @@ -1480,7 +1498,6 @@ int KyraEngine::cmd_makeAmuletAppear(ScriptState *script) { } _screen->showMouse(); } - wsa_close(amulet); setGameFlag(0x2D); return 0; } diff --git a/kyra/seqplayer.cpp b/kyra/seqplayer.cpp index 8f88f175e4..6cd2b97aae 100755 --- a/kyra/seqplayer.cpp +++ b/kyra/seqplayer.cpp @@ -28,6 +28,7 @@ #include "kyra/resource.h" #include "kyra/screen.h" #include "kyra/sound.h" +#include "kyra/wsamovie.h" #include "kyra/seqplayer.h" @@ -51,6 +52,12 @@ SeqPlayer::SeqPlayer(KyraEngine* vm, OSystem* system) { SeqPlayer::~SeqPlayer() { freeHandShapes(); + + for (int i = 0; i < ARRAYSIZE(_seqMovies); ++i) { + _seqMovies[i].movie->close(); + delete _seqMovies[i].movie; + _seqMovies[i].movie = 0; + } } uint8 *SeqPlayer::setPanPages(int pageNum, int shape) { @@ -81,6 +88,8 @@ void SeqPlayer::makeHandShapes() { debug(9, "SeqPlayer::makeHandShapes()"); _vm->loadBitmap("WRITING.CPS", 3, 3, 0); for (int i = 0; i < ARRAYSIZE(_handShapes); ++i) { + if (_handShapes[i]) + free(_handShapes[i]); _handShapes[i] = setPanPages(3, i); } } @@ -98,17 +107,19 @@ void SeqPlayer::s1_wsaOpen() { assert(wsaObj < ARRAYSIZE(_seqMovies)); uint8 offscreenDecode = *_seqData++; _seqWsaCurDecodePage = _seqMovies[wsaObj].page = (offscreenDecode == 0) ? 0 : 3; - _seqMovies[wsaObj].wsa = _vm->wsa_open(_vm->seqWSATable()[wsaObj], offscreenDecode, 0); + if (!_seqMovies[wsaObj].movie) + _seqMovies[wsaObj].movie = _vm->createWSAMovie(); + _seqMovies[wsaObj].movie->_drawPage = _seqMovies[wsaObj].page; + _seqMovies[wsaObj].movie->open(_vm->seqWSATable()[wsaObj], offscreenDecode, 0); _seqMovies[wsaObj].frame = 0; - _seqMovies[wsaObj].numFrames = _vm->wsa_getNumFrames(_seqMovies[wsaObj].wsa) - 1; + _seqMovies[wsaObj].numFrames = _seqMovies[wsaObj].movie->frames() - 1; } void SeqPlayer::s1_wsaClose() { uint8 wsaObj = *_seqData++; assert(wsaObj < ARRAYSIZE(_seqMovies)); - if (_seqMovies[wsaObj].wsa) { - _vm->wsa_close(_seqMovies[wsaObj].wsa); - _seqMovies[wsaObj].wsa = 0; + if (_seqMovies[wsaObj].movie) { + _seqMovies[wsaObj].movie->close(); } } @@ -118,7 +129,10 @@ void SeqPlayer::s1_wsaPlayFrame() { int16 frame = (int8)*_seqData++; _seqMovies[wsaObj].pos.x = READ_LE_UINT16(_seqData); _seqData += 2; _seqMovies[wsaObj].pos.y = *_seqData++; - _vm->wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); + assert(_seqMovies[wsaObj].movie); + _seqMovies[wsaObj].movie->_x = _seqMovies[wsaObj].pos.x; + _seqMovies[wsaObj].movie->_y = _seqMovies[wsaObj].pos.y; + _seqMovies[wsaObj].movie->displayFrame(frame); _seqMovies[wsaObj].frame = frame; } @@ -130,7 +144,7 @@ void SeqPlayer::s1_wsaPlayNextFrame() { frame = 0; _seqMovies[wsaObj].frame = 0; } - _vm->wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); + _seqMovies[wsaObj].movie->displayFrame(frame); } void SeqPlayer::s1_wsaPlayPrevFrame() { @@ -141,7 +155,7 @@ void SeqPlayer::s1_wsaPlayPrevFrame() { frame = _seqMovies[wsaObj].numFrames; _seqMovies[wsaObj].frame = frame; } else { - _vm->wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); + _seqMovies[wsaObj].movie->displayFrame(frame); } } diff --git a/kyra/seqplayer.h b/kyra/seqplayer.h index fd16e9526d..5db5dd0525 100755 --- a/kyra/seqplayer.h +++ b/kyra/seqplayer.h @@ -95,7 +95,7 @@ protected: void s1_prefetchVocFile(); struct SeqMovie { - WSAMovieV1 *wsa; + Movie *movie; int32 page; int16 frame; int16 numFrames; diff --git a/kyra/wsamovie.cpp b/kyra/wsamovie.cpp index 909e457b20..8c8141b993 100644 --- a/kyra/wsamovie.cpp +++ b/kyra/wsamovie.cpp @@ -26,64 +26,67 @@ namespace Kyra { +WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {} +WSAMovieV1::~WSAMovieV1() { close(); } + +void WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { + debug(9, "WSAMovieV1::open('%s', %d, 0x%X)", filename, offscreenDecode, palBuf); + close(); -WSAMovieV1 *KyraEngine::wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf) { - debug(9, "KyraEngine::wsa_open('%s', %d, 0x%X)", filename, offscreenDecode, palBuf); uint32 flags = 0; uint32 fileSize; - uint8 *p = _res->fileData(filename, &fileSize); + uint8 *p = _vm->resource()->fileData(filename, &fileSize); assert(p); - WSAMovieV1 *wsa = new WSAMovieV1; const uint8 *wsaData = p; - wsa->numFrames = READ_LE_UINT16(wsaData); wsaData += 2; - wsa->width = READ_LE_UINT16(wsaData); wsaData += 2; - wsa->height = READ_LE_UINT16(wsaData); wsaData += 2; - wsa->deltaBufferSize = READ_LE_UINT16(wsaData); wsaData += 2; - wsa->offscreenBuffer = NULL; - wsa->flags = 0; - if (_features & GF_TALKIE) { + _numFrames = READ_LE_UINT16(wsaData); wsaData += 2; + _width = READ_LE_UINT16(wsaData); wsaData += 2; + _height = READ_LE_UINT16(wsaData); wsaData += 2; + _deltaBufferSize = READ_LE_UINT16(wsaData); wsaData += 2; + _offscreenBuffer = NULL; + _flags = 0; + if (_vm->features() & GF_TALKIE) { flags = READ_LE_UINT16(wsaData); wsaData += 2; } uint32 offsPal = 0; if (flags & 1) { offsPal = 0x300; - wsa->flags |= WF_HAS_PALETTE; + _flags |= WF_HAS_PALETTE; if (palBuf) { - memcpy(palBuf, wsaData + (wsa->numFrames + 2) * 4, 0x300); + memcpy(palBuf, wsaData + (_numFrames + 2) * 4, 0x300); } } if (offscreenDecode) { - wsa->flags |= WF_OFFSCREEN_DECODE; - const int offscreenBufferSize = wsa->width * wsa->height; - wsa->offscreenBuffer = (uint8 *)malloc(offscreenBufferSize); - memset(wsa->offscreenBuffer, 0, offscreenBufferSize); + _flags |= WF_OFFSCREEN_DECODE; + const int offscreenBufferSize = _width * _height; + _offscreenBuffer = new uint8[offscreenBufferSize]; + memset(_offscreenBuffer, 0, offscreenBufferSize); } - if (wsa->numFrames & 0x8000) { + if (_numFrames & 0x8000) { warning("Unhandled wsa flags 0x80"); - wsa->flags |= 0x80; - wsa->numFrames &= 0x7FFF; + _flags |= 0x80; + _numFrames &= 0x7FFF; } - wsa->currentFrame = wsa->numFrames; + _currentFrame = _numFrames; - wsa->deltaBuffer = (uint8 *)malloc(wsa->deltaBufferSize); - memset(wsa->deltaBuffer, 0, wsa->deltaBufferSize); + _deltaBuffer = new uint8[_deltaBufferSize]; + memset(_deltaBuffer, 0, _deltaBufferSize); // read frame offsets - wsa->frameOffsTable = (uint32 *)malloc((wsa->numFrames + 2) * 4); - wsa->frameOffsTable[0] = 0; + _frameOffsTable = new uint32[_numFrames + 2]; + _frameOffsTable[0] = 0; uint32 frameDataOffs = READ_LE_UINT32(wsaData); wsaData += 4; bool firstFrame = true; if (frameDataOffs == 0) { firstFrame = false; frameDataOffs = READ_LE_UINT32(wsaData); - wsa->flags |= WF_NO_FIRST_FRAME; + _flags |= WF_NO_FIRST_FRAME; } - for (int i = 1; i < wsa->numFrames + 2; ++i) { - wsa->frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs; + for (int i = 1; i < _numFrames + 2; ++i) { + _frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs; wsaData += 4; } @@ -92,75 +95,67 @@ WSAMovieV1 *KyraEngine::wsa_open(const char *filename, int offscreenDecode, uint // read frame data const int frameDataSize = p + fileSize - wsaData; - wsa->frameData = (uint8 *)malloc(frameDataSize); - memcpy(wsa->frameData, wsaData, frameDataSize); + _frameData = new uint8[frameDataSize]; + memcpy(_frameData, wsaData, frameDataSize); // decode first frame if (firstFrame) { - Screen::decodeFrame4(wsa->frameData, wsa->deltaBuffer, wsa->deltaBufferSize); + Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize); } - delete[] p; - return wsa; -} - -void KyraEngine::wsa_close(WSAMovieV1 *wsa) { - debug(9, "KyraEngine::wsa_close(0x%X)", wsa); - if (wsa) { - free(wsa->deltaBuffer); - free(wsa->offscreenBuffer); - free(wsa->frameOffsTable); - delete wsa; - } + delete [] p; + _opened = true; } -uint16 KyraEngine::wsa_getNumFrames(WSAMovieV1 *wsa) const { - debug(9, "KyraEngine::wsa_getNumFrames(0x%X)", wsa); - uint16 n = 0; - if (wsa) { - n = wsa->numFrames; +void WSAMovieV1::close() { + debug(9, "WSAMovieV1::close()"); + if (_opened) { + delete [] _deltaBuffer; + delete [] _offscreenBuffer; + delete [] _frameOffsTable; + delete [] _frameData; + _opened = false; } - return n; } -void KyraEngine::wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum) { - debug(9, "KyraEngine::wsa_play(0x%X, %d, %d, %d, %d)", wsa, frameNum, x, y, pageNum); - if (frameNum > wsa->numFrames) +void WSAMovieV1::displayFrame(int frameNum) { + debug(9, "WSAMovieV1::displayFrame(%d)", frameNum); + if (frameNum > _numFrames || !_opened) return; uint8 *dst; - if (wsa->flags & WF_OFFSCREEN_DECODE) { - dst = wsa->offscreenBuffer; + if (_flags & WF_OFFSCREEN_DECODE) { + dst = _offscreenBuffer; } else { - dst = _screen->getPagePtr(pageNum) + y * Screen::SCREEN_W + x; + dst = _vm->screen()->getPagePtr(_drawPage) + _y * Screen::SCREEN_W + _x; } - if (wsa->currentFrame == wsa->numFrames) { - if (!(wsa->flags & WF_OFFSCREEN_DECODE) && (_features & GF_TALKIE)) - _screen->clearPage(pageNum); - if (!(wsa->flags & WF_NO_FIRST_FRAME)) { - if (wsa->flags & WF_OFFSCREEN_DECODE) { - Screen::decodeFrameDelta(dst, wsa->deltaBuffer); + if (_currentFrame == _numFrames) { + if (!(_flags & WF_OFFSCREEN_DECODE) && (_vm->features() & GF_TALKIE)) + _vm->screen()->clearPage(_drawPage); + if (!(_flags & WF_NO_FIRST_FRAME)) { + if (_flags & WF_OFFSCREEN_DECODE) { + Screen::decodeFrameDelta(dst, _deltaBuffer); } else { - Screen::decodeFrameDeltaPage(dst, wsa->deltaBuffer, wsa->width); + Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width); } } - wsa->currentFrame = 0; + _currentFrame = 0; } // try to reduce the number of needed frame operations - int diffCount = ABS(wsa->currentFrame - frameNum); + int diffCount = ABS(_currentFrame - frameNum); int frameStep = 1; int frameCount; - if (wsa->currentFrame < frameNum) { - frameCount = wsa->numFrames - frameNum + wsa->currentFrame; + if (_currentFrame < frameNum) { + frameCount = _numFrames - frameNum + _currentFrame; if (diffCount > frameCount) { frameStep = -1; } else { frameCount = diffCount; } } else { - frameCount = wsa->numFrames - wsa->currentFrame + frameNum; + frameCount = _numFrames - _currentFrame + frameNum; if (frameCount >= diffCount) { frameStep = -1; frameCount = diffCount; @@ -169,42 +164,43 @@ void KyraEngine::wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageN // process if (frameStep > 0) { - uint16 cf = wsa->currentFrame; + uint16 cf = _currentFrame; while (frameCount--) { cf += frameStep; - wsa_processFrame(wsa, cf, dst); - if (cf == wsa->numFrames) { + processFrame(cf, dst); + if (cf == _numFrames) { cf = 0; } } } else { - uint16 cf = wsa->currentFrame; + uint16 cf = _currentFrame; while (frameCount--) { if (cf == 0) { - cf = wsa->numFrames; + cf = _numFrames; } - wsa_processFrame(wsa, cf, dst); + processFrame(cf, dst); cf += frameStep; } } // display - wsa->currentFrame = frameNum; - if (wsa->flags & WF_OFFSCREEN_DECODE) { - _screen->copyBlockToPage(pageNum, x, y, wsa->width, wsa->height, wsa->offscreenBuffer); + _currentFrame = frameNum; + if (_flags & WF_OFFSCREEN_DECODE) { + _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); } } -void KyraEngine::wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst) { - debug(9, "KyraEngine::wsa_processFrame(0x%X, %d, 0x%X)", wsa, frameNum, dst); - assert(frameNum <= wsa->numFrames); - const uint8 *src = wsa->frameData + wsa->frameOffsTable[frameNum]; - Screen::decodeFrame4(src, wsa->deltaBuffer, wsa->deltaBufferSize); - if (wsa->flags & WF_OFFSCREEN_DECODE) { - Screen::decodeFrameDelta(dst, wsa->deltaBuffer); +void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { + debug(9, "WSAMovieV1::processFrame(%d, 0x%X)", frameNum, dst); + if (!_opened) + return; + assert(frameNum <= _numFrames); + const uint8 *src = _frameData + _frameOffsTable[frameNum]; + Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize); + if (_flags & WF_OFFSCREEN_DECODE) { + Screen::decodeFrameDelta(dst, _deltaBuffer); } else { - Screen::decodeFrameDeltaPage(dst, wsa->deltaBuffer, wsa->width); + Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width); } } - } // end of namespace Kyra diff --git a/kyra/wsamovie.h b/kyra/wsamovie.h index ed0cb6bb96..b151306756 100644 --- a/kyra/wsamovie.h +++ b/kyra/wsamovie.h @@ -25,26 +25,60 @@ #include "kyra/resource.h" namespace Kyra { +class KyraEngine; -enum WSAFlags { - WF_OFFSCREEN_DECODE = 0x10, - WF_NO_FIRST_FRAME = 0x40, - WF_HAS_PALETTE = 0x100 -}; +class Movie { +public: + Movie(KyraEngine *vm) : _x(-1), _y(-1), _drawPage(-1), _vm(vm), _opened(false) {} + virtual ~Movie() {} + + virtual bool opened() { return _opened; } + + virtual void open(const char *filename, int offscreen, uint8 *palette) = 0; + virtual void close() = 0; -struct WSAMovieV1 { - uint16 currentFrame; - uint16 numFrames; - uint16 width; - uint16 height; - uint16 flags; - uint8 *deltaBuffer; - uint32 deltaBufferSize; - uint8 *offscreenBuffer; - uint32 *frameOffsTable; - uint8 *frameData; + virtual int frames() = 0; + + virtual void displayFrame(int frameNum) = 0; + + int _x, _y; + int _drawPage; +protected: + KyraEngine *_vm; + bool _opened; }; +class WSAMovieV1 : public Movie { +public: + WSAMovieV1(KyraEngine *vm); + virtual ~WSAMovieV1(); + + virtual void open(const char *filename, int offscreen, uint8 *palette); + virtual void close(); + + virtual int frames() { return _opened ? _numFrames : -1; } + + virtual void displayFrame(int frameNum); +protected: + virtual void processFrame(int frameNum, uint8 *dst); + + enum WSAFlags { + WF_OFFSCREEN_DECODE = 0x10, + WF_NO_FIRST_FRAME = 0x40, + WF_HAS_PALETTE = 0x100 + }; + + uint16 _currentFrame; + uint16 _numFrames; + uint16 _width; + uint16 _height; + uint16 _flags; + uint8 *_deltaBuffer; + uint32 _deltaBufferSize; + uint8 *_offscreenBuffer; + uint32 *_frameOffsTable; + uint8 *_frameData; +}; } // end of namespace Kyra #endif |