[Scummvm-git-logs] scummvm master -> abbd516eaa44578e5d4b60a9913b6323b53d40eb

elasota noreply at scummvm.org
Sun Nov 6 04:18:19 UTC 2022


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

Summary:
5f9246b4c1 MTROPOLIS: Refactor VISE 3 archive code.
197f59dd00 MTROPOLIS: Add asset ID debug inspector to images.
1b5b4d2528 MTROPOLIS: Fix list variable modifiers in behaviors not copying GUID/name.  Add more debug inspectors to visual elements
b7564754c6 MTROPOLIS: Add list variable modifier "shuffle" attrib.
052f124079 MTROPOLIS: Add world manager "scenefades" attrib stub.
abbd516eaa MTROPOLIS: Fix VISE 3 archives


Commit: 5f9246b4c1eff316d02ecd2f70a3fdb0381bcb0b
    https://github.com/scummvm/scummvm/commit/5f9246b4c1eff316d02ecd2f70a3fdb0381bcb0b
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:57-04:00

Commit Message:
MTROPOLIS: Refactor VISE 3 archive code.

Changed paths:
    engines/mtropolis/boot.cpp


diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp
index a6b83ac70c0..05948fe7a9d 100644
--- a/engines/mtropolis/boot.cpp
+++ b/engines/mtropolis/boot.cpp
@@ -426,10 +426,24 @@ private:
 		Common::String fileName;
 	};
 
-	class FakeFileArchive : public Common::Archive {
+	class VISE3ArchiveMember : public Common::ArchiveMember {
 	public:
-		Common::Array<byte> &getDataFork() { return _dataFork; }
-		Common::Array<byte> &getResFork() { return _resFork; }
+		VISE3ArchiveMember(Common::SeekableReadStream *archiveStream, const VISE3FileDesc *fileDesc, bool isResFork);
+
+		Common::SeekableReadStream *createReadStream() const override;
+		Common::String getName() const override;
+
+	private:
+		Common::SeekableReadStream *_archiveStream;
+		const VISE3FileDesc *_fileDesc;
+		bool _isResFork;
+	};
+
+	class VISE3Archive : public Common::Archive {
+	public:
+		explicit VISE3Archive(Common::SeekableReadStream *archiveStream);
+
+		const VISE3FileDesc *getFileDesc(const Common::Path &path) const;
 
 		bool hasFile(const Common::Path &path) const override;
 		int listMembers(Common::ArchiveMemberList &list) const override;
@@ -437,61 +451,19 @@ private:
 		Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
 
 	private:
-		Common::Array<byte> _dataFork;
-		Common::Array<byte> _resFork;
+		bool getFileDescIndex(const Common::Path &path, uint &anOutIndex, bool &anOutIsResFork) const;
+
+		Common::SeekableReadStream *_archiveStream;
+		Common::Array<VISE3FileDesc> _fileDescs;
 	};
 
 	bool _isMac;
 };
 
