[Scummvm-git-logs] scummvm master -> 3d1a68a3ed46517abb2f547efd85d910dad05768

djsrv dservilla at gmail.com
Thu Jul 16 01:06:29 UTC 2020


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

Summary:
3d1a68a3ed DIRECTOR: Improve file/cast info loading


Commit: 3d1a68a3ed46517abb2f547efd85d910dad05768
    https://github.com/scummvm/scummvm/commit/3d1a68a3ed46517abb2f547efd85d910dad05768
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-15T21:03:58-04:00

Commit Message:
DIRECTOR: Improve file/cast info loading

Changed paths:
    engines/director/cast.cpp
    engines/director/movie.cpp
    engines/director/movie.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index fcf66f4e97..12984f1c27 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -700,9 +700,11 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 	if (debugChannelSet(5, kDebugLoading) && stream.size() < 2048)
 		stream.hexdump(stream.size());
 
-	uint32 size1, size2, size3, castType, sizeToRead;
+	uint32 castSize, castInfoSize, size3, castType, castSizeToRead;
 	byte unk1 = 0, unk2 = 0, unk3 = 0;
 
+	// D2-3 cast members should be loaded in loadCastDataVWCR
+#if 0
 	if (_vm->getVersion() <= 3) {
 		size1 = stream.readUint16();
 		sizeToRead = size1 +16; // 16 is for bounding rects
@@ -712,36 +714,41 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		unk1 = stream.readByte();
 		unk2 = stream.readByte();
 		unk3 = stream.readByte();
-	} else if (_vm->getVersion() == 4) {
-		size1 = stream.readUint16();
-		sizeToRead = size1 + 2 + 16 + 1; // 16 is for bounding rects + 1 is for moved _flag
-		size2 = stream.readUint32();
+	}
+#endif
+
+	if (_vm->getVersion() == 4) {
+		castSize = stream.readUint16();
+		castSizeToRead = castSize - 1; // the first byte is castType
+		castInfoSize = stream.readUint32();
 		size3 = 0;
 		castType = stream.readByte();
 	} else if (_vm->getVersion() == 5) {
 		castType = stream.readUint32();
 		size3 = stream.readUint32();
-		size2 = stream.readUint32();
-		size1 = stream.readUint32();
+		castInfoSize = stream.readUint32();
+		castSize = stream.readUint32();
 		if (castType == 1) {
 			if (size3 == 0)
 				return;
-			for (uint32 skip = 0; skip < (size1 - 4) / 4; skip++)
+			for (uint32 skip = 0; skip < (castSize - 4) / 4; skip++)
 				stream.readUint32();
 		}
 
-		sizeToRead = stream.size();
+		castSizeToRead = stream.size();
 	} else {
 		error("Cast::loadCastData: unsupported Director version (%d)", _vm->getVersion());
 	}
 
-	debugC(3, kDebugLoading, "Cast::loadCastData(): CASt: id: %d type: %x size1: %d size2: %d (%x) size3: %d unk1: %d unk2: %d unk3: %d",
-		id, castType, size1, size2, size2, size3, unk1, unk2, unk3);
+	debugC(3, kDebugLoading, "Cast::loadCastData(): CASt: id: %d type: %x castSize: %d castInfoSize: %d (%x) size3: %d unk1: %d unk2: %d unk3: %d",
+		id, castType, castSize, castInfoSize, castInfoSize, size3, unk1, unk2, unk3);
+
+	// read the cast member itself
 
-	byte *data = (byte *)calloc(sizeToRead, 1);
-	stream.read(data, sizeToRead);
+	byte *data = (byte *)calloc(castSizeToRead, 1);
+	stream.read(data, castSizeToRead);
 
