aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorFlorian Kagerer2009-02-23 20:17:53 +0000
committerFlorian Kagerer2009-02-23 20:17:53 +0000
commit837ca0683e758f7a822452c53b2bff69fa554099 (patch)
treefaba5e246310c377e669b8a2c30a03c556754208 /engines/kyra
parente3afa772e2ad494175b91e011304558150b8901a (diff)
downloadscummvm-rg350-837ca0683e758f7a822452c53b2bff69fa554099.tar.gz
scummvm-rg350-837ca0683e758f7a822452c53b2bff69fa554099.tar.bz2
scummvm-rg350-837ca0683e758f7a822452c53b2bff69fa554099.zip
LOL: - some more work on the interface (you can now click on the banners and windows) and some bug fixes
svn-id: r38818
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/gui_lol.cpp62
-rw-r--r--engines/kyra/items_lol.cpp57
-rw-r--r--engines/kyra/lol.cpp202
-rw-r--r--engines/kyra/lol.h91
-rw-r--r--engines/kyra/scene_lol.cpp120
-rw-r--r--engines/kyra/script_lol.cpp84
-rw-r--r--engines/kyra/staticres.cpp20
-rw-r--r--engines/kyra/text_lol.cpp129
-rw-r--r--engines/kyra/text_lol.h8
-rw-r--r--engines/kyra/timer_lol.cpp28
10 files changed, 539 insertions, 262 deletions
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) {