From 837ca0683e758f7a822452c53b2bff69fa554099 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Mon, 23 Feb 2009 20:17:53 +0000 Subject: LOL: - some more work on the interface (you can now click on the banners and windows) and some bug fixes svn-id: r38818 --- engines/kyra/gui_lol.cpp | 62 +++++++++++++- engines/kyra/items_lol.cpp | 57 ++++++++++++- engines/kyra/lol.cpp | 202 ++++++++++++++++++++++++++++---------------- engines/kyra/lol.h | 91 ++++++++++++-------- engines/kyra/scene_lol.cpp | 120 ++++++++++++++++++++------ engines/kyra/script_lol.cpp | 84 +++++++++++++++--- engines/kyra/staticres.cpp | 20 ++--- engines/kyra/text_lol.cpp | 129 ++++++++++------------------ engines/kyra/text_lol.h | 8 +- engines/kyra/timer_lol.cpp | 28 ++++-- 10 files changed, 539 insertions(+), 262 deletions(-) (limited to 'engines/kyra') diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 3dbf6f826e..81f65c0a9d 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -1193,15 +1193,39 @@ int LoLEngine::clickedUnk16(Button *button) { return 1; } -int LoLEngine::clickedScene1(Button *button) { +int LoLEngine::clickedScenePickupItem(Button *button) { + static const int8 checkX[] = { 0, 0, 1, 0, -1, -1, 1, 1, -1, 0, 2, 0, -2, -1, 1, 2, 2, 1, -1, -2, -2 }; + static const int8 checkY[] = { 0, -1, 0, 1, 0, -1, -1, 1, 1, -2, 0, 2, 0, -2, -2, -1, 1, 2, 2, 1, -1 }; + if (_updateFlags & 1) return 0; int cp = _screen->setCurPage(_sceneDrawPage1); clickSceneSub1(); + int p = 0; + for (int i = 0; i < 21; i++) { + p = _screen->getPagePixel(_screen->_curPage, _mouseX + checkX[i], _mouseY + checkY[i]); + if (p) + break; + } + _screen->setCurPage(cp); + if (!p) + return 0; + + uint16 block = (p <= 128) ? calcNewBlockPosition(_currentBlock, _currentDirection) : _currentBlock; + + int found = checkSceneForItems(&_levelBlockProperties[block], p &0x7f); + + if (found != -1) { + foundItemSub(found, block); + setHandItem(found); + } + + _sceneUpdateRequired = true; + return 1; } @@ -1280,8 +1304,38 @@ int LoLEngine::clickedInventoryScroll(Button *button) { return 1; } -int LoLEngine::clickedUnk20(Button *button) { - return 1; +int LoLEngine::clickedScenePressSwitch(Button *button) { + int block = calcNewBlockPosition(_currentBlock, _currentDirection); + int dir = _currentDirection ^ 2; + uint8 type = _wllBuffer3[_levelBlockProperties[block].walls[dir]]; + + int res = 0; + switch (type) { + case 1: + res = clickedDecoration(block, dir); + break; + + case 2: + break; + + case 3: + break; + + case 4: + break; + + case 5: + res = switchOpenDoor(block, dir); + break; + + case 6: + break; + + default: + break; + } + + return res; } int LoLEngine::clickedScene(Button *button) { @@ -1300,7 +1354,7 @@ int LoLEngine::clickedUnk24(Button *button) { return 1; } -int LoLEngine::clickedUnk25(Button *button) { +int LoLEngine::clickedSceneDropItem(Button *button) { return 1; } diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 12cdba57ff..741cb20d6d 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -154,11 +154,11 @@ void LoLEngine::deleteItem(int itemIndex) { _itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000; } -CLevelItem *LoLEngine::findItem(uint16 index) { +MonsterInPlay *LoLEngine::findItem(uint16 index) { if (index & 0x8000) - return &_cLevelItems[index & 0x7fff]; + return &_monsters[index & 0x7fff]; else - return (CLevelItem *)&_itemsInPlay[index]; + return (MonsterInPlay *)&_itemsInPlay[index]; } void LoLEngine::runItemScript(int charNum, int item, int reg0, int reg3, int reg4) { @@ -202,10 +202,59 @@ void LoLEngine::setHandItem(uint16 itemIndex) { } void LoLEngine::clickSceneSub1() { + assignBlockCaps(_currentBlock, _currentDirection); + _screen->fillRect(112, 0, 287, 119, 0); + static const uint8 sceneItemWidth[] = { 0, 254, 1, 255, 2, 0, 1, 255 } ; + static const uint8 sceneClickTileIndex[] = { 13, 16}; + + int16 x1 = 0; + int16 x2 = 0; + + for (int i = 0; i < 2; i++) { + uint8 tile = sceneClickTileIndex[i]; + setLevelShapesDim(sceneClickTileIndex[i], x1, x2, 13); + uint16 s = _curBlockCaps[tile]->field_6; + + int t = (i << 7) + 1; + while (s) { + if (s & 0x8000) { + s &= 0x7fff; + s = _monsters[i].unk2; + } else { + ItemInPlay *item = &_itemsInPlay[s]; + + if (item->shpCurFrame_flg & 0x4000) { + if (clickSceneSub1Sub1(item->x, item->y, _partyPosX, _partyPosY) > 319) + break; + + int w = sceneItemWidth[s & 7] << 1; + int h = sceneItemWidth[(s >> 1) & 7] + 5; + if (item->unk4 > 1) + h -= ((item->unk4 - 1) * 6); + + uint8 shpIx = _itemProperties[item->itemPropertyIndex].shpIndex; + uint8 *shp = (_itemProperties[item->itemPropertyIndex].flags & 0x40) ? _gameShapes[shpIx] : _itemShapes[_gameShapeMap[shpIx]]; + + drawSceneItem(shp, 0, item->x, item->y, w, h, 0, t, 0); + } + + s = item->unk2; + t++; + } + } + } +} + +int LoLEngine::clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY) { + return 1; +} + +int LoLEngine::checkSceneForItems(LevelBlockProperty *block, int pos) { + return -1; } -void LoLEngine::clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY) { +void LoLEngine::foundItemSub(int item, int block) { } diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 7a2a91d62f..7ee1a32c85 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -100,7 +100,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _spellProperties = 0; _updateFlags = 0; _selectedSpell = 0; - _updateCharNum = _updatePortraitSpeechAnim = _updateCharV2 = _updateCharV3 = _textColourFlag = _hideInventory = 0; + _updateCharNum = _updatePortraitSpeechAnimDuration = _portraitSpeechAnimMode = _updateCharV3 = _textColourFlag = _hideInventory = 0; _fadeText = false; _palUpdateTimer = _updatePortraitNext = 0; _lampStatusTimer = 0xffffffff; @@ -123,7 +123,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _wllShapeMap = 0; _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0; _levelBlockProperties = 0; - _cLevelItems = 0; + _monsters = 0; _monsterProperties = 0; _lvlBlockIndex = _lvlShapeIndex = 0; _unkDrawLevelBool = true; @@ -144,7 +144,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _lampStatusSuspended = false; _tempBuffer5120 = 0; _tmpData136 = 0; - _cLevelItems = 0; + _monsters = 0; _unkGameFlag = 0; _lastMouseRegion = 0; //_preSeq_X1 = _preSeq_Y1 = _preSeq_X2 = _preSeq_Y2 = 0; @@ -284,7 +284,7 @@ LoLEngine::~LoLEngine() { delete[] _lvlShapeLeftRight; delete[] _tempBuffer5120; delete[] _tmpData136; - delete[] _cLevelItems; + delete[] _monsters; delete[] _levelBlockProperties; delete[] _monsterProperties; delete[] _scrollSceneBuffer; @@ -386,8 +386,8 @@ Common::Error LoLEngine::init() { _levelBlockProperties = new LevelBlockProperty[1025]; memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty)); - _cLevelItems = new CLevelItem[30]; - memset(_cLevelItems, 0, 30 * sizeof(CLevelItem)); + _monsters = new MonsterInPlay[30]; + memset(_monsters, 0, 30 * sizeof(MonsterInPlay)); _monsterProperties = new MonsterProperty[5]; memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty)); @@ -877,7 +877,7 @@ bool LoLEngine::addCharacter(int id) { loadCharFaceShapes(numChars, id); - _characters[numChars].rand = _rnd.getRandomNumberRng(1, 12); + _characters[numChars].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6; for (i = 0; i < 11; i++) { if (_characters[numChars].items[i]) { @@ -939,11 +939,11 @@ void LoLEngine::updatePortraitSpeechAnim() { int y = 0; bool redraw = false; - if (_updateCharV2 == 0) { + if (_portraitSpeechAnimMode == 0) { x = _activeCharsXpos[_updateCharNum]; y = 144; redraw = true; - } else if (_updateCharV2 == 1) { + } else if (_portraitSpeechAnimMode == 1) { if (textEnabled()) { x = 90; y = 130; @@ -951,7 +951,7 @@ void LoLEngine::updatePortraitSpeechAnim() { x = _activeCharsXpos[_updateCharNum]; y = 144; } - } else if (_updateCharV2 == 2) { + } else if (_portraitSpeechAnimMode == 2) { if (textEnabled()) { x = 16; y = 134; @@ -970,14 +970,14 @@ void LoLEngine::updatePortraitSpeechAnim() { if (_speechFlag) { if (snd_characterSpeaking() == 2) - _updatePortraitSpeechAnim = 2; + _updatePortraitSpeechAnimDuration = 2; else - _updatePortraitSpeechAnim = 1; + _updatePortraitSpeechAnimDuration = 1; } - _updatePortraitSpeechAnim--; + _updatePortraitSpeechAnimDuration--; - if (_updatePortraitSpeechAnim) { + if (_updatePortraitSpeechAnimDuration) { setCharFaceFrame(_updateCharNum, f); if (redraw) gui_drawCharPortraitWithStats(_updateCharNum); @@ -1000,12 +1000,12 @@ void LoLEngine::updatePortraits() { if (_updateCharNum == -1) return; - _updatePortraitSpeechAnim = _updateCharV3 = 1; + _updatePortraitSpeechAnimDuration = _updateCharV3 = 1; updatePortraitSpeechAnim(); - _updatePortraitSpeechAnim = 1; + _updatePortraitSpeechAnimDuration = 1; _updateCharNum = -1; - if (!_updateCharV2) + if (!_portraitSpeechAnimMode) initTextFading(0, 0); } @@ -1026,26 +1026,6 @@ void LoLEngine::initTextFading(int textType, int clearField) { _timer->disable(11); } -void LoLEngine::charCallback4(int redraw) { - for (int i = 0; i < 3; i++) { - if (!(_characters[i].flags & 1) || (_characters[i].flags & 8) || (_characters[i].curFaceFrame > 1)) - continue; - - if (_characters[i].curFaceFrame == 1) { - _characters[i].curFaceFrame = 0; - gui_drawCharPortraitWithStats(i); - _characters[i].rand = _rnd.getRandomNumberRng(1, 12); - } else { - _characters[i].rand--; - if (_characters[i].rand <= 0 && !redraw) { - _characters[i].curFaceFrame = 1; - gui_drawCharPortraitWithStats(i); - //resetAnimStructs(9, 0, 1); - } - } - } -} - void LoLEngine::setCharFaceFrame(int charNum, int frameNum) { _characters[charNum].curFaceFrame = frameNum; } @@ -1074,12 +1054,12 @@ int LoLEngine::calculateCharacterStats(int charNum, int index) { for (int i = 0; i < 8; i++) c += _characters[charNum].itemsMight[i]; if (c) - c += _characters[charNum].might2; + c += _characters[charNum].might; else c = _characters[charNum].defaultModifiers[8]; c = (c * _characters[charNum].defaultModifiers[1]) >> 8; - c = (c * _characters[charNum].might3) >> 8; + c = (c * _characters[charNum].totalMightModifier) >> 8; return c; @@ -1106,12 +1086,12 @@ int LoLEngine::calculateProtection(int index) { if (index & 0x8000) { // Monster index &= 0x7fff; - c = (_cLevelItems[index].monsters->itemProtection * _cLevelItems[index].monsters->protection) >> 8; + c = (_monsters[index].properties->itemProtection * _monsters[index].properties->protection) >> 8; } else { // Character - c = _characters[index].itemsProtection + _characters[index].protection2; + c = _characters[index].itemsProtection + _characters[index].protection; c = (c * _characters[index].defaultModifiers[2]) >> 8; - c = (c * _characters[index].protection3) >> 8; + c = (c * _characters[index].totalProtectionModifier) >> 8; } return c; @@ -1128,7 +1108,7 @@ void LoLEngine::setupScreenDims() { } void LoLEngine::initDialogueSequence(int controlMode) { - unkHideInventory(); + resetPortraitsArea(); gui_prepareForSequence(112, 0, 176, 120, controlMode); _updateFlags |= 3; @@ -1152,15 +1132,6 @@ void LoLEngine::toggleSelectedCharacterFrame(bool mode) { _screen->setCurPage(cp); } -void LoLEngine::unkHideInventory() { - _hideInventory = 1; - - if (!textEnabled() || !(_hideControls & 2)) - charCallback4(1); - - removeUnkFlags(2); -} - void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int buttonFlags) { setSequenceGui(x, y, w, h, buttonFlags); @@ -1203,6 +1174,14 @@ void LoLEngine::restoreSceneAfterDialogueSequence(int redraw) { _hideInventory = 0; } +void LoLEngine::resetPortraitsArea() { + _hideInventory = 1; + if (!textEnabled() || (!(_hideControls & 2))) + timerUpdatePortraitAnimations(1); + + removeUnkFlags(2); +} + void LoLEngine::fadeText() { if (!_fadeText) return; @@ -1347,15 +1326,15 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) { int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]); if (volIndex > 0) - volIndex = (volIndex * volume) >> 8; + volume = (volIndex * volume) >> 8; else - volIndex *= -1; + volume = -volIndex; // volume TODO int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]); if (vocIndex != -1) { - _sound->voicePlay(_ingameSoundList[vocIndex], true); + _sound->voicePlay(_ingameSoundList[vocIndex], volume & 0xff, true); } else if (_flags.platform == Common::kPlatformPC) { if (_sound->getSfxType() == Sound::kMidiMT32) track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1; @@ -1368,7 +1347,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) { track = 167; if (track != -1) - KyraEngine_v1::snd_playSoundEffect(track); + KyraEngine_v1::snd_playSoundEffect(track, volume); } } @@ -1419,24 +1398,6 @@ int LoLEngine::snd_stopMusic() { return snd_playTrack(-1); } -void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) { - uint32 endTime = _system->getMillis() + millis; - while (endTime > _system->getMillis()) { - if (cUpdate) - update(); - _system->delayMillis(4); - } -} - -void LoLEngine::runLoopSub4(int a) { - cmzS7(a, _currentBlock); -} - -void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) { - x = (block & 0x1f) << 8 | xOffs; - y = ((block & 0xffe0) << 3) | yOffs; -} - bool LoLEngine::characterSays(int track, int charId, bool redraw) { if (charId == 1) { charId = _selectedCharacter; @@ -1458,7 +1419,7 @@ bool LoLEngine::characterSays(int track, int charId, bool redraw) { if (r && redraw) { updatePortraits(); _updateCharNum = charId; - _updateCharV2 = 0; + _portraitSpeechAnimMode = 0; _updateCharV3 = 1; _fadeText = false; updatePortraitSpeechAnim(); @@ -1467,6 +1428,97 @@ bool LoLEngine::characterSays(int track, int charId, bool redraw) { return r ? textEnabled() : 1; } +int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str, EMCState *script, int16 *paramList, int16 paramIndex) { + int ch = 0; + bool skipAnim = false; + + if ((charId == -1) || (!(charId & 0x70))) + charId = ch = (charId == 1) ? (_selectedCharacter ? _characters[_selectedCharacter].id : 0) : charId; + else + charId ^= 0x70; + + updatePortraits(); + + if (charId < 0) { + charId = ch = (_rnd.getRandomNumber(0x7fff) * countActiveCharacters()) / 0x8000; + ch = _rnd.getRandomNumber(countActiveCharacters() - 1); + } else if (charId > 0) { + int i = 0; + + for (; i < 4; i++) { + if (_characters[i].id != charId || !(_characters[i].flags & 1)) + continue; + if (charId == ch) + ch = i; + charId = i; + break; + } + + if (i == 4) { + if (charId == 8) + skipAnim = true; + else + return 0; + } + } + + if (!skipAnim) { + _updateCharNum = charId; + _portraitSpeechAnimMode = mode; + _updatePortraitSpeechAnimDuration = strlen(str) >> 1; + _updateCharV3 = unk1; + } + + if (script) + snd_playCharacterSpeech(script->stack[script->sp + 2], ch, 0); + else if (paramList) + snd_playCharacterSpeech(paramList[1], ch, 0); + + if (textEnabled()) { + if (mode == 0) { + _txt->printDialogueText(3, str, script, paramList, paramIndex); + + } else if (mode == 1) { + _screen->setScreenDim(4); + _screen->clearDim(4); + _screen->modifyScreenDim(4, 16, 123, 23, 47); + _txt->printDialogueText(4, str, script, paramList, paramIndex); + _screen->modifyScreenDim(4, 11, 123, 28, 47); + + } else if (mode == 2) { + _screen->setScreenDim(4); + _screen->clearDim(4); + _screen->modifyScreenDim(4, 9, 133, 30, 60); + _txt->printDialogueText(4, str, script, paramList, 3); + _screen->modifyScreenDim(4, 1, 133, 37, 60); + } + } + + _fadeText = 0; + if (!skipAnim) + updatePortraitSpeechAnim(); + + return 1; +} + +void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) { + uint32 endTime = _system->getMillis() + millis; + while (endTime > _system->getMillis()) { + if (cUpdate) + update(); + _system->delayMillis(4); + } +} + +void LoLEngine::runLoopSub4(int a) { + cmzS7(a, _currentBlock); +} + +void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) { + x = (block & 0x1f) << 8 | xOffs; + y = ((block & 0xffe0) << 3) | yOffs; +} + bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) { if (_spellProperties[spellNum].mpRequired[spellLevel] > _characters[charNum].magicPointsCur) { if (characterSays(0x4043, _characters[charNum].id, true)) diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index dcadab6e86..63b8a47d20 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -67,11 +67,11 @@ struct LoLCharacter { uint8 field_41; uint16 damageSuffered; uint16 weaponHit; - uint16 might3; - uint16 protection3; - uint16 might2; - uint16 protection2; - uint16 rand; + uint16 totalMightModifier; + uint16 totalProtectionModifier; + uint16 might; + uint16 protection; + int16 nextAnimUpdateCountdown; uint16 items[11]; uint8 skillLevels[3]; uint8 skillModifiers[3]; @@ -94,8 +94,7 @@ struct SpellProperty { struct LevelBlockProperty { uint8 walls[4]; uint16 itemIndex; - uint8 field_6; - uint8 field_7; + uint16 field_6; uint8 field_8; uint8 flags; }; @@ -118,10 +117,10 @@ struct MonsterProperty { uint8 unk8[3]; }; -struct CLevelItem { +struct MonsterInPlay { uint16 itemIndexUnk; - uint8 unk2; - uint16 unk3; + uint16 unk2; + uint8 unk4; uint16 blockPropertyIndex; uint16 x; uint16 y; @@ -140,26 +139,25 @@ struct CLevelItem { uint16 field_19; uint8 field_1B; uint8 field_1C; - int16 field_1D; + int16 monsterMight; uint8 field_1F; - uint8 field_20; - MonsterProperty *monsters; + uint8 type; + MonsterProperty *properties; uint8 field_25; uint8 field_26; uint8 field_27; - uint8 field_28; - uint8 field_29; + uint16 itix; uint8 field_2A; uint8 field_2B; - uint8 field_2C; + uint16 field_2C; uint8 field_2D; uint8 field_2E; }; struct ItemInPlay { uint16 itemIndexUnk; - uint8 unk2; - uint16 unk3; + uint16 unk2; + uint8 unk4; uint16 blockPropertyIndex; uint16 x; uint16 y; @@ -311,13 +309,13 @@ private: void setupTimers(); void enableTimer(int id); - void timerSub1(int timerNum); + void timerProcessOpenDoor(int timerNum); void timerSub2(int timerNum); void timerSub3(int timerNum); void timerSub4(int timerNum); void timerSub5(int timerNum); void timerSub6(int timerNum); - void timerSub7(int timerNum); + void timerUpdatePortraitAnimations(int skipUpdate); void timerUpdateLampState(int timerNum); void timerFadeMessageText(int timerNum); @@ -433,15 +431,15 @@ private: int clickedCharInventorySlot(Button *button); int clickedExitCharInventory(Button *button); int clickedUnk16(Button *button); - int clickedScene1(Button *button); + int clickedScenePickupItem(Button *button); int clickedInventorySlot(Button *button); int clickedInventoryScroll(Button *button); - int clickedUnk20(Button *button); + int clickedScenePressSwitch(Button *button); int clickedScene(Button *button); int clickedScroll(Button *button); int clickedUnk23(Button *button); int clickedUnk24(Button *button); - int clickedUnk25(Button *button); + int clickedSceneDropItem(Button *button); int clickedOptions(Button *button); int clickedRestParty(Button *button); int clickedMoneyBox(Button *button); @@ -470,6 +468,9 @@ private: int _buttonList8Size; // text + bool characterSays(int track, int charId, bool redraw); + int playCharacterScriptChat(int charId, int y, int unk1, char *str, EMCState *script, int16 *paramList, int16 paramIndex); + TextDisplayer_LoL *_txt; // emc scripts @@ -506,26 +507,35 @@ private: int olol_loadDoorShapes(EMCState *script); int olol_initAnimStruct(EMCState *script); int olol_freeAnimStruct(EMCState *script); + int olol_getDirection(EMCState *script); int olol_setMusicTrack(EMCState *script); + int olol_clearDialogueField(EMCState *script); int olol_getUnkArrayVal(EMCState *script); int olol_setUnkArrayVal(EMCState *script); int olol_setGlobalVar(EMCState *script); int olol_mapShapeToBlock(EMCState *script); int olol_resetBlockShapeAssignment(EMCState *script); int olol_loadMonsterProperties(EMCState *script); + int olol_68(EMCState *script); int olol_setScriptTimer(EMCState *script); int olol_loadTimScript(EMCState *script); int olol_runTimScript(EMCState *script); int olol_releaseTimScript(EMCState *script); int olol_initDialogueSequence(EMCState *script); int olol_restoreSceneAfterDialogueSequence(EMCState *script); + int olol_85(EMCState *script); int olol_loadLangFile(EMCState *script); int olol_stopTimScript(EMCState *script); + int olol_playCharacterScriptChat(EMCState *script); int olol_loadSoundFile(EMCState *script); int olol_setPaletteBrightness(EMCState *script); int olol_playDialogueTalkText(EMCState *script); + int olol_checkDialogueState(EMCState *script); int olol_setNextFunc(EMCState *script); + int olol_setDoorState(EMCState *script); int olol_assignCustomSfx(EMCState *script); + int olol_resetPortraitsArea(EMCState *script); + int olol_setUnkFlags(EMCState *script); // tim scripts TIM *_activeTim[10]; @@ -559,8 +569,8 @@ private: // graphics void setupScreenDims(); void initDialogueSequence(int controlMode); - void unkHideInventory(); void restoreSceneAfterDialogueSequence(int redraw); + void resetPortraitsArea(); void toggleSelectedCharacterFrame(bool mode); void fadeText(); void updateWsaAnimations(); @@ -594,7 +604,6 @@ private: void updatePortraitSpeechAnim(); void updatePortraits(); void initTextFading(int textType, int clearField); - void charCallback4(int redraw); void setCharFaceFrame(int charNum, int frameNum); void faceFrameRefresh(int charNum); @@ -606,8 +615,8 @@ private: uint16 _activeCharsXpos[3]; int _updateFlags; int _updateCharNum; - int _updatePortraitSpeechAnim; - int _updateCharV2; + int _updatePortraitSpeechAnimDuration; + int _portraitSpeechAnimMode; int _updateCharV3; int _textColourFlag; bool _fadeText; @@ -655,11 +664,11 @@ private: void loadLevel(int index); void addLevelItems(); int initCmzWithScript(int block); - void initCMZ1(CLevelItem *l, int a); - void initCMZ2(CLevelItem *l, uint16 a, uint16 b); + void initCMZ1(MonsterInPlay *l, int a); + void initCMZ2(MonsterInPlay *l, uint16 a, uint16 b); int cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2); - void cmzS2(CLevelItem *l, int a); - void cmzS3(CLevelItem *l); + void cmzS2(MonsterInPlay *l, int a); + void cmzS3(MonsterInPlay *l); void cmzS4(uint16 &itemIndex, int a); int cmzS5(uint16 a, uint16 b); void cmzS6(uint16 &itemIndex, int a); @@ -700,6 +709,7 @@ private: void drawMonstersAndItems(int block); void drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags); void drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl); + void drawSceneItem(uint8 *shape, uint8 *ovl, int x, int y, int w, int h, int flags, int unk1, int unk2); void drawScriptShapes(int pageNum); void updateSceneWindow(); @@ -709,10 +719,18 @@ private: void updateCompass(); void moveParty(uint16 direction, int unk1, int unk2, int buttonShape); - uint16 calcNewBlockPostion(uint16 curBlock, uint16 direction); + uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction); bool checkBlockPassability(uint16 block, uint16 direction); void notifyBlockNotPassable(int scrollFlag); + int clickedDecoration(uint16 block, uint16 direction); + int switchOpenDoor(uint16 block, uint16 direction); + + bool clickedShape(int shapeIndex); + void openDoorSub1(uint16 block, int unk); + void openDoorSub2(uint16 block, int unk); + int _emcDoorState; + void movePartySmoothScrollBlocked(int speed); void movePartySmoothScrollUp(int speed); void movePartySmoothScrollDown(int speed); @@ -782,7 +800,7 @@ private: LevelBlockProperty *_levelBlockProperties; LevelBlockProperty *_curBlockCaps[18]; - CLevelItem *_cLevelItems; + MonsterInPlay *_monsters; MonsterProperty *_monsterProperties; uint16 _partyPosX; @@ -862,11 +880,13 @@ private: int makeItem(int itemIndex, int curFrame, int flags); bool testUnkItemFlags(int itemIndex); void deleteItem(int itemIndex); - CLevelItem *findItem(uint16 index); + MonsterInPlay *findItem(uint16 index); void runItemScript(int charNum, int item, int reg0, int reg3, int reg4); void setHandItem(uint16 itemIndex); void clickSceneSub1(); - void clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY); + int clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY); + int checkSceneForItems(LevelBlockProperty *block, int pos); + void foundItemSub(int item, int block); uint8 _moneyColumnHeight[5]; uint16 _credits; @@ -894,7 +914,6 @@ private: void delay(uint32 millis, bool cUpdate = false, bool isMainLoop = false); void runLoopSub4(int a); void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs); - bool characterSays(int track, int charId, bool redraw); uint8 *_pageBuffer1; uint8 *_pageBuffer2; diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 1efd337f19..7c34bdc945 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -113,7 +113,7 @@ void LoLEngine::addLevelItems() { int LoLEngine::initCmzWithScript(int block) { int i = _levelBlockProperties[block].itemIndex; int cnt = 0; - CLevelItem *t = 0; + MonsterInPlay *t = 0; while (i) { t = findItem(i); @@ -122,7 +122,7 @@ int LoLEngine::initCmzWithScript(int block) { continue; i &= 0x7fff; - t = &_cLevelItems[i]; + t = &_monsters[i]; cnt++; initCMZ1(t, 14); @@ -134,7 +134,7 @@ int LoLEngine::initCmzWithScript(int block) { return cnt; } -void LoLEngine::initCMZ1(CLevelItem *l, int a) { +void LoLEngine::initCMZ1(MonsterInPlay *l, int a) { if (l->field_14 == 13 && a != 14) return; if (a == 7) { @@ -156,7 +156,7 @@ void LoLEngine::initCMZ1(CLevelItem *l, int a) { l->field_14 = a; l->field_15 = 0; if (a == 14) - l->field_1D = 0; + l->monsterMight = 0; if (a == 13 && (l->field_19 & 0x20)) { l->field_14 = 0; cmzS3(l); @@ -171,7 +171,7 @@ void LoLEngine::initCMZ1(CLevelItem *l, int a) { } -void LoLEngine::initCMZ2(CLevelItem *l, uint16 a, uint16 b) { +void LoLEngine::initCMZ2(MonsterInPlay *l, uint16 a, uint16 b) { bool cont = true; int t = l->blockPropertyIndex; if (l->blockPropertyIndex) { @@ -197,10 +197,10 @@ void LoLEngine::initCMZ2(CLevelItem *l, uint16 a, uint16 b) { _levelBlockProperties[l->blockPropertyIndex].field_8 = 5; checkScriptUnk(l->blockPropertyIndex); - if (l->monsters->unk8[0] == 0 || cont == false) + if (l->properties->unk8[0] == 0 || cont == false) return; - if ((!(l->monsters->unk5[0] & 0x100) || ((l->anon9 & 1) == 0)) && l->blockPropertyIndex == t) + if ((!(l->properties->unk5[0] & 0x100) || ((l->anon9 & 1) == 0)) && l->blockPropertyIndex == t) return; if (l->blockPropertyIndex != t) @@ -209,7 +209,7 @@ void LoLEngine::initCMZ2(CLevelItem *l, uint16 a, uint16 b) { if (_updateFlags & 1) return; - cmzS7(l->monsters->unk3[5], l->blockPropertyIndex); + cmzS7(l->properties->unk3[5], l->blockPropertyIndex); } int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { @@ -249,11 +249,11 @@ int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { return Retv[r]; } -void LoLEngine::cmzS2(CLevelItem *l, int a) { +void LoLEngine::cmzS2(MonsterInPlay *l, int a) { // TODO } -void LoLEngine::cmzS3(CLevelItem *l) { +void LoLEngine::cmzS3(MonsterInPlay *l) { // TODO } @@ -278,7 +278,7 @@ void LoLEngine::cmzS7(int a, int block) { } void LoLEngine::moveItemToBlock(uint16 *cmzItemIndex, uint16 item) { - CLevelItem *tmp = 0; + MonsterInPlay *tmp = 0; while (*cmzItemIndex & 0x8000) { tmp = findItem(*cmzItemIndex); @@ -431,10 +431,10 @@ void LoLEngine::loadLevelCmzFile(int index) { _levelBlockProperties[i].flags = *t++; for (int i = 0; i < 30; i++) { - if (_cLevelItems[i].blockPropertyIndex) { - _cLevelItems[i].blockPropertyIndex = 0; - _cLevelItems[i].monsters = _monsterProperties + _cLevelItems[i].field_20; - initCMZ2(&_cLevelItems[i], _cLevelItems[i].x, _cLevelItems[i].y); + if (_monsters[i].blockPropertyIndex) { + _monsters[i].blockPropertyIndex = 0; + _monsters[i].properties = &_monsterProperties[_monsters[i].type]; + initCMZ2(&_monsters[i], _monsters[i].x, _monsters[i].y); } } @@ -450,15 +450,15 @@ void LoLEngine::loadCMZ_Sub(int index1, int index2) { //int r = 0; for (int i = 0; i < 30; i++) { - if (_cLevelItems[i].field_14 >= 14 || _cLevelItems[i].blockPropertyIndex == 0 || _cLevelItems[i].field_1D <= 0) + if (_monsters[i].field_14 >= 14 || _monsters[i].blockPropertyIndex == 0 || _monsters[i].monsterMight <= 0) continue; - int t = (val * _cLevelItems[i].field_1D) >> 8; - _cLevelItems[i].field_1D = t; + int t = (val * _monsters[i].monsterMight) >> 8; + _monsters[i].monsterMight = t; if (index2 < index1) - _cLevelItems[i].field_1D++; - if (_cLevelItems[i].field_1D == 0) - _cLevelItems[i].field_1D = 1; + _monsters[i].monsterMight++; + if (_monsters[i].monsterMight == 0) + _monsters[i].monsterMight = 1; } } @@ -726,10 +726,10 @@ void LoLEngine::resetItems(int flag) { for (int i = 0; i < 1024; i++) { _levelBlockProperties[i].field_8 = 5; uint16 id = _levelBlockProperties[i].itemIndex; - CLevelItem *r = 0; + MonsterInPlay *r = 0; while (id & 0x8000) { - r = (CLevelItem*)findItem(id); + r = (MonsterInPlay*)findItem(id); assert(r); id = r->itemIndexUnk; } @@ -748,9 +748,9 @@ void LoLEngine::resetItems(int flag) { } void LoLEngine::resetLvlBuffer() { - memset(_cLevelItems, 0, 30 * sizeof(CLevelItem)); + memset(_monsters, 0, 30 * sizeof(MonsterInPlay)); for (int i = 0; i < 30; i++) - _cLevelItems[i].field_14 = 0x10; + _monsters[i].field_14 = 0x10; } void LoLEngine::resetBlockProperties() { @@ -860,7 +860,7 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape) gui_toggleButtonDisplayMode(buttonShape, 1); uint16 opos = _currentBlock; - uint16 npos = calcNewBlockPostion(_currentBlock, direction); + uint16 npos = calcNewBlockPosition(_currentBlock, direction); if (!checkBlockPassability(npos, direction)) { notifyBlockNotPassable(unk2 ? 0 : 1); @@ -916,7 +916,7 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape) setLF2(_currentBlock); } -uint16 LoLEngine::calcNewBlockPostion(uint16 curBlock, uint16 direction) { +uint16 LoLEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) { static const int16 blockPosTable[] = { -32, 1, 32, -1, 1, -1, 3, 2, -1, 0, -1, 0, 1, -32, 0, 32 }; return (curBlock + blockPosTable[direction]) & 0x3ff; } @@ -942,7 +942,67 @@ void LoLEngine::notifyBlockNotPassable(int scrollFlag) { snd_stopSpeech(true); _txt->printMessage(0x8002, getLangString(0x403f)); - snd_playSoundEffect(19, 255); + snd_playSoundEffect(19, -1); +} + +int LoLEngine::clickedDecoration(uint16 block, uint16 direction) { + uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; + if (!clickedShape(v)) + return 0; + + snd_stopSpeech(true); + runLevelScript(block, 0x40); + + return 1; +} + +int LoLEngine::switchOpenDoor(uint16 block, uint16 direction) { + uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]]; + if (!clickedShape(v)) + return 0; + + snd_playSoundEffect(78, -1); + _emcDoorState = 0; + runLevelScript(block, 0x40); + + if (!_emcDoorState) { + delay(15 * _tickLength); + openDoorSub1(block, 0); + } + + return 1; +} + +bool LoLEngine::clickedShape(int shapeIndex) { + while (shapeIndex) { + uint16 s = _levelShapeProperties[shapeIndex].shapeIndex[1]; + + if (s == 0xffff) + continue; + + int w = _levelShapes[s][3]; + int h = _levelShapes[s][2]; + int x = _levelShapeProperties[shapeIndex].shapeX[1] + 136; + int y = _levelShapeProperties[shapeIndex].shapeY[1] + 8; + + if (_levelShapeProperties[shapeIndex].flags & 1) + w <<= 1; + + if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8)) + return true; + + shapeIndex = _levelShapeProperties[shapeIndex].next; + } + + return false; +} + +void LoLEngine::openDoorSub1(uint16 block, int unk) { + +} + +void LoLEngine::openDoorSub2(uint16 block, int unk) { + } void LoLEngine::movePartySmoothScrollBlocked(int speed) { @@ -1866,6 +1926,10 @@ void LoLEngine::drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, } } +void LoLEngine::drawSceneItem(uint8 *shape, uint8 *ovl, int x, int y, int w, int h, int flags, int unk1, int unk2) { + +} + void LoLEngine::drawScriptShapes(int pageNum) { if (!_scriptAssignedLevelShape) return; diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 07645ca508..8e65cd3d9b 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -400,12 +400,30 @@ int LoLEngine::olol_freeAnimStruct(EMCState *script) { return 0; } +int LoLEngine::olol_getDirection(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getDirection(%p)", (const void *)script); + return _currentDirection; +} + int LoLEngine::olol_setMusicTrack(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setMusicTrack(%p) (%d)", (const void *)script, stackPos(0)); _curMusicTheme = stackPos(0); return 1; } +int LoLEngine::olol_clearDialogueField(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_clearDialogueField(%p) (%d)", (const void *)script, stackPos(0)); + if (_hideControls && (!textEnabled())) + return 1; + + _screen->setScreenDim(5); + const ScreenDim *d = _screen->getScreenDim(5); + _screen->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 2, d->unkA); + _screen->clearDim(4); + + return 1; +} + int LoLEngine::olol_getUnkArrayVal(EMCState *script) { return _unkEMC46[stackPos(0)]; } @@ -456,8 +474,8 @@ int LoLEngine::olol_setGlobalVar(EMCState *script) { case 8: _updateFlags = b; if (b == 1) { - if (!textEnabled() || !(_hideControls & 2)) - charCallback4(1); + if (!textEnabled() || (!(_hideControls & 2))) + timerUpdatePortraitAnimations(1); removeUnkFlags(2); } else { setUnkFlags(2); @@ -562,6 +580,10 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) { return 1; } +int LoLEngine::olol_68(EMCState *script) { + return 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); @@ -610,6 +632,10 @@ int LoLEngine::olol_restoreSceneAfterDialogueSequence(EMCState *script) { return 1; } +int LoLEngine::olol_85(EMCState *script) { + return 1; +} + int LoLEngine::olol_loadLangFile(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0)); char filename[13]; @@ -626,6 +652,13 @@ int LoLEngine::olol_stopTimScript(EMCState *script) { return 1; } +int LoLEngine::olol_playCharacterScriptChat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playCharacterScriptChat(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + snd_stopSpeech(1); + updatePortraits(); + return playCharacterScriptChat(stackPos(0), stackPos(1), 1, getLangString(stackPos(2)), script, 0, 3); +} + int LoLEngine::olol_loadSoundFile(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0)); snd_loadSoundFile(stackPos(0)); @@ -647,18 +680,33 @@ int LoLEngine::olol_playDialogueTalkText(EMCState *script) { if (!snd_playCharacterSpeech(track, 0, 0) || textEnabled()) { char *s = getLangString(track); - _txt->playDialogue(4, s, script, 0, 1); + _txt->printDialogueText(4, s, script, 0, 1); } return 1; } +int LoLEngine::olol_checkDialogueState(EMCState *script) { + for (int i = 0; i < 30; i++) { + if (stackPos(0) != _monsters[i].type && stackPos(0) != -1) + continue; + return (_monsters[i].field_14 == 1) ? 0 : 1; + } + return 1; +} + int LoLEngine::olol_setNextFunc(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setNextFunc(%p) (%d)", (const void *)script, stackPos(0)); _nextScriptFunc = stackPos(0); return 1; } +int LoLEngine::olol_setDoorState(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setDoorState(%p) (%d)", (const void *)script, stackPos(0)); + _emcDoorState = stackPos(0); + return _emcDoorState; +} + int LoLEngine::olol_assignCustomSfx(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignCustomSfx(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1)); const char *c = stackPosString(0); @@ -675,6 +723,18 @@ int LoLEngine::olol_assignCustomSfx(EMCState *script) { return 0; } +int LoLEngine::olol_resetPortraitsArea(EMCState *script) { + resetPortraitsArea(); + return 1; +} + +int LoLEngine::olol_setUnkFlags(EMCState *script) { + _hideInventory = 0; + setUnkFlags(2); + return 1; +} + + #pragma mark - int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) { @@ -793,7 +853,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_freeAnimStruct); // 0x1C - OpcodeUnImpl(); + Opcode(olol_getDirection); OpcodeUnImpl(); Opcode(olol_setMusicTrack); OpcodeUnImpl(); @@ -801,7 +861,7 @@ void LoLEngine::setupOpcodeTable() { // 0x20 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_clearDialogueField); OpcodeUnImpl(); // 0x24 @@ -853,7 +913,7 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); // 0x44 - OpcodeUnImpl(); + Opcode(olol_68); OpcodeUnImpl(); OpcodeUnImpl(); OpcodeUnImpl(); @@ -878,7 +938,7 @@ void LoLEngine::setupOpcodeTable() { // 0x54 OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_85); Opcode(olol_loadLangFile); OpcodeUnImpl(); @@ -891,7 +951,7 @@ void LoLEngine::setupOpcodeTable() { // 0x5C OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_playCharacterScriptChat); OpcodeUnImpl(); // 0x60 @@ -934,7 +994,7 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); OpcodeUnImpl(); Opcode(olol_playDialogueTalkText); - OpcodeUnImpl(); + Opcode(olol_checkDialogueState); // 0x7C Opcode(olol_setNextFunc); @@ -951,7 +1011,7 @@ void LoLEngine::setupOpcodeTable() { // 0x84 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_setDoorState); OpcodeUnImpl(); // 0x88 @@ -981,8 +1041,8 @@ void LoLEngine::setupOpcodeTable() { // 0x98 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_resetPortraitsArea); + Opcode(olol_setUnkFlags); // 0x9C OpcodeUnImpl(); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index df5d4ee08b..17f473568b 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -984,11 +984,11 @@ bool StaticResource::loadCharData(const char *filename, void *&ptr, int &size) { t->field_41 = file->readByte(); t->damageSuffered = file->readUint16LE(); t->weaponHit = file->readUint16LE(); - t->might3 = file->readUint16LE(); - t->protection3 = file->readUint16LE(); - t->might2 = file->readUint16LE(); - t->protection2 = file->readUint16LE(); - t->rand = file->readUint16LE(); + t->totalMightModifier = file->readUint16LE(); + t->totalProtectionModifier = file->readUint16LE(); + t->might = file->readUint16LE(); + t->protection = file->readUint16LE(); + t->nextAnimUpdateCountdown = file->readSint16LE(); for (int ii = 0; ii < 11; ii++) t->items[ii] = file->readUint16LE(); for (int ii = 0; ii < 3; ii++) @@ -1834,7 +1834,7 @@ void LoLEngine::assignButtonCallback(Button *button, int index) { cb(clickedUnk16), cb(clickedUnk16), cb(clickedUnk16), - cb(clickedScene1), + cb(clickedScenePickupItem), cb(clickedInventorySlot), cb(clickedInventorySlot), cb(clickedInventorySlot), @@ -1847,8 +1847,8 @@ void LoLEngine::assignButtonCallback(Button *button, int index) { cb(clickedInventorySlot), cb(clickedInventoryScroll), cb(clickedInventoryScroll), - cb(clickedUnk20), - cb(clickedUnk20), + cb(clickedScenePressSwitch), + cb(clickedScenePressSwitch), cb(clickedScene), cb(clickedUpArrow), cb(clickedDownArrow), @@ -1871,8 +1871,8 @@ void LoLEngine::assignButtonCallback(Button *button, int index) { cb(clickedUnk23), cb(clickedUnk23), cb(clickedUnk24), - cb(clickedUnk25), - cb(clickedUnk25), + cb(clickedSceneDropItem), + cb(clickedSceneDropItem), cb(clickedOptions), cb(clickedRestParty), cb(clickedMoneyBox), diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index 68523d4c82..7e4648149d 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -38,11 +38,8 @@ TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm _buffer = new char[600]; memset(_buffer, 0, 600); - _out = new char[1024]; - memset(_out, 0, 1024); - - _backupBuffer = new byte[20]; - memset(_backupBuffer, 0, 20); + _dialogueBuffer = new char[1024]; + memset(_dialogueBuffer, 0, 1024); _currentLine = new char[85]; memset(_currentLine, 0, 85); @@ -50,24 +47,23 @@ TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm TextDisplayer_LoL::~TextDisplayer_LoL() { delete[] _buffer; - delete[] _out; - delete[] _backupBuffer; + delete[] _dialogueBuffer; delete[] _currentLine; } void TextDisplayer_LoL::setupField(bool mode) { if (_vm->textEnabled()) { if (mode) { - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer1); _screen->copyRegion(80, 142, 0, 0, 240, 37, 0, 3, Screen::CR_NO_P_CHECK); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer2); - _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer2); + _screen->copyBlockToPage(3, 0, 0, 320, 40, _vm->_pageBuffer1); } else { _screen->clearDim(4); int cp = _screen->setCurPage(2); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); - _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer2); - _screen->copyRegion(80, 142, 0, 0, 240, 37, 3, 2, Screen::CR_NO_P_CHECK); + _screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer1); + _screen->copyBlockToPage(3, 0, 0, 320, 40, _vm->_pageBuffer2); + _screen->copyRegion(0, 0, 80, 142, 240, 37, 3, _screen->_curPage, Screen::CR_NO_P_CHECK); for (int i = 177; i > 141; i--) { uint32 endTime = _vm->_system->getMillis() + _vm->_tickLength; @@ -92,12 +88,14 @@ void TextDisplayer_LoL::setupField(bool mode) { } void TextDisplayer_LoL::expandField() { + uint8 *tmp = _vm->_pageBuffer1 + 1300; + if (_vm->textEnabled()) { _vm->_fadeText = false; _vm->_textColourFlag = 0; _vm->_timer->disable(11); _screen->clearDim(3); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 10, tmp); _screen->copyRegion(83, 140, 0, 0, 235, 3, 0, 2, Screen::CR_NO_P_CHECK); for (int i = 140; i < 177; i++) { @@ -109,7 +107,7 @@ void TextDisplayer_LoL::expandField() { _vm->delayUntil(endTime); } - _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1); + _screen->copyBlockToPage(3, 0, 0, 320, 10, tmp); _vm->_updateFlags |= 2; } else { @@ -133,20 +131,19 @@ void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, ui } } -void TextDisplayer_LoL::playDialogue(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex) { - memcpy(_curPara, _stringParameters, 15 * sizeof(char*)); - //char *cmds = _curPara[0]; +void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex) { _colour1prot = false; + int oldDim = _screen->curDimIndex(); if (dim == 3) { - if (_vm->_updateFlags & 2) { - _screen->clearDim(4); - dim = _screen->curDimIndex(); + if (_vm->_updateFlags & 2) { + _screen->setScreenDim(4); + _screen->clearDim(4); _colour1 = 254; _colour1prot = true; } else { + _screen->setScreenDim(3); _screen->clearDim(3); - dim = _screen->curDimIndex(); _colour1 = 192; _colour1prot = true; _screen->copyColour(192, 254); @@ -154,7 +151,6 @@ void TextDisplayer_LoL::playDialogue(int dim, char *str, EMCState *script, int16 _vm->_textColourFlag = 0; _vm->_fadeText = false; } - } else { _screen->setScreenDim(dim); _colour1 = 254; @@ -164,25 +160,10 @@ void TextDisplayer_LoL::playDialogue(int dim, char *str, EMCState *script, int16 int cp = _screen->setCurPage(0); Screen::FontId of = _screen->setFont(Screen::FID_9_FNT); - memset(_backupBuffer, 0, 20); + preprocessString(str, script, paramList, paramIndex); + displayText(_dialogueBuffer); - if (preprocessString(str, script, paramList, paramIndex)) { - //vsnprintf(_out, 1024, str, cmds); - _stringLength = strlen(_out); - displayText(_out); - } else { - _stringLength = strlen(str); - displayText(str); - displayText(str); - } - - for (int i = 0; i < 10; i++) { - if (!_backupBuffer[i << 1]) - break; - str[_backupBuffer[(i << 1) + 1]] = _backupBuffer[i << 1]; - } - - _screen->setScreenDim(dim); + _screen->setScreenDim(oldDim); _screen->setCurPage(cp); _screen->setFont(of); @@ -232,27 +213,25 @@ void TextDisplayer_LoL::printMessage(uint16 type, char *str, ...) { _vm->_fadeText = false; } -bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex) { - int cnt = 0; - bool res = false; - char *tmpd = _buffer; - char **cmds = _curPara; +void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex) { + char *dst = _dialogueBuffer; for (char *s = str; *s;) { - if (*s++ != '%') + if (*s != '%') { + *dst++ = *s++; continue; + } - char pos = *s; - char para1 = 0; + char para = *++s; bool eos = false; - switch (pos) { + switch (para) { case '\0': eos = true; break; case '#': - para1 = *++s; - switch (para1) { + para = *++s; + switch (para) { case 'E': case 'G': case 'X': @@ -281,9 +260,9 @@ bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *par if (eos) continue; - char para2 = *s; + para = *s; - switch (para2) { + switch (para) { case '\0': eos = true; break; @@ -291,53 +270,38 @@ bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *par ++s; break; default: - while(para2 && para2 > 47 && para2 < 58) - para2 = *++s; + while(para && para > 47 && para < 58) + para = *++s; break; } if (eos) continue; - char para3 = *++s; + para = *s++; - switch (para3) { + switch (para) { case 'a': - _backupBuffer[cnt++] = para3; - _backupBuffer[cnt++] = (int16) (s - str); - snprintf(tmpd, 7, "%d", _scriptParameter); - *cmds++ = tmpd; - tmpd += strlen(tmpd) + 1; - res = true; - *s++ = 's'; + snprintf(dst, 7, "%d", _scriptParameter); + dst += strlen(dst); break; case 'n': - _backupBuffer[cnt++] = para3; - _backupBuffer[cnt++] = (int16) (s - str); - *cmds++ = _vm->_characters[script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]].name; - paramIndex++; - res = true; - *s++ = 's'; + strcpy(dst, _vm->_characters[script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]].name); + dst += strlen(dst); break; case 's': - *cmds++ = _vm->getLangString(script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]); - paramIndex++; - res = true; - s++; + strcpy(dst, _vm->getLangString(script ? script->stack[script->sp + paramIndex] : paramList[paramIndex])); + dst += strlen(dst); break; case 'X': case 'd': case 'u': case 'x': - snprintf(tmpd, 7, "%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]); - *cmds++ = tmpd; - tmpd += strlen(tmpd) + 1; - paramIndex++; - res = true; - *s++ = 's'; + snprintf(dst, 7, "%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]); + dst += strlen(dst); break; case '\0': @@ -345,8 +309,7 @@ bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *par continue; } } - - return res; + *dst = 0; } void TextDisplayer_LoL::displayText(char *str, ...) { diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h index a6232805b9..cc31480e7b 100644 --- a/engines/kyra/text_lol.h +++ b/engines/kyra/text_lol.h @@ -44,7 +44,7 @@ public: void setupField(bool mode); void expandField(); - void playDialogue(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex); + void printDialogueText(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex); void printMessage(uint16 type, char *str, ...); int16 _scriptParameter; @@ -54,7 +54,7 @@ private: char parseCommand(); void readNextPara(); void printLine(char *str); - bool preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex); + void preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex); //typedef void (LoLEngine::*DialogueAnimCallback)(const char *str, uint16 lineWidth, uint8 col1, uint8 col2); //DialogueAnimCallback _dlgAnimCallback; @@ -63,10 +63,8 @@ private: char *_stringParameters[15]; - char *_curPara[15]; char *_buffer; - char *_out; - byte *_backupBuffer; + char *_dialogueBuffer; char *_tempString1; char *_tempString2; char *_currentLine; diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp index 594aa1733e..ab94d97101 100644 --- a/engines/kyra/timer_lol.cpp +++ b/engines/kyra/timer_lol.cpp @@ -34,7 +34,7 @@ namespace Kyra { void LoLEngine::setupTimers() { debugC(9, kDebugLevelMain | kDebugLevelTimer, "LoLEngine::setupTimers()"); - _timer->addTimer(0, TimerV2(timerSub1), 15, true); + _timer->addTimer(0, TimerV2(timerProcessOpenDoor), 15, true); _timer->addTimer(0x10, TimerV2(timerSub2), 6, true); _timer->addTimer(0x11, TimerV2(timerSub2), 6, true); _timer->setNextRun(0x11, 3); @@ -44,7 +44,7 @@ void LoLEngine::setupTimers() { _timer->addTimer(0x51, TimerV2(timerSub5), 0, false); _timer->addTimer(0x52, TimerV2(timerSub5), 0, false); _timer->addTimer(8, TimerV2(timerSub6), 1200, true); - _timer->addTimer(9, TimerV2(timerSub7), 10, true); + _timer->addTimer(9, TimerV2(timerUpdatePortraitAnimations), 10, true); _timer->addTimer(10, TimerV2(timerUpdateLampState), 360, true); _timer->addTimer(11, TimerV2(timerFadeMessageText), 360, false); } @@ -54,7 +54,7 @@ void LoLEngine::enableTimer(int id) { _timer->setNextRun(id, _system->getMillis() + _timer->getDelay(id) * _tickLength); } -void LoLEngine::timerSub1(int timerNum) { +void LoLEngine::timerProcessOpenDoor(int timerNum) { } @@ -78,8 +78,26 @@ void LoLEngine::timerSub6(int timerNum) { } -void LoLEngine::timerSub7(int timerNum) { - +void LoLEngine::timerUpdatePortraitAnimations(int skipUpdate) { + if (skipUpdate != 1) + skipUpdate = 0; + + for (int i = 0; i < 4; i++) { + if (!(_characters[i].flags & 1) || (_characters[i].flags & 8) || (_characters[i].curFaceFrame > 1)) + continue; + + if (_characters[i].curFaceFrame != 1) { + if (--_characters[i].nextAnimUpdateCountdown <= 0 && !skipUpdate) { + _characters[i].curFaceFrame = 1; + gui_drawCharPortraitWithStats(i); + _timer->setCountdown(9, 10); + } + } else { + _characters[i].curFaceFrame = 0; + gui_drawCharPortraitWithStats(i); + _characters[i].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6; + } + } } void LoLEngine::timerUpdateLampState(int timerNum) { -- cgit v1.2.3