diff options
Diffstat (limited to 'kyra')
-rw-r--r-- | kyra/kyra.cpp | 762 | ||||
-rw-r--r-- | kyra/kyra.h | 72 | ||||
-rw-r--r-- | kyra/staticres.cpp | 5 |
3 files changed, 524 insertions, 315 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 5159955397..b145cfa2c4 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -43,6 +43,8 @@ #define TEST_SPRITES 1 +#define SEQOP(n, x) { n, &KyraEngine::x, #x } + using namespace Kyra; struct KyraGameSettings { @@ -809,337 +811,483 @@ bool KyraEngine::seq_skipSequence() const { return _quitFlag || _abortIntroFlag; } +void KyraEngine::s1_wsaOpen() { + uint8 wsaObj = *_seqData++; + assert(wsaObj < 12); + uint8 offscreenDecode = *_seqData++; + _seqWsaCurDecodePage = _seqMovies[wsaObj].page = (offscreenDecode == 0) ? 0 : 3; + if (_game == KYRA1DEMO) { + _seqMovies[wsaObj].wsa = wsa_open(_seq_demo_WSATable[wsaObj], offscreenDecode, 0); + } else { + _seqMovies[wsaObj].wsa = wsa_open(_seq_WSATable[wsaObj], offscreenDecode, 0); + } + _seqMovies[wsaObj].frame = 0; + _seqMovies[wsaObj].numFrames = wsa_getNumFrames(_seqMovies[wsaObj].wsa) - 1; +} + +void KyraEngine::s1_wsaClose() { + uint8 wsaObj = *_seqData++; + assert(wsaObj < 12); + if (_seqMovies[wsaObj].wsa) { + wsa_close(_seqMovies[wsaObj].wsa); + _seqMovies[wsaObj].wsa = 0; + } +} + +void KyraEngine::s1_wsaPlayFrame() { + uint8 wsaObj = *_seqData++; + assert(wsaObj < 12); + int16 frame = (int8)*_seqData++; + _seqMovies[wsaObj].pos.x = READ_LE_UINT16(_seqData); _seqData += 2; + _seqMovies[wsaObj].pos.y = *_seqData++; + wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); + _seqMovies[wsaObj].frame = frame; +} + +void KyraEngine::s1_wsaPlayNextFrame() { + uint8 wsaObj = *_seqData++; + assert(wsaObj < 12); + int16 frame = ++_seqMovies[wsaObj].frame; + if (frame > _seqMovies[wsaObj].numFrames) { + frame = 0; + _seqMovies[wsaObj].frame = 0; + } + wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); +} + +void KyraEngine::s1_wsaPlayPrevFrame() { + uint8 wsaObj = *_seqData++; + assert(wsaObj < 12); + int16 frame = --_seqMovies[wsaObj].frame; + if (frame < 0) { + frame = _seqMovies[wsaObj].numFrames; + _seqMovies[wsaObj].frame = frame; + } else { + wsa_play(_seqMovies[wsaObj].wsa, frame, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, _seqMovies[wsaObj].page); + } +} + +void KyraEngine::s1_drawShape() { + uint8 shapeNum = *_seqData++; + int x = READ_LE_UINT16(_seqData); _seqData += 2; + int y = *_seqData++; + _screen->drawShape(2, _seq_handShapes[shapeNum], x, y, 0, 0, 0); +} + +void KyraEngine::s1_maybeWaitTicks() { + uint16 a = READ_LE_UINT16(_seqData); _seqData += 2; + warning("STUB: s1_maybeWaitTicks(%d)\n", a); +} + +void KyraEngine::s1_waitTicks() { + uint16 ticks = READ_LE_UINT16(_seqData); _seqData += 2; + waitTicks(ticks); +} + +void KyraEngine::s1_copyWaitTicks() { + seq_copyView(); + s1_waitTicks(); +} + +void KyraEngine::s1_shuffleScreen() { + _screen->shuffleScreen(0, 16, 320, 128, 2, 0, 0, false); + _screen->_curPage = 2; +} + +void KyraEngine::s1_copyView() { + seq_copyView(); +} + +void KyraEngine::s1_loopInit() { + uint8 seqLoop = *_seqData++; + if (seqLoop < 20) { + _seqLoopTable[seqLoop].ptr = _seqData; + } else { + _seqQuitFlag = true; + } +} + +void KyraEngine::s1_maybeLoopInc() { + uint8 a = *_seqData++; + int16 b = (int16)READ_LE_UINT16(_seqData); _seqData += 2; + warning("STUB: s1_maybeLoopInc(%d, %d)\n", a, b); +} + +void KyraEngine::s1_loopInc() { + uint8 seqLoop = *_seqData++; + uint16 seqLoopCount = READ_LE_UINT16(_seqData); _seqData += 2; + if (_seqLoopTable[seqLoop].count == 0xFFFF) { + _seqLoopTable[seqLoop].count = seqLoopCount - 1; + _seqData = _seqLoopTable[seqLoop].ptr; + } else if (_seqLoopTable[seqLoop].count == 0) { + _seqLoopTable[seqLoop].count = 0xFFFF; + _seqLoopTable[seqLoop].ptr = 0; + } else { + --_seqLoopTable[seqLoop].count; + _seqData = _seqLoopTable[seqLoop].ptr; + } +} + +void KyraEngine::s1_skip() { + uint8 a = *_seqData++; + warning("STUB: s1_skip(%d)\n", a); +} + +void KyraEngine::s1_loadPalette() { + uint8 colNum = *_seqData++; + uint32 fileSize; + uint8 *srcData; + if (_game == KYRA1DEMO) { + srcData = _res->fileData(_seq_demo_COLTable[colNum], &fileSize); + } else { + srcData = _res->fileData(_seq_COLTable[colNum], &fileSize); + } + memcpy(_screen->_currentPalette, srcData, fileSize); + delete[] srcData; +} + +void KyraEngine::s1_loadBitmap() { + uint8 cpsNum = *_seqData++; + loadBitmap(_seq_CPSTable[cpsNum], 3, 3, 0); +} + +void KyraEngine::s1_fadeToBlack() { + _screen->fadeToBlack(); +} + +void KyraEngine::s1_printText() { + static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; + uint8 txt = *_seqData++; + _screen->fillRect(0, 180, 319, 195, 12); + _screen->setTextColorMap(colorMap); + if (!_seqDisplayTextFlag) { + const char *str = _seq_textsTableEN[txt]; + int x = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; + _screen->printText(str, x, 180, 0xF, 0xC); + } else { + _seqDisplayedTextTimer = _system->getMillis() + 1000 / 60; + _seqDisplayedText = txt; + _seqDisplayedChar = 0; + const char *str = _seq_textsTableEN[_seqDisplayedText]; + _seqDisplayedTextX = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; + } +} + +void KyraEngine::s1_printTalkText() { + uint8 txt = *_seqData++; + int x = READ_LE_UINT16(_seqData); _seqData += 2; + int y = *_seqData++; + uint8 fillColor = *_seqData++; + int b; + if (_seqTalkTextPrinted && !_seqTalkTextRestored) { + if (_seqWsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + restoreTalkTextMessageBkgd(2, b); + } + _seqTalkTextPrinted = true; + _seqTalkTextRestored = false; + if (_seqWsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + printTalkTextMessage(_seq_textsTableEN[txt], x, y, fillColor, b, 2); +} + +void KyraEngine::s1_restoreTalkText() { + if (_seqTalkTextPrinted && !_seqTalkTextRestored) { + int b; + if (_seqWsaCurDecodePage != 0) { + b = 2; + } else { + b = 0; + } + restoreTalkTextMessageBkgd(2, b); + _seqTalkTextRestored = true; + } +} + +void KyraEngine::s1_clearCurrentScreen() { + _screen->fillRect(10, 180, 319, 196, 0xC); +} + +void KyraEngine::s1_break() { + // Do nothing +} + +void KyraEngine::s1_fadeFromBlack() { + _screen->fadeFromBlack(); +} + +void KyraEngine::s1_copyRegion() { + uint8 srcPage = *_seqData++; + uint8 dstPage = *_seqData++; + _screen->copyRegion(0, 0, 0, 0, 320, 200, srcPage, dstPage); +} + +void KyraEngine::s1_copyRegionSpecial() { + static const uint8 colorMap[] = { 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0 }; + const char *copyStr = "Copyright (c) 1992 Westwood Studios"; + const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2; + const int y = 179; + + uint8 so = *_seqData++; + switch (so) { + case 0: + _screen->copyRegion(0, 0, 0, 47, 320, 77, 2, 0); + break; + case 1: + _screen->copyRegion(0, 0, 0, 47, 320, 56, 2, 0); + break; + case 2: + _screen->copyRegion(107, 72, 107, 72, 43, 87, 2, 0); + _screen->copyRegion(130, 159, 130, 159, 35, 17, 2, 0); + _screen->copyRegion(165, 105, 165, 105, 32, 9, 2, 0); + _screen->copyRegion(206, 83, 206, 83, 94, 93, 2, 0); + break; + case 3: + _screen->copyRegion(152, 56, 152, 56, 48, 48, 2, 0); + break; + case 4: + _screen->_charWidth = -2; + _screen->setTextColorMap(colorMap); + _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC); + _screen->printText(copyStr, x, y, 0xF, 0xC); + break; + case 5: + _screen->_curPage = 2; + break; + default: + error("Invalid subopcode %d for s1_copyRegionSpecial", so); + break; + } +} + +void KyraEngine::s1_fillRect() { + int x1 = READ_LE_UINT16(_seqData); _seqData += 2; + int y1 = *_seqData++; + int x2 = READ_LE_UINT16(_seqData); _seqData += 2; + int y2 = *_seqData++; + uint8 color = *_seqData++; + uint8 page = *_seqData++; + _screen->fillRect(x1, y1, x2, y2, color, page); +} + +void KyraEngine::s1_soundUnk1() { + uint8 param = *_seqData++; + waitTicks(3); + snd_playSoundEffect(param); +} + +void KyraEngine::s1_soundUnk2() { + uint8 param = *_seqData++; + snd_seqMessage(param); +} + +void KyraEngine::s1_allocTempBuffer() { + if (_game == KYRA1DEMO) { + _seqQuitFlag = true; + } else { + // allocate offscreen buffer, not needed + } +} + +void KyraEngine::s1_textDisplayEnable() { + _seqDisplayTextFlag = true; +} + +void KyraEngine::s1_textDisplayDisable() { + _seqDisplayTextFlag = false; +} + +void KyraEngine::s1_endOfScript() { + _seqQuitFlag = true; +} + +void KyraEngine::s1_miscUnk1() { + warning("STUB: s1_miscUnk1\n"); +} + +void KyraEngine::s1_miscUnk2() { + uint8 a = *_seqData++; + warning("STUB: s1_miscUnk2(%d)\n", a); +} + +void KyraEngine::s1_miscUnk3() { + warning("STUB: s1_miscUnk3\n"); +} + +void KyraEngine::s1_miscUnk4() { + uint8 a = *_seqData++; + warning("STUB: s1_miscUnk4(%d)\n", a); +} + bool KyraEngine::seq_playSpecialSequence(const uint8 *seqData, bool skipSeq) { + static SeqEntry floppySeqProcs[] = { + // 0x00 + SEQOP(3, s1_wsaOpen), + SEQOP(2, s1_wsaClose), + SEQOP(6, s1_wsaPlayFrame), + SEQOP(2, s1_wsaPlayNextFrame), + // 0x04 + SEQOP(2, s1_wsaPlayPrevFrame), + SEQOP(5, s1_drawShape), + SEQOP(3, s1_waitTicks), + SEQOP(3, s1_copyWaitTicks), + // 0x08 + SEQOP(1, s1_shuffleScreen), + SEQOP(1, s1_copyView), + SEQOP(2, s1_loopInit), + SEQOP(4, s1_loopInc), + // 0x0C + SEQOP(2, s1_loadPalette), + SEQOP(2, s1_loadBitmap), + SEQOP(1, s1_fadeToBlack), + SEQOP(2, s1_printText), + // 0x10 + SEQOP(6, s1_printTalkText), + SEQOP(1, s1_restoreTalkText), + SEQOP(1, s1_clearCurrentScreen), + SEQOP(1, s1_break), + // 0x14 + SEQOP(1, s1_fadeFromBlack), + SEQOP(3, s1_copyRegion), + SEQOP(2, s1_copyRegionSpecial), + SEQOP(9, s1_fillRect), + // 0x18 + SEQOP(2, s1_soundUnk1), + SEQOP(2, s1_soundUnk2), + SEQOP(1, s1_allocTempBuffer), + SEQOP(1, s1_textDisplayEnable), + // 0x1C + SEQOP(1, s1_textDisplayDisable), + SEQOP(1, s1_endOfScript) + }; + +#if 0 + static SeqEntry cdromSeqProcs[] = { + // 0x00 + SEQOP(3, s1_wsaOpen), + SEQOP(2, s1_wsaClose), + SEQOP(6, s1_wsaPlayFrame), + SEQOP(2, s1_wsaPlayNextFrame), + // 0x04 + SEQOP(2, s1_wsaPlayPrevFrame), + SEQOP(5, s1_drawShape), + SEQOP(3, s1_maybeWaitTicks), + SEQOP(3, s1_waitTicks), + // 0x08 + SEQOP(3, s1_copyWaitTicks), + SEQOP(1, s1_shuffleScreen), + SEQOP(1, s1_copyView), + SEQOP(2, s1_loopInit), + // 0x0C + SEQOP(4, s1_maybeLoopInc), + SEQOP(4, s1_maybeLoopInc), // Again? + SEQOP(2, s1_skip), + SEQOP(2, s1_loadPalette), + // 0x10 + SEQOP(2, s1_loadBitmap), + SEQOP(1, s1_fadeToBlack), + SEQOP(2, s1_printText), + SEQOP(6, s1_printTalkText), + // 0x14 + SEQOP(1, s1_restoreTalkText), + SEQOP(1, s1_clearCurrentScreen), + SEQOP(1, s1_break), + SEQOP(1, s1_fadeFromBlack), + // 0x18 + SEQOP(3, s1_copyRegion), + SEQOP(2, s1_copyRegionSpecial), + SEQOP(9, s1_fillRect), + SEQOP(2, s1_soundUnk1), + // 0x1C + SEQOP(2, s1_soundUnk2), + SEQOP(1, s1_allocTempBuffer), + SEQOP(1, s1_textDisplayEnable), + SEQOP(1, s1_textDisplayDisable), + // 0x20 + SEQOP(1, s1_endOfScript), + SEQOP(1, s1_miscUnk1), + SEQOP(2, s1_miscUnk2), + SEQOP(1, s1_miscUnk3), + // 0x24 + SEQOP(2, s1_miscUnk4) + }; +#endif + + const SeqEntry* commands; + int numCommands; + debug(9, "KyraEngine::seq_playSpecialSequence(0x%X, %d)", seqData, skipSeq); - WSAMovieV1 *wsaMovieTable[12]; - uint32 displayedTextTimer = 0xFFFFFFFF; - bool displayTextFlag = false; + + commands = floppySeqProcs; + numCommands = ARRAYSIZE(floppySeqProcs); + bool seqSkippedFlag = false; - uint16 displayedTextX = 0; - uint8 displayedText = 0; - uint8 displayedChar = 0; - int16 wsaCurFramesTable[12]; - uint16 wsaYPosTable[12]; - uint16 wsaXPosTable[12]; - bool talkTextRestored = false; - bool talkTextPrinted = false; - int16 wsaNumFramesTable[12]; - bool quitFlag = false; - uint16 wsaCurDecodePage = 0; - uint32 wsaDecodePage[12]; - SeqLoop seqLoopTable[20]; - + + _seqData = seqData; + + _seqDisplayedTextTimer = 0xFFFFFFFF; + _seqDisplayTextFlag = false; + _seqDisplayedTextX = 0; + _seqDisplayedText = 0; + _seqDisplayedChar = 0; + _seqTalkTextRestored = false; + _seqTalkTextPrinted = false; + + _seqQuitFlag = false; + _seqWsaCurDecodePage = 0; + for (int i = 0; i < 20; ++i) { - seqLoopTable[i].ptr = 0; - seqLoopTable[i].count = 0xFFFF; + _seqLoopTable[i].ptr = 0; + _seqLoopTable[i].count = 0xFFFF; } - memset(wsaMovieTable, 0, sizeof(wsaMovieTable)); + + memset(_seqMovies, 0, sizeof(_seqMovies)); _screen->_curPage = 0; - while (!quitFlag) { + while (!_seqQuitFlag) { if (skipSeq && seq_skipSequence()) { while (1) { - uint8 code = *seqData; - if (code == 29 || code == 19) { + uint8 code = *_seqData; + if (commands[code].proc == &KyraEngine::s1_endOfScript || commands[code].proc == &KyraEngine::s1_break) { break; } - seqData += _seq_codeSizeTable[code] + 1; + _seqData += commands[code].len; } skipSeq = false; seqSkippedFlag = true; } // used in Kallak writing intro - if (displayTextFlag && displayedTextTimer != 0xFFFFFFFF) { - if (displayedTextTimer < _system->getMillis()) { + if (_seqDisplayTextFlag && _seqDisplayedTextTimer != 0xFFFFFFFF) { + if (_seqDisplayedTextTimer < _system->getMillis()) { char charStr[2]; - charStr[0] = _seq_textsTableEN[displayedText][displayedChar]; + charStr[0] = _seq_textsTableEN[_seqDisplayedText][_seqDisplayedChar]; charStr[1] = '\0'; - _screen->printText(charStr, displayedTextX, 180, 0xF, 0xC); - displayedTextX += _screen->getCharWidth(charStr[0]); - ++displayedChar; - if (_seq_textsTableEN[displayedText][displayedChar] == '\0') { - displayedTextTimer = 0xFFFFFFFF; + _screen->printText(charStr, _seqDisplayedTextX, 180, 0xF, 0xC); + _seqDisplayedTextX += _screen->getCharWidth(charStr[0]); + ++_seqDisplayedChar; + if (_seq_textsTableEN[_seqDisplayedText][_seqDisplayedChar] == '\0') { + _seqDisplayedTextTimer = 0xFFFFFFFF; } } else { - displayedTextTimer = _system->getMillis() + 1000 / 60; + _seqDisplayedTextTimer = _system->getMillis() + 1000 / 60; } } - uint8 seqCode = *seqData++; - debug(5, "seqCode = %d", seqCode); - switch (seqCode) { - case 0: { - uint8 wsaObj = *seqData++; - assert(wsaObj < 12); - uint8 offscreenDecode = *seqData++; - wsaCurDecodePage = wsaDecodePage[wsaObj] = (offscreenDecode == 0) ? 0 : 3; - if (_game == KYRA1DEMO) { - wsaMovieTable[wsaObj] = wsa_open(_seq_demo_WSATable[wsaObj], offscreenDecode, 0); - } else { - wsaMovieTable[wsaObj] = wsa_open(_seq_WSATable[wsaObj], offscreenDecode, 0); - } - wsaCurFramesTable[wsaObj] = 0; - wsaNumFramesTable[wsaObj] = wsa_getNumFrames(wsaMovieTable[wsaObj]) - 1; - } - break; - case 1: { - uint8 wsaObj = *seqData++; - assert(wsaObj < 12); - if (wsaMovieTable[wsaObj]) { - wsa_close(wsaMovieTable[wsaObj]); - wsaMovieTable[wsaObj] = 0; - } - } - break; - case 2: { - uint8 wsaObj = *seqData++; - assert(wsaObj < 12); - int16 frame = (int8)*seqData++; - wsaXPosTable[wsaObj] = READ_LE_UINT16(seqData); seqData += 2; - wsaYPosTable[wsaObj] = *seqData++; - wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); - wsaCurFramesTable[wsaObj] = frame; - } - break; - case 3: { - uint8 wsaObj = *seqData++; - assert(wsaObj < 12); - ++wsaCurFramesTable[wsaObj]; - int16 frame = wsaCurFramesTable[wsaObj]; - if (frame > wsaNumFramesTable[wsaObj]) { - frame = 0; - wsaCurFramesTable[wsaObj] = 0; - } - wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); - } - break; - case 4: { - uint8 wsaObj = *seqData++; - assert(wsaObj < 12); - --wsaCurFramesTable[wsaObj]; - int16 frame = wsaCurFramesTable[wsaObj]; - if (wsaCurFramesTable[wsaObj] < 0) { - frame = wsaNumFramesTable[wsaObj]; - wsaCurFramesTable[wsaObj] = wsaNumFramesTable[wsaObj]; - } else { - wsa_play(wsaMovieTable[wsaObj], frame, wsaXPosTable[wsaObj], wsaYPosTable[wsaObj], wsaDecodePage[wsaObj]); - } - } - break; - case 5: { - uint8 shapeNum = *seqData++; - int x = READ_LE_UINT16(seqData); seqData += 2; - int y = *seqData++; - _screen->drawShape(2, _seq_handShapes[shapeNum], x, y, 0, 0, 0); - } - break; - case 6: - case 7: { - if (seqCode == 7) { - seq_copyView(); - } - uint16 ticks = READ_LE_UINT16(seqData); seqData += 2; - waitTicks(ticks); - } - break; - case 8: - _screen->shuffleScreen(0, 16, 320, 128, 2, 0, 0, false); - _screen->_curPage = 2; - break; - case 9: - seq_copyView(); - break; - case 10: { - uint8 seqLoop = *seqData++; - if (seqLoop < 20) { - seqLoopTable[seqLoop].ptr = seqData; - } else { - quitFlag = true; - } - } - break; - case 11: { - uint8 seqLoop = *seqData++; - uint16 seqLoopCount = READ_LE_UINT16(seqData); seqData += 2; - if (seqLoopTable[seqLoop].count == 0xFFFF) { - seqLoopTable[seqLoop].count = seqLoopCount - 1; - seqData = seqLoopTable[seqLoop].ptr; - } else if (seqLoopTable[seqLoop].count == 0) { - seqLoopTable[seqLoop].count = 0xFFFF; - seqLoopTable[seqLoop].ptr = 0; - } else { - --seqLoopTable[seqLoop].count; - seqData = seqLoopTable[seqLoop].ptr; - } - } - break; - case 12: { - uint8 colNum = *seqData++; - uint32 fileSize; - uint8 *srcData; - if (_game == KYRA1DEMO) { - srcData = _res->fileData(_seq_demo_COLTable[colNum], &fileSize); - } else { - srcData = _res->fileData(_seq_COLTable[colNum], &fileSize); - } - memcpy(_screen->_currentPalette, srcData, fileSize); - delete[] srcData; - } - break; - case 13: { - uint8 cpsNum = *seqData++; - loadBitmap(_seq_CPSTable[cpsNum], 3, 3, 0); - } - break; - case 14: - _screen->fadeToBlack(); - break; - case 15: { - static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; - uint8 txt = *seqData++; - _screen->fillRect(0, 180, 319, 195, 12); - _screen->setTextColorMap(colorMap); - if (!displayTextFlag) { - const char *str = _seq_textsTableEN[txt]; - int x = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; - _screen->printText(str, x, 180, 0xF, 0xC); - } else { - displayedTextTimer = _system->getMillis() + 1000 / 60; - displayedText = txt; - displayedChar = 0; - const char *str = _seq_textsTableEN[displayedText]; - displayedTextX = (Screen::SCREEN_W - _screen->getTextWidth(str)) / 2; - } - } - break; - case 16: { - uint8 txt = *seqData++; - int x = READ_LE_UINT16(seqData); seqData += 2; - int y = *seqData++; - uint8 fillColor = *seqData++; - int b; - if (talkTextPrinted && !talkTextRestored) { - if (wsaCurDecodePage != 0) { - b = 2; - } else { - b = 0; - } - restoreTalkTextMessageBkgd(2, b); - } - talkTextPrinted = true; - talkTextRestored = false; - if (wsaCurDecodePage != 0) { - b = 2; - } else { - b = 0; - } - printTalkTextMessage(_seq_textsTableEN[txt], x, y, fillColor, b, 2); - } - break; - case 17: - if (talkTextPrinted && !talkTextRestored) { - int b; - if (wsaCurDecodePage != 0) { - b = 2; - } else { - b = 0; - } - restoreTalkTextMessageBkgd(2, b); - talkTextRestored = true; - } - break; - case 18: - _screen->fillRect(10, 180, 319, 196, 0xC); - break; - case 19: - break; - case 20: - _screen->fadeFromBlack(); - break; - case 21: { - uint8 srcPage = *seqData++; - uint8 dstPage = *seqData++; - _screen->copyRegion(0, 0, 0, 0, 320, 200, srcPage, dstPage); - } - break; - case 22: { - uint8 so = *seqData++; - switch (so) { - case 0: - _screen->copyRegion(0, 0, 0, 47, 320, 77, 2, 0); - break; - case 1: - _screen->copyRegion(0, 0, 0, 47, 320, 56, 2, 0); - break; - case 2: - _screen->copyRegion(107, 72, 107, 72, 43, 87, 2, 0); - _screen->copyRegion(130, 159, 130, 159, 35, 17, 2, 0); - _screen->copyRegion(165, 105, 165, 105, 32, 9, 2, 0); - _screen->copyRegion(206, 83, 206, 83, 94, 93, 2, 0); - break; - case 3: - _screen->copyRegion(152, 56, 152, 56, 48, 48, 2, 0); - break; - case 4: { - static const uint8 colorMap[] = { 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0 }; - _screen->_charWidth = -2; - const char *copyStr = "Copyright (c) 1992 Westwood Studios"; - _screen->setTextColorMap(colorMap); - const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2; - const int y = 179; - _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC); - _screen->printText(copyStr, x, y, 0xF, 0xC); - } - break; - case 5: - _screen->_curPage = 2; - break; - default: - error("Invalid subopcode %d for sequence opcode 22", so); - break; - } - } - break; - case 23: { - int x1 = READ_LE_UINT16(seqData); seqData += 2; - int y1 = *seqData++; - int x2 = READ_LE_UINT16(seqData); seqData += 2; - int y2 = *seqData++; - uint8 color = *seqData++; - uint8 page = *seqData++; - _screen->fillRect(x1, y1, x2, y2, color, page); - } - break; - case 24: { // sound related - uint8 param = *seqData++; - waitTicks(3); - snd_playSoundEffect(param); - } - break; - case 25: { // sound related - uint8 param = *seqData++; - snd_seqMessage(param); - } - break; - case 26: - if (_game == KYRA1DEMO) { - quitFlag = true; - } else { - // allocate offscreen buffer, not needed - } - break; - case 27: - displayTextFlag = true; - break; - case 28: - displayTextFlag = false; - break; - case 29: - quitFlag = true; - break; - default: + + uint8 seqCode = *_seqData++; + if (seqCode < numCommands) { + SeqProc currentProc = commands[seqCode].proc; + debug(5, "seqCode = %d (%s)", seqCode, commands[seqCode].desc); + (this->*currentProc)(); + } else { error("Invalid sequence opcode %d", seqCode); - break; } + _screen->updateScreen(); } return seqSkippedFlag; diff --git a/kyra/kyra.h b/kyra/kyra.h index e170ce06e4..86fc4a28e3 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -23,7 +23,7 @@ #define KYRA_H #include "base/engine.h" -#include "common/util.h" +#include "common/rect.h" namespace Kyra { @@ -206,6 +206,73 @@ protected: static const Cursor _cursors[]; static const int _cursorsCount; + typedef void (KyraEngine::*SeqProc)(); + struct SeqEntry { + uint8 len; + SeqProc proc; + const char* desc; + }; + + // the sequence procs + void s1_wsaOpen(); + void s1_wsaClose(); + void s1_wsaPlayFrame(); + void s1_wsaPlayNextFrame(); + void s1_wsaPlayPrevFrame(); + void s1_drawShape(); + void s1_maybeWaitTicks(); + void s1_waitTicks(); + void s1_copyWaitTicks(); + void s1_shuffleScreen(); + void s1_copyView(); + void s1_loopInit(); + void s1_maybeLoopInc(); + void s1_loopInc(); + void s1_skip(); + void s1_loadPalette(); + void s1_loadBitmap(); + void s1_fadeToBlack(); + void s1_printText(); + void s1_printTalkText(); + void s1_restoreTalkText(); + void s1_clearCurrentScreen(); + void s1_break(); + void s1_fadeFromBlack(); + void s1_copyRegion(); + void s1_copyRegionSpecial(); + void s1_fillRect(); + void s1_soundUnk1(); + void s1_soundUnk2(); + void s1_allocTempBuffer(); + void s1_textDisplayEnable(); + void s1_textDisplayDisable(); + void s1_endOfScript(); + void s1_miscUnk1(); + void s1_miscUnk2(); + void s1_miscUnk3(); + void s1_miscUnk4(); + + struct SeqMovie { + WSAMovieV1 *wsa; + int32 page; + int16 frame; + int16 numFrames; + Common::Point pos; + }; + + const uint8 *_seqData; + SeqMovie _seqMovies[12]; + SeqLoop _seqLoopTable[20]; + uint16 _seqWsaCurDecodePage; + uint32 _seqDisplayedTextTimer; + bool _seqDisplayTextFlag; + uint8 _seqDisplayedText; + uint8 _seqDisplayedChar; + uint16 _seqDisplayedTextX; + bool _seqTalkTextPrinted; + bool _seqTalkTextRestored; + bool _seqQuitFlag; + // these tables are specific to the demo version static const uint8 _seq_demoData_WestwoodLogo[]; static const uint8 _seq_demoData_KyrandiaLogo[]; @@ -223,8 +290,7 @@ protected: static const uint8 _seq_floppyData_KallakMalcom[]; static const uint8 _seq_floppyData_MalcomTree[]; static const uint8 _seq_floppyData_WestwoodLogo[]; - - static const uint8 _seq_codeSizeTable[]; + static const char *_seq_WSATable[]; static const char *_seq_CPSTable[]; static const char *_seq_COLTable[]; diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp index c0cbd5b42e..4bd31e50c3 100644 --- a/kyra/staticres.cpp +++ b/kyra/staticres.cpp @@ -347,11 +347,6 @@ const uint8 KyraEngine::_seq_demoData_Demo4[] = { 0x06, 0x06, 0x04, 0x00, 0x0B, 0x00, 0x39, 0x00, 0x06, 0x5A, 0x00, 0x13, 0x0E, 0x01, 0x06, 0x1A }; -const uint8 KyraEngine::_seq_codeSizeTable[] = { - 2, 1, 5, 1, 1, 4, 2, 2, 0, 0, 1, 3, 1, 1, 0, 1, - 5, 0, 0, 0, 0, 2, 1, 8, 1, 1, 0, 0, 0, 0, 0, 0 -}; - const char *KyraEngine::_seq_WSATable[] = { "kallak.wsa", "tree1.wsa", |