[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