mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
Applied my patch #1314023, since cyx liked the idea of cleaning up the
sequence player. He did note - and I agree - that the player could be further cleaned up by placing it in a class of its own, and that it's possible (though not certain) that we won't be needing alternative opcode sets for the floppy and CD versions. But it'll do for now. I don't have time to do any more with it right now. svn-id: r18944
This commit is contained in:
parent
fb86de70e2
commit
49602286f4
770
kyra/kyra.cpp
770
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;
|
||||
}
|
||||
|
||||
bool KyraEngine::seq_playSpecialSequence(const uint8 *seqData, bool skipSeq) {
|
||||
debug(9, "KyraEngine::seq_playSpecialSequence(0x%X, %d)", seqData, skipSeq);
|
||||
WSAMovieV1 *wsaMovieTable[12];
|
||||
uint32 displayedTextTimer = 0xFFFFFFFF;
|
||||
bool displayTextFlag = false;
|
||||
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];
|
||||
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
seqLoopTable[i].ptr = 0;
|
||||
seqLoopTable[i].count = 0xFFFF;
|
||||
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);
|
||||
}
|
||||
memset(wsaMovieTable, 0, sizeof(wsaMovieTable));
|
||||
_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);
|
||||
|
||||
commands = floppySeqProcs;
|
||||
numCommands = ARRAYSIZE(floppySeqProcs);
|
||||
|
||||
bool seqSkippedFlag = false;
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
72
kyra/kyra.h
72
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[];
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user