Skip to content

Commit

Permalink
KYRA: (EOB) - complete EOBII playability
Browse files Browse the repository at this point in the history
- fixed temp data generation, block data loading, some spell issues, etc.
- both EOB I and II should now be completable
- one big issue remaining (AdLib driver gets swamped with monster sounds which causes heavy lags in some levels)
  • Loading branch information
athrxx authored and Johannes Schickel committed Dec 26, 2011
1 parent c35de37 commit 2448d88
Show file tree
Hide file tree
Showing 21 changed files with 137 additions and 92 deletions.
4 changes: 4 additions & 0 deletions engines/kyra/detection.cpp
Expand Up @@ -160,6 +160,10 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {

SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Skip automatic final saves made by EOB for the purpose of party transfer
if (!scumm_stricmp(file->c_str() + file->size() - 3, "fin"))
continue;

// Obtain the last 3 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 3);

Expand Down
3 changes: 0 additions & 3 deletions engines/kyra/eob1.cpp
Expand Up @@ -78,9 +78,6 @@ Common::Error EobEngine::init() {

_scriptTimersCount = 1;

//_wllWallFlags[132] = 1;
//_wllWallFlags[133] = 1;

return Common::kNoError;
}

Expand Down
11 changes: 4 additions & 7 deletions engines/kyra/eob2.cpp
Expand Up @@ -77,10 +77,6 @@ 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;
}

Expand Down Expand Up @@ -226,8 +222,8 @@ void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex)
SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];

m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
m->x = dc[4];
m->y = dc[5];
m->x = (int8)dc[4];
m->y = (int8)dc[5];
}
}

