aboutsummaryrefslogtreecommitdiff
path: root/kyra
diff options
context:
space:
mode:
Diffstat (limited to 'kyra')
-rw-r--r--kyra/kyra.cpp762
-rw-r--r--kyra/kyra.h72
-rw-r--r--kyra/staticres.cpp5
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",