[Scummvm-git-logs] scummvm master -> d3f4dcb5d8639a8aac0e8a5433b487b5e0bf9967
sev-
noreply at scummvm.org
Sat Jul 25 11:03:25 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:
d3f4dcb5d8 DIRECTOR: Fix config chunk size and tag when saving movies
Commit: d3f4dcb5d8639a8aac0e8a5433b487b5e0bf9967
https://github.com/scummvm/scummvm/commit/d3f4dcb5d8639a8aac0e8a5433b487b5e0bf9967
Author: Gianluca Boiano (morf3089 at gmail.com)
Date: 2026-07-25T13:03:20+02:00
Commit Message:
DIRECTOR: Fix config chunk size and tag when saving movies
Fixes checksum and length warnings reloading saved director-tests/saving movies
Changed paths:
engines/director/archive-save.cpp
engines/director/cast.cpp
engines/director/cast.h
diff --git a/engines/director/archive-save.cpp b/engines/director/archive-save.cpp
index c77f9c974fc..d1ce7e9fb82 100644
--- a/engines/director/archive-save.cpp
+++ b/engines/director/archive-save.cpp
@@ -116,11 +116,21 @@ bool RIFXArchive::writeToFile(Common::String filename, Movie *movie) {
break;
case MKTAG('V', 'W', 'C', 'F'):
- // There is only 'VWCF' resource, that is for the internal cast
+ case MKTAG('D', 'R', 'C', 'F'):
+ // There is only one config resource, that is for the internal cast
// The external casts don't have a config
// movie->getCast() returns the internal cast
cast = movie->getCast();
- cast->saveConfig(saveFile, it->offset);
+ if (cast->getConfigSize() == 0) {
+ // Unsupported version (D10+): keep the original bytes
+ debugC(7, kDebugSaving, "Saving resource %s as it is, without modification", tag2str(it->tag));
+ saveFile->seek(it->offset, SEEK_SET);
+ saveFile->writeUint32LE(it->tag);
+ saveFile->writeUint32LE(it->size);
+ saveFile->writeStream(getResource(it->tag, it->index));
+ } else {
+ cast->saveConfig(saveFile, it->offset, it->tag);
+ }
break;
case MKTAG('B', 'I', 'T', 'D'):
@@ -516,16 +526,23 @@ Common::Array<Resource *> RIFXArchive::rebuildResources(Movie *movie) {
break;
case MKTAG('V', 'W', 'C', 'F'):
+ case MKTAG('D', 'R', 'C', 'F'):
{
- // Only one cast config per movie
+ // Only one config resource per movie
// No need to update the key mapping
cast = movie->getCast();
resSize = cast->getConfigSize();
it->offset = currentSize;
+ if (resSize == 0) {
+ // Unsupported Director version: keep the original size
+ resSize = it->size;
+ } else {
+ it->size = resSize;
+ }
+
currentSize += resSize + 8; // getConfigSize() doesn't include header and size
- it->size = resSize;
}
break;
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 666c348369d..b1cabd72bda 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -635,7 +635,7 @@ bool Cast::loadConfig() {
return true;
}
-void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset) {
+void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset, uint32 tag) {
if (_version < kFileVer400) {
error("Cast::saveConfig called on a pre-D4 Director movie");
}
@@ -644,7 +644,7 @@ void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset) {
uint32 configSize = getConfigSize();
- writeStream->writeUint32LE(MKTAG('V', 'W', 'C', 'F'));
+ writeStream->writeUint32LE(tag);
writeStream->writeUint32LE(configSize);
// These offsets are only for Director Version 4 to Director version 6
@@ -655,8 +655,10 @@ void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset) {
Movie::writeRect(writeStream, _checkRect); // 4, 6, 8, 10
writeStream->writeUint16BE(_castArrayStartForChecksum); // 12
- // This will change
- writeStream->writeUint16BE(_castArrayStartForChecksum + _castArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't')).size()); // 14
+
+ // computeChecksum() reads this field; keep it in sync with the disk
+ _castArrayEndForChecksum = _castArrayStartForChecksum + _castArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't')).size();
+ writeStream->writeUint16BE(_castArrayEndForChecksum); // 14
writeStream->writeByte(_readRate); // 16
writeStream->writeByte(_lightswitch); // 17
@@ -691,21 +693,24 @@ void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset) {
uint32 checksum = computeChecksum();
writeStream->writeUint32BE(checksum); // 64
+ // Reverse the builtin-palette offset applied by loadConfig()
+ int16 paletteMember = _defaultPalette.member;
+ if (paletteMember < 0)
+ paletteMember += 1;
if (_version >= kFileVer400 && _version < kFileVer500) {
writeStream->writeSint16BE(_field30); // 68
+ writeStream->writeSint16BE(paletteMember); // 70
- // This loop isn't writing meaningful data currently
- // But it is possible that this data might be needed
- for (int i = 0; i < 0x08; i++) {
- writeStream->writeByte(0); // 70, 71, 72, 73, 74, 75, 76, 77
- }
- } else if (_version >= kFileVer500 && _version < kFileVer600) {
for (int i = 0; i < 0x08; i++) {
- writeStream->writeByte(0); // 68, 69, 70, 71, 72, 73, 74, 75
+ writeStream->writeByte(0); // 72, 73, 74, 75, 76, 77, 78, 79
}
+ } else if (_version >= kFileVer500 && _version < kFileVer1000) {
+ writeStream->writeSint16BE(_field30); // 68
+ writeStream->writeSint16BE(_defPaletteNum); // 70
+ writeStream->writeSint32BE(_chunkBaseNum); // 72
writeStream->writeSint16BE(_defaultPalette.castLib); // 76
- writeStream->writeSint16BE(_defaultPalette.member); // 78
+ writeStream->writeSint16BE(paletteMember); // 78
}
if (_version >= kFileVer600 && _version < kFileVer1000) {
@@ -745,12 +750,12 @@ void Cast::saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset) {
uint32 Cast::getConfigSize() {
if (_version >= kFileVer400 && _version < kFileVer500) {
- return 78; // 78 bytes of data in castConfig
- } else if (_version >= kFileVer500 && _version < kFileVer600) {
return 80; // 80 bytes of data in castConfig
+ } else if (_version >= kFileVer500 && _version < kFileVer1000) {
+ return _version < kFileVer600 ? 80 : 84; // D5: 80 bytes; D6-D9: 84 bytes
}
- warning("Cast::getConfigSize: Director version 6+ is not handled");
+ warning("Cast::getConfigSize: Director version %d is not handled", humanVersion(_version));
return 0;
}
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 1ab81f0ffe5..7325732d977 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -110,7 +110,7 @@ public:
void loadSord(Common::SeekableReadStreamEndian &stream);
bool importFileInto(int castId, const Common::Path &path);
- void saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset);
+ void saveConfig(Common::SeekableWriteStream *writeStream, uint32 offset, uint32 tag);
void saveCastData(Common::SeekableWriteStream *writeStream, Resource *res);
void saveCastData();
void writeCastInfo(Common::SeekableWriteStream *writeStream, uint32 castId);
More information about the Scummvm-git-logs
mailing list