[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