-	Common::MemoryReadStreamEndian castStream(data, sizeToRead, stream.isBE());
+	Common::MemoryReadStreamEndian castStream(data, castSizeToRead, stream.isBE());
 
 	switch (castType) {
 	case kCastBitmap:
@@ -778,24 +785,24 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		break;
 	case kCastFilmLoop:
 		warning("STUB: Cast::loadCastData(): kCastFilmLoop (%d children)", res->children.size());
-		size2 = 0;
+		castInfoSize = 0;
 		break;
 	case kCastPalette:
 		warning("STUB: Cast::loadCastData(): kCastPalette (%d children)", res->children.size());
-		size2 = 0;
+		castInfoSize = 0;
 		break;
 	case kCastPicture:
 		warning("STUB: Cast::loadCastData(): kCastPicture (%d children)", res->children.size());
-		size2 = 0;
+		castInfoSize = 0;
 		break;
 	case kCastMovie:
 		warning("STUB: Cast::loadCastData(): kCastMovie (%d children)", res->children.size());
-		size2 = 0;
+		castInfoSize = 0;
 		break;
 	default:
 		warning("Cast::loadCastData(): Unhandled cast type: %d [%s] (%d children)", castType, tag2str(castType), res->children.size());
 		// also don't try and read the strings... we don't know what this item is.
-		size2 = 0;
+		castInfoSize = 0;
 		break;
 	}
 
@@ -810,93 +817,10 @@ void Cast::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 
 	free(data);
 
-	if (size2 && _vm->getVersion() < 5) {
-		Common::Array<DataEntry> castStrings = Movie::loadDataEntries(stream, false);
+	// read the cast member info
 
-		debugCN(4, kDebugLoading, "Cast::loadCastData(): str(%d): '", castStrings.size());
-
-		for (uint i = 0; i < castStrings.size(); i++) {
-			debugCN(4, kDebugLoading, "%s'", castStrings[i].readString().c_str());
-			if (i != castStrings.size() - 1)
-				debugCN(4, kDebugLoading, ", '");
-		}
-		debugC(4, kDebugLoading, "'");
-
-		CastMemberInfo *ci = new CastMemberInfo();
-		Common::MemoryReadStreamEndian *entryStream;
-
-		// We have here variable number of strings. Thus, instead of
-		// adding tons of ifs, we use this switch()
-		switch (castStrings.size()) {
-		default:
-			warning("Cast::loadCastData(): BUILDBOT: extra %d strings", castStrings.size() - 8);
-			// fallthrough
-		case 8:
-			if (castStrings[7].len) {
-				entryStream = new Common::MemoryReadStreamEndian(castStrings[7].data, castStrings[7].len, stream.isBE());
-				readEditInfo(&ci->textEditInfo, entryStream);
-				delete entryStream;
-			}
-			// fallthrough
-		case 7:
-			if (castStrings[6].len) {
-				entryStream = new Common::MemoryReadStreamEndian(castStrings[6].data, castStrings[6].len, stream.isBE());
-
-				int16 count = entryStream->readUint16();
-
-				for (uint i = 0; i < count; i++)
-					ci->scriptStyle.read(*entryStream);
-				delete entryStream;
-			}
-			// fallthrough
-		case 6:
-			if (castStrings[5].len) {
-				entryStream = new Common::MemoryReadStreamEndian(castStrings[5].data, castStrings[5].len, stream.isBE());
-				readEditInfo(&ci->scriptEditInfo, entryStream);
-				delete entryStream;
-			}
-			// fallthrough
-		case 5:
-			ci->type = castStrings[4].readString();
-			// fallthrough
-		case 4:
-			ci->fileName = castStrings[3].readString();
-			// fallthrough
-		case 3:
-			ci->directory = castStrings[2].readString();
-			// fallthrough
-		case 2:
-			ci->name = castStrings[1].readString();
-
-			if (!ci->name.empty()) {
-				_castsNames[ci->name] = id;
-			}
-			// fallthrough
-		case 1:
-			ci->script = castStrings[0].readString(false);
-			// fallthrough
-		case 0:
-			break;
-		}
-
-		CastMember *member = _loadedCast->getVal(id);
-		// For D4+ we may force Lingo scripts
-		if (_vm->getVersion() < 4 || debugChannelSet(-1, kDebugNoBytecode)) {
-			if (!ci->script.empty()) {
-				ScriptType scriptType = kCastScript;
-				// the script type here could be wrong!
-				if (member->_type == kCastLingoScript) {
-					scriptType = ((ScriptCastMember *)member)->_scriptType;
-				}
-
-				if (ConfMan.getBool("dump_scripts"))
-					dumpScript(ci->script.c_str(), scriptType, id);
-
-				_lingoArchive->addCode(ci->script.c_str(), scriptType, id, ci->name.c_str());
-			}
-		}
-
-		_castsInfo[id] = ci;
+	if (castInfoSize && _vm->getVersion() < 5) {
+		loadCastInfo(stream, id);
 	}
 
 	if (size3)
@@ -1069,29 +993,90 @@ void Cast::dumpScript(const char *script, ScriptType type, uint16 id) {
 }
 
 void Cast::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id) {
-	Common::Array<DataEntry> castStrings = Movie::loadDataEntries(stream);
-	CastMemberInfo *ci = new CastMemberInfo();
+	InfoEntries castInfo = Movie::loadInfoEntries(stream);
+
+	debugCN(4, kDebugLoading, "Cast::loadCastInfo(): str(%d): '", castInfo.strings.size());
 
-	ci->script = castStrings[0].readString(false);
+	for (uint i = 0; i < castInfo.strings.size(); i++) {
+		debugCN(4, kDebugLoading, "%s'", castInfo.strings[i].readString().c_str());
+		if (i != castInfo.strings.size() - 1)
+			debugCN(4, kDebugLoading, ", '");
+	}
+	debugC(4, kDebugLoading, "'");
+
+	CastMemberInfo *ci = new CastMemberInfo();
+	Common::MemoryReadStreamEndian *entryStream;
 
-	if (!ci->script.empty() && ConfMan.getBool("dump_scripts"))
-		dumpScript(ci->script.c_str(), kCastScript, id);
+	// We have here variable number of strings. Thus, instead of
+	// adding tons of ifs, we use this switch()
+	switch (castInfo.strings.size()) {
+	default:
+		warning("Cast::loadCastInfo(): BUILDBOT: extra %d strings", castInfo.strings.size() - 8);
+		// fallthrough
+	case 8:
+		if (castInfo.strings[7].len) {
+			entryStream = new Common::MemoryReadStreamEndian(castInfo.strings[7].data, castInfo.strings[7].len, stream.isBE());
+			readEditInfo(&ci->textEditInfo, entryStream);
+			delete entryStream;
+		}
+		// fallthrough
+	case 7:
+		if (castInfo.strings[6].len) {
+			entryStream = new Common::MemoryReadStreamEndian(castInfo.strings[6].data, castInfo.strings[6].len, stream.isBE());
 
-	if (!ci->script.empty())
-		_lingoArchive->addCode(ci->script.c_str(), kCastScript, id, ci->name.c_str());
+			int16 count = entryStream->readUint16();
 
-	ci->name = castStrings[1].readString();
-	ci->directory = castStrings[2].readString();
-	ci->fileName = castStrings[3].readString();
-	ci->type = castStrings[4].readString();
+			for (uint i = 0; i < count; i++)
+				ci->scriptStyle.read(*entryStream);
+			delete entryStream;
+		}
+		// fallthrough
+	case 6:
+		if (castInfo.strings[5].len) {
+			entryStream = new Common::MemoryReadStreamEndian(castInfo.strings[5].data, castInfo.strings[5].len, stream.isBE());
+			readEditInfo(&ci->scriptEditInfo, entryStream);
+			delete entryStream;
+		}
+		// fallthrough
+	case 5:
+		ci->type = castInfo.strings[4].readString();
+		// fallthrough
+	case 4:
+		ci->fileName = castInfo.strings[3].readString();
+		// fallthrough
+	case 3:
+		ci->directory = castInfo.strings[2].readString();
+		// fallthrough
+	case 2:
+		ci->name = castInfo.strings[1].readString();
+
+		if (!ci->name.empty()) {
+			_castsNames[ci->name] = id;
+		}
+		// fallthrough
+	case 1:
+		ci->script = castInfo.strings[0].readString(false);
+		// fallthrough
+	case 0:
+		break;
+	}
 
-	castStrings.clear();
+	CastMember *member = _loadedCast->getVal(id);
+	// For D4+ we may force Lingo scripts
+	if (_vm->getVersion() < 4 || debugChannelSet(-1, kDebugNoBytecode)) {
+		if (!ci->script.empty()) {
+			ScriptType scriptType = kCastScript;
+			// the script type here could be wrong!
+			if (member->_type == kCastLingoScript) {
+				scriptType = ((ScriptCastMember *)member)->_scriptType;
+			}
 
-	debugC(5, kDebugLoading, "Cast::loadCastInfo(): CastMemberInfo: name: '%s' directory: '%s', fileName: '%s', type: '%s'",
-				ci->name.c_str(), ci->directory.c_str(), ci->fileName.c_str(), ci->type.c_str());
+			if (ConfMan.getBool("dump_scripts"))
+				dumpScript(ci->script.c_str(), scriptType, id);
 
-	if (!ci->name.empty())
-		_castsNames[ci->name] = id;
+			_lingoArchive->addCode(ci->script.c_str(), scriptType, id, ci->name.c_str());
+		}
+	}
 
 	_castsInfo[id] = ci;
 }
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index a3eca8842f..c5398cb7c4 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -146,50 +146,51 @@ Common::Rect Movie::readRect(Common::ReadStreamEndian &stream) {
 	return rect;
 }
 
-Common::Array<DataEntry> Movie::loadDataEntries(Common::SeekableSubReadStreamEndian &stream, bool hasHeader) {
-	Common::Array<DataEntry> strings;
-	uint32 offset = 0;
-
-	if (hasHeader) {
-		offset = stream.readUint32();
-		/*uint32 unk1 = */ stream.readUint32();
-		/*uint32 unk2 = */ stream.readUint32();
-		/*entryType = */ stream.readUint32();
-		stream.seek(offset);
-	}
+InfoEntries Movie::loadInfoEntries(Common::SeekableSubReadStreamEndian &stream) {
+	uint32 offset = stream.pos();
+	offset += stream.readUint32();
+
+	InfoEntries res;
+	res.unk1 = stream.readUint32();
+	res.unk2 = stream.readUint32();
+	res.flags = stream.readUint32();
+
+	if (g_director->getVersion() >= 4)
+		res.scriptId = stream.readUint32();
 
+	stream.seek(offset);
 	uint16 count = stream.readUint16() + 1;
 
-	debugC(3, kDebugLoading, "Movie::loadDataEntries(): DataEntry: %d entries", count - 1);
+	debugC(3, kDebugLoading, "Movie::loadInfoEntries(): InfoEntry: %d entries", count - 1);
 
 	if (count == 1)
-		return strings;
+		return res;
 
 	uint32 *entries = (uint32 *)calloc(count, sizeof(uint32));
 
 	for (uint i = 0; i < count; i++)
 		entries[i] = stream.readUint32();
 
-	strings.resize(count - 1);
+	res.strings.resize(count - 1);
 
 	for (uint16 i = 0; i < count - 1; i++) {
-		strings[i].len = entries[i + 1] - entries[i];
-		strings[i].data = (byte *)malloc(strings[i].len);
-		stream.read(strings[i].data, strings[i].len);
+		res.strings[i].len = entries[i + 1] - entries[i];
+		res.strings[i].data = (byte *)malloc(res.strings[i].len);
+		stream.read(res.strings[i].data, res.strings[i].len);
 
-		debugC(6, kDebugLoading, "DataEntry %d: %d bytes", i, strings[i].len);
+		debugC(6, kDebugLoading, "InfoEntry %d: %d bytes", i, res.strings[i].len);
 	}
 
 	free(entries);
 
-	return strings;
+	return res;
 }
 
 void Movie::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
 	debugC(2, kDebugLoading, "****** Loading FileInfo VWFI");
 
-	Common::Array<DataEntry> fileInfoStrings = Movie::loadDataEntries(stream);
-	_script = fileInfoStrings[0].readString(false);
+	InfoEntries fileInfo = Movie::loadInfoEntries(stream);
+	_script = fileInfo.strings[0].readString(false);
 
 	if (!_script.empty() && ConfMan.getBool("dump_scripts"))
 		_cast->dumpScript(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
@@ -198,16 +199,16 @@ void Movie::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
 		_cast->_lingoArchive->addCode(_script.c_str(), kMovieScript, _cast->_movieScriptCount);
 
 	_cast->_movieScriptCount++;
-	_changedBy = fileInfoStrings[1].readString();
-	_createdBy = fileInfoStrings[2].readString();
-	_createdBy = fileInfoStrings[3].readString();
+	_changedBy = fileInfo.strings[1].readString();
+	_createdBy = fileInfo.strings[2].readString();
+	_createdBy = fileInfo.strings[3].readString();
 
 	uint16 preload = 0;
-	if (fileInfoStrings[4].len) {
+	if (fileInfo.strings[4].len) {
 		if (stream.isBE())
-			preload = READ_BE_INT16(fileInfoStrings[4].data);
+			preload = READ_BE_INT16(fileInfo.strings[4].data);
 		else
-			preload = READ_LE_INT16(fileInfoStrings[4].data);
+			preload = READ_LE_INT16(fileInfo.strings[4].data);
 	}
 
 	if (debugChannelSet(3, kDebugLoading)) {
@@ -217,9 +218,9 @@ void Movie::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
 		debug("VWFI: directory: '%s'", _createdBy.c_str());
 		debug("VWFI: preload: %d (0x%x)", preload, preload);
 
-		for (uint i = 5; i < fileInfoStrings.size(); i++) {
-			debug("VWFI: entry %d (%d bytes)", i, fileInfoStrings[i].len);
-			Common::hexdump(fileInfoStrings[i].data, fileInfoStrings[i].len);
+		for (uint i = 5; i < fileInfo.strings.size(); i++) {
+			debug("VWFI: entry %d (%d bytes)", i, fileInfo.strings[i].len);
+			Common::hexdump(fileInfo.strings[i].data, fileInfo.strings[i].len);
 		}
 	}
 }
diff --git a/engines/director/movie.h b/engines/director/movie.h
index f2312ac0d9..049983c6bf 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -41,13 +41,13 @@ class ScriptContext;
 class Stage;
 struct Symbol;
 
-struct DataEntry {
+struct InfoEntry {
 	uint32 len;
 	byte *data;
 
-	DataEntry() { len = 0; data = nullptr; }
+	InfoEntry() { len = 0; data = nullptr; }
 
-	~DataEntry() {
+	~InfoEntry() {
 		free(data);
 	}
 
@@ -69,13 +69,23 @@ struct DataEntry {
 	}
 };
 
+struct InfoEntries {
+	uint32 unk1;
+	uint32 unk2;
+	uint32 flags;
+	uint32 scriptId;
+	Common::Array<InfoEntry> strings;
+
+	InfoEntries() : unk1(0), unk2(0), flags(0), scriptId(0) {}
+};
+
 class Movie {
 public:
 	Movie(Stage *stage);
 	~Movie();
 
 	static Common::Rect readRect(Common::ReadStreamEndian &stream);
-	static Common::Array<DataEntry> loadDataEntries(Common::SeekableSubReadStreamEndian &stream, bool hasHeader = true);
+	static InfoEntries loadInfoEntries(Common::SeekableSubReadStreamEndian &stream);
 
 	bool loadArchive();
 	void setArchive(Archive *archive);




More information about the Scummvm-git-logs mailing list