[Scummvm-git-logs] scummvm master -> d67d4cce66530428d3d5cd51ac4b50486aeb05db

sev- noreply at scummvm.org
Fri Aug 7 20:30:35 UTC 2026


This automated email contains information about 39 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
2f7c9f4ed7 DM: Add detection for DOS v3.4 English
e9e4b6aa30 DM: Add platform-dependent asset loaders
0243fc9830 DM: Add DOS-specific palette index definitions to DisplayMan
a7eba4fbe2 DM: Implement DOS VGA palette lookup tables and setMultipleColorsInPalette
1b900f2fbc DM: Implement DOS viewport palette switching and light-level scaling
4a31e5e7d6 DM: Implement DOS palette transitions in startEndFadeToPalette
26821ac37b DM: Add support for DOS wall and floor set graphics mapping
821fd601ba DM: Implement IMG3 RLE decoder for DOS version
534aaff636 DM: Handle DOS even-width padding in getPixelWidth and adjust wall set flip indices
ca291e68e1 DM: Handle DOS null-terminated object names and bitmap blit stride lookups
88beab4c4d DM: Dynamically size flipped wall buffers using actual graphic dimensions
729239556b DM: Fix font indexing and graphics unpacking
0f7e8549ab DM: Map platform-aware graphic database indices for DOS
1d87adc06a DM: Populate UI panel palette entries 0-15 while in dungeon
7367d18611 DM: Correct viewport palette shift to viewport region and enable only when viewport switching active
bb1dfa8c0b DM: Fix entrance gate and UI rendering by expanding dynamic bitmap dimension lookups
687b609e3c DM: Fix DOS right UI panel box bounds
462bae74cc DM: Map spell area lines graphic index for DOS platform
08e6e286bb DM: Add support for sound in DOS version
347084dc58 DM: Clear shared spell area buffer before reusing
10eec0db15 DM: Load and render separate individual wall panel graphics on DOS
3042df79bd DM: Add layout records tables and coordinate traversal logic (DOS)
eb72c689d2 DM: Integrate DOS layout system with dungeon view rendering
ab14dac5e1 DM: Fix D0 side wall clipping and D0R right-alignment offset
93d17d2409 DM: Fix DOS spell casting panel positioning and rendering
a1ceb64063 DM: Fix graphics corruption when scaling D2/D3 ornaments in DOS version
1f2eb0e0cd DM: Fix D2 wall ornament scaling aspect ratio in DOS version
e85d4d437b DM: Fix champion portrait bounding box in DOS version
585faa30ae DM: Fix crash by dynamically sizing temporary bitmap buffer
33045249db DM: Render DOS doors and door frames using DOS Layout Tree
d9abaa1449 DM: Render spell caster controls using Layout Tree zones in DOS version
3c7631ebd5 DM: Map object names graphic index in DOS version
8d5889beac DM: Fix Things corruption on D1 square in DOS version
ca702bf41e DM: Fix entrance sensor version check and completed Firestaff possession matching in DOS version
8df46ac95a DM: Fix teleporter and fluxcage field graphic index mapping in DOS
108b3b4f8e DM: Fix item scaling calculation on D2 and D3 tiles in DOS version
3a1e8046ed DM: Fix door button placement using kDMZoneDoorButton layout zone in DOS version
28ef69171a DM: Fix thrown object and projectile scaling calculation in DOS version
d67d4cce66 DM: Fix floor/ceiling pit positioning and stairs graphic mapping in DOS version


Commit: 2f7c9f4ed7687e7e4f44382cb0a9561a7f956b29
    https://github.com/scummvm/scummvm/commit/2f7c9f4ed7687e7e4f44382cb0a9561a7f956b29
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add detection for DOS v3.4 English

Changed paths:
    engines/dm/detection.cpp


diff --git a/engines/dm/detection.cpp b/engines/dm/detection.cpp
index 82bb6793d11..f6fbfa294f3 100644
--- a/engines/dm/detection.cpp
+++ b/engines/dm/detection.cpp
@@ -48,6 +48,17 @@ static const DMADGameDescription gameDescriptions[] = {
 		{ kDMSaveFormatAmigaPC98FmTowns, kDMSaveFormatEndOfList},
 		{ kDMSavePlatformAcceptAny}
 	},
+	{
+		{"dm", "MS DOS v3.4 English",
+			AD_ENTRY2s("graphics.dat",	"c0cee1d0f9ee9946f955999a66b54eb5", 363417,
+					   "Dungeon.dat",	"ebfc4019b67e66da41a20224c8a3f0c3", 33357),
+	    	Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GUIO_NOMIDI),
+	    },
+	    kDMSaveTargetDM21, kDMSaveFormatAmigaPC98FmTowns, kDMSavePlatformPC,
+	    { kDMSaveTargetDM21, kDMSaveTargetEndOfList},
+	    { kDMSaveFormatAmigaPC98FmTowns, kDMSaveFormatEndOfList},
+	    { kDMSavePlatformAcceptAny }
+	},
 	{
 		{"dm", "Atari v??? English",
 			AD_ENTRY2s("graphics.dat",	"6ffff2a17e2df0effa9a12fb4b1bf6b6", 271911,


Commit: e9e4b6aa30c0e27e3e4213e2c2e884ecdcc06001
    https://github.com/scummvm/scummvm/commit/e9e4b6aa30c0e27e3e4213e2c2e884ecdcc06001
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add platform-dependent asset loaders

Support checking signature bit 0x8000 and skipping width/height attribute tables (DOS version)

Changed paths:
    engines/dm/dm.h
    engines/dm/dungeonman.cpp
    engines/dm/gfx.cpp


diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 431da797a27..55f6b05958e 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -209,6 +209,7 @@ public:
 	void entranceDrawCredits();
 	void fuseSequence(); // @ F0446_STARTEND_FuseSequence
 	Common::Language getGameLanguage();
+	Common::Platform getPlatform() const { return _gameVersion->_desc.platform; }
 
 	Direction turnDirRight(int16 dir); // @ M17_NEXT
 	Direction turnDirLeft(int16 dir); // @ M19_PREVIOUS
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index 212056de1b3..f3338cfe45b 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -479,11 +479,14 @@ void DungeonMan::decompressDungeonFile() {
 	if (!f.isOpen())
 		error("Unable to open Dungeon.dat file");
 
-	if (f.readUint16BE() == 0x8104) { // if dungeon is compressed
-		_rawDunFileDataSize = f.readUint32BE();
+	bool bigEndian = (_vm->getPlatform() != Common::kPlatformDOS);
+	Common::SeekableReadStreamEndianWrapper safeStream(&f, bigEndian, DisposeAfterUse::NO);
+
+	if (safeStream.readUint16() == 0x8104) { // if dungeon is compressed
+		_rawDunFileDataSize = safeStream.readUint32();
 		delete[] _rawDunFileData;
 		_rawDunFileData = new byte[_rawDunFileDataSize];
-		f.readUint16BE(); // discard
+		safeStream.readUint16(); // discard
 		byte common[4];
 		for (uint16 i = 0; i < 4; ++i)
 			common[i] = f.readByte();
@@ -494,7 +497,7 @@ void DungeonMan::decompressDungeonFile() {
 		// start unpacking
 		uint32 uncompIndex = 0;
 		uint8 bitsUsedInWord = 0;
-		uint16 wordBuff = f.readUint16BE();
+		uint16 wordBuff = safeStream.readUint16();
 		uint8 bitsLeftInByte = 8;
 		byte byteBuff = f.readByte();
 		while (uncompIndex < _rawDunFileDataSize) {
@@ -561,26 +564,31 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 	if (_vm->_gameMode != kDMModeLoadSavedGame)
 		decompressDungeonFile();
 
-	Common::ReadStream *dunDataStream = nullptr;
+	Common::SeekableReadStream *rawDunDataStream = nullptr;
 	if (file) {
 		// if loading a save
-		dunDataStream = file;
+		rawDunDataStream = file;
 	} else {
 		// else read dungeon.dat
 		assert(_rawDunFileData && _rawDunFileDataSize);
-		dunDataStream = new Common::MemoryReadStream(_rawDunFileData, _rawDunFileDataSize, DisposeAfterUse::NO);
+		rawDunDataStream = new Common::MemoryReadStream(_rawDunFileData, _rawDunFileDataSize, DisposeAfterUse::NO);
 	}
 
+	bool isSavegame = (file != nullptr);
+	bool bigEndian = isSavegame || (_vm->getPlatform() != Common::kPlatformDOS);
+	Common::SeekableReadStreamEndianWrapper safeStream(rawDunDataStream, bigEndian, isSavegame ? DisposeAfterUse::NO : DisposeAfterUse::YES);
+	Common::SeekableReadStreamEndianWrapper *dunDataStream = &safeStream;
+
 	// initialize _g278_dungeonFileHeader
-	_dungeonFileHeader._ornamentRandomSeed = dunDataStream->readUint16BE();
-	_dungeonFileHeader._rawMapDataSize = dunDataStream->readUint16BE();
+	_dungeonFileHeader._ornamentRandomSeed = dunDataStream->readUint16();
+	_dungeonFileHeader._rawMapDataSize = dunDataStream->readUint16();
 	_dungeonFileHeader._mapCount = dunDataStream->readByte();
 	dunDataStream->readByte(); // discard 1 byte
-	_dungeonFileHeader._textDataWordCount = dunDataStream->readUint16BE();
-	_dungeonFileHeader._partyStartLocation = dunDataStream->readUint16BE();
-	_dungeonFileHeader._squareFirstThingCount = dunDataStream->readUint16BE();
+	_dungeonFileHeader._textDataWordCount = dunDataStream->readUint16();
+	_dungeonFileHeader._partyStartLocation = dunDataStream->readUint16();
+	_dungeonFileHeader._squareFirstThingCount = dunDataStream->readUint16();
 	for (uint16 i = 0; i < kDMThingTypeTotal; ++i)
-		_dungeonFileHeader._thingCounts[i] = dunDataStream->readUint16BE();
+		_dungeonFileHeader._thingCounts[i] = dunDataStream->readUint16();
 
 	// init party position and mapindex
 	if (_vm->_gameMode != kDMModeLoadSavedGame) {
@@ -598,28 +606,28 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 	}
 
 	for (uint16 i = 0; i < _dungeonFileHeader._mapCount; ++i) {
-		_dungeonMaps[i]._rawDunDataOffset = dunDataStream->readUint16BE();
-		dunDataStream->readUint32BE(); // discard 4 bytes
+		_dungeonMaps[i]._rawDunDataOffset = dunDataStream->readUint16();
+		dunDataStream->readUint32(); // discard 4 bytes
 		_dungeonMaps[i]._offsetMapX = dunDataStream->readByte();
 		_dungeonMaps[i]._offsetMapY = dunDataStream->readByte();
 
-		uint16 tmp = dunDataStream->readUint16BE();
+		uint16 tmp = dunDataStream->readUint16();
 		_dungeonMaps[i]._height = tmp >> 11;
 		_dungeonMaps[i]._width = (tmp >> 6) & 0x1F;
 		_dungeonMaps[i]._level = tmp & 0x3F; // Only used in DMII
 
-		tmp = dunDataStream->readUint16BE();
+		tmp = dunDataStream->readUint16();
 		_dungeonMaps[i]._randFloorOrnCount = tmp >> 12;
 		_dungeonMaps[i]._floorOrnCount = (tmp >> 8) & 0xF;
 		_dungeonMaps[i]._randWallOrnCount = (tmp >> 4) & 0xF;
 		_dungeonMaps[i]._wallOrnCount = tmp & 0xF;
 
-		tmp = dunDataStream->readUint16BE();
+		tmp = dunDataStream->readUint16();
 		_dungeonMaps[i]._difficulty = tmp >> 12;
 		_dungeonMaps[i]._creatureTypeCount = (tmp >> 4) & 0xF;
 		_dungeonMaps[i]._doorOrnCount = tmp & 0xF;
 
-		tmp = dunDataStream->readUint16BE();
+		tmp = dunDataStream->readUint16();
 		_dungeonMaps[i]._doorSet1 = (tmp >> 12) & 0xF;
 		_dungeonMaps[i]._doorSet0 = (tmp >> 8) & 0xF;
 		_dungeonMaps[i]._wallSet = (WallSet)((tmp >> 4) & 0xF);
@@ -650,7 +658,7 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 		_dungeonColumnsCumulativeSquareThingCount = new uint16[columCount];
 	}
 	for (uint16 i = 0; i < columCount; ++i)
-		_dungeonColumnsCumulativeSquareThingCount[i] = dunDataStream->readUint16BE();
+		_dungeonColumnsCumulativeSquareThingCount[i] = dunDataStream->readUint16();
 
 	// load square first things
 	if (!_vm->_restartGameRequest) {
@@ -659,7 +667,7 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 	}
 
 	for (uint16 i = 0; i < actualSquareFirstThingCount; ++i)
-		_squareFirstThings[i].set(dunDataStream->readUint16BE());
+		_squareFirstThings[i].set(dunDataStream->readUint16());
 
 	if (_vm->_gameMode != kDMModeLoadSavedGame) {
 		for (uint16 i = 0; i < 300; ++i)
@@ -673,7 +681,7 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 	}
 
 	for (uint16 i = 0; i < _dungeonFileHeader._textDataWordCount; ++i)
-		_dungeonTextData[i] = dunDataStream->readUint16BE();
+		_dungeonTextData[i] = dunDataStream->readUint16();
 
 	if (_vm->_gameMode != kDMModeLoadSavedGame)
 		timeline._eventMaxCount = 100;
@@ -748,108 +756,108 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 			switch (thingType) {
 			case kDMThingTypeDoor: {
 				Door &door = _doors[i];
-				door._nextThing = Thing(dunDataStream->readUint16BE());
-				door._attributes = dunDataStream->readUint16BE();
+				door._nextThing = Thing(dunDataStream->readUint16());
+				door._attributes = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeTeleporter: {
 				Teleporter &tele = _teleporters[i];
-				tele._nextThing = Thing(dunDataStream->readUint16BE());
-				tele._attributes = dunDataStream->readUint16BE();
-				tele._destMapIndex = dunDataStream->readUint16BE();
+				tele._nextThing = Thing(dunDataStream->readUint16());
+				tele._attributes = dunDataStream->readUint16();
+				tele._destMapIndex = dunDataStream->readUint16();
 				break;
 			}
 			case kDMstringTypeText: {
 				TextString &text = _textStrings[i];
-				text._nextThing = Thing(dunDataStream->readUint16BE());
-				text._textDataRef = dunDataStream->readUint16BE();
+				text._nextThing = Thing(dunDataStream->readUint16());
+				text._textDataRef = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeSensor: {
 				Sensor &sens = _sensors[i];
-				sens._nextThing = Thing(dunDataStream->readUint16BE());
-				sens._datAndType = dunDataStream->readUint16BE();
-				sens._attributes = dunDataStream->readUint16BE();
-				sens._action = dunDataStream->readUint16BE();
+				sens._nextThing = Thing(dunDataStream->readUint16());
+				sens._datAndType = dunDataStream->readUint16();
+				sens._attributes = dunDataStream->readUint16();
+				sens._action = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeGroup: {
 				Group &grp = _groups[i];
-				grp._nextThing = Thing(dunDataStream->readUint16BE());
-				uint16 slotVal = dunDataStream->readUint16BE();
+				grp._nextThing = Thing(dunDataStream->readUint16());
+				uint16 slotVal = dunDataStream->readUint16();
 				grp._slot = (slotVal == 0) ? _vm->_thingNone : Thing(slotVal);
 				if (!file) {
 					grp._type = (CreatureType)dunDataStream->readByte();
 					grp._cells = dunDataStream->readByte();
 				} else {
-					grp._type = (CreatureType)dunDataStream->readUint16BE();
-					grp._cells = dunDataStream->readUint16BE();
+					grp._type = (CreatureType)dunDataStream->readUint16();
+					grp._cells = dunDataStream->readUint16();
 				}
-				grp._health[0] = dunDataStream->readUint16BE();
-				grp._health[1] = dunDataStream->readUint16BE();
-				grp._health[2] = dunDataStream->readUint16BE();
-				grp._health[3] = dunDataStream->readUint16BE();
-				grp._flags = dunDataStream->readUint16BE();
+				grp._health[0] = dunDataStream->readUint16();
+				grp._health[1] = dunDataStream->readUint16();
+				grp._health[2] = dunDataStream->readUint16();
+				grp._health[3] = dunDataStream->readUint16();
+				grp._flags = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeWeapon: {
 				Weapon &weap = _weapons[i];
-				weap._nextThing = Thing(dunDataStream->readUint16BE());
-				weap._desc = dunDataStream->readUint16BE();
+				weap._nextThing = Thing(dunDataStream->readUint16());
+				weap._desc = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeArmour: {
 				Armour &arm = _armours[i];
-				arm._nextThing = Thing(dunDataStream->readUint16BE());
-				arm._attributes = dunDataStream->readUint16BE();
+				arm._nextThing = Thing(dunDataStream->readUint16());
+				arm._attributes = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeScroll: {
 				Scroll &scr = _scrolls[i];
-				scr._nextThing = Thing(dunDataStream->readUint16BE());
-				scr._attributes = dunDataStream->readUint16BE();
+				scr._nextThing = Thing(dunDataStream->readUint16());
+				scr._attributes = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypePotion: {
 				Potion &pot = _potions[i];
-				pot._nextThing = Thing(dunDataStream->readUint16BE());
-				pot._attributes = dunDataStream->readUint16BE();
+				pot._nextThing = Thing(dunDataStream->readUint16());
+				pot._attributes = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeContainer: {
 				Container &cont = _containers[i];
-				cont._nextThing = Thing(dunDataStream->readUint16BE());
-				uint16 slotVal = dunDataStream->readUint16BE();
+				cont._nextThing = Thing(dunDataStream->readUint16());
+				uint16 slotVal = dunDataStream->readUint16();
 				cont._slot = (slotVal == 0) ? _vm->_thingNone : Thing(slotVal);
-				cont._type = dunDataStream->readUint16BE();
-				dunDataStream->readUint16BE(); // unused 4th word
+				cont._type = dunDataStream->readUint16();
+				dunDataStream->readUint16(); // unused 4th word
 				break;
 			}
 			case kDMThingTypeJunk: {
 				Junk &jnk = _junks[i];
-				jnk._nextThing = Thing(dunDataStream->readUint16BE());
-				jnk._attributes = dunDataStream->readUint16BE();
+				jnk._nextThing = Thing(dunDataStream->readUint16());
+				jnk._attributes = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeProjectile: {
 				Projectile &proj = _projectiles[i];
-				proj._nextThing = Thing(dunDataStream->readUint16BE());
-				uint16 slotVal = dunDataStream->readUint16BE();
+				proj._nextThing = Thing(dunDataStream->readUint16());
+				uint16 slotVal = dunDataStream->readUint16();
 				proj._slot = (slotVal == 0) ? _vm->_thingNone : Thing(slotVal);
 				if (!file) {
 					proj._kineticEnergy = dunDataStream->readByte();
 					proj._attack = dunDataStream->readByte();
 				} else {
-					proj._kineticEnergy = dunDataStream->readUint16BE();
-					proj._attack = dunDataStream->readUint16BE();
+					proj._kineticEnergy = dunDataStream->readUint16();
+					proj._attack = dunDataStream->readUint16();
 				}
-				proj._eventIndex = dunDataStream->readUint16BE();
+				proj._eventIndex = dunDataStream->readUint16();
 				break;
 			}
 			case kDMThingTypeExplosion: {
 				Explosion &expl = _explosions[i];
-				expl._nextThing = Thing(dunDataStream->readUint16BE());
-				expl._attributes = dunDataStream->readUint16BE();
+				expl._nextThing = Thing(dunDataStream->readUint16());
+				expl._attributes = dunDataStream->readUint16();
 				break;
 			}
 			}
@@ -933,10 +941,6 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
 			}
 		}
 	}
-
-	if (!file) { // this means that we created a new MemoryReadStream
-		delete dunDataStream;
-	} // the deletion of the function parameter 'file' happens elsewhere
 }
 
 void DungeonMan::setCurrentMap(uint16 mapIndex) {
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 58d4a6d7404..182ea6bb8ab 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -684,6 +684,10 @@ DisplayMan::~DisplayMan() {
 	delete _doorFrameD1C;
 }
 
+static uint16 readUint16(const byte *data, Common::Platform platform) {
+	return (platform == Common::kPlatformDOS) ? READ_LE_UINT16(data) : READ_BE_UINT16(data);
+}
+
 uint16 DisplayMan::getBitmapByteCount(uint16 pixelWidth, uint16 height) {
 	return pixelWidth / 2 * height;
 }
@@ -843,17 +847,30 @@ void DisplayMan::initializeGraphicData() {
 void DisplayMan::loadGraphics() {
 	Common::File f;
 	f.open("graphics.dat");
-	_grapItemCount = f.readUint16BE();
+
+	bool bigEndian = (_vm->getPlatform() != Common::kPlatformDOS);
+	Common::SeekableReadStreamEndianWrapper safeStream(&f, bigEndian, DisposeAfterUse::NO);
+
+	uint16 header = safeStream.readUint16();
+	uint32 tableStartOffset = 2;
+	uint32 bytesPerGraphic = 4;
+	if (header & 0x8000) { // graphics.dat v3.x
+		_grapItemCount = safeStream.readUint16();
+		tableStartOffset = 4;
+		bytesPerGraphic = 8;
+	} else {
+		_grapItemCount = header;
+	}
 
 	delete[] _bitmapCompressedByteCount;
 	_bitmapCompressedByteCount = new uint32[_grapItemCount];
 	for (uint16 i = 0; i < _grapItemCount; ++i)
-		_bitmapCompressedByteCount[i] = f.readUint16BE();
+		_bitmapCompressedByteCount[i] = safeStream.readUint16();
 
 	delete[] _bitmapDecompressedByteCount;
 	_bitmapDecompressedByteCount = new uint32[_grapItemCount];
 	for (uint16 i = 0; i < _grapItemCount; ++i)
-		_bitmapDecompressedByteCount[i] = f.readUint16BE();
+		_bitmapDecompressedByteCount[i] = safeStream.readUint16();
 
 	delete[] _packedItemPos;
 	_packedItemPos = new uint32[_grapItemCount + 1];
@@ -867,7 +884,7 @@ void DisplayMan::loadGraphics() {
 
 	LZWdecompressor lzw;
 	Common::Array<byte> tmpBuffer;
-	f.seek(2 + _grapItemCount * 4);
+	f.seek(tableStartOffset + _grapItemCount * bytesPerGraphic);
 	for (uint32 i = 0; i < _grapItemCount; ++i) {
 		byte *bitmap = _packedBitmaps + _packedItemPos[i];
 		f.read(bitmap, _bitmapCompressedByteCount[i]);
@@ -1008,8 +1025,8 @@ void DisplayMan::viewportBlitToScreen() {
 void DisplayMan::loadIntoBitmap(uint16 index, byte *destBitmap) {
 	uint8 *data = _packedBitmaps + _packedItemPos[index];
 
-	uint16 width = READ_BE_UINT16(data);
-	uint16 height = READ_BE_UINT16(data + 2);
+	uint16 width = readUint16(data, _vm->getPlatform());
+	uint16 height = readUint16(data + 2, _vm->getPlatform());
 	uint16 nextByteIndex = 4;
 
 	for (int32 k = 0; k < width * height;) {
@@ -1024,7 +1041,7 @@ void DisplayMan::loadIntoBitmap(uint16 index, byte *destBitmap) {
 			for (int j = 0; j < byte1 + 1; ++j)
 				destBitmap[k++] = nibble2;
 		} else if (nibble1 == 0xC) {
-			uint16 word1 = READ_BE_UINT16(data + nextByteIndex);
+			uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
 			nextByteIndex += 2;
 			for (int j = 0; j < word1 + 1; ++j)
 				destBitmap[k++] = nibble2;
@@ -1034,7 +1051,7 @@ for (int j = 0; j < byte1 + 1; ++j, ++k)
 				destBitmap[k] = destBitmap[k - width];
 			destBitmap[k++] = nibble2;
 		} else if (nibble1 == 0xF) {
-			uint16 word1 = READ_BE_UINT16(data + nextByteIndex);
+			uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
 			nextByteIndex += 2;
 			for (int j = 0; j < word1 + 1; ++j, ++k)
 				destBitmap[k] = destBitmap[k - width];
@@ -1225,12 +1242,12 @@ byte *DisplayMan::getCurrentVgaBuffer() {
 
 uint16 DisplayMan::getPixelWidth(uint16 index) {
 	byte *data = _packedBitmaps + _packedItemPos[index];
-	return READ_BE_UINT16(data);
+	return readUint16(data, _vm->getPlatform());
 }
 
 uint16 DisplayMan::getPixelHeight(uint16 index) {
 	uint8 *data = _packedBitmaps + _packedItemPos[index];
-	return READ_BE_UINT16(data + 2);
+	return readUint16(data + 2, _vm->getPlatform());
 }
 
 void DisplayMan::copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height) {


Commit: 0243fc9830b14dd6dbff9e1895917ae5d3e70651
    https://github.com/scummvm/scummvm/commit/0243fc9830b14dd6dbff9e1895917ae5d3e70651
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add DOS-specific palette index definitions to DisplayMan

Changed paths:
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index babc1470466..68493cc6201 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -697,6 +697,15 @@ public:
 	bool _paletteSwitchingEnabled; // @ G0322_B_PaletteSwitchingEnabled
 	bool _refreshDungeonViewPaleteRequested; // @ G0342_B_RefreshDungeonViewPaletteRequested
 	int16 _dungeonViewPaletteIndex; // @ G0304_i_DungeonViewPaletteIndex
+	int16 _creditsPaletteIndex = 6; // @ C06_CREDITS
+	int16 _entrancePaletteIndex = 7; // @ C07_ENTRANCE_DM
+	int16 _inventoryPaletteIndex = 8; // @ C08_INVENTORY
+	int16 _interfacePaletteIndex = 9; // @ C09_ICON
+	int16 _blackPaletteIndex = 10; // @ C10_ENTRANCE_BLACK
+	int16 _bluePaletteIndex = 11; // @ C11_BLUE
+	int16 _titlePresentsPaletteIndex = 12; // @ C12_PRESENTS
+	int16 _titleDungeonPaletteIndex = 13; // @ C13_DUNGEON
+	int16 _titleMasterPaletteIndex = 14; // @ C14_MASTER
 	uint16 _blankBuffer[32]; // @G0345_aui_BlankBuffer
 	uint16 _paletteTopAndBottomScreen[16]; // @ G0347_aui_Palette_TopAndBottomScreen
 	uint16 _paletteMiddleScreen[16]; // @ G0346_aui_Palette_MiddleScreen


Commit: a7eba4fbe291e44fb91d4157497e2d5ae4180b9f
    https://github.com/scummvm/scummvm/commit/a7eba4fbe291e44fb91d4157497e2d5ae4180b9f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Implement DOS VGA palette lookup tables and setMultipleColorsInPalette

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 182ea6bb8ab..f82c7fbaaae 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -150,6 +150,7 @@ DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) {
 
 	_paletteSwitchingEnabled = false;
 	_dungeonViewPaletteIndex = 0;
+	memset(_vgaPalette, 0, sizeof(_vgaPalette));
 
 	_stairsNativeBitmapIndexUpFrontD3L = 0;
 	_stairsNativeBitmapIndexUpFrontD3C = 0;
@@ -4061,4 +4062,478 @@ void DisplayMan::buildPaletteChangeCopperList(uint16 *middleScreen, uint16 *topA
 	g_system->getPaletteManager()->setPalette(colorPalette, 0, 32);
 }
 
+static const ColorDef G8147_CREDITS[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x00, 0x2D, 0x2D },
+	{ 0x02, 0x3F, 0x3F, 0x1B },
+	{ 0x03, 0x24, 0x12, 0x00 },
+	{ 0x04, 0x3F, 0x3F, 0x24 },
+	{ 0x05, 0x00, 0x00, 0x00 },
+	{ 0x06, 0x00, 0x24, 0x00 },
+	{ 0x07, 0x2D, 0x00, 0x00 },
+	{ 0x08, 0x36, 0x24, 0x12 },
+	{ 0x09, 0x3F, 0x3F, 0x2D },
+	{ 0x0A, 0x3F, 0x24, 0x12 },
+	{ 0x0B, 0x3F, 0x36, 0x00 },
+	{ 0x0C, 0x3F, 0x2D, 0x00 },
+	{ 0x0D, 0x00, 0x00, 0x00 },
+	{ 0x0E, 0x1B, 0x09, 0x00 },
+	{ 0x0F, 0x3F, 0x3F, 0x36 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8148_ENTRANCE[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x1B, 0x1B, 0x1B },
+	{ 0x02, 0x24, 0x24, 0x24 },
+	{ 0x03, 0x24, 0x12, 0x00 },
+	{ 0x04, 0x36, 0x2D, 0x24 },
+	{ 0x05, 0x00, 0x36, 0x00 },
+	{ 0x06, 0x00, 0x24, 0x00 },
+	{ 0x07, 0x00, 0x2D, 0x00 },
+	{ 0x08, 0x24, 0x1B, 0x12 },
+	{ 0x09, 0x3F, 0x00, 0x00 },
+	{ 0x0A, 0x2D, 0x24, 0x1B },
+	{ 0x0B, 0x1B, 0x12, 0x09 },
+	{ 0x0C, 0x12, 0x12, 0x12 },
+	{ 0x0D, 0x2D, 0x2D, 0x2D },
+	{ 0x0E, 0x1B, 0x09, 0x00 },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8149_ICON[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x1B, 0x1B, 0x1B },
+	{ 0x02, 0x24, 0x24, 0x24 },
+	{ 0x03, 0x1B, 0x09, 0x00 },
+	{ 0x04, 0x00, 0x36, 0x36 },
+	{ 0x05, 0x24, 0x12, 0x00 },
+	{ 0x06, 0x00, 0x24, 0x00 },
+	{ 0x07, 0x00, 0x36, 0x00 },
+	{ 0x08, 0x3F, 0x00, 0x00 },
+	{ 0x09, 0x3F, 0x2D, 0x00 },
+	{ 0x0A, 0x36, 0x24, 0x1B },
+	{ 0x0B, 0x3F, 0x3F, 0x00 },
+	{ 0x0C, 0x12, 0x12, 0x12 },
+	{ 0x0D, 0x2D, 0x2D, 0x2D },
+	{ 0x0E, 0x00, 0x00, 0x3F },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8150_INVENTORY[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x1B, 0x1B, 0x1B },
+	{ 0x12, 0x24, 0x24, 0x24 },
+	{ 0x13, 0x1B, 0x09, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x24, 0x12, 0x00 },
+	{ 0x16, 0x00, 0x24, 0x00 },
+	{ 0x17, 0x00, 0x36, 0x00 },
+	{ 0x18, 0x3F, 0x00, 0x00 },
+	{ 0x19, 0x3F, 0x2D, 0x00 },
+	{ 0x1A, 0x36, 0x24, 0x1B },
+	{ 0x1B, 0x3F, 0x3F, 0x00 },
+	{ 0x1C, 0x12, 0x12, 0x12 },
+	{ 0x1D, 0x2D, 0x2D, 0x2D },
+	{ 0x1E, 0x00, 0x00, 0x3F },
+	{ 0x1F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8151_LIGHT0[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x1B, 0x1B, 0x1B },
+	{ 0x12, 0x24, 0x24, 0x24 },
+	{ 0x13, 0x1B, 0x09, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x24, 0x12, 0x00 },
+	{ 0x16, 0x00, 0x24, 0x00 },
+	{ 0x17, 0x00, 0x36, 0x00 },
+	{ 0x18, 0x3F, 0x00, 0x00 },
+	{ 0x19, 0x3F, 0x2D, 0x00 },
+	{ 0x1A, 0x36, 0x24, 0x1B },
+	{ 0x1B, 0x3F, 0x3F, 0x00 },
+	{ 0x1C, 0x12, 0x12, 0x12 },
+	{ 0x1D, 0x2D, 0x2D, 0x2D },
+	{ 0x1E, 0x00, 0x00, 0x3F },
+	{ 0x1F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8152_LIGHT1[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x12, 0x12, 0x12 },
+	{ 0x12, 0x1B, 0x1B, 0x1B },
+	{ 0x13, 0x1B, 0x09, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x24, 0x09, 0x00 },
+	{ 0x16, 0x00, 0x1B, 0x00 },
+	{ 0x17, 0x00, 0x2D, 0x00 },
+	{ 0x18, 0x36, 0x00, 0x00 },
+	{ 0x19, 0x36, 0x24, 0x00 },
+	{ 0x1A, 0x2D, 0x1B, 0x12 },
+	{ 0x1B, 0x3F, 0x36, 0x00 },
+	{ 0x1C, 0x09, 0x09, 0x09 },
+	{ 0x1D, 0x24, 0x24, 0x24 },
+	{ 0x1E, 0x00, 0x00, 0x36 },
+	{ 0x1F, 0x36, 0x36, 0x36 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8153_LIGHT2[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x09, 0x09, 0x09 },
+	{ 0x12, 0x12, 0x12, 0x12 },
+	{ 0x13, 0x12, 0x09, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x1B, 0x09, 0x00 },
+	{ 0x16, 0x00, 0x12, 0x00 },
+	{ 0x17, 0x00, 0x24, 0x00 },
+	{ 0x18, 0x2D, 0x00, 0x00 },
+	{ 0x19, 0x2D, 0x1B, 0x00 },
+	{ 0x1A, 0x24, 0x12, 0x09 },
+	{ 0x1B, 0x3F, 0x2D, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x1B, 0x1B, 0x1B },
+	{ 0x1E, 0x00, 0x00, 0x2D },
+	{ 0x1F, 0x2D, 0x2D, 0x2D },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8154_LIGHT3[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x00, 0x00, 0x00 },
+	{ 0x12, 0x09, 0x09, 0x09 },
+	{ 0x13, 0x09, 0x00, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x12, 0x09, 0x00 },
+	{ 0x16, 0x00, 0x09, 0x00 },
+	{ 0x18, 0x00, 0x1B, 0x00 },
+	{ 0x18, 0x24, 0x00, 0x00 },
+	{ 0x19, 0x24, 0x12, 0x00 },
+	{ 0x1A, 0x1B, 0x09, 0x00 },
+	{ 0x1B, 0x36, 0x24, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x12, 0x12, 0x12 },
+	{ 0x1E, 0x00, 0x00, 0x24 },
+	{ 0x1F, 0x24, 0x24, 0x24 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8155_LIGHT4[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x00, 0x00, 0x00 },
+	{ 0x12, 0x00, 0x00, 0x00 },
+	{ 0x13, 0x00, 0x00, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x09, 0x00, 0x00 },
+	{ 0x16, 0x00, 0x00, 0x00 },
+	{ 0x17, 0x00, 0x12, 0x00 },
+	{ 0x18, 0x1B, 0x00, 0x00 },
+	{ 0x19, 0x1B, 0x09, 0x00 },
+	{ 0x1A, 0x12, 0x00, 0x00 },
+	{ 0x1B, 0x2D, 0x1B, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x09, 0x09, 0x09 },
+	{ 0x1E, 0x00, 0x00, 0x1B },
+	{ 0x1F, 0x1B, 0x1B, 0x1B },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8156_LIGHT5[17] = {
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x00, 0x00, 0x00 },
+	{ 0x12, 0x00, 0x00, 0x00 },
+	{ 0x13, 0x00, 0x00, 0x00 },
+	{ 0x14, 0x00, 0x36, 0x36 },
+	{ 0x15, 0x00, 0x00, 0x00 },
+	{ 0x16, 0x00, 0x00, 0x00 },
+	{ 0x17, 0x00, 0x09, 0x00 },
+	{ 0x18, 0x12, 0x00, 0x00 },
+	{ 0x19, 0x12, 0x00, 0x00 },
+	{ 0x1A, 0x09, 0x00, 0x00 },
+	{ 0x1B, 0x1B, 0x12, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x00, 0x00, 0x00 },
+	{ 0x1E, 0x00, 0x00, 0x12 },
+	{ 0x1F, 0x12, 0x12, 0x12 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8157_BLACK[33] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x00, 0x00, 0x00 },
+	{ 0x02, 0x00, 0x00, 0x00 },
+	{ 0x03, 0x00, 0x00, 0x00 },
+	{ 0x04, 0x00, 0x00, 0x00 },
+	{ 0x05, 0x00, 0x00, 0x00 },
+	{ 0x06, 0x00, 0x00, 0x00 },
+	{ 0x07, 0x00, 0x00, 0x00 },
+	{ 0x08, 0x00, 0x00, 0x00 },
+	{ 0x09, 0x00, 0x00, 0x00 },
+	{ 0x0A, 0x00, 0x00, 0x00 },
+	{ 0x0B, 0x00, 0x00, 0x00 },
+	{ 0x0C, 0x00, 0x00, 0x00 },
+	{ 0x0D, 0x00, 0x00, 0x00 },
+	{ 0x0E, 0x00, 0x00, 0x00 },
+	{ 0x0F, 0x00, 0x00, 0x00 },
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x00, 0x00, 0x00 },
+	{ 0x12, 0x00, 0x00, 0x00 },
+	{ 0x13, 0x00, 0x00, 0x00 },
+	{ 0x14, 0x00, 0x00, 0x00 },
+	{ 0x15, 0x00, 0x00, 0x00 },
+	{ 0x16, 0x00, 0x00, 0x00 },
+	{ 0x17, 0x00, 0x00, 0x00 },
+	{ 0x18, 0x00, 0x00, 0x00 },
+	{ 0x19, 0x00, 0x00, 0x00 },
+	{ 0x1A, 0x00, 0x00, 0x00 },
+	{ 0x1B, 0x00, 0x00, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x00, 0x00, 0x00 },
+	{ 0x1E, 0x00, 0x00, 0x00 },
+	{ 0x1F, 0x00, 0x00, 0x00 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8158_BLUE[33] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x00, 0x00, 0x00 },
+	{ 0x02, 0x00, 0x00, 0x00 },
+	{ 0x03, 0x00, 0x00, 0x00 },
+	{ 0x04, 0x00, 0x00, 0x00 },
+	{ 0x05, 0x00, 0x00, 0x00 },
+	{ 0x06, 0x00, 0x00, 0x00 },
+	{ 0x07, 0x00, 0x00, 0x00 },
+	{ 0x08, 0x00, 0x00, 0x00 },
+	{ 0x09, 0x00, 0x00, 0x00 },
+	{ 0x0A, 0x00, 0x00, 0x00 },
+	{ 0x0B, 0x00, 0x00, 0x00 },
+	{ 0x0C, 0x00, 0x00, 0x00 },
+	{ 0x0D, 0x00, 0x00, 0x00 },
+	{ 0x0E, 0x00, 0x00, 0x00 },
+	{ 0x0F, 0x00, 0x00, 0x00 },
+	{ 0x10, 0x00, 0x00, 0x00 },
+	{ 0x11, 0x00, 0x00, 0x00 },
+	{ 0x12, 0x00, 0x00, 0x00 },
+	{ 0x13, 0x00, 0x00, 0x00 },
+	{ 0x14, 0x00, 0x00, 0x00 },
+	{ 0x15, 0x00, 0x00, 0x00 },
+	{ 0x16, 0x00, 0x00, 0x00 },
+	{ 0x17, 0x00, 0x00, 0x00 },
+	{ 0x18, 0x00, 0x00, 0x00 },
+	{ 0x19, 0x00, 0x00, 0x00 },
+	{ 0x1A, 0x00, 0x00, 0x00 },
+	{ 0x1B, 0x00, 0x00, 0x00 },
+	{ 0x1C, 0x00, 0x00, 0x00 },
+	{ 0x1D, 0x00, 0x00, 0x00 },
+	{ 0x1E, 0x00, 0x00, 0x00 },
+	{ 0x1F, 0x00, 0x00, 0x00 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8159_PRESENTS[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x00, 0x00, 0x00 },
+	{ 0x02, 0x00, 0x00, 0x00 },
+	{ 0x03, 0x00, 0x00, 0x00 },
+	{ 0x04, 0x00, 0x00, 0x00 },
+	{ 0x05, 0x00, 0x00, 0x00 },
+	{ 0x06, 0x00, 0x00, 0x00 },
+	{ 0x07, 0x00, 0x00, 0x00 },
+	{ 0x08, 0x00, 0x00, 0x00 },
+	{ 0x09, 0x00, 0x00, 0x00 },
+	{ 0x0A, 0x00, 0x00, 0x00 },
+	{ 0x0B, 0x00, 0x00, 0x00 },
+	{ 0x0C, 0x00, 0x00, 0x00 },
+	{ 0x0D, 0x00, 0x00, 0x00 },
+	{ 0x0E, 0x00, 0x00, 0x00 },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8160_DUNGEON[10] = {
+	{ 0x03, 0x2F, 0x27, 0x0F },
+	{ 0x04, 0x27, 0x17, 0x0F },
+	{ 0x05, 0x37, 0x2F, 0x0F },
+	{ 0x06, 0x2F, 0x17, 0x0F },
+	{ 0x07, 0x37, 0x37, 0x17 },
+	{ 0x08, 0x3F, 0x3F, 0x0F },
+	{ 0x0B, 0x1F, 0x0F, 0x07 },
+	{ 0x0C, 0x3F, 0x00, 0x00 },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8161_MASTER[2] = {
+	{ 0x0C, 0x3F, 0x00, 0x00 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8162_SWOOSH1[2] = {
+	{ 0x01, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8163_SWOOSH2[2] = {
+	{ 0x02, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8164_SWOOSH3[2] = {
+	{ 0x03, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8165_SWOOSH4[2] = {
+	{ 0x04, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8166_SWOOSH5[2] = {
+	{ 0x05, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8167_SWOOSH6[2] = {
+	{ 0x06, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8168_SWOOSH7[2] = {
+	{ 0x07, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8169_SWOOSH8[5] = {
+	{ 0x08, 0x3F, 0x3F, 0x3F },
+	{ 0x09, 0x3F, 0x3F, 0x3F },
+	{ 0x0A, 0x2F, 0x2F, 0x2F },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8170_SWOOSH9[5] = {
+	{ 0x08, 0x00, 0x00, 0x00 },
+	{ 0x0B, 0x3F, 0x3F, 0x3F },
+	{ 0x0C, 0x2F, 0x2F, 0x2F },
+	{ 0x0D, 0x1F, 0x1F, 0x1F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8171_SWOOSH10[3] = {
+	{ 0x0E, 0x3F, 0x3F, 0x00 },
+	{ 0x0F, 0x3F, 0x3F, 0x00 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8172_[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x00, 0x00, 0x14 },
+	{ 0x02, 0x00, 0x00, 0x1C },
+	{ 0x03, 0x00, 0x00, 0x24 },
+	{ 0x04, 0x00, 0x00, 0x34 },
+	{ 0x05, 0x00, 0x18, 0x2C },
+	{ 0x06, 0x00, 0x24, 0x28 },
+	{ 0x07, 0x1C, 0x14, 0x0C },
+	{ 0x08, 0x3F, 0x3F, 0x00 },
+	{ 0x09, 0x14, 0x14, 0x14 },
+	{ 0x0A, 0x20, 0x20, 0x20 },
+	{ 0x0B, 0x28, 0x28, 0x28 },
+	{ 0x0C, 0x28, 0x1C, 0x14 },
+	{ 0x0D, 0x3F, 0x00, 0x00 },
+	{ 0x0E, 0x28, 0x08, 0x08 },
+	{ 0x0F, 0x3F, 0x30, 0x28 },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8173_[17] = {
+	{ 0x00, 0x03, 0x03, 0x03 },
+	{ 0x01, 0x33, 0x1B, 0x0B },
+	{ 0x02, 0x1F, 0x13, 0x07 },
+	{ 0x03, 0x2B, 0x17, 0x0B },
+	{ 0x04, 0x3F, 0x03, 0x03 },
+	{ 0x05, 0x2F, 0x03, 0x03 },
+	{ 0x06, 0x03, 0x03, 0x2F },
+	{ 0x07, 0x03, 0x03, 0x3F },
+	{ 0x08, 0x17, 0x17, 0x17 },
+	{ 0x09, 0x1F, 0x1F, 0x1F },
+	{ 0x0A, 0x2F, 0x2F, 0x2F },
+	{ 0x0B, 0x37, 0x37, 0x37 },
+	{ 0x0C, 0x23, 0x1B, 0x13 },
+	{ 0x0D, 0x27, 0x23, 0x17 },
+	{ 0x0E, 0x33, 0x27, 0x1B },
+	{ 0x0F, 0x3B, 0x2B, 0x1F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef G8174_[17] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x01, 0x1B, 0x1B, 0x1B },
+	{ 0x02, 0x23, 0x23, 0x23 },
+	{ 0x03, 0x23, 0x13, 0x03 },
+	{ 0x04, 0x33, 0x2B, 0x23 },
+	{ 0x05, 0x13, 0x0B, 0x0B },
+	{ 0x06, 0x03, 0x23, 0x03 },
+	{ 0x07, 0x03, 0x2B, 0x03 },
+	{ 0x08, 0x23, 0x1B, 0x13 },
+	{ 0x09, 0x3F, 0x03, 0x03 },
+	{ 0x0A, 0x2B, 0x23, 0x1B },
+	{ 0x0B, 0x1B, 0x13, 0x0B },
+	{ 0x0C, 0x13, 0x13, 0x13 },
+	{ 0x0D, 0x2B, 0x2B, 0x2B },
+	{ 0x0E, 0x1B, 0x0B, 0x03 },
+	{ 0x0F, 0x3F, 0x3F, 0x3F },
+	{ 0xFF, 0x00, 0x00, 0x00 }
+};
+
+static const ColorDef *const g_vgaPaletteTable[29] = { // @ G8176_PaletteTable
+	G8151_LIGHT0,           /* C00_LIGHT0 */
+	G8152_LIGHT1,           /* C01_LIGHT1 */
+	G8153_LIGHT2,           /* C02_LIGHT2 */
+	G8154_LIGHT3,           /* C03_LIGHT3 */
+	G8155_LIGHT4,           /* C04_LIGHT4 */
+	G8156_LIGHT5,           /* C05_LIGHT5 */
+	G8147_CREDITS,          /* C06_CREDITS */
+	G8148_ENTRANCE,         /* C07_ENTRANCE_DM */
+	G8150_INVENTORY,        /* C08_INVENTORY */
+	G8149_ICON,             /* C09_ICON */
+	G8157_BLACK,            /* C10_ENTRANCE_BLACK */
+	G8158_BLUE,             /* C11_BLUE */
+	G8159_PRESENTS,         /* C12_PRESENTS */
+	G8160_DUNGEON,          /* C13_DUNGEON */
+	G8161_MASTER,           /* C14_MASTER */
+	G8157_BLACK,            /* C15_SWOOSH_BLACK */
+	G8162_SWOOSH1,          /* C16_SWOOSH1 */
+	G8163_SWOOSH2,          /* C17_SWOOSH2 */
+	G8164_SWOOSH3,          /* C18_SWOOSH3 */
+	G8165_SWOOSH4,          /* C19_SWOOSH4 */
+	G8166_SWOOSH5,          /* C20_SWOOSH5 */
+	G8167_SWOOSH6,          /* C21_SWOOSH6 */
+	G8168_SWOOSH7,          /* C22_SWOOSH7 */
+	G8169_SWOOSH8,          /* C23_SWOOSH8 */
+	G8170_SWOOSH9,          /* C24_SWOOSH9 */
+	G8171_SWOOSH10,         /* C25_SWOOSH10 */
+	G8172_,                 /* 26 */
+	G8173_,                 /* 27 */
+	G8174_                  /* 28 */
+};
+
+void DisplayMan::setMultipleColorsInPalette(int16 paletteIndex) {
+	assert(paletteIndex >= 0 && paletteIndex < 29);
+	const ColorDef *colorDef = g_vgaPaletteTable[paletteIndex];
+	int8 colorIndex;
+	while ((colorIndex = (int8)colorDef->index) >= 0) {
+		if (colorIndex < 32) {
+			_vgaPalette[colorIndex * 3] = (colorDef->r << 2) | (colorDef->r >> 4);
+			_vgaPalette[colorIndex * 3 + 1] = (colorDef->g << 2) | (colorDef->g >> 4);
+			_vgaPalette[colorIndex * 3 + 2] = (colorDef->b << 2) | (colorDef->b >> 4);
+		}
+		colorDef++;
+	}
+	g_system->getPaletteManager()->setPalette(_vgaPalette, 0, 32);
+}
+
 }
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 68493cc6201..7f32b81d97f 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -565,6 +565,11 @@ public:
 #define D11_MASK_GREEN_COMPONENT 0x00F0
 #define D12_MASK_BLUE_COMPONENT 0x000F
 
+struct ColorDef { // @ COLOR_DEF
+	uint8 index;
+	uint8 r, g, b;
+};
+
 class DisplayMan {
 	friend class DM::TextMan;
 
@@ -707,6 +712,7 @@ public:
 	int16 _titleDungeonPaletteIndex = 13; // @ C13_DUNGEON
 	int16 _titleMasterPaletteIndex = 14; // @ C14_MASTER
 	uint16 _blankBuffer[32]; // @G0345_aui_BlankBuffer
+	byte _vgaPalette[32 * 3]; // @ G8183_aac_FullPalette
 	uint16 _paletteTopAndBottomScreen[16]; // @ G0347_aui_Palette_TopAndBottomScreen
 	uint16 _paletteMiddleScreen[16]; // @ G0346_aui_Palette_MiddleScreen
 
@@ -834,6 +840,7 @@ public:
 	uint16 getDarkenedColor(uint16 RGBcolor);
 	void startEndFadeToPalette(uint16 *P0849_pui_Palette); // @ F0436_STARTEND_FadeToPalette
 	void buildPaletteChangeCopperList(uint16 *middleScreen, uint16 *topAndBottom); // @ F0508_AMIGA_BuildPaletteChangeCopperList
+	void setMultipleColorsInPalette(int16 paletteIndex); // @ F8157_VIDRV_08_SetMultipleColorsInPalette
 	void shadeScreenBox(Box *box, Color color); // @ F0136_VIDEO_ShadeScreenBox
 
 private:


Commit: 1b900f2fbc28a07adc399dc38feae315f2d298b6
    https://github.com/scummvm/scummvm/commit/1b900f2fbc28a07adc399dc38feae315f2d298b6
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Implement DOS viewport palette switching and light-level scaling

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index f82c7fbaaae..b1d5e94da0e 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1208,6 +1208,34 @@ void DisplayMan::updateScreen() {
 }
 
 void DisplayMan::drawViewport(int16 palSwitchingRequestedState) {
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		if (palSwitchingRequestedState == k2_viewportAsBeforeSleepOrFreezeGame)
+			palSwitchingRequestedState = (_lastVgaViewportPaletteIndex != -1) ? 1 : 0;
+
+		switch (palSwitchingRequestedState) {
+		case 1:
+			if (_dungeonViewPaletteIndex != _lastVgaViewportPaletteIndex) {
+				setMultipleColorsInPalette(_dungeonViewPaletteIndex);
+				_lastVgaViewportPaletteIndex = _dungeonViewPaletteIndex;
+			}
+			break;
+		case 0:
+			if (_vm->_dungeonMan->_partyMapIndex != kDMMapIndexEntrance)
+				setMultipleColorsInPalette(_inventoryPaletteIndex);
+			else
+				setMultipleColorsInPalette(0); // C00_LIGHT0
+
+			_lastVgaViewportPaletteIndex = -1;
+			break;
+		default:
+			break;
+		}
+		_paletteSwitchingEnabled = (palSwitchingRequestedState == 1);
+		viewportBlitToScreen();
+		updateScreen();
+		return;
+	}
+
 	static uint16 *dungeonViewCurrentPalette; // @ K0010_pui_DungeonViewCurrentPalette
 
 	// ignored code F0510_AMIGA_WaitBottomOfViewPort
@@ -2741,6 +2769,9 @@ void DisplayMan::applyCreatureReplColors(int replacedColor, int replacementColor
 
 	_palChangesCreatureD2[replacedColor] = creatureReplColorSets[replacementColor]._d2ReplacementColor;
 	_palChangesCreatureD3[replacedColor] = creatureReplColorSets[replacementColor]._d3ReplacementColor;
+
+	if (_vm->getPlatform() == Common::kPlatformDOS)
+		_lastVgaViewportPaletteIndex = -1;
 }
 
 void DisplayMan::drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &f) {
@@ -4523,15 +4554,30 @@ static const ColorDef *const g_vgaPaletteTable[29] = { // @ G8176_PaletteTable
 
 void DisplayMan::setMultipleColorsInPalette(int16 paletteIndex) {
 	assert(paletteIndex >= 0 && paletteIndex < 29);
-	const ColorDef *colorDef = g_vgaPaletteTable[paletteIndex];
-	int8 colorIndex;
-	while ((colorIndex = (int8)colorDef->index) >= 0) {
-		if (colorIndex < 32) {
-			_vgaPalette[colorIndex * 3] = (colorDef->r << 2) | (colorDef->r >> 4);
-			_vgaPalette[colorIndex * 3 + 1] = (colorDef->g << 2) | (colorDef->g >> 4);
-			_vgaPalette[colorIndex * 3 + 2] = (colorDef->b << 2) | (colorDef->b >> 4);
+	if (paletteIndex < 6) {
+		/* Read light levels directly from _palDungeonView, which already
+		contains runtime-applied creature replacements. Bypasses the need
+		for DOS version's G8175_CREAT_PAL lookup table. */
+		for (int i = 0; i < 16; ++i) {
+			uint16 color = _palDungeonView[paletteIndex][i];
+			uint8 r = (color >> 8) & 0xF;
+			uint8 g = (color >> 4) & 0xF;
+			uint8 b = color & 0xF;
+			_vgaPalette[(16 + i) * 3]     = (r << 4) | r;
+			_vgaPalette[(16 + i) * 3 + 1] = (g << 4) | g;
+			_vgaPalette[(16 + i) * 3 + 2] = (b << 4) | b;
+		}
+	} else {
+		const ColorDef *colorDef = g_vgaPaletteTable[paletteIndex];
+		int8 colorIndex;
+		while ((colorIndex = (int8)colorDef->index) >= 0) {
+			if (colorIndex < 32) {
+				_vgaPalette[colorIndex * 3]     = (colorDef->r << 2) | (colorDef->r >> 4);
+				_vgaPalette[colorIndex * 3 + 1] = (colorDef->g << 2) | (colorDef->g >> 4);
+				_vgaPalette[colorIndex * 3 + 2] = (colorDef->b << 2) | (colorDef->b >> 4);
+			}
+			colorDef++;
 		}
-		colorDef++;
 	}
 	g_system->getPaletteManager()->setPalette(_vgaPalette, 0, 32);
 }
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 7f32b81d97f..ec89ddfffef 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -702,6 +702,7 @@ public:
 	bool _paletteSwitchingEnabled; // @ G0322_B_PaletteSwitchingEnabled
 	bool _refreshDungeonViewPaleteRequested; // @ G0342_B_RefreshDungeonViewPaletteRequested
 	int16 _dungeonViewPaletteIndex; // @ G0304_i_DungeonViewPaletteIndex
+	int16 _lastVgaViewportPaletteIndex = -1; // @ G2123_
 	int16 _creditsPaletteIndex = 6; // @ C06_CREDITS
 	int16 _entrancePaletteIndex = 7; // @ C07_ENTRANCE_DM
 	int16 _inventoryPaletteIndex = 8; // @ C08_INVENTORY


Commit: 4a31e5e7d6d36dd24d389e59e8f98a5f50cebee7
    https://github.com/scummvm/scummvm/commit/4a31e5e7d6d36dd24d389e59e8f98a5f50cebee7
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Implement DOS palette transitions in startEndFadeToPalette

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index b1d5e94da0e..debb374591a 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -4023,8 +4023,64 @@ uint16 DisplayMan::getDarkenedColor(uint16 RGBcolor) {
 }
 
 void DisplayMan::startEndFadeToPalette(uint16 *P0849_pui_Palette) {
-	uint16 *paletteRegister = _paletteFadeTemporary;
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		int16 targetPaletteIndex = -1;
+
+		if (P0849_pui_Palette == _blankBuffer) {
+			targetPaletteIndex = _blackPaletteIndex;
+		} else if (P0849_pui_Palette == _palCredits) {
+			targetPaletteIndex = _creditsPaletteIndex;
+		} else if (P0849_pui_Palette == _paletteTopAndBottomScreen || P0849_pui_Palette == _paletteMiddleScreen) {
+			targetPaletteIndex = 0; // C00_LIGHT0
+		} else {
+			bool isEntrance = true;
+			static const uint16 palEntrance[16] = {0x000, 0x666, 0x888, 0x840, 0xCA8, 0x0C0, 0x080, 0x0A0, 0x864, 0xF00, 0xA86, 0x642, 0x444, 0xAAA, 0x620, 0xFFF}; // @ G0020_aui_Graphic562_Palette_Entrance
+			for (int i = 0; i < 16; ++i) {
+				if (P0849_pui_Palette[i] != palEntrance[i]) {
+					isEntrance = false;
+					break;
+				}
+			}
+			if (isEntrance) {
+				targetPaletteIndex = _entrancePaletteIndex;
+			} else {
+				bool isDungeonView = false;
+				for (int idx = 0; idx < 6; ++idx) {
+					if (P0849_pui_Palette == _palDungeonView[idx]) {
+						targetPaletteIndex = idx;
+						isDungeonView = true;
+						break;
+					}
+				}
+				if (!isDungeonView) {
+					uint16 col1 = P0849_pui_Palette[1];
+					uint16 col4 = P0849_pui_Palette[4];
+					uint16 col8 = P0849_pui_Palette[8];
+					uint16 col12 = P0849_pui_Palette[12];
+					uint16 col15 = P0849_pui_Palette[15];
+
+					if (col15 == 0x0004)
+						targetPaletteIndex = _bluePaletteIndex;
+					else if (col15 == 0x0FFF && col1 == 0x0004)
+						targetPaletteIndex = _titlePresentsPaletteIndex;
+					else if (col8 == 0x0FF4)
+						targetPaletteIndex = _titleDungeonPaletteIndex;
+					else if (col12 == 0x0F00)
+						targetPaletteIndex = _titleMasterPaletteIndex;
+					else if (col1 == 0x086F && col4 == 0x0FFF)
+						targetPaletteIndex = _interfacePaletteIndex;
+					else
+						targetPaletteIndex = _blackPaletteIndex;
+				}
+			}
+		}
 
+		if (targetPaletteIndex != -1)
+			setMultipleColorsInPalette(targetPaletteIndex);
+		return;
+	}
+
+	uint16 *paletteRegister = _paletteFadeTemporary;
 	for (int16 i = 0; i < 16; i++)
 		paletteRegister[i] = _paletteFadeFrom[i];
 


Commit: 26821ac37ba73352d9f93d17ebd26be851809889
    https://github.com/scummvm/scummvm/commit/26821ac37ba73352d9f93d17ebd26be851809889
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add support for DOS wall and floor set graphics mapping

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index debb374591a..73019e62c6c 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -706,23 +706,43 @@ void DisplayMan::setUpScreens(uint16 width, uint16 height) {
 
 
 void DisplayMan::initializeGraphicData() {
-	_bitmapCeiling = new byte[224 * 29];
-	_bitmapFloor = new byte[224 * 70];
-	_bitmapWallSetD3L2 = new byte[16 * 49];
-	_bitmapWallSetD3R2 = new byte[16 * 49];
-	_bitmapWallSetD3LCR = new byte[128 * 51];
-	_bitmapWallSetD2LCR = new byte[144 * 71];
-	_bitmapWallSetD1LCR = new byte[256 * 111];
-	_bitmapWallSetWallD0L = new byte[32 * 136];
-	_bitmapWallSetWallD0R = new byte[32 * 136];
-	_bitmapWallSetDoorFrameTopD2LCR = new byte[96 * 3];
-	_bitmapWallSetDoorFrameTopD1LCR = new byte[128 * 4];
-	_bitmapWallSetDoorFrameLeftD3L = new byte[32 * 44];
-	_bitmapWallSetDoorFrameLeftD3C = new byte[32 * 44];
-	_bitmapWallSetDoorFrameLeftD2C = new byte[48 * 65];
-	_bitmapWallSetDoorFrameLeftD1C = new byte[32 * 94];
-	_bitmapWallSetDoorFrameRightD1C = new byte[32 * 94]();
-	_bitmapWallSetDoorFrameFront = new byte[32 * 123];
+	int16 firstFloorSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k78_FirstFloorSetDOS : k75_FirstFloorSet;
+	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
+
+	// Floor set mapping
+	_bitmapFloor = new byte[getPixelWidth(firstFloorSet) * getPixelHeight(firstFloorSet)];
+	_bitmapCeiling = new byte[getPixelWidth(firstFloorSet + 1) * getPixelHeight(firstFloorSet + 1)];
+
+	// Wall set mapping
+	int16 doorFrameFrontIdx = firstWallSet + 0;
+	int16 doorFrameLeftD1CIdx = firstWallSet + 1;
+	int16 doorFrameLeftD2CIdx = firstWallSet + 2;
+	int16 doorFrameLeftD3CIdx = firstWallSet + 3;
+	int16 doorFrameLeftD3LIdx = firstWallSet + 4;
+	int16 doorFrameTopD1LCRIdx = firstWallSet + 5;
+	int16 doorFrameTopD2LCRIdx = firstWallSet + 6;
+	int16 wallD0RIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 7) : (firstWallSet + 7);
+	int16 wallD0LIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 8) : (firstWallSet + 8);
+	int16 d1LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 11) : (firstWallSet + 9);
+	int16 d2LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 16) : (firstWallSet + 10);
+	int16 d3LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 21) : (firstWallSet + 11);
+	int16 d3L2Idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 18) : (firstWallSet + 12);
+
+	_bitmapWallSetD3L2 = new byte[getPixelWidth(d3L2Idx) * getPixelHeight(d3L2Idx)];
+	_bitmapWallSetD3R2 = new byte[getPixelWidth(d3L2Idx) * getPixelHeight(d3L2Idx)]; // Flipped copy of D3L2
+	_bitmapWallSetD3LCR = new byte[getPixelWidth(d3LcrIdx) * getPixelHeight(d3LcrIdx)];
+	_bitmapWallSetD2LCR = new byte[getPixelWidth(d2LcrIdx) * getPixelHeight(d2LcrIdx)];
+	_bitmapWallSetD1LCR = new byte[getPixelWidth(d1LcrIdx) * getPixelHeight(d1LcrIdx)];
+	_bitmapWallSetWallD0L = new byte[getPixelWidth(wallD0LIdx) * getPixelHeight(wallD0LIdx)];
+	_bitmapWallSetWallD0R = new byte[getPixelWidth(wallD0RIdx) * getPixelHeight(wallD0RIdx)];
+	_bitmapWallSetDoorFrameTopD2LCR = new byte[getPixelWidth(doorFrameTopD2LCRIdx) * getPixelHeight(doorFrameTopD2LCRIdx)];
+	_bitmapWallSetDoorFrameTopD1LCR = new byte[getPixelWidth(doorFrameTopD1LCRIdx) * getPixelHeight(doorFrameTopD1LCRIdx)];
+	_bitmapWallSetDoorFrameLeftD3L = new byte[getPixelWidth(doorFrameLeftD3LIdx) * getPixelHeight(doorFrameLeftD3LIdx)];
+	_bitmapWallSetDoorFrameLeftD3C = new byte[getPixelWidth(doorFrameLeftD3CIdx) * getPixelHeight(doorFrameLeftD3CIdx)];
+	_bitmapWallSetDoorFrameLeftD2C = new byte[getPixelWidth(doorFrameLeftD2CIdx) * getPixelHeight(doorFrameLeftD2CIdx)];
+	_bitmapWallSetDoorFrameLeftD1C = new byte[getPixelWidth(doorFrameLeftD1CIdx) * getPixelHeight(doorFrameLeftD1CIdx)];
+	_bitmapWallSetDoorFrameRightD1C = new byte[getPixelWidth(doorFrameLeftD1CIdx) * getPixelHeight(doorFrameLeftD1CIdx)](); // Flipped copy of LeftD1C
+	_bitmapWallSetDoorFrameFront = new byte[getPixelWidth(doorFrameFrontIdx) * getPixelHeight(doorFrameFrontIdx)];
 	_bitmapViewport = new byte[224 * 136]();
 
 	if (!_derivedBitmapByteCount) {
@@ -2474,7 +2494,8 @@ void DisplayMan::loadFloorSet(FloorSet set) {
 		return;
 
 	_currentFloorSet = set;
-	int16 index = (set * k2_FloorSetGraphicCount) + k75_FirstFloorSet;
+	int16 firstFloorSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k78_FirstFloorSetDOS : k75_FirstFloorSet;
+	int16 index = (set * k2_FloorSetGraphicCount) + firstFloorSet;
 	loadIntoBitmap(index, _bitmapFloor);
 	loadIntoBitmap(index + 1, _bitmapCeiling);
 }
@@ -2485,20 +2506,37 @@ void DisplayMan::loadWallSet(WallSet set) {
 
 	_currentWallSet = set;
 
-	int16 graphicIndice = (set * k13_WallSetGraphicCount) + k77_FirstWallSet;
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameFront);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD1C);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD2C);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD3C);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD3L);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameTopD1LCR);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameTopD2LCR);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetWallD0R);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetWallD0L);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetD1LCR);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetD2LCR);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetD3LCR);
-	loadIntoBitmap(graphicIndice++, _bitmapWallSetD3L2);
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		int16 graphicIndice = (set * k40_WallSetGraphicCountDOS) + k86_FirstWallSetDOS;
+		loadIntoBitmap(graphicIndice + 0, _bitmapWallSetDoorFrameFront);
+		loadIntoBitmap(graphicIndice + 1, _bitmapWallSetDoorFrameLeftD1C);
+		loadIntoBitmap(graphicIndice + 2, _bitmapWallSetDoorFrameLeftD2C);
+		loadIntoBitmap(graphicIndice + 3, _bitmapWallSetDoorFrameLeftD3C);
+		loadIntoBitmap(graphicIndice + 4, _bitmapWallSetDoorFrameLeftD3L);
+		loadIntoBitmap(graphicIndice + 5, _bitmapWallSetDoorFrameTopD1LCR);
+		loadIntoBitmap(graphicIndice + 6, _bitmapWallSetDoorFrameTopD2LCR);
+		loadIntoBitmap(graphicIndice + 7, _bitmapWallSetWallD0R);   // C00_WALL_D0R (93)
+		loadIntoBitmap(graphicIndice + 8, _bitmapWallSetWallD0L);   // C01_WALL_D0L (94)
+		loadIntoBitmap(graphicIndice + 11, _bitmapWallSetD1LCR);   // C04_WALL_D1C (97)
+		loadIntoBitmap(graphicIndice + 16, _bitmapWallSetD2LCR);   // C09_WALL_D2C (102)
+		loadIntoBitmap(graphicIndice + 21, _bitmapWallSetD3LCR);   // C14_WALL_D3C (107)
+		loadIntoBitmap(graphicIndice + 18, _bitmapWallSetD3L2);    // C11_WALL_D3L2 (104)
+	} else {
+		int16 graphicIndice = (set * k13_WallSetGraphicCount) + k77_FirstWallSet;
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameFront);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD1C);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD2C);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD3C);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameLeftD3L);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameTopD1LCR);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameTopD2LCR);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetWallD0R);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetWallD0L);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetD1LCR);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetD2LCR);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetD3LCR);
+		loadIntoBitmap(graphicIndice++, _bitmapWallSetD3L2);
+	}
 
 	copyBitmapAndFlipHorizontal(_bitmapWallSetDoorFrameLeftD1C, _bitmapWallSetDoorFrameRightD1C,
 									_doorFrameRightD1C._srcByteWidth, _doorFrameRightD1C._srcHeight);
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index ec89ddfffef..a824e76ddb1 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -300,6 +300,7 @@ enum GraphicIndice {
 
 #define k2_FloorSetGraphicCount 2 // @ C002_FLOOR_SET_GRAPHIC_COUNT
 #define k13_WallSetGraphicCount 13 // @ C013_WALL_SET_GRAPHIC_COUNT
+#define k40_WallSetGraphicCountDOS 40 // @ M647_WALL_SET_GRAPHIC_COUNT
 #define k18_StairsGraphicCount 18 // @ C018_STAIRS_GRAPHIC_COUNT
 #define k3_DoorSetGraphicsCount 3 // @ C003_DOOR_SET_GRAPHIC_COUNT
 #define k1_DoorButtonCount 1 // @ C001_DOOR_BUTTON_COUNT
@@ -322,7 +323,9 @@ enum GraphicIndice {
 #define k2_ShiftSet_D2BackD3Front 2 // @ C2_SHIFT_SET_D2_BACK_OR_D3_FRONT
 
 #define k75_FirstFloorSet 75 // @ C075_GRAPHIC_FIRST_FLOOR_SET
+#define k78_FirstFloorSetDOS 78 // @ M644_GRAPHIC_FIRST_FLOOR_SET
 #define k77_FirstWallSet 77 // @ C077_GRAPHIC_FIRST_WALL_SET
+#define k86_FirstWallSetDOS 86 // @ M646_GRAPHIC_FIRST_WALL_SET
 #define k90_FirstStairs 90 // @ C090_GRAPHIC_FIRST_STAIRS
 #define k108_FirstDoorSet 108 // @ C108_GRAPHIC_FIRST_DOOR_SET
 #define k120_InscriptionFont 120 // @ C120_GRAPHIC_INSCRIPTION_FONT


Commit: 821fd601baa7f1860e75e739c42dc482cbed5648
    https://github.com/scummvm/scummvm/commit/821fd601baa7f1860e75e739c42dc482cbed5648
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Implement IMG3 RLE decoder for DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 73019e62c6c..46b0bb5de7c 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1048,46 +1048,157 @@ void DisplayMan::loadIntoBitmap(uint16 index, byte *destBitmap) {
 
 	uint16 width = readUint16(data, _vm->getPlatform());
 	uint16 height = readUint16(data + 2, _vm->getPlatform());
-	uint16 nextByteIndex = 4;
-
-	for (int32 k = 0; k < width * height;) {
-		uint8 nextByte = data[nextByteIndex++];
-		uint8 nibble1 = (nextByte & 0xF0) >> 4;
-		uint8 nibble2 = (nextByte & 0x0F);
-		if (nibble1 <= 7) {
-			for (int j = 0; j < nibble1 + 1; ++j)
-				destBitmap[k++] = nibble2;
-		} else if (nibble1 == 0x8) {
-			uint8 byte1 = data[nextByteIndex++];
-			for (int j = 0; j < byte1 + 1; ++j)
-				destBitmap[k++] = nibble2;
-		} else if (nibble1 == 0xC) {
-			uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
-			nextByteIndex += 2;
-			for (int j = 0; j < word1 + 1; ++j)
+
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		// IMG3 Decompressor
+		int16 evenWidth = (width + 1) & ~1;
+		int32 totalPixels = evenWidth * height;
+
+		int32 nibbleIndex = 8;
+		auto getNibble = [&]() -> uint8 {
+			uint32 bytePos = nibbleIndex >> 1;
+			uint8 val = data[bytePos];
+			uint8 nibble = (nibbleIndex & 1) ? (val & 0x0F) : (val >> 4);
+			nibbleIndex++;
+			return nibble;
+		};
+
+		auto getPixelCount = [&]() -> int16 {
+			int16 count = getNibble();
+			if (count == 15) {
+				count = (getNibble() << 4) | getNibble();
+				if (count == 255)
+					count = (getNibble() << 12) | (getNibble() << 8) | (getNibble() << 4) | getNibble();
+				else
+					count += 17;
+			} else {
+				count += 2;
+			}
+			return count;
+		};
+
+		uint8 localPalette[6];
+		for (int i = 0; i < 6; ++i) {
+			localPalette[i] = getNibble();
+		}
+
+		int32 destPos = 0;
+
+		if (width != evenWidth) {
+			int16 padding = evenWidth - width;
+			int16 remainingInLine = width;
+			do {
+				uint8 cmdNibble = getNibble();
+				uint8 cmdType = cmdNibble & 0x07;
+				int16 count = 1;
+				if (cmdType == 6) {
+					if (cmdNibble & 8)
+						count = getPixelCount();
+					while (count >= remainingInLine) {
+						for (int i = 0; i < remainingInLine; ++i)
+							destBitmap[destPos + i] = destBitmap[destPos + i - evenWidth];
+						destPos += remainingInLine + padding;
+						count -= remainingInLine;
+						remainingInLine = width;
+					}
+					if (count > 0) {
+						for (int i = 0; i < count; ++i)
+							destBitmap[destPos + i] = destBitmap[destPos + i - evenWidth];
+						destPos += count;
+						remainingInLine -= count;
+					}
+				} else {
+					uint8 color;
+					if (cmdType < 6)
+						color = localPalette[cmdType];
+					else
+						color = getNibble();
+					if (cmdNibble & 8)
+						count = getPixelCount();
+					while (count >= remainingInLine) {
+						for (int i = 0; i < remainingInLine; ++i)
+							destBitmap[destPos + i] = color;
+						destPos += remainingInLine + padding;
+						count -= remainingInLine;
+						remainingInLine = width;
+					}
+					if (count > 0) {
+						for (int i = 0; i < count; ++i)
+							destBitmap[destPos + i] = color;
+						destPos += count;
+						remainingInLine -= count;
+					}
+				}
+			} while (destPos < totalPixels);
+		} else {
+			do {
+				uint8 cmdNibble = getNibble();
+				uint8 cmdType = cmdNibble & 0x07;
+				if (cmdType == 6) {
+					int16 count = 1;
+					if (cmdNibble & 8)
+						count = getPixelCount();
+					for (int i = 0; i < count; ++i)
+						destBitmap[destPos + i] = destBitmap[destPos + i - evenWidth];
+					destPos += count;
+				} else {
+					uint8 color;
+					if (cmdType < 6)
+						color = localPalette[cmdType];
+					else
+						color = getNibble();
+					int16 count = 1;
+					if (cmdNibble & 8)
+						count = getPixelCount();
+					for (int i = 0; i < count; ++i)
+						destBitmap[destPos + i] = color;
+					destPos += count;
+				}
+			} while (destPos < totalPixels);
+		}
+	} else {
+		// IMG2 Decompressor
+		uint16 nextByteIndex = 4;
+
+		for (int32 k = 0; k < width * height;) {
+			uint8 nextByte = data[nextByteIndex++];
+			uint8 nibble1 = (nextByte & 0xF0) >> 4;
+			uint8 nibble2 = (nextByte & 0x0F);
+			if (nibble1 <= 7) {
+				for (int j = 0; j < nibble1 + 1; ++j)
+					destBitmap[k++] = nibble2;
+			} else if (nibble1 == 0x8) {
+				uint8 byte1 = data[nextByteIndex++];
+				for (int j = 0; j < byte1 + 1; ++j)
+					destBitmap[k++] = nibble2;
+			} else if (nibble1 == 0xC) {
+				uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
+				nextByteIndex += 2;
+				for (int j = 0; j < word1 + 1; ++j)
+					destBitmap[k++] = nibble2;
+			} else if (nibble1 == 0xB) {
+				uint8 byte1 = data[nextByteIndex++];
+				for (int j = 0; j < byte1 + 1; ++j, ++k)
+					destBitmap[k] = destBitmap[k - width];
 				destBitmap[k++] = nibble2;
-		} else if (nibble1 == 0xB) {
-			uint8 byte1 = data[nextByteIndex++];
-for (int j = 0; j < byte1 + 1; ++j, ++k)
-				destBitmap[k] = destBitmap[k - width];
-			destBitmap[k++] = nibble2;
-		} else if (nibble1 == 0xF) {
-			uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
-			nextByteIndex += 2;
-			for (int j = 0; j < word1 + 1; ++j, ++k)
-				destBitmap[k] = destBitmap[k - width];
-			destBitmap[k++] = nibble2;
-		} else if (nibble1 == 9) {
-			uint8 byte1 = data[nextByteIndex++];
-			if (byte1 % 2)
-				byte1++;
-			else
+			} else if (nibble1 == 0xF) {
+				uint16 word1 = (_vm->getPlatform() == Common::kPlatformDOS) ? READ_LE_UINT16(data + nextByteIndex) : READ_BE_UINT16(data + nextByteIndex);
+				nextByteIndex += 2;
+				for (int j = 0; j < word1 + 1; ++j, ++k)
+					destBitmap[k] = destBitmap[k - width];
 				destBitmap[k++] = nibble2;
+			} else if (nibble1 == 9) {
+				uint8 byte1 = data[nextByteIndex++];
+				if (byte1 % 2)
+					byte1++;
+				else
+					destBitmap[k++] = nibble2;
 
-			for (int j = 0; j < byte1 / 2; ++j) {
-				uint8 byte2 = data[nextByteIndex++];
-				destBitmap[k++] = (byte2 & 0xF0) >> 4;
-				destBitmap[k++] = byte2 & 0x0F;
+				for (int j = 0; j < byte1 / 2; ++j) {
+					uint8 byte2 = data[nextByteIndex++];
+					destBitmap[k++] = (byte2 & 0xF0) >> 4;
+					destBitmap[k++] = byte2 & 0x0F;
+				}
 			}
 		}
 	}


Commit: 534aaff6362b879c78c82ffeeafb440212af090f
    https://github.com/scummvm/scummvm/commit/534aaff6362b879c78c82ffeeafb440212af090f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Handle DOS even-width padding in getPixelWidth and adjust wall set flip indices

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 46b0bb5de7c..458b85ef8e9 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1402,7 +1402,10 @@ byte *DisplayMan::getCurrentVgaBuffer() {
 
 uint16 DisplayMan::getPixelWidth(uint16 index) {
 	byte *data = _packedBitmaps + _packedItemPos[index];
-	return readUint16(data, _vm->getPlatform());
+	uint16 width = readUint16(data, _vm->getPlatform());
+	if (_vm->getPlatform() == Common::kPlatformDOS)
+		return (width + 1) & ~1; // DOS version IMG3 compression
+	return width;
 }
 
 uint16 DisplayMan::getPixelHeight(uint16 index) {
@@ -2649,10 +2652,14 @@ void DisplayMan::loadWallSet(WallSet set) {
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetD3L2);
 	}
 
+	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
+	int16 doorFrameLeftD1CIdx = firstWallSet + 1;
+	int16 d3R2Idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 18) : (firstWallSet + 12);
+
 	copyBitmapAndFlipHorizontal(_bitmapWallSetDoorFrameLeftD1C, _bitmapWallSetDoorFrameRightD1C,
-									_doorFrameRightD1C._srcByteWidth, _doorFrameRightD1C._srcHeight);
+									getPixelWidth(doorFrameLeftD1CIdx) / 2, getPixelHeight(doorFrameLeftD1CIdx));
 	copyBitmapAndFlipHorizontal(_bitmapWallSetD3L2, _bitmapWallSetD3R2,
-									_frameWallD3R2._srcByteWidth, _frameWallD3R2._srcHeight);
+									getPixelWidth(d3R2Idx) / 2, getPixelHeight(d3R2Idx));
 }
 
 void DisplayMan::loadCurrentMapGraphics() {


Commit: ca291e68e164c4032cc050a56c1f349603e759f9
    https://github.com/scummvm/scummvm/commit/ca291e68e164c4032cc050a56c1f349603e759f9
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Handle DOS null-terminated object names and bitmap blit stride lookups

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h
    engines/dm/objectman.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 458b85ef8e9..b3006ab2c9b 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1204,15 +1204,110 @@ void DisplayMan::loadIntoBitmap(uint16 index, byte *destBitmap) {
 	}
 }
 
+bool DisplayMan::getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &height) {
+	if (bitmap == nullptr)
+		return false;
+
+	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
+
+	if (bitmap == _bitmapWallSetD3LCR) {
+		int16 idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 21) : (firstWallSet + 11);
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD2LCR) {
+		int16 idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 16) : (firstWallSet + 10);
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD1LCR) {
+		int16 idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 11) : (firstWallSet + 9);
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetWallD0L) {
+		int16 idx = firstWallSet + 8;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetWallD0R) {
+		int16 idx = firstWallSet + 7;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD3L2 || bitmap == _bitmapWallSetD3R2) {
+		int16 idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 18) : (firstWallSet + 12);
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameFront) {
+		int16 idx = firstWallSet + 0;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameLeftD1C || bitmap == _bitmapWallSetDoorFrameRightD1C) {
+		int16 idx = firstWallSet + 1;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameLeftD2C) {
+		int16 idx = firstWallSet + 2;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameLeftD3C) {
+		int16 idx = firstWallSet + 3;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameLeftD3L) {
+		int16 idx = firstWallSet + 4;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameTopD1LCR) {
+		int16 idx = firstWallSet + 5;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetDoorFrameTopD2LCR) {
+		int16 idx = firstWallSet + 6;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	return false;
+}
+
 void DisplayMan::blitToBitmap(byte *srcBitmap, byte *destBitmap, const Box &box, uint16 srcX, uint16 srcY, uint16 srcByteWidth,
 								   uint16 destByteWidth, Color transparent, int16 srcHeight, int16 destHight) {
 	uint16 srcWidth = srcByteWidth * 2;
+	uint16 actualWidth = srcWidth;
+	uint16 actualHeight = srcHeight;
+	uint16 lookupWidth, lookupHeight;
+	if (getBitmapDimensions(srcBitmap, lookupWidth, lookupHeight)) {
+		actualWidth = lookupWidth;
+		actualHeight = lookupHeight;
+	}
+
 	uint16 destWidth = destByteWidth * 2;
 	for (uint16 y = 0; y < box._rect.bottom + 1 - box._rect.top; ++y) { // + 1 for inclusive boundaries
 		for (uint16 x = 0; x < box._rect.right + 1 - box._rect.left; ++x) { // + 1 for inclusive boundaries
-			if (srcX + x < srcWidth && y + srcY < srcHeight
+			if (srcX + x < actualWidth && y + srcY < actualHeight
 				&& box._rect.left + x < destWidth && y + box._rect.top < destHight) {
-				byte srcPixel = srcBitmap[srcWidth * (y + srcY) + srcX + x];
+				byte srcPixel = srcBitmap[actualWidth * (y + srcY) + srcX + x];
 				if (srcPixel != transparent)
 					destBitmap[destWidth * (y + box._rect.top) + box._rect.left + x] = srcPixel;
 			}
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index a824e76ddb1..0aeb577d49d 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -740,6 +740,8 @@ public:
 	uint16 getPixelWidth(uint16 index);
 	/// Gives the height of an IMG1 type item
 	uint16 getPixelHeight(uint16 index);
+	/// Looks up actual decompressed dimensions of a display bitmap buffer
+	bool getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &height);
 
 	void copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height); // @ F0099_DUNGEONVIEW_CopyBitmapAndFlipHorizontal
 	void drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIndex); // @ F0108_DUNGEONVIEW_DrawFloorOrnament
diff --git a/engines/dm/objectman.cpp b/engines/dm/objectman.cpp
index c07d4de5279..7181f87ea9e 100644
--- a/engines/dm/objectman.cpp
+++ b/engines/dm/objectman.cpp
@@ -118,15 +118,26 @@ void ObjectMan::loadObjectNames() {
 	char *objectNames = new char[dispMan.getCompressedDataSize(kDMObjectNamesGraphicIndice) + kDMObjectNameCount];
 	Common::MemoryReadStream stream = dispMan.getCompressedData(kDMObjectNamesGraphicIndice);
 
-	for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
-		_objectNames[objNameIndex] = objectNames;
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
+			_objectNames[objNameIndex] = objectNames;
+			byte tmpByte;
+			while ((tmpByte = stream.readByte()) != '\0') {
+				*objectNames++ = tmpByte;
+			}
+			*objectNames++ = '\0';
+		}
+	} else {
+		for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
+			_objectNames[objNameIndex] = objectNames;
 
-		byte tmpByte;
-		for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte()) // last char of object name has 7th bit on
-			*objectNames++ = tmpByte; // write while not last char
+			byte tmpByte;
+			for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte()) // last char of object name has 7th bit on
+				*objectNames++ = tmpByte; // write while not last char
 
-		*objectNames++ = tmpByte & 0x7F; // write without the 7th bit
-		*objectNames++ = '\0'; // terminate string
+			*objectNames++ = tmpByte & 0x7F; // write without the 7th bit
+			*objectNames++ = '\0'; // terminate string
+		}
 	}
 }
 


Commit: 88beab4c4d487e6a8b969d8fc662cf0414f0a7fd
    https://github.com/scummvm/scummvm/commit/88beab4c4d487e6a8b969d8fc662cf0414f0a7fd
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Dynamically size flipped wall buffers using actual graphic dimensions

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index b3006ab2c9b..5ce92379922 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -965,11 +965,18 @@ void DisplayMan::loadFNT1intoBitmap(uint16 index, byte *destBitmap) {
 }
 
 void DisplayMan::allocateFlippedWallBitmaps() {
-	_bitmapWallD3LCRFlipped = new byte[128 * 51];
-	_bitmapWallD2LCRFlipped = new byte[144 * 71];
-	_bitmapWallD1LCRFlipped = new byte[256 * 111];
-	_bitmapWallD0LFlipped = new byte[32 * 136];
-	_bitmapWallD0RFlipped = new byte[32 * 136];
+	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
+	int16 d3LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 21) : (firstWallSet + 11);
+	int16 d2LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 16) : (firstWallSet + 10);
+	int16 d1LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 11) : (firstWallSet + 9);
+	int16 wallD0LIdx = firstWallSet + 8;
+	int16 wallD0RIdx = firstWallSet + 7;
+
+	_bitmapWallD3LCRFlipped = new byte[getPixelWidth(d3LcrIdx) * getPixelHeight(d3LcrIdx)];
+	_bitmapWallD2LCRFlipped = new byte[getPixelWidth(d2LcrIdx) * getPixelHeight(d2LcrIdx)];
+	_bitmapWallD1LCRFlipped = new byte[getPixelWidth(d1LcrIdx) * getPixelHeight(d1LcrIdx)];
+	_bitmapWallD0LFlipped = new byte[getPixelWidth(wallD0LIdx) * getPixelHeight(wallD0LIdx)];
+	_bitmapWallD0RFlipped = new byte[getPixelWidth(wallD0RIdx) * getPixelHeight(wallD0RIdx)];
 }
 
 void DisplayMan::drawDoorBitmap(Frame *frame) {
@@ -2860,22 +2867,29 @@ void DisplayMan::loadCurrentMapGraphics() {
 
 	_useByteBoxCoordinates = true;
 
+	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
+	int16 d3LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 21) : (firstWallSet + 11);
+	int16 d2LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 16) : (firstWallSet + 10);
+	int16 d1LcrIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 11) : (firstWallSet + 9);
+	int16 wallD0LIdx = firstWallSet + 8;
+	int16 wallD0RIdx = firstWallSet + 7;
+
 	copyBitmapAndFlipHorizontal(_bitmapWallD3LCRNative = _bitmapWallSetD3LCR, _tmpBitmap,
-									_frameWalls163[kDMViewSquareD3C]._srcByteWidth, _frameWalls163[kDMViewSquareD3C]._srcHeight);
-	fillBitmap(_bitmapWallD3LCRFlipped, kDMColorFlesh, 64, 51);
-	blitToBitmap(_tmpBitmap, _bitmapWallD3LCRFlipped, boxWallD3LCR, 11, 0, 64, 64, kDMColorNoTransparency, 51, 51);
+									getPixelWidth(d3LcrIdx) / 2, getPixelHeight(d3LcrIdx));
+	fillBitmap(_bitmapWallD3LCRFlipped, kDMColorFlesh, getPixelWidth(d3LcrIdx) / 2, getPixelHeight(d3LcrIdx));
+	blitToBitmap(_tmpBitmap, _bitmapWallD3LCRFlipped, boxWallD3LCR, 11, 0, getPixelWidth(d3LcrIdx) / 2, getPixelWidth(d3LcrIdx) / 2, kDMColorNoTransparency, getPixelHeight(d3LcrIdx), getPixelHeight(d3LcrIdx));
 
 	copyBitmapAndFlipHorizontal(_bitmapWallD2LCRNative = _bitmapWallSetD2LCR, _tmpBitmap,
-									_frameWalls163[kDMViewSquareD2C]._srcByteWidth, _frameWalls163[kDMViewSquareD2C]._srcHeight);
-	fillBitmap(_bitmapWallD2LCRFlipped, kDMColorFlesh, 72, 71);
-	blitToBitmap(_tmpBitmap, _bitmapWallD2LCRFlipped, boxWallD2LCR, 8, 0, 72, 72, kDMColorNoTransparency, 71, 71);
+									getPixelWidth(d2LcrIdx) / 2, getPixelHeight(d2LcrIdx));
+	fillBitmap(_bitmapWallD2LCRFlipped, kDMColorFlesh, getPixelWidth(d2LcrIdx) / 2, getPixelHeight(d2LcrIdx));
+	blitToBitmap(_tmpBitmap, _bitmapWallD2LCRFlipped, boxWallD2LCR, 8, 0, getPixelWidth(d2LcrIdx) / 2, getPixelWidth(d2LcrIdx) / 2, kDMColorNoTransparency, getPixelHeight(d2LcrIdx), getPixelHeight(d2LcrIdx));
 
 	copyBitmapAndFlipHorizontal(_bitmapWallD1LCRNative = _bitmapWallSetD1LCR, _bitmapWallD1LCRFlipped,
-									_frameWalls163[kDMViewSquareD1C]._srcByteWidth, _frameWalls163[kDMViewSquareD1C]._srcHeight);
+									getPixelWidth(d1LcrIdx) / 2, getPixelHeight(d1LcrIdx));
 	copyBitmapAndFlipHorizontal(_bitmapWallD0LNative = _bitmapWallSetWallD0L, _bitmapWallD0RFlipped,
-									_frameWalls163[kDMViewSquareD0L]._srcByteWidth, _frameWalls163[kDMViewSquareD0L]._srcHeight);
+									getPixelWidth(wallD0LIdx) / 2, getPixelHeight(wallD0LIdx));
 	copyBitmapAndFlipHorizontal(_bitmapWallD0RNative = _bitmapWallSetWallD0R, _bitmapWallD0LFlipped,
-									_frameWalls163[kDMViewSquareD0L]._srcByteWidth, _frameWalls163[kDMViewSquareD0L]._srcHeight);
+									getPixelWidth(wallD0RIdx) / 2, getPixelHeight(wallD0RIdx));
 
 	int16 val = dungeon._currMap->_wallSet * k18_StairsGraphicCount + k90_FirstStairs;
 	_stairsNativeBitmapIndexUpFrontD3L = val++;


Commit: 729239556bb1b887d86f828ea1aaee22b1748a98
    https://github.com/scummvm/scummvm/commit/729239556bb1b887d86f828ea1aaee22b1748a98
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix font indexing and graphics unpacking

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h
    engines/dm/text.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 5ce92379922..05d3ae13c1c 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -922,18 +922,22 @@ void DisplayMan::loadGraphics() {
 }
 
 void DisplayMan::unpackGraphics() {
+	uint16 lastGraphicIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? 670 : 532;
+	uint16 fontIdx = getFontIndex();
+	uint16 maxBitmapsCount = fontIdx + 1;
+
 	uint32 unpackedBitmapsSize = 0;
 	for (uint16 i = 0; i <= 20; ++i)
 		unpackedBitmapsSize += getPixelWidth(i) * getPixelHeight(i);
-	for (uint16 i = 22; i <= 532; ++i)
+	for (uint16 i = 22; i <= lastGraphicIdx; ++i)
 		unpackedBitmapsSize += getPixelWidth(i) * getPixelHeight(i);
 	unpackedBitmapsSize += (5 + 1) * 6 * 128; // 5 x 6 characters, 128 of them, +1 for convenience padding
-	// graphics items go from 0-20 and 22-532 inclusive, _unpackedItemPos 21 and 22 are there for indexing convenience
+	// graphics items go from 0-20 and 22-lastGraphicIdx inclusive, _unpackedItemPos 21 and 22 are there for indexing convenience
 	if (_bitmaps) {
 		delete[] _bitmaps[0];
 		delete[] _bitmaps;
 	}
-	_bitmaps = new byte *[575]; // largest graphic indice (i think)
+	_bitmaps = new byte *[maxBitmapsCount];
 	_bitmaps[0] = new byte[unpackedBitmapsSize];
 	loadIntoBitmap(0, _bitmaps[0]);
 	for (uint16 i = 1; i <= 20; ++i) {
@@ -941,12 +945,12 @@ void DisplayMan::unpackGraphics() {
 		loadIntoBitmap(i, _bitmaps[i]);
 	}
 	_bitmaps[22] = _bitmaps[20] + getPixelWidth(20) * getPixelHeight(20);
-	for (uint16 i = 23; i <= 532; ++i) {
+	for (uint16 i = 23; i <= lastGraphicIdx; ++i) {
 		_bitmaps[i] = _bitmaps[i - 1] + getPixelWidth(i - 1) * getPixelHeight(i - 1);
 		loadIntoBitmap(i, _bitmaps[i]);
 	}
-	_bitmaps[kDMGraphicIdxFont] = _bitmaps[532] + getPixelWidth(532) * getPixelHeight(532);
-	loadFNT1intoBitmap(kDMGraphicIdxFont, _bitmaps[kDMGraphicIdxFont]);
+	_bitmaps[fontIdx] = _bitmaps[lastGraphicIdx] + getPixelWidth(lastGraphicIdx) * getPixelHeight(lastGraphicIdx);
+	loadFNT1intoBitmap(fontIdx, _bitmaps[fontIdx]);
 }
 
 void DisplayMan::loadFNT1intoBitmap(uint16 index, byte *destBitmap) {
@@ -1515,6 +1519,10 @@ uint16 DisplayMan::getPixelHeight(uint16 index) {
 	return readUint16(data + 2, _vm->getPlatform());
 }
 
+uint16 DisplayMan::getFontIndex() const {
+	return (_vm->getPlatform() == Common::kPlatformDOS) ? k695_FontDOS : kDMGraphicIdxFont;
+}
+
 void DisplayMan::copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height) {
 	memmove(destBitmap, srcBitmap, (size_t)byteWidth * 2 * height * sizeof(byte));
 	flipBitmapHorizontal(destBitmap, byteWidth, height);
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 0aeb577d49d..65f2744d4a3 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -332,6 +332,7 @@ enum GraphicIndice {
 #define k121_FirstWallOrn 121 // @ C121_GRAPHIC_FIRST_WALL_ORNAMENT
 #define k247_FirstFloorOrn 247 // @ C247_GRAPHIC_FIRST_FLOOR_ORNAMENT
 #define k303_FirstDoorOrn 303 // @ C303_GRAPHIC_FIRST_DOOR_ORNAMENT
+#define k695_FontDOS 695 // @ M653_GRAPHIC_FONT
 #define k730_DerivedBitmapMaximumCount 730 // @ C730_DERIVED_BITMAP_MAXIMUM_COUNT
 
 #define k16_Scale_D3 16 // @ C16_SCALE_D3
@@ -743,6 +744,8 @@ public:
 	/// Looks up actual decompressed dimensions of a display bitmap buffer
 	bool getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &height);
 
+	uint16 getFontIndex() const;
+
 	void copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height); // @ F0099_DUNGEONVIEW_CopyBitmapAndFlipHorizontal
 	void drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIndex); // @ F0108_DUNGEONVIEW_DrawFloorOrnament
 	void drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doorNativeBitmapIndices, int16 byteCount,
diff --git a/engines/dm/text.cpp b/engines/dm/text.cpp
index 47d8a782d87..42993a15beb 100644
--- a/engines/dm/text.cpp
+++ b/engines/dm/text.cpp
@@ -59,7 +59,7 @@ void TextMan::printTextToBitmap(byte *destBitmap, uint16 destByteWidth, int16 de
 	size_t textLength = strlen(text);
 	uint16 nextX = destX;
 	uint16 nextY = destY;
-	byte *srcBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(kDMGraphicIdxFont);
+	byte *srcBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(_vm->_displayMan->getFontIndex());
 
 	byte *tmp = _vm->_displayMan->_tmpBitmap;
 	for (uint16 i = 0; i < (kDMFontLetterWidth + 1) * kDMFontLetterHeight * 128; ++i)


Commit: 0f7e8549abc3f4e31b01da818316e59595feb03f
    https://github.com/scummvm/scummvm/commit/0f7e8549abc3f4e31b01da818316e59595feb03f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Map platform-aware graphic database indices for DOS

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h
    engines/dm/text.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 05d3ae13c1c..7f9bceb1f79 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -923,7 +923,7 @@ void DisplayMan::loadGraphics() {
 
 void DisplayMan::unpackGraphics() {
 	uint16 lastGraphicIdx = (_vm->getPlatform() == Common::kPlatformDOS) ? 670 : 532;
-	uint16 fontIdx = getFontIndex();
+	uint16 fontIdx = getGraphicIndex(kDMGraphicIdxFont);
 	uint16 maxBitmapsCount = fontIdx + 1;
 
 	uint32 unpackedBitmapsSize = 0;
@@ -1006,7 +1006,7 @@ void DisplayMan::drawDoorButton(int16 doorButtonOrdinal, DoorButton doorButton)
 
 		assert(doorButtonOrdinal == 0);
 
-		int16 nativeBitmapIndex = doorButtonOrdinal + kDMGraphicIdxFirstDoorButton;
+		int16 nativeBitmapIndex = doorButtonOrdinal + getGraphicIndex(kDMGraphicIdxFirstDoorButton);
 		int coordSet = _doorButtonCoordSet[doorButtonOrdinal];
 		uint16 *coordSetRedEagle = _doorButtonCoordSets[coordSet][doorButton];
 
@@ -1416,11 +1416,11 @@ byte *DisplayMan::getExplosionBitmap(uint16 explosionAspIndex, uint16 scale, int
 	byte *bitmap;
 	int16 derBitmapIndex = (explosionAspIndex * 14) + scale / 2 + kDMDerivedBitmapFirstExplosion - 2;
 	if ((scale == 32) && (explosionAspIndex != kDMExplosionAspectSmoke))
-		bitmap = getNativeBitmapOrGraphic(explosionAspIndex + kDMGraphicIdxFirstExplosion);
+		bitmap = getNativeBitmapOrGraphic(explosionAspIndex + getGraphicIndex(kDMGraphicIdxFirstExplosion));
 	else if (isDerivedBitmapInCache(derBitmapIndex))
 		bitmap = getDerivedBitmap(derBitmapIndex);
 	else {
-		byte *nativeBitmap = getNativeBitmapOrGraphic(MIN(explosionAspIndex, (uint16)kDMExplosionAspectPoison) + kDMGraphicIdxFirstExplosion);
+		byte *nativeBitmap = getNativeBitmapOrGraphic(MIN(explosionAspIndex, (uint16)kDMExplosionAspectPoison) + getGraphicIndex(kDMGraphicIdxFirstExplosion));
 		bitmap = getDerivedBitmap(derBitmapIndex);
 		blitToBitmapShrinkWithPalChange(nativeBitmap, bitmap, explAsp->_byteWidth * 2, explAsp->_height, pixelWidth * 2, height,
 			(explosionAspIndex == kDMExplosionAspectSmoke) ? _palChangeSmoke : _palChangesNoChanges);
@@ -1519,8 +1519,42 @@ uint16 DisplayMan::getPixelHeight(uint16 index) {
 	return readUint16(data + 2, _vm->getPlatform());
 }
 
-uint16 DisplayMan::getFontIndex() const {
-	return (_vm->getPlatform() == Common::kPlatformDOS) ? k695_FontDOS : kDMGraphicIdxFont;
+uint16 DisplayMan::getGraphicIndex(uint16 index) const {
+	if (_vm->getPlatform() != Common::kPlatformDOS)
+		return index;
+
+	switch (index) {
+	case k90_FirstStairs:
+		return k108_FirstStairsDOS;
+	case k108_FirstDoorSet:
+		return k246_FirstDoorSetDOS;
+	case k120_InscriptionFont:
+		return k258_InscriptionFontDOS;
+	case k121_FirstWallOrn:
+		return k259_FirstWallOrnDOS;
+	case k247_FirstFloorOrn:
+		return k385_FirstFloorOrnDOS;
+	case kDMGraphicIdxDoorMaskDestroyed:
+		return k439_DoorMaskDestroyedDOS;
+	case k303_FirstDoorOrn:
+		return k441_FirstDoorOrnDOS;
+	case kDMGraphicIdxFirstDoorButton:
+		return k453_FirstDoorButtonDOS;
+	case kDMGraphicIdxFirstProjectile:
+		return k454_FirstProjectileDOS;
+	case kDMGraphicIdxFirstExplosion:
+		return k486_FirstExplosionDOS;
+	case kDMGraphicIdxFirstExplosionPattern:
+		return k489_FirstExplosionPatternDOS;
+	case kDMGraphicIdxFirstObject:
+		return k498_FirstObjectDOS;
+	case kDMGraphicIdxFirstCreature:
+		return k584_FirstCreatureDOS;
+	case kDMGraphicIdxFont:
+		return k695_FontDOS;
+	default:
+		return index;
+	}
 }
 
 void DisplayMan::copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height) {
@@ -2899,7 +2933,7 @@ void DisplayMan::loadCurrentMapGraphics() {
 	copyBitmapAndFlipHorizontal(_bitmapWallD0RNative = _bitmapWallSetWallD0R, _bitmapWallD0LFlipped,
 									getPixelWidth(wallD0RIdx) / 2, getPixelHeight(wallD0RIdx));
 
-	int16 val = dungeon._currMap->_wallSet * k18_StairsGraphicCount + k90_FirstStairs;
+	int16 val = dungeon._currMap->_wallSet * k18_StairsGraphicCount + getGraphicIndex(k90_FirstStairs);
 	_stairsNativeBitmapIndexUpFrontD3L = val++;
 	_stairsNativeBitmapIndexUpFrontD3C = val++;
 	_stairsNativeBitmapIndexUpFrontD2L = val++;
@@ -2929,7 +2963,7 @@ void DisplayMan::loadCurrentMapGraphics() {
 	doorSets[0] = dungeon._currMap->_doorSet0;
 	doorSets[1] = dungeon._currMap->_doorSet1;
 	for (uint16 doorSet = 0; doorSet <= 1; doorSet++) {
-		int16 counter = k108_FirstDoorSet + (doorSets[doorSet] * k3_DoorSetGraphicsCount);
+		int16 counter = getGraphicIndex(k108_FirstDoorSet) + (doorSets[doorSet] * k3_DoorSetGraphicsCount);
 		_doorNativeBitmapIndexFrontD3LCR[doorSet] = counter++;
 		_doorNativeBitmapIndexFrontD2LCR[doorSet] = counter++;
 		_doorNativeBitmapIndexFrontD1LCR[doorSet] = counter++;
@@ -2944,7 +2978,7 @@ void DisplayMan::loadCurrentMapGraphics() {
 	for (int16 ornamentIndex = 0; ornamentIndex <= currMap._wallOrnCount; ornamentIndex++) {
 		uint16 greenOrn = _currMapWallOrnIndices[ornamentIndex];
 		/* Each wall ornament has 2 graphics */
-		_currMapWallOrnInfo[ornamentIndex].nativeIndice = k121_FirstWallOrn + greenOrn * 2;
+		_currMapWallOrnInfo[ornamentIndex].nativeIndice = getGraphicIndex(k121_FirstWallOrn) + greenOrn * 2;
 		for (int16 ornamentCounter = 0; ornamentCounter < k3_AlcoveOrnCount; ornamentCounter++) {
 			if (greenOrn == g192_AlcoveOrnIndices[ornamentCounter]) {
 				_currMapAlcoveOrnIndices[alcoveCount++] = ornamentIndex;
@@ -2973,16 +3007,14 @@ void DisplayMan::loadCurrentMapGraphics() {
 
 	for (uint16 i = 0; i < currMap._floorOrnCount; ++i) {
 		uint16 ornIndice = _currMapFloorOrnIndices[i];
-		uint16 nativeIndice = k247_FirstFloorOrn + ornIndice * 6;
+		uint16 nativeIndice = getGraphicIndex(k247_FirstFloorOrn) + ornIndice * 6;
 		_currMapFloorOrnInfo[i].nativeIndice = nativeIndice;
 		_currMapFloorOrnInfo[i].coordinateSet = floorOrnCoordSetIndices[ornIndice];
 	}
 
-
-
 	for (uint16 i = 0; i < currMap._doorOrnCount; ++i) {
 		uint16 ornIndice = _currMapDoorOrnIndices[i];
-		_currMapDoorOrnInfo[i].nativeIndice = k303_FirstDoorOrn + ornIndice;
+		_currMapDoorOrnInfo[i].nativeIndice = getGraphicIndex(k303_FirstDoorOrn) + ornIndice;
 		_currMapDoorOrnInfo[i].coordinateSet = doorOrnCoordIndices[ornIndice];
 
 		uint16 *coords = _doorOrnCoordSets[_currMapDoorOrnInfo[i].coordinateSet][0];
@@ -3121,7 +3153,7 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 			if (isInscription) {
 				blitToBitmap(_bitmapWallSetD1LCR, _bitmapViewport, boxWallPatchBehindInscription, 94, 28, _frameWalls163[kDMViewSquareD1C]._srcByteWidth, k112_byteWidthViewport, kDMColorNoTransparency, _frameWalls163[kDMViewSquareD1C]._srcHeight, k136_heightViewport);
 				byte *inscrString = inscriptionString;
-				byte *L0092_puc_Bitmap = getNativeBitmapOrGraphic(k120_InscriptionFont);
+				byte *L0092_puc_Bitmap = getNativeBitmapOrGraphic(getGraphicIndex(k120_InscriptionFont));
 				int16 textLineIndex = 0;
 				do {
 					int16 characterCount = 0;
@@ -3611,7 +3643,7 @@ void DisplayMan::drawObjectsCreaturesProjectilesExplosions(Thing thingParam, Dir
 				if (aspectIndex >= k85_ObjAspectCount)
 					continue;
 				objectAspect = &(_objectAspects209[aspectIndex]);
-				AL_4_nativeBitmapIndex = kDMGraphicIdxFirstObject + objectAspect->_firstNativeBitmapRelativeIndex;
+				AL_4_nativeBitmapIndex = getGraphicIndex(kDMGraphicIdxFirstObject) + objectAspect->_firstNativeBitmapRelativeIndex;
 				useAlcoveObjectImage = (L0135_B_DrawAlcoveObjects && getFlag(objectAspect->_graphicInfo, k0x0010_ObjectAlcoveMask) && (viewLane == kDMViewLaneCenter));
 				if (useAlcoveObjectImage)
 					AL_4_nativeBitmapIndex++;
@@ -3802,7 +3834,7 @@ T0115077_DrawSecondHalfSquareCreature:
 		if (!coordinateSet[1])
 			goto T0115126_CreatureNotVisible;
 		creatureGraphicInfoRed = creatureGraphicInfoGreen;
-		AL_4_nativeBitmapIndex = kDMGraphicIdxFirstCreature + ((CreatureAspect *)objectAspect)->_firstNativeBitmapRelativeIndex; /* By default, assume using the front image */
+		AL_4_nativeBitmapIndex = getGraphicIndex(kDMGraphicIdxFirstCreature) + ((CreatureAspect *)objectAspect)->_firstNativeBitmapRelativeIndex; /* By default, assume using the front image */
 		derivedBitmapIndex = ((CreatureAspect *)objectAspect)->_firstDerivedBitmapIndex;
 		int16 sourceByteWidth;
 		int16 sourceHeight;
@@ -3991,7 +4023,7 @@ T0115129_DrawProjectiles:
 				AL_4_projectileAspect = dungeon.getProjectileAspect(projectile->_slot);
 				if (AL_4_projectileAspect < 0) { /* Negative value: projectile aspect is the ordinal of a PROJECTIL_ASPECT */
 					objectAspect = (ObjectAspect *)&_projectileAspect[_vm->ordinalToIndex(-AL_4_projectileAspect)];
-					AL_4_nativeBitmapIndex = ((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + kDMGraphicIdxFirstProjectile;
+					AL_4_nativeBitmapIndex = ((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + getGraphicIndex(kDMGraphicIdxFirstProjectile);
 					projectileAspectType = getFlag(((ProjectileAspect *)objectAspect)->_graphicInfo, k0x0003_ProjectileAspectTypeMask);
 
 					bool doNotScaleWithKineticEnergy = !getFlag(((ProjectileAspect *)objectAspect)->_graphicInfo, k0x0100_ProjectileScaleWithKineticEnergyMask);
@@ -4096,7 +4128,7 @@ T0115129_DrawProjectiles:
 					projectileCoordinates[1] = 47;
 					coordinateSet = projectileCoordinates;
 					objectAspect = &_objectAspects209[AL_4_projectileAspect];
-					AL_4_nativeBitmapIndex = objectAspect->_firstNativeBitmapRelativeIndex + kDMGraphicIdxFirstObject;
+					AL_4_nativeBitmapIndex = objectAspect->_firstNativeBitmapRelativeIndex + getGraphicIndex(kDMGraphicIdxFirstObject);
 					drawProjectileAsObject = true;
 					goto T0115015_DrawProjectileAsObject; /* Go to code section to draw an object. Once completed, it jumps back to T0115171_BackFromT0115015_DrawProjectileAsObject below */
 				}
@@ -4135,7 +4167,7 @@ T0115171_BackFromT0115015_DrawProjectileAsObject:;
 				} else {
 					if (AL_4_explosionType == kDMExplosionTypeRebirthStep1) {
 						objectAspect = (ObjectAspect *)&_projectileAspect[_vm->ordinalToIndex(-dungeon.getProjectileAspect(_vm->_thingExplLightningBolt))];
-						bitmapRedBanana = getNativeBitmapOrGraphic(((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + (kDMGraphicIdxFirstProjectile + 1));
+						bitmapRedBanana = getNativeBitmapOrGraphic(((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + (getGraphicIndex(kDMGraphicIdxFirstProjectile) + 1));
 						explosionCoordinates = rebirthStep1ExplosionCoordinates[AL_1_viewSquareExplosionIndex - 3];
 						byteWidth = getScaledDimension((((ProjectileAspect *)objectAspect)->_byteWidth), explosionCoordinates[2]);
 						heightRedEagle = getScaledDimension((((ProjectileAspect *)objectAspect)->_height), explosionCoordinates[2]);
@@ -4165,7 +4197,7 @@ T0115171_BackFromT0115015_DrawProjectileAsObject:;
 						AL_4_explosionAspectIndex++; /* Use third graphic in the pattern for large explosion attack */
 				}
 				isDerivedBitmapInCache(kDMDerivedBitmapViewport);
-				bitmapRedBanana = getNativeBitmapOrGraphic(AL_4_explosionAspectIndex + kDMGraphicIdxFirstExplosionPattern);
+				bitmapRedBanana = getNativeBitmapOrGraphic(AL_4_explosionAspectIndex + getGraphicIndex(kDMGraphicIdxFirstExplosionPattern));
 				if (smoke) {
 					blitToBitmapShrinkWithPalChange(bitmapRedBanana, _tmpBitmap, 48, 32, 48, 32, _palChangeSmoke);
 					bitmapRedBanana = _tmpBitmap;
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 65f2744d4a3..f5a8aadc53d 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -327,11 +327,24 @@ enum GraphicIndice {
 #define k77_FirstWallSet 77 // @ C077_GRAPHIC_FIRST_WALL_SET
 #define k86_FirstWallSetDOS 86 // @ M646_GRAPHIC_FIRST_WALL_SET
 #define k90_FirstStairs 90 // @ C090_GRAPHIC_FIRST_STAIRS
+#define k108_FirstStairsDOS 108 // @ M645_GRAPHIC_FIRST_STAIRS
 #define k108_FirstDoorSet 108 // @ C108_GRAPHIC_FIRST_DOOR_SET
+#define k246_FirstDoorSetDOS 246 // @ M633_GRAPHIC_FIRST_DOOR_SET
 #define k120_InscriptionFont 120 // @ C120_GRAPHIC_INSCRIPTION_FONT
+#define k258_InscriptionFontDOS 258 // @ M648_GRAPHIC_INSCRIPTION_FONT
 #define k121_FirstWallOrn 121 // @ C121_GRAPHIC_FIRST_WALL_ORNAMENT
+#define k259_FirstWallOrnDOS 259 // @ M615_GRAPHIC_FIRST_WALL_ORNAMENT
 #define k247_FirstFloorOrn 247 // @ C247_GRAPHIC_FIRST_FLOOR_ORNAMENT
+#define k385_FirstFloorOrnDOS 385 // @ M616_GRAPHIC_FIRST_FLOOR_ORNAMENT
+#define k439_DoorMaskDestroyedDOS 439 // @ M649_GRAPHIC_DOOR_MASK_DESTROYED
 #define k303_FirstDoorOrn 303 // @ C303_GRAPHIC_FIRST_DOOR_ORNAMENT
+#define k441_FirstDoorOrnDOS 441 // @ M617_GRAPHIC_FIRST_DOOR_ORNAMENT
+#define k453_FirstDoorButtonDOS 453 // @ M634_GRAPHIC_FIRST_DOOR_BUTTON
+#define k454_FirstProjectileDOS 454 // @ M613_GRAPHIC_FIRST_PROJECTILE
+#define k486_FirstExplosionDOS 486 // @ M614_GRAPHIC_FIRST_EXPLOSION
+#define k489_FirstExplosionPatternDOS 489 // @ M636_GRAPHIC_FIRST_EXPLOSION_PATTERN
+#define k498_FirstObjectDOS 498 // @ M612_GRAPHIC_FIRST_OBJECT
+#define k584_FirstCreatureDOS 584 // @ M618_GRAPHIC_FIRST_CREATURE
 #define k695_FontDOS 695 // @ M653_GRAPHIC_FONT
 #define k730_DerivedBitmapMaximumCount 730 // @ C730_DERIVED_BITMAP_MAXIMUM_COUNT
 
@@ -744,7 +757,7 @@ public:
 	/// Looks up actual decompressed dimensions of a display bitmap buffer
 	bool getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &height);
 
-	uint16 getFontIndex() const;
+	uint16 getGraphicIndex(uint16 index) const;
 
 	void copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height); // @ F0099_DUNGEONVIEW_CopyBitmapAndFlipHorizontal
 	void drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIndex); // @ F0108_DUNGEONVIEW_DrawFloorOrnament
diff --git a/engines/dm/text.cpp b/engines/dm/text.cpp
index 42993a15beb..d8566ef3af7 100644
--- a/engines/dm/text.cpp
+++ b/engines/dm/text.cpp
@@ -59,7 +59,7 @@ void TextMan::printTextToBitmap(byte *destBitmap, uint16 destByteWidth, int16 de
 	size_t textLength = strlen(text);
 	uint16 nextX = destX;
 	uint16 nextY = destY;
-	byte *srcBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(_vm->_displayMan->getFontIndex());
+	byte *srcBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(_vm->_displayMan->getGraphicIndex(kDMGraphicIdxFont));
 
 	byte *tmp = _vm->_displayMan->_tmpBitmap;
 	for (uint16 i = 0; i < (kDMFontLetterWidth + 1) * kDMFontLetterHeight * 128; ++i)


Commit: 1d87adc06a567ac983dc43a9e90457aec39de7f0
    https://github.com/scummvm/scummvm/commit/1d87adc06a567ac983dc43a9e90457aec39de7f0
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Populate UI panel palette entries 0-15 while in dungeon

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 7f9bceb1f79..47812b9a93c 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -4916,6 +4916,17 @@ static const ColorDef *const g_vgaPaletteTable[29] = { // @ G8176_PaletteTable
 void DisplayMan::setMultipleColorsInPalette(int16 paletteIndex) {
 	assert(paletteIndex >= 0 && paletteIndex < 29);
 	if (paletteIndex < 6) {
+		// Populate UI palette entries (0..15) from _interfacePaletteIndex
+		const ColorDef *uiColorDef = g_vgaPaletteTable[_interfacePaletteIndex];
+		int8 uiColorIndex;
+		while ((uiColorIndex = (int8)uiColorDef->index) >= 0) {
+			int8 targetIdx = uiColorIndex & 0x0F;
+			_vgaPalette[targetIdx * 3]     = (uiColorDef->r << 2) | (uiColorDef->r >> 4);
+			_vgaPalette[targetIdx * 3 + 1] = (uiColorDef->g << 2) | (uiColorDef->g >> 4);
+			_vgaPalette[targetIdx * 3 + 2] = (uiColorDef->b << 2) | (uiColorDef->b >> 4);
+			uiColorDef++;
+		}
+
 		/* Read light levels directly from _palDungeonView, which already
 		contains runtime-applied creature replacements. Bypasses the need
 		for DOS version's G8175_CREAT_PAL lookup table. */


Commit: 7367d18611fd4910373e8c397d351c0121a93b35
    https://github.com/scummvm/scummvm/commit/7367d18611fd4910373e8c397d351c0121a93b35
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Correct viewport palette shift to viewport region and enable only when viewport switching active

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 47812b9a93c..640bb6c0cee 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1434,14 +1434,19 @@ byte *DisplayMan::getExplosionBitmap(uint16 explosionAspIndex, uint16 scale, int
 
 void DisplayMan::updateScreen() {
 	_vm->_textMan->updateMessageArea();
-	// apply copper
-	for (uint32 i = 320 * 30; i < 320 * 170; ++i)
-		_bitmapScreen[i] += 16;
-	g_system->copyRectToScreen(_bitmapScreen, _screenWidth, 0, 0, _screenWidth, _screenHeight);
 
+	if (_paletteSwitchingEnabled)
+		for (uint16 y = 33; y <= 168; ++y)
+			for (uint16 x = 0; x <= 223; ++x)
+				_bitmapScreen[y * 320 + x] += 16;
+
+	g_system->copyRectToScreen(_bitmapScreen, _screenWidth, 0, 0, _screenWidth, _screenHeight);
 	g_system->updateScreen();
-	for (uint32 i = 320 * 30; i < 320 * 170; ++i)
-		_bitmapScreen[i] -= 16;
+
+	if (_paletteSwitchingEnabled)
+		for (uint16 y = 33; y <= 168; ++y)
+			for (uint16 x = 0; x <= 223; ++x)
+				_bitmapScreen[y * 320 + x] -= 16;
 }
 
 void DisplayMan::drawViewport(int16 palSwitchingRequestedState) {


Commit: bb1dfa8c0b60429ca86293d3164bd0e622cd2384
    https://github.com/scummvm/scummvm/commit/bb1dfa8c0b60429ca86293d3164bd0e622cd2384
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix entrance gate and UI rendering by expanding dynamic bitmap dimension lookups

Clean up bitmap dimension lookups in blitToBitmap

Changed paths:
    engines/dm/dm.h
    engines/dm/gfx.cpp


diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 55f6b05958e..9fd67b5fb75 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -227,7 +227,6 @@ public:
 
 private:
 	uint16 _dungeonId; // @ G0526_ui_DungeonID
-	byte *_entranceDoorAnimSteps[10]; // @ G0562_apuc_Bitmap_EntranceDoorAnimationSteps
 	byte *_interfaceCredits; // @ G0564_puc_Graphic5_InterfaceCredits
 	Common::RandomSource *_rnd;
 
@@ -235,6 +234,7 @@ private:
 	const DMADGameDescription *_gameVersion;
 	bool _canLoadFromGMM;
 public:
+	byte *_entranceDoorAnimSteps[10]; // @ G0562_apuc_Bitmap_EntranceDoorAnimationSteps
 	Console *_console;
 	DisplayMan *_displayMan;
 	DungeonMan *_dungeonMan;
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 640bb6c0cee..18eb812bbba 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -33,6 +33,7 @@
 #include "dm/gfx.h"
 #include "dm/dungeonman.h"
 #include "dm/group.h"
+#include "dm/menus.h"
 #include "dm/timeline.h"
 #include "dm/champion.h"
 #include "dm/eventman.h"
@@ -1219,6 +1220,50 @@ bool DisplayMan::getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &
 	if (bitmap == nullptr)
 		return false;
 
+	if (_bitmaps && _bitmaps[0]) {
+		uint16 fontIdx = getGraphicIndex(kDMGraphicIdxFont);
+		uint16 maxBitmapsCount = fontIdx + 1;
+		for (uint16 i = 0; i < maxBitmapsCount; ++i) {
+			if (bitmap == _bitmaps[i]) {
+				width = getPixelWidth(i);
+				height = getPixelHeight(i);
+				return true;
+			}
+		}
+	}
+
+	if (_vm->_entranceDoorAnimSteps[0] && bitmap == _vm->_entranceDoorAnimSteps[0]) {
+		uint16 idx = kDMGraphicIdxEntranceLeftDoor;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (_vm->_entranceDoorAnimSteps[4] && bitmap == _vm->_entranceDoorAnimSteps[4]) {
+		uint16 idx = kDMGraphicIdxEntranceRightDoor;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+
+	if (_vm->_menuMan && bitmap == _vm->_menuMan->_bitmapSpellAreaLines) {
+		uint16 idx = getGraphicIndex(kDMGraphicIdxMenuSpellAreLines);
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+
+	int16 firstFloorSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k78_FirstFloorSetDOS : k75_FirstFloorSet;
+	if (bitmap == _bitmapFloor) {
+		width = getPixelWidth(firstFloorSet);
+		height = getPixelHeight(firstFloorSet);
+		return true;
+	}
+	if (bitmap == _bitmapCeiling) {
+		width = getPixelWidth(firstFloorSet + 1);
+		height = getPixelHeight(firstFloorSet + 1);
+		return true;
+	}
+
 	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
 
 	if (bitmap == _bitmapWallSetD3LCR) {
@@ -1304,16 +1349,18 @@ bool DisplayMan::getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &
 
 void DisplayMan::blitToBitmap(byte *srcBitmap, byte *destBitmap, const Box &box, uint16 srcX, uint16 srcY, uint16 srcByteWidth,
 								   uint16 destByteWidth, Color transparent, int16 srcHeight, int16 destHight) {
-	uint16 srcWidth = srcByteWidth * 2;
-	uint16 actualWidth = srcWidth;
+	uint16 actualWidth = srcByteWidth * 2;
 	uint16 actualHeight = srcHeight;
-	uint16 lookupWidth, lookupHeight;
-	if (getBitmapDimensions(srcBitmap, lookupWidth, lookupHeight)) {
-		actualWidth = lookupWidth;
-		actualHeight = lookupHeight;
+	uint16 w, h;
+	if (getBitmapDimensions(srcBitmap, w, h)) {
+		actualWidth = w;
+		actualHeight = h;
 	}
 
 	uint16 destWidth = destByteWidth * 2;
+	if (getBitmapDimensions(destBitmap, w, h))
+		destWidth = w;
+
 	for (uint16 y = 0; y < box._rect.bottom + 1 - box._rect.top; ++y) { // + 1 for inclusive boundaries
 		for (uint16 x = 0; x < box._rect.right + 1 - box._rect.left; ++x) { // + 1 for inclusive boundaries
 			if (srcX + x < actualWidth && y + srcY < actualHeight


Commit: 687b609e3c4f64ed5b3642e3ead09780ab1a2fc2
    https://github.com/scummvm/scummvm/commit/687b609e3c4f64ed5b3642e3ead09780ab1a2fc2
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix DOS right UI panel box bounds

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/menus.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 18eb812bbba..d4a75f5433d 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -636,7 +636,10 @@ void DisplayMan::initConstants() {
 	);
 
 	_boxThievesEyeViewPortVisibleArea = Box(64, 159, 19, 113); // @ G0106_s_Graphic558_Box_ThievesEye_ViewportVisibleArea
-	_boxMovementArrows = Box(224, 319, 124, 168); // @ G0002_s_Graphic562_Box_MovementArrows
+	if (_vm->getPlatform() == Common::kPlatformDOS)
+		_boxMovementArrows = Box(233, 319, 124, 168);
+	else
+		_boxMovementArrows = Box(224, 319, 124, 168); // @ G0002_s_Graphic562_Box_MovementArrows
 }
 
 DisplayMan::~DisplayMan() {
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index f43b6063f89..899036f1bae 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -135,11 +135,19 @@ void MenuMan::initConstants() {
 		2   /* FUSE */
 	};
 
-	_boxActionArea1ActionMenu = Box(224, 319, 77, 97); // @ G0501_s_Graphic560_Box_ActionArea1ActionMenu
-	_boxActionArea2ActionMenu = Box(224, 319, 77, 109); // @ G0500_s_Graphic560_Box_ActionArea2ActionsMenu
-	_boxActionArea3ActionMenu = Box(224, 319, 77, 121); // @ G0499_s_Graphic560_Box_ActionArea3ActionsMenu
-	_boxActionArea = Box(224, 319, 77, 121); // @ G0001_s_Graphic562_Box_ActionArea
-	_boxSpellArea = Box(224, 319, 42, 74);
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		_boxActionArea1ActionMenu = Box(233, 319, 77, 97);
+		_boxActionArea2ActionMenu = Box(233, 319, 77, 109);
+		_boxActionArea3ActionMenu = Box(233, 319, 77, 121);
+		_boxActionArea = Box(233, 319, 77, 121);
+		_boxSpellArea = Box(233, 319, 42, 74);
+	} else {
+		_boxActionArea1ActionMenu = Box(224, 319, 77, 97);
+		_boxActionArea2ActionMenu = Box(224, 319, 77, 109);
+		_boxActionArea3ActionMenu = Box(224, 319, 77, 121);
+		_boxActionArea = Box(224, 319, 77, 121);
+		_boxSpellArea = Box(224, 319, 42, 74);
+	}
 
 	for (int i = 0; i < 44; i++) {
 		_actionSkillIndex[i] = actionSkillIndex[i];


Commit: 462bae74cce87ea56cc7c3e319e9b75e71c959e5
    https://github.com/scummvm/scummvm/commit/462bae74cce87ea56cc7c3e319e9b75e71c959e5
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Map spell area lines graphic index for DOS platform

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index d4a75f5433d..df5fd935448 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1605,6 +1605,8 @@ uint16 DisplayMan::getGraphicIndex(uint16 index) const {
 		return k498_FirstObjectDOS;
 	case kDMGraphicIdxFirstCreature:
 		return k584_FirstCreatureDOS;
+	case kDMGraphicIdxMenuSpellAreLines:
+		return k9_MenuSpellAreaLinesDOS;
 	case kDMGraphicIdxFont:
 		return k695_FontDOS;
 	default:
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index f5a8aadc53d..1c52ac0080b 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -322,6 +322,7 @@ enum GraphicIndice {
 #define k1_ShiftSet_D1BackD2Front 1 // @ C1_SHIFT_SET_D1_BACK_OR_D2_FRONT
 #define k2_ShiftSet_D2BackD3Front 2 // @ C2_SHIFT_SET_D2_BACK_OR_D3_FRONT
 
+#define k9_MenuSpellAreaLinesDOS 9 // @ C009_GRAPHIC_MENU_SPELL_AREA_LINES
 #define k75_FirstFloorSet 75 // @ C075_GRAPHIC_FIRST_FLOOR_SET
 #define k78_FirstFloorSetDOS 78 // @ M644_GRAPHIC_FIRST_FLOOR_SET
 #define k77_FirstWallSet 77 // @ C077_GRAPHIC_FIRST_WALL_SET


Commit: 08e6e286bb8e3e8b6de504b5d2b9854e06644f36
    https://github.com/scummvm/scummvm/commit/08e6e286bb8e3e8b6de504b5d2b9854e06644f36
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add support for sound in DOS version

Changed paths:
    engines/dm/sounds.cpp


diff --git a/engines/dm/sounds.cpp b/engines/dm/sounds.cpp
index 4000c13bbe6..c11ad87aaa4 100644
--- a/engines/dm/sounds.cpp
+++ b/engines/dm/sounds.cpp
@@ -44,6 +44,7 @@ SoundMan *SoundMan::getSoundMan(DMEngine *vm, const DMADGameDescription *gameVer
 		warning("Unknown platform, using default Amiga SoundMan");
 		// fall through
 	case Common::kPlatformAmiga:
+	case Common::kPlatformDOS:
 		return new SoundMan(vm);
 	case Common::kPlatformAtariST:
 		return new SoundMan_Atari(vm);
@@ -51,7 +52,7 @@ SoundMan *SoundMan::getSoundMan(DMEngine *vm, const DMADGameDescription *gameVer
 }
 
 void SoundMan::initConstants() {
-	Sound sounds[kDMSoundCount] = {
+	Sound soundsAmiga[kDMSoundCount] = {
 		Sound(533, 112,  11, 3, 6), /* k00_soundMETALLIC_THUD 0 */
 		Sound(534, 112,  15, 0, 3), /* k01_soundSWITCH 1 */
 		Sound(535, 112,  72, 3, 6), /* k02_soundDOOR_RATTLE 2 */
@@ -87,8 +88,47 @@ void SoundMan::initConstants() {
 		Sound(573, 138,  29, 0, 4), /* k32_soundMOVE_RED_DRAGON 32 Atari ST: not present */
 		Sound(574, 150,  22, 0, 4)  /* k33_soundMOVE_SKELETON 33 Atari ST: not present */
 	};
+
+	Sound soundsDOS[kDMSoundCount] = {
+		Sound(671, 112,  11, 3, 6), /* k00_soundMETALLIC_THUD 0 */
+		Sound(672, 112,  15, 0, 3), /* k01_soundSWITCH 1 */
+		Sound(673, 112,  72, 3, 6), /* k02_soundDOOR_RATTLE 2 */
+		Sound(688, 112,  60, 3, 5), /* k03_soundATTACK_PAIN_RAT_HELLHOUND_RED_DRAGON 3 */
+		Sound(674, 112,  10, 3, 6), /* k04_soundWOODEN_THUD 4 */
+		Sound(675, 112,  99, 3, 7), /* k05_soundSTRONG_EXPLOSION 5 */
+		Sound(677, 112, 110, 3, 6), /* k06_soundSCREAM 6 */
+		Sound(689, 112,  55, 3, 5), /* k07_soundATTACK_MUMMY_GHOST_RIVE 7 */
+		Sound(678, 112,   2, 3, 6), /* k08_soundSWALLOW 8 */
+		Sound(679, 112,  80, 3, 6), /* k09_soundCHAMPION_0_DAMAGED 9 */
+		Sound(680, 112,  82, 3, 6), /* k10_soundCHAMPION_1_DAMAGED 10 */
+		Sound(681, 112,  84, 3, 6), /* k11_soundCHAMPION_2_DAMAGED 11 */
+		Sound(682, 112,  86, 3, 6), /* k12_soundCHAMPION_3_DAMAGED 12 */
+		Sound(683, 112,  95, 3, 6), /* k13_soundSPELL 13 */
+		Sound(690, 112,  57, 3, 5), /* k14_soundATTACK_SCREAMER_OITU 14 */
+		Sound(691, 112,  52, 3, 5), /* k15_soundATTACK_GIANT_SCORPION_SCORPION 15 */
+		Sound(684, 112,  40, 2, 4), /* k16_soundCOMBAT_ATTACK_SKELETON 16 */
+		Sound(685, 112,  70, 1, 4), /* k17_soundBUZZ 17 */
+		Sound(687, 138,  75, 3, 6), /* k18_soundPARTY_DAMAGED 18 */
+		Sound(692, 112,  50, 3, 5), /* k19_soundATTACK_MAGENTA_WORM_WORM 19 */
+		Sound(675, 112,  98, 0, 4), /* k20_soundWEAK_EXPLOSION 20 */
+		Sound(693, 112,  96, 2, 4), /* k21_soundATTACK_GIGGLER 21 */
+		Sound(701, 138,  24, 0, 4), /* k22_soundMOVE_ANIMATED_ARMOUR 22 */
+		Sound(702, 138,  21, 0, 4), /* k23_soundMOVE_COUATL 23 */
+		Sound(703, 138,  23, 0, 4), /* k24_soundMOVE_MUMMY 24 */
+		Sound(704, 138, 105, 0, 4), /* k25_soundBLOW_HORN 25 */
+		Sound(705, 138,  27, 0, 4), /* k26_soundMOVE_SCREAMER 26 */
+		Sound(706, 138,  28, 0, 4), /* k27_soundMOVE_SWAMP_SLIME 27 */
+		Sound(707, 138, 106, 0, 4), /* k28_soundWAR_CRY 28 */
+		Sound(708, 138,  56, 0, 4), /* k29_soundATTACK_ROCK 29 */
+		Sound(709, 138,  58, 0, 4), /* k30_soundATTACK_WATER_ELEMENTAL 30 */
+		Sound(710, 112,  53, 0, 4), /* k31_soundATTACK_COUATL 31 */
+		Sound(711, 138,  29, 0, 4), /* k32_soundMOVE_RED_DRAGON 32 */
+		Sound(712, 150,  22, 0, 4)  /* k33_soundMOVE_SKELETON 33 */
+	};
+
+	const Sound *src = (_vm->getPlatform() == Common::kPlatformDOS) ? soundsDOS : soundsAmiga;
 	for (int i = 0; i < kDMSoundCount; i++)
-		_sounds[i] = sounds[i];
+		_sounds[i] = src[i];
 }
 
 SoundMan::SoundMan(DMEngine *vm) : _vm(vm) {
@@ -109,14 +149,18 @@ void SoundMan::loadSounds() {
 		soundData->_firstSample = new byte[soundData->_byteCount];
 
 		Common::MemoryReadStream stream = _vm->_displayMan->getCompressedData(graphicIndex);
-		soundData->_sampleCount = stream.readUint16BE();
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			soundData->_sampleCount = stream.readUint16LE();
+		else
+			soundData->_sampleCount = stream.readUint16BE();
 		stream.read(soundData->_firstSample, soundData->_byteCount);
 	}
 }
 
 void SoundMan::play(uint16 soundIndex, uint16 period, uint8 leftVolume, uint8 rightVolume) {
 	SoundData *sound = &_soundData[soundIndex];
-	Audio::AudioStream *stream = Audio::makeRawStream(sound->_firstSample, sound->_byteCount, (72800 / period) * 8, 0, DisposeAfterUse::NO);
+	byte flags = (_vm->getPlatform() == Common::kPlatformDOS) ? Audio::FLAG_UNSIGNED : 0;
+	Audio::AudioStream *stream = Audio::makeRawStream(sound->_firstSample, sound->_byteCount, (72800 / period) * 8, flags, DisposeAfterUse::NO);
 
 	signed char balance = ((int16)rightVolume - (int16)leftVolume) / 2;
 


Commit: 347084dc58571b47dd78e0459c74396156cf7e1e
    https://github.com/scummvm/scummvm/commit/347084dc58571b47dd78e0459c74396156cf7e1e
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Clear shared spell area buffer before reusing

Changed paths:
    engines/dm/menus.cpp


diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 899036f1bae..460ee6f895a 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -441,6 +441,8 @@ void MenuMan::buildSpellAreaLine(int16 spellAreaBitmapLine) {
 
 	char spellSymbolString[2] = {'\0', '\0'};
 	Champion *magicChampion = &championMan._champions[championMan._magicCasterChampionIndex];
+	// Clear the buffer before reusing to avoid ghost artifacts
+	memset(_bitmapSpellAreaLine, 0, 96 * 12);
 	if (spellAreaBitmapLine == kDMSpellAreaAvailableSymbols) {
 		_vm->_displayMan->_useByteBoxCoordinates = false;
 		_vm->_displayMan->blitToBitmap(_bitmapSpellAreaLines, _bitmapSpellAreaLine, boxSpellAreaLine, 0, 12, k48_byteWidth, k48_byteWidth, kDMColorNoTransparency, 36, 12);


Commit: 10eec0db158ef8e3d59306f572478878e90e553a
    https://github.com/scummvm/scummvm/commit/10eec0db158ef8e3d59306f572478878e90e553a
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Load and render separate individual wall panel graphics on DOS

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index df5fd935448..0328c411954 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -118,11 +118,19 @@ DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) {
 	_inscriptionThing = _vm->_thingNone;
 	_useByteBoxCoordinates = false;
 
+	_bitmapWallSetD2L2 = nullptr;
+	_bitmapWallSetD2R2 = nullptr;
 	_bitmapWallSetD3L2 = nullptr;
 	_bitmapWallSetD3R2 = nullptr;
 	_bitmapWallSetD3LCR = nullptr;
 	_bitmapWallSetD2LCR = nullptr;
 	_bitmapWallSetD1LCR = nullptr;
+	_bitmapWallSetD1L = nullptr;
+	_bitmapWallSetD1R = nullptr;
+	_bitmapWallSetD2L = nullptr;
+	_bitmapWallSetD2R = nullptr;
+	_bitmapWallSetD3L = nullptr;
+	_bitmapWallSetD3R = nullptr;
 	_bitmapWallSetWallD0L = nullptr;
 	_bitmapWallSetWallD0R = nullptr;
 	_bitmapWallSetDoorFrameTopD2LCR = nullptr;
@@ -663,11 +671,19 @@ DisplayMan::~DisplayMan() {
 
 	delete[] _bitmapCeiling;
 	delete[] _bitmapFloor;
+	delete[] _bitmapWallSetD2L2;
+	delete[] _bitmapWallSetD2R2;
 	delete[] _bitmapWallSetD3L2;
 	delete[] _bitmapWallSetD3R2;
 	delete[] _bitmapWallSetD3LCR;
 	delete[] _bitmapWallSetD2LCR;
 	delete[] _bitmapWallSetD1LCR;
+	delete[] _bitmapWallSetD1L;
+	delete[] _bitmapWallSetD1R;
+	delete[] _bitmapWallSetD2L;
+	delete[] _bitmapWallSetD2R;
+	delete[] _bitmapWallSetD3L;
+	delete[] _bitmapWallSetD3R;
 	delete[] _bitmapWallSetWallD0L;
 	delete[] _bitmapWallSetWallD0R;
 	delete[] _bitmapWallSetDoorFrameTopD2LCR;
@@ -737,6 +753,24 @@ void DisplayMan::initializeGraphicData() {
 	_bitmapWallSetD3LCR = new byte[getPixelWidth(d3LcrIdx) * getPixelHeight(d3LcrIdx)];
 	_bitmapWallSetD2LCR = new byte[getPixelWidth(d2LcrIdx) * getPixelHeight(d2LcrIdx)];
 	_bitmapWallSetD1LCR = new byte[getPixelWidth(d1LcrIdx) * getPixelHeight(d1LcrIdx)];
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		int16 d1rIdx = firstWallSet + 9;
+		int16 d1lIdx = firstWallSet + 10;
+		int16 d2r2Idx = firstWallSet + 12;
+		int16 d2l2Idx = firstWallSet + 13;
+		int16 d2rIdx = firstWallSet + 14;
+		int16 d2lIdx = firstWallSet + 15;
+		int16 d3rIdx = firstWallSet + 19;
+		int16 d3lIdx = firstWallSet + 20;
+		_bitmapWallSetD1R = new byte[getPixelWidth(d1rIdx) * getPixelHeight(d1rIdx)];
+		_bitmapWallSetD1L = new byte[getPixelWidth(d1lIdx) * getPixelHeight(d1lIdx)];
+		_bitmapWallSetD2R2 = new byte[getPixelWidth(d2r2Idx) * getPixelHeight(d2r2Idx)];
+		_bitmapWallSetD2L2 = new byte[getPixelWidth(d2l2Idx) * getPixelHeight(d2l2Idx)];
+		_bitmapWallSetD2R = new byte[getPixelWidth(d2rIdx) * getPixelHeight(d2rIdx)];
+		_bitmapWallSetD2L = new byte[getPixelWidth(d2lIdx) * getPixelHeight(d2lIdx)];
+		_bitmapWallSetD3R = new byte[getPixelWidth(d3rIdx) * getPixelHeight(d3rIdx)];
+		_bitmapWallSetD3L = new byte[getPixelWidth(d3lIdx) * getPixelHeight(d3lIdx)];
+	}
 	_bitmapWallSetWallD0L = new byte[getPixelWidth(wallD0LIdx) * getPixelHeight(wallD0LIdx)];
 	_bitmapWallSetWallD0R = new byte[getPixelWidth(wallD0RIdx) * getPixelHeight(wallD0RIdx)];
 	_bitmapWallSetDoorFrameTopD2LCR = new byte[getPixelWidth(doorFrameTopD2LCRIdx) * getPixelHeight(doorFrameTopD2LCRIdx)];
@@ -1347,6 +1381,54 @@ bool DisplayMan::getBitmapDimensions(const byte *bitmap, uint16 &width, uint16 &
 		height = getPixelHeight(idx);
 		return true;
 	}
+	if (bitmap == _bitmapWallSetD1L) {
+		int16 idx = firstWallSet + 10;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD1R) {
+		int16 idx = firstWallSet + 9;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD2L2) {
+		int16 idx = firstWallSet + 13;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD2R2) {
+		int16 idx = firstWallSet + 12;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD2L) {
+		int16 idx = firstWallSet + 15;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD2R) {
+		int16 idx = firstWallSet + 14;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD3L) {
+		int16 idx = firstWallSet + 20;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
+	if (bitmap == _bitmapWallSetD3R) {
+		int16 idx = firstWallSet + 19;
+		width = getPixelWidth(idx);
+		height = getPixelHeight(idx);
+		return true;
+	}
 	return false;
 }
 
@@ -1812,17 +1894,21 @@ void DisplayMan::blitToScreen(byte *bitmap, const Box *box, int16 byteWidth, Col
 }
 
 void DisplayMan::drawWallSetBitmapWithoutTransparency(byte *bitmap, Frame &f) {
-	if (!f._srcByteWidth)
+	if (!bitmap || !f._srcByteWidth)
 		return;
 
-	blitToBitmap(bitmap, _bitmapViewport, f._box, f._srcX, f._srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorNoTransparency, f._srcHeight, k136_heightViewport);
+	uint16 srcX = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcX;
+	uint16 srcY = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcY;
+	blitToBitmap(bitmap, _bitmapViewport, f._box, srcX, srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorNoTransparency, f._srcHeight, k136_heightViewport);
 }
 
 void DisplayMan::drawWallSetBitmap(byte *bitmap, Frame &f) {
-	if (!f._srcByteWidth)
+	if (!bitmap || !f._srcByteWidth)
 		return;
 
-	blitToBitmap(bitmap, _bitmapViewport, f._box, f._srcX, f._srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
+	uint16 srcX = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcX;
+	uint16 srcY = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcY;
+	blitToBitmap(bitmap, _bitmapViewport, f._box, srcX, srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
 }
 
 
@@ -1862,7 +1948,7 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3L);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3L]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD3L : _bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD3LRight);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD3LFront))
 			order = kDMCellOrderAlcove;
@@ -1941,7 +2027,7 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3R);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3R]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD3R : _bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD3RLeft);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD3RFront))
 			order = kDMCellOrderAlcove;
@@ -2104,7 +2190,7 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2L); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2L]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD2L : _bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD2LRight);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD2LFront))
 			order = kDMCellOrderAlcove;
@@ -2189,7 +2275,7 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2R]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD2R : _bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD2RLeft);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD2RFront))
 			order = kDMCellOrderAlcove;
@@ -2359,7 +2445,7 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1L]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD1L : _bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD1LRight);
 		return;
 	case kDMElementTypeStairsSide:
@@ -2438,7 +2524,7 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1R]);
+		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD1R : _bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD1RLeft);
 		return;
 	case kDMElementTypeStairsSide:
@@ -2832,10 +2918,18 @@ void DisplayMan::loadWallSet(WallSet set) {
 		loadIntoBitmap(graphicIndice + 6, _bitmapWallSetDoorFrameTopD2LCR);
 		loadIntoBitmap(graphicIndice + 7, _bitmapWallSetWallD0R);   // C00_WALL_D0R (93)
 		loadIntoBitmap(graphicIndice + 8, _bitmapWallSetWallD0L);   // C01_WALL_D0L (94)
-		loadIntoBitmap(graphicIndice + 11, _bitmapWallSetD1LCR);   // C04_WALL_D1C (97)
-		loadIntoBitmap(graphicIndice + 16, _bitmapWallSetD2LCR);   // C09_WALL_D2C (102)
-		loadIntoBitmap(graphicIndice + 21, _bitmapWallSetD3LCR);   // C14_WALL_D3C (107)
-		loadIntoBitmap(graphicIndice + 18, _bitmapWallSetD3L2);    // C11_WALL_D3L2 (104)
+		loadIntoBitmap(graphicIndice + 9, _bitmapWallSetD1R);       // C02_WALL_D1R (95)
+		loadIntoBitmap(graphicIndice + 10, _bitmapWallSetD1L);      // C03_WALL_D1L (96)
+		loadIntoBitmap(graphicIndice + 11, _bitmapWallSetD1LCR);    // C04_WALL_D1C (97)
+		loadIntoBitmap(graphicIndice + 12, _bitmapWallSetD2R2);     // C05_WALL_D2R2 (98)
+		loadIntoBitmap(graphicIndice + 13, _bitmapWallSetD2L2);     // C06_WALL_D2L2 (99)
+		loadIntoBitmap(graphicIndice + 14, _bitmapWallSetD2R);      // C07_WALL_D2R (100)
+		loadIntoBitmap(graphicIndice + 15, _bitmapWallSetD2L);      // C08_WALL_D2L (101)
+		loadIntoBitmap(graphicIndice + 16, _bitmapWallSetD2LCR);    // C09_WALL_D2C (102)
+		loadIntoBitmap(graphicIndice + 18, _bitmapWallSetD3L2);     // C11_WALL_D3L2 (104)
+		loadIntoBitmap(graphicIndice + 19, _bitmapWallSetD3R);      // C12_WALL_D3R (105)
+		loadIntoBitmap(graphicIndice + 20, _bitmapWallSetD3L);      // C13_WALL_D3L (106)
+		loadIntoBitmap(graphicIndice + 21, _bitmapWallSetD3LCR);    // C14_WALL_D3C (107)
 	} else {
 		int16 graphicIndice = (set * k13_WallSetGraphicCount) + k77_FirstWallSet;
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameFront);
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 1c52ac0080b..259e24ce5e7 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -659,10 +659,18 @@ class DisplayMan {
 
 	byte *_bitmapFloor; // @ G0084_puc_Bitmap_Floor
 	byte *_bitmapCeiling; // @ G0085_puc_Bitmap_Ceiling
+	byte *_bitmapWallSetD2L2;
+	byte *_bitmapWallSetD2R2;
 	byte *_bitmapWallSetD3L2; // @ G0697_puc_Bitmap_WallSet_Wall_D3L2
 	byte *_bitmapWallSetD3R2; // @ G0696_puc_Bitmap_WallSet_Wall_D3R2
 	byte *_bitmapWallSetD3LCR; // @ G0698_puc_Bitmap_WallSet_Wall_D3LCR
 	byte *_bitmapWallSetD2LCR; // @ G0699_puc_Bitmap_WallSet_Wall_D2LCR
+	byte *_bitmapWallSetD1L;
+	byte *_bitmapWallSetD1R;
+	byte *_bitmapWallSetD2L;
+	byte *_bitmapWallSetD2R;
+	byte *_bitmapWallSetD3L;
+	byte *_bitmapWallSetD3R;
 public:
 	byte *_bitmapWallSetD1LCR; // @ G0700_puc_Bitmap_WallSet_Wall_D1LCR
 private:


Commit: 3042df79bd7e323f0415651a2799f089599ac034
    https://github.com/scummvm/scummvm/commit/3042df79bd7e323f0415651a2799f089599ac034
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Add layout records tables and coordinate traversal logic (DOS)

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 0328c411954..509998964d5 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -42,6 +42,356 @@
 
 namespace DM {
 
+namespace {
+
+// @ G3038_s_LayoutData23
+static const LayoutRecord g_layoutRecords23[] = {
+	{ 9, 2, 39, 29 }, { 2, 110, 319, 0 }, { 9, 111, 19, 14 }, { 1, 112, 0, 0 },
+	{ 1, 112, 20, 0 }, { 1, 112, 20, 15 }, { 1, 112, 0, 15 }
+};
+static const LayoutRange g_layoutData23 = { nullptr, 110, 116, g_layoutRecords23 };
+
+// @ G3037_s_LayoutData22
+static const LayoutRecord g_layoutRecords22[] = {
+	{ 9, 9, 28, 19 }, { 9, 9, 27, 19 }, { 9, 9, 28, 19 }, { 1, 65, 1, 1 },
+	{ 1, 67, 58, 1 }, { 1, 66, 30, 1 }, { 1, 67, 58, 21 }, { 1, 66, 30, 21 },
+	{ 1, 65, 1, 21 }
+};
+static const LayoutRange g_layoutData22 = { &g_layoutData23, 65, 73, g_layoutRecords22 };
+
+// @ G3036_s_LayoutData21
+static const LayoutRecord g_layoutRecords21[] = {
+	{ 10, 11, 0, 0 }, { 9, 11, 87, 51 }, { 2, 76, 86, 0 }, { 9, 11, 87, 30 },
+	{ 2, 78, 86, 0 }, { 1, 11, 2, 2 }, { 9, 11, 85, 20 }, { 1, 81, 1, 9 },
+	{ 1, 81, 1, 30 }, { 1, 81, 1, 51 }, { 10, 82, 0, 0 }, { 10, 83, 0, 0 },
+	{ 10, 84, 0, 0 }, { 9, 11, 20, 62 }, { 1, 88, 0, 9 }, { 1, 88, 22, 9 },
+	{ 1, 88, 44, 9 }, { 1, 88, 66, 9 }, { 10, 89, 0, 0 }, { 10, 90, 0, 0 },
+	{ 10, 91, 0, 0 }, { 10, 92, 0, 0 }, { 9, 11, 25, 7 }, { 2, 97, 86, 0 }
+};
+static const LayoutRange g_layoutData21 = { &g_layoutData22, 75, 98, g_layoutRecords21 };
+
+// @ G3035_s_LayoutData20
+static const LayoutRecord g_layoutRecords20[] = {
+	{ 9, 13, 87, 8 }, { 1, 220, 0, 0 }, { 9, 221, 45, 8 }, { 9, 221, 12, 7 },
+	{ 1, 222, 0, 0 }, { 1, 223, 47, 0 }, { 1, 223, 61, 0 }, { 1, 223, 75, 0 },
+	{ 18, 224, 2, 1 }, { 1, 223, 0, 0 }, { 1, 222, 14, 0 }, { 1, 223, 61, 0 },
+	{ 1, 223, 75, 0 }, { 18, 230, 2, 1 }, { 1, 223, 0, 0 }, { 1, 223, 14, 0 },
+	{ 1, 222, 28, 0 }, { 1, 223, 75, 0 }, { 18, 236, 2, 1 }, { 1, 223, 0, 0 },
+	{ 1, 223, 14, 0 }, { 1, 223, 28, 0 }, { 1, 222, 42, 0 }, { 18, 242, 2, 1 },
+	{ 9, 13, 13, 11 }, { 1, 244, 2, 9 }, { 1, 244, 16, 9 }, { 1, 244, 30, 9 },
+	{ 1, 244, 44, 9 }, { 1, 244, 58, 9 }, { 1, 244, 72, 9 }, { 9, 13, 70, 11 },
+	{ 1, 251, 1, 21 }, { 9, 13, 14, 11 }, { 1, 253, 72, 21 }, { 10, 245, 0, 0 },
+	{ 10, 246, 0, 0 }, { 10, 247, 0, 0 }, { 10, 248, 0, 0 }, { 10, 249, 0, 0 },
+	{ 10, 250, 0, 0 }, { 18, 252, 8, 0 }, { 18, 252, 17, 0 }, { 18, 252, 26, 0 },
+	{ 18, 252, 35, 0 }
+};
+static const LayoutRange g_layoutData20 = { &g_layoutData21, 220, 264, g_layoutRecords20 };
+
+// @ G3034_s_LayoutData19
+static const LayoutRecord g_layoutRecords19[] = {
+	{ 9, 0, 67, 29 }, { 1, 150, 0, 0 }, { 1, 150, 69, 0 }, { 1, 150, 138, 0 },
+	{ 1, 150, 207, 0 }, { 9, 151, 43, 7 }, { 9, 152, 43, 7 }, { 9, 153, 43, 7 },
+	{ 9, 154, 43, 7 }, { 1, 155, 0, 0 }, { 1, 156, 0, 0 }, { 1, 157, 0, 0 },
+	{ 1, 158, 0, 0 }, { 18, 159, 1, 0 }, { 18, 160, 1, 0 }, { 18, 161, 1, 0 },
+	{ 18, 162, 1, 0 }, { 10, 159, 0, 0 }, { 10, 160, 0, 0 }, { 10, 161, 0, 0 },
+	{ 10, 162, 0, 0 }, { 9, 151, 32, 29 }, { 9, 152, 32, 29 }, { 9, 153, 32, 29 },
+	{ 9, 154, 32, 29 }, { 1, 171, 7, 0 }, { 1, 172, 7, 0 }, { 1, 173, 7, 0 },
+	{ 1, 174, 7, 0 }, { 10, 175, 0, 0 }, { 10, 176, 0, 0 }, { 10, 177, 0, 0 },
+	{ 10, 178, 0, 0 }, { 9, 151, 24, 29 }, { 9, 152, 24, 29 }, { 9, 153, 24, 29 },
+	{ 9, 154, 24, 29 }, { 1, 183, 43, 0 }, { 1, 184, 43, 0 }, { 1, 185, 43, 0 },
+	{ 1, 186, 43, 0 }, { 9, 187, 4, 25 }, { 9, 188, 4, 25 }, { 9, 189, 4, 25 },
+	{ 9, 190, 4, 25 }, { 7, 191, 5, 26 }, { 7, 192, 5, 26 }, { 7, 193, 5, 26 },
+	{ 7, 194, 5, 26 }, { 7, 191, 12, 26 }, { 7, 192, 12, 26 }, { 7, 193, 12, 26 },
+	{ 7, 194, 12, 26 }, { 7, 191, 19, 26 }, { 7, 192, 19, 26 }, { 7, 193, 19, 26 },
+	{ 7, 194, 19, 26 }, { 9, 151, 16, 16 }, { 9, 152, 16, 16 }, { 9, 153, 16, 16 },
+	{ 9, 154, 16, 16 }, { 1, 207, 4, 0 }, { 1, 208, 4, 0 }, { 1, 209, 4, 0 },
+	{ 1, 210, 4, 0 }, { 10, 211, 0, 0 }, { 10, 212, 0, 0 }, { 10, 213, 0, 0 },
+	{ 10, 214, 0, 0 }
+};
+static const LayoutRange g_layoutData19 = { &g_layoutData20, 150, 218, g_layoutRecords19 };
+
+// @ G3033_s_LayoutData18
+static const LayoutRecord g_layoutRecords18[] = {
+	{ 1, 584, 7, 41 }, { 1, 584, 17, 41 }, { 1, 584, 27, 41 }, { 1, 584, 37, 41 },
+	{ 1, 584, 47, 41 }, { 1, 584, 57, 41 }, { 1, 584, 67, 41 }, { 1, 584, 77, 41 },
+	{ 1, 584, 87, 41 }, { 1, 584, 97, 41 }, { 1, 584, 107, 41 }, { 1, 584, 117, 41 },
+	{ 1, 584, 27, 51 }, { 1, 584, 37, 51 }, { 1, 584, 47, 51 }, { 1, 584, 57, 51 },
+	{ 1, 584, 67, 51 }, { 1, 584, 77, 51 }, { 1, 584, 87, 51 }, { 1, 584, 97, 51 },
+	{ 1, 584, 107, 51 }, { 1, 584, 117, 51 }
+};
+static const LayoutRange g_layoutData18 = { &g_layoutData19, 585, 606, g_layoutRecords18 };
+
+// @ G3032_s_LayoutData17
+static const LayoutRecord g_layoutRecords17[] = {
+	{ 9, 4, 144, 73 }, { 0, 100, 152, 89 }, { 9, 101, 95, 5 }, { 8, 102, 33, 25 },
+	{ 8, 102, 33, 50 }, { 9, 4, 16, 16 }, { 9, 101, 16, 16 }
+};
+static const LayoutRange g_layoutData17 = { &g_layoutData18, 100, 106, g_layoutRecords17 };
+
+// @ G3031_s_LayoutData16
+static const LayoutRecord g_layoutRecords16[] = {
+	{ 4, 4, 192, 7 }, { 1, 4, 0, 51 }, { 1, 4, 102, 89 }, { 1, 4, 102, 62 },
+	{ 9, 4, 192, 17 }, { 9, 4, 86, 17 }, { 1, 454, 16, 104 }, { 1, 454, 16, 67 },
+	{ 1, 455, 16, 67 }, { 1, 455, 123, 67 }, { 1, 455, 16, 104 }, { 1, 455, 123, 104 },
+	{ 10, 456, 0, 0 }, { 10, 457, 0, 0 }, { 10, 458, 0, 0 }, { 10, 459, 0, 0 },
+	{ 10, 460, 0, 0 }, { 10, 461, 0, 0 }, { 9, 4, 188, 73 }, { 0, 468, 112, 49 },
+	{ 9, 4, 188, 36 }, { 0, 470, 112, 32 }
+};
+static const LayoutRange g_layoutData16 = { &g_layoutData17, 450, 471, g_layoutRecords16 };
+
+// @ G3030_s_LayoutData15
+static const LayoutRecord g_layoutRecords15[] = {
+	{ 0, 4, 202, 43 }, { 0, 4, 141, 43 }, { 0, 4, 154, 45 }, { 0, 4, 171, 48 }
+};
+static const LayoutRange g_layoutData15 = { &g_layoutData16, 1950, 1953, g_layoutRecords15 };
+
+// @ G3029_s_LayoutData14
+static const LayoutRecord g_layoutRecords14[] = {
+	{ 1, 129, 0, 0 }, { 4, 129, 0, 10 }, { 4, 129, 0, 20 }, { 4, 129, 0, 30 },
+	{ 2, 129, 6, 0 }, { 2, 129, 12, 0 }, { 2, 129, 18, 0 }, { 1, 129, 42, 0 },
+	{ 1, 129, 36, 0 }, { 1, 129, 30, 0 }, { 1, 130, 0, 0 }, { 4, 130, 0, 10 },
+	{ 4, 130, 0, 20 }, { 4, 130, 0, 30 }, { 2, 130, 6, 0 }, { 2, 130, 12, 0 },
+	{ 2, 130, 18, 0 }, { 1, 130, 42, 0 }, { 1, 130, 36, 0 }, { 1, 130, 30, 0 },
+	{ 1, 131, 0, 0 }, { 4, 131, 0, 10 }, { 4, 131, 0, 20 }, { 4, 131, 0, 30 },
+	{ 2, 131, 6, 0 }, { 2, 131, 12, 0 }, { 2, 131, 18, 0 }, { 1, 131, 42, 0 },
+	{ 1, 131, 36, 0 }, { 1, 131, 30, 0 }, { 1, 132, 0, 0 }, { 4, 132, 0, 16 },
+	{ 4, 132, 0, 31 }, { 4, 132, 0, 46 }, { 2, 132, 8, 0 }, { 2, 132, 16, 0 },
+	{ 2, 132, 24, 0 }, { 1, 132, 56, 0 }, { 1, 132, 48, 0 }, { 1, 132, 40, 0 },
+	{ 1, 133, 0, 0 }, { 4, 133, 0, 16 }, { 4, 133, 0, 31 }, { 4, 133, 0, 46 },
+	{ 2, 133, 8, 0 }, { 2, 133, 16, 0 }, { 2, 133, 24, 0 }, { 1, 133, 56, 0 },
+	{ 1, 133, 48, 0 }, { 1, 133, 40, 0 }, { 1, 134, 0, 0 }, { 4, 134, 0, 16 },
+	{ 4, 134, 0, 31 }, { 4, 134, 0, 46 }, { 2, 134, 8, 0 }, { 2, 134, 16, 0 },
+	{ 2, 134, 24, 0 }, { 1, 134, 56, 0 }, { 1, 134, 48, 0 }, { 1, 134, 40, 0 },
+	{ 1, 135, 0, 0 }, { 4, 135, 0, 22 }, { 4, 135, 0, 44 }, { 4, 135, 0, 66 },
+	{ 2, 135, 12, 0 }, { 2, 135, 24, 0 }, { 2, 135, 36, 0 }, { 1, 135, 84, 0 },
+	{ 1, 135, 72, 0 }, { 1, 135, 60, 0 }, { 1, 136, 0, 0 }, { 4, 136, 0, 22 },
+	{ 4, 136, 0, 44 }, { 4, 136, 0, 66 }, { 2, 136, 12, 0 }, { 2, 136, 24, 0 },
+	{ 2, 136, 36, 0 }, { 1, 136, 84, 0 }, { 1, 136, 72, 0 }, { 1, 136, 60, 0 },
+	{ 1, 137, 0, 0 }, { 4, 137, 0, 22 }, { 4, 137, 0, 44 }, { 4, 137, 0, 66 },
+	{ 2, 137, 12, 0 }, { 2, 137, 24, 0 }, { 2, 137, 36, 0 }, { 1, 137, 84, 0 },
+	{ 1, 137, 72, 0 }, { 1, 137, 60, 0 }
+};
+static const LayoutRange g_layoutData14 = { &g_layoutData15, 3700, 3789, g_layoutRecords14 };
+
+// @ G3028_s_LayoutData13
+static const LayoutRecord g_layoutRecords13[] = {
+	{ 15, 123, 0, 13 }, { 15, 124, 0, 17 }, { 15, 125, 0, 22 }, { 10, 123, 0, 0 },
+	{ 10, 124, 0, -2 }, { 10, 125, 0, 0 }, { 17, 123, 6, -1 }, { 17, 124, 8, -8 },
+	{ 17, 125, 12, -8 }
+};
+static const LayoutRange g_layoutData13 = { &g_layoutData14, 2000, 2008, g_layoutRecords13 };
+
+// @ G3027_s_LayoutData12
+static const LayoutRecord g_layoutRecords12[] = {
+	{ 0, 4, 41, 69 }, { 0, 4, 112, 69 }, { 0, 4, 183, 69 }, { 0, 4, 21, 83 },
+	{ 0, 4, 112, 83 }, { 0, 4, 203, 83 }, { 8, 4, -13, 105 }, { 0, 4, 112, 105 },
+	{ 6, 4, 238, 105 }
+};
+static const LayoutRange g_layoutData12 = { &g_layoutData13, 1500, 1508, g_layoutRecords12 };
+
+// @ G3026_s_LayoutData11
+static const LayoutRecord g_layoutRecords11[] = {
+	{ 7, 4, 112, 54 }, { 7, 4, 112, 72 }, { 7, 4, 112, 89 }, { 7, 4, 112, 106 },
+	{ 0, 4, 82, 43 }, { 0, 4, 142, 43 }, { 0, 4, 23, 45 }, { 0, 4, 112, 45 },
+	{ 0, 4, 194, 45 }, { 0, 4, 72, 45 }, { 0, 4, 151, 45 }, { 0, 4, 6, 46 },
+	{ 0, 4, 112, 46 }, { 0, 4, 217, 46 }, { 0, 4, 56, 46 }, { 0, 4, 168, 46 },
+	{ 0, 4, 112, 50 }, { 0, 4, 78, 51 }, { 0, 4, 145, 51 }, { 0, 4, 24, 51 },
+	{ 0, 4, 112, 51 }, { 0, 4, 194, 51 }, { 0, 4, 69, 53 }, { 0, 4, 155, 53 },
+	{ 0, 4, 11, 56 }, { 0, 4, 112, 56 }, { 0, 4, 212, 56 }, { 0, 4, 48, 60 },
+	{ 0, 4, 176, 60 }, { 0, 4, 112, 64 }, { 7, 4, 82, 70 }, { 7, 4, 142, 70 },
+	{ 7, 4, 23, 75 }, { 7, 4, 112, 75 }, { 7, 4, 194, 75 }, { 7, 4, 72, 83 },
+	{ 7, 4, 151, 83 }, { 7, 4, 6, 90 }, { 7, 4, 112, 90 }, { 7, 4, 217, 90 },
+	{ 7, 4, 56, 102 }, { 7, 4, 168, 102 }, { 7, 4, 112, 119 }, { 0, 4, 82, 51 },
+	{ 0, 4, 142, 51 }, { 0, 4, 23, 56 }, { 0, 4, 112, 56 }, { 0, 4, 194, 56 },
+	{ 0, 4, 72, 58 }, { 0, 4, 151, 58 }, { 0, 4, 6, 64 }, { 0, 4, 112, 64 },
+	{ 0, 4, 217, 64 }, { 0, 4, 56, 67 }, { 0, 4, 168, 67 }, { 0, 4, 112, 78 },
+	{ 0, 4, 83, 42 }, { 0, 4, 141, 42 }, { 0, 4, 25, 47 }, { 0, 4, 112, 47 },
+	{ 0, 4, 195, 47 }, { 0, 4, 69, 44 }, { 0, 4, 155, 44 }, { 0, 4, 3, 47 },
+	{ 0, 4, 112, 47 }, { 0, 4, 216, 47 }, { 0, 4, 48, 58 }, { 0, 4, 176, 58 },
+	{ 0, 4, 112, 58 }, { 0, 4, 82, 44 }, { 0, 4, 142, 44 }, { 0, 4, 26, 44 },
+	{ 0, 4, 112, 44 }, { 0, 4, 195, 44 }, { 0, 4, 71, 46 }, { 0, 4, 153, 46 },
+	{ 0, 4, 5, 48 }, { 0, 4, 112, 48 }, { 0, 4, 215, 48 }, { 0, 4, 49, 49 },
+	{ 0, 4, 175, 49 }, { 0, 4, 112, 51 }, { 7, 4, 79, 75 }, { 7, 4, 146, 75 },
+	{ 7, 4, 36, 75 }, { 7, 4, 112, 75 }, { 7, 4, 187, 75 }, { 7, 4, 69, 90 },
+	{ 7, 4, 155, 90 }, { 7, 4, 8, 90 }, { 7, 4, 112, 90 }, { 7, 4, 214, 90 },
+	{ 7, 4, 49, 119 }, { 7, 4, 177, 119 }, { 7, 4, 112, 119 }, { 5, 4, 78, 38 },
+	{ 5, 4, 145, 38 }, { 5, 4, 24, 33 }, { 5, 4, 112, 33 }, { 5, 4, 194, 33 },
+	{ 5, 4, 67, 36 }, { 5, 4, 157, 36 }, { 5, 4, 11, 35 }, { 5, 4, 112, 35 },
+	{ 5, 4, 212, 35 }, { 5, 4, 49, 34 }, { 5, 4, 176, 34 }, { 5, 4, 112, 31 }
+};
+static const LayoutRange g_layoutData11 = { &g_layoutData12, 1000, 1107, g_layoutRecords11 };
+
+// @ G3025_s_LayoutData10
+static const LayoutRecord g_layoutRecords10[] = {
+	{ 0, 4, 112, 53 }, { 0, 4, 24, 53 }, { 0, 4, 194, 53 }, { 0, 4, 112, 59 },
+	{ 0, 4, 15, 59 }, { 0, 4, 208, 59 }, { 0, 4, 112, 70 }, { 0, 4, 112, 57 },
+	{ 0, 4, 24, 57 }, { 0, 4, 194, 57 }, { 0, 4, 112, 63 }, { 0, 4, 12, 63 },
+	{ 0, 4, 213, 63 }, { 0, 4, 112, 76 }, { 0, 4, 112, 47 }, { 0, 4, 57, 47 },
+	{ 0, 4, 167, 47 }, { 0, 4, 112, 50 }, { 0, 4, 45, 50 }, { 0, 4, 179, 50 },
+	{ 0, 4, 112, 53 }, { 0, 4, 20, 53 }, { 0, 4, 205, 53 }, { 0, 4, 112, 57 },
+	{ 0, 4, -30, 57 }, { 0, 4, 253, 57 }, { 0, 4, 112, 60 }, { 0, 4, -53, 60 },
+	{ 0, 4, 276, 60 }, { 0, 4, 100, 47 }, { 0, 4, 122, 47 }, { 0, 4, 52, 47 },
+	{ 0, 4, 76, 47 }, { 0, 4, 148, 47 }, { 0, 4, 172, 47 }, { 0, 4, 95, 50 },
+	{ 0, 4, 127, 50 }, { 0, 4, 42, 50 }, { 0, 4, 73, 50 }, { 0, 4, 150, 50 },
+	{ 0, 4, 181, 50 }, { 0, 4, 88, 53 }, { 0, 4, 134, 53 }, { 0, 4, 30, 53 },
+	{ 0, 4, 69, 53 }, { 0, 4, 154, 53 }, { 0, 4, 193, 53 }, { 0, 4, 77, 57 },
+	{ 0, 4, 145, 57 }, { 0, 4, 13, 57 }, { 0, 4, 62, 57 }, { 0, 4, 161, 57 },
+	{ 0, 4, 210, 57 }, { 0, 4, 66, 60 }, { 0, 4, 156, 60 }, { 0, 4, -6, 60 },
+	{ 0, 4, 54, 60 }, { 0, 4, 169, 60 }, { 0, 4, 229, 60 }
+};
+static const LayoutRange g_layoutData10 = { &g_layoutData11, 3000, 3058, g_layoutRecords10 };
+
+// @ G3024_s_LayoutData09
+static const LayoutRecord g_layoutRecords09[] = {
+	{ 1, 4, 105, 73 }, { 1, 4, 105, 90 }, { 1, 4, 70, 73 }, { 1, 4, 140, 73 },
+	{ 1, 4, 54, 90 }, { 1, 4, 156, 90 }, { 1, 4, 35, 107 }, { 1, 4, 175, 107 },
+	{ 1, 4, 6, 33 }, { 1, 4, 6, 73 }, { 1, 4, 62, 73 }, { 1, 4, 79, 73 },
+	{ 1, 4, 62, 90 }, { 1, 4, 79, 90 }, { 1, 4, 6, 33 }, { 1, 4, 6, 73 },
+	{ 1, 4, 62, 73 }, { 1, 4, 66, 33 }, { 1, 4, 83, 16 }, { 1, 4, 100, 16 },
+	{ 1, 4, 117, 16 }, { 1, 4, 134, 16 }, { 1, 4, 151, 16 }, { 1, 4, 168, 16 },
+	{ 1, 4, 185, 16 }, { 1, 4, 202, 16 }, { 1, 4, 83, 33 }, { 1, 4, 100, 33 },
+	{ 1, 4, 117, 33 }, { 1, 4, 134, 33 }, { 1, 4, 151, 33 }, { 1, 4, 168, 33 },
+	{ 1, 4, 185, 33 }, { 1, 4, 202, 33 }, { 1, 4, 37, 7 }, { 1, 4, 26, 24 },
+	{ 1, 4, 31, 41 }, { 1, 4, 48, 46 }, { 1, 4, 65, 49 }, { 1, 4, 82, 51 },
+	{ 1, 4, 99, 52 }, { 1, 4, 116, 53 }, { 1, 4, 56, 13 }, { 1, 4, 12, 13 },
+	{ 4, 4, 5, 116 }, { 4, 4, 5, 124 }, { 4, 4, 5, 132 }, { 3, 4, 95, 114 },
+	{ 3, 4, 95, 123 }, { 3, 4, 95, 132 }, { 4, 4, 3, 7 }, { 4, 4, 104, 132 },
+	{ 3, 4, 218, 132 }, { 4, 101, 28, 7 }, { 4, 101, 28, 6 }, { 4, 101, 28, 34 },
+	{ 4, 101, 94, 34 }, { 0, 101, 84, 35 }, { 9, 4, 11, 11 }, { 1, 561, 179, 2 },
+	{ 9, 4, 19, 11 }, { 1, 563, 190, 2 }, { 9, 4, 11, 11 }, { 1, 565, 209, 2 },
+	{ 9, 4, 114, 24 }, { 1, 569, 24, 29 }, { 9, 101, 114, 15 }, { 1, 572, 24, 57 },
+	{ 4, 101, 97, 6 }, { 4, 101, 25, 25 }, { 9, 101, 69, 9 }, { 1, 576, 27, 62 },
+	{ 9, 101, 19, 9 }, { 1, 578, 117, 62 }, { 9, 101, 9, 19 }, { 1, 580, 127, 41 },
+	{ 9, 101, 9, 9 }, { 1, 582, 27, 31 }, { 1, 582, 37, 31 }, { 1, 582, 47, 31 },
+	{ 1, 582, 57, 31 }, { 1, 582, 67, 31 }, { 1, 582, 77, 31 }, { 1, 582, 87, 31 },
+	{ 1, 582, 97, 31 }, { 1, 582, 107, 31 }, { 1, 582, 117, 31 }, { 1, 584, 7, 41 },
+	{ 1, 584, 17, 41 }, { 1, 584, 27, 41 }, { 1, 584, 37, 41 }, { 1, 584, 47, 41 },
+	{ 1, 584, 57, 41 }, { 1, 584, 67, 41 }, { 1, 584, 77, 41 }, { 1, 584, 87, 41 },
+	{ 1, 584, 97, 41 }, { 1, 584, 107, 41 }, { 1, 584, 117, 41 }, { 1, 584, 27, 51 },
+	{ 1, 584, 37, 51 }, { 1, 584, 47, 51 }, { 1, 584, 57, 51 }, { 1, 584, 67, 51 },
+	{ 1, 584, 77, 51 }, { 1, 584, 87, 51 }, { 1, 584, 97, 51 }, { 1, 584, 107, 51 },
+	{ 1, 584, 117, 51 }
+};
+static const LayoutRange g_layoutData09 = { &g_layoutData10, 500, 606, g_layoutRecords09 };
+
+// @ G3023_s_LayoutData08
+static const LayoutRecord g_layoutRecords08[] = {
+	{ 0, 4, 112, 107 }, { 0, 4, 54, 107 }, { 0, 4, 170, 107 }, { 0, 4, 112, 119 },
+	{ 0, 4, 32, 119 }, { 0, 4, 192, 119 }, { 0, 4, 112, 136 }, { 0, 4, 112, 110 },
+	{ 0, 4, 54, 110 }, { 0, 4, 170, 110 }, { 0, 4, 112, 122 }, { 0, 4, 28, 122 },
+	{ 0, 4, 196, 122 }, { 0, 4, 112, 136 }
+};
+static const LayoutRange g_layoutData08 = { &g_layoutData09, 850, 863, g_layoutRecords08 };
+
+// @ G3022_s_LayoutData07
+static const LayoutRecord g_layoutRecords07[] = {
+	{ 1, 4, 0, 0 }, { 1, 4, 112, 0 }, { 1, 4, 224, 0 }
+};
+static const LayoutRange g_layoutData07 = { &g_layoutData08, 900, 902, g_layoutRecords07 };
+
+// @ G3021_s_LayoutData06
+static const LayoutRecord g_layoutRecords06[] = {
+	{ 1, 4, 0, 0 }, { 1, 4, 224, 0 }, { 1, 4, 224, 136 }, { 1, 4, 0, 136 },
+	{ 1, 4, 112, 0 }, { 1, 4, 224, 68 }, { 1, 4, 112, 136 }, { 1, 4, 0, 68 }
+};
+static const LayoutRange g_layoutData06 = { &g_layoutData07, 950, 957, g_layoutRecords06 };
+
+// @ G3020_s_LayoutData05
+static const LayoutRecord g_layoutRecords05[] = {
+	{ 1, 4, 0, 0 }, { 1, 4, 0, 136 }
+};
+static const LayoutRange g_layoutData05 = { &g_layoutData06, 960, 961, g_layoutRecords05 };
+
+// @ G3019_s_LayoutData04
+static const LayoutRecord g_layoutRecords04[] = {
+	{ 11, 4, 0, 0 }, { 14, 4, 0, 0 }, { 11, 4, 0, 25 }, { 12, 4, 0, 25 },
+	{ 15, 4, 0, 25 }, { 11, 4, 0, 25 }, { 12, 4, 0, 25 }, { 15, 4, 0, 20 },
+	{ 11, 4, 0, 20 }, { 12, 4, 0, 20 }, { 15, 4, 0, 9 }, { 11, 4, 0, 9 },
+	{ 12, 4, 0, 9 }, { 1, 3, 0, 0 }, { 11, 4, 0, 0 }, { 12, 4, 0, 0 },
+	{ 11, 4, 12, 28 }, { 12, 4, -12, 28 }, { 15, 4, 0, 25 }, { 11, 4, 0, 25 },
+	{ 12, 4, 0, 25 }, { 15, 4, 0, 20 }, { 11, 4, 0, 20 }, { 12, 4, 0, 20 },
+	{ 15, 4, 0, 9 }, { 11, 4, 0, 9 }, { 12, 4, 0, 9 }, { 1, 3, 0, 0 },
+	{ 11, 4, 0, 0 }, { 12, 4, 0, 0 }, { 11, 4, 12, 28 }, { 12, 4, -12, 28 },
+	{ 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 },
+	{ 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 },
+	{ 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 }, { 1, 4, 0, 0 },
+	{ 1, 4, 0, 0 }, { 1, 4, 0, 0 }
+};
+static const LayoutRange g_layoutData04 = { &g_layoutData05, 700, 745, g_layoutRecords04 };
+
+// @ G3018_s_LayoutData03
+static const LayoutRecord g_layoutRecords03[] = {
+	{ 0, 4, 112, 41 }, { 0, 4, 43, 41 }, { 0, 4, 181, 41 }, { 0, 4, 112, 46 },
+	{ 0, 4, 21, 46 }, { 0, 4, 203, 46 }, { 0, 4, 112, 53 }, { 0, 4, 112, 44 },
+	{ 0, 4, 43, 44 }, { 0, 4, 181, 44 }, { 0, 4, 112, 48 }, { 0, 4, 18, 48 },
+	{ 0, 4, 206, 48 }, { 0, 4, 112, 56 }
+};
+static const LayoutRange g_layoutData03 = { &g_layoutData04, 800, 813, g_layoutRecords03 };
+
+// @ G3017_s_LayoutData02
+static const LayoutRecord g_layoutRecords02[] = {
+	{ 0, 4, 112, 67 }, { 0, 4, 79, 67 }, { 0, 4, 145, 67 }, { 0, 4, 112, 70 },
+	{ 0, 4, 60, 70 }, { 0, 4, 164, 70 }, { 0, 4, 112, 74 }, { 0, 4, 30, 74 },
+	{ 0, 4, 194, 74 }, { 0, 4, 112, 80 }, { 0, 4, 112, 69 }, { 0, 4, 78, 69 },
+	{ 0, 4, 146, 69 }, { 0, 4, 112, 71 }, { 0, 4, 59, 71 }, { 0, 4, 165, 71 },
+	{ 0, 4, 112, 75 }, { 0, 4, 27, 75 }, { 0, 4, 197, 75 }, { 0, 4, 112, 83 },
+	{ 0, 4, -13, 105 }, { 0, 4, 112, 105 }, { 0, 4, 238, 105 }, { 0, 4, -20, 105 },
+	{ 0, 4, 112, 105 }, { 0, 4, 244, 105 }, { 0, 4, 112, 105 }, { 0, 4, -13, 105 },
+	{ 0, 4, 238, 105 }, { 0, 4, -20, 105 }, { 0, 4, 112, 105 }, { 0, 4, 244, 105 },
+	{ 0, 4, 112, 105 }, { 0, 4, -13, 105 }, { 0, 4, 238, 105 }, { 0, 4, -20, 105 },
+	{ 0, 4, 112, 105 }, { 0, 4, 244, 105 }, { 0, 4, 112, 105 }, { 0, 4, 112, 67 },
+	{ 0, 4, 79, 67 }, { 0, 4, 145, 67 }, { 0, 4, 112, 70 }, { 0, 4, 60, 70 },
+	{ 0, 4, 164, 70 }, { 0, 4, 112, 74 }, { 0, 4, 30, 74 }, { 0, 4, 194, 74 },
+	{ 0, 4, 112, 80 }, { 0, 4, 112, 69 }, { 0, 4, 78, 69 }, { 0, 4, 146, 69 },
+	{ 0, 4, 112, 71 }, { 0, 4, 59, 71 }, { 0, 4, 165, 71 }, { 0, 4, 112, 75 },
+	{ 0, 4, 27, 75 }, { 0, 4, 197, 75 }, { 0, 4, 112, 83 }, { 0, 4, -13, 105 },
+	{ 0, 4, 112, 105 }, { 0, 4, 238, 105 }, { 0, 4, -20, 105 }, { 0, 4, 112, 105 },
+	{ 0, 4, 244, 105 }, { 0, 4, 112, 105 }, { 0, 4, -13, 105 }, { 0, 4, 238, 105 },
+	{ 0, 4, -20, 105 }, { 0, 4, 112, 105 }, { 0, 4, 244, 105 }, { 0, 4, 112, 105 },
+	{ 0, 4, -13, 105 }, { 0, 4, 238, 105 }, { 0, 4, -20, 105 }, { 0, 4, 112, 105 },
+	{ 0, 4, 244, 105 }, { 0, 4, 112, 105 }
+};
+static const LayoutRange g_layoutData02 = { &g_layoutData03, 850, 927, g_layoutRecords02 };
+
+// @ G3016_s_LayoutData01
+static const LayoutRecord g_layoutRecords01[] = {
+	{ 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 9, 0, 224, 136 }, { 1, 3, 0, 0 },
+	{ 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 },
+	{ 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 },
+	{ 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 },
+	{ 1, 0, 0, 0 }
+};
+static const LayoutRange g_layoutData01 = { &g_layoutData02, 1, 17, g_layoutRecords01 };
+
+// @ G2002_NegativeBitmaps
+static const Struct3 g_defaultNegativeBitmaps[45] = {
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 1, 0, 50, 0, 7, 0, { 0 } },
+	{ 1, 0, 6, 0, 7, 0, { 0 } }, { 1, 0, 62, 0, 7, 0, { 0 } },
+	{ 1, 0, 6, 0, 7, 0, { 0 } }, { 2, 0, 7, 0, 4, 0, { 0 } },
+	{ 2, 0, 6, 0, 4, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 16, 0, 60, 0, { 0 } },
+	{ 2, 0, 0, 0, 0, 0, { 0 } }, { 2, 0, 16, 0, 60, 0, { 0 } },
+	{ 2, 0, 16, 0, 32, 0, { 0 } }, { 2, 0, 0, 0, 0, 0, { 0 } },
+	{ 2, 0, 16, 0, 32, 0, { 0 } }, { 2, 0, 90, 28, 4, 26, { 0 } },
+	{ 1, 0, 32, 0, 32, 0, { kDMGraphicIdxHoleInWall } },
+	{ 2, 0, 64, 19, 96, 95, { 0 } }, { 2, 0, 0, 14, 0, 75, { 0 } },
+	{ 2, 0, 102, 52, 21, 37, { 0 } }, { 2, 0, 102, 99, 21, 36, { 0 } },
+	{ 1, 0, 168, 3, 9, 9, { kDMGraphicIdxInventory } },
+	{ 2, 0, 0, 137, 0, 16, { 0 } }, { 2, 0, 0, 0, 0, 80, { 0 } },
+	{ 2, 0, 0, 80, 0, 57, { 0 } }
+};
+}
+
 FieldAspect::FieldAspect(uint16 native, uint16 base, uint16 transparent, byte mask, uint16 byteWidth, uint16 height, uint16 xPos, uint16 bitplane)
 	: _nativeBitmapRelativeIndex(native), _baseStartUnitIndex(base), _transparentColor(transparent), _mask(mask),
 	_byteWidth(byteWidth), _height(height), _xPos(xPos), _bitplaneWordCount(bitplane) {}
@@ -83,6 +433,7 @@ DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) {
 	_championPortraitOrdinal = 0;
 	_currMapViAltarIndex = 0;
 	_drawFloorAndCeilingRequested = true;
+	memcpy(_negativeBitmaps, g_defaultNegativeBitmaps, sizeof(_negativeBitmaps));
 
 	for (int i = 0; i < 4; i++)
 		_palChangesProjectile[i] = nullptr;
@@ -2236,6 +2587,333 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 		drawField(&_fieldAspects188[kDMViewSquareD2L], _frameWalls163[kDMViewSquareD2L]._box);
 }
 
+const LayoutRecord *DisplayMan::getLayoutRecord(int16 layoutRecordIndex) {
+	if (!layoutRecordIndex)
+		return nullptr;
+
+	const LayoutRange *range = &g_layoutData01;
+	while (range) {
+		if (range->_firstIndex <= layoutRecordIndex && range->_lastIndex >= layoutRecordIndex)
+			return &range->_records[layoutRecordIndex - range->_firstIndex];
+		range = range->_nextRange;
+	}
+	return nullptr;
+}
+
+byte *DisplayMan::initBitmapStruct2(int16 graphicIndex, Struct2 *outStruct) {
+	byte *bitmap = nullptr;
+	if (graphicIndex < 0) {
+		int16 idx = -1 - graphicIndex;
+		if (idx >= 0 && idx < 45) {
+			const Struct3 &s3 = _negativeBitmaps[idx];
+			outStruct->_x = s3._x;
+			outStruct->_y = s3._y;
+			if (s3._s3m1 == 1)
+				bitmap = getNativeBitmapOrGraphic(s3._s3u._graphicIndex);
+			else
+				bitmap = s3._s3u._bitmap;
+
+			uint16 w = 0, h = 0;
+			if (bitmap)
+				getBitmapDimensions(bitmap, w, h);
+
+			outStruct->_width = s3._width ? s3._width : w;
+			outStruct->_height = s3._height ? s3._height : h;
+		}
+	} else {
+		outStruct->_x = 0;
+		outStruct->_y = 0;
+		bitmap = getNativeBitmapOrGraphic(graphicIndex);
+		uint16 w = 0, h = 0;
+		if (bitmap)
+			getBitmapDimensions(bitmap, w, h);
+		outStruct->_width = w;
+		outStruct->_height = h;
+	}
+	outStruct->_s2m1 = bitmap;
+	return bitmap;
+}
+
+int16 *DisplayMan::getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16 *inOutX, int16 *inOutY) {
+	if (zoneIndex == -1 || !outXYZ)
+		return nullptr;
+
+	const LayoutRecord *rec = getLayoutRecord(zoneIndex);
+	if (!rec)
+		return nullptr;
+
+	int16 parentXYZ[4] = { 0, 0, 20000, 20000 };
+	int16 recType = rec->_recordType;
+	int16 xOffset = 0, yOffset = 0;
+
+	if (recType <= 8) {
+		xOffset = rec->_data1;
+		yOffset = rec->_data2;
+	} else {
+		if (recType == 9)
+			return nullptr;
+		recType -= 10;
+		xOffset = 0;
+		yOffset = 0;
+	}
+
+	if (inOutX && inOutY && (*inOutX || *inOutY)) {
+		xOffset += *inOutX;
+		yOffset += *inOutY;
+		*inOutX = 0;
+		*inOutY = 0;
+	}
+
+	bool flag = false;
+	const LayoutRecord *currentRec = rec;
+
+	while (currentRec->_parentRecordIndex) {
+		const LayoutRecord *parentRec = getLayoutRecord(currentRec->_parentRecordIndex);
+		if (!parentRec)
+			break;
+
+		if (currentRec->_recordType >= 10 && currentRec->_recordType <= 18) {
+			int16 data1 = parentRec->_data1;
+			int16 data2 = parentRec->_data2;
+			int16 parentRecType = parentRec->_recordType;
+
+			const LayoutRecord *grandParent = getLayoutRecord(parentRec->_parentRecordIndex);
+			if (!grandParent)
+				break;
+
+			switch (parentRecType) {
+			case 0:
+				data2 -= ((grandParent->_data2 + 1) >> 1);
+			case 5:
+				data1 -= ((grandParent->_data1 + 1) >> 1);
+				break;
+			case 3:
+				data2 -= (grandParent->_data2 - 1);
+			case 2:
+				data1 -= (grandParent->_data1 - 1);
+				break;
+			case 6:
+				data1 -= (grandParent->_data1 - 1);
+			case 8:
+				data2 -= ((grandParent->_data2 + 1) >> 1);
+				break;
+			case 7:
+				data1 -= ((grandParent->_data1 + 1) >> 1);
+			case 4:
+				data2 -= (grandParent->_data2 - 1);
+				break;
+			case 1:
+				break;
+			default:
+				return nullptr;
+			}
+
+			if ((parentXYZ[0] += data1) < data1)
+				parentXYZ[0] = data1;
+			if (parentXYZ[0] + parentXYZ[2] >= grandParent->_data1 + data1)
+				parentXYZ[2] = grandParent->_data1 - parentXYZ[0] + data1;
+
+			if ((parentXYZ[1] += data2) < data2)
+				parentXYZ[1] = data2;
+			if (parentXYZ[1] + parentXYZ[3] >= grandParent->_data2 + data2)
+				parentXYZ[3] = grandParent->_data2 - parentXYZ[1] + data2;
+
+			switch (currentRec->_recordType) {
+			case 10:
+				data2 += ((grandParent->_data2 + 1) >> 1);
+			case 15:
+				data1 += ((grandParent->_data1 + 1) >> 1);
+				break;
+			case 13:
+				data2 += (grandParent->_data2 - 1);
+			case 12:
+				data1 += (grandParent->_data1 - 1);
+				break;
+			case 16:
+				data1 += (grandParent->_data1 - 1);
+			case 18:
+				data2 += ((grandParent->_data2 + 1) >> 1);
+				break;
+			case 17:
+				data1 += ((grandParent->_data1 + 1) >> 1);
+			case 14:
+				data2 += (grandParent->_data2 - 1);
+				break;
+			case 11:
+				break;
+			default:
+				return nullptr;
+			}
+
+			xOffset += data1 + currentRec->_data1;
+			yOffset += data2 + currentRec->_data2;
+			currentRec = grandParent;
+		} else {
+			int16 data1 = parentRec->_data1;
+			int16 data2 = parentRec->_data2;
+
+			if (parentRec->_recordType == 1) {
+				xOffset += data1;
+				yOffset += data2;
+				parentXYZ[0] += data1;
+				parentXYZ[1] += data2;
+			} else if (parentRec->_recordType == 9) {
+				switch (currentRec->_recordType) {
+				case 0:
+					data1 = currentRec->_data1 - ((data1 + 1) >> 1);
+					data2 = currentRec->_data2 - ((data2 + 1) >> 1);
+					break;
+				case 1:
+					data1 = currentRec->_data1;
+					data2 = currentRec->_data2;
+					break;
+				case 2:
+					data1 = currentRec->_data1 - (data1 - 1);
+					data2 = currentRec->_data2;
+					break;
+				case 3:
+					data1 = currentRec->_data1 - (data1 - 1);
+					data2 = currentRec->_data2 - (data2 - 1);
+					break;
+				case 4:
+					data1 = currentRec->_data1;
+					data2 = currentRec->_data2 - (data2 - 1);
+					break;
+				case 5:
+					data1 = currentRec->_data1 - ((data1 + 1) >> 1);
+					data2 = currentRec->_data2;
+					break;
+				case 6:
+					data1 = currentRec->_data1 - (data1 - 1);
+					data2 = currentRec->_data2 - ((data2 + 1) >> 1);
+					break;
+				case 7:
+					data1 = currentRec->_data1 - ((data1 + 1) >> 1);
+					data2 = currentRec->_data2 - (data2 - 1);
+					break;
+				case 8:
+					data1 = currentRec->_data1;
+					data2 = currentRec->_data2 - ((data2 + 1) >> 1);
+					break;
+				default:
+					break;
+				}
+
+				if (flag) {
+					flag = false;
+					xOffset += data1;
+					yOffset += data2;
+					parentXYZ[0] += data1;
+					parentXYZ[1] += data2;
+				}
+				if (parentXYZ[0] < data1)
+					parentXYZ[0] = data1;
+				if (parentXYZ[0] + parentXYZ[2] >= parentRec->_data1 + data1)
+					parentXYZ[2] = parentRec->_data1 - parentXYZ[0] + data1;
+
+				if (parentXYZ[1] < data2)
+					parentXYZ[1] = data2;
+				if (parentXYZ[1] + parentXYZ[3] >= parentRec->_data2 + data2)
+					parentXYZ[3] = parentRec->_data2 - parentXYZ[1] + data2;
+			} else {
+				if (parentRec->_recordType <= 8)
+					flag = true;
+			}
+			currentRec = parentRec;
+		}
+	}
+
+	uint16 headerW = 0, headerH = 0;
+	if (bitmap)
+		getBitmapDimensions(bitmap, headerW, headerH);
+
+	int16 bmpWidth = (inOutX && *inOutX) ? *inOutX : (int16)headerW;
+	int16 bmpHeight = (inOutY && *inOutY) ? *inOutY : (int16)headerH;
+
+	switch (recType) {
+	case 0:
+		outXYZ[0] = xOffset - ((bmpWidth + 1) >> 1);
+		outXYZ[1] = yOffset - ((bmpHeight + 1) >> 1);
+		break;
+	case 1:
+		outXYZ[0] = xOffset;
+		outXYZ[1] = yOffset;
+		break;
+	case 2:
+		outXYZ[0] = xOffset - (bmpWidth - 1);
+		outXYZ[1] = yOffset;
+		break;
+	case 3:
+		outXYZ[0] = xOffset - (bmpWidth - 1);
+		outXYZ[1] = yOffset - (bmpHeight - 1);
+		break;
+	case 4:
+		outXYZ[0] = xOffset;
+		outXYZ[1] = yOffset - (bmpHeight - 1);
+		break;
+	case 5:
+		outXYZ[0] = xOffset - ((bmpWidth + 1) >> 1);
+		outXYZ[1] = yOffset;
+		break;
+	case 6:
+		outXYZ[0] = xOffset - (bmpWidth - 1);
+		outXYZ[1] = yOffset - ((bmpHeight + 1) >> 1);
+		break;
+	case 7:
+		outXYZ[0] = xOffset - ((bmpWidth + 1) >> 1);
+		outXYZ[1] = yOffset - (bmpHeight - 1);
+		break;
+	case 8:
+		outXYZ[0] = xOffset;
+		outXYZ[1] = yOffset - ((bmpHeight + 1) >> 1);
+		break;
+	default:
+		return nullptr;
+	}
+
+	int16 clipX = parentXYZ[0] - outXYZ[0];
+	int16 clipY = parentXYZ[1] - outXYZ[1];
+
+	if (clipX <= 0) {
+		if (inOutX)
+			*inOutX = 0;
+		outXYZ[2] = MIN((int16)bmpWidth, (int16)(parentXYZ[2] + clipX));
+	} else {
+		if (inOutX)
+			*inOutX = clipX;
+		outXYZ[0] = parentXYZ[0];
+		outXYZ[2] = MIN((int16)(bmpWidth - clipX), parentXYZ[2]);
+	}
+
+	if (clipY <= 0) {
+		if (inOutY)
+			*inOutY = 0;
+		outXYZ[3] = MIN((int16)bmpHeight, (int16)(parentXYZ[3] + clipY));
+	} else {
+		if (inOutY)
+			*inOutY = clipY;
+		outXYZ[1] = parentXYZ[1];
+		outXYZ[3] = MIN((int16)(bmpHeight - clipY), parentXYZ[3]);
+	}
+
+	if (outXYZ[2] <= 0 || outXYZ[3] <= 0)
+		return nullptr;
+
+	return outXYZ;
+}
+
+bool DisplayMan::getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox) {
+	Struct2 s2;
+	byte *bmp = initBitmapStruct2(graphicIndex, &s2);
+	int16 xyz[4] = { 0, 0, 0, 0 };
+
+	if (!getCoord(bmp, xyz, zoneIndex, &s2._width, &s2._height))
+		return false;
+
+	outBox = Box(xyz[0], xyz[0] + xyz[2] - 1, xyz[1], xyz[1] + xyz[3] - 1);
+	return true;
+}
+
 void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 	static Frame doorFrameTopD2R = Frame(164, 223, 22, 24, 48, 3, 16, 0); // @ G0175_s_Graphic558_Frame_DoorFrameTop_D2R
 	static Frame frameStairsUpFrontD2R = Frame(160, 223, 22, 83, 32, 62, 0, 0); // @ G0115_s_Graphic558_Frame_StairsUpFront_D2R
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 259e24ce5e7..ca4abdd6266 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -57,6 +57,41 @@ enum DoorState {
 	kDMDoorStateDestroyed = 5    // @ C5_DOOR_STATE_DESTROYED
 };
 
+struct LayoutRecord {
+	uint16 _recordType;
+	int16 _parentRecordIndex;
+	int16 _data1;
+	int16 _data2;
+};
+
+struct LayoutRange {
+	const LayoutRange *_nextRange;
+	int16 _firstIndex;
+	int16 _lastIndex;
+	const LayoutRecord *_records;
+};
+
+struct Struct3 {
+	uint8 _s3m1; // Type: 1: graphic index, 2: bitmap pointer
+	int8 _s3m2;
+	int16 _x;
+	int16 _y;
+	int16 _width;
+	int16 _height;
+	union {
+		int16 _graphicIndex;
+		byte *_bitmap;
+	} _s3u;
+};
+
+struct Struct2 {
+	byte *_s2m1; // Bitmap pointer
+	int16 _x;
+	int16 _y;
+	int16 _width;
+	int16 _height;
+};
+
 enum DoorOrnament {
 	kDMDoorOrnamentD3LCR = 0, // @ C0_VIEW_DOOR_ORNAMENT_D3LCR
 	kDMDoorOrnamentD2LCR = 1, // @ C1_VIEW_DOOR_ORNAMENT_D2LCR
@@ -618,6 +653,12 @@ class DisplayMan {
 	void drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &frame); // @ F0104_DUNGEONVIEW_DrawFloorPitOrStairsBitmap
 	void drawWallSetBitmap(byte *bitmap, Frame &f); // @ F0100_DUNGEONVIEW_DrawWallSetBitmap
 	void drawWallSetBitmapWithoutTransparency(byte *bitmap, Frame &f); // @ F0101_DUNGEONVIEW_DrawWallSetBitmapWithoutTransparency
+
+	// DOS Layout Tree Engine (GET_COORD)
+	const LayoutRecord *getLayoutRecord(int16 layoutRecordIndex); // @ F0634_GetLayoutRecord
+	byte *initBitmapStruct2(int16 graphicIndex, Struct2 *outStruct); // @ F0630_InitBitmapStruct2
+	int16 *getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16 *inOutX, int16 *inOutY); // @ F0635_
+	bool getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox);
 	void drawSquareD3L(Direction dir, int16 posX, int16 posY); // @ F0116_DUNGEONVIEW_DrawSquareD3L
 	void drawSquareD3R(Direction dir, int16 posX, int16 posY); // @ F0117_DUNGEONVIEW_DrawSquareD3R
 	void drawSquareD3C(Direction dir, int16 posX, int16 posY); // @ F0118_DUNGEONVIEW_DrawSquareD3C_CPSF
@@ -635,6 +676,7 @@ class DisplayMan {
 
 	bool isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex); // @ F0107_DUNGEONVIEW_IsDrawnWallOrnamentAnAlcove_CPSF
 
+	Struct3 _negativeBitmaps[45]; // @ G2002_NegativeBitmaps
 	uint16 *_derivedBitmapByteCount; // @ G0639_pui_DerivedBitmapByteCount
 	byte **_derivedBitmaps; // @ G0638_pui_DerivedBitmapBlockIndices
 


Commit: eb72c689d229ae3c6f034552bed45bff46c03b57
    https://github.com/scummvm/scummvm/commit/eb72c689d229ae3c6f034552bed45bff46c03b57
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Integrate DOS layout system with dungeon view rendering

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 509998964d5..5a544d7fdfa 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -468,6 +468,8 @@ DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) {
 
 	_inscriptionThing = _vm->_thingNone;
 	_useByteBoxCoordinates = false;
+	memcpy(_negativeBitmaps, g_defaultNegativeBitmaps, sizeof(_negativeBitmaps));
+	_dosLayoutData = nullptr;
 
 	_bitmapWallSetD2L2 = nullptr;
 	_bitmapWallSetD2R2 = nullptr;
@@ -1022,6 +1024,10 @@ DisplayMan::~DisplayMan() {
 
 	delete[] _bitmapCeiling;
 	delete[] _bitmapFloor;
+	for (uint i = 0; i < _dosLayoutRangeAllocs.size(); i++) {
+		delete[] _dosLayoutRangeAllocs[i]->_records;
+		delete _dosLayoutRangeAllocs[i];
+	}
 	delete[] _bitmapWallSetD2L2;
 	delete[] _bitmapWallSetD2R2;
 	delete[] _bitmapWallSetD3L2;
@@ -1308,6 +1314,10 @@ void DisplayMan::loadGraphics() {
 
 	f.close();
 	unpackGraphics();
+
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		loadLayoutData(696); // C696_GRAPHIC_LAYOUT
+	}
 }
 
 void DisplayMan::unpackGraphics() {
@@ -2299,7 +2309,10 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3L);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD3L : _bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3L]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD3L, kDMNegGraphicWallD3L, kDMNegGraphicWallD3R);
+		else
+			drawWallSetBitmap(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD3LRight);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD3LFront))
 			order = kDMCellOrderAlcove;
@@ -2378,7 +2391,10 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3R);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD3R : _bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3R]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD3R, kDMNegGraphicWallD3R, kDMNegGraphicWallD3L);
+		else
+			drawWallSetBitmap(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD3RLeft);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD3RFront))
 			order = kDMCellOrderAlcove;
@@ -2463,7 +2479,10 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3C); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmapWithoutTransparency(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3C]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD3C, kDMNegGraphicWallD3C, kDMNegGraphicWallD3C, true);
+		else
+			drawWallSetBitmapWithoutTransparency(_bitmapWallSetD3LCR, _frameWalls163[kDMViewSquareD3C]);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD3CFront))
 			order = kDMCellOrderAlcove;
 		else
@@ -2541,7 +2560,10 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2L); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD2L : _bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2L]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD2L, kDMNegGraphicWallD2L, kDMNegGraphicWallD2R);
+		else
+			drawWallSetBitmap(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD2LRight);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD2LFront))
 			order = kDMCellOrderAlcove;
@@ -2587,10 +2609,91 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 		drawField(&_fieldAspects188[kDMViewSquareD2L], _frameWalls163[kDMViewSquareD2L]._box);
 }
 
+void DisplayMan::loadLayoutData(uint16 graphicIndex) {
+	if (graphicIndex >= _grapItemCount)
+		return;
+
+	uint8 *rawData = _packedBitmaps + _packedItemPos[graphicIndex];
+	uint32 dataSize = _bitmapDecompressedByteCount[graphicIndex];
+	uint8 *data = rawData;
+	uint32 remaining = dataSize;
+
+	if (remaining < 4)
+		return;
+	uint16 magic = READ_LE_UINT16(data);
+	data += 2;
+	if (magic != 0xFC0D) {
+		warning("DisplayMan::loadLayoutData: bad magic 0x%04X (expected 0xFC0D)", magic);
+		return;
+	}
+	uint16 rangeCount = READ_LE_UINT16(data); data += 2;
+
+	// Read range index pairs
+	uint16 *firstIndices = new uint16[rangeCount];
+	uint16 *lastIndices = new uint16[rangeCount];
+	for (uint16 i = 0; i < rangeCount; i++) {
+		firstIndices[i] = READ_LE_UINT16(data); data += 2;
+		lastIndices[i] = READ_LE_UINT16(data); data += 2;
+	}
+
+	if (!_dosLayoutData) {
+		_dosLayoutData = new DynLayoutRange();
+		_dosLayoutData->_nextRange = nullptr;
+		_dosLayoutData->_firstIndex = 0;
+		_dosLayoutData->_lastIndex = -1;
+		_dosLayoutData->_records = nullptr;
+		_dosLayoutRangeAllocs.push_back(_dosLayoutData);
+	}
+
+	DynLayoutRange *tail = _dosLayoutData;
+	while (tail->_nextRange)
+		tail = tail->_nextRange;
+
+	for (uint16 r = 0; r < rangeCount; r++) {
+		int16 firstIdx = (int16)firstIndices[r];
+		int16 lastIdx = (int16)lastIndices[r];
+		int recordCount = lastIdx - firstIdx + 1;
+		if (recordCount <= 0)
+			continue;
+
+		DynLayoutRange *range = new DynLayoutRange();
+		range->_nextRange = nullptr;
+		range->_firstIndex = firstIdx;
+		range->_lastIndex = lastIdx;
+		range->_records = new LayoutRecord[recordCount];
+
+		for (int i = 0; i < recordCount; i++) {
+			range->_records[i]._recordType = (uint16)READ_LE_INT16(data); data += 2;
+			range->_records[i]._parentRecordIndex = READ_LE_INT16(data); data += 2;
+			range->_records[i]._data1 = READ_LE_INT16(data); data += 2;
+			range->_records[i]._data2 = READ_LE_INT16(data); data += 2;
+		}
+
+		tail->_nextRange = range;
+		tail = range;
+		_dosLayoutRangeAllocs.push_back(range);
+	}
+
+	delete[] firstIndices;
+	delete[] lastIndices;
+}
+
 const LayoutRecord *DisplayMan::getLayoutRecord(int16 layoutRecordIndex) {
 	if (!layoutRecordIndex)
 		return nullptr;
 
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		if (!_dosLayoutData)
+			return nullptr;
+		DynLayoutRange *range = _dosLayoutData;
+		while (range) {
+			if (range->_firstIndex <= layoutRecordIndex && range->_lastIndex >= layoutRecordIndex)
+				return &range->_records[layoutRecordIndex - range->_firstIndex];
+			range = range->_nextRange;
+		}
+		return nullptr;
+	}
+
 	const LayoutRange *range = &g_layoutData01;
 	while (range) {
 		if (range->_firstIndex <= layoutRecordIndex && range->_lastIndex >= layoutRecordIndex)
@@ -2638,6 +2741,9 @@ int16 *DisplayMan::getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16
 	if (zoneIndex == -1 || !outXYZ)
 		return nullptr;
 
+	bool shiftObjectsAndCreatures = (zoneIndex & 0x8000) != 0;
+	zoneIndex &= ~0x8000;
+
 	const LayoutRecord *rec = getLayoutRecord(zoneIndex);
 	if (!rec)
 		return nullptr;
@@ -2657,7 +2763,7 @@ int16 *DisplayMan::getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16
 		yOffset = 0;
 	}
 
-	if (inOutX && inOutY && (*inOutX || *inOutY)) {
+	if (shiftObjectsAndCreatures && inOutX && inOutY) {
 		xOffset += *inOutX;
 		yOffset += *inOutY;
 		*inOutX = 0;
@@ -2710,12 +2816,12 @@ int16 *DisplayMan::getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16
 
 			if ((parentXYZ[0] += data1) < data1)
 				parentXYZ[0] = data1;
-			if (parentXYZ[0] + parentXYZ[2] >= grandParent->_data1 + data1)
+			if (parentXYZ[0] + parentXYZ[2] > grandParent->_data1 + data1)
 				parentXYZ[2] = grandParent->_data1 - parentXYZ[0] + data1;
 
 			if ((parentXYZ[1] += data2) < data2)
 				parentXYZ[1] = data2;
-			if (parentXYZ[1] + parentXYZ[3] >= grandParent->_data2 + data2)
+			if (parentXYZ[1] + parentXYZ[3] > grandParent->_data2 + data2)
 				parentXYZ[3] = grandParent->_data2 - parentXYZ[1] + data2;
 
 			switch (currentRec->_recordType) {
@@ -2808,12 +2914,12 @@ int16 *DisplayMan::getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16
 				}
 				if (parentXYZ[0] < data1)
 					parentXYZ[0] = data1;
-				if (parentXYZ[0] + parentXYZ[2] >= parentRec->_data1 + data1)
+				if (parentXYZ[0] + parentXYZ[2] > parentRec->_data1 + data1)
 					parentXYZ[2] = parentRec->_data1 - parentXYZ[0] + data1;
 
 				if (parentXYZ[1] < data2)
 					parentXYZ[1] = data2;
-				if (parentXYZ[1] + parentXYZ[3] >= parentRec->_data2 + data2)
+				if (parentXYZ[1] + parentXYZ[3] > parentRec->_data2 + data2)
 					parentXYZ[3] = parentRec->_data2 - parentXYZ[1] + data2;
 			} else {
 				if (parentRec->_recordType <= 8)
@@ -2914,6 +3020,41 @@ bool DisplayMan::getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox) {
 	return true;
 }
 
+void DisplayMan::drawWallSetBitmapDOS(int16 zoneIndex, int16 normalNegIndex, int16 oppositeNegIndex, bool withoutTransparency) {
+	int16 negIndex = _useFlippedWallAndFootprintsBitmap ? oppositeNegIndex : normalNegIndex;
+	Struct2 s2;
+	byte *bmp = initBitmapStruct2(negIndex, &s2);
+	if (!bmp)
+		return;
+
+	uint16 bmpPixelWidth = 0, bmpPixelHeight = 0;
+	if (getBitmapDimensions(bmp, bmpPixelWidth, bmpPixelHeight)) {
+		s2._width = bmpPixelWidth;
+		s2._height = bmpPixelHeight;
+	}
+
+	int16 xyz[4] = { 0, 0, 0, 0 };
+	int16 inOutX = s2._width;
+	int16 inOutY = s2._height;
+
+	if (!getCoord(bmp, xyz, zoneIndex, &inOutX, &inOutY))
+		return;
+
+	Box destBox(xyz[0], xyz[0] + xyz[2] - 1, xyz[1], xyz[1] + xyz[3] - 1);
+	uint16 srcX = s2._x + inOutX;
+	uint16 srcY = s2._y + inOutY;
+	uint16 byteWidth = bmpPixelWidth / 2;
+	Color transp = withoutTransparency ? kDMColorNoTransparency : kDMColorFlesh;
+
+	if (_useFlippedWallAndFootprintsBitmap) {
+		copyBitmapAndFlipHorizontal(bmp, _tmpBitmap, byteWidth, bmpPixelHeight);
+		uint16 flippedSrcX = bmpPixelWidth - srcX - xyz[2];
+		blitToBitmap(_tmpBitmap, _bitmapViewport, destBox, flippedSrcX, srcY, byteWidth, k112_byteWidthViewport, transp, bmpPixelHeight, k136_heightViewport);
+	} else {
+		blitToBitmap(bmp, _bitmapViewport, destBox, srcX, srcY, byteWidth, k112_byteWidthViewport, transp, bmpPixelHeight, k136_heightViewport);
+	}
+}
+
 void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 	static Frame doorFrameTopD2R = Frame(164, 223, 22, 24, 48, 3, 16, 0); // @ G0175_s_Graphic558_Frame_DoorFrameTop_D2R
 	static Frame frameStairsUpFrontD2R = Frame(160, 223, 22, 83, 32, 62, 0, 0); // @ G0115_s_Graphic558_Frame_StairsUpFront_D2R
@@ -2953,7 +3094,10 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD2R : _bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2R]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD2R, kDMNegGraphicWallD2R, kDMNegGraphicWallD2L);
+		else
+			drawWallSetBitmap(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD2RLeft);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD2RFront))
 			order = kDMCellOrderAlcove;
@@ -3041,7 +3185,10 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD2C, &frameCeilingPitD2C, posX, posY, false);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmapWithoutTransparency(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2C]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD2C, kDMNegGraphicWallD2C, kDMNegGraphicWallD2C, true);
+		else
+			drawWallSetBitmapWithoutTransparency(_bitmapWallSetD2LCR, _frameWalls163[kDMViewSquareD2C]);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD2CFront))
 			order = kDMCellOrderAlcove;
 		else
@@ -3123,7 +3270,10 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD1L : _bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1L]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD1L, kDMNegGraphicWallD1L, kDMNegGraphicWallD1R);
+		else
+			drawWallSetBitmap(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1L]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectRightWallOrnOrd], kDMViewWallD1LRight);
 		return;
 	case kDMElementTypeStairsSide:
@@ -3202,7 +3352,10 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_vm->getPlatform() == Common::kPlatformDOS ? _bitmapWallSetD1R : _bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1R]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD1R, kDMNegGraphicWallD1R, kDMNegGraphicWallD1L);
+		else
+			drawWallSetBitmap(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1R]);
 		isDrawnWallOrnAnAlcove(squareAspect[kDMSquareAspectLeftWallOrnOrd], kDMViewWallD1RLeft);
 		return;
 	case kDMElementTypeStairsSide:
@@ -3285,7 +3438,10 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) {
 			blitToBitmap(bitmap, getDerivedBitmap(kDMDerivedBitmapThievesEyeVisibleArea),
 							  boxThievesEyeVisibleArea, 0, 0, 48, 48, kDMColorFlesh, 95, 95);
 		}
-		drawWallSetBitmapWithoutTransparency(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1C]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD1C, kDMNegGraphicWallD1C, kDMNegGraphicWallD1C, true);
+		else
+			drawWallSetBitmapWithoutTransparency(_bitmapWallSetD1LCR, _frameWalls163[kDMViewSquareD1C]);
 		if (isDrawnWallOrnAnAlcove(squareAspect[kDMSquareFrontWallOrnOrd], kDMViewWallD1CFront))
 			drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD1C, kDMCellOrderAlcove);
 
@@ -3352,7 +3508,10 @@ void DisplayMan::drawSquareD0L(Direction dir, int16 posX, int16 posY) {
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD0L, kDMCellOrderBackRight);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetWallD0L, _frameWalls163[kDMViewSquareD0L]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD0L, kDMNegGraphicWallD0L, kDMNegGraphicWallD0R);
+		else
+			drawWallSetBitmap(_bitmapWallSetWallD0L, _frameWalls163[kDMViewSquareD0L]);
 		return;
 	default:
 		break;
@@ -3386,7 +3545,10 @@ void DisplayMan::drawSquareD0R(Direction dir, int16 posX, int16 posY) {
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD0R, kDMCellOrderBackLeft);
 		break;
 	case kDMElementTypeWall:
-		drawWallSetBitmap(_bitmapWallSetWallD0R, _frameWalls163[kDMViewSquareD0R]);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD0R, kDMNegGraphicWallD0R, kDMNegGraphicWallD0L);
+		else
+			drawWallSetBitmap(_bitmapWallSetWallD0R, _frameWalls163[kDMViewSquareD0R]);
 		return;
 	default:
 		break;
@@ -3465,22 +3627,32 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) {
 		copyBitmapAndFlipHorizontal(_bitmapFloor, _tmpBitmap, k112_byteWidthViewport, 70);
 		drawWallSetBitmap(_tmpBitmap, floorFrame);
 
-		_bitmapWallSetD3LCR = _bitmapWallD3LCRFlipped;
-		_bitmapWallSetD2LCR = _bitmapWallD2LCRFlipped;
-		_bitmapWallSetD1LCR = _bitmapWallD1LCRFlipped;
-		_bitmapWallSetWallD0L = _bitmapWallD0LFlipped;
-		_bitmapWallSetWallD0R = _bitmapWallD0RFlipped;
+		if (_vm->getPlatform() != Common::kPlatformDOS) {
+			_bitmapWallSetD3LCR = _bitmapWallD3LCRFlipped;
+			_bitmapWallSetD2LCR = _bitmapWallD2LCRFlipped;
+			_bitmapWallSetD1LCR = _bitmapWallD1LCRFlipped;
+			_bitmapWallSetWallD0L = _bitmapWallD0LFlipped;
+			_bitmapWallSetWallD0R = _bitmapWallD0RFlipped;
+		}
 	} else {
 		copyBitmapAndFlipHorizontal(_bitmapCeiling, _tmpBitmap, k112_byteWidthViewport, 29);
 		drawWallSetBitmap(_tmpBitmap, ceilingFrame);
 		drawWallSetBitmap(_bitmapFloor, floorFrame);
 	}
 
-	if (dungeon.getRelSquareType(dir, 3, -2, posX, posY) == kDMElementTypeWall)
-		drawWallSetBitmap(_bitmapWallSetD3L2, frameWallD3L2);
+	if (dungeon.getRelSquareType(dir, 3, -2, posX, posY) == kDMElementTypeWall) {
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD3L2, kDMNegGraphicWallD3L2, kDMNegGraphicWallD3R2);
+		else
+			drawWallSetBitmap(_bitmapWallSetD3L2, frameWallD3L2);
+	}
 
-	if (dungeon.getRelSquareType(dir, 3, 2, posX, posY) == kDMElementTypeWall)
-		drawWallSetBitmap(_bitmapWallSetD3R2, _frameWallD3R2);
+	if (dungeon.getRelSquareType(dir, 3, 2, posX, posY) == kDMElementTypeWall) {
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawWallSetBitmapDOS(kDMZoneWallD3R2, kDMNegGraphicWallD3R2, kDMNegGraphicWallD3L2);
+		else
+			drawWallSetBitmap(_bitmapWallSetD3R2, _frameWallD3R2);
+	}
 
 	int16 tmpPosX = posX;
 	int16 tmpPosY = posY;
@@ -3506,6 +3678,23 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) {
 	tmpPosY = posY;
 	dungeon.mapCoordsAfterRelMovement(dir, 3, 0, tmpPosX, tmpPosY);
 	drawSquareD3C(dir, tmpPosX, tmpPosY);
+
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		uint16 sqAspect[5];
+		tmpPosX = posX;
+		tmpPosY = posY;
+		dungeon.mapCoordsAfterRelMovement(dir, 2, -2, tmpPosX, tmpPosY);
+		dungeon.setSquareAspect(sqAspect, dir, tmpPosX, tmpPosY);
+		if (sqAspect[kDMSquareAspectElement] == kDMElementTypeWall)
+			drawWallSetBitmapDOS(kDMZoneWallD2L2, kDMNegGraphicWallD2L2, kDMNegGraphicWallD2R2);
+
+		tmpPosX = posX;
+		tmpPosY = posY;
+		dungeon.mapCoordsAfterRelMovement(dir, 2, 2, tmpPosX, tmpPosY);
+		dungeon.setSquareAspect(sqAspect, dir, tmpPosX, tmpPosY);
+		if (sqAspect[kDMSquareAspectElement] == kDMElementTypeWall)
+			drawWallSetBitmapDOS(kDMZoneWallD2R2, kDMNegGraphicWallD2R2, kDMNegGraphicWallD2L2);
+	}
 	tmpPosX = posX;
 	tmpPosY = posY;
 	dungeon.mapCoordsAfterRelMovement(dir, 2, -1, tmpPosX, tmpPosY);
@@ -3541,11 +3730,13 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) {
 	drawSquareD0C(dir, posX, posY);
 
 	if (_useFlippedWallAndFootprintsBitmap) {
-		_bitmapWallSetD3LCR = _bitmapWallD3LCRNative;
-		_bitmapWallSetD2LCR = _bitmapWallD2LCRNative;
-		_bitmapWallSetD1LCR = _bitmapWallD1LCRNative;
-		_bitmapWallSetWallD0L = _bitmapWallD0LNative;
-		_bitmapWallSetWallD0R = _bitmapWallD0RNative;
+		if (_vm->getPlatform() != Common::kPlatformDOS) {
+			_bitmapWallSetD3LCR = _bitmapWallD3LCRNative;
+			_bitmapWallSetD2LCR = _bitmapWallD2LCRNative;
+			_bitmapWallSetD1LCR = _bitmapWallD1LCRNative;
+			_bitmapWallSetWallD0L = _bitmapWallD0LNative;
+			_bitmapWallSetWallD0R = _bitmapWallD0RNative;
+		}
 	}
 
 	drawViewport((dungeon._partyMapIndex != kDMMapIndexEntrance) ? 1 : 0);
@@ -3577,6 +3768,11 @@ void DisplayMan::loadFloorSet(FloorSet set) {
 	int16 index = (set * k2_FloorSetGraphicCount) + firstFloorSet;
 	loadIntoBitmap(index, _bitmapFloor);
 	loadIntoBitmap(index + 1, _bitmapCeiling);
+
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		_negativeBitmaps[0]._s3u._bitmap = _bitmapFloor;   // -1
+		_negativeBitmaps[1]._s3u._bitmap = _bitmapCeiling; // -2
+	}
 }
 
 void DisplayMan::loadWallSet(WallSet set) {
@@ -3608,6 +3804,22 @@ void DisplayMan::loadWallSet(WallSet set) {
 		loadIntoBitmap(graphicIndice + 19, _bitmapWallSetD3R);      // C12_WALL_D3R (105)
 		loadIntoBitmap(graphicIndice + 20, _bitmapWallSetD3L);      // C13_WALL_D3L (106)
 		loadIntoBitmap(graphicIndice + 21, _bitmapWallSetD3LCR);    // C14_WALL_D3C (107)
+
+		_negativeBitmaps[2]._s3u._bitmap = _bitmapWallSetD3L2;       // -3
+		_negativeBitmaps[3]._s3u._bitmap = _bitmapWallSetD3R2;       // -4
+		_negativeBitmaps[4]._s3u._bitmap = _bitmapWallSetD3LCR;      // -5
+		_negativeBitmaps[5]._s3u._bitmap = _bitmapWallSetD3L;        // -6
+		_negativeBitmaps[6]._s3u._bitmap = _bitmapWallSetD3R;        // -7
+		_negativeBitmaps[7]._s3u._bitmap = _bitmapWallSetD2L2;       // -8
+		_negativeBitmaps[8]._s3u._bitmap = _bitmapWallSetD2R2;       // -9
+		_negativeBitmaps[9]._s3u._bitmap = _bitmapWallSetD2LCR;      // -10
+		_negativeBitmaps[10]._s3u._bitmap = _bitmapWallSetD2L;       // -11
+		_negativeBitmaps[11]._s3u._bitmap = _bitmapWallSetD2R;       // -12
+		_negativeBitmaps[12]._s3u._bitmap = _bitmapWallSetD1LCR;     // -13
+		_negativeBitmaps[13]._s3u._bitmap = _bitmapWallSetD1L;       // -14
+		_negativeBitmaps[14]._s3u._bitmap = _bitmapWallSetD1R;       // -15
+		_negativeBitmaps[15]._s3u._bitmap = _bitmapWallSetWallD0L;   // -16
+		_negativeBitmaps[16]._s3u._bitmap = _bitmapWallSetWallD0R;   // -17
 	} else {
 		int16 graphicIndice = (set * k13_WallSetGraphicCount) + k77_FirstWallSet;
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetDoorFrameFront);
@@ -3623,16 +3835,14 @@ void DisplayMan::loadWallSet(WallSet set) {
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetD2LCR);
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetD3LCR);
 		loadIntoBitmap(graphicIndice++, _bitmapWallSetD3L2);
-	}
 
-	int16 firstWallSet = (_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet;
-	int16 doorFrameLeftD1CIdx = firstWallSet + 1;
-	int16 d3R2Idx = (_vm->getPlatform() == Common::kPlatformDOS) ? (firstWallSet + 18) : (firstWallSet + 12);
-
-	copyBitmapAndFlipHorizontal(_bitmapWallSetDoorFrameLeftD1C, _bitmapWallSetDoorFrameRightD1C,
-									getPixelWidth(doorFrameLeftD1CIdx) / 2, getPixelHeight(doorFrameLeftD1CIdx));
-	copyBitmapAndFlipHorizontal(_bitmapWallSetD3L2, _bitmapWallSetD3R2,
-									getPixelWidth(d3R2Idx) / 2, getPixelHeight(d3R2Idx));
+		int16 firstWallSet = k77_FirstWallSet;
+		int16 doorFrameLeftD1CIdx = firstWallSet + 1;
+		copyBitmapAndFlipHorizontal(_bitmapWallSetDoorFrameLeftD1C, _bitmapWallSetDoorFrameRightD1C,
+										getPixelWidth(doorFrameLeftD1CIdx) / 2, getPixelHeight(doorFrameLeftD1CIdx));
+		copyBitmapAndFlipHorizontal(_bitmapWallSetD3L2, _bitmapWallSetD3R2,
+										getPixelWidth(firstWallSet + 12) / 2, getPixelHeight(firstWallSet + 12));
+	}
 }
 
 void DisplayMan::loadCurrentMapGraphics() {
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index ca4abdd6266..546093c61d8 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -98,6 +98,45 @@ enum DoorOrnament {
 	kDMDoorOrnamentD1LCR = 2  // @ C2_VIEW_DOOR_ORNAMENT_D1LCR
 };
 
+enum ZoneIndex {
+	kDMZoneWallD3L2 = 702, // @ C702_ZONE_WALL_D3L2
+	kDMZoneWallD3R2 = 703, // @ C703_ZONE_WALL_D3R2
+	kDMZoneWallD3C  = 704, // @ C704_ZONE_WALL_D3C
+	kDMZoneWallD3L  = 705, // @ C705_ZONE_WALL_D3L
+	kDMZoneWallD3R  = 706, // @ C706_ZONE_WALL_D3R
+	kDMZoneWallD2L2 = 707, // @ C707_ZONE_WALL_D2L2
+	kDMZoneWallD2R2 = 708, // @ C708_ZONE_WALL_D2R2
+	kDMZoneWallD2C  = 709, // @ C709_ZONE_WALL_D2C
+	kDMZoneWallD2L  = 710, // @ C710_ZONE_WALL_D2L
+	kDMZoneWallD2R  = 711, // @ C711_ZONE_WALL_D2R
+	kDMZoneWallD1C  = 712, // @ C712_ZONE_WALL_D1C
+	kDMZoneWallD1L  = 713, // @ C713_ZONE_WALL_D1L
+	kDMZoneWallD1R  = 714, // @ C714_ZONE_WALL_D1R
+	kDMZoneWallD0C  = 715, // @ C715_ZONE_WALL_D0C
+	kDMZoneWallD0L  = 716, // @ C716_ZONE_WALL_D0L
+	kDMZoneWallD0R  = 717  // @ C717_ZONE_WALL_D0R
+};
+
+enum NegGraphicIndex {
+	kDMNegGraphicFloor     = -1,
+	kDMNegGraphicCeiling   = -2,
+	kDMNegGraphicWallD3L2  = -3,
+	kDMNegGraphicWallD3R2  = -4,
+	kDMNegGraphicWallD3C   = -5,
+	kDMNegGraphicWallD3L   = -6,
+	kDMNegGraphicWallD3R   = -7,
+	kDMNegGraphicWallD2L2  = -8,
+	kDMNegGraphicWallD2R2  = -9,
+	kDMNegGraphicWallD2C   = -10,
+	kDMNegGraphicWallD2L   = -11,
+	kDMNegGraphicWallD2R   = -12,
+	kDMNegGraphicWallD1C   = -13,
+	kDMNegGraphicWallD1L   = -14,
+	kDMNegGraphicWallD1R   = -15,
+	kDMNegGraphicWallD0L   = -16,
+	kDMNegGraphicWallD0R   = -17
+};
+
 enum DoorButton {
 	kDMDoorButtonD3R = 0, // @ C0_VIEW_DOOR_BUTTON_D3R
 	kDMDoorButtonD3C = 1, // @ C1_VIEW_DOOR_BUTTON_D3C
@@ -659,6 +698,18 @@ class DisplayMan {
 	byte *initBitmapStruct2(int16 graphicIndex, Struct2 *outStruct); // @ F0630_InitBitmapStruct2
 	int16 *getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16 *inOutX, int16 *inOutY); // @ F0635_
 	bool getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox);
+	void drawWallSetBitmapDOS(int16 zoneIndex, int16 normalNegIndex, int16 oppositeNegIndex, bool withoutTransparency = false);
+	void loadLayoutData(uint16 graphicIndex); // @ F0640_LoadLayoutData
+
+	struct DynLayoutRange {
+		DynLayoutRange *_nextRange;
+		int16 _firstIndex;
+		int16 _lastIndex;
+		LayoutRecord *_records;
+	};
+	DynLayoutRange *_dosLayoutData;
+	Common::Array<DynLayoutRange *> _dosLayoutRangeAllocs;
+
 	void drawSquareD3L(Direction dir, int16 posX, int16 posY); // @ F0116_DUNGEONVIEW_DrawSquareD3L
 	void drawSquareD3R(Direction dir, int16 posX, int16 posY); // @ F0117_DUNGEONVIEW_DrawSquareD3R
 	void drawSquareD3C(Direction dir, int16 posX, int16 posY); // @ F0118_DUNGEONVIEW_DrawSquareD3C_CPSF


Commit: ab14dac5e1f1fd4eb73cf5804cd7b9b2b1097da1
    https://github.com/scummvm/scummvm/commit/ab14dac5e1f1fd4eb73cf5804cd7b9b2b1097da1
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix D0 side wall clipping and D0R right-alignment offset

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 5a544d7fdfa..886a51f1dd6 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -3043,12 +3043,21 @@ void DisplayMan::drawWallSetBitmapDOS(int16 zoneIndex, int16 normalNegIndex, int
 	Box destBox(xyz[0], xyz[0] + xyz[2] - 1, xyz[1], xyz[1] + xyz[3] - 1);
 	uint16 srcX = s2._x + inOutX;
 	uint16 srcY = s2._y + inOutY;
+	if (zoneIndex == kDMZoneWallD0L && destBox._rect.right > 30)
+		destBox._rect.right = 30;
+	if (zoneIndex == kDMZoneWallD0R) {
+		if (destBox._rect.left < 193)
+			destBox._rect.left = 193;
+		srcX += 1; // Offset +1 compensates for RecordType 2 right-alignment math
+	}
 	uint16 byteWidth = bmpPixelWidth / 2;
 	Color transp = withoutTransparency ? kDMColorNoTransparency : kDMColorFlesh;
 
 	if (_useFlippedWallAndFootprintsBitmap) {
 		copyBitmapAndFlipHorizontal(bmp, _tmpBitmap, byteWidth, bmpPixelHeight);
-		uint16 flippedSrcX = bmpPixelWidth - srcX - xyz[2];
+		uint16 flippedSrcX = bmpPixelWidth - (s2._x + inOutX) - xyz[2];
+		if (zoneIndex == kDMZoneWallD0R)
+			flippedSrcX += 1;
 		blitToBitmap(_tmpBitmap, _bitmapViewport, destBox, flippedSrcX, srcY, byteWidth, k112_byteWidthViewport, transp, bmpPixelHeight, k136_heightViewport);
 	} else {
 		blitToBitmap(bmp, _bitmapViewport, destBox, srcX, srcY, byteWidth, k112_byteWidthViewport, transp, bmpPixelHeight, k136_heightViewport);


Commit: 93d17d24097c120f8d25b76956fad8bd8a4dbf3c
    https://github.com/scummvm/scummvm/commit/93d17d24097c120f8d25b76956fad8bd8a4dbf3c
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix DOS spell casting panel positioning and rendering

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h
    engines/dm/menus.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 886a51f1dd6..33cdfbaa734 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -3012,8 +3012,10 @@ bool DisplayMan::getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox) {
 	Struct2 s2;
 	byte *bmp = initBitmapStruct2(graphicIndex, &s2);
 	int16 xyz[4] = { 0, 0, 0, 0 };
+	int16 inOutX = (graphicIndex < 0) ? s2._width : 0;
+	int16 inOutY = (graphicIndex < 0) ? s2._height : 0;
 
-	if (!getCoord(bmp, xyz, zoneIndex, &s2._width, &s2._height))
+	if (!getCoord(bmp, xyz, zoneIndex, &inOutX, &inOutY))
 		return false;
 
 	outBox = Box(xyz[0], xyz[0] + xyz[2] - 1, xyz[1], xyz[1] + xyz[3] - 1);
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 546093c61d8..3e55fe7b64a 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -99,22 +99,31 @@ enum DoorOrnament {
 };
 
 enum ZoneIndex {
-	kDMZoneWallD3L2 = 702, // @ C702_ZONE_WALL_D3L2
-	kDMZoneWallD3R2 = 703, // @ C703_ZONE_WALL_D3R2
-	kDMZoneWallD3C  = 704, // @ C704_ZONE_WALL_D3C
-	kDMZoneWallD3L  = 705, // @ C705_ZONE_WALL_D3L
-	kDMZoneWallD3R  = 706, // @ C706_ZONE_WALL_D3R
-	kDMZoneWallD2L2 = 707, // @ C707_ZONE_WALL_D2L2
-	kDMZoneWallD2R2 = 708, // @ C708_ZONE_WALL_D2R2
-	kDMZoneWallD2C  = 709, // @ C709_ZONE_WALL_D2C
-	kDMZoneWallD2L  = 710, // @ C710_ZONE_WALL_D2L
-	kDMZoneWallD2R  = 711, // @ C711_ZONE_WALL_D2R
-	kDMZoneWallD1C  = 712, // @ C712_ZONE_WALL_D1C
-	kDMZoneWallD1L  = 713, // @ C713_ZONE_WALL_D1L
-	kDMZoneWallD1R  = 714, // @ C714_ZONE_WALL_D1R
-	kDMZoneWallD0C  = 715, // @ C715_ZONE_WALL_D0C
-	kDMZoneWallD0L  = 716, // @ C716_ZONE_WALL_D0L
-	kDMZoneWallD0R  = 717  // @ C717_ZONE_WALL_D0R
+	kDMZoneScreen               = 2,   // @ C002_ZONE_SCREEN
+	kDMZoneViewport             = 7,   // @ C007_ZONE_VIEWPORT
+	kDMZoneMovementArrows       = 9,   // @ C009_ZONE_MOVEMENT_ARROWS
+	kDMZoneActionArea           = 11,  // @ C011_ZONE_ACTION_AREA
+	kDMZoneSpellArea            = 13,  // @ C013_ZONE_SPELL_AREA
+	kDMZoneMessageArea          = 15,  // @ C015_ZONE_MESSAGE_AREA
+	kDMZoneViewportCeiling      = 700, // @ C700_ZONE_VIEWPORT_CEILING_AREA
+	kDMZoneViewportFloor        = 701, // @ C701_ZONE_VIEWPORT_FLOOR_AREA
+	kDMZoneWallD3L2             = 702, // @ C702_ZONE_WALL_D3L2
+	kDMZoneWallD3R2             = 703, // @ C703_ZONE_WALL_D3R2
+	kDMZoneWallD3C              = 704, // @ C704_ZONE_WALL_D3C
+	kDMZoneWallD3L              = 705, // @ C705_ZONE_WALL_D3L
+	kDMZoneWallD3R              = 706, // @ C706_ZONE_WALL_D3R
+	kDMZoneWallD2L2             = 707, // @ C707_ZONE_WALL_D2L2
+	kDMZoneWallD2R2             = 708, // @ C708_ZONE_WALL_D2R2
+	kDMZoneWallD2C              = 709, // @ C709_ZONE_WALL_D2C
+	kDMZoneWallD2L              = 710, // @ C710_ZONE_WALL_D2L
+	kDMZoneWallD2R              = 711, // @ C711_ZONE_WALL_D2R
+	kDMZoneWallD1C              = 712, // @ C712_ZONE_WALL_D1C
+	kDMZoneWallD1L              = 713, // @ C713_ZONE_WALL_D1L
+	kDMZoneWallD1R              = 714, // @ C714_ZONE_WALL_D1R
+	kDMZoneWallD0C              = 715, // @ C715_ZONE_WALL_D0C
+	kDMZoneWallD0L              = 716, // @ C716_ZONE_WALL_D0L
+	kDMZoneWallD0R              = 717, // @ C717_ZONE_WALL_D0R
+	kDMZonePortraitOnWall       = 737  // @ M635_ZONE_PORTRAIT_ON_WALL
 };
 
 enum NegGraphicIndex {
@@ -697,7 +706,9 @@ class DisplayMan {
 	const LayoutRecord *getLayoutRecord(int16 layoutRecordIndex); // @ F0634_GetLayoutRecord
 	byte *initBitmapStruct2(int16 graphicIndex, Struct2 *outStruct); // @ F0630_InitBitmapStruct2
 	int16 *getCoord(byte *bitmap, int16 *outXYZ, int16 zoneIndex, int16 *inOutX, int16 *inOutY); // @ F0635_
+public:
 	bool getZoneBox(int16 zoneIndex, int16 graphicIndex, Box &outBox);
+private:
 	void drawWallSetBitmapDOS(int16 zoneIndex, int16 normalNegIndex, int16 oppositeNegIndex, bool withoutTransparency = false);
 	void loadLayoutData(uint16 graphicIndex); // @ F0640_LoadLayoutData
 
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 460ee6f895a..628e57bd7c9 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -370,7 +370,8 @@ void MenuMan::drawSpellAreaControls(ChampionIndex champIndex) {
 	int16 champHP2 = championMan._champions[2]._currHealth;
 	int16 champHP3 = championMan._champions[3]._currHealth;
 	_vm->_eventMan->showMouse();
-	_vm->_displayMan->fillScreenBox(boxSpellAreaControls, kDMColorBlack);
+	if (_vm->getPlatform() != Common::kPlatformDOS)
+		_vm->_displayMan->fillScreenBox(boxSpellAreaControls, kDMColorBlack);
 
 	switch (champIndex) {
 	case 0:
@@ -478,6 +479,8 @@ void MenuMan::setMagicCasterAndDrawSpellArea(ChampionIndex champIndex) {
 
 	if (championMan._magicCasterChampionIndex == kDMChampionNone) {
 		_vm->_eventMan->showMouse();
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			_vm->_displayMan->getZoneBox(kDMZoneSpellArea, kDMGraphicIdxMenuSpellAreaBackground, _boxSpellArea);
 		_vm->_displayMan->blitToScreen(_vm->_displayMan->getNativeBitmapOrGraphic(kDMGraphicIdxMenuSpellAreaBackground), &_boxSpellArea, k48_byteWidth, kDMColorNoTransparency, 33);
 		_vm->_eventMan->hideMouse();
 	}
@@ -490,6 +493,18 @@ void MenuMan::setMagicCasterAndDrawSpellArea(ChampionIndex champIndex) {
 		return;
 	}
 	championMan._magicCasterChampionIndex = champIndex;
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		Champion *champ = &championMan._champions[champIndex];
+		_vm->_displayMan->getZoneBox(kDMZoneSpellArea, kDMGraphicIdxMenuSpellAreaBackground, _boxSpellArea);
+		_vm->_displayMan->blitToScreen(_vm->_displayMan->getNativeBitmapOrGraphic(kDMGraphicIdxMenuSpellAreaBackground), &_boxSpellArea, k48_byteWidth, kDMColorNoTransparency, 33);
+		_vm->_eventMan->showMouse();
+		drawSpellAreaControls(champIndex);
+		drawAvailableSymbols(champ->_symbolStep);
+		drawChampionSymbols(champ);
+		_vm->_eventMan->hideMouse();
+		return;
+	}
+
 	buildSpellAreaLine(kDMSpellAreaAvailableSymbols);
 	_vm->_eventMan->showMouse();
 	drawSpellAreaControls(champIndex);
@@ -895,10 +910,11 @@ void MenuMan::drawAvailableSymbols(uint16 symbolStep) {
 	displayBuffer[1] = '\0';
 	char curCharacter = 96 + 6 * symbolStep;
 	int16 textPosX = 225;
+	Color bgColor = (_vm->getPlatform() == Common::kPlatformDOS) ? kDMColorNoTransparency : kDMColorBlack;
 	for (uint16 L1214_ui_Counter = 0; L1214_ui_Counter < 6; L1214_ui_Counter++) {
 		displayBuffer[0] = curCharacter++;
 		textPosX += 14;
-		_vm->_textMan->printToLogicalScreen(textPosX, 58, kDMColorCyan, kDMColorBlack, displayBuffer);
+		_vm->_textMan->printToLogicalScreen(textPosX, 58, kDMColorCyan, bgColor, displayBuffer);
 	}
 }
 
@@ -907,6 +923,7 @@ void MenuMan::drawChampionSymbols(Champion *champ) {
 	int16 textPosX = 232;
 	char displayBuffer[2];
 	displayBuffer[1] = '\0';
+	Color bgColor = (_vm->getPlatform() == Common::kPlatformDOS) ? kDMColorNoTransparency : kDMColorBlack;
 
 	for (uint16 symbolIndex = 0; symbolIndex < 4; symbolIndex++) {
 		if (symbolIndex >= symbolCount)
@@ -915,7 +932,7 @@ void MenuMan::drawChampionSymbols(Champion *champ) {
 			displayBuffer[0] = champ->_symbols[symbolIndex];
 
 		textPosX += 9;
-		_vm->_textMan->printToLogicalScreen(textPosX, 70, kDMColorCyan, kDMColorBlack, displayBuffer);
+		_vm->_textMan->printToLogicalScreen(textPosX, 70, kDMColorCyan, bgColor, displayBuffer);
 	}
 }
 


Commit: a1ceb64063f6bc2e4c6f570e65cac6a7716f8916
    https://github.com/scummvm/scummvm/commit/a1ceb64063f6bc2e4c6f570e65cac6a7716f8916
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix graphics corruption when scaling D2/D3 ornaments in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 33cdfbaa734..866ebf9f4ad 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1422,9 +1422,10 @@ void DisplayMan::drawDoorButton(int16 doorButtonOrdinal, DoorButton doorButton)
 			if (!isDerivedBitmapInCache(doorButtonOrdinal)) {
 				uint16 *coordSetBlueGoat = _doorButtonCoordSets[coordSet][kDMDoorButtonD1C];
 				byte *bitmapNative = getNativeBitmapOrGraphic(nativeBitmapIndex);
+				int16 srcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(nativeBitmapIndex) : (coordSetBlueGoat[4] << 1);
+				int16 srcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeBitmapIndex) : coordSetBlueGoat[5];
 				blitToBitmapShrinkWithPalChange(bitmapNative, getDerivedBitmap(doorButtonOrdinal),
-													 coordSetBlueGoat[4] << 1, coordSetBlueGoat[5],
-													 // modified code line
+													 srcWidth, srcHeight,
 													 coordSetRedEagle[4] << 1,
 													 coordSetRedEagle[5],
 													 (doorButton == kDMDoorButtonD2C) ? _palChangesDoorButtonAndWallOrnD2 : _palChangesDoorButtonAndWallOrnD3);
@@ -2206,7 +2207,9 @@ void DisplayMan::drawDoorOrnament(int16 doorOrnOrdinal, DoorOrnament doorOrnamen
 		if (!isDerivedBitmapInCache(height)) {
 			uint16 *coordSetRedEagle = &_doorOrnCoordSets[coordSetGreenToad][kDMDoorOrnamentD1LCR][0];
 			byte *nativeBitmap = getNativeBitmapOrGraphic(nativeBitmapIndex);
-			blitToBitmapShrinkWithPalChange(nativeBitmap, getDerivedBitmap(height), coordSetRedEagle[4] << 1, coordSetRedEagle[5], coordSetOrangeElk[1] - coordSetOrangeElk[0] + 1, coordSetOrangeElk[5], (doorOrnament == kDMDoorOrnamentD3LCR) ? palChangesDoorOrnD3 : palChangesDoorOrnd2);
+			int16 srcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(nativeBitmapIndex) : (coordSetRedEagle[4] << 1);
+			int16 srcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeBitmapIndex) : coordSetRedEagle[5];
+			blitToBitmapShrinkWithPalChange(nativeBitmap, getDerivedBitmap(height), srcWidth, srcHeight, coordSetOrangeElk[1] - coordSetOrangeElk[0] + 1, coordSetOrangeElk[5], (doorOrnament == kDMDoorOrnamentD3LCR) ? palChangesDoorOrnD3 : palChangesDoorOrnd2);
 			addDerivedBitmap(height);
 		}
 		blitBitmap = getDerivedBitmap(height);
@@ -4263,7 +4266,9 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 		wallOrnamentIndex = kDMDerivedBitmapFirstWallOrnament + (wallOrnamentIndex << 2) + wallOrnDerivedBitmapIndexIncrement[viewWallIndex];
 		if (!isDerivedBitmapInCache(wallOrnamentIndex)) {
 			byte *blitBitmap = getNativeBitmapOrGraphic(ornNativeBitmapIndex);
-			blitToBitmapShrinkWithPalChange(blitBitmap, getDerivedBitmap(wallOrnamentIndex), ornBlitBitmap[4] << 1, ornBlitBitmap[5], ornCoordSet[4] << 1, ornCoordSet[5], (viewWallIndex <= kDMViewWallD3RFront) ? _palChangesDoorButtonAndWallOrnD3 : _palChangesDoorButtonAndWallOrnD2);
+			int16 srcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(ornNativeBitmapIndex) : (ornBlitBitmap[4] << 1);
+			int16 srcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(ornNativeBitmapIndex) : ornBlitBitmap[5];
+			blitToBitmapShrinkWithPalChange(blitBitmap, getDerivedBitmap(wallOrnamentIndex), srcWidth, srcHeight, ornCoordSet[4] << 1, ornCoordSet[5], (viewWallIndex <= kDMViewWallD3RFront) ? _palChangesDoorButtonAndWallOrnD3 : _palChangesDoorButtonAndWallOrnD2);
 			addDerivedBitmap(wallOrnamentIndex);
 		}
 		ornBlitBitmap = getDerivedBitmap(wallOrnamentIndex);


Commit: 1f2eb0e0cd99c549fcbc1f53482a192e69c399eb
    https://github.com/scummvm/scummvm/commit/1f2eb0e0cd99c549fcbc1f53482a192e69c399eb
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix D2 wall ornament scaling aspect ratio in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 866ebf9f4ad..e13a26b6776 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -4268,7 +4268,9 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 			byte *blitBitmap = getNativeBitmapOrGraphic(ornNativeBitmapIndex);
 			int16 srcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(ornNativeBitmapIndex) : (ornBlitBitmap[4] << 1);
 			int16 srcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(ornNativeBitmapIndex) : ornBlitBitmap[5];
-			blitToBitmapShrinkWithPalChange(blitBitmap, getDerivedBitmap(wallOrnamentIndex), srcWidth, srcHeight, ornCoordSet[4] << 1, ornCoordSet[5], (viewWallIndex <= kDMViewWallD3RFront) ? _palChangesDoorButtonAndWallOrnD3 : _palChangesDoorButtonAndWallOrnD2);
+			int16 destWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (coords[1] - coords[0] + 1) : (ornCoordSet[4] << 1);
+			int16 destHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? coords[5] : ornCoordSet[5];
+			blitToBitmapShrinkWithPalChange(blitBitmap, getDerivedBitmap(wallOrnamentIndex), srcWidth, srcHeight, destWidth, destHeight, (viewWallIndex <= kDMViewWallD3RFront) ? _palChangesDoorButtonAndWallOrnD3 : _palChangesDoorButtonAndWallOrnD2);
 			addDerivedBitmap(wallOrnamentIndex);
 		}
 		ornBlitBitmap = getDerivedBitmap(wallOrnamentIndex);


Commit: e85d4d437bbc6f5e1ceeff527f5cac15160b5a0c
    https://github.com/scummvm/scummvm/commit/e85d4d437bbc6f5e1ceeff527f5cac15160b5a0c
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix champion portrait bounding box in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index e13a26b6776..9b4a5b3926c 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -4306,7 +4306,8 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 		ornCoordSet[4], k112_byteWidthViewport, kDMColorFlesh, ornCoordSet[5], k136_heightViewport);
 
 	if ((viewWallIndex == kDMViewWallD1CFront) && _championPortraitOrdinal--) {
-		blitToBitmap(getNativeBitmapOrGraphic(kDMGraphicIdxChampionPortraits), _bitmapViewport, boxChampionPortraitOnWall,
+		Box portraitBox = (_vm->getPlatform() == Common::kPlatformDOS) ? Box(88, 119, 35, 63) : boxChampionPortraitOnWall;
+		blitToBitmap(getNativeBitmapOrGraphic(kDMGraphicIdxChampionPortraits), _bitmapViewport, portraitBox,
 			(_championPortraitOrdinal & 0x0007) << 5, (_championPortraitOrdinal >> 3) * 29,
 			k128_byteWidth, k112_byteWidthViewport, kDMColorDarkGary, 87, k136_heightViewport); /* A portrait is 32x29 pixels */
 	}


Commit: 585faa30ae19ea9e6aeaeb0ab4829856462f3bb6
    https://github.com/scummvm/scummvm/commit/585faa30ae19ea9e6aeaeb0ab4829856462f3bb6
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix crash by dynamically sizing temporary bitmap buffer

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 9b4a5b3926c..3b5d748e709 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2413,7 +2413,7 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3R);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD3R, kDMCellOrderDoorPass1BackRightBackLeft);
-		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3L, 32 * 44);
+		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3L, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4));
 		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3R);
 		if (_vm->_dungeonMan->getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD3R);
@@ -2496,7 +2496,7 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) {
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3C);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD3C, kDMCellOrderDoorPass1BackLeftBackRight);
 		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3C, doorFrameLeftD3C);
-		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3C, 32 * 44);
+		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3));
 		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3C);
 		if (dungeon.getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD3C);
@@ -3213,7 +3213,7 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) {
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD2C, kDMCellOrderDoorPass1BackLeftBackRight);
 		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2C);
 		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD2C, doorFrameLeftD2C);
-		memcpy(_tmpBitmap, _bitmapWallSetDoorFrameLeftD2C, 48 * 65);
+		memcpy(_tmpBitmap, _bitmapWallSetDoorFrameLeftD2C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2));
 		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD2C);
 		if (dungeon.getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD2C);
@@ -3589,7 +3589,7 @@ void DisplayMan::drawSquareD0C(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeDoorSide:
 		if (championMan._party._event73Count_ThievesEye) {
-			memmove(_tmpBitmap, _bitmapWallSetDoorFrameFront, 32 * 123);
+			memmove(_tmpBitmap, _bitmapWallSetDoorFrameFront, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 0) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 0));
 			blitToBitmap(getNativeBitmapOrGraphic(kDMGraphicIdxHoleInWall),
 							  _tmpBitmap, boxThievesEyeHoleInDoorFrame, doorFrameD0C._box._rect.left - _boxThievesEyeViewPortVisibleArea._rect.left,
 							  0, 48, 16, kDMColorGold, 95, 123);


Commit: 33045249db3135066f223aeb1e6dacdbfe1a97e2
    https://github.com/scummvm/scummvm/commit/33045249db3135066f223aeb1e6dacdbfe1a97e2
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Render DOS doors and door frames using DOS Layout Tree

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 3b5d748e709..9255bcd96a0 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2142,7 +2142,7 @@ void DisplayMan::drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIn
 		drawFloorOrnament(_vm->indexToOrdinal(k15_FloorOrnFootprints), viewFloorIndex);
 }
 
-void DisplayMan::drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doorNativeBitmapIndices, int16 byteCount, DoorOrnament doorOrnament, DoorFrames *doorFrames) {
+void DisplayMan::drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doorNativeBitmapIndices, int16 byteCount, DoorOrnament doorOrnament, DoorFrames *doorFrames, int16 zoneIndexDOS) {
 	if (doorState == kDMDoorStateOpen)
 		return;
 
@@ -2152,7 +2152,15 @@ void DisplayMan::drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doo
 	DoorFrames *doorFramesTemp = doorFrames;
 	Door *door = dungeon.getDoor(doorThingIndex);
 	uint16 doorType = door->getType();
-	memmove(_tmpBitmap, getNativeBitmapOrGraphic(doorNativeBitmapIndices[doorType]), byteCount * 2);
+
+	byte *nativeBmp = getNativeBitmapOrGraphic(doorNativeBitmapIndices[doorType]);
+	uint16 copyBytes = byteCount * 2;
+	uint16 doorPixelW = 0, doorPixelH = 0;
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		if (getBitmapDimensions(nativeBmp, doorPixelW, doorPixelH))
+			copyBytes = doorPixelW * doorPixelH;
+	}
+	memmove(_tmpBitmap, nativeBmp, copyBytes);
 	drawDoorOrnament(door->getOrnOrdinal(), doorOrnament);
 	if (getFlag(dungeon._currMapDoorInfo[doorType]._attributes, kDMMaskDoorInfoAnimated)) {
 		if (_vm->getRandomNumber(2))
@@ -2165,6 +2173,15 @@ void DisplayMan::drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doo
 	if ((doorFramesTemp == _doorFrameD1C) && championMan._party._event73Count_ThievesEye)
 		drawDoorOrnament(_vm->indexToOrdinal(k16_DoorOrnThivesEyeMask), kDMDoorOrnamentD1LCR);
 
+	if (_vm->getPlatform() == Common::kPlatformDOS && zoneIndexDOS >= 0) {
+		if (doorState == kDMDoorStateDestroyed)
+			drawDoorOrnament(_vm->indexToOrdinal(k15_DoorOrnDestroyedMask), doorOrnament);
+		else if (doorState != kDMDoorStateClosed)
+			zoneIndexDOS += doorState;
+		drawBitmapDOS(_tmpBitmap, zoneIndexDOS, false, kDMColorFlesh, doorPixelW, doorPixelH);
+		return;
+	}
+
 	if (doorState == kDMDoorStateClosed)
 		drawDoorBitmap(&doorFramesTemp->_closedOrDestroyed);
 	else if (doorState == kDMDoorStateDestroyed) {
@@ -2270,9 +2287,7 @@ void DisplayMan::drawWallSetBitmap(byte *bitmap, Frame &f) {
 	if (!bitmap || !f._srcByteWidth)
 		return;
 
-	uint16 srcX = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcX;
-	uint16 srcY = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcY;
-	blitToBitmap(bitmap, _bitmapViewport, f._box, srcX, srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
+	blitToBitmap(bitmap, _bitmapViewport, f._box, f._srcX, f._srcY, f._srcByteWidth, k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
 }
 
 
@@ -2331,9 +2346,14 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3L);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD3L, kDMCellOrderDoorPass1BackLeftBackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3L, doorFrameLeftD3L);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3L, kDMZoneDoorFrameLeftD3L);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3L, kDMZoneDoorFrameRightD3L, true);
+		} else {
+			drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3L, doorFrameLeftD3L);
+		}
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD3LCR, getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3L);
+					  _doorNativeBitmapIndexFrontD3LCR, getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3L, kDMZoneDoorD3L);
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
@@ -2413,14 +2433,19 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3R);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD3R, kDMCellOrderDoorPass1BackRightBackLeft);
-		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3L, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4));
-		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3R);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3L, kDMZoneDoorFrameLeftD3R);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3L, kDMZoneDoorFrameRightD3R, true);
+		} else {
+			memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3L, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 4));
+			drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3R);
+		}
 		if (_vm->_dungeonMan->getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD3R);
 
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex],
 					  (DoorState)squareAspect[kDMSquareAspectDoorState], _doorNativeBitmapIndexFrontD3LCR,
-					  getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3R);
+					  getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3R, kDMZoneDoorD3R);
 		break;
 	case kDMElementTypePit:
 		if (!squareAspect[kDMSquareAspectPitInvisible])
@@ -2495,14 +2520,19 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3C);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD3C, kDMCellOrderDoorPass1BackLeftBackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3C, doorFrameLeftD3C);
-		memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3));
-		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3C);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3C, kDMZoneDoorFrameLeftD3C);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD3C, kDMZoneDoorFrameRightD3C, true);
+		} else {
+			drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3C, doorFrameLeftD3C);
+			memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 3));
+			drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3C);
+		}
 		if (dungeon.getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD3C);
 
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD3LCR, getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3C);
+					  _doorNativeBitmapIndexFrontD3LCR, getBitmapByteCount(48, 41), kDMDoorOrnamentD3LCR, &doorFrameD3C, kDMZoneDoorD3C);
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
@@ -2583,9 +2613,12 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2L);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD2L, kDMCellOrderDoorPass1BackLeftBackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2L);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD2LCR, kDMZoneDoorFrameTopD2L);
+		else
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2L);
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState], _doorNativeBitmapIndexFrontD2LCR,
-					  getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2L);
+					  getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2L, kDMZoneDoorD2L);
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
@@ -3130,9 +3163,12 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2R);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD2R, kDMCellOrderDoorPass1BackRightBackLeft);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2R);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD2LCR, kDMZoneDoorFrameTopD2R);
+		else
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2R);
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD2LCR, getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2R);
+					  _doorNativeBitmapIndexFrontD2LCR, getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2R, kDMZoneDoorD2R);
 		order = kDMCellOrderDoorPass2FrontRightFrontLeft;
 		break;
 	case kDMElementTypePit:
@@ -3211,15 +3247,21 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2C);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD2C, kDMCellOrderDoorPass1BackLeftBackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2C);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD2C, doorFrameLeftD2C);
-		memcpy(_tmpBitmap, _bitmapWallSetDoorFrameLeftD2C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2));
-		drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD2C);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD2LCR, kDMZoneDoorFrameTopD2C);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD2C, kDMZoneDoorFrameLeftD2C);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD2C, kDMZoneDoorFrameRightD2C);
+		} else {
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD2LCR, doorFrameTopD2C);
+			drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD2C, doorFrameLeftD2C);
+			memcpy(_tmpBitmap, _bitmapWallSetDoorFrameLeftD2C, getPixelWidth(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2) * getPixelHeight(((_vm->getPlatform() == Common::kPlatformDOS) ? k86_FirstWallSetDOS : k77_FirstWallSet) + 2));
+			drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD2C);
+		}
 		if (dungeon.getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD2C);
 
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD2LCR, getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2C);
+					  _doorNativeBitmapIndexFrontD2LCR, getBitmapByteCount(64, 61), kDMDoorOrnamentD2LCR, &doorFrameD2C, kDMZoneDoorD2C);
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
@@ -3307,9 +3349,12 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1L);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD1L, kDMCellOrderDoorPass1BackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1L);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD1LCR, kDMZoneDoorFrameTopD1L);
+		else
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1L);
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, &doorFrameD1L);
+					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, &doorFrameD1L, kDMZoneDoorD1L);
 		order = kDMCellOrderDoorPass2FrontRight;
 		break;
 	case kDMElementTypePit:
@@ -3389,9 +3434,12 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1R);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD1R, kDMCellOrderDoorPass1BackLeft);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1R);
+		if (_vm->getPlatform() == Common::kPlatformDOS)
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD1LCR, kDMZoneDoorFrameTopD1R);
+		else
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1R);
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, &doorFrameD1R);
+					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, &doorFrameD1R, kDMZoneDoorD1R);
 		order = kDMCellOrderDoorPass2FrontLeft;
 		break;
 	case kDMElementTypePit:
@@ -3470,14 +3518,20 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1C);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD1C, kDMCellOrderDoorPass1BackLeftBackRight);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1C);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD1C, _doorFrameLeftD1C);
-		drawWallSetBitmap(_bitmapWallSetDoorFrameRightD1C, _doorFrameRightD1C);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(_bitmapWallSetDoorFrameTopD1LCR, kDMZoneDoorFrameTopD1C);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD1C, kDMZoneDoorFrameLeftD1C);
+			drawBitmapDOS(_bitmapWallSetDoorFrameLeftD1C, kDMZoneDoorFrameRightD1C, true);
+		} else {
+			drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1C);
+			drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD1C, _doorFrameLeftD1C);
+			drawWallSetBitmap(_bitmapWallSetDoorFrameRightD1C, _doorFrameRightD1C);
+		}
 		if (dungeon.getDoor(squareAspect[kDMSquareAspectDoorThingIndex])->hasButton())
 			drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD1C);
 
 		drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState],
-					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, _doorFrameD1C);
+					  _doorNativeBitmapIndexFrontD1LCR, getBitmapByteCount(96, 88), kDMDoorOrnamentD1LCR, _doorFrameD1C, kDMZoneDoorD1C);
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
@@ -4132,6 +4186,33 @@ void DisplayMan::applyCreatureReplColors(int replacedColor, int replacementColor
 		_lastVgaViewportPaletteIndex = -1;
 }
 
+void DisplayMan::drawBitmapDOS(byte *srcBitmap, int16 zoneIndex, bool flipHorizontal, Color transparentColor, uint16 explicitWidth, uint16 explicitHeight) {
+	if (!srcBitmap || zoneIndex < 0)
+		return;
+	uint16 w = explicitWidth, h = explicitHeight;
+	if (w == 0 || h == 0) {
+		if (!getBitmapDimensions(srcBitmap, w, h))
+			return;
+	}
+
+	byte *drawSrc = srcBitmap;
+	if (flipHorizontal) {
+		copyBitmapAndFlipHorizontal(srcBitmap, _tmpBitmap, w / 2, h);
+		drawSrc = _tmpBitmap;
+	}
+
+	int16 xyz[4] = { 0, 0, 0, 0 };
+	int16 inOutX = (int16)w;
+	int16 inOutY = (int16)h;
+	if (!getCoord(drawSrc, xyz, zoneIndex, &inOutX, &inOutY))
+		return;
+
+	Box destBox(xyz[0], xyz[0] + xyz[2] - 1, xyz[1], xyz[1] + xyz[3] - 1);
+	uint16 srcX = flipHorizontal ? (w - inOutX - xyz[2]) : (uint16)inOutX;
+	blitToBitmap(drawSrc, _bitmapViewport, destBox, srcX, inOutY,
+		w / 2, k112_byteWidthViewport, transparentColor, h, k136_heightViewport);
+}
+
 void DisplayMan::drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &f) {
 	if (f._srcByteWidth)
 		blitToBitmap(getNativeBitmapOrGraphic(nativeIndex), _bitmapViewport, f._box, f._srcX, f._srcY,
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 3e55fe7b64a..96f66a215ab 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -123,7 +123,35 @@ enum ZoneIndex {
 	kDMZoneWallD0C              = 715, // @ C715_ZONE_WALL_D0C
 	kDMZoneWallD0L              = 716, // @ C716_ZONE_WALL_D0L
 	kDMZoneWallD0R              = 717, // @ C717_ZONE_WALL_D0R
-	kDMZonePortraitOnWall       = 737  // @ M635_ZONE_PORTRAIT_ON_WALL
+	kDMZoneDoorFrameLeftD3L     = 718, // @ C718_ZONE_DOOR_FRAME_LEFT_D3L
+	kDMZoneDoorFrameRightD3L    = 719, // @ C719_ZONE_DOOR_FRAME_RIGHT_D3L
+	kDMZoneDoorFrameLeftD3R     = 720, // @ C720_ZONE_DOOR_FRAME_LEFT_D3R
+	kDMZoneDoorFrameRightD3R    = 721, // @ C721_ZONE_DOOR_FRAME_RIGHT_D3R
+	kDMZoneDoorFrameLeftD3C     = 722, // @ C722_ZONE_DOOR_FRAME_LEFT_D3C
+	kDMZoneDoorFrameRightD3C    = 723, // @ C723_ZONE_DOOR_FRAME_RIGHT_D3C
+	kDMZoneDoorFrameLeftD2C     = 724, // @ C724_ZONE_DOOR_FRAME_LEFT_D2C
+	kDMZoneDoorFrameRightD2C    = 725, // @ C725_ZONE_DOOR_FRAME_RIGHT_D2C
+	kDMZoneDoorFrameLeftD1C     = 726, // @ C726_ZONE_DOOR_FRAME_LEFT_D1C
+	kDMZoneDoorFrameRightD1C    = 727, // @ C727_ZONE_DOOR_FRAME_RIGHT_D1C
+	kDMZoneDoorFrameD0C         = 728, // @ C728_ZONE_DOOR_FRAME_D0C
+	kDMZoneDoorFrameTopD2L      = 729, // @ C729_ZONE_DOOR_FRAME_TOP_D2L
+	kDMZoneDoorFrameTopD2C      = 730, // @ C730_ZONE_DOOR_FRAME_TOP_D2C
+	kDMZoneDoorFrameTopD2R      = 731, // @ C731_ZONE_DOOR_FRAME_TOP_D2R
+	kDMZoneDoorFrameTopD1L      = 732, // @ C732_ZONE_DOOR_FRAME_TOP_D1L
+	kDMZoneDoorFrameTopD1C      = 733, // @ C733_ZONE_DOOR_FRAME_TOP_D1C
+	kDMZoneDoorFrameTopD1R      = 734, // @ C734_ZONE_DOOR_FRAME_TOP_D1R
+	kDMZonePortraitOnWall       = 737, // @ M635_ZONE_PORTRAIT_ON_WALL
+	kDMZoneDoorD3L2             = 3700,
+	kDMZoneDoorD3R2             = 3710,
+	kDMZoneDoorD3L              = 3720,
+	kDMZoneDoorD3C              = 3730,
+	kDMZoneDoorD3R              = 3740,
+	kDMZoneDoorD2L              = 3750,
+	kDMZoneDoorD2C              = 3760,
+	kDMZoneDoorD2R              = 3770,
+	kDMZoneDoorD1L              = 3780,
+	kDMZoneDoorD1C              = 3790,
+	kDMZoneDoorD1R              = 3800
 };
 
 enum NegGraphicIndex {
@@ -697,6 +725,7 @@ class DisplayMan {
 	void viewportSetPalette(uint16 *middleScreenPalette, uint16 *topAndBottomScreen); // @ F0565_VIEWPORT_SetPalette
 	void viewportBlitToScreen(); // @ F0566_VIEWPORT_BlitToScreen
 
+	void drawBitmapDOS(byte *srcBitmap, int16 zoneIndex, bool flipHorizontal = false, Color transparentColor = kDMColorFlesh, uint16 explicitWidth = 0, uint16 explicitHeight = 0); // @ F0791_DUNGEONVIEW_DrawBitmapXX
 	void drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &frame); // @ F0105_DUNGEONVIEW_DrawFloorPitOrStairsBitmapFlippedHorizontally
 	void drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &frame); // @ F0104_DUNGEONVIEW_DrawFloorPitOrStairsBitmap
 	void drawWallSetBitmap(byte *bitmap, Frame &f); // @ F0100_DUNGEONVIEW_DrawWallSetBitmap
@@ -875,7 +904,7 @@ public:
 	void copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height); // @ F0099_DUNGEONVIEW_CopyBitmapAndFlipHorizontal
 	void drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIndex); // @ F0108_DUNGEONVIEW_DrawFloorOrnament
 	void drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doorNativeBitmapIndices, int16 byteCount,
-					   DoorOrnament doorOrnament, DoorFrames *doorFrames); // @ F0111_DUNGEONVIEW_DrawDoor
+					   DoorOrnament doorOrnament, DoorFrames *doorFrames, int16 zoneIndexDOS = -1);
 	void drawDoorOrnament(int16 doorOrnOdinal, DoorOrnament doorOrnament); // @ F0109_DUNGEONVIEW_DrawDoorOrnament
 	void drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal); // @ F0112_DUNGEONVIEW_DrawCeilingPit
 


Commit: d9abaa14491649dcb4abd48bad5d943e02d3e398
    https://github.com/scummvm/scummvm/commit/d9abaa14491649dcb4abd48bad5d943e02d3e398
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Render spell caster controls using Layout Tree zones in DOS version

Changed paths:
    engines/dm/gfx.h
    engines/dm/menus.cpp


diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 96f66a215ab..adbd024441c 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -105,6 +105,8 @@ enum ZoneIndex {
 	kDMZoneActionArea           = 11,  // @ C011_ZONE_ACTION_AREA
 	kDMZoneSpellArea            = 13,  // @ C013_ZONE_SPELL_AREA
 	kDMZoneMessageArea          = 15,  // @ C015_ZONE_MESSAGE_AREA
+	kDMZoneSpellAreaSetMagicCaster = 221, // @ C221_ZONE_SPELL_AREA_SET_MAGIC_CASTER
+	kDMZoneSpellAreaMagicCasterTab = 224, // @ C224_ZONE_SPELL_AREA_MAGIC_CASTER_TAB
 	kDMZoneViewportCeiling      = 700, // @ C700_ZONE_VIEWPORT_CEILING_AREA
 	kDMZoneViewportFloor        = 701, // @ C701_ZONE_VIEWPORT_FLOOR_AREA
 	kDMZoneWallD3L2             = 702, // @ C702_ZONE_WALL_D3L2
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 628e57bd7c9..054b689de13 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -370,8 +370,27 @@ void MenuMan::drawSpellAreaControls(ChampionIndex champIndex) {
 	int16 champHP2 = championMan._champions[2]._currHealth;
 	int16 champHP3 = championMan._champions[3]._currHealth;
 	_vm->_eventMan->showMouse();
-	if (_vm->getPlatform() != Common::kPlatformDOS)
-		_vm->_displayMan->fillScreenBox(boxSpellAreaControls, kDMColorBlack);
+	if (_vm->getPlatform() == Common::kPlatformDOS) {
+		Box zoneBox;
+		if (_vm->_displayMan->getZoneBox(kDMZoneSpellAreaSetMagicCaster, 0, zoneBox))
+			_vm->_displayMan->fillScreenBox(zoneBox, kDMColorBlack);
+
+		int16 tabZoneIndex = (champIndex * 5) + kDMZoneSpellAreaMagicCasterTab;
+		for (int16 cIdx = 0; cIdx < 4; cIdx++) {
+			if (championMan._champions[cIdx]._currHealth && (championMan._partyChampionCount > cIdx)) {
+				Box highlightBox;
+				if (_vm->_displayMan->getZoneBox(tabZoneIndex + cIdx, 0, highlightBox))
+					_vm->_eventMan->highlightScreenBox(highlightBox._rect.left, highlightBox._rect.right, highlightBox._rect.top, highlightBox._rect.bottom);
+			}
+		}
+
+		Box nameBox;
+		if (_vm->_displayMan->getZoneBox(tabZoneIndex + 4, 0, nameBox))
+			_vm->_textMan->printToLogicalScreen(nameBox._rect.left + 2, nameBox._rect.bottom - 1, kDMColorBlack, kDMColorCyan, champ->_name);
+		_vm->_eventMan->hideMouse();
+		return;
+	}
+	_vm->_displayMan->fillScreenBox(boxSpellAreaControls, kDMColorBlack);
 
 	switch (champIndex) {
 	case 0:


Commit: 3c7631ebd51b39cbf04fe9e56627011fbe9e657f
    https://github.com/scummvm/scummvm/commit/3c7631ebd51b39cbf04fe9e56627011fbe9e657f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Map object names graphic index in DOS version

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h
    engines/dm/objectman.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 9255bcd96a0..4a42250c28a 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2053,6 +2053,8 @@ uint16 DisplayMan::getGraphicIndex(uint16 index) const {
 		return k9_MenuSpellAreaLinesDOS;
 	case kDMGraphicIdxFont:
 		return k695_FontDOS;
+	case kDMObjectNamesGraphicIndice:
+		return k694_ObjectNamesDOS;
 	default:
 		return index;
 	}
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index adbd024441c..ed21e69567e 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -388,7 +388,8 @@ enum GraphicIndice {
 	kDMGraphicIdxFirstExplosionPattern = 351, // @ C351_GRAPHIC_FIRST_EXPLOSION_PATTERN
 	kDMGraphicIdxFirstObject = 360, // @ C360_GRAPHIC_FIRST_OBJECT
 	kDMGraphicIdxFirstCreature = 446, // @ C446_GRAPHIC_FIRST_CREATURE
-	kDMGraphicIdxFont = 557 // @ C557_GRAPHIC_FONT
+	kDMGraphicIdxFont = 557, // @ C557_GRAPHIC_FONT
+	kDMObjectNamesGraphicIndice = 556 // @ C556_GRAPHIC_OBJECT_NAMES
 };
 
 #define kDMMaskDoorInfoCreaturesCanSeeThrough 0x0001 // @ MASK0x0001_CREATURES_CAN_SEE_THROUGH
@@ -460,6 +461,7 @@ enum GraphicIndice {
 #define k498_FirstObjectDOS 498 // @ M612_GRAPHIC_FIRST_OBJECT
 #define k584_FirstCreatureDOS 584 // @ M618_GRAPHIC_FIRST_CREATURE
 #define k695_FontDOS 695 // @ M653_GRAPHIC_FONT
+#define k694_ObjectNamesDOS 694 // @ M564_GRAPHIC_OBJECT_NAMES
 #define k730_DerivedBitmapMaximumCount 730 // @ C730_DERIVED_BITMAP_MAXIMUM_COUNT
 
 #define k16_Scale_D3 16 // @ C16_SCALE_D3
diff --git a/engines/dm/objectman.cpp b/engines/dm/objectman.cpp
index 7181f87ea9e..98777b37442 100644
--- a/engines/dm/objectman.cpp
+++ b/engines/dm/objectman.cpp
@@ -115,29 +115,17 @@ void ObjectMan::loadObjectNames() {
 
 	_objectIconForMousePointer = new byte[16 * 16];
 
-	char *objectNames = new char[dispMan.getCompressedDataSize(kDMObjectNamesGraphicIndice) + kDMObjectNameCount];
-	Common::MemoryReadStream stream = dispMan.getCompressedData(kDMObjectNamesGraphicIndice);
-
-	if (_vm->getPlatform() == Common::kPlatformDOS) {
-		for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
-			_objectNames[objNameIndex] = objectNames;
-			byte tmpByte;
-			while ((tmpByte = stream.readByte()) != '\0') {
-				*objectNames++ = tmpByte;
-			}
-			*objectNames++ = '\0';
-		}
-	} else {
-		for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
-			_objectNames[objNameIndex] = objectNames;
-
-			byte tmpByte;
-			for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte()) // last char of object name has 7th bit on
-				*objectNames++ = tmpByte; // write while not last char
-
-			*objectNames++ = tmpByte & 0x7F; // write without the 7th bit
-			*objectNames++ = '\0'; // terminate string
-		}
+	uint16 graphicIdx = dispMan.getGraphicIndex(kDMObjectNamesGraphicIndice);
+	char *objectNames = new char[dispMan.getCompressedDataSize(graphicIdx) + kDMObjectNameCount];
+	Common::MemoryReadStream stream = dispMan.getCompressedData(graphicIdx);
+
+	for (uint16 objNameIndex = 0; objNameIndex < kDMObjectNameCount; ++objNameIndex) {
+		_objectNames[objNameIndex] = objectNames;
+		byte tmpByte;
+		for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte())
+			*objectNames++ = tmpByte;
+		*objectNames++ = tmpByte & 0x7F;
+		*objectNames++ = '\0';
 	}
 }
 


Commit: 8d5889beacf789eeb49a378a8e4803bf69d58e3c
    https://github.com/scummvm/scummvm/commit/8d5889beacf789eeb49a378a8e4803bf69d58e3c
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix Things corruption on D1 square in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 4a42250c28a..070f71a29c1 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1493,6 +1493,7 @@ void DisplayMan::loadIntoBitmap(uint16 index, byte *destBitmap) {
 			localPalette[i] = getNibble();
 		}
 
+		memset(destBitmap, kDMColorFlesh, totalPixels);
 		int32 destPos = 0;
 
 		if (width != evenWidth) {
@@ -2126,18 +2127,21 @@ void DisplayMan::drawFloorOrnament(uint16 floorOrnOrdinal, ViewFloor viewFloorIn
 		int16 nativeBitmapIndex = _currMapFloorOrnInfo[floorOrnIndex].nativeIndice
 			+ g191_floorOrnNativeBitmapndexInc[viewFloorIndex];
 		uint16 *coordSets = g206_floorOrnCoordSets[_currMapFloorOrnInfo[floorOrnIndex].coordinateSet][viewFloorIndex];
+		uint16 floorByteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(nativeBitmapIndex) / 2) : coordSets[4];
+		uint16 floorHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeBitmapIndex) : coordSets[5];
+
 		byte *bitmap;
 		if ((viewFloorIndex == kDMViewFloorD1R) || (viewFloorIndex == kDMViewFloorD2R)
 			|| (viewFloorIndex == kDMViewFloorD3R)
 			|| ((floorOrnIndex == k15_FloorOrnFootprints) && _useFlippedWallAndFootprintsBitmap &&
 			((viewFloorIndex == kDMViewFloorD1C) || (viewFloorIndex == kDMViewFloorD2C) || (viewFloorIndex == kDMViewFloorD3C)))) {
 			bitmap = _tmpBitmap;
-			copyBitmapAndFlipHorizontal(getNativeBitmapOrGraphic(nativeBitmapIndex), bitmap, coordSets[4], coordSets[5]);
+			copyBitmapAndFlipHorizontal(getNativeBitmapOrGraphic(nativeBitmapIndex), bitmap, floorByteWidth, floorHeight);
 		} else
 			bitmap = getNativeBitmapOrGraphic(nativeBitmapIndex);
 
 		Box blitBox(coordSets[0], coordSets[1], coordSets[2], coordSets[3]);
-		blitToBitmap(bitmap, _bitmapViewport, blitBox, 0, 0, coordSets[4], k112_byteWidthViewport, kDMColorFlesh, coordSets[5], k136_heightViewport);
+		blitToBitmap(bitmap, _bitmapViewport, blitBox, 0, 0, floorByteWidth, k112_byteWidthViewport, kDMColorFlesh, floorHeight, k136_heightViewport);
 	}
 
 	if (drawFootprints)
@@ -4216,16 +4220,21 @@ void DisplayMan::drawBitmapDOS(byte *srcBitmap, int16 zoneIndex, bool flipHorizo
 }
 
 void DisplayMan::drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &f) {
-	if (f._srcByteWidth)
+	if (f._srcByteWidth) {
+		uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(nativeIndex) / 2) : f._srcByteWidth;
+		uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeIndex) : f._srcHeight;
 		blitToBitmap(getNativeBitmapOrGraphic(nativeIndex), _bitmapViewport, f._box, f._srcX, f._srcY,
-						f._srcByteWidth, k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
+						byteWidth, k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
+	}
 }
 
 void DisplayMan::drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &f) {
 	if (f._srcByteWidth) {
-		copyBitmapAndFlipHorizontal(getNativeBitmapOrGraphic(nativeIndex), _tmpBitmap, f._srcByteWidth, f._srcHeight);
-		blitToBitmap(_tmpBitmap, _bitmapViewport, f._box, f._srcX, f._srcY, f._srcByteWidth,
-						k112_byteWidthViewport, kDMColorFlesh, f._srcHeight, k136_heightViewport);
+		uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(nativeIndex) / 2) : f._srcByteWidth;
+		uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeIndex) : f._srcHeight;
+		copyBitmapAndFlipHorizontal(getNativeBitmapOrGraphic(nativeIndex), _tmpBitmap, byteWidth, height);
+		blitToBitmap(_tmpBitmap, _bitmapViewport, f._box, f._srcX, f._srcY, byteWidth,
+						k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
 	}
 }
 
@@ -4324,8 +4333,11 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 			}
 		}
 		ornBlitBitmap = getNativeBitmapOrGraphic(ornNativeBitmapIndex);
+		uint16 ornByteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(ornNativeBitmapIndex) / 2) : ornCoordSet[4];
+		uint16 ornHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(ornNativeBitmapIndex) : ornCoordSet[5];
+
 		if (viewWallIndex == kDMViewWallD1RLeft) {
-			copyBitmapAndFlipHorizontal(ornBlitBitmap, _tmpBitmap, ornCoordSet[4], ornCoordSet[5]);
+			copyBitmapAndFlipHorizontal(ornBlitBitmap, _tmpBitmap, ornByteWidth, ornHeight);
 			ornBlitBitmap = _tmpBitmap;
 		}
 		blitPosX = 0;
@@ -4385,8 +4397,10 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 	}
 
 	Box tmpBox(ornCoordSet[0], ornCoordSet[1], ornCoordSet[2], ornCoordSet[3]);
+	uint16 blitByteWidth = (viewWallIndex >= kDMViewWallD1LRight && _vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(ornNativeBitmapIndex) / 2) : ornCoordSet[4];
+	uint16 blitHeight = (viewWallIndex >= kDMViewWallD1LRight && _vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(ornNativeBitmapIndex) : ornCoordSet[5];
 	blitToBitmap(ornBlitBitmap, _bitmapViewport, tmpBox, blitPosX, 0,
-		ornCoordSet[4], k112_byteWidthViewport, kDMColorFlesh, ornCoordSet[5], k136_heightViewport);
+		blitByteWidth, k112_byteWidthViewport, kDMColorFlesh, blitHeight, k136_heightViewport);
 
 	if ((viewWallIndex == kDMViewWallD1CFront) && _championPortraitOrdinal--) {
 		Box portraitBox = (_vm->getPlatform() == Common::kPlatformDOS) ? Box(88, 119, 35, 63) : boxChampionPortraitOnWall;
@@ -4803,8 +4817,8 @@ T0115015_DrawProjectileAsObject:
 					drawingGrabbableObject = ((viewLane == kDMViewLaneCenter) && !drawProjectileAsObject); /* If object is in the center lane (only D0C or D1C with condition above) and is not a projectile */
 					AL_8_shiftSetIndex = k0_ShiftSet_D0BackD1Front;
 					bitmapRedBanana = getNativeBitmapOrGraphic(AL_4_nativeBitmapIndex); /* Use base graphic, no resizing */
-					byteWidth = objectAspect->_byteWidth;
-					heightRedEagle = objectAspect->_height;
+					byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(AL_4_nativeBitmapIndex) / 2) : objectAspect->_byteWidth;
+					heightRedEagle = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(AL_4_nativeBitmapIndex) : objectAspect->_height;
 					if (flipHorizontal) {
 						copyBitmapAndFlipHorizontal(bitmapRedBanana, _tmpBitmap, byteWidth, heightRedEagle);
 						bitmapRedBanana = _tmpBitmap;
@@ -4836,7 +4850,9 @@ T0115015_DrawProjectileAsObject:
 					else {
 						bitmapGreenAnt = getNativeBitmapOrGraphic(AL_4_nativeBitmapIndex);
 						bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
-						blitToBitmapShrinkWithPalChange(bitmapGreenAnt, bitmapRedBanana, objectAspect->_byteWidth << 1, objectAspect->_height, byteWidth << 1, heightRedEagle, paletteChanges);
+						int16 srcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(AL_4_nativeBitmapIndex) : (objectAspect->_byteWidth << 1);
+						int16 srcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(AL_4_nativeBitmapIndex) : objectAspect->_height;
+						blitToBitmapShrinkWithPalChange(bitmapGreenAnt, bitmapRedBanana, srcWidth, srcHeight, byteWidth << 1, heightRedEagle, paletteChanges);
 						if (flipHorizontal)
 							flipBitmapHorizontal(bitmapRedBanana, getNormalizedByteWidth(byteWidth), heightRedEagle);
 


Commit: ca702bf41e6c953ad4773a06678a684dcfa6e8ae
    https://github.com/scummvm/scummvm/commit/ca702bf41e6c953ad4773a06678a684dcfa6e8ae
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix entrance sensor version check and completed Firestaff possession matching in DOS version

Changed paths:
    engines/dm/movesens.cpp


diff --git a/engines/dm/movesens.cpp b/engines/dm/movesens.cpp
index 228fa145f5e..eabe9d855da 100644
--- a/engines/dm/movesens.cpp
+++ b/engines/dm/movesens.cpp
@@ -815,7 +815,7 @@ void MovesensMan::processThingAdditionOrRemoval(uint16 mapX, uint16 mapY, Thing
 						continue;
 
 					// Strangerke: 20 is a hardcoded version of the game. later version uses 21. Not present in the original dungeons anyway.
-					triggerSensor = (curSensorData <= 20);
+					triggerSensor = (curSensorData <= 21);
 					break;
 				default:
 					continue;
@@ -885,14 +885,19 @@ bool MovesensMan::isObjectInPartyPossession(int16 objectType) {
 				}
 
 				int16 curObjectType = _vm->_objectMan->getObjectType(curThing);
-				if (curObjectType == objectType)
+				if ((curObjectType == objectType) ||
+					((objectType == kDMIconIndiceWeaponTheFirestaff || objectType == kDMIconIndiceWeaponTheFirestaffComplete) &&
+					(curObjectType == kDMIconIndiceWeaponTheFirestaff || curObjectType == kDMIconIndiceWeaponTheFirestaffComplete)))
 					return true;
 
 				if (curObjectType == kDMIconIndiceContainerChestClosed) {
 					Container *container = dungeon.getContainer(curThing);
 					curThing = container->getSlot();
 					while (curThing != _vm->_thingEndOfList) {
-						if (_vm->_objectMan->getObjectType(curThing) == objectType)
+						int16 chestObjectType = _vm->_objectMan->getObjectType(curThing);
+						if ((chestObjectType == objectType) ||
+							((objectType == kDMIconIndiceWeaponTheFirestaff || objectType == kDMIconIndiceWeaponTheFirestaffComplete) &&
+							(chestObjectType == kDMIconIndiceWeaponTheFirestaff || chestObjectType == kDMIconIndiceWeaponTheFirestaffComplete)))
 							return true;
 
 						curThing = dungeon.getNextThing(curThing);


Commit: 8df46ac95ad5686c18627f69090b32f23bd7fd6d
    https://github.com/scummvm/scummvm/commit/8df46ac95ad5686c18627f69090b32f23bd7fd6d
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix teleporter and fluxcage field graphic index mapping in DOS

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 070f71a29c1..603a5c1bfd0 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2050,6 +2050,10 @@ uint16 DisplayMan::getGraphicIndex(uint16 index) const {
 		return k498_FirstObjectDOS;
 	case kDMGraphicIdxFirstCreature:
 		return k584_FirstCreatureDOS;
+	case kDMGraphicIdxFieldMaskD3R:
+		return 70;
+	case kDMGraphicIdxFieldTeleporter:
+		return 76;
 	case kDMGraphicIdxMenuSpellAreLines:
 		return k9_MenuSpellAreaLinesDOS;
 	case kDMGraphicIdxFont:
@@ -4454,7 +4458,7 @@ void DisplayMan::drawField(FieldAspect *fieldAspect, Box& box) {
 
 	if (fieldAspect->_mask != kMaskFieldAspectNoMask) {
 		bitmapMask = _tmpBitmap;
-		memmove(bitmapMask, getNativeBitmapOrGraphic(kDMGraphicIdxFieldMaskD3R + getFlag(fieldAspect->_mask, kMaskFieldAspectIndex)),
+		memmove(bitmapMask, getNativeBitmapOrGraphic(getGraphicIndex(kDMGraphicIdxFieldMaskD3R) + getFlag(fieldAspect->_mask, kMaskFieldAspectIndex)),
 				fieldAspect->_height * fieldAspect->_byteWidth * 2);
 		if (getFlag(fieldAspect->_mask, kMaskFieldAspectFlipMask)) {
 			flipBitmapHorizontal(bitmapMask, fieldAspect->_byteWidth, fieldAspect->_height);
@@ -4462,7 +4466,7 @@ void DisplayMan::drawField(FieldAspect *fieldAspect, Box& box) {
 	}
 
 	isDerivedBitmapInCache(kDMDerivedBitmapViewport);
-	byte *bitmap = getNativeBitmapOrGraphic(kDMGraphicIdxFieldTeleporter + fieldAspect->_nativeBitmapRelativeIndex);
+	byte *bitmap = getNativeBitmapOrGraphic(getGraphicIndex(kDMGraphicIdxFieldTeleporter) + fieldAspect->_nativeBitmapRelativeIndex);
 	blitBoxFilledWithMaskedBitmap(bitmap, _bitmapViewport, bitmapMask, getDerivedBitmap(kDMDerivedBitmapViewport), box,
 									   _vm->getRandomNumber(2) + fieldAspect->_baseStartUnitIndex, _vm->getRandomNumber(32), k112_byteWidthViewport,
 									   fieldAspect->_transparentColor, fieldAspect->_xPos, 0, 136, fieldAspect->_bitplaneWordCount);


Commit: 108b3b4f8e9dedc59d3f19d7c964051ef52c2350
    https://github.com/scummvm/scummvm/commit/108b3b4f8e9dedc59d3f19d7c964051ef52c2350
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix item scaling calculation on D2 and D3 tiles in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 603a5c1bfd0..f278e3529b6 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -4831,16 +4831,18 @@ T0115015_DrawProjectileAsObject:
 					drawingGrabbableObject = false;
 					derivedBitmapIndex = kDMDerivedBitmapFirstObject + objectAspect->_firstDerivedBitmapRelativeIndex;
 					byte *paletteChanges;
+					uint16 baseByteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(AL_4_nativeBitmapIndex) / 2) : objectAspect->_byteWidth;
+					uint16 baseHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(AL_4_nativeBitmapIndex) : objectAspect->_height;
 					if ((viewSquareIndex >= kDMViewSquareD1C) || ((viewSquareIndex >= kDMViewSquareD2C) && (AL_2_viewCell >= kDMViewCellBackRight))) {
 						derivedBitmapIndex++;
 						AL_8_shiftSetIndex = k1_ShiftSet_D1BackD2Front;
-						byteWidth = getScaledDimension(objectAspect->_byteWidth, k20_Scale_D2);
-						heightRedEagle = getScaledDimension(objectAspect->_height, k20_Scale_D2);
+						byteWidth = getScaledDimension(baseByteWidth, k20_Scale_D2);
+						heightRedEagle = getScaledDimension(baseHeight, k20_Scale_D2);
 						paletteChanges = _palChangesFloorOrnD2;
 					} else {
 						AL_8_shiftSetIndex = k2_ShiftSet_D2BackD3Front;
-						byteWidth = getScaledDimension(objectAspect->_byteWidth, k16_Scale_D3);
-						heightRedEagle = getScaledDimension(objectAspect->_height, k16_Scale_D3);
+						byteWidth = getScaledDimension(baseByteWidth, k16_Scale_D3);
+						heightRedEagle = getScaledDimension(baseHeight, k16_Scale_D3);
 						paletteChanges = _palChangesFloorOrnD3;
 					}
 					if (flipHorizontal) {


Commit: 3a1e8046ed1e086fba5481144931789ad758b344
    https://github.com/scummvm/scummvm/commit/3a1e8046ed1e086fba5481144931789ad758b344
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix door button placement using kDMZoneDoorButton layout zone in DOS version

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index f278e3529b6..24f50599ad3 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -1434,9 +1434,13 @@ void DisplayMan::drawDoorButton(int16 doorButtonOrdinal, DoorButton doorButton)
 			}
 			bitmap = getDerivedBitmap(doorButtonOrdinal);
 		}
-		Box blitBox(coordSetRedEagle[0], coordSetRedEagle[1], coordSetRedEagle[2], coordSetRedEagle[3]);
-		blitToBitmap(bitmap, _bitmapViewport, blitBox, 0, 0,
-						  coordSetRedEagle[4], k112_byteWidthViewport, kDMColorFlesh, coordSetRedEagle[5], k136_heightViewport);
+		if (_vm->getPlatform() == Common::kPlatformDOS) {
+			drawBitmapDOS(bitmap, kDMZoneDoorButton + coordSet + doorButton, false, kDMColorFlesh);
+		} else {
+			Box blitBox(coordSetRedEagle[0], coordSetRedEagle[1], coordSetRedEagle[2], coordSetRedEagle[3]);
+			blitToBitmap(bitmap, _bitmapViewport, blitBox, 0, 0,
+							  coordSetRedEagle[4], k112_byteWidthViewport, kDMColorFlesh, coordSetRedEagle[5], k136_heightViewport);
+		}
 	}
 }
 
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index ed21e69567e..1502b7884a6 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -143,6 +143,7 @@ enum ZoneIndex {
 	kDMZoneDoorFrameTopD1C      = 733, // @ C733_ZONE_DOOR_FRAME_TOP_D1C
 	kDMZoneDoorFrameTopD1R      = 734, // @ C734_ZONE_DOOR_FRAME_TOP_D1R
 	kDMZonePortraitOnWall       = 737, // @ M635_ZONE_PORTRAIT_ON_WALL
+	kDMZoneDoorButton           = 1950, // @ C1950_ZONE_DOOR_BUTTON
 	kDMZoneDoorD3L2             = 3700,
 	kDMZoneDoorD3R2             = 3710,
 	kDMZoneDoorD3L              = 3720,


Commit: 28ef69171af13eae240c94db5c5977be6855f40d
    https://github.com/scummvm/scummvm/commit/28ef69171af13eae240c94db5c5977be6855f40d
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix thrown object and projectile scaling calculation in DOS version

Changed paths:
    engines/dm/gfx.cpp


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 24f50599ad3..269212f16b6 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -5194,18 +5194,21 @@ T0115129_DrawProjectiles:
 					projectileAspectType = getFlag(((ProjectileAspect *)objectAspect)->_graphicInfo, k0x0003_ProjectileAspectTypeMask);
 
 					bool doNotScaleWithKineticEnergy = !getFlag(((ProjectileAspect *)objectAspect)->_graphicInfo, k0x0100_ProjectileScaleWithKineticEnergyMask);
+					uint16 projBaseByteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(AL_4_nativeBitmapIndex) / 2) : ((ProjectileAspect *)objectAspect)->_byteWidth;
+					uint16 projBaseHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(AL_4_nativeBitmapIndex) : ((ProjectileAspect *)objectAspect)->_height;
+
 					if ((doNotScaleWithKineticEnergy || (projectile->_kineticEnergy == 255)) && (viewSquareIndex == kDMViewSquareD0C)) {
 						scale = 0; /* Use native bitmap without resizing */
-						byteWidth = ((ProjectileAspect *)objectAspect)->_byteWidth;
-						heightRedEagle = ((ProjectileAspect *)objectAspect)->_height;
+						byteWidth = projBaseByteWidth;
+						heightRedEagle = projBaseHeight;
 					} else {
 						AL_8_projectileScaleIndex = ((viewSquareIndex / 3) << 1) + (AL_2_viewCell >> 1);
 						scale = _projectileScales[AL_8_projectileScaleIndex];
 						if (!doNotScaleWithKineticEnergy) {
 							scale = (scale * MAX(96, projectile->_kineticEnergy + 1)) >> 8;
 						}
-						byteWidth = getScaledDimension(((ProjectileAspect *)objectAspect)->_byteWidth, scale);
-						heightRedEagle = getScaledDimension(((ProjectileAspect *)objectAspect)->_height, scale);
+						byteWidth = getScaledDimension(projBaseByteWidth, scale);
+						heightRedEagle = getScaledDimension(projBaseHeight, scale);
 					}
 					bool projectileAspectTypeHasBackGraphicAndRotation = (projectileAspectType == k0_ProjectileAspectHasBackGraphicRotation);
 					if (projectileAspectTypeHasBackGraphicAndRotation)
@@ -5258,7 +5261,9 @@ T0115129_DrawProjectiles:
 							else
 								bitmapRedBanana = _tmpBitmap;
 
-							blitToBitmapShrinkWithPalChange(bitmapGreenAnt, bitmapRedBanana, ((ProjectileAspect *)objectAspect)->_byteWidth << 1, ((ProjectileAspect *)objectAspect)->_height, byteWidth << 1, heightRedEagle, _palChangesProjectile[AL_8_projectileScaleIndex >> 1]);
+							int16 projSrcWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelWidth(AL_4_nativeBitmapIndex) : (((ProjectileAspect *)objectAspect)->_byteWidth << 1);
+							int16 projSrcHeight = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(AL_4_nativeBitmapIndex) : ((ProjectileAspect *)objectAspect)->_height;
+							blitToBitmapShrinkWithPalChange(bitmapGreenAnt, bitmapRedBanana, projSrcWidth, projSrcHeight, byteWidth << 1, heightRedEagle, _palChangesProjectile[AL_8_projectileScaleIndex >> 1]);
 							if (doNotScaleWithKineticEnergy) {
 								addDerivedBitmap(derivedBitmapIndex);
 							}


Commit: d67d4cce66530428d3d5cd51ac4b50486aeb05db
    https://github.com/scummvm/scummvm/commit/d67d4cce66530428d3d5cd51ac4b50486aeb05db
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-08-07T22:30:11+02:00

Commit Message:
DM: Fix floor/ceiling pit positioning and stairs graphic mapping in DOS version

Changed paths:
    engines/dm/gfx.cpp
    engines/dm/gfx.h


diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 269212f16b6..24e4777187e 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2027,6 +2027,10 @@ uint16 DisplayMan::getGraphicIndex(uint16 index) const {
 	if (_vm->getPlatform() != Common::kPlatformDOS)
 		return index;
 
+	// On DOS, shift all floor and ceiling pit graphic indices up by +1 relative to Amiga
+	if (index >= kDMGraphicIdxFloorPitD3L && index <= kDMGraphicIdxCeilingPitD0C)
+		return index + 1;
+
 	switch (index) {
 	case k90_FirstStairs:
 		return k108_FirstStairsDOS;
@@ -2257,7 +2261,7 @@ void DisplayMan::drawDoorOrnament(int16 doorOrnOrdinal, DoorOrnament doorOrnamen
 	blitToBitmap(blitBitmap, _tmpBitmap, box, 0, 0, coordSetOrangeElk[4], byteWidth, kDMColorGold, coordSetOrangeElk[5], height);
 }
 
-void DisplayMan::drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal) {
+void DisplayMan::drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal, int16 zoneIndexDOS) {
 	DungeonMan &dungeon = *_vm->_dungeonMan;
 
 	int16 mapIndex = dungeon.getLocationAfterLevelChange(dungeon._currMapIndex, -1, &mapX, &mapY);
@@ -2268,9 +2272,9 @@ void DisplayMan::drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 map
 	int16 mapSquare = dungeon._dungeonMapData[mapIndex][mapX][mapY];
 	if ((Square(mapSquare).getType() == kDMElementTypePit) && getFlag(mapSquare, kDMSquareMaskPitOpen)) {
 		if (flipHorizontal)
-			drawFloorPitOrStairsBitmapFlippedHorizontally(nativeBitmapIndex, *frame);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(nativeBitmapIndex, *frame, zoneIndexDOS);
 		else
-			drawFloorPitOrStairsBitmap(nativeBitmapIndex, *frame);
+			drawFloorPitOrStairsBitmap(nativeBitmapIndex, *frame, zoneIndexDOS);
 	}
 }
 
@@ -2333,9 +2337,9 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD3L, frameStairsUpFrontD3L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD3L, frameStairsUpFrontD3L, kDMZoneStairsUpFrontD3L);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD3L, frameStairsDownFrontD3L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD3L, frameStairsDownFrontD3L, kDMZoneStairsDownFrontD3L);
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3L);
@@ -2372,7 +2376,7 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		if (!squareAspect[kDMSquareAspectPitInvisible])
-			drawFloorPitOrStairsBitmap(kDMGraphicIdxFloorPitD3L, frameFloorPitD3L);
+			drawFloorPitOrStairsBitmap(kDMGraphicIdxFloorPitD3L, frameFloorPitD3L, kDMZoneFloorPitD3L);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
@@ -2419,9 +2423,9 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD3L, frameStairsUpFrontD3R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD3L, frameStairsUpFrontD3R, kDMZoneStairsUpFrontD3R);
 		else
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD3L, frameStairsDownFrontD3R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD3L, frameStairsDownFrontD3R, kDMZoneStairsDownFrontD3R);
 
 		order = kDMCellOrderBackRightBackLeftFrontRightFrontLeft;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
@@ -2463,7 +2467,7 @@ void DisplayMan::drawSquareD3R(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		if (!squareAspect[kDMSquareAspectPitInvisible])
-			drawFloorPitOrStairsBitmapFlippedHorizontally(kDMGraphicIdxFloorPitD3L, frameFloorPitD3R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(kDMGraphicIdxFloorPitD3L, frameFloorPitD3R, kDMZoneFloorPitD3R);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
@@ -2513,9 +2517,9 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD3C, frameStairsUpFrontD3C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD3C, frameStairsUpFrontD3C, kDMZoneStairsUpFrontD3C);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD3C, frameStairsDownFrontD3C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD3C, frameStairsDownFrontD3C, kDMZoneStairsDownFrontD3C);
 
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD3C); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
@@ -2551,7 +2555,7 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		if (!squareAspect[kDMSquareAspectPitInvisible])
-			drawFloorPitOrStairsBitmap(kDMGraphicIdxFloorPitD3C, frameFloorPitD3C);
+			drawFloorPitOrStairsBitmap(kDMGraphicIdxFloorPitD3C, frameFloorPitD3C, kDMZoneFloorPitD3C);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
@@ -2599,9 +2603,9 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD2L, frameStairsUpFrontD2L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD2L, frameStairsUpFrontD2L, kDMZoneStairsUpFrontD2L);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD2L, frameStairsDownFrontD2L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD2L, frameStairsDownFrontD2L, kDMZoneStairsDownFrontD2L);
 
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2L); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
@@ -2618,7 +2622,7 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 			return;
 		break;
 	case kDMElementTypeStairsSide:
-		drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexSideD2L, frameStairsSideD2L);
+		drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexSideD2L, frameStairsSideD2L, kDMZoneStairsSideD2L);
 		// fall through
 	case kDMElementTypeDoorSide:
 		order = kDMCellOrderBackRightFrontLeftFrontRight;
@@ -2637,7 +2641,7 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD2L : kDMGraphicIdxFloorPitD2L,
-										frameFloorPitD2L);
+										frameFloorPitD2L, kDMZoneFloorPitD2L);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
@@ -2651,7 +2655,7 @@ void DisplayMan::drawSquareD2L(Direction dir, int16 posX, int16 posY) {
 	}
 
 	if (!skip) {
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &FrameCeilingPitD2L, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &FrameCeilingPitD2L, posX, posY, false, kDMZoneCeilingPitD2L);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD2L, order);
 	}
 
@@ -3145,14 +3149,14 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD2L, frameStairsUpFrontD2R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD2L, frameStairsUpFrontD2R, kDMZoneStairsUpFrontD2R);
 		else
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD2L, frameStairsDownFrontD2R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD2L, frameStairsDownFrontD2R, kDMZoneStairsDownFrontD2R);
 
 		order = kDMCellOrderBackRightBackLeftFrontRightFrontLeft;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2R);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true, kDMZoneCeilingPitD2R);
 		break;
 	case kDMElementTypeWall:
 		if (_vm->getPlatform() == Common::kPlatformDOS)
@@ -3166,13 +3170,13 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 			return;
 		break;
 	case kDMElementTypeStairsSide:
-		drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexSideD2L, frameStairsSideD2R);
+		drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexSideD2L, frameStairsSideD2R, kDMZoneStairsSideD2R);
 		// fall through
 	case kDMElementTypeDoorSide:
 		order = kDMCellOrderBackLeftFrontRightFrontLeft;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2R);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true, kDMZoneCeilingPitD2R);
 		break;
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2R);
@@ -3187,14 +3191,14 @@ void DisplayMan::drawSquareD2R(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		drawFloorPitOrStairsBitmapFlippedHorizontally(
-			squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD2L : kDMGraphicIdxFloorPitD2L, frameFloorPitD2R);
+			squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD2L : kDMGraphicIdxFloorPitD2L, frameFloorPitD2R, kDMZoneFloorPitD2R);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
 		order = kDMCellOrderBackRightBackLeftFrontRightFrontLeft;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2R);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2L, &frameCeilingPitD2R, posX, posY, true, kDMZoneCeilingPitD2R);
 		break;
 	default:
 		skip = true;
@@ -3239,14 +3243,14 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD2C, frameStairsUpFrontD2C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD2C, frameStairsUpFrontD2C, kDMZoneStairsUpFrontD2C);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD2C, frameStairsDownFrontD2C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD2C, frameStairsDownFrontD2C, kDMZoneStairsDownFrontD2C);
 
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2C);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2C, &frameCeilingPitD2C, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2C, &frameCeilingPitD2C, posX, posY, false, kDMZoneCeilingPitD2C);
 		break;
 	case kDMElementTypeWall:
 		if (_vm->getPlatform() == Common::kPlatformDOS)
@@ -3279,14 +3283,14 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) {
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
-		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD2C : kDMGraphicIdxFloorPitD2C, frameFloorPitD2C);
+		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD2C : kDMGraphicIdxFloorPitD2C, frameFloorPitD2C, kDMZoneFloorPitD2C);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD2C);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD2C, &frameCeilingPitD2C, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD2C, &frameCeilingPitD2C, posX, posY, false, kDMZoneCeilingPitD2C);
 		break;
 	default:
 		skip = true;
@@ -3330,14 +3334,14 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD1L, frameStairsUpFrontD1L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD1L, frameStairsUpFrontD1L, kDMZoneStairsUpFrontD1L);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD1L, frameStairsDownFrontD1L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD1L, frameStairsDownFrontD1L, kDMZoneStairsDownFrontD1L);
 
 		order = kDMCellOrderBackRightFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1L);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false, kDMZoneCeilingPitD1L);
 		break;
 	case kDMElementTypeWall:
 		if (_vm->getPlatform() == Common::kPlatformDOS)
@@ -3348,9 +3352,9 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 		return;
 	case kDMElementTypeStairsSide:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpSideD1L, frameStairsUpSideD1L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpSideD1L, frameStairsUpSideD1L, kDMZoneStairsUpSideD1L);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownSideD1L, frameStairsDownSideD1L);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownSideD1L, frameStairsDownSideD1L, kDMZoneStairsDownSideD1L);
 		// fall through
 	case kDMElementTypeDoorSide:
 	case kDMElementTypeTeleporter:
@@ -3358,7 +3362,7 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 		order = kDMCellOrderBackRightFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1L);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1L, posX, posY, false, kDMZoneCeilingPitD1L);
 		break;
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1L);
@@ -3372,7 +3376,7 @@ void DisplayMan::drawSquareD1L(Direction dir, int16 posX, int16 posY) {
 		order = kDMCellOrderDoorPass2FrontRight;
 		break;
 	case kDMElementTypePit:
-		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD1L : kDMGraphicIdxFloorPitD1L, frameFloorPitD1L);
+		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD1L : kDMGraphicIdxFloorPitD1L, frameFloorPitD1L, kDMZoneFloorPitD1L);
 		// fall through
 	default:
 		skip = true;
@@ -3416,13 +3420,13 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD1L, frameStairsUpFrontD1R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD1L, frameStairsUpFrontD1R, kDMZoneStairsUpFrontD1R);
 		else
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD1L, frameStairsDownFrontD1R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD1L, frameStairsDownFrontD1R, kDMZoneStairsDownFrontD1R);
 
 		order = kDMCellOrderBackLeftFrontLeft;
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1R); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true, kDMZoneCeilingPitD1R);
 		break;
 	case kDMElementTypeWall:
 		if (_vm->getPlatform() == Common::kPlatformDOS)
@@ -3433,9 +3437,9 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 		return;
 	case kDMElementTypeStairsSide:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpSideD1L, frameStairsUpSideD1R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpSideD1L, frameStairsUpSideD1R, kDMZoneStairsUpSideD1R);
 		else
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownSideD1L, frameStairsDownSideD1R);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownSideD1L, frameStairsDownSideD1R, kDMZoneStairsDownSideD1R);
 
 		// fall through
 	case kDMElementTypeDoorSide:
@@ -3443,7 +3447,7 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 	case kDMElementTypeCorridor:
 		order = kDMCellOrderBackLeftFrontLeft;
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1R); /* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1L, &frameCeilingPitD1R, posX, posY, true, kDMZoneCeilingPitD1R);
 		break;
 	case kDMElementTypeDoorFront:
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1R);
@@ -3458,7 +3462,7 @@ void DisplayMan::drawSquareD1R(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypePit:
 		drawFloorPitOrStairsBitmapFlippedHorizontally(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD1L
-														   : kDMGraphicIdxFloorPitD1L, frameFloorPitD1R);
+														   : kDMGraphicIdxFloorPitD1L, frameFloorPitD1R, kDMZoneFloorPitD1R);
 		// fall through
 	default:
 		skip = true;
@@ -3492,14 +3496,14 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) {
 	switch (dungeon._squareAheadElement = (ElementType)squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp])
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD1C, frameStairsUpFrontD1C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD1C, frameStairsUpFrontD1C, kDMZoneStairsUpFrontD1C);
 		else
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD1C, frameStairsDownFrontD1C);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD1C, frameStairsDownFrontD1C, kDMZoneStairsDownFrontD1C);
 
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1C);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1C, &frameCeilingPitD1C, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1C, &frameCeilingPitD1C, posX, posY, false, kDMZoneCeilingPitD1C);
 		break;
 	case kDMElementTypeWall:
 		dungeon._isFacingAlcove = false;
@@ -3549,14 +3553,14 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) {
 		order = kDMCellOrderDoorPass2FrontLeftFrontRight;
 		break;
 	case kDMElementTypePit:
-		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD1C : kDMGraphicIdxFloorPitD1C, frameFloorPitD1C);
+		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD1C : kDMGraphicIdxFloorPitD1C, frameFloorPitD1C, kDMZoneFloorPitD1C);
 		// fall through
 	case kDMElementTypeTeleporter:
 	case kDMElementTypeCorridor:
 		order = kDMCellOrderBackLeftBackRightFrontLeftFrontRight;
 		/* BUG0_64 Floor ornaments are drawn over open pits. There is no check to prevent drawing floor ornaments over open pits */
 		drawFloorOrnament(squareAspect[kDMSquareAspectFloorOrn], kDMViewFloorD1C);
-		drawCeilingPit(kDMGraphicIdxCeilingPitD1C, &frameCeilingPitD1C, posX, posY, false);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD1C, &frameCeilingPitD1C, posX, posY, false, kDMZoneCeilingPitD1C);
 		break;
 	default:
 		skip = true;
@@ -3579,10 +3583,10 @@ void DisplayMan::drawSquareD0L(Direction dir, int16 posX, int16 posY) {
 	_vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY);
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsSide:
-		drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexSideD0L, frameStairsSideD0L);
+		drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexSideD0L, frameStairsSideD0L, kDMZoneStairsSideD0L);
 		return;
 	case kDMElementTypePit:
-		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD0L : kDMGraphicIdxFloorPitD0L, frameFloorPitD0L);
+		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD0L : kDMGraphicIdxFloorPitD0L, frameFloorPitD0L, kDMZoneFloorPitD0L);
 		// fall through
 	case kDMElementTypeCorridor:
 	case kDMElementTypeDoorSide:
@@ -3599,7 +3603,7 @@ void DisplayMan::drawSquareD0L(Direction dir, int16 posX, int16 posY) {
 		break;
 	}
 
-	drawCeilingPit(kDMGraphicIdxCeilingPitD0L, &frameCeilingPitD0L, posX, posY, false);
+	drawCeilingPit(kDMGraphicIdxCeilingPitD0L, &frameCeilingPitD0L, posX, posY, false, kDMZoneCeilingPitD0L);
 	if ((squareAspect[kDMSquareAspectElement] == kDMElementTypeTeleporter) && squareAspect[kDMSquareAspectTeleporterVisible])
 		drawField(&_fieldAspects188[kDMViewSquareD0L], _frameWalls163[kDMViewSquareD0L]._box);
 }
@@ -3614,16 +3618,16 @@ void DisplayMan::drawSquareD0R(Direction dir, int16 posX, int16 posY) {
 	_vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY);
 	switch (squareAspect[kDMSquareAspectElement]) {
 	case kDMElementTypeStairsSide:
-		drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexSideD0L, frameStairsSideD0R);
+		drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexSideD0L, frameStairsSideD0R, kDMZoneStairsSideD0R);
 		return;
 	case kDMElementTypePit:
 		drawFloorPitOrStairsBitmapFlippedHorizontally(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD0L
-														   : kDMGraphicIdxFloorPitD0L, frameFloorPitD0R);
+														   : kDMGraphicIdxFloorPitD0L, frameFloorPitD0R, kDMZoneFloorPitD0R);
 		// fall through
 	case kDMElementTypeCorridor:
 	case kDMElementTypeDoorSide:
 	case kDMElementTypeTeleporter:
-		drawCeilingPit(kDMGraphicIdxCeilingPitD0L, &frameCeilingPitD0R, posX, posY, true);
+		drawCeilingPit(kDMGraphicIdxCeilingPitD0L, &frameCeilingPitD0R, posX, posY, true, kDMZoneCeilingPitD0R);
 		drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD0R, kDMCellOrderBackLeft);
 		break;
 	case kDMElementTypeWall:
@@ -3667,20 +3671,20 @@ void DisplayMan::drawSquareD0C(Direction dir, int16 posX, int16 posY) {
 		break;
 	case kDMElementTypeStairsFront:
 		if (squareAspect[kDMSquareAspectStairsUp]) {
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD0CLeft, frameStairsUpFrontD0L);
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD0CLeft, frameStairsUpFrontD0R);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD0CLeft, frameStairsUpFrontD0L, kDMZoneStairsUpFrontD0L);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexUpFrontD0CLeft, frameStairsUpFrontD0R, kDMZoneStairsUpFrontD0R);
 		} else {
-			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD0CLeft, frameStairsDownFrontD0L);
-			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD0CLeft, frameStairsDownFrontD0R);
+			drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexDownFrontD0CLeft, frameStairsDownFrontD0L, kDMZoneStairsDownFrontD0L);
+			drawFloorPitOrStairsBitmapFlippedHorizontally(_stairsNativeBitmapIndexDownFrontD0CLeft, frameStairsDownFrontD0R, kDMZoneStairsDownFrontD0R);
 		}
 		break;
 	case kDMElementTypePit:
-		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD0C : kDMGraphicIdxFloorPitD0C, frameFloorPitD0C);
+		drawFloorPitOrStairsBitmap(squareAspect[kDMSquareAspectPitInvisible] ? kDMGraphicIdxFloorPitInvisibleD0C : kDMGraphicIdxFloorPitD0C, frameFloorPitD0C, kDMZoneFloorPitD0C);
 		break;
 	default:
 		break;
 	}
-	drawCeilingPit(kDMGraphicIdxCeilingPitD0C, &frameCeilingPitD0C, posX, posY, false);
+	drawCeilingPit(kDMGraphicIdxCeilingPitD0C, &frameCeilingPitD0C, posX, posY, false, kDMZoneCeilingPitD0C);
 	drawObjectsCreaturesProjectilesExplosions(Thing(squareAspect[kDMSquareAspectFirstGroupOrObject]), dir, posX, posY, kDMViewSquareD0C, kDMCellOrderBackLeftBackRight);
 	if ((squareAspect[kDMSquareAspectElement] == kDMElementTypeTeleporter) && squareAspect[kDMSquareAspectTeleporterVisible])
 		drawField(&_fieldAspects188[kDMViewSquareD0C], _frameWalls163[kDMViewSquareD0C]._box);
@@ -4227,22 +4231,38 @@ void DisplayMan::drawBitmapDOS(byte *srcBitmap, int16 zoneIndex, bool flipHorizo
 		w / 2, k112_byteWidthViewport, transparentColor, h, k136_heightViewport);
 }
 
-void DisplayMan::drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &f) {
+void DisplayMan::drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &f, int16 zoneIndexDOS) {
 	if (f._srcByteWidth) {
-		uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(nativeIndex) / 2) : f._srcByteWidth;
-		uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeIndex) : f._srcHeight;
-		blitToBitmap(getNativeBitmapOrGraphic(nativeIndex), _bitmapViewport, f._box, f._srcX, f._srcY,
-						byteWidth, k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
+		uint16 dosNativeIndex = (_vm->getPlatform() == Common::kPlatformDOS && nativeIndex >= k108_FirstStairsDOS && nativeIndex < k246_FirstDoorSetDOS) ? nativeIndex : getGraphicIndex(nativeIndex);
+		byte *bitmap = getNativeBitmapOrGraphic(dosNativeIndex);
+		if (_vm->getPlatform() == Common::kPlatformDOS && zoneIndexDOS >= 0) {
+			drawBitmapDOS(bitmap, zoneIndexDOS, false, kDMColorFlesh);
+		} else {
+			uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(dosNativeIndex) / 2) : f._srcByteWidth;
+			uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(dosNativeIndex) : f._srcHeight;
+			uint16 srcX = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcX;
+			uint16 srcY = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcY;
+			blitToBitmap(bitmap, _bitmapViewport, f._box, srcX, srcY,
+							byteWidth, k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
+		}
 	}
 }
 
-void DisplayMan::drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &f) {
+void DisplayMan::drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &f, int16 zoneIndexDOS) {
 	if (f._srcByteWidth) {
-		uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(nativeIndex) / 2) : f._srcByteWidth;
-		uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(nativeIndex) : f._srcHeight;
-		copyBitmapAndFlipHorizontal(getNativeBitmapOrGraphic(nativeIndex), _tmpBitmap, byteWidth, height);
-		blitToBitmap(_tmpBitmap, _bitmapViewport, f._box, f._srcX, f._srcY, byteWidth,
-						k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
+		uint16 dosNativeIndex = (_vm->getPlatform() == Common::kPlatformDOS && nativeIndex >= k108_FirstStairsDOS && nativeIndex < k246_FirstDoorSetDOS) ? nativeIndex : getGraphicIndex(nativeIndex);
+		byte *bitmap = getNativeBitmapOrGraphic(dosNativeIndex);
+		if (_vm->getPlatform() == Common::kPlatformDOS && zoneIndexDOS >= 0) {
+			drawBitmapDOS(bitmap, zoneIndexDOS, true, kDMColorFlesh);
+		} else {
+			uint16 byteWidth = (_vm->getPlatform() == Common::kPlatformDOS) ? (getPixelWidth(dosNativeIndex) / 2) : f._srcByteWidth;
+			uint16 height = (_vm->getPlatform() == Common::kPlatformDOS) ? getPixelHeight(dosNativeIndex) : f._srcHeight;
+			copyBitmapAndFlipHorizontal(bitmap, _tmpBitmap, byteWidth, height);
+			uint16 srcX = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcX;
+			uint16 srcY = (_vm->getPlatform() == Common::kPlatformDOS) ? 0 : f._srcY;
+			blitToBitmap(_tmpBitmap, _bitmapViewport, f._box, srcX, srcY, byteWidth,
+							k112_byteWidthViewport, kDMColorFlesh, height, k136_heightViewport);
+		}
 	}
 }
 
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index 1502b7884a6..e2b9c11cb10 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -143,6 +143,57 @@ enum ZoneIndex {
 	kDMZoneDoorFrameTopD1C      = 733, // @ C733_ZONE_DOOR_FRAME_TOP_D1C
 	kDMZoneDoorFrameTopD1R      = 734, // @ C734_ZONE_DOOR_FRAME_TOP_D1R
 	kDMZonePortraitOnWall       = 737, // @ M635_ZONE_PORTRAIT_ON_WALL
+	kDMZoneStairsUpFrontD3L     = 802, // @ C802_ZONE_STAIRS_UP_FRONT_D3L
+	kDMZoneStairsUpFrontD3C     = 803, // @ C803_ZONE_STAIRS_UP_FRONT_D3C
+	kDMZoneStairsUpFrontD3R     = 804, // @ C804_ZONE_STAIRS_UP_FRONT_D3R
+	kDMZoneStairsUpFrontD2L     = 805, // @ C805_ZONE_STAIRS_UP_FRONT_D2L
+	kDMZoneStairsUpFrontD2C     = 806, // @ C806_ZONE_STAIRS_UP_FRONT_D2C
+	kDMZoneStairsUpFrontD2R     = 807, // @ C807_ZONE_STAIRS_UP_FRONT_D2R
+	kDMZoneStairsUpFrontD1L     = 808, // @ C808_ZONE_STAIRS_UP_FRONT_D1L
+	kDMZoneStairsUpFrontD1C     = 809, // @ C809_ZONE_STAIRS_UP_FRONT_D1C
+	kDMZoneStairsUpFrontD1R     = 810, // @ C810_ZONE_STAIRS_UP_FRONT_D1R
+	kDMZoneStairsUpFrontD0L     = 811, // @ C811_ZONE_STAIRS_UP_FRONT_D0L
+	kDMZoneStairsUpFrontD0R     = 812, // @ C812_ZONE_STAIRS_UP_FRONT_D0R
+	kDMZoneStairsDownFrontD3L   = 815, // @ C815_ZONE_STAIRS_DOWN_FRONT_D3L
+	kDMZoneStairsDownFrontD3C   = 816, // @ C816_ZONE_STAIRS_DOWN_FRONT_D3C
+	kDMZoneStairsDownFrontD3R   = 817, // @ C817_ZONE_STAIRS_DOWN_FRONT_D3R
+	kDMZoneStairsDownFrontD2L   = 818, // @ C818_ZONE_STAIRS_DOWN_FRONT_D2L
+	kDMZoneStairsDownFrontD2C   = 819, // @ C819_ZONE_STAIRS_DOWN_FRONT_D2C
+	kDMZoneStairsDownFrontD2R   = 820, // @ C820_ZONE_STAIRS_DOWN_FRONT_D2R
+	kDMZoneStairsDownFrontD1L   = 821, // @ C821_ZONE_STAIRS_DOWN_FRONT_D1L
+	kDMZoneStairsDownFrontD1C   = 822, // @ C822_ZONE_STAIRS_DOWN_FRONT_D1C
+	kDMZoneStairsDownFrontD1R   = 823, // @ C823_ZONE_STAIRS_DOWN_FRONT_D1R
+	kDMZoneStairsDownFrontD0L   = 824, // @ C824_ZONE_STAIRS_DOWN_FRONT_D0L
+	kDMZoneStairsDownFrontD0R   = 825, // @ C825_ZONE_STAIRS_DOWN_FRONT_D0R
+	kDMZoneStairsSideD2L        = 826, // @ C826_ZONE_STAIRS_SIDE_D2L
+	kDMZoneStairsSideD2R        = 827, // @ C827_ZONE_STAIRS_SIDE_D2R
+	kDMZoneStairsUpSideD1L      = 828, // @ C828_ZONE_STAIRS_UP_SIDE_D1L
+	kDMZoneStairsUpSideD1R      = 829, // @ C829_ZONE_STAIRS_UP_SIDE_D1R
+	kDMZoneStairsDownSideD1L    = 830, // @ C830_ZONE_STAIRS_DOWN_SIDE_D1L
+	kDMZoneStairsDownSideD1R    = 831, // @ C831_ZONE_STAIRS_DOWN_SIDE_D1R
+	kDMZoneStairsSideD0L        = 832, // @ C832_ZONE_STAIRS_SIDE_D0L
+	kDMZoneStairsSideD0R        = 833, // @ C833_ZONE_STAIRS_SIDE_D0R
+	kDMZoneFloorPitD3L          = 852, // @ C852_ZONE_FLOORPIT_D3L
+	kDMZoneFloorPitD3C          = 853, // @ C853_ZONE_FLOORPIT_D3C
+	kDMZoneFloorPitD3R          = 854, // @ C854_ZONE_FLOORPIT_D3R
+	kDMZoneFloorPitD2L          = 855, // @ C855_ZONE_FLOORPIT_D2L
+	kDMZoneFloorPitD2C          = 856, // @ C856_ZONE_FLOORPIT_D2C
+	kDMZoneFloorPitD2R          = 857, // @ C857_ZONE_FLOORPIT_D2R
+	kDMZoneFloorPitD1L          = 858, // @ C858_ZONE_FLOORPIT_D1L
+	kDMZoneFloorPitD1C          = 859, // @ C859_ZONE_FLOORPIT_D1C
+	kDMZoneFloorPitD1R          = 860, // @ C860_ZONE_FLOORPIT_D1R
+	kDMZoneFloorPitD0L          = 861, // @ C861_ZONE_FLOORPIT_D0L
+	kDMZoneFloorPitD0C          = 862, // @ C862_ZONE_FLOORPIT_D0C
+	kDMZoneFloorPitD0R          = 863, // @ C863_ZONE_FLOORPIT_D0R
+	kDMZoneCeilingPitD2L        = 864, // @ C864_ZONE_CEILING_PIT_D2L
+	kDMZoneCeilingPitD2C        = 865, // @ C865_ZONE_CEILING_PIT_D2C
+	kDMZoneCeilingPitD2R        = 866, // @ C866_ZONE_CEILING_PIT_D2R
+	kDMZoneCeilingPitD1L        = 867, // @ C867_ZONE_CEILING_PIT_D1L
+	kDMZoneCeilingPitD1C        = 868, // @ C868_ZONE_CEILING_PIT_D1C
+	kDMZoneCeilingPitD1R        = 869, // @ C869_ZONE_CEILING_PIT_D1R
+	kDMZoneCeilingPitD0L        = 870, // @ C870_ZONE_CEILING_PIT_D0L
+	kDMZoneCeilingPitD0C        = 871, // @ C871_ZONE_CEILING_PIT_D0C
+	kDMZoneCeilingPitD0R        = 872, // @ C872_ZONE_CEILING_PIT_D0R
 	kDMZoneDoorButton           = 1950, // @ C1950_ZONE_DOOR_BUTTON
 	kDMZoneDoorD3L2             = 3700,
 	kDMZoneDoorD3R2             = 3710,
@@ -731,8 +782,8 @@ class DisplayMan {
 	void viewportBlitToScreen(); // @ F0566_VIEWPORT_BlitToScreen
 
 	void drawBitmapDOS(byte *srcBitmap, int16 zoneIndex, bool flipHorizontal = false, Color transparentColor = kDMColorFlesh, uint16 explicitWidth = 0, uint16 explicitHeight = 0); // @ F0791_DUNGEONVIEW_DrawBitmapXX
-	void drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &frame); // @ F0105_DUNGEONVIEW_DrawFloorPitOrStairsBitmapFlippedHorizontally
-	void drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &frame); // @ F0104_DUNGEONVIEW_DrawFloorPitOrStairsBitmap
+	void drawFloorPitOrStairsBitmapFlippedHorizontally(uint16 nativeIndex, Frame &frame, int16 zoneIndexDOS = -1); // @ F0105_DUNGEONVIEW_DrawFloorPitOrStairsBitmapFlippedHorizontally
+	void drawFloorPitOrStairsBitmap(uint16 nativeIndex, Frame &frame, int16 zoneIndexDOS = -1); // @ F0104_DUNGEONVIEW_DrawFloorPitOrStairsBitmap
 	void drawWallSetBitmap(byte *bitmap, Frame &f); // @ F0100_DUNGEONVIEW_DrawWallSetBitmap
 	void drawWallSetBitmapWithoutTransparency(byte *bitmap, Frame &f); // @ F0101_DUNGEONVIEW_DrawWallSetBitmapWithoutTransparency
 
@@ -911,7 +962,7 @@ public:
 	void drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doorNativeBitmapIndices, int16 byteCount,
 					   DoorOrnament doorOrnament, DoorFrames *doorFrames, int16 zoneIndexDOS = -1);
 	void drawDoorOrnament(int16 doorOrnOdinal, DoorOrnament doorOrnament); // @ F0109_DUNGEONVIEW_DrawDoorOrnament
-	void drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal); // @ F0112_DUNGEONVIEW_DrawCeilingPit
+	void drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal, int16 zoneIndexDOS = -1); // @ F0112_DUNGEONVIEW_DrawCeilingPit
 
 	void blitToViewport(byte *bitmap, Box &box, int16 byteWidth, Color transparent, int16 height); // @ F0020_MAIN_BlitToViewport
 	void blitToViewport(byte *bitmap, int16 *box, int16 byteWidth, Color transparent, int16 height); // @ F0020_MAIN_BlitToViewport




More information about the Scummvm-git-logs mailing list