Expand Down Expand Up @@ -281,6 +277,7 @@ bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
if (m->type) {
_playFinale = true;
_runFlag = false;
delay(850);
} else {
m->hitPointsCur = 150;
m->curRemoteWeapon = 0;
Expand All @@ -306,7 +303,7 @@ const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex,
shapeDefs += 8;
_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
shapeDefs += 2;
_doorSwitches[doorIndex * 3 + i]. y= *shapeDefs;
_doorSwitches[doorIndex * 3 + i].y= *shapeDefs;
shapeDefs += 2;
}
_screen->_curPage = 0;
Expand Down
5 changes: 4 additions & 1 deletion engines/kyra/eobcommon.cpp
Expand Up @@ -398,8 +398,11 @@ Common::Error EobCoreEngine::go() {
if (!shouldQuit() && action > -3) {
runLoop();

if (_playFinale)
if (_playFinale) {
// make final save for party transfer
saveGameStateIntern(-1, 0, 0);
seq_playFinale();
}
}

return Common::kNoError;
Expand Down
25 changes: 14 additions & 11 deletions engines/kyra/eobcommon.h
Expand Up @@ -151,8 +151,8 @@ struct EobItemType {

struct SpriteDecoration {
uint8 *shp;
uint8 x;
uint8 y;
int16 x;
int16 y;
};

struct EobMonsterProperty {
Expand Down Expand Up @@ -574,11 +574,13 @@ friend class CharacterGenerator;
const int8 *_monsterDirChangeTable;

// Level
void loadLevel(int level, int func);
Common::String initLevelData(int func);
void loadLevel(int level, int sub);
Common::String initLevelData(int sub);
void addLevelItems();
void loadVcnData(const char *file, const char */*nextFile*/);
void loadBlockProperties(const char *mazFile);
const uint8 *getBlockFileData(int levelIndex);
const uint8 *getBlockFileData(const char *mazFile);
void loadDecorations(const char *cpsFile, const char *decFile);
void assignWallsAndDecorations(int wallIndex, int vmpIndex, int decDataIndex, int specialType, int flags);
void releaseDecorations();
Expand Down Expand Up @@ -613,6 +615,7 @@ friend class CharacterGenerator;

int8 _currentSub;
Common::String _curGfxFile;
Common::String _curBlockFile;

uint32 _drawSceneTimer;
uint32 _flashShapeTimer;
Expand Down Expand Up @@ -1006,13 +1009,13 @@ friend class CharacterGenerator;
void spellCallback_start_heal();
void spellCallback_start_layOnHands();
void spellCallback_start_turnUndead();
bool spellCallback_end_lightningBoltPassive(void *obj);
bool spellCallback_end_unk1Passive(void *obj);
bool spellCallback_end_unk2Passive(void *obj);
bool spellCallback_end_deathSpellPassive(void *obj);
bool spellCallback_end_disintegratePassive(void *obj);
bool spellCallback_end_causeCriticalWoundsPassive(void *obj);
bool spellCallback_end_fleshToStonePassive(void *obj);
bool spellCallback_end_monster_lightningBolt(void *obj);
bool spellCallback_end_monster_fireball1(void *obj);
bool spellCallback_end_monster_fireball2(void *obj);
bool spellCallback_end_monster_deathSpell(void *obj);
bool spellCallback_end_monster_disintegrate(void *obj);
bool spellCallback_end_monster_causeCriticalWounds(void *obj);
bool spellCallback_end_monster_fleshToStone(void *obj);

int8 _openBookSpellLevel;
int8 _openBookSpellSelectedItem;
Expand Down
8 changes: 5 additions & 3 deletions engines/kyra/gui_eob.cpp
Expand Up @@ -853,12 +853,12 @@ int EobCoreEngine::clickedCamp(Button *button) {
gui_drawCharPortraitWithStats(i);
}

_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
_screen->copyPage(0, 7);
_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);

_gui->runCampMenu();

_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
_screen->setScreenDim(cd);
drawScene(0);

Expand Down Expand Up @@ -2250,7 +2250,7 @@ void GUI_Eob::runCampMenu() {
_vm->dropCharacter(selectCharacterDialogue(53));
_vm->gui_drawPlayField(false);
res = true;
_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
_screen->setFont(Screen::FID_6_FNT);
_vm->gui_drawAllCharPortraitsWithStats();
_screen->setFont(Screen::FID_8_FNT);
Expand Down Expand Up @@ -2282,6 +2282,8 @@ void GUI_Eob::runCampMenu() {
default:
break;
}

lastMenu = -1;

} else {
Common::Point p = _vm->getMousePos();
Expand Down
7 changes: 5 additions & 2 deletions engines/kyra/items_eob.cpp
Expand Up @@ -208,8 +208,8 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
int itm = _characters[charIndex].inventory[slot];
int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;

if (slot < 2 && (_items[itm].flags & 0x20) && ex > 0 && ex < 4) {
if (_flags.gameID == GI_EOB2)
if (_items[itm].flags & 0x20 && (_flags.gameID == GI_EOB1 || slot < 2)) {
if (_flags.gameID == GI_EOB2 && ex > 0 && ex < 4)
_txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
return 0;
}
Expand Down Expand Up @@ -692,6 +692,9 @@ void EobCoreEngine::endObjectFlight(EobFlyingObject *fo) {
}

void EobCoreEngine::checkFlyingObjects() {
if (!_runFlag)
return;

for (int i = 0; i < 10; i++) {
EobFlyingObject *fo = &_flyingObjects[i];
if (!fo->enable)
Expand Down
1 change: 1 addition & 0 deletions engines/kyra/lol.h
Expand Up @@ -917,6 +917,7 @@ friend class HistoryPlayer;
uint8 *getLevelDecorationShapes(int index);
void restoreTempDataAdjustMonsterStrength(int index);
void loadBlockProperties(const char *cmzFile);
const uint8 *getBlockFileData(int levelIndex);
void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile);

Expand Down
4 changes: 3 additions & 1 deletion engines/kyra/loleobbase.h
Expand Up @@ -147,6 +147,7 @@ friend class TextDisplayer_Eob;
virtual void drawSceneShapes(int start) = 0;
virtual void drawDecorations(int index) = 0;

virtual const uint8 *getBlockFileData(int levelIndex) = 0;
void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim);
void scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim);
void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2);
Expand Down Expand Up @@ -233,6 +234,7 @@ friend class TextDisplayer_Eob;
const uint8 *_dscTileIndex;

const uint8 *_dscDoorShpIndex;
int _dscDoorShpIndexSize;
const uint8 *_dscDoorY2;

// Script
Expand Down Expand Up @@ -308,7 +310,7 @@ friend class TextDisplayer_Eob;
virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;

void generateTempData();
void restoreBlockTempData(int levelIndex);
virtual void restoreBlockTempData(int levelIndex);
void releaseTempData();
virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
Expand Down
22 changes: 14 additions & 8 deletions engines/kyra/magic_eob.cpp
Expand Up @@ -236,8 +236,14 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
EobCharacter *c = &_characters[charIndex];
EobSpell *s = &_spells[spell];

if (showWarning)
if (showWarning) {
int od = _screen->curDimIndex();
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
_screen->setScreenDim(7);
printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
_screen->setScreenDim(od);
_screen->setFont(of);
}

if (s->endCallback)
(this->*s->endCallback)(c);
Expand Down Expand Up @@ -1281,12 +1287,12 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
_preventMonsterFlash = false;
}

bool EobCoreEngine::spellCallback_end_lightningBoltPassive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_lightningBolt(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
return magicObjectDamageHit(fo, 0, 0, 12, 1);
}

bool EobCoreEngine::spellCallback_end_unk1Passive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_fireball1(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
bool res = false;
if (_partyEffectFlags & 0x20000) {
Expand All @@ -1301,12 +1307,12 @@ bool EobCoreEngine::spellCallback_end_unk1Passive(void *obj) {
return res;
}

bool EobCoreEngine::spellCallback_end_unk2Passive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_fireball2(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
return magicObjectDamageHit(fo, 0, 0, 18, 0);
}

bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_deathSpell(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
if (fo->curBlock != _currentBlock)
return false;
Expand All @@ -1323,7 +1329,7 @@ bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
return true;
}

bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_disintegrate(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
if (fo->curBlock != _currentBlock)
return false;
Expand All @@ -1339,7 +1345,7 @@ bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
return true;
}

bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_causeCriticalWounds(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
if (fo->curBlock != _currentBlock)
return false;
Expand All @@ -1353,7 +1359,7 @@ bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
return true;
}

bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void *obj) {
bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) {
EobFlyingObject *fo = (EobFlyingObject*)obj;
if (fo->curBlock != _currentBlock)
return false;
Expand Down
50 changes: 24 additions & 26 deletions engines/kyra/saveload_eob.cpp
Expand Up @@ -47,15 +47,7 @@ void LolEobBaseEngine::generateTempData() {
_lvlTempData[l]->wallsXorData = new uint8[4096];
_lvlTempData[l]->flags = new uint16[1024];

const uint8 *p = 0;
const uint8 *p2 = 0;
if (_flags.gameID == GI_LOL) {
screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", _currentLevel).c_str(), 15, 15, 0);
p = screen()->getCPagePtr(14);
} else {
p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", _currentLevel).c_str(), 0);
}

const uint8 *p = getBlockFileData(_currentLevel);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;

Expand All @@ -75,20 +67,11 @@ void LolEobBaseEngine::generateTempData() {
_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);

_hasTempDataFlags |= (1 << l);
delete[] p2;
}

void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
int l = levelIndex - 1;
const uint8 *p = 0;
const uint8 *p2 = 0;
if (_flags.gameID == GI_LOL) {
screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 3, 3, 0);
p = screen()->getCPagePtr(2);
} else {
p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", levelIndex).c_str(), 0);
}

const uint8 *p = getBlockFileData(levelIndex);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;

Expand All @@ -106,8 +89,6 @@ void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
restoreMonsterTempData(_lvlTempData[l]);
restoreFlyingObjectTempData(_lvlTempData[l]);
restoreWallOfForceTempData(_lvlTempData[l]);

delete[] p2;
}

void LolEobBaseEngine::releaseTempData() {
Expand Down Expand Up @@ -144,7 +125,14 @@ void LolEobBaseEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
#ifdef ENABLE_EOB

Common::Error EobCoreEngine::loadGameState(int slot) {
const char *fileName = getSavegameFilename(slot);
const char *fileName = 0;

if (slot == -1) {
_savegameFilename = /*_targetName + */Common::String("eob.fin");
fileName = _savegameFilename.c_str();
} else {
fileName = getSavegameFilename(slot);
}

SaveHeader header;
Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
Expand Down Expand Up @@ -388,7 +376,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
useMagicBookOrSymbol(_openBookChar, _openBookType);
}

_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);

gui_toggleButtons();
setHandItem(_itemInHand);
Expand All @@ -404,8 +392,18 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
}

Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
const Common::String finSuffix(".FIN");
const char *fileName = (slot != -1) ? getSavegameFilename(slot) : (_targetName + finSuffix).c_str();
Common::String saveNameTmp;
const char *fileName = 0;

if (slot == -1) {
_savegameFilename = _targetName + Common::String(".fin");
fileName = _savegameFilename.c_str();
saveNameTmp = _targetName + Common::String(" final");
saveNameTmp.toUppercase();
saveName = saveNameTmp.c_str();
} else {
fileName = getSavegameFilename(slot);
}

Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
if (!out)
Expand Down Expand Up @@ -525,7 +523,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
LevelTempData *l = _lvlTempData[i];
if (!l || !(_hasTempDataFlags & (1 << i)))
continue;

out->write(l->wallsXorData, 4096);
for (int ii = 0; ii < 1024; ii++)
out->writeByte(l->flags[ii] & 0xff);
Expand Down

0 comments on commit 2448d88

Please sign in to comment.