Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.49
diff -u -r1.49 kyra.cpp
--- kyra.cpp	3 Oct 2005 20:21:18 -0000	1.49
+++ kyra.cpp	5 Oct 2005 16:05:40 -0000
@@ -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 @@
 	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;
Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.20
diff -u -r1.20 kyra.h
--- kyra.h	3 Oct 2005 20:21:18 -0000	1.20
+++ kyra.h	5 Oct 2005 16:05:40 -0000
@@ -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 @@
 	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 @@
 	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[];
Index: staticres.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/staticres.cpp,v
retrieving revision 1.7
diff -u -r1.7 staticres.cpp
--- staticres.cpp	3 Oct 2005 20:21:18 -0000	1.7
+++ staticres.cpp	5 Oct 2005 16:05:40 -0000
@@ -347,11 +347,6 @@
 	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",
