From bccca104d0635949d328a18d722218ba4bf59f0c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 31 May 2009 00:42:44 +0000 Subject: - Add support for the Lands of Lore outro TIM file - Cleanup svn-id: r41053 --- engines/kyra/lol.cpp | 4 + engines/kyra/lol.h | 12 ++- engines/kyra/screen_lol.cpp | 31 +++++++ engines/kyra/screen_lol.h | 2 + engines/kyra/script_lol.cpp | 113 ++++++++++++++++++++++- engines/kyra/script_tim.cpp | 220 +++++++++++++++++++++++++++++--------------- engines/kyra/script_tim.h | 12 +-- engines/kyra/wsamovie.h | 3 + 8 files changed, 312 insertions(+), 85 deletions(-) (limited to 'engines') diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 911b62cd07..45ab0202eb 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -337,6 +337,10 @@ LoLEngine::~LoLEngine() { delete *i; _timIntroOpcodes.clear(); + for (Common::Array::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i) + delete *i; + _timOutroOpcodes.clear(); + for (Common::Array::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i) delete *i; _timIngameOpcodes.clear(); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index c65e7d7bf6..b90808db82 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -773,6 +773,16 @@ private: int tlol_processWsaFrame(const TIM *tim, const uint16 *param); int tlol_displayText(const TIM *tim, const uint16 *param); + Common::Array _timOutroOpcodes; + int tlol_fadeInScene(const TIM *tim, const uint16 *param); + int tlol_unusedResourceFunc(const TIM *tim, const uint16 *param); + int tlol_fadeInPalette(const TIM *tim, const uint16 *param); + int tlol_fadeSoundOut(const TIM *tim, const uint16 *param); + int tlol_displayAnimFrame(const TIM *tim, const uint16 *param); + int tlol_delayForChat(const TIM *tim, const uint16 *param); + int tlol_fadeOutSound(const TIM *tim, const uint16 *param); + + Common::Array _timIngameOpcodes; int tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param); int tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param); int tlol_giveItem(const TIM *tim, const uint16 *param); @@ -790,8 +800,6 @@ private: int tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param); int tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param); - Common::Array _timIngameOpcodes; - // translation int _lang; diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index dd3f81b7fa..b834123d2f 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -738,6 +738,37 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight); } +void Screen_LoL::copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const uint8 *ovl) { + if (!ovl) + return; + + const byte *src = getCPagePtr(srcPage); + byte *dst = getPagePtr(dstPage); + + for (int y = 0; y < 200; ++y) { + for (int x = 0; x < 80; ++x) { + uint32 srcData = READ_LE_UINT32(src); src += 4; + uint32 dstData = READ_LE_UINT32(dst); + uint16 offset = 0; + + offset = ((srcData & 0xFF) << 8) + (dstData & 0xFF); + *dst++ = ovl[offset]; + + offset = (srcData & 0xFF00) + ((dstData & 0xFF00) >> 8); + *dst++ = ovl[offset]; + + srcData >>= 16; + dstData >>= 16; + + offset = ((srcData & 0xFF) << 8) + (dstData & 0xFF); + *dst++ = ovl[offset]; + + offset = (srcData & 0xFF00) + ((dstData & 0xFF00) >> 8); + *dst++ = ovl[offset]; + } + } +} + void Screen_LoL::calcBoundariesIntern(int dstX, int dstY, int width, int height) { _internBlockWidth = _internBlockWidth2 = width; _internBlockHeight = height; diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index 3b9e370ccc..1ad5379d29 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -82,6 +82,8 @@ public: void copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl); void applyOverlaySpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, int flag, uint8 *ovl); + void copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const uint8 *ovl); + uint8 getShapePaletteSize(const uint8 *shp); uint8 *_paletteOverlay1; diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 108190132b..1e5740dfc3 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -2191,7 +2191,10 @@ int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) { int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], (int16)param[1]); - _tim->displayText(param[0], param[1]); + if (tim->isLoLOutro) + _tim->displayText(param[0], param[1], param[2]); + else + _tim->displayText(param[0], param[1]); return 1; } @@ -2356,6 +2359,87 @@ int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) return 1; } +int LoLEngine::tlol_fadeInScene(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInScene(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]); + const char *sceneFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1))); + const char *overlayFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[1]<<1))); + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK); + + char filename[32]; + strcpy(filename, sceneFile); + strcat(filename, ".CPS"); + + _screen->loadBitmap(filename, 7, 5, _screen->getPalette(0)); + + filename[0] = 0; + + if (_flags.isTalkie) { + strcpy(filename, _languageExt[_lang]); + strcat(filename, "/"); + } + + strcat(filename, overlayFile); + uint8 *overlay = _res->fileData(filename, 0); + + for (int i = 0; i < 3; ++i) { + uint32 endTime = _system->getMillis() + 10 * _tickLength; + _screen->copyBlockAndApplyOverlayOutro(4, 2, overlay); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delayUntil(endTime); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + delete[] overlay; + + return 1; +} + +int LoLEngine::tlol_unusedResourceFunc(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_unusedResourceFunc(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]); + // The original used 0x6 / 0x7 for some resource caching, we don't need this. + return 1; +} + +int LoLEngine::tlol_fadeInPalette(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInPalette(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]); + const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1))); + uint8 palette[768]; + _screen->loadBitmap(bitmap, 3, 3, palette); + _screen->fadePalette(palette, param[1]); + return 1; +} + +int LoLEngine::tlol_fadeOutSound(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeOutSound(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]); + _sound->beginFadeOut(); + return 1; +} + +int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]); + + TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim; + if (param[1] == 0xFFFF) { + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + } else { + anim->wsa->displayFrame(param[1], 2, anim->x, anim->y, 0); + _screen->copyRegion(anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->width(), anim->wsa->height(), 2, 0); + } + + return 1; +} + +int LoLEngine::tlol_delayForChat(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_delayForChat(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]); + if (!speechEnabled()) + delay(param[0]); + return 1; +} + #pragma mark - typedef Common::Functor1Mem OpcodeV2; @@ -2678,6 +2762,33 @@ void LoLEngine::setupOpcodeTable() { OpcodeTimUnImpl(); OpcodeTimUnImpl(); + _timOutroOpcodes.reserve(16); + SetTimOpcodeTable(_timOutroOpcodes); + + // 0x00 + OpcodeTim(tlol_setupPaletteFade); + OpcodeTimUnImpl(); + OpcodeTim(tlol_loadPalette); + OpcodeTim(tlol_setupPaletteFadeEx); + + // 0x04 + OpcodeTimUnImpl(); + OpcodeTim(tlol_fadeInScene); + OpcodeTim(tlol_unusedResourceFunc); + OpcodeTim(tlol_unusedResourceFunc); + + // 0x08 + OpcodeTim(tlol_fadeInPalette); + OpcodeTimUnImpl(); + OpcodeTimUnImpl(); + OpcodeTim(tlol_fadeOutSound); + + // 0x0C + OpcodeTim(tlol_displayAnimFrame); + OpcodeTim(tlol_delayForChat); + OpcodeTim(tlol_displayText); + OpcodeTimUnImpl(); + _timIngameOpcodes.reserve(17); SetTimOpcodeTable(_timIngameOpcodes); diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 521abc2556..1b1fd61d3b 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -98,7 +98,7 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys _textDisplayed = false; _textAreaBuffer = new uint8[320*40]; assert(_textAreaBuffer); - _drawPage2 = (vm()->gameFlags().isDemo && vm()->gameFlags().gameID == GI_LOL) ? 0 : 8; + _drawPage2 = (_vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL) ? 0 : 8; _palDelayInc = _palDiff = _palDelayAcc = 0; _abortFlag = 0; @@ -117,10 +117,10 @@ TIMInterpreter::~TIMInterpreter() { } TIM *TIMInterpreter::load(const char *filename, const Common::Array *opcodes) { - if (!vm()->resource()->exists(filename)) + if (!_vm->resource()->exists(filename)) return 0; - Common::SeekableReadStream *stream = vm()->resource()->createReadStream(filename); + Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename); if (!stream) error("Couldn't open TIM file '%s'", filename); @@ -176,6 +176,9 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Arrayfilename, filename, 13); tim->filename[12] = 0; + tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM"); + tim->lolCharacter = 0; + return tim; } @@ -191,7 +194,7 @@ void TIMInterpreter::unload(TIM *&tim) const { void TIMInterpreter::setLangData(const char *filename) { delete[] _langData; - _langData = vm()->resource()->fileData(filename, 0); + _langData = _vm->resource()->fileData(filename, 0); } int TIMInterpreter::exec(TIM *tim, bool loop) { @@ -254,11 +257,11 @@ int TIMInterpreter::exec(TIM *tim, bool loop) { if (cur.ip) { cur.ip += cur.ip[0]; cur.lastTime = cur.nextTime; - cur.nextTime += (cur.ip[1] ) * vm()->tickLength(); + cur.nextTime += (cur.ip[1] ) * _vm->tickLength(); } } } - } while (loop && !vm()->shouldQuit()); + } while (loop && !_vm->shouldQuit()); return _currentTim->clickedButton; } @@ -279,7 +282,7 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) { char *text = getTableEntry(textId); if (_textDisplayed) { - screen()->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer); + _screen->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer); _textDisplayed = false; } @@ -298,7 +301,7 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) { } if (filename[0]) - vm()->sound()->voicePlay(filename); + _vm->sound()->voicePlay(filename); if (text[0] == '$') text = strchr(text + 1, '$') + 1; @@ -308,13 +311,13 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) { if (flags < 0) { static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - screen()->setFont(Screen::FID_8_FNT); - screen()->setTextColorMap(colorMap); - screen()->_charWidth = -2; + _screen->setFont(Screen::FID_8_FNT); + _screen->setTextColorMap(colorMap); + _screen->_charWidth = -2; } - screen()->_charOffset = -4; - screen()->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer); + _screen->_charOffset = -4; + _screen->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer); _textDisplayed = true; char backupChar = 0; @@ -330,14 +333,14 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) { nextLine[0] = '\0'; } - int width = screen()->getTextWidth(str); + int width = _screen->getTextWidth(str); if (flags >= 0) - screen()->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00); + _screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00); else - screen()->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00); + _screen->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00); - heightAdd += screen()->getFontHeight(); + heightAdd += _screen->getFontHeight(); str += strlen(str); if (backupChar) { @@ -346,14 +349,66 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) { } } - screen()->_charOffset = 0; + _screen->_charOffset = 0; if (flags < 0) { static const uint8 colorMap[] = { 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00 }; - screen()->setFont(Screen::FID_INTRO_FNT); - screen()->setTextColorMap(colorMap); - screen()->_charWidth = 0; + _screen->setFont(Screen::FID_INTRO_FNT); + _screen->setTextColorMap(colorMap); + _screen->_charWidth = 0; + } +} + +void TIMInterpreter::displayText(uint16 textId, int16 flags, uint8 color) { + if (!_vm->textEnabled() && !(textId & 0x8000)) + return; + + char *text = getTableEntry(textId & 0x7FFF); + + if (flags > 0) + _screen->copyBlockToPage(0, 0, 0, 320, 40, _textAreaBuffer); + + if (flags == 255) + return; + + _screen->setFont(Screen::FID_INTRO_FNT); + + static const uint8 colorMap[] = { 0x00, 0xA0, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + _screen->setTextColorMap(colorMap); + _screen->_charWidth = 0; + _screen->_charOffset = -4; + + if (!flags) + _screen->copyRegionToBuffer(0, 0, 0, 320, 40, _textAreaBuffer); + + char backupChar = 0; + char *str = text; + int y = 0; + + while (str[0]) { + char *nextLine = strchr(str, '\r'); + + backupChar = 0; + if (nextLine) { + backupChar = nextLine[0]; + nextLine[0] = '\0'; + } + + int width = _screen->getTextWidth(str); + + if (flags >= 0) + _screen->printText(str, (320 - width) >> 1, y, color, 0x00); + else + _screen->printText(str, 0, y, color, 0x00); + + y += _screen->getFontHeight() - 4; + str += strlen(str); + + if (backupChar) { + nextLine[0] = backupChar; + ++str; + } } } @@ -368,7 +423,7 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) { }; for (int i = 0; i < 15; ++i) { - uint8 *palette = screen()->getPalette(0) + (240 + i) * 3; + uint8 *palette = _screen->getPalette(0) + (240 + i) * 3; uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100; uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100; @@ -380,29 +435,21 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) { } if (!fadePalette && !_palDiff) { - screen()->setScreenPalette(screen()->getPalette(0)); + _screen->setScreenPalette(_screen->getPalette(0)); } else { - screen()->getFadeParams(screen()->getPalette(0), fadePalette, _palDelayInc, _palDiff); + _screen->getFadeParams(_screen->getPalette(0), fadePalette, _palDelayInc, _palDiff); _palDelayAcc = 0; } } -KyraEngine_v1 *TIMInterpreter::vm() { - return _vm; -} - -Screen_v2 *TIMInterpreter::screen() { - return _screen; -} - TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) { Animation *anim = &_animations[index]; anim->x = x; anim->y = y; anim->wsaCopyParams = wsaFlags; - const bool isLoLDemo = vm()->gameFlags().isDemo && vm()->gameFlags().gameID == GI_LOL; + const bool isLoLDemo = _vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL; - _drawPage2 = isLoLDemo ? 0 : 8; + _drawPage2 = (isLoLDemo || _currentTim->isLoLOutro) ? 0 : 8; uint16 wsaOpenFlags = 0; if (isLoLDemo) { @@ -420,14 +467,14 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char char file[32]; snprintf(file, 32, "%s.WSA", filename); - if (vm()->resource()->exists(file)) { + if (_vm->resource()->exists(file)) { if (isLoLDemo) anim->wsa = new WSAMovie_v1(_vm); else anim->wsa = new WSAMovie_v2(_vm, _screen); assert(anim->wsa); - anim->wsa->open(file, wsaOpenFlags, (index == 1) ? screen()->getPalette(0) : 0); + anim->wsa->open(file, wsaOpenFlags, (index == 1) ? _screen->getPalette(0) : 0); } if (anim->wsa && anim->wsa->opened()) { @@ -453,50 +500,50 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char } if (wsaFlags & 2) { - screen()->fadePalette(screen()->getPalette(1), 15, 0); - screen()->clearPage(_drawPage2); + _screen->fadePalette(_screen->getPalette(1), 15, 0); + _screen->clearPage(_drawPage2); if (_drawPage2) - screen()->checkedPageUpdate(8, 4); - screen()->updateScreen(); + _screen->checkedPageUpdate(8, 4); + _screen->updateScreen(); } if (wsaFlags & 4) { snprintf(file, 32, "%s.CPS", filename); - if (vm()->resource()->exists(file)) { - screen()->loadBitmap(file, 3, 3, screen()->getPalette(0)); - screen()->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK); + if (_vm->resource()->exists(file)) { + _screen->loadBitmap(file, 3, 3, _screen->getPalette(0)); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK); if (_drawPage2) - screen()->checkedPageUpdate(8, 4); - screen()->updateScreen(); + _screen->checkedPageUpdate(8, 4); + _screen->updateScreen(); } anim->wsa->displayFrame(0, 0, x, y, 0); } if (wsaFlags & 2) - screen()->fadePalette(screen()->getPalette(0), 30, 0); + _screen->fadePalette(_screen->getPalette(0), 30, 0); } else { if (wsaFlags & 2) { - screen()->fadePalette(screen()->getPalette(1), 15, 0); - screen()->clearPage(_drawPage2); + _screen->fadePalette(_screen->getPalette(1), 15, 0); + _screen->clearPage(_drawPage2); if (_drawPage2) - screen()->checkedPageUpdate(8, 4); - screen()->updateScreen(); + _screen->checkedPageUpdate(8, 4); + _screen->updateScreen(); } snprintf(file, 32, "%s.CPS", filename); - if (vm()->resource()->exists(file)) { - screen()->loadBitmap(file, 3, 3, screen()->getPalette(0)); - screen()->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK); + if (_vm->resource()->exists(file)) { + _screen->loadBitmap(file, 3, 3, _screen->getPalette(0)); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK); if (_drawPage2) - screen()->checkedPageUpdate(8, 4); - screen()->updateScreen(); + _screen->checkedPageUpdate(8, 4); + _screen->updateScreen(); } if (wsaFlags & 2) - screen()->fadePalette(screen()->getPalette(0), 30, 0); + _screen->fadePalette(_screen->getPalette(0), 30, 0); } return anim; @@ -636,12 +683,15 @@ int TIMInterpreter::cmd_wsaDisplayFrame(const uint16 *param) { if (anim.wsa) anim.wsa->displayFrame(frame, page, anim.x, anim.y, anim.wsaCopyParams & 0xF0FF, 0, 0); if (!page) - screen()->updateScreen(); + _screen->updateScreen(); return 1; } int TIMInterpreter::cmd_displayText(const uint16 *param) { - displayText(param[0], param[1]); + if (_currentTim->isLoLOutro) + displayText(param[0], param[1], 0xF2); + else + displayText(param[0], param[1]); return 1; } @@ -650,6 +700,32 @@ int TIMInterpreter::cmd_loadVocFile(const uint16 *param) { const int index = param[1]; _vocFiles[index] = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (stringId << 1))); + + if (index == 2 && _currentTim->isLoLOutro) { + _vocFiles[index] = "CONGRATA.VOC"; + + switch (_currentTim->lolCharacter) { + case 0: + _vocFiles[index].setChar('K', 7); + break; + + case 1: + _vocFiles[index].setChar('A', 7); + break; + + case 2: + _vocFiles[index].setChar('M', 7); + break; + + case 3: + _vocFiles[index].setChar('C', 7); + break; + + default: + break; + } + } + for (int i = 0; i < 4; ++i) _vocFiles[index].deleteLastChar(); return 1; @@ -666,11 +742,11 @@ int TIMInterpreter::cmd_playVocFile(const uint16 *param) { const int volume = (param[1] * 255) / 100; if (index < ARRAYSIZE(_vocFiles) && !_vocFiles[index].empty()) - vm()->sound()->voicePlay(_vocFiles[index].c_str(), 0, volume, true); + _vm->sound()->voicePlay(_vocFiles[index].c_str(), 0, volume, true); else if (index == 7 && !_vm->gameFlags().isTalkie) - vm()->sound()->playTrack(index); + _vm->sound()->playTrack(index); else - vm()->sound()->playSoundEffect(index); + _vm->sound()->playSoundEffect(index); return 1; } @@ -678,15 +754,15 @@ int TIMInterpreter::cmd_playVocFile(const uint16 *param) { int TIMInterpreter::cmd_loadSoundFile(const uint16 *param) { const char *file = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[0]<<1))); - vm()->sound()->loadSoundFile(file); - if (vm()->gameFlags().gameID == GI_LOL) - vm()->sound()->loadSfxFile(file); + _vm->sound()->loadSoundFile(file); + if (_vm->gameFlags().gameID == GI_LOL) + _vm->sound()->loadSfxFile(file); return 1; } int TIMInterpreter::cmd_playMusicTrack(const uint16 *param) { - vm()->sound()->playTrack(param[0]); + _vm->sound()->playTrack(param[0]); return 1; } @@ -705,9 +781,9 @@ int TIMInterpreter::cmd_continueLoop(const uint16 *param) { uint16 factor = param[0]; if (factor) { - const uint32 random = vm()->_rnd.getRandomNumberRng(0, 0x8000); + const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000); uint32 waitTime = (random * factor) / 0x8000; - func.nextTime += waitTime * vm()->tickLength(); + func.nextTime += waitTime * _vm->tickLength(); } return -2; @@ -764,7 +840,7 @@ int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) { } int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) { - while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !vm()->shouldQuit()) { + while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) { update(); _currentTim->clickedButton = processDialogue(); } @@ -905,14 +981,6 @@ int TIMInterpreter_LoL::freeAnimStruct(int index) { return 1; } -KyraEngine_v1 *TIMInterpreter_LoL::vm() { - return _vm; -} - -Screen_v2 *TIMInterpreter_LoL::screen() { - return _screen; -} - void TIMInterpreter_LoL::advanceToOpcode(int opcode) { TIM::Function *f = &_currentTim->func[_currentTim->dlgFunc]; uint16 len = f->ip[0]; diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h index 2dbfff49d4..10337b4b09 100644 --- a/engines/kyra/script_tim.h +++ b/engines/kyra/script_tim.h @@ -80,6 +80,11 @@ struct TIM { uint8 *text; const Common::Array *opcodes; + + // TODO: Get rid of this ugly HACK to allow the + // Lands of Lore outro to be working properly. + bool isLoLOutro; + uint8 lolCharacter; }; class TIMInterpreter { @@ -134,6 +139,7 @@ public: void refreshTimersAfterPause(uint32 elapsedTime); void displayText(uint16 textId, int16 flags); + void displayText(uint16 textId, int16 flags, uint8 color); void setupTextPalette(uint index, int fadePalette); virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {} @@ -154,9 +160,6 @@ public: int _abortFlag; protected: - virtual KyraEngine_v1 *vm(); - virtual Screen_v2 *screen(); - KyraEngine_v1 *_vm; Screen_v2 *_screen; OSystem *_system; @@ -242,9 +245,6 @@ public: int resetAnimationLastPart(int animIndex); private: - KyraEngine_v1 *vm(); - Screen_v2 *screen(); - void update(); void checkSpeechProgress(); diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index bc5d723bbd..ab6007f060 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -42,6 +42,9 @@ public: virtual bool opened() { return _opened; } + virtual int xAdd() const { return 0; } + virtual int yAdd() const { return 0; } + virtual int width() const = 0; virtual int height() const = 0; -- cgit v1.2.3