diff options
author | Florian Kagerer | 2009-03-14 13:48:12 +0000 |
---|---|---|
committer | Florian Kagerer | 2009-03-14 13:48:12 +0000 |
commit | 092f2a37e3e8ef1283ee04281727ed113061ff27 (patch) | |
tree | 2851442f7002d0d93f5f1f3aa5e9558d6cc30eee /engines/kyra | |
parent | 6225bf905f95addf161790fb74268cf5fb0954c7 (diff) | |
download | scummvm-rg350-092f2a37e3e8ef1283ee04281727ed113061ff27.tar.gz scummvm-rg350-092f2a37e3e8ef1283ee04281727ed113061ff27.tar.bz2 scummvm-rg350-092f2a37e3e8ef1283ee04281727ed113061ff27.zip |
LOL: - complete support for the three "special rooms" in the castle
svn-id: r39391
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/items_lol.cpp | 47 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 75 | ||||
-rw-r--r-- | engines/kyra/lol.h | 38 | ||||
-rw-r--r-- | engines/kyra/resource.h | 2 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 177 | ||||
-rw-r--r-- | engines/kyra/script_tim.cpp | 166 | ||||
-rw-r--r-- | engines/kyra/script_tim.h | 48 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 6 | ||||
-rw-r--r-- | engines/kyra/text_lol.cpp | 13 |
9 files changed, 500 insertions, 72 deletions
diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 5eb0214ac6..3852bcf55b 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -31,10 +31,8 @@ namespace Kyra { void LoLEngine::giveCredits(int credits, int redraw) { - static const uint8 stashSetupData[] = { 4, 4, 4, 4, 2, 2, 2, 3, 3, 0, 1, 1 }; - if (redraw) - snd_playSoundEffect(0x65, 0xff); + snd_playSoundEffect(101, -1); int t = credits / 30; if (!t) @@ -51,7 +49,7 @@ void LoLEngine::giveCredits(int credits, int redraw) { do { if (_credits < 60) { - int d = stashSetupData[_credits % 12] - _credits / 12; + int d = _stashSetupData[_credits % 12] - _credits / 12; if (d < 0) d += 5; _moneyColumnHeight[d]++; @@ -71,6 +69,47 @@ void LoLEngine::giveCredits(int credits, int redraw) { } } +void LoLEngine::takeCredits(int credits, int redraw) { + if (redraw) + snd_playSoundEffect(101, -1); + + if (credits > _credits) + credits = _credits; + + int t = credits / 30; + if (!t) + t = 1; + + int cnt = 0; + + while (credits && _credits > 0) { + if (t > credits) + t = credits; + + if (_credits - t < 60 && t >= 0) { + cnt = 0; + + do { + if (--_credits < 60) { + int d = _stashSetupData[_credits % 12] - _credits / 12; + if (d < 0) + d += 5; + _moneyColumnHeight[d]--; + } + } while (++cnt < t); + } else if (_credits - t < 60) { + _credits -= t; + } + + if (redraw) { + gui_drawMoneyBox(6); + if (credits) + delay(_tickLength, 1); + } + credits -= t; + } +} + int LoLEngine::makeItem(int itemIndex, int curFrame, int flags) { int cnt = 0; int r = 0; diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index ceb756b3c7..022375fd90 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -76,7 +76,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _lastMusicTrack = -1; _lastSfxTrack = -1; _curTlkFile = -1; - _lastSpeaker = _lastSpeechId = -1; + _lastSpeaker = _lastSpeechId = _nextSpeechId = _nextSpeaker = -1; memset(_moneyColumnHeight, 0, 5); _credits = 0; @@ -95,6 +95,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _monsterShapesEx = 0; _gameShapeMap = 0; memset(_monsterUnk, 0, 3); + _pageSavedFlag = false; _ingameMT32SoundIndex = _ingameGMSoundIndex = /*_ingameADLSoundIndex =*/ 0; @@ -791,7 +792,7 @@ void LoLEngine::runLoop() { } void LoLEngine::update() { - updateWsaAnimations(); + updateSequenceBackgroundAnimations(); if (_updateCharNum != -1 && _system->getMillis() > _updatePortraitNext) updatePortraitSpeechAnim(); @@ -1278,11 +1279,31 @@ void LoLEngine::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness } } -void LoLEngine::updateWsaAnimations() { +void LoLEngine::updateSequenceBackgroundAnimations() { if (_updateFlags & 8) return; - //TODO + for (int i = 0; i < 6; i++) + _tim->updateBackgroundAnimation(i); +} + +void LoLEngine::savePage5() { + if (_pageSavedFlag) + return; + + _screen->copyRegionToBuffer(5, 0, 0, 320, 200, _pageBuffer2); + _pageSavedFlag = true; +} + +void LoLEngine::restorePage5() { + if (!_pageSavedFlag) + return; + + for (int i = 0; i < 6; i++) + _tim->freeAnimStruct(i); + + _screen->copyBlockToPage(5, 0, 0, 320, 200, _pageBuffer2); + _pageSavedFlag = false; } void LoLEngine::loadTalkFile(int index) { @@ -1319,6 +1340,7 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { _lastSpeechId = id; _lastSpeaker = speaker; + _nextSpeechId = _nextSpeaker = -1; Common::List<const char*> playList; @@ -1326,6 +1348,8 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { char pattern2[5]; char file1[13]; char file2[13]; + char file3[13]; + file3[0] = 0; snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile); @@ -1334,23 +1358,30 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { } else if (id < 1000) { snprintf(pattern1, sizeof(pattern1), "%03d", id); } else { - snprintf(pattern1, sizeof(pattern1), "@%04d", id - 1000); + snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2); + if (_res->exists(file3)) { + char *f = new char[strlen(file3) + 1]; + strcpy(f, file3); + playList.push_back(f); + } } - for (char i = 0; ; i++) { - char symbol = '0' + i; - snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2); - snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2); - if (_res->exists(file1)) { - char *f = new char[strlen(file1) + 1]; - strcpy(f, file1); - playList.push_back(f); - } else if (_res->exists(file2)) { - char *f = new char[strlen(file2) + 1]; - strcpy(f, file2); - playList.push_back(f); - } else { - break; + if (!file3[0]) { + for (char i = 0; ; i++) { + char symbol = '0' + i; + snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2); + snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2); + if (_res->exists(file1)) { + char *f = new char[strlen(file1) + 1]; + strcpy(f, file1); + playList.push_back(f); + } else if (_res->exists(file2)) { + char *f = new char[strlen(file2) + 1]; + strcpy(f, file2); + playList.push_back(f); + } else { + break; + } } } @@ -1381,6 +1412,11 @@ int LoLEngine::snd_characterSpeaking() { _lastSpeechId = _lastSpeaker = -1; _activeVoiceFileTotalTime = 0; + if (_nextSpeechId != -1) { + if (snd_playCharacterSpeech(_nextSpeechId, _nextSpeaker, 0)) + return 2; + } + return 1; } @@ -1391,6 +1427,7 @@ void LoLEngine::snd_stopSpeech(bool setFlag) { //_dlgTimer = 0; _sound->voiceStop(_activeVoiceFile); _activeVoiceFileTotalTime = 0; + _nextSpeechId = _nextSpeaker = -1; if (setFlag) _tim->_abortFlag = 1; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index f433de7f4c..3759953536 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -344,6 +344,8 @@ private: int _environmentSfx; int _environmentSfxVol; int _environmentSfxDistThreshold; + int _nextSpeechId; + int _nextSpeaker; int _curTlkFile; int _speechFlag; @@ -476,7 +478,7 @@ private: // text bool characterSays(int track, int charId, bool redraw); - int playCharacterScriptChat(int charId, int y, int unk1, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex); + int playCharacterScriptChat(int charId, int mode, int unk1, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex); TextDisplayer_LoL *_txt; @@ -516,12 +518,17 @@ private: int olol_closeLevelShapeFile(EMCState *script); int olol_loadDoorShapes(EMCState *script); int olol_initAnimStruct(EMCState *script); + int olol_playAnimSequence(EMCState *script); int olol_freeAnimStruct(EMCState *script); int olol_getDirection(EMCState *script); int olol_setMusicTrack(EMCState *script); int olol_checkRectForMousePointer(EMCState *script); int olol_clearDialogueField(EMCState *script); + int olol_setupBackgroundAnimationPart(EMCState *script); + int olol_startBackgroundAnimation(EMCState *script); + int olol_fadePalette(EMCState *script); int olol_loadBitmap(EMCState *script); + int olol_stopBackgroundAnimation(EMCState *script); int olol_getGlobalScriptVar(EMCState *script); int olol_setGlobalScriptVar(EMCState *script); int olol_getGlobalVar(EMCState *script); @@ -533,10 +540,14 @@ private: int olol_copyRegion(EMCState *script); int olol_initMonster(EMCState *script); int olol_fadeClearSceneWindow(EMCState *script); + int olol_fadeSequencePalette(EMCState *script); int olol_loadMonsterProperties(EMCState *script); int olol_moveMonster(EMCState *script); int olol_dialogueBox(EMCState *script); + int olol_giveTakeMoney(EMCState *script); + int olol_checkMoney(EMCState *script); int olol_setScriptTimer(EMCState *script); + int olol_createHandItem(EMCState *script); int olol_loadTimScript(EMCState *script); int olol_runTimScript(EMCState *script); int olol_releaseTimScript(EMCState *script); @@ -562,11 +573,15 @@ private: int olol_setNextFunc(EMCState *script); int olol_setDoorState(EMCState *script); int olol_processButtonClick(EMCState *script); + int olol_savePage5(EMCState *script); + int olol_restorePage5(EMCState *script); int olol_initNonAnimatedDialogue(EMCState *script); int olol_restoreAfterNonAnimatedDialogue(EMCState *script); int olol_assignCustomSfx(EMCState *script); int olol_resetPortraitsArea(EMCState *script); int olol_enableSysTimer(EMCState *script); + int olol_queueSpeech(EMCState *script); + int olol_getItemPrice(EMCState *script); // tim scripts TIM *_activeTim[10]; @@ -586,11 +601,16 @@ private: int tlol_giveItem(const TIM *tim, const uint16 *param); int tlol_setPartyPosition(const TIM *tim, const uint16 *param); int tlol_fadeClearWindow(const TIM *tim, const uint16 *param); + int tlol_copyRegion(const TIM *tim, const uint16 *param); + int tlol_characterChat(const TIM *tim, const uint16 *param); + int tlol_drawScene(const TIM *tim, const uint16 *param); int tlol_update(const TIM *tim, const uint16 *param); int tlol_loadSoundFile(const TIM *tim, const uint16 *param); int tlol_playMusicTrack(const TIM *tim, const uint16 *param); int tlol_playDialogueTalkText(const TIM *tim, const uint16 *param); int tlol_playSoundEffect(const TIM *tim, const uint16 *param); + int tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param); + int tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param); Common::Array<const TIMOpcode*> _timIngameOpcodes; @@ -619,7 +639,9 @@ private: void fadeText(); void setPaletteBrightness(uint8 *palette, int brightness, int modifier); void generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier); - void updateWsaAnimations(); + void updateSequenceBackgroundAnimations(); + void savePage5(); + void restorePage5(); bool _dialogueField; uint8 **_itemIconShapes; @@ -640,6 +662,8 @@ private: uint8 *_characterFaceShapes[40][3]; + bool _pageSavedFlag; + // characters bool addCharacter(int id); void initCharacter(int charNum, int firstFaceFrame, int unk2, int redraw); @@ -916,6 +940,7 @@ private: // items void giveCredits(int credits, int redraw); + void takeCredits(int credits, int redraw); int makeItem(int itemIndex, int curFrame, int flags); bool addItemToInventory(int itemIndex); bool testUnkItemFlags(int itemIndex); @@ -940,15 +965,18 @@ private: int _hideControls; int _lastCharInventory; + EMCData _itemScript; + const uint8 *_charInvIndex; int _charInvIndexSize; const uint8 *_charInvDefs; int _charInvDefsSize; - - EMCData _itemScript; - const uint16 *_inventorySlotDesc; int _inventorySlotDescSize; + const uint16 *_itemCost; + int _itemCostSize; + const uint8 *_stashSetupData; + int _stashSetupDataSize; // monsters void loadMonsterShapes(const char *file, int monsterIndex, int b); diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 66cc883667..3de89bc3c9 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -240,6 +240,8 @@ enum kKyraResources { kLolLevelShpList, kLolLevelDatList, kLolCompassDefs, + kLolItemPrices, + kLolStashSetup, kLolDscUnk1, kLolDscShapeIndex, diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 2e6e9671ec..d9a7d9cb6e 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -421,6 +421,12 @@ int LoLEngine::olol_initAnimStruct(EMCState *script) { return 0; } +int LoLEngine::olol_playAnimSequence(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAnimSequence(%p) (%s, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); + + return 1; +} + int LoLEngine::olol_freeAnimStruct(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_freeAnimStruct(%p) (%d)", (const void *)script, stackPos(0)); if (_tim->freeAnimStruct(stackPos(0))) @@ -457,6 +463,25 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) { return 1; } +int LoLEngine::olol_setupBackgroundAnimationPart(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupBackgroundAnimationPart(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); + _tim->setupBackgroundAnimationPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); + return 0; +} + +int LoLEngine::olol_startBackgroundAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_startBackgroundAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _tim->startBackgroundAnimation(stackPos(0), stackPos(1)); + return 1; +} + +int LoLEngine::olol_fadePalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadePalette(%p)", (const void *)script); + _screen->fadePalette(_screen->getPalette(3), 10); + _screen->_fadeFlag = 0; + return 1; +} + int LoLEngine::olol_loadBitmap(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_clearDialogueField(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->loadBitmap(stackPosString(0), 3, 3, _screen->getPalette(3)); @@ -465,6 +490,12 @@ int LoLEngine::olol_loadBitmap(EMCState *script) { return 1; } +int LoLEngine::olol_stopBackgroundAnimation(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopBackgroundAnimation(%p) (%d)", (const void *)script, stackPos(0)); + _tim->stopBackgroundAnimation(stackPos(0)); + return 1; +} + int LoLEngine::olol_getGlobalScriptVar(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getGlobalScriptVar(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < 16); @@ -681,6 +712,15 @@ int LoLEngine::olol_fadeClearSceneWindow(EMCState *script) { return 1; } +int LoLEngine::olol_fadeSequencePalette(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeSequencePalette(%p)", (const void *)script); + memcpy(_screen->getPalette(3) + 0x180, _screen->_currentPalette + 0x180, 0x180); + _screen->loadSpecialColours(_screen->getPalette(3)); + _screen->fadePalette(_screen->getPalette(3), 10); + _screen->_fadeFlag = 0; + return 1; +} + int LoLEngine::olol_loadMonsterProperties(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), @@ -763,6 +803,22 @@ int LoLEngine::olol_dialogueBox(EMCState *script) { return 1; } +int LoLEngine::olol_giveTakeMoney(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveTakeMoney(%p) (%d)", (const void *)script, stackPos(0)); + int c = stackPos(0); + if (c >= 0) + giveCredits(c, 1); + else + takeCredits(-c, 1); + + return 1; +} + +int LoLEngine::olol_checkMoney(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMoney(%p) (%d)", (const void *)script, stackPos(0)); + return (stackPos(0) > _credits) ? 0 : 1; +} + int LoLEngine::olol_setScriptTimer(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setScriptTimer(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); uint8 id = 0x50 + stackPos(0); @@ -778,6 +834,14 @@ int LoLEngine::olol_setScriptTimer(EMCState *script) { return 1; } +int LoLEngine::olol_createHandItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createHandItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + if (_itemInHand) + return 0; + setHandItem(makeItem(stackPos(0), stackPos(1), stackPos(2))); + return 1; +} + int LoLEngine::olol_loadTimScript(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1)); if (_activeTim[stackPos(0)]) @@ -967,10 +1031,19 @@ int LoLEngine::olol_setDoorState(EMCState *script) { int LoLEngine::olol_processButtonClick(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_processButtonClick(%p) (%d)", (const void *)script, stackPos(0)); - int n = _tim->getNumberOfDialogueButtons(); - _activeTim[stackPos(0)]->procFunc = 0; - _activeTim[stackPos(0)]->procParam = n ? n : 1; - _tim->setDialogueParameters(0, -1); + _tim->resetDialogueState(_activeTim[stackPos(0)]); + return 1; +} + +int LoLEngine::olol_savePage5(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_savePage5(%p)", (const void *)script); + savePage5(); + return 1; +} + +int LoLEngine::olol_restorePage5(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restorePage5(%p)", (const void *)script); + restorePage5(); return 1; } @@ -1014,6 +1087,34 @@ int LoLEngine::olol_enableSysTimer(EMCState *script) { return 1; } +int LoLEngine::olol_queueSpeech(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_queueSpeech(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + if (stackPos(0) && stackPos(1)) { + _nextSpeechId = stackPos(0) + 1000; + _nextSpeaker = stackPos(1); + } + return 1; +} + +int LoLEngine::olol_getItemPrice(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getItemPrice(%p) (%d)", (const void *)script, stackPos(0)); + int c = stackPos(0); + if (c < 0) { + c = -c; + if (c < 50) + return 50; + c = (c + 99) / 100; + return c * 100; + + } else { + for (int i = 0; i < 46; i++) { + if (_itemCost[i] >= c) + return _itemCost[i]; + } + } + + return 0; +} #pragma mark - @@ -1158,6 +1259,26 @@ int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) { return 1; } +int LoLEngine::tlol_copyRegion(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_copyRegion(%p, %p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void*)tim, (const void*)param, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7]); + _screen->copyRegion(param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], Screen::CR_NO_P_CHECK); + return 1; +} + +int LoLEngine::tlol_characterChat(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_characterChat(%p, %p) (%d, %d, %d)", (const void*)tim, (const void*)param, param[0], param[1], param[2]); + playCharacterScriptChat(param[0], param[1], 1, getLangString(param[2]), 0, param, 3); + return 1; +} + +int LoLEngine::tlol_drawScene(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_drawScene(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); + gui_drawScene(param[0]); + if (_sceneDrawPage2 != 2 && param[0] == 2) + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage2, 2, Screen::CR_NO_P_CHECK); + return 1; +} + int LoLEngine::tlol_update(const TIM *tim, const uint16 *param) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_update(%p, %p)", (const void*)tim, (const void*)param); update(); @@ -1189,6 +1310,18 @@ int LoLEngine::tlol_playSoundEffect(const TIM *tim, const uint16 *param) { return 1; } +int LoLEngine::tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_startBackgroundAnimation(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], param[1]); + _tim->startBackgroundAnimation(param[0], param[1]); + return 1; +} + +int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_stopBackgroundAnimation(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]); + _tim->stopBackgroundAnimation(param[0]); + return 1; +} + #pragma mark - typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2; @@ -1244,7 +1377,7 @@ void LoLEngine::setupOpcodeTable() { // 0x18 Opcode(olol_loadDoorShapes); Opcode(olol_initAnimStruct); - OpcodeUnImpl(); + Opcode(olol_playAnimSequence); Opcode(olol_freeAnimStruct); // 0x1C @@ -1257,18 +1390,18 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); Opcode(olol_checkRectForMousePointer); Opcode(olol_clearDialogueField); - OpcodeUnImpl(); + Opcode(olol_setupBackgroundAnimationPart); // 0x24 - OpcodeUnImpl(); + Opcode(olol_startBackgroundAnimation); OpcodeUnImpl(); OpcodeUnImpl(); OpcodeUnImpl(); // 0x28 - OpcodeUnImpl(); + Opcode(olol_fadePalette); Opcode(olol_loadBitmap); - OpcodeUnImpl(); + Opcode(olol_stopBackgroundAnimation); OpcodeUnImpl(); // 0x2C @@ -1292,7 +1425,7 @@ void LoLEngine::setupOpcodeTable() { // 0x38 Opcode(olol_initMonster); Opcode(olol_fadeClearSceneWindow); - OpcodeUnImpl(); + Opcode(olol_fadeSequencePalette); OpcodeUnImpl(); // 0x3C @@ -1310,12 +1443,12 @@ void LoLEngine::setupOpcodeTable() { // 0x44 Opcode(olol_moveMonster); Opcode(olol_dialogueBox); - OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_giveTakeMoney); + Opcode(olol_checkMoney); // 0x48 Opcode(olol_setScriptTimer); - OpcodeUnImpl(); + Opcode(olol_createHandItem); OpcodeUnImpl(); OpcodeUnImpl(); @@ -1412,8 +1545,8 @@ void LoLEngine::setupOpcodeTable() { // 0x88 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_savePage5); + Opcode(olol_restorePage5); // 0x8C Opcode(olol_initNonAnimatedDialogue); @@ -1488,8 +1621,8 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); // 0xBC - OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_queueSpeech); + Opcode(olol_getItemPrice); OpcodeUnImpl(); OpcodeUnImpl(); @@ -1519,11 +1652,11 @@ void LoLEngine::setupOpcodeTable() { // 0x04 OpcodeTim(tlol_setPartyPosition); OpcodeTim(tlol_fadeClearWindow); - OpcodeTimUnImpl(); - OpcodeTimUnImpl(); + OpcodeTim(tlol_copyRegion); + OpcodeTim(tlol_characterChat); // 0x08 - OpcodeTimUnImpl(); + OpcodeTim(tlol_drawScene); OpcodeTim(tlol_update); OpcodeTimUnImpl(); OpcodeTim(tlol_loadSoundFile); @@ -1532,10 +1665,10 @@ void LoLEngine::setupOpcodeTable() { OpcodeTim(tlol_playMusicTrack); OpcodeTim(tlol_playDialogueTalkText); OpcodeTim(tlol_playSoundEffect); - OpcodeTimUnImpl(); + OpcodeTim(tlol_startBackgroundAnimation); // 0x10 - OpcodeTimUnImpl(); + OpcodeTim(tlol_stopBackgroundAnimation); } } // end of namespace Kyra diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 3150e7ab01..207f53b8de 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -90,7 +90,9 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys _commands = commandProcs ; _commandsSize = ARRAYSIZE(commandProcs); - memset(&_animations, 0, sizeof(_animations)); + _animations = new Animation[TIM::kWSASlots]; + memset(_animations, 0, TIM::kWSASlots * sizeof(Animation)); + _langData = 0; _textDisplayed = false; _textAreaBuffer = new uint8[320*40]; @@ -104,6 +106,13 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys TIMInterpreter::~TIMInterpreter() { delete[] _langData; delete[] _textAreaBuffer; + + for (int i = 0; i < TIM::kWSASlots; i++) { + delete _animations[i].wsa; + delete[] _animations[i].parts; + } + + delete[] _animations; } TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes) { @@ -196,7 +205,6 @@ int TIMInterpreter::exec(TIM *tim, bool loop) { if (cnt++ > 0) { if (_currentTim->procFunc != -1) execCommand(28, &_currentTim->procParam); - update(); } @@ -451,7 +459,6 @@ int TIMInterpreter::freeAnimStruct(int index) { delete anim->wsa; memset(anim, 0, sizeof(Animation)); - return 1; } @@ -539,8 +546,16 @@ int TIMInterpreter::cmd_uninitWSA(const uint16 *param) { //XXX delete anim.wsa; + bool hasParts = anim.parts ? true : false; + delete[] anim.parts; + memset(&anim, 0, sizeof(Animation)); memset(&slot, 0, sizeof(TIM::WSASlot)); + + if (hasParts) { + anim.parts = new AnimPart[TIM::kAnimParts]; + memset(anim.parts, 0, TIM::kAnimParts * sizeof(AnimPart)); + } } return 1; @@ -698,7 +713,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(); } @@ -768,6 +783,11 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2, _commandsSize = ARRAYSIZE(commandProcs); _screen = engine->_screen; + + for (int i = 0; i < TIM::kWSASlots; i++) { + _animations[i].parts = new AnimPart[TIM::kAnimParts]; + memset(_animations[i].parts, 0, TIM::kAnimParts * sizeof(AnimPart)); + } _drawPage2 = 0; @@ -775,11 +795,14 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2, _dialogueButtonPosX = _dialogueButtonPosY = _dialogueNumButtons = _dialogueButtonXoffs = _dialogueHighlightedButton = 0; } -TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int copyPara, int, uint16 wsaFlags) { +TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int offscreenBuffer, uint16 wsaFlags) { Animation *anim = &_animations[index]; anim->x = x; anim->y = y; + anim->frameDelay = frameDelay; anim->wsaCopyParams = wsaFlags; + anim->enable = 0; + anim->lastPart = -1; uint16 wsaOpenFlags = 0; if (wsaFlags & 0x10) @@ -822,6 +845,21 @@ TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const c return anim; } +int TIMInterpreter_LoL::freeAnimStruct(int index) { + Animation *anim = &_animations[index]; + if (!anim) + return 0; + + delete anim->wsa; + delete[] anim->parts; + memset(anim, 0, sizeof(Animation)); + + anim->parts = new AnimPart[TIM::kAnimParts]; + memset(anim->parts, 0, TIM::kAnimParts * sizeof(AnimPart)); + + return 1; +} + KyraEngine_v1 *TIMInterpreter_LoL::vm() { return _vm; } @@ -847,11 +885,12 @@ void TIMInterpreter_LoL::advanceToOpcode(int opcode) { } void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) { + _screen->setScreenDim(5); + if (numStr == 1 && _vm->_speechFlag) { - _screen->setScreenDim(5); + _dialogueNumButtons = 0; _dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0; } else { - _screen->setScreenDim(5); _dialogueNumButtons = numStr; _dialogueButtonString[0] = s1; _dialogueButtonString[1] = s2; @@ -876,6 +915,96 @@ void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char _vm->removeInputTop(); } +void TIMInterpreter_LoL::setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) { + AnimPart *a = &_animations[animIndex].parts[part]; + a->firstFrame = firstFrame; + a->lastFrame = lastFrame; + a->cycles = cycles; + a->nextPart = nextPart; + a->partDelay = partDelay; + a->field_A = f; + a->sfxIndex = sfxIndex; + a->sfxFrame = sfxFrame; +} + +void TIMInterpreter_LoL::startBackgroundAnimation(int animIndex, int part) { + Animation *anim = &_animations[animIndex]; + anim->curPart = part; + AnimPart *p = &anim->parts[part]; + anim->enable = 1; + anim->nextFrame = _system->getMillis() + anim->frameDelay * _vm->_tickLength; + anim->curFrame = p->firstFrame; + anim->cyclesCompleted = 0; + + anim->wsa->setX(anim->x); + anim->wsa->setY(anim->y); + anim->wsa->setDrawPage(0); + anim->wsa->displayFrame(anim->curFrame - 1, 0, 0); +} + +void TIMInterpreter_LoL::stopBackgroundAnimation(int animIndex) { + Animation *anim = &_animations[animIndex]; + anim->enable = 0; + anim->field_D = 0; + if (animIndex == 5) { + delete anim->wsa; + anim->wsa = 0; + } +} + +void TIMInterpreter_LoL::updateBackgroundAnimation(int animIndex) { + Animation *anim = &_animations[animIndex]; + if (!anim->enable || anim->nextFrame >= _system->getMillis()) + return; + + AnimPart *p = &anim->parts[anim->curPart]; + anim->nextFrame = 0; + + int step = 0; + if (p->lastFrame >= p->firstFrame) { + step = 1; + anim->curFrame++; + } else { + step = -1; + anim->curFrame--; + } + + if (anim->curFrame == (p->lastFrame + step)) { + anim->cyclesCompleted++; + + if ((anim->cyclesCompleted > p->cycles) || anim->field_D) { + anim->lastPart = anim->curPart; + + if ((p->nextPart == -1) || (anim->field_D && p->field_A)) { + anim->enable = 0; + anim->field_D = 0; + return; + } + + anim->nextFrame += (p->partDelay * _vm->_tickLength); + anim->curPart = p->nextPart; + + p = &anim->parts[anim->curPart]; + anim->curFrame = p->firstFrame; + anim->cyclesCompleted = 0; + + } else { + anim->curFrame = p->firstFrame; + } + } + + if (p->sfxIndex != -1 && p->sfxFrame == anim->curFrame) + _vm->snd_playSoundEffect(p->sfxIndex, -1); + + anim->nextFrame += (anim->frameDelay * _vm->_tickLength); + + anim->wsa->setX(anim->x); + anim->wsa->setY(anim->y); + anim->wsa->setDrawPage(0); + anim->wsa->displayFrame(anim->curFrame - 1, 0, 0); + anim->nextFrame += _system->getMillis(); +} + void TIMInterpreter_LoL::drawDialogueButtons() { int cp = _screen->setCurPage(0); Screen::FontId of = _screen->setFont(Screen::FID_6_FNT); @@ -996,6 +1125,16 @@ uint16 TIMInterpreter_LoL::processDialogue() { return res; } +void TIMInterpreter_LoL::resetDialogueState(TIM *tim) { + if (!tim) + return; + + tim->procFunc = 0; + tim->procParam = _dialogueNumButtons ? _dialogueNumButtons : 1; + tim->clickedButton = 0; + tim->dlgFunc = -1; +} + void TIMInterpreter_LoL::update() { _vm->update(); } @@ -1007,6 +1146,10 @@ void TIMInterpreter_LoL::checkSpeechProgress() { _currentTim->dlgFunc = _currentFunc; advanceToOpcode(21); _currentTim->dlgFunc = -1; + _animations[5].field_D = 0; + _animations[5].enable = 0; + delete _animations[5].wsa; + _animations[5].wsa = 0; } } } @@ -1064,8 +1207,8 @@ int TIMInterpreter_LoL::cmd_continueLoop(const uint16 *param) { int TIMInterpreter_LoL::cmd_processDialogue(const uint16 *param) { int res = processDialogue(); - if (!res ||!_currentTim->procParam) - return 0; + if (!res || !_currentTim->procParam) + return res; _vm->snd_stopSpeech(false); @@ -1074,6 +1217,11 @@ int TIMInterpreter_LoL::cmd_processDialogue(const uint16 *param) { _currentTim->procFunc = -1; _currentTim->clickedButton = res; + _animations[5].field_D = 0; + _animations[5].enable = 0; + delete _animations[5].wsa; + _animations[5].wsa = 0; + if (_currentTim->procParam) advanceToOpcode(21); diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h index eb3d972fa2..f73c63a2c7 100644 --- a/engines/kyra/script_tim.h +++ b/engines/kyra/script_tim.h @@ -64,7 +64,8 @@ struct TIM { } func[kCountFuncs]; enum { - kWSASlots = 10 + kWSASlots = 6, + kAnimParts = 10 }; struct WSASlot { @@ -83,10 +84,30 @@ struct TIM { class TIMInterpreter { public: + struct AnimPart { + uint16 firstFrame; + uint16 lastFrame; + uint16 cycles; + int16 nextPart; + int16 partDelay; + uint16 field_A; + int16 sfxIndex; + uint16 sfxFrame; + }; + struct Animation { WSAMovie_v2 *wsa; int16 x, y; + uint32 nextFrame; + uint8 enable; + uint8 field_D; + uint8 frameDelay; + int8 curPart; + uint8 curFrame; + uint8 cyclesCompleted; uint16 wsaCopyParams; + int8 lastPart; + AnimPart *parts; }; TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system); @@ -96,7 +117,7 @@ public: void unload(TIM *&tim) const; virtual Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags); - int freeAnimStruct(int index); + virtual int freeAnimStruct(int index); void setLangData(const char *filename); void clearLangData() { delete[] _langData; _langData = 0; } @@ -118,8 +139,12 @@ public: virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {} virtual uint16 processDialogue() { return 1; } - void setDialogueParameters(int clickedButton, int dlgFunc) { _currentTim->clickedButton = clickedButton; _currentTim->dlgFunc = dlgFunc; } - virtual int getNumberOfDialogueButtons() { return 0; } + virtual void setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) {} + virtual void startBackgroundAnimation(int animIndex, int part) {} + virtual void stopBackgroundAnimation(int animIndex) {} + virtual void updateBackgroundAnimation(int animIndex) {} + + virtual void resetDialogueState(TIM *tim) {} int _drawPage2; @@ -141,7 +166,7 @@ protected: Common::String _vocFiles[120]; - Animation _animations[TIM::kWSASlots]; + Animation *_animations; virtual void update() {} virtual void checkSpeechProgress() {} @@ -199,12 +224,19 @@ class TIMInterpreter_LoL : public TIMInterpreter { friend class LoLEngine; public: TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system); - Animation *initAnimStruct(int index, const char *filename, int x, int y, int copyPara, int, uint16 wsaFlags); + Animation *initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int offscreenBuffer, uint16 wsaCopyParams); + int freeAnimStruct(int index); + void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3); uint16 processDialogue(); + + void setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame); + void startBackgroundAnimation(int animIndex, int part); + void stopBackgroundAnimation(int animIndex); + void updateBackgroundAnimation(int animIndex); - int getNumberOfDialogueButtons() { return _dialogueNumButtons; } + void resetDialogueState(TIM *tim); private: KyraEngine_v1 *vm(); @@ -212,7 +244,7 @@ private: void update(); void checkSpeechProgress(); - + char *getTableString(int id); void advanceToOpcode(int opcode); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 03bc59448b..dfe1f00d56 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@ namespace Kyra { -#define RESFILE_VERSION 40 +#define RESFILE_VERSION 41 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -401,6 +401,8 @@ bool StaticResource::init() { { kLolLevelShpList, kStringList, "SHPFILES.TXT" }, { kLolLevelDatList, kStringList, "DATFILES.TXT" }, { kLolCompassDefs, kLolCompassData, "COMPASS.DEF" }, + { kLolItemPrices, kLolRawDataBe16, "ITEMCOST.DEF" }, + { kLolStashSetup, kRawData, "MONEYSTS.DEF" }, { kLolDscUnk1, kRawData, "DSCSHPU1.DEF" }, { kLolDscShapeIndex, kRawData, "DSCSHPI1.DEF" }, @@ -1771,6 +1773,8 @@ void LoLEngine::initStaticResource() { _levelShpList = _staticres->loadStrings(kLolLevelShpList, _levelShpListSize); _levelDatList = _staticres->loadStrings(kLolLevelDatList, _levelDatListSize); _compassDefs = _staticres->loadCompassData(kLolCompassDefs, _compassDefsSize); + _itemCost = _staticres->loadRawDataBe16(kLolItemPrices, _itemCostSize); + _stashSetupData = _staticres->loadRawData(kLolStashSetup, _stashSetupDataSize); _dscUnk1 = (const int8*)_staticres->loadRawData(kLolDscUnk1, _dscUnk1Size); _dscShapeIndex = (const int8*)_staticres->loadRawData(kLolDscShapeIndex, _dscShapeIndexSize); diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index 99be70214a..7b0024d62d 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -187,15 +187,16 @@ void TextDisplayer_LoL::printMessage(uint16 type, char *str, ...) { if (_vm->_updateFlags & 2) { _screen->setScreenDim(4); - clearCurDim(); + clearCurDim(); + _colour1 = col; } else { _screen->setScreenDim(3); clearCurDim(); _screen->copyColour(192, col); + _colour1 = 192; _vm->enableTimer(11); } - - _colour1 = 192; + _colour1prot = true; va_list args; @@ -551,7 +552,11 @@ void TextDisplayer_LoL::printLine(char *str) { if (str[s] == ' ') s++; - strcpy(str, &str[s]); + uint32 len = strlen(&str[s]); + for (uint32 i = 0; i < len; i++) + str[i] = str[s + i]; + str[len] = 0; + _numCharsLeft = strlen(str); _lineWidth = _screen->getTextWidth(str); |