aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp9
-rw-r--r--devtools/create_kyradat/create_kyradat.h3
-rw-r--r--devtools/create_kyradat/games.cpp3
-rw-r--r--devtools/create_kyradat/tables.cpp10
-rw-r--r--dists/engine-data/kyra.datbin465202 -> 465243 bytes
-rw-r--r--engines/kyra/detection.cpp10
-rw-r--r--engines/kyra/eob2.cpp10
-rw-r--r--engines/kyra/eob2.h5
-rw-r--r--engines/kyra/eobcommon.cpp20
-rw-r--r--engines/kyra/magic_eob.cpp17
-rw-r--r--engines/kyra/resource.h3
-rw-r--r--engines/kyra/saveload_eob.cpp7
-rw-r--r--engines/kyra/scene_eob.cpp10
-rw-r--r--engines/kyra/screen_eob.cpp17
-rw-r--r--engines/kyra/script_eob.cpp48
-rw-r--r--engines/kyra/script_eob.h9
-rw-r--r--engines/kyra/sequences_eob2.cpp7
-rw-r--r--engines/kyra/staticres_eob.cpp3
-rw-r--r--engines/kyra/text_eob.cpp37
-rw-r--r--engines/kyra/timer_eob.cpp7
20 files changed, 137 insertions, 98 deletions
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index ad56fb44c2..11e868f3ed 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -570,7 +570,8 @@ const ExtractFilename extractFilenames[] = {
{ kEob2Npc1Strings, kTypeStringList, true },
{ kEob2Npc2Strings, kTypeStringList, true },
{ kEob2MonsterDustStrings, kTypeStringList, true },
- { kEob2DranFoolsStrings, kTypeStringList, true },
+ { kEob2DreamSteps, kTypeRawData, false },
+ { kEob2KheldranStrings, kTypeStringList, true },
{ kEob2HornStrings, kTypeStringList, true },
{ kEob2HornSounds, kTypeRawData, false },
{ kEob2WallOfForceDsX, kLolTypeRaw16, false },
@@ -1991,8 +1992,10 @@ const char *getIdString(const int id) {
return "kEob2Npc2Strings";
case kEob2MonsterDustStrings:
return "kEob2MonsterDustStrings";
- case kEob2DranFoolsStrings:
- return "kEob2DranFoolsStrings";
+ case kEob2DreamSteps:
+ return "kEob2DreamSteps";
+ case kEob2KheldranStrings:
+ return "kEob2KheldranStrings";
case kEob2HornStrings:
return "kEob2HornStrings";
case kEob2HornSounds:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index d7bcc4d986..4ac94755e7 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -552,7 +552,8 @@ enum kExtractID {
kEob2Npc2Strings,
kEob2MonsterDustStrings,
- kEob2DranFoolsStrings,
+ kEob2DreamSteps,
+ kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 78baeb6b39..cc81abaa39 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1594,7 +1594,8 @@ const int eob2FloppyNeed[] = {
kEob2Npc1Strings,
kEob2Npc2Strings,
kEob2MonsterDustStrings,
- kEob2DranFoolsStrings,
+ kEob2DreamSteps,
+ kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,
kEob2WallOfForceDsX,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 239ee6e1bd..064b3c80ae 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -3187,7 +3187,12 @@ const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
+const ExtractEntrySearchData kEob2DreamStepsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000E, 0x00000114, { { 0x27, 0x32, 0xCB, 0x89, 0x27, 0xC5, 0xDD, 0x91, 0xBE, 0x97, 0x62, 0xF5, 0x76, 0xF7, 0xCD, 0x25 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2KheldranStringsProvider[] = {
{ EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
EXTRACT_END_ENTRY
@@ -4198,7 +4203,8 @@ const ExtractEntry extractProviders[] = {
{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
- { kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
+ { kEob2DreamSteps, kEob2DreamStepsProvider },
+ { kEob2KheldranStrings, kEob2KheldranStringsProvider },
{ kEob2HornStrings, kEob2HornStringsProvider },
{ kEob2HornSounds, kEob2HornSoundsProvider },
{ kEob2WallOfForceDsX, kEob2WallOfForceDsXProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 8d45a5f0d6..704c8adc3c 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 44fbc0fe68..adfb1c612a 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -188,7 +188,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
// In Kyra games slot 0 can't be deleted, it's for restarting the game(s).
// An exception makes Lands of Lore here, it does not have any way to restart the
// game except via its main menu.
- if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol"))
+ if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2"))
return;
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
@@ -198,7 +198,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
- const bool lolGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol");
+ bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");
if (in) {
Kyra::KyraEngine_v1::SaveHeader header;
@@ -212,12 +212,12 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// Slot 0 is used for the 'restart game' save in all three Kyrandia games, thus
// we prevent it from being deleted.
- desc.setDeletableFlag(slot != 0 || lolGame);
+ desc.setDeletableFlag(slot != 0 || nonKyraGame);
// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
- desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+ desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
desc.setThumbnail(header.thumbnail);
return desc;
@@ -229,7 +229,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
- desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+ desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
return desc;
}
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 0ecdba0fd3..0ffca10093 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -77,6 +77,10 @@ Common::Error DarkMoonEngine::init() {
_color13 = 177;
_color14 = 182;
+ // Necessary wall hacks (where the original code makes out of bounds accesses)
+ _wllWallFlags[183] = 0x50;
+ _wllVmpMap[183] = 1;
+
return Common::kNoError;
}
@@ -312,6 +316,8 @@ const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex,
void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
int shapeIndex = type * 3 + 2 - mDim;
uint8 *shp = _doorShapes[shapeIndex];
+ if (!shp)
+ return;
if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
y = _dscDoorY1[mDim] - shp[1];
@@ -392,7 +398,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
bool DarkMoonEngine::checkPartyStatusExtra() {
if (checkScriptFlags(0x100000))
- seq_dranFools();
+ seq_kheldran();
return _gui->confirmDialogue2(14, 67, 1);
}
@@ -462,7 +468,7 @@ void DarkMoonEngine::characterLevelGain(int charIndex) {
if (er == 0xffffffff)
continue;
- increaseCharacterExperience(charIndex, er - c->experience[i]);
+ increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
}
}
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index f24db79e62..6da09010b4 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -88,10 +88,11 @@ private:
// Ingame sequence
void seq_nightmare();
- void seq_dranFools();
+ void seq_kheldran();
void seq_dranDragonTransformation();
- const char *const *_dranFoolsStrings;
+ const int8 *_dreamSteps;
+ const char *const *_kheldranStrings;
// characters
void drawNpcScene(int npcIndex);
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 3a298d84ad..67609520fa 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -302,13 +302,6 @@ Common::Error EobCoreEngine::init() {
memset(&_wllShapeMap[3], -1, 5);
memset(&_wllShapeMap[13], -1, 5);
- /*int clen = _flags.gameID == GI_EOB2 ? 80 : 70;
- memcpy(&_wllShapeMap[256 - clen], _wllVmpMap, clen);
- memcpy(&_specialWallTypes[256 - 2 * clen], _wllVmpMap, clen);
- memcpy(&_specialWallTypes[256 - clen], _wllShapeMap, clen);
- memcpy(&_wllWallFlags[256 - 2 * clen], _wllShapeMap, clen);
- memcpy(&_wllWallFlags[256 - clen], _specialWallTypes, clen);*/
-
_wllVcnOffset = 16;
_monsters = new EobMonsterInPlay[30];
@@ -1248,6 +1241,7 @@ void EobCoreEngine::initDialogueSequence() {
_txt->resetPageBreakString();
gui_updateControls();
+ //_allowSkip = true;
_sound->playTrack(0);
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
@@ -1263,6 +1257,7 @@ void EobCoreEngine::restoreAfterDialogueSequence() {
_dialogueLastBitmap[0] = 0;
gui_restorePlayField();
+ //_allowSkip = false;
_screen->setScreenDim(7);
if (_flags.gameID == GI_EOB2)
@@ -1603,14 +1598,18 @@ bool EobCoreEngine::checkPassword() {
for (int i = 0; i < 3; i++) {
_screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1);
int c = rollDice(1, _mnNumWord - 1, -1);
- _screen->drawShape(0, _largeItemShapes[_mnDef[c << 2]], 100, 2, 13);
+ const uint8 *shp = (_mnDef[c << 2] < _numLargeItemShapes) ? _largeItemShapes[_mnDef[c << 2]] : (_mnDef[c << 2] < 15 ? 0 : _smallItemShapes[_mnDef[c << 2] - 15]);
+ assert(shp);
+ _screen->drawShape(0, shp, 100, 2, 13);
_screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1);
memset(answ, 0, 20);
gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1);
gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);
if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0)
i = 3;
- if (scumm_stricmp(_mnWord[c], answ) && i == 2)
+ if (!scumm_stricmp(_mnWord[c], answ))
+ break;
+ else if (i == 2)
return false;
}
@@ -1806,7 +1805,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
EobCharacter *c = &_characters[charIndex];
if (savingThrowType != 5) {
- if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex))
+ if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
s = savingThrowReduceDamage(savingThrowEffect, s);
}
@@ -2006,6 +2005,7 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
_txt->printMessage(_ripItemStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
printFullItemName(itm);
_txt->printMessage(_ripItemStrings[2]);
+ break;
}
gui_drawCharPortraitWithStats(c);
}
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 646d389706..0424558b04 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -360,7 +360,7 @@ void EobCoreEngine::startSpell(int spell) {
if (_castScrollSlot) {
gui_updateSlotAfterScrollUse();
} else {
- c->disabledSlots |= 4;
+ _characters[_openBookChar].disabledSlots |= 4;
setCharEventTimer(_openBookChar, 72, 11, 1);
gui_toggleButtons();
gui_drawSpellbook();
@@ -405,7 +405,6 @@ void EobCoreEngine::sparkEffectDefensive(int charIndex) {
_screen->updateScreen();
}
}
- resetSkipFlag();
delay(2 * _tickLength);
}
@@ -430,7 +429,6 @@ void EobCoreEngine::sparkEffectOffensive() {
if (shpIndex)
_screen->drawShape(2, _sparkShapes[shpIndex - 1], _sparkEffectOfX[ii], _sparkEffectOfY[ii], 0);
}
- resetSkipFlag();
delay(2 * _tickLength);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
@@ -444,6 +442,7 @@ void EobCoreEngine::sparkEffectOffensive() {
}
void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
+ assert (spell >= 0);
int l = _openBookType == 1 ? getClericPaladinLevel(_openBookChar) : getMageLevel(_openBookChar);
uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
@@ -753,7 +752,7 @@ int EobCoreEngine::findFirstCharacterSpellTarget() {
}
int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
- for (; _characterSpellTarget < 6; _characterSpellTarget++) {
+ for (_characterSpellTarget++; _characterSpellTarget < 6; ) {
if (++curCharIndex == 6)
curCharIndex = 0;
if (testCharacter(curCharIndex, 3))
@@ -763,8 +762,14 @@ int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
}
int EobCoreEngine::charDeathSavingThrow(int charIndex, int div) {
- if (specialAttackSavingThrow(charIndex, 4))
+ bool _beholderOrgBhv = true;
+ // Due to a bug in the original code the saving throw result is completely ignored
+ // here. The Beholders' disintegrate spell will alway succeed while their flesh to
+ // stone spell will always fail.
+ if (_beholderOrgBhv)
div >>= 1;
+ else
+ div = specialAttackSavingThrow(charIndex, 4) ? 1 : 0;
return div;
}
@@ -1226,7 +1231,7 @@ bool EobCoreEngine::spellCallback_end_flameStrike(void *obj) {
}
void EobCoreEngine::spellCallback_start_raiseDead() {
- if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
+ if (_characters[_activeSpellCharId].hitPointsCur == -10 && ((_characters[_activeSpellCharId].raceSex >> 1) != 1)) {
_characters[_activeSpellCharId].hitPointsCur = 1;
gui_drawCharPortraitWithStats(_activeSpellCharId);
} else {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index cd3865736f..a7060cdf6d 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -626,7 +626,8 @@ enum KyraResources {
kEob2Npc2Strings,
kEob2MonsterDustStrings,
- kEob2DranFoolsStrings,
+ kEob2DreamSteps,
+ kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 847f304288..01fbd75cfe 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -366,6 +366,13 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
_sceneUpdateRequired = true;
_screen->setFont(Screen::FID_6_FNT);
+ for (int i = 0; i < 6; i++) {
+ for (int ii = 0; ii < 10; ii++) {
+ if (_characters[i].events[ii] == -57)
+ spellCallback_start_trueSeeing();
+ }
+ }
+
_screen->setCurPage(0);
gui_drawPlayField(false);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 1bd7fca04a..98cd60dcd9 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -647,8 +647,12 @@ void EobCoreEngine::loadLevel(int level, int sub) {
delete s;
}
- Common::String gfxFile = initLevelData(sub);
-
+ Common::String gfxFile;
+ // Work around for issue with corrupt (incomplete) monster property data
+ // when loading a savegame saved in a sub level
+ for (int i = 0; i <= sub; i++)
+ gfxFile = initLevelData(i);
+
const uint8 *data = _screen->getCPagePtr(5);
const uint8 *pos = data + READ_LE_UINT16(data);
uint16 len = READ_LE_UINT16(pos);
@@ -1142,7 +1146,7 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
int f = _wllWallFlags[w];
//if (!f)
- assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
+ assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index d29af69f0a..9c67750ba8 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -774,15 +774,8 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
if (py > ymax)
py = ymax;
- if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
+ if (posWithinRect(px, py, rX1, rY1, rX2, rY2))
setPagePixel(0, px, py, ptr6[i]);
- if (i % 5 == 0) {
- updateScreen();
- uint32 cur = _system->getMillis();
- if (end > cur)
- _system->delayMillis(end - cur);
- }
- }
}
}
@@ -914,14 +907,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
setPagePixel(0, px, py, pixBackup[ii]);
-
- if (ii % 15 == 0) {
- updateScreen();
- uint32 cur = _system->getMillis();
- if (nextDelay > cur)
- _system->delayMillis(nextDelay - cur);
- nextDelay += 1;
- }
}
}
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 6feac6bd77..1dbb02414f 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -106,8 +106,8 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
Opcode(oeob_calcAndInflictCharacterDamage);
Opcode(oeob_jump);
Opcode(oeob_end);
- Opcode(oeob_popPosAndReturn);
- Opcode(oeob_pushPosAndJump);
+ Opcode(oeob_returnFromSubroutine);
+ Opcode(oeob_callSubroutine);
OpcodeAlt(oeob_eval);
Opcode(oeob_deleteItem);
Opcode(oeob_loadNewLevelOrMonsters);
@@ -125,6 +125,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
#undef OpcodeAlt
_scriptData = 0;
+ _scriptSize = 0;
_abortScript = 0;
_abortAfterSubroutine = 0;
@@ -134,9 +135,9 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
_lastScriptFunc = 0;
_lastScriptSub = 0;
- _scriptPosStack = new int8*[10];
- memset(_scriptPosStack, 0, 10 * sizeof(int8*));
- _scriptPosStackIndex = 0;
+ _subroutineStack = new int8*[10];
+ memset(_subroutineStack, 0, 10 * sizeof(int8*));
+ _subroutineStackPos = 0;
_flagTable = new uint32[18];
memset(_flagTable, 0, 18 * sizeof(uint32));
@@ -145,14 +146,14 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
memset(_stack, 0, 30 * sizeof(int16));
_stackIndex = 0;
- memset(_scriptPosStack, 0, sizeof(_scriptPosStack));
- _scriptPosStackIndex = 0;
+ memset(_subroutineStack, 0, sizeof(_subroutineStack));
+ _subroutineStackPos = 0;
_activeCharacter = -1;
}
EobInfProcessor::~EobInfProcessor() {
- delete[] _scriptPosStack;
+ delete[] _subroutineStack;
delete[] _flagTable;
delete[] _stack;
delete[] _scriptData;
@@ -163,8 +164,9 @@ EobInfProcessor::~EobInfProcessor() {
void EobInfProcessor::loadData(const uint8 *data, uint32 dataSize) {
delete[] _scriptData;
- _scriptData = new int8[dataSize];
- memcpy(_scriptData, data, dataSize);
+ _scriptSize = dataSize;
+ _scriptData = new int8[_scriptSize];
+ memcpy(_scriptData, data, _scriptSize);
}
void EobInfProcessor::run(int func, int sub) {
@@ -382,7 +384,7 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
int bc = _lastScriptSub;
int bd = _abortScript;
int be = _activeCharacter;
- int bf = _scriptPosStackIndex;
+ int bf = _subroutineStackPos;
_vm->moveParty(d);
@@ -392,7 +394,7 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
_abortScript = bd;
_activeCharacter = be;
if (!_abortAfterSubroutine)
- _scriptPosStackIndex = bf;
+ _subroutineStackPos = bf;
_vm->_sceneDefaultUpdate = 0;
} else if ((a == -31 && _vm->game() == GI_EOB2) || a == -11) {
@@ -589,7 +591,6 @@ int EobInfProcessor::oeob_playSoundEffect(int8 *data) {
int EobInfProcessor::oeob_removeFlags(int8 *data) {
int8 *pos = data;
int8 a = *pos++;
- int8 b = *pos++;
switch (a) {
case -47:
@@ -601,11 +602,11 @@ int EobInfProcessor::oeob_removeFlags(int8 *data) {
break;
case -17:
- _flagTable[_vm->_currentLevel] &= ~(1 << b);
+ _flagTable[_vm->_currentLevel] &= ~(1 << (*pos++));
break;
case -16:
- _flagTable[17] &= ~(1 << b);
+ _flagTable[17] &= ~(1 << (*pos++));
break;
default:
@@ -667,28 +668,29 @@ int EobInfProcessor::oeob_jump(int8 *data) {
int EobInfProcessor::oeob_end(int8 *data) {
_abortScript = 1;
- _scriptPosStackIndex = 0;
+ _subroutineStackPos = 0;
return 0;
}
-int EobInfProcessor::oeob_popPosAndReturn(int8 *data) {
+int EobInfProcessor::oeob_returnFromSubroutine(int8 *data) {
int8 *pos = data;
- if (_scriptPosStackIndex)
- pos = _scriptPosStack[--_scriptPosStackIndex];
+ if (_subroutineStackPos)
+ pos = _subroutineStack[--_subroutineStackPos];
else
_abortScript = 1;
return pos - data;
}
-int EobInfProcessor::oeob_pushPosAndJump(int8 *data) {
+int EobInfProcessor::oeob_callSubroutine(int8 *data) {
int8 *pos = data;
uint16 offs = READ_LE_UINT16(pos);
+ assert(offs < _scriptSize);
pos += 2;
- if (_scriptPosStackIndex < 10) {
- _scriptPosStack[_scriptPosStackIndex++] = pos;
+ if (_subroutineStackPos < 10) {
+ _subroutineStack[_subroutineStackPos++] = pos;
pos = _scriptData + offs;
}
@@ -1245,7 +1247,7 @@ int EobInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
_vm->_sceneUpdateRequired = true;
_vm->gui_drawAllCharPortraitsWithStats();
- _scriptPosStackIndex = 0;
+ _subroutineStackPos = 0;
} else {
cmd = *pos++;
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 648d214017..8f44c7f6f9 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -69,8 +69,8 @@ private:
int oeob_calcAndInflictCharacterDamage(int8 *data);
int oeob_jump(int8 *data);
int oeob_end(int8 *data);
- int oeob_popPosAndReturn(int8 *data);
- int oeob_pushPosAndJump(int8 *data);
+ int oeob_returnFromSubroutine(int8 *data);
+ int oeob_callSubroutine(int8 *data);
int oeob_eval_v1(int8 *data);
int oeob_eval_v2(int8 *data);
int oeob_deleteItem(int8 *data);
@@ -94,6 +94,7 @@ private:
Common::Array<const InfProc*> _opcodes;
int8 *_scriptData;
+ uint16 _scriptSize;
uint8 _abortScript;
uint16 _abortAfterSubroutine;
@@ -103,8 +104,8 @@ private:
uint16 _lastScriptFunc;
uint16 _lastScriptSub;
- int8 **_scriptPosStack;
- int _scriptPosStackIndex;
+ int8 **_subroutineStack;
+ int _subroutineStackPos;
uint32 *_flagTable;
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index ea96779bb1..dcf293bd52 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -1282,12 +1282,11 @@ void DarkMoonEngine::seq_nightmare() {
_txt->printDialogueText(99, 0);
snd_playSoundEffect(54);
- static const int8 dreamSteps[] = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 3, 2, 1, 0, -1 };
static const uint8 seqX[] = { 0, 20, 0, 20 };
static const uint8 seqY[] = { 0, 0, 96, 96 };
static const uint8 seqDelay[] = { 12, 7, 7, 12 };
- for (const int8 *i = dreamSteps; *i != -1; ++i) {
+ for (const int8 *i = _dreamSteps; *i != -1; ++i) {
drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
delay(seqDelay[*i] * _tickLength);
}
@@ -1299,14 +1298,14 @@ void DarkMoonEngine::seq_nightmare() {
_screen->setFont(of);
}
-void DarkMoonEngine::seq_dranFools() {
+void DarkMoonEngine::seq_kheldran() {
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
initDialogueSequence();
gui_drawDialogueBox();
static const char file[] = "KHELDRAN";
- _txt->printDialogueText(_dranFoolsStrings[0]);
+ _txt->printDialogueText(_kheldranStrings[0]);
drawSequenceBitmap(file, 0, 0, 0, 0);
_txt->printDialogueText(20, _moreStrings[0]);
snd_playSoundEffect(56);
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 57ee737ba0..274feba4fa 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1280,7 +1280,8 @@ void DarkMoonEngine::initStaticResource() {
_npc1Strings = _staticres->loadStrings(kEob2Npc1Strings, temp);
_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
- _dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
+ _dreamSteps = (const int8*)_staticres->loadRawData(kEob2DreamSteps, temp);
+ _kheldranStrings = _staticres->loadStrings(kEob2KheldranStrings, temp);
_hornStrings = _staticres->loadStrings(kEob2HornStrings, temp);
_hornSounds = _staticres->loadRawData(kEob2HornSounds, temp);
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 318147c679..a2cc5c6e00 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -29,16 +29,18 @@
#include "common/system.h"
-#define EOBTEXTBUFFERSIZE 2048
-
namespace Kyra {
+enum {
+ kEobTextBufferSize = 2048
+};
+
TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
- _dialogueBuffer = new char[EOBTEXTBUFFERSIZE];
- memset(_dialogueBuffer, 0, EOBTEXTBUFFERSIZE);
+ _dialogueBuffer = new char[kEobTextBufferSize];
+ memset(_dialogueBuffer, 0, kEobTextBufferSize);
_currentLine = new char[85];
memset(_currentLine, 0, 85);
@@ -221,12 +223,14 @@ void TextDisplayer_Eob::displayText(char *str, ...) {
break;
default:
- _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
- _currentLine[_numCharsLeft++] = c;
- _currentLine[_numCharsLeft] = 0;
+ if (_vm->game() == GI_LOL || c > 30) {
+ _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
+ _currentLine[_numCharsLeft++] = c;
+ _currentLine[_numCharsLeft] = 0;
- if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
- printLine(_currentLine);
+ if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+ printLine(_currentLine);
+ }
}
c = parseCommand();
@@ -271,6 +275,10 @@ void TextDisplayer_Eob::readNextPara() {
_tempString1 = 0;
}
+ if (d & 0x80) {
+ warning("TextDisplayer_Eob::readNextPara():");
+ }
+
_ctrl[1] = d;
_ctrl[2] = 0;
}
@@ -442,8 +450,8 @@ void TextDisplayer_Eob::printLine(char *str) {
void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) {
const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
- assert (strlen(str) < EOBTEXTBUFFERSIZE);
- Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+ assert (strlen(str) < kEobTextBufferSize);
+ Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
displayText(_dialogueBuffer);
@@ -457,8 +465,8 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
}
void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
- assert (strlen(str) < EOBTEXTBUFFERSIZE);
- Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+ assert (strlen(str) < kEobTextBufferSize);
+ Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
strcpy(_dialogueBuffer, str);
displayText(_dialogueBuffer);
@@ -474,7 +482,7 @@ void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
va_list args;
va_start(args, textColor);
- vsnprintf(_dialogueBuffer, 240, str, args);
+ vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args);
va_end(args);
displayText(_dialogueBuffer);
@@ -655,6 +663,7 @@ void TextDisplayer_Eob::displayWaitButton() {
while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
_screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
+ _screen->updateScreen();
vm()->_dialogueButtonW = 95;
SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
clearCurDim();
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index caeae8cb29..f36688df39 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -221,6 +221,13 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
}
}
}
+
+ for (int i = 0; i < 5; i++) {
+ if (_wallsOfForce[i].duration > ct) {
+ uint32 chrt = _wallsOfForce[i].duration - ct;
+ _wallsOfForce[i].duration = chrt > millis ? ct + chrt - millis : ct;
+ }
+ }
}
void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {