[Scummvm-git-logs] scummvm master -> 31f0ac5467138a5e7147235b947f079ed9018a44

sev- noreply at scummvm.org
Sat Jul 18 21:08:44 UTC 2026


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:
31f0ac5467 DIRECTOR: Honor Afterburner Fcdr compression types when reading resources


Commit: 31f0ac5467138a5e7147235b947f079ed9018a44
    https://github.com/scummvm/scummvm/commit/31f0ac5467138a5e7147235b947f079ed9018a44
Author: Gianluca Boiano (morf3089 at gmail.com)
Date: 2026-07-18T23:08:40+02:00

Commit Message:
DIRECTOR: Honor Afterburner Fcdr compression types when reading resources

We assumed every Afterburner resource is zlib-compressed, but the Fcdr
chunk declares a compression type per resource: fontmap, null-compressed
and SWA resources are stored verbatim and made getResource() fatally
error on inflate.

Fixes fatal 'Could not uncompress FXmp' loading DATA/login.dcr in loewe7

Changed paths:
    engines/director/archive.cpp
    engines/director/archive.h


diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 7655282b61d..d3322609648 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -901,7 +901,33 @@ bool RIFXArchive::readAfterburnerMap(Common::SeekableReadStreamEndian &stream, u
 	}
 
 	_fcdrLength = readVarInt(stream);
-	stream.skip(_fcdrLength);
+	_fcdrZlibTypes.clear();
+	{
+		uint32 fcdrStart = stream.pos();
+		uint32 fcdrUncompLength = 16384;	// the table holds a handful of GUIDs plus names; generous cap
+		Common::SeekableReadStreamEndian *fcdrStream = readZlibData(stream, _fcdrLength, &fcdrUncompLength, _isBigEndian);
+		if (fcdrStream) {
+			uint16 compressionTypeCount = fcdrStream->readUint16();
+			for (uint16 i = 0; i < compressionTypeCount; i++) {
+				// MOA GUID identifying the codec for this compression type index
+				uint32 data1 = fcdrStream->readUint32();
+				uint16 data2 = fcdrStream->readUint16();
+				uint16 data3 = fcdrStream->readUint16();
+				uint32 data4 = fcdrStream->readUint32();
+				uint32 data5 = fcdrStream->readUint32();
+				bool zlib = data1 == 0xAC99E904 && data2 == 0x0070 && data3 == 0x0B36 &&
+							((data4 == 0x00080000 && data5 == 0x347A3707) ||
+							 (data4 == 0x00000800 && data5 == 0x07377A34));
+				_fcdrZlibTypes.push_back(zlib);
+				debugC(3, kDebugLoading, "Fcdr: compression type %d: %08x-%04x-%04x-%08x%08x%s",
+					i, data1, data2, data3, data4, data5, zlib ? " (zlib)" : "");
+			}
+			delete fcdrStream;
+		} else {
+			warning("RIFXArchive::readAfterburnerMap(): Could not uncompress Fcdr");
+		}
+		stream.seek(fcdrStart + _fcdrLength);
+	}
 
 	// Afterburner map
 	if (stream.readUint32() != MKTAG('A', 'B', 'M', 'P')) {
@@ -1133,6 +1159,17 @@ Common::SeekableReadStreamEndian *RIFXArchive::getResource(uint32 tag, uint16 id
 		if (res.offset == -1) {
 			return new Common::MemoryReadStreamEndian(_ilsData[id], res.uncompSize, bigEndian, DisposeAfterUse::NO);
 		} else {
+			// Only inflate resources whose Fcdr compression type is zlib; fontmap,
+			// null-compressed and SWA resources are stored verbatim.
+			bool zlib = res.size != res.uncompSize;
+			if (res.compressionType < _fcdrZlibTypes.size())
+				zlib = zlib && _fcdrZlibTypes[res.compressionType];
+
+			if (!zlib) {
+				auto rawStream = new Common::SeekableSubReadStream(_stream, _ilsBodyOffset + res.offset, _ilsBodyOffset + res.offset + res.size, DisposeAfterUse::NO);
+				return new Common::SeekableReadStreamEndianWrapper(rawStream, bigEndian, DisposeAfterUse::YES);
+			}
+
 			_stream->seek(_ilsBodyOffset + res.offset);
 			uint32 actualUncompLength = res.uncompSize;
 			Common::SeekableReadStreamEndian *stream = readZlibData(*_stream, res.size, &actualUncompLength, bigEndian);
diff --git a/engines/director/archive.h b/engines/director/archive.h
index aaa91867588..a75816bb9a2 100644
--- a/engines/director/archive.h
+++ b/engines/director/archive.h
@@ -219,6 +219,7 @@ private:
 	uint32 _fverLength;
 	uint32 _afterBurnerVersion;
 	uint32 _fcdrLength;
+	Common::Array<bool> _fcdrZlibTypes;
 	uint32 _abmpLength;
 	uint32 _abmpEnd;
 	uint32 _abmpCompressionType;




More information about the Scummvm-git-logs mailing list