diff options
author | athrxx | 2011-12-13 21:56:35 +0100 |
---|---|---|
committer | athrxx | 2011-12-28 00:01:31 +0100 |
commit | 75c0036925107a844d211854f7194aebcbedd718 (patch) | |
tree | 69a70868687c71ca36c1c63f4d241ade5a539f40 | |
parent | 99b14c5dbc9414b46afffabafb4be9c9c4c51fd1 (diff) | |
download | scummvm-rg350-75c0036925107a844d211854f7194aebcbedd718.tar.gz scummvm-rg350-75c0036925107a844d211854f7194aebcbedd718.tar.bz2 scummvm-rg350-75c0036925107a844d211854f7194aebcbedd718.zip |
KYRA: (LOL) - add support for loading original DOS version save files
-rw-r--r-- | engines/kyra/saveload.cpp | 12 | ||||
-rw-r--r-- | engines/kyra/saveload_lol.cpp | 208 |
2 files changed, 147 insertions, 73 deletions
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index 3bca6b0e3c..9fd470f740 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -54,7 +54,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab header.gameID = in->readByte(); } else { // try checking for original save header - const int descriptionSize[2] = { 30, 80 }; + const int descriptionSize[3] = { 30, 80, 60 }; char descriptionBuffer[81]; bool saveOk = false; @@ -78,6 +78,16 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab header.description = descriptionBuffer; header.gameID = GI_KYRA3; break; + } else if (type == MKTAG('C','D','0','4')) { + header.version = in->readUint32BE(); + // We don't check the minor version, since the original doesn't do that either and it isn't required. + if (header.version != MKTAG(' ','C','D','1')) + continue; + saveOk = true; + header.description = descriptionBuffer; + header.gameID = GI_LOL; + in->seek(6, SEEK_CUR); + break; } } diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp index c4262c0edd..2b7236f48b 100644 --- a/engines/kyra/saveload_lol.cpp +++ b/engines/kyra/saveload_lol.cpp @@ -27,6 +27,7 @@ #include "common/savefile.h" #include "common/substream.h" +#include "common/memstream.h" #include "graphics/scaler.h" @@ -44,6 +45,9 @@ Common::Error LoLEngine::loadGameState(int slot) { return Common::kNoError; } + if (header.originalSave) + warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported"); + _screen->fadeClearSceneWindow(10); completeDoorOperations(); _screen->fillRect(112, 0, 287, 119, 0, 0); @@ -53,38 +57,40 @@ Common::Error LoLEngine::loadGameState(int slot) { for (int i = 0; i < 4; i++) { LoLCharacter *c = &_characters[i]; - c->flags = in.readUint16BE(); + c->flags = in.readUint16(); in.read(c->name, 11); c->raceClassSex = in.readByte(); - c->id = in.readSint16BE(); + c->id = in.readSint16(); c->curFaceFrame = in.readByte(); c->tempFaceFrame = in.readByte(); c->screamSfx = in.readByte(); + if (header.originalSave) + in.skip(4); for (int ii = 0; ii < 8; ii++) - c->itemsMight[ii] = in.readUint16BE(); + c->itemsMight[ii] = in.readUint16(); for (int ii = 0; ii < 8; ii++) - c->protectionAgainstItems[ii] = in.readUint16BE(); - c->itemProtection = in.readUint16BE(); - c->hitPointsCur = in.readSint16BE(); - c->hitPointsMax = in.readUint16BE(); - c->magicPointsCur = in.readSint16BE(); - c->magicPointsMax = in.readUint16BE(); + c->protectionAgainstItems[ii] = in.readUint16(); + c->itemProtection = in.readUint16(); + c->hitPointsCur = in.readSint16(); + c->hitPointsMax = in.readUint16(); + c->magicPointsCur = in.readSint16(); + c->magicPointsMax = in.readUint16(); c->field_41 = in.readByte(); - c->damageSuffered = in.readUint16BE(); - c->weaponHit = in.readUint16BE(); - c->totalMightModifier = in.readUint16BE(); - c->totalProtectionModifier = in.readUint16BE(); - c->might = in.readUint16BE(); - c->protection = in.readUint16BE(); - c->nextAnimUpdateCountdown = in.readSint16BE(); + c->damageSuffered = in.readUint16(); + c->weaponHit = in.readUint16(); + c->totalMightModifier = in.readUint16(); + c->totalProtectionModifier = in.readUint16(); + c->might = in.readUint16(); + c->protection = in.readUint16(); + c->nextAnimUpdateCountdown = in.readSint16(); for (int ii = 0; ii < 11; ii++) - c->items[ii] = in.readUint16BE(); + c->items[ii] = in.readUint16(); for (int ii = 0; ii < 3; ii++) c->skillLevels[ii] = in.readByte(); for (int ii = 0; ii < 3; ii++) c->skillModifiers[ii] = in.readSByte(); for (int ii = 0; ii < 3; ii++) - c->experiencePts[ii] = in.readUint32BE(); + c->experiencePts[ii] = in.readUint32(); for (int ii = 0; ii < 5; ii++) c->characterUpdateEvents[ii] = in.readByte(); for (int ii = 0; ii < 5; ii++) @@ -96,39 +102,48 @@ Common::Error LoLEngine::loadGameState(int slot) { } } - in.read(_wllAutomapData, 80); + if (!header.originalSave) + in.read(_wllAutomapData, 80); - _currentBlock = in.readUint16BE(); - _partyPosX = in.readUint16BE(); - _partyPosY = in.readUint16BE(); - _updateFlags = in.readUint16BE(); + _currentBlock = in.readUint16(); + _partyPosX = in.readUint16(); + _partyPosY = in.readUint16(); + _updateFlags = in.readUint16(); _scriptDirection = in.readByte(); _selectedSpell = in.readByte(); + + if (header.originalSave) + in.skip(2); + _sceneDefaultUpdate = in.readByte(); _compassBroken = in.readByte(); _drainMagic = in.readByte(); - _currentDirection = in.readUint16BE(); - _compassDirection = in.readUint16BE(); + _currentDirection = in.readUint16(); + _compassDirection = in.readUint16(); _selectedCharacter = in.readSByte(); + + if (header.originalSave) + in.skip(1); + _currentLevel = in.readByte(); for (int i = 0; i < 48; i++) - _inventory[i] = in.readSint16BE(); - _inventoryCurItem = in.readSint16BE(); - _itemInHand = in.readSint16BE(); - _lastMouseRegion = in.readSint16BE(); + _inventory[i] = in.readSint16(); + _inventoryCurItem = in.readSint16(); + _itemInHand = in.readSint16(); + _lastMouseRegion = in.readSint16(); - if (header.version <= 15) { + if (header.originalSave || header.version <= 15) { uint16 flags[40]; memset(flags, 0, sizeof(flags)); if (header.version == 14) { for (int i = 0; i < 16; i++) - flags[i] = in.readUint16BE(); - flags[26] = in.readUint16BE(); - flags[36] = in.readUint16BE(); - } else if (header.version == 15) { + flags[i] = in.readUint16(); + flags[26] = in.readUint16(); + flags[36] = in.readUint16(); + } else if (header.originalSave || header.version == 15) { for (int i = 0; i < 40; i++) - flags[i] = in.readUint16BE(); + flags[i] = in.readUint16(); } memset(_flagsTable, 0, sizeof(_flagsTable)); @@ -139,37 +154,56 @@ Common::Error LoLEngine::loadGameState(int slot) { } } } else { - uint32 flagsSize = in.readUint32BE(); + uint32 flagsSize = in.readUint32(); assert(flagsSize <= sizeof(_flagsTable)); in.read(_flagsTable, flagsSize); } + if (header.originalSave) + in.skip(120); + for (int i = 0; i < 24; i++) - _globalScriptVars[i] = in.readUint16BE(); + _globalScriptVars[i] = in.readUint16(); + + if (header.originalSave) + in.skip(152); + _brightness = in.readByte(); _lampOilStatus = in.readByte(); _lampEffect = in.readSByte(); - _credits = in.readUint16BE(); + + if (header.originalSave) + in.skip(1); + + _credits = in.readUint16(); for (int i = 0; i < 8; i++) - _globalScriptVars2[i] = in.readUint16BE(); + _globalScriptVars2[i] = in.readUint16(); in.read(_availableSpells, 7); - _hasTempDataFlags = in.readUint32BE(); + _hasTempDataFlags = in.readUint32(); + + uint8 *origCmp = 0; + if (header.originalSave) { + in.skip(6); + origCmp = new uint8[2496]; + } for (int i = 0; i < 400; i++) { ItemInPlay *t = &_itemsInPlay[i]; - t->nextAssignedObject = in.readUint16BE(); - t->nextDrawObject = in.readUint16BE(); + t->nextAssignedObject = in.readUint16(); + t->nextDrawObject = in.readUint16(); t->flyingHeight = in.readByte(); - t->block = in.readUint16BE(); - t->x = in.readUint16BE(); - t->y = in.readUint16BE(); + t->block = in.readUint16(); + t->x = in.readUint16(); + t->y = in.readUint16(); t->level = in.readSByte(); - t->itemPropertyIndex = in.readUint16BE(); - t->shpCurFrame_flg = in.readUint16BE(); - t->destDirection = in.readByte(); - t->hitOffsX = in.readSByte(); - t->hitOffsY = in.readSByte(); - t->currentSubFrame = in.readByte(); + t->itemPropertyIndex = in.readUint16(); + t->shpCurFrame_flg = in.readUint16(); + if (!header.originalSave) { + t->destDirection = in.readByte(); + t->hitOffsX = in.readSByte(); + t->hitOffsY = in.readSByte(); + t->currentSubFrame = in.readByte(); + } } for (int i = 0; i < 1024; i++) { @@ -179,8 +213,13 @@ Common::Error LoLEngine::loadGameState(int slot) { } for (int i = 0; i < 29; i++) { - if (!(_hasTempDataFlags & (1 << i))) + if (!(_hasTempDataFlags & (1 << i))) { + if (header.originalSave) { + if (in.size() - in.pos() >= 2500) + in.skip(2500); + } continue; + } if (_lvlTempData[i]) { delete[] _lvlTempData[i]->wallsXorData; @@ -195,26 +234,40 @@ Common::Error LoLEngine::loadGameState(int slot) { _lvlTempData[i]->wallsXorData = new uint8[4096]; _lvlTempData[i]->flags = new uint16[1024]; LoLMonsterInPlay *lm = new LoLMonsterInPlay[30]; - _lvlTempData[i]->monsters = lm; + _lvlTempData[i]->monsters = lm; FlyingObject *lf = new FlyingObject[_numFlyingObjects]; _lvlTempData[i]->flyingObjects = lf; LevelTempData *l = _lvlTempData[i]; + + uint32 next = in.pos() + 2500; + + if (header.originalSave) { + in.skip(4); + in.read(origCmp, in.readUint16()); + _screen->decodeFrame4(origCmp, _tempBuffer5120, 5120); + memcpy(l->wallsXorData, _tempBuffer5120, 4096); + for (int ii = 0; ii < 1024; ii++) + l->flags[ii] = _tempBuffer5120[4096 + ii]; + } else { + in.read(l->wallsXorData, 4096); + for (int ii = 0; ii < 1024; ii++) + l->flags[ii] = in.readByte(); + } - in.read(l->wallsXorData, 4096); - for (int ii = 0; ii < 1024; ii++) - l->flags[ii] = in.readByte(); + if (header.originalSave) + l->monsterDifficulty = in.readUint16(); for (int ii = 0; ii < 30; ii++) { LoLMonsterInPlay *m = &lm[ii]; - m->nextAssignedObject = in.readUint16BE(); - m->nextDrawObject = in.readUint16BE(); + m->nextAssignedObject = in.readUint16(); + m->nextDrawObject = in.readUint16(); m->flyingHeight = in.readByte(); - m->block = in.readUint16BE(); - m->x = in.readUint16BE(); - m->y = in.readUint16BE(); + m->block = in.readUint16(); + m->x = in.readUint16(); + m->y = in.readUint16(); m->shiftStep = in.readSByte(); - m->destX = in.readUint16BE(); - m->destY = in.readUint16BE(); + m->destX = in.readUint16(); + m->destY = in.readUint16(); m->destDirection = in.readByte(); m->hitOffsX = in.readSByte(); m->hitOffsY = in.readSByte(); @@ -224,15 +277,19 @@ Common::Error LoLEngine::loadGameState(int slot) { m->id = in.readByte(); m->direction = in.readByte(); m->facing = in.readByte(); - m->flags = in.readUint16BE(); - m->damageReceived = in.readUint16BE(); - m->hitPoints = in.readSint16BE(); + m->flags = in.readUint16(); + m->damageReceived = in.readUint16(); + m->hitPoints = in.readSint16(); m->speedTick = in.readByte(); m->type = in.readByte(); + + if (header.originalSave) + in.skip(4); + m->numDistAttacks = in.readByte(); m->curDistWeapon = in.readByte(); m->distAttackTick = in.readSByte(); - m->assignedItems = in.readUint16BE(); + m->assignedItems = in.readUint16(); m->properties = &_monsterProperties[m->type]; in.read(m->equipmentShapes, 4); } @@ -241,10 +298,10 @@ Common::Error LoLEngine::loadGameState(int slot) { FlyingObject *m = &lf[ii]; m->enable = in.readByte(); m->objectType = in.readByte(); - m->attackerId = in.readUint16BE(); - m->item = in.readSint16BE(); - m->x = in.readUint16BE(); - m->y = in.readUint16BE(); + m->attackerId = in.readUint16(); + m->item = in.readSint16(); + m->x = in.readUint16(); + m->y = in.readUint16(); m->flyingHeight = in.readByte(); m->direction = in.readByte(); m->distance = in.readByte(); @@ -253,9 +310,15 @@ Common::Error LoLEngine::loadGameState(int slot) { m->flags = in.readByte(); m->wallFlags = in.readByte(); } - l->monsterDifficulty = in.readByte(); + + if (header.originalSave) + in.seek(next, SEEK_SET); + else + l->monsterDifficulty = in.readByte(); } + delete[] origCmp; + calcCharPortraitXpos(); memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight)); int t = _credits; @@ -369,6 +432,7 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con out->writeSByte(t->level); out->writeUint16BE(t->itemPropertyIndex); out->writeUint16BE(t->shpCurFrame_flg); + out->writeByte(t->destDirection); out->writeSByte(t->hitOffsX); out->writeSByte(t->hitOffsY); |