-SPQRGameDataHandler::VISE3FileDesc::VISE3FileDesc() : type{ 0, 0, 0, 0 }, creator{ 0, 0, 0, 0 }, compressedDataSize(0), uncompressedDataSize(0), compressedResSize(0), uncompressedResSize(0), positionInArchive(0) {
-}
-
-bool SPQRGameDataHandler::FakeFileArchive::hasFile(const Common::Path &path) const {
-	return false;
-}
-
-int SPQRGameDataHandler::FakeFileArchive::listMembers(Common::ArchiveMemberList &list) const {
-	return 0;
-}
-
-const Common::ArchiveMemberPtr SPQRGameDataHandler::FakeFileArchive::getMember(const Common::Path &path) const {
-	return nullptr;
+SPQRGameDataHandler::VISE3ArchiveMember::VISE3ArchiveMember(Common::SeekableReadStream *archiveStream, const SPQRGameDataHandler::VISE3FileDesc *fileDesc, bool isResFork) : _archiveStream(archiveStream), _fileDesc(fileDesc), _isResFork(isResFork) {
 }
 
-Common::SeekableReadStream *SPQRGameDataHandler::FakeFileArchive::createReadStreamForMember(const Common::Path &path) const {
-	const Common::Array<byte> *forkData = nullptr;
-	if (path.rawString() == "file")
-		forkData = &_dataFork;
-	else if (path.rawString() == "file.rsrc")
-		forkData = &_resFork;
-	else
-		return nullptr;
-
-	if (forkData->size() == 0)
-		return nullptr;
-
-	byte *clonedData = static_cast<byte *>(malloc(forkData->size()));
-	if (!clonedData)
-		return nullptr;
-
-	memcpy(clonedData, &(*forkData)[0], forkData->size());
-
-	return new Common::MemoryReadStream(clonedData, forkData->size(), DisposeAfterUse::YES);
-}
-
-SPQRGameDataHandler::SPQRGameDataHandler(const Game &game, const MTropolisGameDescription &gameDesc) : GameDataHandler(game, gameDesc), _isMac(gameDesc.desc.platform == Common::kPlatformMacintosh) {
-}
-
-void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<ProjectPersistentResource> > &persistentResources, Common::Array<FileIdentification> &files) {
-	const MacVISE3InstallerUnpackRequest unpackRequests[] = {
-		{"Basic.rPP", false, true, MTFT_EXTENSION},
-		{"Extras.rPP", false, true, MTFT_EXTENSION},
-		{"mCursors.cPP", false, true, MTFT_EXTENSION},
-		{"SPQR PPC Start", false, true, MTFT_PLAYER},
-		{"Data File SPQR", true, false, MTFT_MAIN},
-	};
-
+Common::SeekableReadStream *SPQRGameDataHandler::VISE3ArchiveMember::createReadStream() const {
 	static const uint8 vl3DeobfuscationTable[] = {
 		0x6a, 0xb7, 0x36, 0xec, 0x15, 0xd9, 0xc8, 0x73, 0xe8, 0x38, 0x9a, 0xdf, 0x21, 0x25, 0xd0, 0xcc,
 		0xfd, 0xdc, 0x16, 0xd7, 0xe3, 0x43, 0x05, 0xc5, 0x8f, 0x48, 0xda, 0xf2, 0x3f, 0x10, 0x23, 0x6c,
@@ -511,27 +483,68 @@ void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<
 		0x86, 0xdd, 0x5f, 0x42, 0xd3, 0x02, 0x61, 0x95, 0x0c, 0x5c, 0xa5, 0xcd, 0xc0, 0x07, 0xe2, 0xf3,
 	};
 
-	Common::SharedPtr<Common::MacResManager> installerResMan(new Common::MacResManager());
+	uint32 uncompressedSize = _isResFork ? _fileDesc->uncompressedResSize : _fileDesc->uncompressedDataSize;
+	uint32 compressedSize = _isResFork ? _fileDesc->compressedResSize : _fileDesc->compressedDataSize;
+	uint32 filePosition = _fileDesc->positionInArchive;
 
-	if (!installerResMan->open("Install.vct"))
-		error("Failed to open SPQR installer");
+	if (_isResFork)
+		filePosition += _fileDesc->compressedDataSize;
 
-	if (!installerResMan->hasDataFork())
-		error("SPQR installer has no data fork");
+	if (uncompressedSize == 0)
+		return nullptr;
 
-	Common::SharedPtr<Common::SeekableReadStream> installerDataForkStream(installerResMan->getDataFork());
+	Common::Array<byte> compressedData;
+	compressedData.resize(compressedSize);
+
+	_archiveStream->seek(filePosition, SEEK_SET);
+	if (_archiveStream->read(&compressedData[0], compressedSize) != compressedSize)
+		return nullptr;
+
+	// Undo byte swapping
+	for (uint i = 1; i < compressedSize; i += 2) {
+		byte temp = compressedData[i];
+		compressedData[i] = compressedData[i - 1];
+		compressedData[i - 1] = temp;
+	}
+
+	// Undo obfuscation
+	for (byte &b : compressedData)
+		b = vl3DeobfuscationTable[b];
+
+	byte *decompressedData = static_cast<byte *>(malloc(uncompressedSize));
+	if (!decompressedData)
+		return nullptr;
+
+	if (!Common::inflateZlibHeaderless(decompressedData, uncompressedSize, &compressedData[0], compressedSize)) {
+		free(decompressedData);
+		return nullptr;
+	}
+
+	return new Common::MemoryReadStream(decompressedData, uncompressedSize, DisposeAfterUse::YES);
+}
+
+Common::String SPQRGameDataHandler::VISE3ArchiveMember::getName() const {
+	if (_isResFork)
+		return _fileDesc->fileName + ".rsrc";
+	else
+		return _fileDesc->fileName;
+}
 
+SPQRGameDataHandler::VISE3FileDesc::VISE3FileDesc() : type{ 0, 0, 0, 0 }, creator{ 0, 0, 0, 0 }, compressedDataSize(0), uncompressedDataSize(0), compressedResSize(0), uncompressedResSize(0), positionInArchive(0) {
+}
+
+SPQRGameDataHandler::VISE3Archive::VISE3Archive(Common::SeekableReadStream *archiveStream) : _archiveStream(archiveStream) {
 	uint8 vl3Header[44];
-	if (installerDataForkStream->read(vl3Header, 44) != 44 || memcmp(vl3Header, "SVCT", 4))
+	if (archiveStream->read(vl3Header, 44) != 44 || memcmp(vl3Header, "SVCT", 4))
 		error("Failed to read VISE 3 header");
 
 	uint32 catalogPosition = READ_BE_UINT32(vl3Header + 36);
 
-	if (!installerDataForkStream->seek(catalogPosition))
+	if (!archiveStream->seek(catalogPosition))
 		error("Failed to seek to VISE 3 catalog");
 
 	uint8 vl3Catalog[20];
-	if (installerDataForkStream->read(vl3Catalog, 20) != 20 || memcmp(vl3Catalog, "CVCT", 4))
+	if (archiveStream->read(vl3Catalog, 20) != 20 || memcmp(vl3Catalog, "CVCT", 4))
 		error("Failed to read VISE 3 catalog");
 
 	uint16 numEntries = READ_BE_UINT16(vl3Catalog + 16);
@@ -540,19 +553,19 @@ void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<
 
 	for (uint16 i = 0; i < numEntries; i++) {
 		uint8 entryMagic[4];
-		if (installerDataForkStream->read(entryMagic, 4) != 4 || memcmp(entryMagic + 1, "VCT", 3))
+		if (archiveStream->read(entryMagic, 4) != 4 || memcmp(entryMagic + 1, "VCT", 3))
 			error("Failed to read VISE 3 catalog item");
 
 		if (entryMagic[0] == 'D') {
 			uint8 directoryData[78];
-			if (installerDataForkStream->read(directoryData, 78) != 78)
+			if (archiveStream->read(directoryData, 78) != 78)
 				error("Failed to read VISE 3 directory");
 
 			uint8 nameLength = directoryData[76];
-			installerDataForkStream->seek(nameLength, SEEK_CUR);
+			archiveStream->seek(nameLength, SEEK_CUR);
 		} else if (entryMagic[0] == 'F') {
 			uint8 fileData[120];
-			if (installerDataForkStream->read(fileData, 120) != 120)
+			if (archiveStream->read(fileData, 120) != 120)
 				error("Failed to read VISE 3 file");
 
 			VISE3FileDesc desc;
@@ -568,7 +581,7 @@ void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<
 
 			if (nameLength > 0) {
 				char fileNameChars[256];
-				if (installerDataForkStream->read(fileNameChars, nameLength) != nameLength)
+				if (archiveStream->read(fileNameChars, nameLength) != nameLength)
 					error("Failed to read VISE 3 file name");
 				desc.fileName = Common::String(fileNameChars, nameLength);
 			}
@@ -578,87 +591,129 @@ void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<
 			error("Unknown VISE 3 catalog entry item type");
 		}
 	}
+}
 
-	debug(1, "Unpacking files...");
+const SPQRGameDataHandler::VISE3FileDesc *SPQRGameDataHandler::VISE3Archive::getFileDesc(const Common::Path &path) const {
+	uint index = 0;
+	bool isResFork = false;
+	if (!getFileDescIndex(path, index, isResFork))
+		return nullptr;
 
-	for (const MacVISE3InstallerUnpackRequest &request : unpackRequests) {
-		const VISE3FileDesc *fileDesc = nullptr;
-		for (const VISE3FileDesc &candidateDesc : archiveFiles) {
-			if (candidateDesc.fileName == request.fileName) {
-				fileDesc = &candidateDesc;
-				break;
-			}
+	return &_fileDescs[index];
+}
+
+bool SPQRGameDataHandler::VISE3Archive::hasFile(const Common::Path &path) const {
+	uint index = 0;
+	bool isResFork = false;
+	return getFileDescIndex(path, index, isResFork);
+}
+
+int SPQRGameDataHandler::VISE3Archive::listMembers(Common::ArchiveMemberList &list) const {
+	int numMembers = 0;
+	for (uint fileIndex = 0; fileIndex < _fileDescs.size(); fileIndex++) {
+		const VISE3FileDesc &desc = _fileDescs[fileIndex];
+
+		if (desc.uncompressedDataSize) {
+			list.push_back(Common::ArchiveMemberPtr(new VISE3ArchiveMember(_archiveStream, &desc, false)));
+			numMembers++;
 		}
+		if (desc.uncompressedResSize) {
+			list.push_back(Common::ArchiveMemberPtr(new VISE3ArchiveMember(_archiveStream, &desc, true)));
+			numMembers++;
+		}
+	}
+	return numMembers;
+}
 
-		if (!fileDesc)
-			error("Couldn't find file '%s' in VISE 3 archive", request.fileName);
+const Common::ArchiveMemberPtr SPQRGameDataHandler::VISE3Archive::getMember(const Common::Path &path) const {
+	uint descIndex = 0;
+	bool isResFork = false;
+	if (!getFileDescIndex(path, descIndex, isResFork))
+		return nullptr;
 
-		FileIdentification ident;
-		ident.fileName = fileDesc->fileName;
-		ident.macCreator.value = MKTAG(fileDesc->creator[0], fileDesc->creator[1], fileDesc->creator[2], fileDesc->creator[3]);
-		ident.macType.value = MKTAG(fileDesc->type[0], fileDesc->type[1], fileDesc->type[2], fileDesc->type[3]);
-		ident.category = request.fileType;
+	return Common::ArchiveMemberPtr(new VISE3ArchiveMember(_archiveStream, &_fileDescs[descIndex], isResFork));
+}
 
-		Common::SharedPtr<FakeFileArchive> fakeArchive(new FakeFileArchive());
+Common::SeekableReadStream *SPQRGameDataHandler::VISE3Archive::createReadStreamForMember(const Common::Path &path) const {
+	Common::ArchiveMemberPtr archiveMember = getMember(path);
+	if (!archiveMember)
+		return nullptr;
 
-		bool forksNeeded[2] = {request.extractData,
-							   request.extractResources};
-		uint32 forkCompressedDataLoc[2] = {fileDesc->positionInArchive,
-										   fileDesc->positionInArchive + fileDesc->compressedDataSize};
-		uint32 forkCompressedSize[2] = {fileDesc->compressedDataSize,
-										fileDesc->compressedResSize};
-		uint32 forkUncompressedSize[2] = { fileDesc->uncompressedDataSize,
-										  fileDesc->uncompressedResSize};
+	return archiveMember->createReadStream();
+}
 
-		Common::Array<byte> *forkDecompressedData[2] = {&fakeArchive->getDataFork(),
-														&fakeArchive->getResFork()};
+bool SPQRGameDataHandler::VISE3Archive::getFileDescIndex(const Common::Path &path, uint &anOutIndex, bool &anOutIsResFork) const {
+	Common::String convertedPath = path.toString(':');
+	bool isResFork = false;
+	if (convertedPath.hasSuffix(".rsrc")) {
+		isResFork = true;
+		convertedPath = convertedPath.substr(0, convertedPath.size() - 5);
+	}
 
-		for (int fi = 0; fi < 2; fi++) {
-			if (!forksNeeded[fi])
-				continue;
+	for (uint descIndex = 0; descIndex < _fileDescs.size(); descIndex++) {
+		const VISE3FileDesc &desc = _fileDescs[descIndex];
 
-			assert(forkCompressedSize[fi] != 0);
-			if (forkCompressedSize[fi] == 0)
-				continue;
+		if (desc.fileName == convertedPath) {
+			if ((isResFork ? desc.uncompressedResSize : desc.uncompressedDataSize) == 0)
+				return false;
 
-			installerDataForkStream->seek(forkCompressedDataLoc[fi]);
+			anOutIsResFork = isResFork;
+			anOutIndex = descIndex;
+			return true;
+		}
+	}
 
-			Common::Array<byte> compressedData;
-			compressedData.resize(forkCompressedSize[fi]);
+	return false;
+}
 
-			uint8 *compressedBytes = &compressedData[0];
-			uint32 compressedSize = forkCompressedSize[fi];
-			uint32 uncompressedSize = forkUncompressedSize[fi];
-			installerDataForkStream->read(compressedBytes, forkCompressedSize[fi]);
+SPQRGameDataHandler::SPQRGameDataHandler(const Game &game, const MTropolisGameDescription &gameDesc) : GameDataHandler(game, gameDesc), _isMac(gameDesc.desc.platform == Common::kPlatformMacintosh) {
+}
 
-			// Undo obfuscation
-			for (uint32 i = 0; i < compressedSize; i++)
-				compressedBytes[i] = vl3DeobfuscationTable[compressedBytes[i]];
+void SPQRGameDataHandler::unpackAdditionalFiles(Common::Array<Common::SharedPtr<ProjectPersistentResource> > &persistentResources, Common::Array<FileIdentification> &files) {
+	const MacVISE3InstallerUnpackRequest unpackRequests[] = {
+		{"Basic.rPP", false, true, MTFT_EXTENSION},
+		{"Extras.rPP", false, true, MTFT_EXTENSION},
+		{"mCursors.cPP", false, true, MTFT_EXTENSION},
+		{"SPQR PPC Start", false, true, MTFT_PLAYER},
+		{"Data File SPQR", true, false, MTFT_MAIN},
+	};
 
-			// Undo 16-bit byte swaps
-			for (uint32 i = 1; i < compressedSize; i += 2) {
-				uint8 temp = compressedBytes[i];
-				compressedBytes[i] = compressedBytes[i - 1];
-				compressedBytes[i - 1] = temp;
-			}
+	Common::SharedPtr<Common::MacResManager> installerResMan(new Common::MacResManager());
+
+	if (!installerResMan->open("Install.vct"))
+		error("Failed to open SPQR installer");
 
-			Common::Array<byte> &decompressedData = *forkDecompressedData[fi];
-			decompressedData.resize(uncompressedSize);
+	if (!installerResMan->hasDataFork())
+		error("SPQR installer has no data fork");
 
-			if (!Common::inflateZlibHeaderless(&decompressedData[0], uncompressedSize, &compressedBytes[0], compressedSize))
-				error("Failed to decompress file '%s'", request.fileName);
-		}
+	Common::SharedPtr<Common::SeekableReadStream> installerDataForkStream(installerResMan->getDataFork());
+
+	VISE3Archive archive(installerDataForkStream.get());
+
+	debug(1, "Unpacking files...");
+
+	for (const MacVISE3InstallerUnpackRequest &request : unpackRequests) {
+		const VISE3FileDesc *fileDesc = archive.getFileDesc(request.fileName);
+
+		if (!fileDesc)
+			error("Couldn't find file '%s' in VISE 3 archive", request.fileName);
+
+		FileIdentification ident;
+		ident.fileName = fileDesc->fileName;
+		ident.macCreator.value = MKTAG(fileDesc->creator[0], fileDesc->creator[1], fileDesc->creator[2], fileDesc->creator[3]);
+		ident.macType.value = MKTAG(fileDesc->type[0], fileDesc->type[1], fileDesc->type[2], fileDesc->type[3]);
+		ident.category = request.fileType;
 
 		if (request.extractResources) {
 			Common::SharedPtr<Common::MacResManager> resMan(new Common::MacResManager());
-			if (!resMan->open("file", *fakeArchive))
+			if (!resMan->open(request.fileName, archive))
 				error("Failed to open Mac res manager for file '%s'", request.fileName);
 
 			ident.resMan = resMan;
 		}
 
 		if (request.extractData)
-			ident.stream.reset(fakeArchive->createReadStreamForMember("file"));
+			ident.stream.reset(archive.createReadStreamForMember(request.fileName));
 
 		files.push_back(ident);
 	}


Commit: 197f59dd00e0517ed715a9a4c68b9dfa8e6f2f53
    https://github.com/scummvm/scummvm/commit/197f59dd00e0517ed715a9a4c68b9dfa8e6f2f53
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:57-04:00

Commit Message:
MTROPOLIS: Add asset ID debug inspector to images.

Changed paths:
    engines/mtropolis/elements.cpp
    engines/mtropolis/elements.h


diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp
index 247a88233f0..f8f8abfd7ea 100644
--- a/engines/mtropolis/elements.cpp
+++ b/engines/mtropolis/elements.cpp
@@ -1109,6 +1109,15 @@ void ImageElement::render(Window *window) {
 	}
 }
 
+#ifdef MTROPOLIS_DEBUG_ENABLE
+void ImageElement::debugInspect(IDebugInspectionReport *report) const {
+	VisualElement::debugInspect(report);
+
+	if (report->declareStatic("assetID"))
+		report->declareStaticContents(Common::String::format("%i", static_cast<int>(_assetID)));
+}
+#endif
+
 MiniscriptInstructionOutcome ImageElement::scriptSetFlushPriority(MiniscriptThread *thread, const DynamicValue &value) {
 	// We don't support flushing media, and this value isn't readable, so just discard it
 	return kMiniscriptInstructionOutcomeContinue;
diff --git a/engines/mtropolis/elements.h b/engines/mtropolis/elements.h
index 7cfc7a7d8e2..01011a304bc 100644
--- a/engines/mtropolis/elements.h
+++ b/engines/mtropolis/elements.h
@@ -193,6 +193,7 @@ public:
 #ifdef MTROPOLIS_DEBUG_ENABLE
 	const char *debugGetTypeName() const override { return "Image Element"; }
 	SupportStatus debugGetSupportStatus() const override { return kSupportStatusDone; }
+	void debugInspect(IDebugInspectionReport *report) const override;
 #endif
 
 private:


Commit: 1b5b4d25285fe25acf976fb2ce510dd48af6bd9b
    https://github.com/scummvm/scummvm/commit/1b5b4d25285fe25acf976fb2ce510dd48af6bd9b
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:58-04:00

Commit Message:
MTROPOLIS: Fix list variable modifiers in behaviors not copying GUID/name.  Add more debug inspectors to visual elements.

Changed paths:
    engines/mtropolis/plugin/standard.cpp
    engines/mtropolis/runtime.cpp


diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index e06c557ffdc..e787dbad29d 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -2901,7 +2901,7 @@ void ListVariableModifier::debugInspect(IDebugInspectionReport *report) const {
 }
 #endif
 
-ListVariableModifier::ListVariableModifier(const ListVariableModifier &other) : _preferredContentType(DynamicValueTypes::kNull) {
+ListVariableModifier::ListVariableModifier(const ListVariableModifier &other) : VariableModifier(other), _preferredContentType(DynamicValueTypes::kNull) {
 	if (other._list)
 		_list = other._list->clone();
 }
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 1266ba4350e..d48c7d61c55 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -222,7 +222,12 @@ void ModifierChildCloner::visitChildStructuralRef(Common::SharedPtr<Structural>
 }
 
 void ModifierChildCloner::visitChildModifierRef(Common::SharedPtr<Modifier> &modifier) {
+	uint32 oldGUID = modifier->getStaticGUID();
 	modifier = modifier->shallowClone();
+	assert(modifier->getStaticGUID() == oldGUID);
+
+	(void)oldGUID;
+
 	modifier->setSelfReference(modifier);
 	modifier->setParent(_relinkParent);
 
@@ -7957,6 +7962,8 @@ const Common::SharedPtr<Palette> &VisualElement::getPalette() const {
 void VisualElement::debugInspect(IDebugInspectionReport *report) const {
 	report->declareDynamic("layer", Common::String::format("%i", static_cast<int>(_layer)));
 	report->declareDynamic("relRect", Common::String::format("(%i,%i)-(%i,%i)", static_cast<int>(_rect.left), static_cast<int>(_rect.top), static_cast<int>(_rect.right), static_cast<int>(_rect.bottom)));
+	report->declareDynamic("directToScreen", Common::String(_directToScreen ? "true" : "false"));
+	report->declareDynamic("visible", Common::String(_visible ? "true" : "false"));
 
 	Element::debugInspect(report);
 }


Commit: b7564754c6bed2cd6f1fbd9eaa80d6fcd5d0340b
    https://github.com/scummvm/scummvm/commit/b7564754c6bed2cd6f1fbd9eaa80d6fcd5d0340b
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:59-04:00

Commit Message:
MTROPOLIS: Add list variable modifier "shuffle" attrib.

Changed paths:
    engines/mtropolis/plugin/standard.cpp


diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index e787dbad29d..85c88837566 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -2816,6 +2816,28 @@ bool ListVariableModifier::readAttribute(MiniscriptThread *thread, DynamicValue
 
 		size_t index = thread->getRuntime()->getRandom()->getRandomNumber(_list->getSize() - 1);
 		return _list->getAtIndex(index, result);
+	} else if (attrib == "shuffle") {
+		_list = _list->clone();
+
+		Common::RandomSource *rng = thread->getRuntime()->getRandom();
+
+		size_t listSize = _list->getSize();
+		for (size_t i = 1; i < listSize; i++) {
+			size_t sourceIndex = i;
+			size_t destIndex = rng->getRandomNumber(static_cast<uint>(listSize - 1 - i));
+			if (sourceIndex != destIndex) {
+				DynamicValue srcValue;
+				DynamicValue destValue;
+				(void)_list->getAtIndex(sourceIndex, srcValue);
+				(void)_list->getAtIndex(destIndex, destValue);
+
+				(void)_list->setAtIndex(destIndex, srcValue);
+				(void)_list->setAtIndex(sourceIndex, destValue);
+			}
+		}
+
+		result.setInt(listSize);
+		return true;
 	}
 
 	return Modifier::readAttribute(thread, result, attrib);


Commit: 052f124079b86b60708b0dde6853a6b118c56751
    https://github.com/scummvm/scummvm/commit/052f124079b86b60708b0dde6853a6b118c56751
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:59-04:00

Commit Message:
MTROPOLIS: Add world manager "scenefades" attrib stub.

Changed paths:
    engines/mtropolis/runtime.cpp


diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index d48c7d61c55..b73b4a43dd7 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -2603,6 +2603,11 @@ MiniscriptInstructionOutcome WorldManagerInterface::writeRefAttribute(Miniscript
 		DynamicValueWriteBoolHelper::create(&_gameMode, result);
 		return kMiniscriptInstructionOutcomeContinue;
 	}
+	if (attrib == "scenefades") {
+		// TODO
+		DynamicValueWriteDiscardHelper::create(result);
+		return kMiniscriptInstructionOutcomeContinue;
+	}
 	return RuntimeObject::writeRefAttribute(thread, result, attrib);
 }
 


Commit: abbd516eaa44578e5d4b60a9913b6323b53d40eb
    https://github.com/scummvm/scummvm/commit/abbd516eaa44578e5d4b60a9913b6323b53d40eb
Author: elasota (ejlasota at gmail.com)
Date: 2022-11-06T00:15:59-04:00

Commit Message:
MTROPOLIS: Fix VISE 3 archives

Changed paths:
    engines/mtropolis/boot.cpp


diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp
index 05948fe7a9d..7821af797e9 100644
--- a/engines/mtropolis/boot.cpp
+++ b/engines/mtropolis/boot.cpp
@@ -549,8 +549,6 @@ SPQRGameDataHandler::VISE3Archive::VISE3Archive(Common::SeekableReadStream *arch
 
 	uint16 numEntries = READ_BE_UINT16(vl3Catalog + 16);
 
-	Common::Array<VISE3FileDesc> archiveFiles;
-
 	for (uint16 i = 0; i < numEntries; i++) {
 		uint8 entryMagic[4];
 		if (archiveStream->read(entryMagic, 4) != 4 || memcmp(entryMagic + 1, "VCT", 3))
@@ -586,7 +584,7 @@ SPQRGameDataHandler::VISE3Archive::VISE3Archive(Common::SeekableReadStream *arch
 				desc.fileName = Common::String(fileNameChars, nameLength);
 			}
 
-			archiveFiles.push_back(desc);
+			_fileDescs.push_back(desc);
 		} else {
 			error("Unknown VISE 3 catalog entry item type");
 		}
@@ -594,12 +592,13 @@ SPQRGameDataHandler::VISE3Archive::VISE3Archive(Common::SeekableReadStream *arch
 }
 
 const SPQRGameDataHandler::VISE3FileDesc *SPQRGameDataHandler::VISE3Archive::getFileDesc(const Common::Path &path) const {
-	uint index = 0;
-	bool isResFork = false;
-	if (!getFileDescIndex(path, index, isResFork))
-		return nullptr;
+	Common::String convertedPath = path.toString(':');
+	for (const VISE3FileDesc &desc : _fileDescs) {
+		if (desc.fileName == convertedPath)
+			return &desc;
+	}
 
-	return &_fileDescs[index];
+	return nullptr;
 }
 
 bool SPQRGameDataHandler::VISE3Archive::hasFile(const Common::Path &path) const {




More information about the Scummvm-git-logs mailing list