From c8aa32d095b76c0ba443d16714b32d9cf4cea1fa Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 16 May 2006 16:04:24 +0000 Subject: - implements kyrandia 3 wsa loader - fixes initalisation problems - adds setX, setY, setDrawPage to Kyra::Movie instead of directly accessing _x, _y and _drawPage svn-id: r22490 --- engines/kyra/kyra.cpp | 6 ++-- engines/kyra/kyra.h | 8 +++-- engines/kyra/kyra3.cpp | 20 ++++++++--- engines/kyra/resource.cpp | 2 +- engines/kyra/script_v1.cpp | 36 ++++++++++---------- engines/kyra/seqplayer.cpp | 6 ++-- engines/kyra/sequences_v1.cpp | 52 ++++++++++++++--------------- engines/kyra/staticres.cpp | 5 ++- engines/kyra/wsamovie.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++ engines/kyra/wsamovie.h | 28 ++++++++++++++-- 10 files changed, 181 insertions(+), 60 deletions(-) (limited to 'engines') diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index 2269f1f751..186faaacc4 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -95,6 +95,7 @@ KyraEngine::KyraEngine(OSystem *system) _scrollUpButton.process0PtrShape = _scrollUpButton.process1PtrShape = _scrollUpButton.process2PtrShape = 0; _scrollDownButton.process0PtrShape = _scrollDownButton.process1PtrShape = _scrollDownButton.process2PtrShape = 0; memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); + _features = 0; } KyraEngine_v1::KyraEngine_v1(OSystem *system) @@ -189,6 +190,7 @@ int KyraEngine::init() { _staticres = new StaticResource(this); assert(_staticres); assert(_staticres->init()); + initStaticResource(); _paletteChanged = 1; @@ -306,8 +308,8 @@ int KyraEngine::init() { _mousePressFlag = false; _menuDirectlyToLoad = false; - - _lastMusicCommand = 0; + + _lastMusicCommand = 0; _gameSpeed = 60; _tickLength = (uint8)(1000.0 / _gameSpeed); diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 2cfe4b437c..5dd689f516 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -261,7 +261,7 @@ public: Sound *sound() { return _sound; } StaticResource *staticres() { return _staticres; } uint32 tickLength() const { return _tickLength; } - Movie *createWSAMovie(); + virtual Movie *createWSAMovie(); uint8 game() const { return _game; } uint32 features() const { return _features; } @@ -479,8 +479,8 @@ public: protected: - int go(); - int init(); + virtual int go(); + virtual int init(); void startup(); void mainLoop(); @@ -1015,6 +1015,8 @@ class KyraEngine_v3 : public KyraEngine { public: KyraEngine_v3(OSystem *system); ~KyraEngine_v3(); + + Movie *createWSAMovie(); int setupGameFlags() { return 0; } diff --git a/engines/kyra/kyra3.cpp b/engines/kyra/kyra3.cpp index 4ac2810247..f1db8eaf10 100644 --- a/engines/kyra/kyra3.cpp +++ b/engines/kyra/kyra3.cpp @@ -34,6 +34,10 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system) : KyraEngine(system) { KyraEngine_v3::~KyraEngine_v3() { } +Movie *KyraEngine_v3::createWSAMovie() { + return new WSAMovieV3(this); +} + int KyraEngine_v3::go() { _screen->_curPage = 0; _screen->clearPage(0); @@ -42,8 +46,9 @@ int KyraEngine_v3::go() { assert(pal); memset(pal, 0, sizeof(byte)*768); - /*Movie *logo = createWSAMovie(); + Movie *logo = createWSAMovie(); logo->open("REVENGE.WSA", 1, pal); + assert(logo->opened()); pal[0] = pal[1] = pal[2] = 0; @@ -51,14 +56,21 @@ int KyraEngine_v3::go() { // XXX - logo->_x = logo->_y = 0; - logo->_drawPage = 0; + logo->setX(0); logo->setY(0); + logo->setDrawPage(0); for (int i = 0; i < 64; ++i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; logo->displayFrame(i); _screen->updateScreen(); delayUntil(nextRun); - }*/ + } + + for (int i = 64; i >= 29; --i) { + uint32 nextRun = _system->getMillis() + 3 * _tickLength; + logo->displayFrame(i); + _screen->updateScreen(); + delayUntil(nextRun); + } delete [] pal; diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 90fbdcf5a3..c708928b8b 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -114,7 +114,7 @@ Resource::Resource(KyraEngine *engine) { static const char *kyra3Filelist[] = { // enough for now - "ONETIME.PAK", 0 + "MISC_EMC.PAK", "MISC_CPS.PAK", "OTHER.PAK", "ONETIME.PAK", 0 }; const char **usedFilelist = 0; diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index f3e3acc2b1..ff1494b894 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -447,9 +447,9 @@ 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; + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); while (running) { _movieObjects[wsaIndex]->displayFrame(wsaFrame++); _animator->_updateScreen = true; @@ -482,9 +482,9 @@ int KyraEngine::cmd_displayWSAFrame(ScriptState *script) { int waitTime = stackPos(3); int wsaIndex = stackPos(4); _screen->hideMouse(); - _movieObjects[wsaIndex]->_x = xpos; - _movieObjects[wsaIndex]->_y = ypos; - _movieObjects[wsaIndex]->_drawPage = 0; + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); _movieObjects[wsaIndex]->displayFrame(frame); _animator->_updateScreen = true; uint32 continueTime = waitTime * _tickLength + _system->getMillis(); @@ -525,9 +525,9 @@ int KyraEngine::cmd_runWSAFrames(ScriptState *script) { int endFrame = stackPos(4); int wsaIndex = stackPos(5); _screen->hideMouse(); - _movieObjects[wsaIndex]->_x = xpos; - _movieObjects[wsaIndex]->_y = ypos; - _movieObjects[wsaIndex]->_drawPage = 0; + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); for (; startFrame <= endFrame; ++startFrame) { uint32 nextRun = _system->getMillis() + delayTime * _tickLength; _movieObjects[wsaIndex]->displayFrame(startFrame); @@ -722,9 +722,9 @@ int KyraEngine::cmd_displayWSAFrameOnHidPage(ScriptState *script) { _screen->hideMouse(); uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - _movieObjects[wsaIndex]->_x = xpos; - _movieObjects[wsaIndex]->_y = ypos; - _movieObjects[wsaIndex]->_drawPage = 2; + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(2); _movieObjects[wsaIndex]->displayFrame(frame); _animator->_updateScreen = true; while (_system->getMillis() < continueTime) { @@ -753,9 +753,9 @@ int KyraEngine::cmd_displayWSASequentialFrames(ScriptState *script) { if (maxTime - 1 <= 0) maxTime = 1; - _movieObjects[wsaIndex]->_x = xpos; - _movieObjects[wsaIndex]->_y = ypos; - _movieObjects[wsaIndex]->_drawPage = 0; + _movieObjects[wsaIndex]->setX(xpos); + _movieObjects[wsaIndex]->setY(ypos); + _movieObjects[wsaIndex]->setDrawPage(0); int curTime = 0; _screen->hideMouse(); @@ -1244,9 +1244,9 @@ int KyraEngine::cmd_makeAmuletAppear(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "cmd_makeAmuletAppear(%p) ()", (const void *)script); WSAMovieV1 amulet(this); amulet.open("AMULET.WSA", 1, 0); - amulet._drawPage = 0; - amulet._x = 224; - amulet._y = 152; + amulet.setX(224); + amulet.setY(152); + amulet.setDrawPage(0); if (amulet.opened()) { assert(_amuleteAnim); _screen->hideMouse(); diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index a7e206a998..a883f4cd70 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -116,7 +116,7 @@ void SeqPlayer::s1_wsaOpen() { _seqWsaCurDecodePage = _seqMovies[wsaObj].page = (offscreenDecode == 0) ? 0 : 3; if (!_seqMovies[wsaObj].movie) _seqMovies[wsaObj].movie = _vm->createWSAMovie(); - _seqMovies[wsaObj].movie->_drawPage = _seqMovies[wsaObj].page; + _seqMovies[wsaObj].movie->setDrawPage(_seqMovies[wsaObj].page); _seqMovies[wsaObj].movie->open(_vm->seqWSATable()[wsaObj], offscreenDecode, 0); _seqMovies[wsaObj].frame = 0; _seqMovies[wsaObj].numFrames = _seqMovies[wsaObj].movie->frames() - 1; @@ -137,8 +137,8 @@ void SeqPlayer::s1_wsaPlayFrame() { _seqMovies[wsaObj].pos.x = READ_LE_UINT16(_seqData); _seqData += 2; _seqMovies[wsaObj].pos.y = *_seqData++; assert(_seqMovies[wsaObj].movie); - _seqMovies[wsaObj].movie->_x = _seqMovies[wsaObj].pos.x; - _seqMovies[wsaObj].movie->_y = _seqMovies[wsaObj].pos.y; + _seqMovies[wsaObj].movie->setX(_seqMovies[wsaObj].pos.x); + _seqMovies[wsaObj].movie->setY(_seqMovies[wsaObj].pos.y); _seqMovies[wsaObj].movie->displayFrame(frame); _seqMovies[wsaObj].frame = frame; } diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp index 71378513db..08bb75b89f 100644 --- a/engines/kyra/sequences_v1.cpp +++ b/engines/kyra/sequences_v1.cpp @@ -946,8 +946,8 @@ int KyraEngine::seq_playEnd() { _finalA = new WSAMovieV1(this); assert(_finalA); _finalA->open("finald.wsa", 1, 0); - _finalA->_x = _finalA->_y = 8; - _finalA->_drawPage = 0; + _finalA->setX(8); _finalA->setY(8); + _finalA->setDrawPage(0); delayUntil(nextTime); snd_playSoundEffect(0x40); for (int i = 0; i < 22; ++i) { @@ -1172,9 +1172,9 @@ int KyraEngine::handleMalcolmFlag() { case 2: if (_system->getMillis() >= timer2) { - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1190,9 +1190,9 @@ int KyraEngine::handleMalcolmFlag() { if (_system->getMillis() < timer1) { if (_system->getMillis() >= timer2) { frame = _rnd.getRandomNumberRng(14, 17); - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1205,9 +1205,9 @@ int KyraEngine::handleMalcolmFlag() { case 4: if (_system->getMillis() >= timer2) { - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1222,9 +1222,9 @@ int KyraEngine::handleMalcolmFlag() { case 5: if (_system->getMillis() >= timer2) { - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1239,9 +1239,9 @@ int KyraEngine::handleMalcolmFlag() { case 6: if (_unkEndSeqVar4) { if (frame <= 33 && _system->getMillis() >= timer2) { - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1267,9 +1267,9 @@ int KyraEngine::handleMalcolmFlag() { case 8: if (_system->getMillis() >= timer2) { - _finalA->_x = 8; - _finalA->_y = 46; - _finalA->_drawPage = 0; + _finalA->setX(8); + _finalA->setY(46); + _finalA->setDrawPage(0); _finalA->displayFrame(frame); _screen->updateScreen(); timer2 = _system->getMillis() + 8 * _tickLength; @@ -1285,9 +1285,9 @@ int KyraEngine::handleMalcolmFlag() { case 9: snd_playSoundEffect(12); snd_playSoundEffect(12); - _finalC->_x = 16; - _finalC->_y = 50; - _finalC->_drawPage = 0; + _finalC->setX(16); + _finalC->setY(50); + _finalC->setDrawPage(0); for (int i = 0; i < 18; ++i) { timer2 = _system->getMillis() + 4 * _tickLength; _finalC->displayFrame(i); @@ -1489,9 +1489,9 @@ int KyraEngine::handleBeadState() { if (beadState1.dstX == 290) { _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); uint32 nextRun = 0; - _finalB->_x = 224; - _finalB->_y = 8; - _finalB->_drawPage = 0; + _finalB->setX(224); + _finalB->setY(8); + _finalB->setDrawPage(0); for (int i = 0; i < 8; ++i) { nextRun = _system->getMillis() + _tickLength; _finalB->displayFrame(i); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index b710222dd8..0cb2548408 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -306,7 +306,8 @@ const StaticResource::FileType *StaticResource::getFiletype(int type) { const void *StaticResource::getData(int id, int requesttype, int &size) { const void *ptr = 0; - int type = -1; + int type = -1; + size = 0; if (checkResList(id, type, ptr, size)) { if (type == requesttype) @@ -606,6 +607,8 @@ void KyraEngine::initStaticResource() { const Room *tempRoomList = _staticres->loadRoomTable(kRoomList, _roomTableSize); if (_roomTableSize > 0) { + printf("%d\n", _roomTableSize); + fflush(stdout); _roomTable = new Room[_roomTableSize]; assert(_roomTable); diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index ac9625efed..165da86a6d 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -204,4 +204,82 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, 0); } } + +#pragma mark - + +WSAMovieV3::WSAMovieV3(KyraEngine_v3 *vm) : WSAMovieV1(vm), _vm3(vm), _xAdd(0), _yAdd(0) {} + +void WSAMovieV3::open(const char *filename, int unk1, uint8 *palBuf) { + debugC(9, kDebugLevelMovie, "WSAMovieV3::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); + close(); + + uint32 flags = 0; + uint32 fileSize; + uint8 *p = _vm->resource()->fileData(filename, &fileSize); + if (!p) { + warning("couldn't load wsa file: '%s'", filename); + return; + } + + const uint8 *wsaData = p; + _numFrames = READ_LE_UINT16(wsaData); wsaData += 2; + _xAdd = (int16)(READ_LE_UINT16(wsaData)); wsaData += 2; + _yAdd = (int16)(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; + flags = READ_LE_UINT16(wsaData); wsaData += 2; + + uint32 offsPal = 0; + if (flags & 1) { + offsPal = 0x300; + _flags |= WF_HAS_PALETTE; + if (palBuf) { + memcpy(palBuf, wsaData + 8 + ((_numFrames << 2) & 0xFFFF), 0x300); + } + } + + if (!(unk1 & 2)) { + _flags |= WF_OFFSCREEN_DECODE; + const int offscreenBufferSize = _width * _height; + _offscreenBuffer = new uint8[offscreenBufferSize]; + memset(_offscreenBuffer, 0, offscreenBufferSize); + } + + if (_numFrames & 0x8000) { + warning("Unhandled wsa flags 0x80"); + _flags |= 0x80; + _numFrames &= 0x7FFF; + } + _currentFrame = _numFrames; + + _deltaBuffer = new uint8[_deltaBufferSize]; + memset(_deltaBuffer, 0, _deltaBufferSize); + + // read frame offsets + _frameOffsTable = new uint32[_numFrames + 2]; + _frameOffsTable[0] = 0; + uint32 frameDataOffs = READ_LE_UINT32(wsaData); wsaData += 4; + for (int i = 1; i < _numFrames + 2; ++i) { + _frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs; + wsaData += 4; + } + + // skip palette + wsaData += offsPal; + + // read frame data + const int frameDataSize = p + fileSize - wsaData; + _frameData = new uint8[frameDataSize]; + memcpy(_frameData, wsaData, frameDataSize); + + // decode first frame + Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize); + + delete [] p; + _opened = true; +} + } // end of namespace Kyra diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index fe3927f175..00fe4ef4f3 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -42,11 +42,15 @@ public: virtual void displayFrame(int frameNum) = 0; - int _x, _y; - int _drawPage; + virtual void setX(int x) { _x = x; } + virtual void setY(int y) { _y = y; } + virtual void setDrawPage(int page) { _drawPage = page; } protected: KyraEngine *_vm; bool _opened; + + int _x, _y; + int _drawPage; }; class WSAMovieV1 : public Movie { @@ -80,6 +84,26 @@ protected: uint32 *_frameOffsTable; uint8 *_frameData; }; + +#ifdef ENABLE_KYRA3 +class KyraEngine_v3; + +class WSAMovieV3 : public WSAMovieV1 { +public: + WSAMovieV3(KyraEngine_v3 *vm); + + void open(const char *filename, int unk1, uint8 *palette); + + void setX(int x) { _x = x + _xAdd; } + void setY(int y) { _y = y + _yAdd; } +protected: + KyraEngine_v3 *_vm3; + + int16 _xAdd; + int16 _yAdd; +}; +#endif + } // end of namespace Kyra #endif -- cgit v1.2.3