[Scummvm-git-logs] scummvm master -> 1bdab8188cb55a8e4ed9d035b45fc8acace6e553

sev- noreply at scummvm.org
Thu Aug 28 12:07:08 UTC 2025


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

Summary:
c123b21902 DIRECTOR: Fix D6 sprite data saving
d1d04b052e DIRECTOR: Implement main channel reading for D7+
70210bd98f DIRECTOR: Implement main channel saving for D7+
871bb62711 DIRECTOR: Implemented D7+ sprite data reading
0efd3a61bf DIRECTOR: Implement D7+ sprite data writing
1bdab8188c DIRECTOR: Allow spritelist indices read as half


Commit: c123b219020bb40886e8c443bba3424a090feeef
    https://github.com/scummvm/scummvm/commit/c123b219020bb40886e8c443bba3424a090feeef
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T00:18:54+02:00

Commit Message:
DIRECTOR: Fix D6 sprite data saving

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 26f61146383..74d3f5ec06e 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1614,29 +1614,21 @@ void readSpriteDataD6(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 }
 
 void writeSpriteDataD6(Common::SeekableWriteStream *writeStream, Sprite &sprite) {
-	// Writing 24 bytes of sprite data
-	// The original data for a certain sprite might be less
 	writeStream->writeByte(sprite._spriteType);			// 0
-
-	if (sprite._puppet) {
-		for (int i = 1; i < kSprChannelSizeD6; i++)
-			writeStream->writeByte(0);
-	} else {
-		writeStream->writeByte(sprite._inkData);				// 1
-		writeStream->writeByte(sprite._foreColor);				// 2
-		writeStream->writeByte(sprite._backColor);				// 3
-		writeStream->writeSint16BE(sprite._castId.castLib);		// 4, 5
-		writeStream->writeUint16BE(sprite._castId.member);		// 6, 7
-		writeStream->writeUint32BE(sprite._spriteListIdx);		// 8, 9, 10, 11
-		writeStream->writeUint16BE(sprite._startPoint.y);		// 12, 13
-		writeStream->writeUint16BE(sprite._startPoint.x);		// 14, 15
-		writeStream->writeUint16BE(sprite._height);				// 16, 17
-		writeStream->writeUint16BE(sprite._width);				// 18, 19
-		writeStream->writeByte(sprite._colorcode);				// 20
-		writeStream->writeByte(sprite._blendAmount);			// 21
-		writeStream->writeByte(sprite._thickness);				// 22
-		writeStream->writeByte(0);								// 23, unused
-	}
+	writeStream->writeByte(sprite._inkData);				// 1
+	writeStream->writeByte(sprite._foreColor);				// 2
+	writeStream->writeByte(sprite._backColor);				// 3
+	writeStream->writeSint16BE(sprite._castId.castLib);		// 4, 5
+	writeStream->writeUint16BE(sprite._castId.member);		// 6, 7
+	writeStream->writeUint32BE(sprite._spriteListIdx);		// 8, 9, 10, 11
+	writeStream->writeUint16BE(sprite._startPoint.y);		// 12, 13
+	writeStream->writeUint16BE(sprite._startPoint.x);		// 14, 15
+	writeStream->writeUint16BE(sprite._height);				// 16, 17
+	writeStream->writeUint16BE(sprite._width);				// 18, 19
+	writeStream->writeByte(sprite._colorcode);				// 20
+	writeStream->writeByte(sprite._blendAmount);			// 21
+	writeStream->writeByte(sprite._thickness);				// 22
+	writeStream->writeByte(0);								// 23, unused
 }
 
 /**************************


Commit: d1d04b052ec031cbbbc0e3235bfe903b8ff1a442
    https://github.com/scummvm/scummvm/commit/d1d04b052ec031cbbbc0e3235bfe903b8ff1a442
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T00:27:56+02:00

Commit Message:
DIRECTOR: Implement main channel reading for D7+

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


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 74d3f5ec06e..ce6736ec9a8 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1358,7 +1358,7 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 			break;
 		case 120+9:
 			stream.read(unk, 15); // alignment bytes
-			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): sound2.unk: ");
+			hexdumpIfNotZero(unk, 15, "Frame::readMainChannelsD6(): script.unk: ");
 			break;
 
 		// 144 bytes (24 * 6)
@@ -1665,7 +1665,173 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		debugC(8, kDebugLoading, "Frame::readMainChannelsD7(): %d byte header", size);
 		stream.hexdump(size);
 	}
-	error("Frame::readMainChannelsD7(): Miscomputed field position: %d", offset);
+
+	uint32 initPos = stream.pos();
+	uint32 finishPosition = initPos + size;
+	byte unk[40];
+
+	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, 39); // alignment bytes
+			hexdumpIfNotZero(unk, 39, "Frame::readMainChannelsD7(): sound1.unk: ");
+			break;
+
+		// Sound2
+		case 48+0:
+			_mainChannels.sound2.castLib = stream.readUint16();
+			break;
+		case 48+2:
+			_mainChannels.sound2.member = stream.readUint16();
+			break;
+		case 48+4:
+			_mainChannels.sound2SpriteListIdx = stream.readUint32();
+			break;
+		case 48+8:
+			_mainChannels.colorSound2 = stream.readByte();
+			break;
+		case 48+9:
+			stream.read(unk, 39); // alignment bytes
+			hexdumpIfNotZero(unk, 39, "Frame::readMainChannelsD7(): sound2.unk: ");
+			break;
+
+		// Palette
+		case 96+0:
+			_mainChannels.palette.paletteId.castLib = stream.readSint16();
+			break;
+		case 96+2:
+			_mainChannels.palette.paletteId.member = stream.readSint16();
+			if (!_mainChannels.palette.paletteId.isNull())
+				_mainChannels.scoreCachedPaletteId = _mainChannels.palette.paletteId;
+			break;
+		case 96+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 96+6:
+			_mainChannels.palette.firstColor = g_director->transformColor(stream.readByte() ^ 0x80); // 51
+			_mainChannels.palette.lastColor = g_director->transformColor(stream.readByte() ^ 0x80); // 52
+			break;
+		case 96+8:
+			_mainChannels.palette.frameCount = stream.readUint16(); // 53
+			break;
+		case 96+10:
+			_mainChannels.palette.cycleCount = stream.readUint16(); // 55
+			break;
+		case 96+12:
+			_mainChannels.palette.fade = stream.readByte();
+			break;
+		case 96+13:
+			_mainChannels.palette.delay = stream.readByte();
+			break;
+		case 96+14:
+			_mainChannels.palette.style = stream.readByte();
+			break;
+		case 96+15:
+			_mainChannels.palette.colorCode = stream.readByte();
+			break;
+		case 96+16:
+			_mainChannels.palette.spriteListIdx = stream.readUint32();
+			break;
+		case 96+20:
+			stream.read(unk, 28); // alignment bytes
+			hexdumpIfNotZero(unk, 28, "Frame::readMainChannelsD7(): palette.unk: ");
+			break;
+
+		// Transition
+		case 144+0:
+			_mainChannels.trans.castLib = stream.readUint16();
+			break;
+		case 144+2:
+			_mainChannels.trans.member = stream.readUint16();
+			break;
+		case 144+4:
+			_mainChannels.transSpriteListIdx = stream.readUint32();
+			break;
+		case 144+8:
+			_mainChannels.colorTrans = stream.readByte();
+			break;
+		case 144+9:
+			stream.read(unk, 39); // alignment bytes
+			hexdumpIfNotZero(unk, 39, "Frame::readMainChannelsD7(): trans.unk: ");
+			break;
+
+		// Tempo
+		case 192+0:
+			_mainChannels.tempoSpriteListIdx = stream.readUint32();
+			break;
+		case 192+4:
+			_mainChannels.tempoD6Flags = stream.readUint16();
+			break;
+		case 192+6:
+			_mainChannels.tempo = stream.readByte();
+			if (_mainChannels.tempo && _mainChannels.tempo <= 120)
+				_mainChannels.scoreCachedTempo = _mainChannels.tempo;
+			break;
+		case 192+7:
+			_mainChannels.colorTempo = stream.readByte();
+			break;
+		case 192+8:
+			stream.read(unk, 40); // alignment bytes
+			hexdumpIfNotZero(unk, 40, "Frame::readMainChannelsD7(): tempo.unk: ");
+			break;
+
+		// Script
+		case 240+0:
+			_mainChannels.actionId.castLib = stream.readUint16();
+			break;
+		case 240+2:
+			_mainChannels.actionId.member = stream.readUint16();
+			break;
+		case 240+4:
+			_mainChannels.scriptSpriteListIdx = stream.readUint32();
+			break;
+		case 240+8:
+			_mainChannels.colorScript = stream.readByte();
+			break;
+		case 240+9:
+			stream.read(unk, 39); // alignment bytes
+			hexdumpIfNotZero(unk, 39, "Frame::readMainChannelsD7(): script.unk: ");
+			break;
+
+		// 144 bytes (24 * 6)
+
+		default:
+			// This means that a `case` label has to be split at this position
+			error("Frame::readMainChannelsD7(): 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::readMainChannelsD7(): 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::writeMainChannelsD7(Common::SeekableWriteStream *writeStream) {
diff --git a/engines/director/frame.h b/engines/director/frame.h
index 18674205157..e30f6f848ac 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -56,8 +56,8 @@ enum {
 	kMainChannelSizeD6 = 144,
 	kSprChannelSizeD6 = 24,
 
-	kMainChannelSizeD7 = 48,
-	kSprChannelSizeD7 = 24,
+	kMainChannelSizeD7 = 288,
+	kSprChannelSizeD7 = 48,
 };
 
 struct PaletteInfo {


Commit: 70210bd98fe6d82b438fd093c7f2f20308462290
    https://github.com/scummvm/scummvm/commit/70210bd98fe6d82b438fd093c7f2f20308462290
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T00:35:50+02:00

Commit Message:
DIRECTOR: Implement main channel saving for D7+

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index ce6736ec9a8..8972c2cfccc 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1379,18 +1379,20 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 	_mainChannels.transDuration = CLIP<uint16>(_mainChannels.transDuration, 0, 32000);  // restrict to 32 secs
 }
 
+static void writePadding(Common::SeekableWriteStream *writeStream, int size) {
+	for (int i = 0; i < size; i++) {
+		writeStream->writeByte(0);
+	}
+}
+
 void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
-	// Sound2
+	// Sound1
 	writeStream->writeUint16BE(_mainChannels.sound1.castLib);			// 0
 	writeStream->writeUint16BE(_mainChannels.sound1.member);			// 2
 	writeStream->writeUint32BE(_mainChannels.sound1SpriteListIdx);		// 4
 	writeStream->writeUint16BE(_mainChannels.sound1SpriteListIdx);		// 6
 	writeStream->writeByte(_mainChannels.colorSound1);					// 8
-	// 15 empty bytes
-	writeStream->writeByte(0);											// 9
-	writeStream->writeUint64BE(0);										// 10
-	writeStream->writeUint32BE(0);										// 18
-	writeStream->writeUint16BE(0);										// 22
+	writePadding(writeStream, 15);										// 9-23
 
 	// Sound2
 	writeStream->writeUint16BE(_mainChannels.sound2.castLib);			// 24+0
@@ -1398,11 +1400,7 @@ void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint32BE(_mainChannels.sound2SpriteListIdx);		// 24+4
 	writeStream->writeUint16BE(_mainChannels.sound2SpriteListIdx);		// 24+6
 	writeStream->writeByte(_mainChannels.colorSound2);					// 24+8
-	// 15 empty bytes
-	writeStream->writeByte(0);											// 24+9
-	writeStream->writeUint64BE(0);										// 24+10
-	writeStream->writeUint32BE(0);										// 24+18
-	writeStream->writeUint16BE(0);										// 24+22
+	writePadding(writeStream, 15);										// 24+9
 
 	// Palette
 	writeStream->writeUint16BE(_mainChannels.palette.paletteId.castLib);	// 48+0
@@ -1418,37 +1416,28 @@ void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeByte(_mainChannels.palette.style);					// 48+14
 	writeStream->writeByte(_mainChannels.palette.colorCode);				// 48+15
 	writeStream->writeUint32BE(_mainChannels.palette.spriteListIdx);		// 48+16
-	writeStream->writeUint32BE(0);											// 48+20
+	writePadding(writeStream, 4);											// 48+20
 
 	// Transition
 	writeStream->writeUint16BE(_mainChannels.trans.castLib);				// 72+0
 	writeStream->writeUint16BE(_mainChannels.trans.member);					// 72+2
 	writeStream->writeUint32BE(_mainChannels.transSpriteListIdx);			// 72+4
 	writeStream->writeByte(_mainChannels.colorTrans);						// 72+8
-	// 15 empty bytes
-	writeStream->writeByte(0);												// 72+9
-	writeStream->writeUint64BE(0);											// 72+10
-	writeStream->writeUint32BE(0);											// 72+18
-	writeStream->writeUint16BE(0);											// 72+22
+	writePadding(writeStream, 15);											// 72+9
 
 	// Tempo
 	writeStream->writeUint32BE(_mainChannels.tempoSpriteListIdx);			// 96+0
 	writeStream->writeUint16BE(_mainChannels.tempoD6Flags);					// 96+4
 	writeStream->writeByte(_mainChannels.tempo);							// 96+6
 	writeStream->writeByte(_mainChannels.colorTempo);						// 96+7
-	writeStream->writeUint64BE(0);											// 96+8
-	writeStream->writeUint64BE(0);											// 96+16
+	writePadding(writeStream, 16);											// 96+8
 
 	// Script
 	writeStream->writeUint32BE(_mainChannels.actionId.castLib);				// 120+0
 	writeStream->writeUint16BE(_mainChannels.actionId.member);				// 120+2
 	writeStream->writeUint32BE(_mainChannels.scriptSpriteListIdx);			// 120+4
 	writeStream->writeByte(_mainChannels.colorScript);						// 120+8
-	// 15 empty bytes
-	writeStream->writeByte(0);												// 120+9
-	writeStream->writeUint64BE(0);											// 120+10
-	writeStream->writeUint32BE(0);											// 120+18
-	writeStream->writeUint16BE(0);											// 120+22
+	writePadding(writeStream, 15);											// 120+9
 }
 
 void Frame::readSpriteD6(Common::MemoryReadStreamEndian &stream, uint16 offset, uint16 size) {
@@ -1835,7 +1824,58 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 }
 
 void Frame::writeMainChannelsD7(Common::SeekableWriteStream *writeStream) {
-	warning("STUB: Frame::writeMainChannelsD7()");
+	// Sound1
+	writeStream->writeUint16BE(_mainChannels.sound1.castLib);			// 0
+	writeStream->writeUint16BE(_mainChannels.sound1.member);			// 2
+	writeStream->writeUint32BE(_mainChannels.sound1SpriteListIdx);		// 4
+	writeStream->writeUint16BE(_mainChannels.sound1SpriteListIdx);		// 6
+	writeStream->writeByte(_mainChannels.colorSound1);					// 8
+	writePadding(writeStream, 39);										// 9-23
+
+	// Sound2
+	writeStream->writeUint16BE(_mainChannels.sound2.castLib);			// 48+0
+	writeStream->writeUint16BE(_mainChannels.sound2.member);			// 48+2
+	writeStream->writeUint32BE(_mainChannels.sound2SpriteListIdx);		// 48+4
+	writeStream->writeUint16BE(_mainChannels.sound2SpriteListIdx);		// 48+6
+	writeStream->writeByte(_mainChannels.colorSound2);					// 48+8
+	writePadding(writeStream, 39);										// 48+9
+
+	// Palette
+	writeStream->writeUint16BE(_mainChannels.palette.paletteId.castLib);	// 96+0
+	writeStream->writeUint16BE(_mainChannels.palette.paletteId.member);		// 96+2
+	writeStream->writeByte(_mainChannels.palette.speed);					// 96+4
+	writeStream->writeByte(_mainChannels.palette.flags);					// 96+5
+	writeStream->writeByte(_mainChannels.palette.firstColor);				// 96+6
+	writeStream->writeByte(_mainChannels.palette.lastColor);				// 96+7
+	writeStream->writeUint16BE(_mainChannels.palette.frameCount);			// 96+8
+	writeStream->writeUint16BE(_mainChannels.palette.cycleCount);			// 96+10
+	writeStream->writeByte(_mainChannels.palette.fade);						// 96+12
+	writeStream->writeByte(_mainChannels.palette.delay);					// 96+13
+	writeStream->writeByte(_mainChannels.palette.style);					// 96+14
+	writeStream->writeByte(_mainChannels.palette.colorCode);				// 96+15
+	writeStream->writeUint32BE(_mainChannels.palette.spriteListIdx);		// 96+16
+	writePadding(writeStream, 28);											// 96+20
+
+	// Transition
+	writeStream->writeUint16BE(_mainChannels.trans.castLib);				// 144+0
+	writeStream->writeUint16BE(_mainChannels.trans.member);					// 144+2
+	writeStream->writeUint32BE(_mainChannels.transSpriteListIdx);			// 144+4
+	writeStream->writeByte(_mainChannels.colorTrans);						// 144+8
+	writePadding(writeStream, 39);											// 144+9
+
+	// Tempo
+	writeStream->writeUint32BE(_mainChannels.tempoSpriteListIdx);			// 192+0
+	writeStream->writeUint16BE(_mainChannels.tempoD6Flags);					// 192+4
+	writeStream->writeByte(_mainChannels.tempo);							// 192+6
+	writeStream->writeByte(_mainChannels.colorTempo);						// 192+7
+	writePadding(writeStream, 40);											// 192+8
+
+	// Script
+	writeStream->writeUint32BE(_mainChannels.actionId.castLib);				// 240+0
+	writeStream->writeUint16BE(_mainChannels.actionId.member);				// 240+2
+	writeStream->writeUint32BE(_mainChannels.scriptSpriteListIdx);			// 240+4
+	writeStream->writeByte(_mainChannels.colorScript);						// 240+8
+	writePadding(writeStream, 39);											// 240+9
 }
 
 void Frame::readSpriteD7(Common::MemoryReadStreamEndian &stream, uint16 offset, uint16 size) {


Commit: 871bb627117e700230d4b2f4b43e0055be620267
    https://github.com/scummvm/scummvm/commit/871bb627117e700230d4b2f4b43e0055be620267
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T00:51:42+02:00

Commit Message:
DIRECTOR: Implemented D7+ sprite data reading

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


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 8972c2cfccc..3d7e0691402 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1908,6 +1908,8 @@ void Frame::readSpriteD7(Common::MemoryReadStreamEndian &stream, uint16 offset,
 }
 
 void readSpriteDataD7(Common::SeekableReadStreamEndian &stream, Sprite &sprite, uint32 startPosition, uint32 finishPosition) {
+	byte unk[12];
+
 	while (stream.pos() < finishPosition) {
 		switch (stream.pos() - startPosition) {
 		case 0:
@@ -1917,35 +1919,29 @@ void readSpriteDataD7(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 				sprite._spriteType = (SpriteType)stream.readByte();
 			}
 			break;
-		case 1: {
-			byte inkData = stream.readByte();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPInk))
-				continue;
-
-			sprite._inkData = inkData;
+		case 1:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPInk)) {
+				stream.readByte();
+			} else {
+				sprite._inkData = stream.readByte();
 
-			sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
-			sprite._trails = sprite._inkData & 0x40 ? true : false;
-			sprite._stretch = sprite._inkData & 0x80 ? true : false;
+				sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
+				sprite._trails = sprite._inkData & 0x40 ? true : false;
+				sprite._stretch = sprite._inkData & 0x80 ? true : false;
 			}
 			break;
-		case 2: {
-			uint8 foreColor = stream.readByte();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPForeColor))
-				continue;
-
-			sprite._foreColor = g_director->transformColor(foreColor);
+		case 2:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPForeColor)) {
+				stream.readByte();
+			} else {
+				sprite._foreColor = g_director->transformColor((uint8)stream.readByte());
 			}
 			break;
-		case 3: {
-			uint8 backColor = stream.readByte();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPBackColor))
-				continue;
-
-			sprite._backColor = g_director->transformColor(backColor);
+		case 3:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPBackColor)) {
+				stream.readByte();
+			} else {
+				sprite._backColor = g_director->transformColor((uint8)stream.readByte());
 			}
 			break;
 		case 4:
@@ -1964,73 +1960,69 @@ void readSpriteDataD7(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 				sprite._castId = CastMemberID(memberID, sprite._castId.castLib);  // Inherit castLib from previous frame
 			}
 			break;
-		case 8: {
-				int scriptCastLib = stream.readSint16();
-				sprite._scriptId = CastMemberID(sprite._scriptId.member, scriptCastLib);
+		case 8:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPCast)) {
+				stream.readUint32();
+			} else {
+				sprite._spriteListIdx = stream.readUint32();
 			}
 			break;
-		case 10: {
-				uint16 scriptMemberID = stream.readUint16();
-				sprite._scriptId = CastMemberID(scriptMemberID, sprite._scriptId.castLib);  // Inherit castLib from previous frame
+		case 10: // This field could be optimized
+			if (sprite._puppet || sprite.getAutoPuppet(kAPCast)) {
+				stream.readUint16();
+			} else {
+				sprite._spriteListIdx = stream.readUint16();
 			}
 			break;
-		case 12: {
-			uint16 startPointY = stream.readUint16();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPLocV) || sprite.getAutoPuppet(kAPLoc))
-				continue;
-
-			sprite._startPoint.y = startPointY;
-			break;
+		case 12:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPLoc)) {
+				stream.readUint16();
+			} else {
+				sprite._startPoint.y = (int16)stream.readUint16();
 			}
-		case 14: {
-			uint16 startPointX = stream.readUint16();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPLocH) || sprite.getAutoPuppet(kAPLoc))
-				continue;
-
-			sprite._startPoint.x = startPointX;
+			break;
+		case 14:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPLoc)) {
+				stream.readUint16();
+			} else {
+				sprite._startPoint.x = (int16)stream.readUint16();
 			}
 			break;
-		case 16: {
-			uint16 height = stream.readUint16();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPHeight))
-				continue;
-
-			sprite._height = height;
+		case 16:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPHeight)) {
+				stream.readUint16();
+			} else {
+				sprite._height = (int16)stream.readUint16();
 			}
 			break;
-		case 18: {
-			uint16 width = stream.readUint16();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPWidth))
-				continue;
-
-			sprite._width = width;
+		case 18:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPWidth)) {
+				stream.readUint16();
+			} else {
+				sprite._width = (int16)stream.readUint16();
 			}
 			break;
 		case 20:
-			// & 0x0f scorecolor
-			// 0x10 forecolor is rgb
-			// 0x20 bgcolor is rgb
-			// 0x40 editable
-			// 0x80 moveable
-			sprite._colorcode = stream.readByte();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPMoveable))
-				continue;
+			if (sprite._puppet || sprite.getAutoPuppet(kAPMoveable)) {
+				stream.readByte();
+			} else {
+				// & 0x0f scorecolor
+				// 0x10 forecolor is rgb
+				// 0x20 bgcolor is rgb
+				// 0x40 editable
+				// 0x80 moveable
+				sprite._colorcode = stream.readByte();
 
-			sprite._editable = ((sprite._colorcode & 0x40) == 0x40);
-			sprite._moveable = ((sprite._colorcode & 0x80) == 0x80);
+				sprite._editable = ((sprite._colorcode & 0x40) == 0x40);
+				sprite._moveable = ((sprite._colorcode & 0x80) == 0x80);
+				sprite._moveable = ((sprite._colorcode & 0x80) == 0x80);
+			}
 			break;
-		case 21: {
-			byte blendAmount = stream.readByte();
-
-			if (sprite._puppet || sprite.getAutoPuppet(kAPBlend))
-				continue;
-
-			sprite._blendAmount = blendAmount;
+		case 21:
+			if (sprite._puppet) {
+				stream.readByte();
+			} else {
+				sprite._blendAmount = stream.readByte();
 			}
 			break;
 		case 22:
@@ -2041,7 +2033,45 @@ void readSpriteDataD7(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 			}
 			break;
 		case 23:
-			(void)stream.readByte(); // unused
+			sprite._flags = stream.readByte();
+			break;
+		case 24:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPForeColor)) {
+				stream.readByte();
+			} else {
+				sprite._fgColorG = (uint8)stream.readByte();
+			}
+			break;
+		case 25:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPBackColor)) {
+				stream.readByte();
+			} else {
+				sprite._bgColorG = (uint8)stream.readByte();
+			}
+			break;
+		case 26:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPForeColor)) {
+				stream.readByte();
+			} else {
+				sprite._fgColorB = (uint8)stream.readByte();
+			}
+			break;
+		case 27:
+			if (sprite._puppet || sprite.getAutoPuppet(kAPBackColor)) {
+				stream.readByte();
+			} else {
+				sprite._bgColorB = (uint8)stream.readByte();
+			}
+			break;
+		case 28:
+			sprite._angleRot = stream.readUint32();
+			break;
+		case 32:
+			sprite._angleSkew = stream.readUint32();
+			break;
+		case 36:
+			stream.read(unk, 12); // alignment bytes
+			hexdumpIfNotZero(unk, 12, "Frame::readSpriteDataD7(): sprite.unk: ");
 			break;
 		default:
 			// This means that a `case` label has to be split at this position
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 3290f00d7d8..221f4536005 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -76,7 +76,14 @@ void Sprite::reset() {
 	_volume = 0;
 	_stretch = false;
 
-	_spriteListIdx = 0;
+	_spriteListIdx = 0; // D6+
+
+	// D7+
+	_flags = 0;
+	_fgColorG = _fgColorB = 0;
+	_bgColorG = _bgColorB = 0;
+	_angleRot = 0;
+	_angleSkew = 0;
 }
 
 Sprite& Sprite::operator=(const Sprite &sprite) {
@@ -126,6 +133,14 @@ Sprite& Sprite::operator=(const Sprite &sprite) {
 
 	_spriteListIdx = sprite._spriteListIdx;
 
+	_flags = sprite._flags;
+	_fgColorG = sprite._fgColorG;
+	_fgColorB = sprite._fgColorB;
+	_bgColorG = sprite._bgColorG;
+	_bgColorB = sprite._bgColorB;
+	_angleRot = sprite._angleRot;
+	_angleSkew = sprite._angleSkew;
+
 	return *this;
 }
 
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 66ca94b4310..41030f6bc5c 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -139,7 +139,14 @@ public:
 	byte _volume;
 	bool _stretch;
 
-	uint32 _spriteListIdx;
+	uint32 _spriteListIdx;	 // D6+
+
+	// D7+
+	byte _flags;
+	byte _fgColorG, _fgColorB;		// R component sits in _foreColor
+	byte _bgColorG, _bgColorB;		// R component sits in _backColor
+	int32 _angleRot;
+	int32 _angleSkew;
 };
 
 } // End of namespace Director


Commit: 0efd3a61bf2ab984c8b7130cf7131b73c207c519
    https://github.com/scummvm/scummvm/commit/0efd3a61bf2ab984c8b7130cf7131b73c207c519
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T00:55:31+02:00

Commit Message:
DIRECTOR: Implement D7+ sprite data writing

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 3d7e0691402..3e34c5b26e1 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1603,7 +1603,7 @@ void readSpriteDataD6(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 }
 
 void writeSpriteDataD6(Common::SeekableWriteStream *writeStream, Sprite &sprite) {
-	writeStream->writeByte(sprite._spriteType);			// 0
+	writeStream->writeByte(sprite._spriteType);				// 0
 	writeStream->writeByte(sprite._inkData);				// 1
 	writeStream->writeByte(sprite._foreColor);				// 2
 	writeStream->writeByte(sprite._backColor);				// 3
@@ -2081,7 +2081,28 @@ void readSpriteDataD7(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
 }
 
 void writeSpriteDataD7(Common::SeekableWriteStream *writeStream, Sprite &sprite) {
-	warning("STUB: writeSpriteDataD7()");
+	writeStream->writeByte(sprite._spriteType);				// 0
+	writeStream->writeByte(sprite._inkData);				// 1
+	writeStream->writeByte(sprite._foreColor);				// 2
+	writeStream->writeByte(sprite._backColor);				// 3
+	writeStream->writeSint16BE(sprite._castId.castLib);		// 4, 5
+	writeStream->writeUint16BE(sprite._castId.member);		// 6, 7
+	writeStream->writeUint32BE(sprite._spriteListIdx);		// 8, 9, 10, 11
+	writeStream->writeUint16BE(sprite._startPoint.y);		// 12, 13
+	writeStream->writeUint16BE(sprite._startPoint.x);		// 14, 15
+	writeStream->writeUint16BE(sprite._height);				// 16, 17
+	writeStream->writeUint16BE(sprite._width);				// 18, 19
+	writeStream->writeByte(sprite._colorcode);				// 20
+	writeStream->writeByte(sprite._blendAmount);			// 21
+	writeStream->writeByte(sprite._thickness);				// 22
+	writeStream->writeByte(sprite._flags);					// 23
+	writeStream->writeByte(sprite._fgColorG);				// 24
+	writeStream->writeByte(sprite._bgColorG);				// 25
+	writeStream->writeByte(sprite._fgColorB);				// 26
+	writeStream->writeByte(sprite._bgColorB);				// 27
+	writeStream->writeUint32BE(sprite._angleRot);			// 28
+	writeStream->writeUint32BE(sprite._angleSkew);			// 32
+	writePadding(writeStream, 12);							// 36-47
 }
 
 /**************************


Commit: 1bdab8188cb55a8e4ed9d035b45fc8acace6e553
    https://github.com/scummvm/scummvm/commit/1bdab8188cb55a8e4ed9d035b45fc8acace6e553
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-08-28T12:25:19+02:00

Commit Message:
DIRECTOR: Allow spritelist indices read as half

It is pretty often seen that this field starts from the middle.

The original "compression" was relying on word (2-byte) difference
between two frames, thus, in this case it was landing in the middle
of the field.

Changed paths:
    engines/director/frame.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 3e34c5b26e1..b5fa2cd8aef 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1248,6 +1248,9 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 24+4:
 			_mainChannels.sound2SpriteListIdx = stream.readUint32();
 			break;
+		case 24+6:
+			_mainChannels.sound2SpriteListIdx = stream.readUint16();
+			break;
 		case 24+8:
 			_mainChannels.colorSound2 = stream.readByte();
 			break;
@@ -1300,6 +1303,9 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 48+16:
 			_mainChannels.palette.spriteListIdx = stream.readUint32();
 			break;
+		case 48+18:
+			_mainChannels.palette.spriteListIdx = stream.readUint16();
+			break;
 		case 48+20:
 			stream.read(unk, 4); // alignment bytes
 			hexdumpIfNotZero(unk, 4, "Frame::readMainChannelsD6(): palette.unk: ");
@@ -1315,6 +1321,9 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 72+4:
 			_mainChannels.transSpriteListIdx = stream.readUint32();
 			break;
+		case 72+6:
+			_mainChannels.transSpriteListIdx = stream.readUint16();
+			break;
 		case 72+8:
 			_mainChannels.colorTrans = stream.readByte();
 			break;
@@ -1327,6 +1336,9 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 96+0:
 			_mainChannels.tempoSpriteListIdx = stream.readUint32();
 			break;
+		case 96+2:
+			_mainChannels.tempoSpriteListIdx = stream.readUint16();
+			break;
 		case 96+4:
 			_mainChannels.tempoD6Flags = stream.readUint16();
 			break;
@@ -1353,6 +1365,9 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 120+4:
 			_mainChannels.scriptSpriteListIdx = stream.readUint32();
 			break;
+		case 120+6:
+			_mainChannels.scriptSpriteListIdx = stream.readUint16();
+			break;
 		case 120+8:
 			_mainChannels.colorScript = stream.readByte();
 			break;
@@ -1390,7 +1405,6 @@ void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint16BE(_mainChannels.sound1.castLib);			// 0
 	writeStream->writeUint16BE(_mainChannels.sound1.member);			// 2
 	writeStream->writeUint32BE(_mainChannels.sound1SpriteListIdx);		// 4
-	writeStream->writeUint16BE(_mainChannels.sound1SpriteListIdx);		// 6
 	writeStream->writeByte(_mainChannels.colorSound1);					// 8
 	writePadding(writeStream, 15);										// 9-23
 
@@ -1398,7 +1412,6 @@ void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint16BE(_mainChannels.sound2.castLib);			// 24+0
 	writeStream->writeUint16BE(_mainChannels.sound2.member);			// 24+2
 	writeStream->writeUint32BE(_mainChannels.sound2SpriteListIdx);		// 24+4
-	writeStream->writeUint16BE(_mainChannels.sound2SpriteListIdx);		// 24+6
 	writeStream->writeByte(_mainChannels.colorSound2);					// 24+8
 	writePadding(writeStream, 15);										// 24+9
 
@@ -1692,6 +1705,9 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 48+4:
 			_mainChannels.sound2SpriteListIdx = stream.readUint32();
 			break;
+		case 48+6:
+			_mainChannels.sound2SpriteListIdx = stream.readUint16();
+			break;
 		case 48+8:
 			_mainChannels.colorSound2 = stream.readByte();
 			break;
@@ -1744,6 +1760,9 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 96+16:
 			_mainChannels.palette.spriteListIdx = stream.readUint32();
 			break;
+		case 96+18:
+			_mainChannels.palette.spriteListIdx = stream.readUint16();
+			break;
 		case 96+20:
 			stream.read(unk, 28); // alignment bytes
 			hexdumpIfNotZero(unk, 28, "Frame::readMainChannelsD7(): palette.unk: ");
@@ -1759,6 +1778,9 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 144+4:
 			_mainChannels.transSpriteListIdx = stream.readUint32();
 			break;
+		case 144+6:
+			_mainChannels.transSpriteListIdx = stream.readUint16();
+			break;
 		case 144+8:
 			_mainChannels.colorTrans = stream.readByte();
 			break;
@@ -1771,6 +1793,9 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 192+0:
 			_mainChannels.tempoSpriteListIdx = stream.readUint32();
 			break;
+		case 192+2:
+			_mainChannels.tempoSpriteListIdx = stream.readUint16();
+			break;
 		case 192+4:
 			_mainChannels.tempoD6Flags = stream.readUint16();
 			break;
@@ -1797,6 +1822,9 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 		case 240+4:
 			_mainChannels.scriptSpriteListIdx = stream.readUint32();
 			break;
+		case 240+6:
+			_mainChannels.scriptSpriteListIdx = stream.readUint16();
+			break;
 		case 240+8:
 			_mainChannels.colorScript = stream.readByte();
 			break;
@@ -1828,7 +1856,6 @@ void Frame::writeMainChannelsD7(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint16BE(_mainChannels.sound1.castLib);			// 0
 	writeStream->writeUint16BE(_mainChannels.sound1.member);			// 2
 	writeStream->writeUint32BE(_mainChannels.sound1SpriteListIdx);		// 4
-	writeStream->writeUint16BE(_mainChannels.sound1SpriteListIdx);		// 6
 	writeStream->writeByte(_mainChannels.colorSound1);					// 8
 	writePadding(writeStream, 39);										// 9-23
 
@@ -1836,7 +1863,6 @@ void Frame::writeMainChannelsD7(Common::SeekableWriteStream *writeStream) {
 	writeStream->writeUint16BE(_mainChannels.sound2.castLib);			// 48+0
 	writeStream->writeUint16BE(_mainChannels.sound2.member);			// 48+2
 	writeStream->writeUint32BE(_mainChannels.sound2SpriteListIdx);		// 48+4
-	writeStream->writeUint16BE(_mainChannels.sound2SpriteListIdx);		// 48+6
 	writeStream->writeByte(_mainChannels.colorSound2);					// 48+8
 	writePadding(writeStream, 39);										// 48+9
 




More information about the Scummvm-git-logs mailing list