[Scummvm-git-logs] scummvm master -> b1a5acf0673350a26dfe9ef2142d8669e56f94d7
sev-
noreply at scummvm.org
Wed Sep 3 21:53:05 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
b1a5acf067 DIRECTOR: Properly read BitmapCastMembers for D6+
Commit: b1a5acf0673350a26dfe9ef2142d8669e56f94d7
https://github.com/scummvm/scummvm/commit/b1a5acf0673350a26dfe9ef2142d8669e56f94d7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-03T23:52:58+02:00
Commit Message:
DIRECTOR: Properly read BitmapCastMembers for D6+
Changed paths:
engines/director/castmember/bitmap.cpp
engines/director/castmember/bitmap.h
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 6d78b08cbf9..1b377a7fcb1 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -57,6 +57,9 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
_ditheredTargetClut = CastMemberID(0, 0);
_bitsPerPixel = 0;
_external = false;
+ _editVersion = 0;
+ _updateFlags = 0;
+ _version = version;
if (debugChannelSet(5, kDebugLoading)) {
stream.hexdump(stream.size());
@@ -65,6 +68,9 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
if (version < kFileVer400) {
_flags1 = flags1; // region: 0 - auto, 1 - matte, 2 - disabled
+ _updateFlags |= (_flags1 & kFlagCenterRegPointD4) ? kFlagCenterRegPoint : 0;
+ _updateFlags |= (_flags1 & kFlagMatteD4) ? kFlagMatte : 0;
+
_bytes = stream.readUint16();
// A little context about how bitmap bounding boxes are stored.
// In the Director editor, images can be edited on a big scrolling canvas with
@@ -100,8 +106,12 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
_pitch *= _bitsPerPixel;
_pitch >>= 3;
- } else if (version >= kFileVer400 && version < kFileVer700) {
+ } else if (version >= kFileVer400 && version < kFileVer600) {
_flags1 = flags1;
+
+ _updateFlags |= (_flags1 & kFlagCenterRegPointD4) ? kFlagCenterRegPoint : 0;
+ _updateFlags |= (_flags1 & kFlagMatteD4) ? kFlagMatte : 0;
+
_pitch = stream.readUint16();
_pitch &= 0x0fff;
@@ -146,6 +156,65 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
if (_bitsPerPixel == 0)
_bitsPerPixel = 1;
+ int tail = stream.size() - stream.pos();
+ if (tail > 0) {
+ warning("BUILDBOT: BitmapCastMember: %d bytes left", tail);
+ if (debugChannelSet(2, kDebugLoading)) {
+ byte buf[256];
+ tail = MIN(256, tail);
+ stream.read(buf, tail);
+ debug("BitmapCastMember: tail");
+ Common::hexdump(buf, tail);
+ }
+ }
+ } else if (version >= kFileVer600 && version < kFileVer1100) {
+ _flags1 = flags1;
+ _pitch = stream.readUint16();
+
+ _initialRect = Movie::readRect(stream);
+
+ if (version >= kFileVer700) {
+ _alphaThreshold = stream.readByte();
+ stream.readByte(); // padding
+ } else {
+ stream.readUint16(); // padding
+ }
+
+ _editVersion = stream.readUint16();
+
+ _scrollPoint.y = stream.readSint16();
+ _scrollPoint.x = stream.readSint16();
+
+ _regY = stream.readUint16();
+ _regX = stream.readUint16();
+
+ _updateFlags = stream.readByte();
+
+ // 22 bytes
+ // This is color image flag
+ if (_pitch & 0x8000) {
+ _pitch &= 0x0fff;
+
+ _bitsPerPixel = stream.readByte();
+
+ int clutCastLib = -1;
+ if (version >= kFileVer500) {
+ clutCastLib = stream.readSint16();
+ }
+ int clutId = stream.readSint16();
+
+ if (clutId <= 0) // builtin palette
+ _clut = CastMemberID(clutId - 1, -1);
+ else if (clutId > 0) {
+ if (clutCastLib == -1) {
+ clutCastLib = _cast->_castLibID;
+ }
+ _clut = CastMemberID(clutId, clutCastLib);
+ }
+ } else {
+ _bitsPerPixel = 1;
+ }
+
int tail = stream.size() - stream.pos();
if (tail > 0) {
warning("BUILDBOT: BitmapCastMember: %d bytes left", tail);
@@ -187,6 +256,10 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecode
_flags2 = 0;
_tag = 0;
_external = false;
+ _editVersion = 0;
+ _updateFlags = 0;
+
+ _version = g_director->getVersion();
}
BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &source)
@@ -212,6 +285,9 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &
_bytes = source._bytes;
_clut = source._clut;
_ditheredTargetClut = source._ditheredTargetClut;
+ _editVersion = source._editVersion;
+ _updateFlags = source._updateFlags;
+ _scrollPoint = source._scrollPoint;
_bitsPerPixel = source._bitsPerPixel;
@@ -219,6 +295,8 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &
_noMatte = source._noMatte;
_external = source._external;
+ _version = source._version;
+
warning("BitmapCastMember(): Duplicating source %d to target %d! This is unlikely to work properly, as the resource loader is based on the cast ID", source._castId, castId);
}
@@ -548,15 +626,28 @@ Graphics::Surface *BitmapCastMember::getMatte(const Common::Rect &bbox) {
}
Common::String BitmapCastMember::formatInfo() {
- return Common::String::format(
- "initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %s",
- _initialRect.width(), _initialRect.height(),
- _initialRect.left, _initialRect.top,
- _boundingRect.width(), _boundingRect.height(),
- _boundingRect.left, _boundingRect.top,
- getForeColor(), getBackColor(),
- _regX, _regY, _pitch, _bitsPerPixel, _clut.asString().c_str()
- );
+ if (_version < kFileVer600) {
+ return Common::String::format(
+ "initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %s",
+ _initialRect.width(), _initialRect.height(),
+ _initialRect.left, _initialRect.top,
+ _boundingRect.width(), _boundingRect.height(),
+ _boundingRect.left, _boundingRect.top,
+ getForeColor(), getBackColor(),
+ _regX, _regY, _pitch, _bitsPerPixel, _clut.asString().c_str()
+ );
+ } else {
+ return Common::String::format(
+ "initialRect: %dx%d@%d,%d, scrollPoint: %d,%d, alphaThreshold: %d, foreColor: %d, backColor: %d, regX: %d, regY: %d, pitch: %d, bitsPerPixel: %d, palette: %s, editVersion: %d, updateFlags: 0x%02x",
+ _initialRect.width(), _initialRect.height(),
+ _initialRect.left, _initialRect.top,
+ _scrollPoint.x, _scrollPoint.y,
+ _alphaThreshold,
+ getForeColor(), getBackColor(),
+ _regX, _regY, _pitch, _bitsPerPixel, _clut.asString().c_str(),
+ _editVersion, _updateFlags
+ );
+ }
}
void BitmapCastMember::load() {
@@ -1012,6 +1103,8 @@ void BitmapCastMember::writeCastData(Common::SeekableWriteStream *writeStream) {
writeStream->writeUint16BE(_regY);
writeStream->writeUint16BE(_regX);
+ warning("BitmapCastMember::writeCastData(): TODO process D6+");
+
if (_bitsPerPixel != 0) {
writeStream->writeByte(0); // Skip one byte (not stored)
writeStream->writeByte(_bitsPerPixel);
diff --git a/engines/director/castmember/bitmap.h b/engines/director/castmember/bitmap.h
index 77aa9d01f2e..d505538401f 100644
--- a/engines/director/castmember/bitmap.h
+++ b/engines/director/castmember/bitmap.h
@@ -74,19 +74,58 @@ public:
Graphics::Surface *_ditheredImg;
Graphics::Surface *_matte;
- uint16 _pitch;
- int16 _regX;
- int16 _regY;
+ int _version;
+
uint16 _flags2;
uint16 _bytes;
CastMemberID _clut;
CastMemberID _ditheredTargetClut;
- uint8 _bitsPerPixel;
-
uint32 _tag;
bool _noMatte;
bool _external;
+
+ // D4 stucture:
+ // uint16 _pitch;
+ // _initialRect // 2
+ // _boundingRect // 10
+ // int16 _regY; // 18
+ // int16 _regX; // 20
+ // uint8 _bitsPerPixel; // 22 when _pitch & 0x8000
+
+ // D6+ structure
+ uint16 _pitch;
+ // _initialRect // 2
+ // _boundingRect // 10 D%-
+ byte _alphaThreshold; // 10 D7+
+ // padding
+ uint16 _editVersion; // 12 D6+
+ Common::Point _scrollPoint; // 14
+ int16 _regY; // 18
+ int16 _regX; // 20
+ byte _updateFlags; // 21
+
+ uint8 _bitsPerPixel; // 22 when _pitch & 0x8000
+
+ // These sit in _flags1
+ enum {
+ kFlagCenterRegPointD4 = 0x01, // centerRegPoint property
+ kFlagMatteD4 = 0x20, // double check value
+ };
+
+ enum {
+ kFlagDither = 0x01, // Bitmap needs dithering
+ kFlagRemapPalette = 0x02, // Bitmap needs palette remap
+ kFlagSyncPalette = 0x04, // When bitmap comes from outside, sync its palette castmember
+ kFlagDitherOnUpdate = 0x08, // Forced dither
+
+ // D7+
+ kFlagFollowAlpha = 0x10, // Alpha channel for 32-bit images must be followed
+ kFlagCenterRegPoint = 0x20, // centerRegPoint property
+ kFlagMatte = 0x40, // it is used for matte image
+ kFlagNoAutoCrop = 0x80, // do not automatically crop the image
+ };
+
};
} // End of namespace Director
More information about the Scummvm-git-logs
mailing list