diff options
author | Bendegúz Nagy | 2016-07-26 00:18:31 +0200 |
---|---|---|
committer | Bendegúz Nagy | 2016-08-26 23:02:22 +0200 |
commit | 715ef2d404994737f72de13fd4824ca1ec1708c1 (patch) | |
tree | f27a5cd83130cee279753b90e40143d84832ffdc | |
parent | 9fd7c561986357ea539391cb0d4be238b27ac96d (diff) | |
download | scummvm-rg350-715ef2d404994737f72de13fd4824ca1ec1708c1.tar.gz scummvm-rg350-715ef2d404994737f72de13fd4824ca1ec1708c1.tar.bz2 scummvm-rg350-715ef2d404994737f72de13fd4824ca1ec1708c1.zip |
DM: Debug loading savegames, add missing save loading parts
-rw-r--r-- | engines/dm/champion.cpp | 28 | ||||
-rw-r--r-- | engines/dm/dm.cpp | 17 | ||||
-rw-r--r-- | engines/dm/dungeonman.cpp | 146 | ||||
-rw-r--r-- | engines/dm/dungeonman.h | 10 | ||||
-rw-r--r-- | engines/dm/loadsave.cpp | 93 |
5 files changed, 176 insertions, 118 deletions
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp index 508605baea..a9cfe7a2ef 100644 --- a/engines/dm/champion.cpp +++ b/engines/dm/champion.cpp @@ -1787,8 +1787,32 @@ ChampionIndex ChampionMan::f285_getIndexInCell(int16 cell) { }
void ChampionMan::f278_resetDataToStartGame() {
- if (!_vm->_g298_newGame)
- error("MISSING CODE: stuff for resetting for loaded games");
+ if (!_vm->_g298_newGame) {
+ Thing L0787_T_Thing;
+ if ((L0787_T_Thing = _g414_leaderHandObject) == Thing::_none) {
+ _g415_leaderEmptyHanded = true;
+ _g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
+ _vm->_eventMan->f69_setMousePointer();
+ } else {
+ f297_putObjectInLeaderHand(L0787_T_Thing, true); /* This call will add the weight of the leader hand object to the Load of the leader a first time */
+ }
+ Champion *L0788_ps_Champion = _gK71_champions;
+ int16 L0785_i_ChampionIndex;
+ for (L0785_i_ChampionIndex = k0_ChampionFirst; L0785_i_ChampionIndex < _g305_partyChampionCount; L0785_i_ChampionIndex++, L0788_ps_Champion++) {
+ clearFlag(L0788_ps_Champion->_attributes, k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon | k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport | k0x8000_ChampionAttributeActionHand);
+ setFlag(L0788_ps_Champion->_attributes, k0x8000_ChampionAttributeActionHand | k0x1000_ChampionAttributeStatusBox | k0x0400_ChampionAttributeIcon);
+ }
+ f293_drawAllChampionStates();
+ if ((L0785_i_ChampionIndex = _g411_leaderIndex) != kM1_ChampionNone) {
+ _g411_leaderIndex = kM1_ChampionNone;
+ _vm->_eventMan->f368_commandSetLeader((ChampionIndex)L0785_i_ChampionIndex);
+ }
+ if ((L0785_i_ChampionIndex = _g514_magicCasterChampionIndex) != kM1_ChampionNone) {
+ _g514_magicCasterChampionIndex = kM1_ChampionNone;
+ _vm->_menuMan->f394_setMagicCasterAndDrawSpellArea(L0785_i_ChampionIndex);
+ }
+ return;
+ }
_g414_leaderHandObject = Thing::_none;
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp index cd69479961..dc778aa734 100644 --- a/engines/dm/dm.cpp +++ b/engines/dm/dm.cpp @@ -277,8 +277,11 @@ void DMEngine::f462_startGame() { f3_processNewPartyMap(_dungeonMan->_g309_partyMapIndex); if (!_g298_newGame) { - warning(false, "TODO: loading game"); - assert(false); + _displayMan->_g578_useByteBoxCoordinates = false; + f22_delay(1); + _displayMan->D24_fillScreenBox(g61_boxScreenTop, k0_ColorBlack); + _displayMan->D24_fillScreenBox(g62_boxScreenRight, k0_ColorBlack); + _displayMan->D24_fillScreenBox(g63_boxScreenBottom, k0_ColorBlack); } else { _displayMan->_g578_useByteBoxCoordinates = false; _displayMan->D24_fillScreenBox(g61_boxScreenTop, k0_ColorBlack); @@ -331,10 +334,12 @@ Common::Error DMEngine::run() { } void DMEngine::f2_gameloop() { - warning(false, "DUMMY CODE: SETTING PARTY POS AND DIRECTION"); - _dungeonMan->_g306_partyMapX = 9; - _dungeonMan->_g307_partyMapY = 9; - _dungeonMan->_g308_partyDir = kDirWest; + if (_g298_newGame) { + warning(false, "DUMMY CODE: SETTING PARTY POS AND DIRECTION"); + _dungeonMan->_g306_partyMapX = 9; + _dungeonMan->_g307_partyMapY = 9; + _dungeonMan->_g308_partyDir = kDirWest; + } _g318_waitForInputMaxVerticalBlankCount = 10; while (true) { diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index 38658ce601..da7d2dafa0 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -421,6 +421,7 @@ DungeonMan::~DungeonMan() { for (uint16 i = 0; i < 16; ++i) { delete[] _g284_thingData[i]; } + delete[] _g276_dungeonRawMapData; } void DungeonMan::f455_decompressDungeonFile() { @@ -535,108 +536,119 @@ const Thing Thing::_explRebirthStep1(0xFFE4); // @ C0xFFE4_THING_EXPLOSION_REBIR const Thing Thing::_explRebirthStep2(0xFFE5); // @ C0xFFE5_THING_EXPLOSION_REBIRTH_STEP2 const Thing Thing::_party(0xFFFF); // @ C0xFFFF_THING_PARTY -void DungeonMan::f434_loadDungeonFile() { - - if(!_rawDunFileData) +void DungeonMan::f434_loadDungeonFile(Common::InSaveFile *file) { + if (_vm->_g298_newGame) f455_decompressDungeonFile(); - Common::MemoryReadStream dunDataStream(_rawDunFileData, _rawDunFileDataSize, DisposeAfterUse::NO); + + Common::ReadStream *dunDataStream = nullptr; + if (file) { // if loading a save + dunDataStream = file; + } else { // else read dungeon.dat + assert(_rawDunFileData && _rawDunFileDataSize); + dunDataStream = new Common::MemoryReadStream(_rawDunFileData, _rawDunFileDataSize, DisposeAfterUse::NO); + } // initialize _g278_dungeonFileHeader - _g278_dungeonFileHeader._dungeonId = _g278_dungeonFileHeader._ornamentRandomSeed = dunDataStream.readUint16BE(); - _g278_dungeonFileHeader._rawMapDataSize = dunDataStream.readUint16BE(); - _g278_dungeonFileHeader._mapCount = dunDataStream.readByte(); - dunDataStream.readByte(); // discard 1 byte - _g278_dungeonFileHeader._textDataWordCount = dunDataStream.readUint16BE(); - uint16 partyPosition = dunDataStream.readUint16BE(); - _g278_dungeonFileHeader._partyStartDir = (Direction)((partyPosition >> 10) & 3); - _g278_dungeonFileHeader._partyStartPosY = (partyPosition >> 5) & 0x1F; - _g278_dungeonFileHeader._partyStartPosX = (partyPosition >> 0) & 0x1F; - _g278_dungeonFileHeader._squareFirstThingCount = dunDataStream.readUint16BE(); + _g278_dungeonFileHeader._ornamentRandomSeed = dunDataStream->readUint16BE(); + _g278_dungeonFileHeader._rawMapDataSize = dunDataStream->readUint16BE(); + _g278_dungeonFileHeader._mapCount = dunDataStream->readByte(); + dunDataStream->readByte(); // discard 1 byte + _g278_dungeonFileHeader._textDataWordCount = dunDataStream->readUint16BE(); + _g278_dungeonFileHeader._partyStartLocation = dunDataStream->readUint16BE(); + _g278_dungeonFileHeader._squareFirstThingCount = dunDataStream->readUint16BE(); for (uint16 i = 0; i < k16_ThingTypeTotal; ++i) - _g278_dungeonFileHeader._thingCounts[i] = dunDataStream.readUint16BE(); + _g278_dungeonFileHeader._thingCounts[i] = dunDataStream->readUint16BE(); // init party position and mapindex if (_vm->_g298_newGame) { - _g308_partyDir = _g278_dungeonFileHeader._partyStartDir; - _g306_partyMapX = _g278_dungeonFileHeader._partyStartPosX; - _g307_partyMapY = _g278_dungeonFileHeader._partyStartPosY; + uint16 startLoc = _g278_dungeonFileHeader._partyStartLocation; + _g308_partyDir = (Direction)((startLoc >> 10) & 3); + _g306_partyMapX = startLoc & 0x1F; + _g307_partyMapY = (startLoc >> 5) & 0x1F; _g309_partyMapIndex = 0; } // load map data - delete[] _g277_dungeonMaps; - _g277_dungeonMaps = new Map[_g278_dungeonFileHeader._mapCount]; - for (uint16 i = 0; i < _g278_dungeonFileHeader._mapCount; ++i) { - _g277_dungeonMaps[i]._rawDunDataOffset = dunDataStream.readUint16BE(); - dunDataStream.readUint32BE(); // discard 4 bytes - _g277_dungeonMaps[i]._offsetMapX = dunDataStream.readByte(); - _g277_dungeonMaps[i]._offsetMapY = dunDataStream.readByte(); + if (!_vm->_g523_restartGameRequest) { + delete[] _g277_dungeonMaps; + _g277_dungeonMaps = new Map[_g278_dungeonFileHeader._mapCount]; + } - uint16 tmp = dunDataStream.readUint16BE(); + for (uint16 i = 0; i < _g278_dungeonFileHeader._mapCount; ++i) { + _g277_dungeonMaps[i]._rawDunDataOffset = dunDataStream->readUint16BE(); + dunDataStream->readUint32BE(); // discard 4 bytes + _g277_dungeonMaps[i]._offsetMapX = dunDataStream->readByte(); + _g277_dungeonMaps[i]._offsetMapY = dunDataStream->readByte(); + + uint16 tmp = dunDataStream->readUint16BE(); _g277_dungeonMaps[i]._height = tmp >> 11; _g277_dungeonMaps[i]._width = (tmp >> 6) & 0x1F; - _g277_dungeonMaps[i]._level = tmp & 0x1F; // Only used in DMII + _g277_dungeonMaps[i]._level = tmp & 0x3F; // Only used in DMII - tmp = dunDataStream.readUint16BE(); + tmp = dunDataStream->readUint16BE(); _g277_dungeonMaps[i]._randFloorOrnCount = tmp >> 12; _g277_dungeonMaps[i]._floorOrnCount = (tmp >> 8) & 0xF; _g277_dungeonMaps[i]._randWallOrnCount = (tmp >> 4) & 0xF; _g277_dungeonMaps[i]._wallOrnCount = tmp & 0xF; - tmp = dunDataStream.readUint16BE(); + tmp = dunDataStream->readUint16BE(); _g277_dungeonMaps[i]._difficulty = tmp >> 12; _g277_dungeonMaps[i]._creatureTypeCount = (tmp >> 4) & 0xF; _g277_dungeonMaps[i]._doorOrnCount = tmp & 0xF; - tmp = dunDataStream.readUint16BE(); + tmp = dunDataStream->readUint16BE(); _g277_dungeonMaps[i]._doorSet1 = (tmp >> 12) & 0xF; _g277_dungeonMaps[i]._doorSet0 = (tmp >> 8) & 0xF; _g277_dungeonMaps[i]._wallSet = (WallSet)((tmp >> 4) & 0xF); _g277_dungeonMaps[i]._floorSet = (FloorSet)(tmp & 0xF); } - // TODO: ??? is this - begin - delete[] _g281_dungeonMapsFirstColumnIndex; - _g281_dungeonMapsFirstColumnIndex = new uint16[_g278_dungeonFileHeader._mapCount]; + // load column stuff thingy + if (!_vm->_g523_restartGameRequest) { + delete[] _g281_dungeonMapsFirstColumnIndex; + _g281_dungeonMapsFirstColumnIndex = new uint16[_g278_dungeonFileHeader._mapCount]; + } uint16 columCount = 0; for (uint16 i = 0; i < _g278_dungeonFileHeader._mapCount; ++i) { _g281_dungeonMapsFirstColumnIndex[i] = columCount; columCount += _g277_dungeonMaps[i]._width + 1; } _g282_dungeonColumCount = columCount; - // TODO: ??? is this - end - uint32 actualSquareFirstThingCount = _g278_dungeonFileHeader._squareFirstThingCount; - if (_vm->_g298_newGame) // TODO: what purpose does this serve? + if (_vm->_g298_newGame) _g278_dungeonFileHeader._squareFirstThingCount += 300; - // TODO: ??? is this - begin - delete[] _g280_dungeonColumnsCumulativeSquareThingCount; - _g280_dungeonColumnsCumulativeSquareThingCount = new uint16[columCount]; + if (!_vm->_g523_restartGameRequest) { + delete[] _g280_dungeonColumnsCumulativeSquareThingCount; + _g280_dungeonColumnsCumulativeSquareThingCount = new uint16[columCount]; + } for (uint16 i = 0; i < columCount; ++i) - _g280_dungeonColumnsCumulativeSquareThingCount[i] = dunDataStream.readUint16BE(); - // TODO: ??? is this - end + _g280_dungeonColumnsCumulativeSquareThingCount[i] = dunDataStream->readUint16BE(); - // TODO: ??? is this - begin - delete[] _g283_squareFirstThings; - _g283_squareFirstThings = new Thing[_g278_dungeonFileHeader._squareFirstThingCount]; + + // load sqaure first things + if (!_vm->_g523_restartGameRequest) { + delete[] _g283_squareFirstThings; + _g283_squareFirstThings = new Thing[_g278_dungeonFileHeader._squareFirstThingCount]; + } for (uint16 i = 0; i < actualSquareFirstThingCount; ++i) - _g283_squareFirstThings[i].set(dunDataStream.readUint16BE()); + _g283_squareFirstThings[i].set(dunDataStream->readUint16BE()); if (_vm->_g298_newGame) for (uint16 i = 0; i < 300; ++i) _g283_squareFirstThings[actualSquareFirstThingCount + i] = Thing::_none; - // TODO: ??? is this - end // load text data - delete[] _g260_dungeonTextData; - _g260_dungeonTextData = new uint16[_g278_dungeonFileHeader._textDataWordCount]; + if (!_vm->_g523_restartGameRequest) { + delete[] _g260_dungeonTextData; + _g260_dungeonTextData = new uint16[_g278_dungeonFileHeader._textDataWordCount]; + } for (uint16 i = 0; i < _g278_dungeonFileHeader._textDataWordCount; ++i) - _g260_dungeonTextData[i] = dunDataStream.readUint16BE(); + _g260_dungeonTextData[i] = dunDataStream->readUint16BE(); + - // TODO: ??? what this if (_vm->_g298_newGame) _vm->_timeline->_g369_eventMaxCount = 100; @@ -651,35 +663,26 @@ void DungeonMan::f434_loadDungeonFile() { if (thingStoreWordCount == 0) continue; - if (_g284_thingData[thingType]) { + if (!_vm->_g523_restartGameRequest) { delete[] _g284_thingData[thingType]; + _g284_thingData[thingType] = new uint16[_g278_dungeonFileHeader._thingCounts[thingType] * thingStoreWordCount]; } - _g284_thingData[thingType] = new uint16[_g278_dungeonFileHeader._thingCounts[thingType] * thingStoreWordCount]; - if (thingType == k4_GroupThingType) { + if ((thingType == k4_GroupThingType || thingType == k14_ProjectileThingType) && !file) { // !file because save files have diff. structure than dungeon.dat for (uint16 i = 0; i < thingCount; ++i) { uint16 *nextSlot = _g284_thingData[thingType] + i *thingStoreWordCount; for (uint16 j = 0; j < thingStoreWordCount; ++j) { if (j == 2 || j == 3) - nextSlot[j] = dunDataStream.readByte(); + nextSlot[j] = dunDataStream->readByte(); else - nextSlot[j] = dunDataStream.readUint16BE(); + nextSlot[j] = dunDataStream->readUint16BE(); } } - } else if (thingType == k14_ProjectileThingType) { - for (uint16 i = 0; i < thingCount; ++i) { - uint16 *nextSlot = _g284_thingData[thingType] + i * thingStoreWordCount; - nextSlot[0] = dunDataStream.readUint16BE(); - nextSlot[1] = dunDataStream.readUint16BE(); - nextSlot[2] = dunDataStream.readByte(); - nextSlot[3] = dunDataStream.readByte(); - nextSlot[4] = dunDataStream.readUint16BE(); - } } else { for (uint16 i = 0; i < thingCount; ++i) { uint16 *nextSlot = _g284_thingData[thingType] + i *thingStoreWordCount; for (uint16 j = 0; j < thingStoreWordCount; ++j) - nextSlot[j] = dunDataStream.readUint16BE(); + nextSlot[j] = dunDataStream->readUint16BE(); } } @@ -693,8 +696,13 @@ void DungeonMan::f434_loadDungeonFile() { } // load map data - if (!_vm->_g523_restartGameRequest) - _g276_dungeonRawMapData = _rawDunFileData + dunDataStream.pos(); + if (!_vm->_g523_restartGameRequest) { + delete[] _g276_dungeonRawMapData; + _g276_dungeonRawMapData = new byte[_g278_dungeonFileHeader._rawMapDataSize]; + } + + for (uint32 i = 0; i < _g278_dungeonFileHeader._rawMapDataSize; ++i) + _g276_dungeonRawMapData[i] = dunDataStream->readByte(); if (!_vm->_g523_restartGameRequest) { @@ -712,6 +720,10 @@ void DungeonMan::f434_loadDungeonFile() { } } } + + if (!file) { // this means that we created a new MemoryReadStream + delete file; + } // the deletion of the function parameter 'file' happens elsewhere } void DungeonMan::f173_setCurrentMap(uint16 mapIndex) { diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h index 34aef8d5c4..6fed1848a9 100644 --- a/engines/dm/dungeonman.h +++ b/engines/dm/dungeonman.h @@ -605,14 +605,11 @@ public: }; // wrapper for bytes which are used as squares struct DungeonFileHeader { - uint16 _dungeonId; - // equal to dungeonId uint16 _ornamentRandomSeed; - uint32 _rawMapDataSize; + uint16 _rawMapDataSize; uint8 _mapCount; uint16 _textDataWordCount; - Direction _partyStartDir; // @ InitialPartyLocation - uint16 _partyStartPosX, _partyStartPosY; + uint16 _partyStartLocation; uint16 _squareFirstThingCount; // @ SquareFirstThingCount uint16 _thingCounts[16]; // @ ThingCount[16] }; // @ DUNGEON_HEADER @@ -681,7 +678,7 @@ public: uint16 *f157_getSquareFirstThingData(int16 mapX, int16 mapY); // @ F0157_DUNGEON_GetSquareFirstThingData // TODO: this does stuff other than load the file! - void f434_loadDungeonFile(); // @ F0434_STARTEND_IsLoadDungeonSuccessful_CPSC + void f434_loadDungeonFile(Common::InSaveFile *file); // @ F0434_STARTEND_IsLoadDungeonSuccessful_CPSC void f174_setCurrentMapAndPartyMap(uint16 mapIndex); // @ F0174_DUNGEON_SetCurrentMapAndPartyMap bool f149_isWallOrnAnAlcove(int16 wallOrnIndex); // @ F0149_DUNGEON_IsWallOrnamentAnAlcove @@ -740,7 +737,6 @@ public: Map *_g277_dungeonMaps; // @ G0277_ps_DungeonMaps - // does not have to be freed byte *_g276_dungeonRawMapData; // @ G0276_puc_DungeonRawMapData int16 _g265_currMapInscriptionWallOrnIndex; // @ G0265_i_CurrentMapInscriptionWallOrnamentIndex diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp index 86060d5c9b..ddacff5785 100644 --- a/engines/dm/loadsave.cpp +++ b/engines/dm/loadsave.cpp @@ -42,11 +42,20 @@ namespace DM { #define C2_FORMAT_DM_AMIGA_2X_PC98_X68000_FM_TOWNS_CSB_ATARI_ST 2 #define C3_PLATFORM_AMIGA 3 #define C10_DUNGEON_DM 10 + LoadgameResponse DMEngine::f435_loadgame(int16 slot) { Common::String fileName; Common::SaveFileManager *saveFileManager = nullptr; Common::InSaveFile *file = nullptr; + struct { + int16 _g528_saveFormat = 0; + int16 saveAndPlayChoice = 0; + int32 _g525_gameId = 0; + int16 _g527_platform = 0; + uint16 _g526_dungeonId = 0; + } dmSaveHeader; + if (!_g298_newGame) { fileName = getSavefileName(slot); saveFileManager = _system->getSavefileManager(); @@ -69,8 +78,6 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) { goto T0435004; }*/ - warning(false, "DUMMY CODE in f435_loadgame setting _g298_newGame to k1_modeLoadDungeon"); - _g298_newGame = k1_modeLoadDungeon; SaveGameHeader header; readSaveGameHeader(file, &header); @@ -78,6 +85,14 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) { warning(false, "MISSING CODE: missing check for matching format and platform in save in f435_loadgame"); + dmSaveHeader._g528_saveFormat = file->readSint16BE(); + dmSaveHeader.saveAndPlayChoice = file->readSint16BE(); + dmSaveHeader._g525_gameId = file->readSint32BE(); + dmSaveHeader._g527_platform = file->readSint16BE(); + dmSaveHeader._g526_dungeonId = file->readUint16BE(); + + _g525_gameId = dmSaveHeader._g525_gameId; + _g313_gameTime = file->readSint32BE(); // G0349_ul_LastRandomNumber = L1371_s_GlobalData.LastRandomNumber; _championMan->_g305_partyChampionCount = file->readUint16BE(); @@ -108,10 +123,14 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) { _timeline->load3_eventsPart(file); _timeline->load4_timelinePart(file); - _g525_gameId = file->readSint32BE(); + // read sentinel + uint32 sentinel = file->readUint32BE(); + assert(sentinel == 0x6f85e3d3); } - _dungeonMan->f434_loadDungeonFile(); + _dungeonMan->f434_loadDungeonFile(file); + delete file; + if (_g298_newGame) { _timeline->f233_initTimeline(); _groupMan->f196_initActiveGroups(); @@ -124,16 +143,15 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) { F0436_STARTEND_FadeToPalette(_vm->_displayMan->_g347_paletteTopAndBottomScreen); }*/ } else { - _g528_saveFormat = file->readSint16BE(); - _g527_platform = file->readSint16BE(); - _g526_dungeonId = file->readUint16BE(); + _g528_saveFormat = dmSaveHeader._g528_saveFormat; + _g527_platform = dmSaveHeader._g527_platform; + _g526_dungeonId = dmSaveHeader._g526_dungeonId; - _g524_restartGameAllowed = true; + _g524_restartGameAllowed = true; warning(false, "MISSING CDOE: F0427_DIALOG_Draw in f435_loadgame"); } _championMan->_g303_partyDead = false; - delete file; return k1_LoadgameSuccess; } @@ -168,6 +186,12 @@ void DMEngine::f433_processCommand140_saveGame(uint16 slot, const Common::String writeSaveGameHeader(file, desc); + file->writeSint16BE(_g528_saveFormat); + file->writeSint16BE(saveAndPlayChoice); + file->writeSint32BE(_g525_gameId); + file->writeSint16BE(_g527_platform); + file->writeUint16BE(_g526_dungeonId); + // write C0_SAVE_PART_GLOBAL_DATA part file->writeSint32BE(_g313_gameTime); //L1348_s_GlobalData.LastRandomNumber = G0349_ul_LastRandomNumber; @@ -199,24 +223,18 @@ void DMEngine::f433_processCommand140_saveGame(uint16 slot, const Common::String // write C4_SAVE_PART_TIMELINE part _timeline->save4_timelinePart(file); - file->writeSint32BE(_g525_gameId); - file->writeSint16BE(_g528_saveFormat); - file->writeSint16BE(_g527_platform); - file->writeUint16BE(_g526_dungeonId); - - file->writeSint16BE(saveAndPlayChoice); + // write sentinel + file->writeUint32BE(0x6f85e3d3); // save _g278_dungeonFileHeader { DungeonFileHeader &header = _dungeonMan->_g278_dungeonFileHeader; - file->writeUint16BE(header._dungeonId); file->writeUint16BE(header._ornamentRandomSeed); - file->writeUint32BE(header._rawMapDataSize); + file->writeUint16BE(header._rawMapDataSize); file->writeByte(header._mapCount); + file->writeByte(0); // to match the structure of dungeon.dat, will be discarded file->writeUint16BE(header._textDataWordCount); - file->writeUint16BE(header._partyStartDir); - file->writeUint16BE(header._partyStartPosX); - file->writeUint16BE(header._partyStartPosY); + file->writeUint16BE(header._partyStartLocation); file->writeUint16BE(header._squareFirstThingCount); for (uint16 i = 0; i < 16; ++i) file->writeUint16BE(header._thingCounts[i]); @@ -225,23 +243,26 @@ void DMEngine::f433_processCommand140_saveGame(uint16 slot, const Common::String // save _g277_dungeonMaps for (uint16 i = 0; i < _dungeonMan->_g278_dungeonFileHeader._mapCount; ++i) { Map &map = _dungeonMan->_g277_dungeonMaps[i]; - file->writeUint32BE(map._rawDunDataOffset); + uint16 tmp; + + file->writeUint16BE(map._rawDunDataOffset); + file->writeUint32BE(0); // to match the structure of dungeon.dat, will be discarded file->writeByte(map._offsetMapX); file->writeByte(map._offsetMapY); - file->writeByte(map._level); - file->writeByte(map._width); - file->writeByte(map._height); - file->writeByte(map._wallOrnCount); - file->writeByte(map._randWallOrnCount); - file->writeByte(map._floorOrnCount); - file->writeByte(map._randFloorOrnCount); - file->writeByte(map._doorOrnCount); - file->writeByte(map._creatureTypeCount); - file->writeByte(map._difficulty); - file->writeSint16BE(map._floorSet); - file->writeSint16BE(map._wallSet); - file->writeByte(map._doorSet0); - file->writeByte(map._doorSet1); + + tmp = ((map._height & 0x1F) << 11) | ((map._width & 0x1F) << 6) | (map._level & 0x3F); + file->writeUint16BE(tmp); + + tmp = ((map._randFloorOrnCount & 0xF) << 12) | ((map._floorOrnCount & 0xF) << 8) + | ((map._randWallOrnCount & 0xF) << 4) | (map._wallOrnCount & 0xF); + file->writeUint16BE(tmp); + + tmp = ((map._difficulty & 0xF) << 12) | ((map._creatureTypeCount & 0xF) << 4) | (map._doorOrnCount & 0xF); + file->writeUint16BE(tmp); + + tmp = ((map._doorSet1 & 0xF) << 12) | ((map._doorSet0 & 0xF) << 8) + | ((map._wallSet & 0xF) << 4) | (map._floorSet & 0xF); + file->writeUint16BE(tmp); } // save _g280_dungeonColumnsCumulativeSquareThingCount @@ -262,7 +283,7 @@ void DMEngine::f433_processCommand140_saveGame(uint16 slot, const Common::String file->writeUint16BE(_dungeonMan->_g284_thingData[thingIndex][i]); // save _g276_dungeonRawMapData - for (uint16 i = 0; i < _dungeonMan->_g278_dungeonFileHeader._rawMapDataSize; ++i) + for (uint32 i = 0; i < _dungeonMan->_g278_dungeonFileHeader._rawMapDataSize; ++i) file->writeByte(_dungeonMan->_g276_dungeonRawMapData[i]); file->flush(); |