[Scummvm-git-logs] scummvm master -> 84025113321c26a7bbdd27e560f91e281e3c5769

sev- noreply at scummvm.org
Wed Aug 27 14:36:24 UTC 2025


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

Summary:
71739bdfd0 DIRECTOR: Clarify D5 nain channels reading. Tidy up
f0006a42ea DIRECTOR: Complete D5 channel data reading
8402511332 DIRECTOR: Initial code for D6 main channel reading


Commit: 71739bdfd0b162832fdf19e79a84329c6d1cd24c
    https://github.com/scummvm/scummvm/commit/71739bdfd0b162832fdf19e79a84329c6d1cd24c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-27T10:10:16+02:00

Commit Message:
DIRECTOR: Clarify D5 nain channels reading. Tidy up

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 3b8117f4b1b..7174f4b3b5f 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -169,7 +169,8 @@ void Frame::readMainChannelsD2(Common::MemoryReadStreamEndian &stream, uint16 of
 
 	while (stream.pos() < finishPosition) {
 		switch (stream.pos() - initPos + offset) {
-		case 0: // Sound/Tempo/Transition
+		// Sound/Tempo/Transition
+		case 0:
 			_mainChannels.actionId = CastMemberID(stream.readByte(), DEFAULT_CAST_LIB);
 			break;
 		case 1:
@@ -222,8 +223,9 @@ void Frame::readMainChannelsD2(Common::MemoryReadStreamEndian &stream, uint16 of
 			if (unk[0] || unk[1])
 				debugC(8, kDebugLoading, "Frame::readMainChannelsD2(): STUB: unk2: 0x%02x 0x%02x", unk[0], unk[1]);
 			break;
+
+		// Palette
 		case 16: {
-				// palette
 				int16 paletteId = stream.readSint16();
 				if (paletteId == 0) {
 					_mainChannels.palette.paletteId = CastMemberID(0, 0);
@@ -447,8 +449,8 @@ void Frame::readMainChannelsD4(Common::MemoryReadStreamEndian &stream, uint16 of
 
 	while (stream.pos() < finishPosition) {
 		switch (stream.pos() - initPos + offset) {
+		// Sound/Tempo/Transition
 		case 0:
-			// Sound/Tempo/Transition
 			unk1 = stream.readByte();
 			if (unk1)
 				warning("Frame::readMainChannelsD4(): STUB: unk1: %d 0x%x", unk1, unk1);
@@ -509,8 +511,9 @@ void Frame::readMainChannelsD4(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 19:
 			_mainChannels.colorTrans = stream.readByte();
 			break;
+
+		// Palette, 20 bytes
 		case 20: {
-				// palette, 13 bytes
 				int16 paletteId = stream.readSint16();
 				if (paletteId == 0) {
 					_mainChannels.palette.paletteId = CastMemberID(0, 0);
@@ -850,8 +853,8 @@ void Frame::readMainChannelsD5(Common::MemoryReadStreamEndian &stream, uint16 of
 
 	while (stream.pos() < finishPosition) {
 		switch (stream.pos() - initPos + offset) {
+		// Sound/Tempo/Transition
 		case 0:
-			// Sound/Tempo/Transition
 			_mainChannels.actionId.castLib = stream.readUint16();
 			break;
 		case 2:
@@ -876,19 +879,19 @@ void Frame::readMainChannelsD5(Common::MemoryReadStreamEndian &stream, uint16 of
 			_mainChannels.trans.member = stream.readUint16();
 			break;
 		case 16:
-			stream.read(unk, 2);
-			if (unk[0] || unk[1])
-				warning("Frame::readMainChannelsD5(): STUB: unk1: 0x%02x 0x%02x", unk[0], unk[1]);
+			_mainChannels.colorTempo = stream.readByte();
+			break;
+		case 17:
+			_mainChannels.colorSound1 = stream.readByte();
 			break;
 		case 18:
-			stream.read(unk, 2);
-			if (unk[0] || unk[1])
-				warning("Frame::readMainChannelsD5(): STUB: unk2: 0x%02x 0x%02x", unk[0], unk[1]);
+			_mainChannels.colorSound2 = stream.readByte();
+			break;
+		case 19:
+			_mainChannels.colorScript = stream.readByte();
 			break;
 		case 20:
-			stream.read(unk, 1);
-			if (unk[0])
-				warning("Frame::readMainChannelsD5(): STUB: unk3: 0x%02x", unk[0]);
+			_mainChannels.colorTrans = stream.readByte();
 			break;
 		case 21:
 			_mainChannels.tempo = stream.readByte();
@@ -900,6 +903,8 @@ void Frame::readMainChannelsD5(Common::MemoryReadStreamEndian &stream, uint16 of
 			if (unk[0] || unk[1])
 				warning("Frame::readMainChannelsD5(): STUB: unk4: 0x%02x 0x%02x", unk[0], unk[1]);
 			break;
+
+		// Palette
 		case 24:
 			_mainChannels.palette.paletteId.castLib = stream.readSint16();
 			break;
@@ -974,9 +979,11 @@ void Frame::writeMainChannelsD5(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint16BE(_mainChannels.trans.member);			// 12, 13
 	writeStream->writeUint16BE(_mainChannels.trans.member);			// 14, 15
 
-	writeStream->writeUint16BE(0);		// Unknown	// 16, 17
-	writeStream->writeUint16BE(0);		// Unknown	// 18, 19
-	writeStream->writeByte(0);			// Unknown: Sound/Tempo/Transition	// 20
+	writeStream->writeByte(_mainChannels.colorTempo);				// 16
+	writeStream->writeByte(_mainChannels.colorSound1);				// 17
+	writeStream->writeByte(_mainChannels.colorSound2);				// 18
+	writeStream->writeByte(_mainChannels.colorScript);				// 19
+	writeStream->writeByte(_mainChannels.colorTrans);				// 20
 
 	writeStream->writeByte(_mainChannels.tempo);			// 21
 	writeStream->writeUint16BE(0);		// Unknown	// 22, 23


Commit: f0006a42ea46bb3f564153156948c37ed52c29fe
    https://github.com/scummvm/scummvm/commit/f0006a42ea46bb3f564153156948c37ed52c29fe
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-27T14:35:57+02:00

Commit Message:
DIRECTOR: Complete D5 channel data reading

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 7174f4b3b5f..e86591260f6 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -899,7 +899,7 @@ void Frame::readMainChannelsD5(Common::MemoryReadStreamEndian &stream, uint16 of
 				_mainChannels.scoreCachedTempo = _mainChannels.tempo;
 			break;
 		case 22:
-			stream.read(unk, 2);
+			stream.read(unk, 2); // alignment bytes
 			if (unk[0] || unk[1])
 				warning("Frame::readMainChannelsD5(): STUB: unk4: 0x%02x 0x%02x", unk[0], unk[1]);
 			break;
@@ -934,17 +934,19 @@ void Frame::readMainChannelsD5(Common::MemoryReadStreamEndian &stream, uint16 of
 			_mainChannels.palette.cycleCount = stream.readUint16(); // 34
 			break;
 		case 36:
-			stream.read(unk, 2);
-			if (unk[0] || unk[1])
-				warning("Frame::readMainChannelsD5(): STUB: unk5: 0x%02x 0x%02x", unk[0], unk[1]);
+			_mainChannels.palette.fade = stream.readByte();
+			break;
+		case 37:
+			_mainChannels.palette.delay = stream.readByte();
 			break;
 		case 38:
-			stream.read(unk, 2);
-			if (unk[0] || unk[1])
-				warning("Frame::readMainChannelsD5(): STUB: unk6: 0x%02x 0x%02x", unk[0], unk[1]);
+			_mainChannels.palette.style = stream.readByte();
+			break;
+		case 39:
+			_mainChannels.palette.colorCode = stream.readByte();
 			break;
 		case 40: {
-				stream.read(unk, 8);
+				stream.read(unk, 8); // alignment bytes
 
 				Common::String s;
 				for (int i = 0; i < 8; i++)
@@ -997,9 +999,11 @@ void Frame::writeMainChannelsD5(Common::SeekableWriteStream *writeStream) {
 
 	writeStream->writeUint16BE(_mainChannels.palette.frameCount);			// 32, 33
 	writeStream->writeUint16BE(_mainChannels.palette.cycleCount);			// 34, 35
+	writeStream->writeByte(_mainChannels.palette.fade);					// 36
+	writeStream->writeByte(_mainChannels.palette.delay);					// 37
+	writeStream->writeByte(_mainChannels.palette.style);					// 38
+	writeStream->writeByte(_mainChannels.palette.colorCode);				// 39
 
-	writeStream->writeUint16BE(0);		// Unknown	// 36, 37
-	writeStream->writeUint16BE(0);		// Unknown	// 38, 39
 	writeStream->writeUint64BE(0);		// Unknown 	// 40, 41, 42, 43, 44, 45, 46, 47
 }
 


Commit: 84025113321c26a7bbdd27e560f91e281e3c5769
    https://github.com/scummvm/scummvm/commit/84025113321c26a7bbdd27e560f91e281e3c5769
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-27T16:33:24+02:00

Commit Message:
DIRECTOR: Initial code for D6 main channel reading

Changed paths:
    engines/director/frame.cpp
    engines/director/frame.h
    engines/director/util.cpp
    engines/director/util.h


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index e86591260f6..430d52cdc02 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1226,7 +1226,173 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		debugC(8, kDebugLoading, "Frame::readMainChannelsD6(): %d byte header", size);
 		stream.hexdump(size);
 	}
-	error("Frame::readMainChannelsD6(): Miscomputed field position: %d", offset);
+
+	uint32 initPos = stream.pos();
+	uint32 finishPosition = initPos + size;
+	byte unk[16];
+
+	while (stream.pos() < finishPosition) {
+		switch (stream.pos() - initPos + offset) {
+		// Sound1
+		case 0:
+			_mainChannels.sound1.castLib = stream.readUint16();
+			break;
+		case 2:
+			_mainChannels.sound1.member = stream.readUint16();
+			break;
+		case 4:
+			_mainChannels.sound1SpriteListIdx = stream.readUint32();
+			break;
+		case 6:
+			_mainChannels.sound1SpriteListIdx = stream.readUint16();
+			break;
+		case 8:
+			_mainChannels.colorSound1 = stream.readByte();
+			break;
+		case 9:
+			stream.read(unk, 15); // alignment bytes
+			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): sound1.unk: ");
+			break;
+
+		// Sound2
+		case 24+0:
+			_mainChannels.sound2.castLib = stream.readUint16();
+			break;
+		case 24+2:
+			_mainChannels.sound2.member = stream.readUint16();
+			break;
+		case 24+4:
+			_mainChannels.sound2SpriteListIdx = stream.readUint32();
+			break;
+		case 24+8:
+			_mainChannels.colorSound2 = stream.readByte();
+			break;
+		case 24+9:
+			stream.read(unk, 15); // alignment bytes
+			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): sound2.unk: ");
+			break;
+
+		// Palette
+		case 48+0:
+			_mainChannels.palette.paletteId.castLib = stream.readSint16();
+			break;
+		case 48+2:
+			_mainChannels.palette.paletteId.member = stream.readSint16();
+			if (!_mainChannels.palette.paletteId.isNull())
+				_mainChannels.scoreCachedPaletteId = _mainChannels.palette.paletteId;
+			break;
+		case 48+4:
+			_mainChannels.palette.speed = stream.readByte(); // 52
+			_mainChannels.palette.flags = stream.readByte(); // 53
+			_mainChannels.palette.colorCycling = (_mainChannels.palette.flags & 0x80) != 0;
+			_mainChannels.palette.normal = (_mainChannels.palette.flags & 0x60) == 0x00;
+			_mainChannels.palette.fadeToBlack = (_mainChannels.palette.flags & 0x60) == 0x60;
+			_mainChannels.palette.fadeToWhite = (_mainChannels.palette.flags & 0x60) == 0x40;
+			_mainChannels.palette.autoReverse = (_mainChannels.palette.flags & 0x10) != 0;
+			_mainChannels.palette.overTime = (_mainChannels.palette.flags & 0x04) != 0;
+			break;
+		case 48+6:
+			_mainChannels.palette.firstColor = g_director->transformColor(stream.readByte() ^ 0x80); // 51
+			_mainChannels.palette.lastColor = g_director->transformColor(stream.readByte() ^ 0x80); // 52
+			break;
+		case 48+8:
+			_mainChannels.palette.frameCount = stream.readUint16(); // 53
+			break;
+		case 48+10:
+			_mainChannels.palette.cycleCount = stream.readUint16(); // 55
+			break;
+		case 48+12:
+			_mainChannels.palette.fade = stream.readByte();
+			break;
+		case 48+13:
+			_mainChannels.palette.delay = stream.readByte();
+			break;
+		case 48+14:
+			_mainChannels.palette.style = stream.readByte();
+			break;
+		case 48+15:
+			_mainChannels.palette.colorCode = stream.readByte();
+			break;
+		case 48+16:
+			_mainChannels.palette.spriteListIdx = stream.readUint32();
+			break;
+		case 48+20:
+			stream.read(unk, 4); // alignment bytes
+			hexdumpIfNotZero(unk, 4, "Frame::readMainChannelsD6(): palette.unk: ");
+			break;
+
+		// Transition
+		case 72+0:
+			_mainChannels.trans.castLib = stream.readUint16();
+			break;
+		case 72+2:
+			_mainChannels.trans.member = stream.readUint16();
+			break;
+		case 72+4:
+			_mainChannels.transSpriteListIdx = stream.readUint32();
+			break;
+		case 72+8:
+			_mainChannels.colorTrans = stream.readByte();
+			break;
+		case 72+9:
+			stream.read(unk, 15); // alignment bytes
+			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): trans.unk: ");
+			break;
+
+		// Tempo
+		case 96+0:
+			_mainChannels.tempoSpriteListIdx = stream.readUint32();
+			break;
+		case 96+4:
+			_mainChannels.tempoD6Flags = stream.readUint16();
+			break;
+		case 96+6:
+			_mainChannels.tempo = stream.readByte();
+			if (_mainChannels.tempo && _mainChannels.tempo <= 120)
+				_mainChannels.scoreCachedTempo = _mainChannels.tempo;
+			break;
+		case 96+7:
+			_mainChannels.colorTempo = stream.readByte();
+			break;
+		case 96+8:
+			stream.read(unk, 16); // alignment bytes
+			hexdumpIfNotZero(unk, 16, "Frame::readMainChannelsD6(): tempo.unk: ");
+			break;
+
+		// Script
+		case 120+0:
+			_mainChannels.actionId.castLib = stream.readUint16();
+			break;
+		case 120+2:
+			_mainChannels.actionId.member = stream.readUint16();
+			break;
+		case 120+4:
+			_mainChannels.scriptSpriteListIdx = stream.readUint32();
+			break;
+		case 120+8:
+			_mainChannels.colorScript = stream.readByte();
+			break;
+		case 120+9:
+			stream.read(unk, 15); // alignment bytes
+			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): sound2.unk: ");
+			break;
+
+		// 144 bytes (24 * 6)
+
+		default:
+			// This means that a `case` label has to be split at this position
+			error("Frame::readMainChannelsD6(): Miscomputed field position: %" PRId64, stream.pos() - initPos + offset);
+			break;
+		}
+	}
+
+	if (stream.pos() > finishPosition) {
+		// This means that the relevant `case` label reads too many bytes and must be split
+		error("Frame::readMainChannelsD6(): Read %" PRId64 "extra bytes", stream.pos() - finishPosition);
+	}
+
+	_mainChannels.transChunkSize = CLIP<byte>(_mainChannels.transChunkSize, 0, 128);
+	_mainChannels.transDuration = CLIP<uint16>(_mainChannels.transDuration, 0, 32000);  // restrict to 32 secs
 }
 
 void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
@@ -1320,6 +1486,13 @@ void readSpriteDataD6(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 				sprite._spriteListIdx = stream.readUint32();
 			}
 			break;
+		case 10: // This field could be optimized
+			if (sprite._puppet || sprite.getAutoPuppet(kAPCast)) {
+				stream.readUint16();
+			} else {
+				sprite._spriteListIdx = stream.readUint16();
+			}
+			break;
 		case 12:
 			if (sprite._puppet || sprite.getAutoPuppet(kAPLoc)) {
 				stream.readUint16();
diff --git a/engines/director/frame.h b/engines/director/frame.h
index e6394919946..18674205157 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -53,7 +53,7 @@ enum {
 	kMainChannelSizeD5 = 48,
 	kSprChannelSizeD5 = 24,
 
-	kMainChannelSizeD6 = 48,
+	kMainChannelSizeD6 = 144,
 	kSprChannelSizeD6 = 24,
 
 	kMainChannelSizeD7 = 48,
@@ -80,6 +80,8 @@ struct PaletteInfo {
 	byte style;
 	byte colorCode;
 
+	uint32 spriteListIdx; // D6+
+
 	PaletteInfo() {
 		paletteId = CastMemberID(0, 0);
 		firstColor = lastColor = 0;
@@ -89,26 +91,34 @@ struct PaletteInfo {
 		overTime = false; speed = 0;
 		frameCount = cycleCount = 0;
 		fade = delay = style = colorCode = 0;
+		spriteListIdx = 0;
 	}
 };
 
 struct MainChannels {
 	CastMemberID actionId;
+	uint32 scriptSpriteListIdx; // D6+
+
 	uint16 transDuration;
 	uint8 transArea; // 1 - Whole Window, 0 - Changing Area
 	uint8 transChunkSize;
 	TransitionType transType;
 	CastMemberID trans;
+	uint32 transSpriteListIdx; // D6+
 	PaletteInfo palette;
 	uint8 tempo;
+	uint32 tempoSpriteListIdx; // D6+
+	uint16 tempoD6Flags;
 
 	uint8 scoreCachedTempo;
 	CastMemberID scoreCachedPaletteId;
 
 	CastMemberID sound1;
 	uint8 soundType1;
+	uint32 sound1SpriteListIdx; // D6+
 	CastMemberID sound2;
 	uint8 soundType2;
+	uint32 sound2SpriteListIdx; // D6+
 
 	byte colorTempo;
 	byte colorSound1;
@@ -125,6 +135,8 @@ struct MainChannels {
 		transArea = 0;
 		transChunkSize = 0;
 		tempo = 0;
+		tempoSpriteListIdx = 0;
+		tempoD6Flags = 0;
 
 		scoreCachedTempo = 0;
 		scoreCachedPaletteId = CastMemberID(0, 0);
@@ -133,8 +145,11 @@ struct MainChannels {
 		sound2 = CastMemberID(0, 0);
 		soundType1 = 0;
 		soundType2 = 0;
+		sound1SpriteListIdx = 0;
+		sound2SpriteListIdx = 0;
 
 		actionId = CastMemberID(0, 0);
+		scriptSpriteListIdx = 0;
 		skipFrameFlag = 0;
 		blend = 0;
 
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index ad704640800..aa9a61b1425 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -1810,3 +1810,20 @@ double readAppleFloat80(void *ptr_) {
 
 	return Common::XPFloat(signAndExponent, mantissa).toDouble(Common::XPFloat::kSemanticsSANE);
 }
+
+void hexdumpIfNotZero(byte *data, int len, const char *prefix) {
+	bool nonZero = false;
+	for (int i = 0; i < len; i++) {
+		if (data[i] != 0) {
+			nonZero = true;
+			break;
+		}
+	}
+
+	if (nonZero) {
+		if (prefix)
+			debugN("%s ", prefix);
+
+		Common::hexdump(data, len);
+	}
+}
diff --git a/engines/director/util.h b/engines/director/util.h
index e5b3f4f8446..285f24aefbe 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -140,5 +140,6 @@ inline void lerpPalette(byte *target, const byte *palA, int palALength, const by
 } // End of namespace Director
 
 double readAppleFloat80(void *ptr);
+void hexdumpIfNotZero(byte *data, int len, const char *prefix);
 
 #endif




More information about the Scummvm-git-logs mailing list