aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/dm/champion.cpp28
-rw-r--r--engines/dm/dm.cpp17
-rw-r--r--engines/dm/dungeonman.cpp146
-rw-r--r--engines/dm/dungeonman.h10
-rw-r--r--engines/dm/loadsave.cpp93
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();