mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
KYRA: (EOB) - lots of bug fixes, mostly for EOB II
This commit is contained in:
parent
f7032c126d
commit
c35de374df
@ -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:
|
||||
|
@ -552,7 +552,8 @@ enum kExtractID {
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
|
||||
kEob2DranFoolsStrings,
|
||||
kEob2DreamSteps,
|
||||
kEob2KheldranStrings,
|
||||
kEob2HornStrings,
|
||||
kEob2HornSounds,
|
||||
|
||||
|
@ -1594,7 +1594,8 @@ const int eob2FloppyNeed[] = {
|
||||
kEob2Npc1Strings,
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
kEob2DranFoolsStrings,
|
||||
kEob2DreamSteps,
|
||||
kEob2KheldranStrings,
|
||||
kEob2HornStrings,
|
||||
kEob2HornSounds,
|
||||
kEob2WallOfForceDsX,
|
||||
|
@ -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 },
|
||||
|
Binary file not shown.
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -626,7 +626,8 @@ enum KyraResources {
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
|
||||
kEob2DranFoolsStrings,
|
||||
kEob2DreamSteps,
|
||||
kEob2KheldranStrings,
|
||||
kEob2HornStrings,
|
||||
kEob2HornSounds,
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user