DM: Debug loading savegames, add missing save loading parts

This commit is contained in:
Bendegúz Nagy 2016-07-26 00:18:31 +02:00
parent 9fd7c56198
commit 715ef2d404
5 changed files with 176 additions and 118 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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();