[Scummvm-git-logs] scummvm master -> 139536ced1aadd4a53c6e3715001799797634a5d

elasota noreply at scummvm.org
Sat Sep 3 03:20:50 UTC 2022


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:
139536ced1 MTROPOLIS: Refactor boot file tables to reduce detection size


Commit: 139536ced1aadd4a53c6e3715001799797634a5d
    https://github.com/scummvm/scummvm/commit/139536ced1aadd4a53c6e3715001799797634a5d
Author: elasota (ejlasota at gmail.com)
Date: 2022-09-02T23:20:20-04:00

Commit Message:
MTROPOLIS: Refactor boot file tables to reduce detection size

Changed paths:
    engines/mtropolis/boot.cpp
    engines/mtropolis/detection.h
    engines/mtropolis/detection_tables.h
    engines/mtropolis/metaengine.cpp
    engines/mtropolis/mtropolis.h


diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp
index cce214baa43..b4a90b1335d 100644
--- a/engines/mtropolis/boot.cpp
+++ b/engines/mtropolis/boot.cpp
@@ -41,6 +41,45 @@ namespace MTropolis {
 
 namespace Boot {
 
+class GameDataHandler;
+
+struct ManifestSubtitlesDef {
+	const char *linesTablePath;
+	const char *speakerTablePath;
+	const char *assetMappingTablePath;
+	const char *modifierMappingTablePath;
+};
+
+enum ManifestFileType {
+	MTFT_AUTO = 0,       // Automatic, determine based on extension or file type
+	MTFT_PLAYER = 1,     // mTropolis Player program
+	MTFT_EXTENSION = 2,  // Extension (only use this if the extension contains cursors, otherwise use MTFT_SPECIAL if it has something else useful, or exclude it if not)
+	MTFT_MAIN = 3,       // Main segment
+	MTFT_ADDITIONAL = 4, // Additional segment
+	MTFT_VIDEO = 5,      // External video file
+	MTFT_SPECIAL = 6,    // Some other kind of file, or something that might be incorrectly detected as a different type of file (e.g. installers)
+};
+
+struct ManifestFile {
+	const char *fileName;
+	ManifestFileType fileType;
+};
+
+struct Game {
+	MTropolisGameBootID bootID;
+	const ManifestFile *manifest;
+	const char **directories;
+	const ManifestSubtitlesDef *subtitlesDef;
+	GameDataHandler *(*gameDataFactory)(const Boot::Game &game, const MTropolisGameDescription &desc);
+};
+
+template<class T>
+struct GameDataHandlerFactory {
+	static GameDataHandler *create(const Boot::Game &game, const MTropolisGameDescription &desc) {
+		return new T(game, desc);
+	}
+};
+
 struct FileIdentification {
 	union Tag {
 		uint32 value;
@@ -50,7 +89,7 @@ struct FileIdentification {
 	FileIdentification();
 
 	Common::String fileName;
-	MTropolisFileType category;
+	ManifestFileType category;
 
 	Tag macType;
 	Tag macCreator;
@@ -73,6 +112,7 @@ static void initResManForFile(FileIdentification &f) {
 
 class GameDataHandler {
 public:
+	GameDataHandler(const Boot::Game &game, const MTropolisGameDescription &desc);
 	virtual ~GameDataHandler();
 
 	virtual void unpackAdditionalFiles(Common::Array<Common::SharedPtr<ProjectPersistentResource> > &persistentResources, Common::Array<FileIdentification> &files);
@@ -80,6 +120,9 @@ public:
 	virtual void addPlugIns(ProjectDescription &projectDesc, const Common::Array<FileIdentification> &files);
 };
 
+GameDataHandler::GameDataHandler(const Boot::Game &game, const MTropolisGameDescription &desc) {
+}
+
 GameDataHandler::~GameDataHandler() {
 }
 
@@ -122,7 +165,7 @@ Common::SharedPtr<ProjectPersistentResource> PersistentResource<T>::wrap(const C
 
 class ObsidianGameDataHandler : public GameDataHandler {
 public:
-	explicit ObsidianGameDataHandler(const MTropolisGameDescription &gameDesc);
+	ObsidianGameDataHandler(const Game &game, const MTropolisGameDescription &gameDesc);
 
 	void unpackAdditionalFiles(Common::Array<Common::SharedPtr<ProjectPersistentResource> > &persistentResources, Common::Array<FileIdentification> &files) override;
 	void categorizeSpecialFiles(Common::Array<FileIdentification> &files) override;
@@ -140,7 +183,7 @@ private:
 	Common::SharedPtr<Common::Archive> _installerArchive;
 };
 
-ObsidianGameDataHandler::ObsidianGameDataHandler(const MTropolisGameDescription &gameDesc) {
+ObsidianGameDataHandler::ObsidianGameDataHandler(const Game &game, const MTropolisGameDescription &gameDesc) : GameDataHandler(game, gameDesc) {
 	_isMac = (gameDesc.desc.platform == Common::kPlatformMacintosh);
 	_isEnglish = (gameDesc.desc.language == Common::EN_ANY);
 	_isRetail = ((gameDesc.desc.flags & ADGF_DEMO) == 0);
@@ -527,7 +570,292 @@ static bool loadCursorsWin(FileIdentification &f, CursorGraphicCollection &curso
 	return true;
 }
 
-} // namespace Boot
+namespace Games {
+
+const ManifestFile obsidianRetailMacEnFiles[] = {
+	{"Obsidian Installer", MTFT_SPECIAL},
+	{"Obsidian Data 2", MTFT_ADDITIONAL},
+	{"Obsidian Data 3", MTFT_ADDITIONAL},
+	{"Obsidian Data 4", MTFT_ADDITIONAL},
+	{"Obsidian Data 5", MTFT_ADDITIONAL},
+	{"Obsidian Data 6", MTFT_ADDITIONAL},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoMacEnFiles[] = {
+	{"Obsidian Demo", MTFT_PLAYER},
+	{"Basic.rPP", MTFT_EXTENSION},
+	{"Experimental.rPP", MTFT_EXTENSION},
+	{"Extras.rPP", MTFT_EXTENSION},
+	{"mCursors.cPP", MTFT_EXTENSION},
+	{"mNet.rPP", MTFT_EXTENSION},
+	{"Obsidian.cPP", MTFT_EXTENSION},
+	{"RSGKit.rPP", MTFT_SPECIAL},
+	{"Obs Demo Large w Sega", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianRetailWinEnFiles[] = {
+	{"Obsidian.exe", MTFT_PLAYER},
+	{"Obsidian.c95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"RSGKit.r95", MTFT_SPECIAL},
+	{"Obsidian Data 1.MPL", MTFT_MAIN},
+	{"Obsidian Data 2.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 3.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 4.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 5.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 6.MPX", MTFT_ADDITIONAL},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles1[] = {
+	{"OBSIDIAN.EXE", MTFT_PLAYER},
+	{"OBSIDIAN.R95", MTFT_EXTENSION},
+	{"TEXTWORK.R95", MTFT_EXTENSION},
+	{"EXPRMNTL.R95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"OBSIDIAN DEMO DATA.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles2[] = {
+	{"OBSIDIAN.EXE", MTFT_PLAYER},
+	{"OBSIDIAN.R95", MTFT_EXTENSION},
+	{"TEXTWORK.R95", MTFT_EXTENSION},
+	{"EXPRMNTL.R95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"OBSIDI~1.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles3[] = {
+	{"OBSIDIAN DEMO.EXE", MTFT_PLAYER},
+	{"OBSIDIAN1.R95", MTFT_EXTENSION},
+	{"OBSIDIAN2.R95", MTFT_EXTENSION},
+	{"OBSIDIAN3.R95", MTFT_EXTENSION},
+	{"OBSIDIAN4.C95", MTFT_EXTENSION},
+	{"OBSIDIAN DEMO DATA.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles4[] = {
+	{"OBSIDIAN.EXE", MTFT_PLAYER},
+	{"OBSIDIAN.R95", MTFT_EXTENSION},
+	{"TEXTWORK.R95", MTFT_EXTENSION},
+	{"EXPRMNTL.R95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"OBSIDIAN.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles5[] = {
+	{"OBSIDI~1.EXE", MTFT_PLAYER},
+	{"OBSIDIAN.R95", MTFT_EXTENSION},
+	{"TEXTWORK.R95", MTFT_EXTENSION},
+	{"EXPRMNTL.R95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"OBSIDI~1.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles6[] = {
+	{"OBSIDIAN.EXE", MTFT_PLAYER},
+	{"OBSIDIAN.R95", MTFT_EXTENSION},
+	{"TEXTWORK.R95", MTFT_EXTENSION},
+	{"EXPRMNTL.R95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"OBSIDIAN DEMO DATA.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const ManifestFile obsidianDemoWinEnFiles7[] = {
+	{"OBSIDIAN DEMO.EXE", MTFT_PLAYER},
+	{"OBSIDIAN1.R95", MTFT_EXTENSION},
+	{"OBSIDIAN2.R95", MTFT_EXTENSION},
+	{"OBSIDIAN3.R95", MTFT_EXTENSION},
+	{"OBSIDIAN4.C95", MTFT_EXTENSION},
+	{"OBSIDIAN DEMO DATA.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+
+
+const ManifestFile obsidianRetailWinDeFiles[] = {
+	{"Obsidian.exe", MTFT_PLAYER},
+	{"Obsidian.c95", MTFT_EXTENSION},
+	{"MCURSORS.C95", MTFT_EXTENSION},
+	{"Obsidian Data 1.MPL", MTFT_MAIN},
+	{"Obsidian Data 2.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 3.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 4.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 5.MPX", MTFT_ADDITIONAL},
+	{"Obsidian Data 6.MPX", MTFT_ADDITIONAL},
+	{nullptr, MTFT_AUTO}
+};
+
+
+const char *obsidianRetailWinDirectories[] = {
+	"Obsidian",
+	"Obsidian/RESOURCE",
+	"RESOURCE",
+	nullptr
+};
+
+const ManifestSubtitlesDef obsidianRetailEnSubtitlesDef = {
+	"subtitles_lines_obsidian_en.csv",
+	"subtitles_speakers_obsidian_en.csv",
+	"subtitles_asset_mapping_obsidian_en.csv",
+
+	// Modifier mapping is the same for both Mac and Win retail, since the MIDI GUIDs are all identical.
+	"subtitles_modifier_mapping_obsidian_en.csv"
+};
+
+const ManifestFile mtiRetailWinFiles[] = {
+	{"MTPLAY32.EXE", MTFT_PLAYER},
+	{"GROUP3.R95", MTFT_EXTENSION},
+	{"MTIKIT.R95", MTFT_EXTENSION},
+	{"MTI1.MPL", MTFT_MAIN},
+	{"MTI2.MPX", MTFT_ADDITIONAL},
+	{"MTI3.MPX", MTFT_ADDITIONAL},
+	{"MTI4.MPX", MTFT_ADDITIONAL},
+	{"1.AVI", MTFT_VIDEO},
+	{"2.AVI", MTFT_VIDEO},
+	{"3.AVI", MTFT_VIDEO},
+	{"4.AVI", MTFT_VIDEO},
+	{"5.AVI", MTFT_VIDEO},
+	{"6.AVI", MTFT_VIDEO},
+	{"7.AVI", MTFT_VIDEO},
+	{"8.AVI", MTFT_VIDEO},
+	{"9.AVI", MTFT_VIDEO},
+	{"10.AVI", MTFT_VIDEO},
+	{nullptr, MTFT_AUTO}};
+
+const ManifestFile mtiDemoWinFiles[] = {
+	{"MTIWIN95.EXE", MTFT_PLAYER},
+	{"GROUP3.R95", MTFT_EXTENSION},
+	{"MTIKIT.R95", MTFT_EXTENSION},
+	{"MUP_DATA.MPL", MTFT_MAIN},
+	{nullptr, MTFT_AUTO}
+};
+
+const char *mtiRetailWinDirectories[] = {
+	"MTPLAY32",
+	"MTPLAY32/RESOURCE",
+	"VIDEO",
+	nullptr
+};
+
+const Game games[] = {
+	// Obsidian - Retail - Macintosh - English
+	{
+		MTBOOT_OBSIDIAN_RETAIL_MAC_EN,
+		obsidianRetailMacEnFiles,
+		nullptr,
+		&obsidianRetailEnSubtitlesDef,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Retail - Windows - English
+	{
+		MTBOOT_OBSIDIAN_RETAIL_WIN_EN,
+		obsidianRetailWinEnFiles,
+		obsidianRetailWinDirectories,
+		&obsidianRetailEnSubtitlesDef,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Retail - Windows - German
+	{
+		MTBOOT_OBSIDIAN_RETAIL_WIN_DE,
+		obsidianRetailWinDeFiles,
+		obsidianRetailWinDirectories,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Macintosh - English
+	{
+		MTBOOT_OBSIDIAN_DEMO_MAC_EN,
+		obsidianDemoMacEnFiles,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 1
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_1,
+		obsidianDemoWinEnFiles1,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 2
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_2,
+		obsidianDemoWinEnFiles2,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 3
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_3,
+		obsidianDemoWinEnFiles3,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 4
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_4,
+		obsidianDemoWinEnFiles4,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 5
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_5,
+		obsidianDemoWinEnFiles5,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 6
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_6,
+		obsidianDemoWinEnFiles6,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Obsidian - Demo - Windows - English - Variant 7
+	{
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_7,
+		obsidianDemoWinEnFiles7,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<ObsidianGameDataHandler>::create
+	},
+	// Muppet Treasure Island - Retail - Windows - Multiple languages
+	{
+		MTBOOT_MTI_RETAIL_WIN,
+		mtiRetailWinFiles,
+		mtiRetailWinDirectories,
+		nullptr,
+		GameDataHandlerFactory<GameDataHandler>::create
+	},
+	// Muppet Treasure Island - Demo - Windows
+	{
+		MTBOOT_MTI_DEMO_WIN,
+		mtiDemoWinFiles,
+		nullptr,
+		nullptr,
+		GameDataHandlerFactory<GameDataHandler>::create
+	},
+};
+
+} // End of namespace Games
+
+} // End of namespace Boot
 
 Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription &gameDesc) {
 	Common::SharedPtr<ProjectDescription> desc;
@@ -546,22 +874,29 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 	Common::String assetMappingTablePath;
 	Common::String modifierMappingTablePath;
 
-	switch (gameDesc.gameID) {
-	case GID_OBSIDIAN:
-		gameDataHandler.reset(new Boot::ObsidianGameDataHandler(gameDesc));
+	const Boot::Game *bootGame = nullptr;
+	for (const Boot::Game &bootGameCandidate : Boot::Games::games) {
+		if (bootGameCandidate.bootID == gameDesc.bootID) {
+			// Multiple manifests should not have the same manifest ID!
+			assert(!bootGame);
+			bootGame = &bootGameCandidate;
+		}
+	}
 
-		if ((gameDesc.desc.flags & ADGF_DEMO) == 0 && gameDesc.desc.language == Common::EN_ANY) {
-			linesTablePath = "subtitles_lines_obsidian_en.csv";
-			speakerTablePath = "subtitles_speakers_obsidian_en.csv";
-			assetMappingTablePath = "subtitles_asset_mapping_obsidian_en.csv";
+	if (!bootGame)
+		error("Couldn't boot mTropolis game, don't have a file manifest for manifest ID %i", static_cast<int>(gameDesc.bootID));
 
-			// Currently, modifier mapping is the same for both Mac and Win retail, since the MIDI GUIDs are all identical.
-			modifierMappingTablePath = "subtitles_modifier_mapping_obsidian_en.csv";
-		}
-		break;
-	default:
-		gameDataHandler.reset(new Boot::GameDataHandler());
-		break;
+	if (bootGame->gameDataFactory)
+		gameDataHandler.reset(bootGame->gameDataFactory(*bootGame, gameDesc));
+	else
+		gameDataHandler.reset(new Boot::GameDataHandler(*bootGame, gameDesc));
+
+
+	if (bootGame->subtitlesDef) {
+		linesTablePath = bootGame->subtitlesDef->linesTablePath;
+		speakerTablePath = bootGame->subtitlesDef->speakerTablePath;
+		assetMappingTablePath = bootGame->subtitlesDef->assetMappingTablePath;
+		modifierMappingTablePath = bootGame->subtitlesDef->modifierMappingTablePath;
 	}
 
 	if (gameDesc.desc.platform == Common::kPlatformMacintosh) {
@@ -569,16 +904,16 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 
 		debug(1, "Attempting to boot Macintosh game...");
 
-		const ADGameFileDescription *fileDesc = gameDesc.desc.filesDescriptions;
+		const Boot::ManifestFile *fileDesc = bootGame->manifest;
 		while (fileDesc->fileName) {
 			const char *fileName = fileDesc->fileName;
 
 			Boot::FileIdentification ident;
 			ident.fileName = fileName;
-			ident.category = static_cast<MTropolisFileType>(fileDesc->fileType);
+			ident.category = static_cast<Boot::ManifestFileType>(fileDesc->fileType);
 			ident.macType.value = 0;
 			ident.macCreator.value = 0;
-			if (ident.category == MTFT_AUTO && !Boot::getMacTypesForFile(fileName, ident.macType.value, ident.macCreator.value))
+			if (ident.category == Boot::MTFT_AUTO && !Boot::getMacTypesForFile(fileName, ident.macType.value, ident.macCreator.value))
 				error("Couldn't determine Mac file type code for file '%s'", fileName);
 
 			macFiles.push_back(ident);
@@ -602,7 +937,7 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 		bool haveAnyMFxm = false;
 
 		for (Boot::FileIdentification &macFile : macFiles) {
-			if (macFile.category == MTFT_AUTO) {
+			if (macFile.category == Boot::MTFT_AUTO) {
 				switch (macFile.macType.value) {
 				case MKTAG('M', 'F', 'm', 'm'):
 					haveAnyMFmm = true;
@@ -628,25 +963,25 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 
 		// Identify unknown files
 		for (Boot::FileIdentification &macFile : macFiles) {
-			if (macFile.category == MTFT_AUTO) {
+			if (macFile.category == Boot::MTFT_AUTO) {
 				switch (macFile.macType.value) {
 				case MKTAG('M', 'F', 'm', 'm'):
-					macFile.category = MTFT_MAIN;
+					macFile.category = Boot::MTFT_MAIN;
 					break;
 				case MKTAG('M', 'F', 'm', 'x'):
-					macFile.category = isMT2CrossPlatform ? MTFT_MAIN : MTFT_ADDITIONAL;
+					macFile.category = isMT2CrossPlatform ? Boot::MTFT_MAIN : Boot::MTFT_ADDITIONAL;
 					break;
 				case MKTAG('M', 'F', 'x', 'm'):
 				case MKTAG('M', 'F', 'x', 'x'):
-					macFile.category = MTFT_ADDITIONAL;
+					macFile.category = Boot::MTFT_ADDITIONAL;
 					break;
 				case MKTAG('A', 'P', 'P', 'L'):
-					macFile.category = MTFT_PLAYER;
+					macFile.category = Boot::MTFT_PLAYER;
 					break;
 				case MKTAG('M', 'F', 'c', 'o'):
 				case MKTAG('M', 'F', 'c', 'r'):
 				case MKTAG('M', 'F', 'X', 'O'):
-					macFile.category = MTFT_EXTENSION;
+					macFile.category = Boot::MTFT_EXTENSION;
 					break;
 				default:
 					error("Failed to categorize input file '%s'", macFile.fileName.c_str());
@@ -661,16 +996,16 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 		// Bin segments
 		for (Boot::FileIdentification &macFile : macFiles) {
 			switch (macFile.category) {
-			case MTFT_PLAYER:
+			case Boot::MTFT_PLAYER:
 				// Case handled below after cursor loading
 				break;
-			case MTFT_EXTENSION:
+			case Boot::MTFT_EXTENSION:
 				// Case handled below after cursor loading
 				break;
-			case MTFT_MAIN:
+			case Boot::MTFT_MAIN:
 				mainSegmentFile = &macFile;
 				break;
-			case MTFT_ADDITIONAL: {
+			case Boot::MTFT_ADDITIONAL: {
 					int segmentID = Boot::resolveFileSegmentID(macFile.fileName);
 					if (segmentID < 2)
 						error("Unusual segment numbering scheme");
@@ -680,9 +1015,9 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 						segmentFiles.push_back(nullptr);
 					segmentFiles[segmentIndex] = &macFile;
 				} break;
-			case MTFT_SPECIAL:
+			case Boot::MTFT_SPECIAL:
 				break;
-			case MTFT_AUTO:
+			case Boot::MTFT_AUTO:
 				break;
 			}
 		}
@@ -696,12 +1031,12 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 		Common::SharedPtr<CursorGraphicCollection> cursorGraphics(new CursorGraphicCollection());
 
 		for (Boot::FileIdentification &macFile : macFiles) {
-			if (macFile.category == MTFT_PLAYER)
+			if (macFile.category == Boot::MTFT_PLAYER)
 				Boot::loadCursorsMac(macFile, *cursorGraphics);
 		}
 
 		for (Boot::FileIdentification &macFile : macFiles) {
-			if (macFile.category == MTFT_EXTENSION)
+			if (macFile.category == Boot::MTFT_EXTENSION)
 				Boot::loadCursorsMac(macFile, *cursorGraphics);
 		}
 
@@ -738,13 +1073,13 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 
 		debug(1, "Attempting to boot Windows game...");
 
-		const ADGameFileDescription *fileDesc = gameDesc.desc.filesDescriptions;
+		const Boot::ManifestFile *fileDesc = bootGame->manifest;
 		while (fileDesc->fileName) {
 			const char *fileName = fileDesc->fileName;
 
 			Boot::FileIdentification ident;
 			ident.fileName = fileName;
-			ident.category = MTFT_AUTO;
+			ident.category = Boot::MTFT_AUTO;
 			ident.macType.value = 0;
 			ident.macCreator.value = 0;
 			winFiles.push_back(ident);
@@ -764,17 +1099,17 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 
 		// Identify unknown files
 		for (Boot::FileIdentification &winFile : winFiles) {
-			if (winFile.category == MTFT_AUTO) {
+			if (winFile.category == Boot::MTFT_AUTO) {
 				switch (Boot::getWinFileEndingPseudoTag(winFile.fileName)) {
 				case MKTAG('.', 'm', 'p', 'l'):
-					winFile.category = MTFT_MAIN;
+					winFile.category = Boot::MTFT_MAIN;
 					isWindows = true;
 					isMT1 = true;
 					if (isMT2)
 						error("Unexpected mix of file platforms");
 					break;
 				case MKTAG('.', 'm', 'p', 'x'):
-					winFile.category = MTFT_ADDITIONAL;
+					winFile.category = Boot::MTFT_ADDITIONAL;
 					isWindows = true;
 					isMT1 = true;
 					if (isMT2)
@@ -782,7 +1117,7 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 					break;
 
 				case MKTAG('.', 'm', 'f', 'w'):
-					winFile.category = MTFT_MAIN;
+					winFile.category = Boot::MTFT_MAIN;
 					if (isMT1 || isCrossPlatform)
 						error("Unexpected mix of file platforms");
 					isWindows = true;
@@ -790,7 +1125,7 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 					break;
 
 				case MKTAG('.', 'm', 'x', 'w'):
-					winFile.category = MTFT_ADDITIONAL;
+					winFile.category = Boot::MTFT_ADDITIONAL;
 					if (isMT1 || isCrossPlatform)
 						error("Unexpected mix of file platforms");
 					isWindows = true;
@@ -798,7 +1133,7 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 					break;
 
 				case MKTAG('.', 'm', 'f', 'x'):
-					winFile.category = MTFT_MAIN;
+					winFile.category = Boot::MTFT_MAIN;
 					if (isWindows)
 						error("Unexpected mix of file platforms");
 					isCrossPlatform = true;
@@ -806,7 +1141,7 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 					break;
 
 				case MKTAG('.', 'm', 'x', 'x'):
-					winFile.category = MTFT_ADDITIONAL;
+					winFile.category = Boot::MTFT_ADDITIONAL;
 					if (isWindows)
 						error("Unexpected mix of file platforms");
 					isCrossPlatform = true;
@@ -817,11 +1152,11 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 				case MKTAG('.', 'e', '9', '5'):
 				case MKTAG('.', 'r', '9', '5'):
 				case MKTAG('.', 'x', '9', '5'):
-					winFile.category = MTFT_EXTENSION;
+					winFile.category = Boot::MTFT_EXTENSION;
 					break;
 
 				case MKTAG('.', 'e', 'x', 'e'):
-					winFile.category = MTFT_PLAYER;
+					winFile.category = Boot::MTFT_PLAYER;
 					break;
 
 				default:
@@ -837,16 +1172,16 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 		// Bin segments
 		for (Boot::FileIdentification &macFile : winFiles) {
 			switch (macFile.category) {
-			case MTFT_PLAYER:
+			case Boot::MTFT_PLAYER:
 				// Case handled below after cursor loading
 				break;
-			case MTFT_EXTENSION:
+			case Boot::MTFT_EXTENSION:
 				// Case handled below after cursor loading
 				break;
-			case MTFT_MAIN:
+			case Boot::MTFT_MAIN:
 				mainSegmentFile = &macFile;
 				break;
-			case MTFT_ADDITIONAL: {
+			case Boot::MTFT_ADDITIONAL: {
 				int segmentID = Boot::resolveFileSegmentID(macFile.fileName);
 				if (segmentID < 2)
 					error("Unusual segment numbering scheme");
@@ -856,9 +1191,9 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 					segmentFiles.push_back(nullptr);
 				segmentFiles[segmentIndex] = &macFile;
 			} break;
-			case MTFT_SPECIAL:
+			case Boot::MTFT_SPECIAL:
 				break;
-			case MTFT_AUTO:
+			case Boot::MTFT_AUTO:
 				break;
 			}
 		}
@@ -872,12 +1207,12 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 		Common::SharedPtr<CursorGraphicCollection> cursorGraphics(new CursorGraphicCollection());
 
 		for (Boot::FileIdentification &winFile : winFiles) {
-			if (winFile.category == MTFT_PLAYER)
+			if (winFile.category == Boot::MTFT_PLAYER)
 				Boot::loadCursorsWin(winFile, *cursorGraphics);
 		}
 
 		for (Boot::FileIdentification &winFile : winFiles) {
-			if (winFile.category == MTFT_EXTENSION)
+			if (winFile.category == Boot::MTFT_EXTENSION)
 				Boot::loadCursorsWin(winFile, *cursorGraphics);
 		}
 
@@ -946,16 +1281,26 @@ Common::SharedPtr<ProjectDescription> bootProject(const MTropolisGameDescription
 
 void bootAddSearchPaths(const Common::FSNode &gameDataDir, const MTropolisGameDescription &gameDesc) {
 
-	if (gameDesc.gameID == GID_OBSIDIAN && gameDesc.desc.platform == Common::kPlatformWindows) {
-		SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian");
-		SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian/RESOURCE");
-		SearchMan.addSubDirectoryMatching(gameDataDir, "RESOURCE");
+	const Boot::Game *bootGame = nullptr;
+	for (const Boot::Game &bootGameCandidate : Boot::Games::games) {
+		if (bootGameCandidate.bootID == gameDesc.bootID) {
+			// Multiple manifests should not have the same manifest ID!
+			assert(!bootGame);
+			bootGame = &bootGameCandidate;
+		}
 	}
 
-	if (gameDesc.gameID == GID_MTI && gameDesc.desc.platform == Common::kPlatformWindows) {
-		SearchMan.addSubDirectoryMatching(gameDataDir, "MTPLAY32");
-		SearchMan.addSubDirectoryMatching(gameDataDir, "MTPLAY32/RESOURCE");
-		SearchMan.addSubDirectoryMatching(gameDataDir, "VIDEO");
+	if (!bootGame)
+		error("Couldn't boot mTropolis game, don't have a file manifest for manifest ID %i", static_cast<int>(gameDesc.bootID));
+
+	if (!bootGame->directories)
+		return;
+
+	size_t index = 0;
+	while (bootGame->directories[index]) {
+		const char *directoryPath = bootGame->directories[index++];
+
+		SearchMan.addSubDirectoryMatching(gameDataDir, directoryPath);
 	}
 }
 
diff --git a/engines/mtropolis/detection.h b/engines/mtropolis/detection.h
index 6b71fae44c0..70511bb9591 100644
--- a/engines/mtropolis/detection.h
+++ b/engines/mtropolis/detection.h
@@ -32,13 +32,26 @@ enum MTropolisGameID {
 	GID_MTI    				= 2,
 };
 
-enum MTropolisFileType {
-	MTFT_AUTO		= 0,	// Automatic, determine based on extension or file type
-	MTFT_PLAYER		= 1,	// mTropolis Player program
-	MTFT_EXTENSION	= 2,	// Extension (only use this if the extension contains cursors, otherwise use MTFT_SPECIAL if it has something else useful, or exclude it if not)
-	MTFT_MAIN		= 3,	// Main segment
-	MTFT_ADDITIONAL	= 4,	// Additional segment
-	MTFT_SPECIAL	= 5,	// Some other kind of file, or something that might be incorrectly detected as a different type of file (e.g. installers)
+// Boot IDs - These can be shared across different variants if the file list and other properties are identical.
+// Cross-reference with the game table in mTropolis engine's boot.cpp
+enum MTropolisGameBootID {
+	MTBOOT_INVALID = 0,
+
+	MTBOOT_OBSIDIAN_RETAIL_MAC_EN,
+	MTBOOT_OBSIDIAN_RETAIL_WIN_EN,
+	MTBOOT_OBSIDIAN_RETAIL_WIN_DE,
+	MTBOOT_OBSIDIAN_DEMO_MAC_EN,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_1,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_2,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_3,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_4,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_5,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_6,
+	MTBOOT_OBSIDIAN_DEMO_WIN_EN_7,
+
+	MTBOOT_MTI_RETAIL_MAC,
+	MTBOOT_MTI_RETAIL_WIN,
+	MTBOOT_MTI_DEMO_WIN,
 };
 
 struct MTropolisGameDescription {
@@ -46,7 +59,7 @@ struct MTropolisGameDescription {
 
 	int gameID;
 	int gameType;
-	uint16 version;
+	MTropolisGameBootID bootID;
 };
 
 } // End of namespace MTropolis
diff --git a/engines/mtropolis/detection_tables.h b/engines/mtropolis/detection_tables.h
index 3297557410e..9cfa7231a5f 100644
--- a/engines/mtropolis/detection_tables.h
+++ b/engines/mtropolis/detection_tables.h
@@ -43,11 +43,11 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"V1.0, 1/13/97, CD",
 			{
 				{ "Obsidian Installer", 0, "1c272c23dc50b771970cabe8410c9349", 9250304 },
-				{ "Obsidian Data 2",	0, "1e590e3154c1af09efb951a07abc48b8", 563287808 },
-				{ "Obsidian Data 3",	0, "48e514a594b7a7ad190351d6d32d5d33", 617413632 },
-				{ "Obsidian Data 4",	0, "8dfa726c675aae3778951ddd18e4484c", 599297536 },
-				{ "Obsidian Data 5",	0, "6f085578b13b3db99543b969c9009b17", 583581056 },
-				{ "Obsidian Data 6",	0, "120ddcb1780be0f6380d708041733406", 558315648 },
+				//{ "Obsidian Data 2",	0, "1e590e3154c1af09efb951a07abc48b8", 563287808 },
+				//{ "Obsidian Data 3",	0, "48e514a594b7a7ad190351d6d32d5d33", 617413632 },
+				//{ "Obsidian Data 4",	0, "8dfa726c675aae3778951ddd18e4484c", 599297536 },
+				//{ "Obsidian Data 5",	0, "6f085578b13b3db99543b969c9009b17", 583581056 },
+				//{ "Obsidian Data 6",	0, "120ddcb1780be0f6380d708041733406", 558315648 },
 				AD_LISTEND
 			},
 			Common::EN_ANY,
@@ -57,19 +57,19 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_RETAIL_MAC_EN,
 	},
 	{ // Obsidian Macintosh, data forks only
 		{
 			"obsidian",
 			"V1.0, 1/13/97, CD",
 			{
-				{ "Obsidian Installer", MTFT_SPECIAL,		"c8859ba831a202a112eaffc5aee3ddf5", 9138050 },
-				{ "Obsidian Data 2",	MTFT_ADDITIONAL,	"a07c8ba79b9cb1de5496345dbe168527", 563284971 },
-				{ "Obsidian Data 3",	MTFT_ADDITIONAL,	"7cd809daa365b478ed96acbd6434966b", 617410816 },
-				{ "Obsidian Data 4",	MTFT_ADDITIONAL,	"ee67b2032f27133800f50c8b5cf08129", 599294667 },
-				{ "Obsidian Data 5",	MTFT_ADDITIONAL,	"13a221b93471b7d551316735cec21e7f", 583578222 },
-				{ "Obsidian Data 6",	MTFT_ADDITIONAL,	"5388ee329d1f5621333249f2f09cfb0c", 558312729 },
+				{ "Obsidian Installer", 0,	"c8859ba831a202a112eaffc5aee3ddf5", 9138050 },
+				//{ "Obsidian Data 2",	0,	"a07c8ba79b9cb1de5496345dbe168527", 563284971 },
+				//{ "Obsidian Data 3",	0,	"7cd809daa365b478ed96acbd6434966b", 617410816 },
+				//{ "Obsidian Data 4",	0,	"ee67b2032f27133800f50c8b5cf08129", 599294667 },
+				//{ "Obsidian Data 5",	0,	"13a221b93471b7d551316735cec21e7f", 583578222 },
+				//{ "Obsidian Data 6",	0,	"5388ee329d1f5621333249f2f09cfb0c", 558312729 },
 				AD_LISTEND
 			},
 			Common::EN_ANY,
@@ -79,7 +79,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_RETAIL_MAC_EN,
 	},
 
 	{ // Obsidian Windows, installed
@@ -87,16 +87,16 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"obsidian",
 			"V1.0, 1/13/97, installed, CD",
 			{
-				{ "Obsidian.exe",		 0, "0b50a779136ae6c9cc8bcfa3148c1127", 762368 },
-				{ "Obsidian.c95",		 0, "fea68ff30ff319cdab30b79d2850a480", 145920 },
-				{ "RSGKit.r95",			 0, "071dc9098f9610fcec45c96342b1b69a", 625152 },
-				{ "MCURSORS.C95",		 0, "dcbe480913eebf233d0cdc33809bf048", 87040 },
+				//{ "Obsidian.exe",		 0, "0b50a779136ae6c9cc8bcfa3148c1127", 762368 },
+				//{ "Obsidian.c95",		 0, "fea68ff30ff319cdab30b79d2850a480", 145920 },
+				//{ "RSGKit.r95",			 0, "071dc9098f9610fcec45c96342b1b69a", 625152 },
+				//{ "MCURSORS.C95",		 0, "dcbe480913eebf233d0cdc33809bf048", 87040 },
 				{ "Obsidian Data 1.MPL", 0, "9531162c32272c33837074be4646422a", 14755456 },
-				{ "Obsidian Data 2.MPX", 0, "c13c9be0ab0482a952532fa647a67a7a", 558175757 },
-				{ "Obsidian Data 3.MPX", 0, "35d8332221a7236b122b43233428f5dc", 614504412 },
-				{ "Obsidian Data 4.MPX", 0, "263fe824a1dd6f91390bce447c01e54c", 597911854 },
-				{ "Obsidian Data 5.MPX", 0, "894e4712a7bfb1b3c54086d43e6f3bb7", 576841795 },
-				{ "Obsidian Data 6.MPX", 0, "f491955b858e1a41d25efbb060424833", 554803689 },
+				//{ "Obsidian Data 2.MPX", 0, "c13c9be0ab0482a952532fa647a67a7a", 558175757 },
+				//{ "Obsidian Data 3.MPX", 0, "35d8332221a7236b122b43233428f5dc", 614504412 },
+				//{ "Obsidian Data 4.MPX", 0, "263fe824a1dd6f91390bce447c01e54c", 597911854 },
+				//{ "Obsidian Data 5.MPX", 0, "894e4712a7bfb1b3c54086d43e6f3bb7", 576841795 },
+				//{ "Obsidian Data 6.MPX", 0, "f491955b858e1a41d25efbb060424833", 554803689 },
 				AD_LISTEND
 			},
 			Common::EN_ANY,
@@ -106,7 +106,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_RETAIL_WIN_EN,
 	},
 	{
 		// Obsidian, German Windows, installed
@@ -115,15 +115,15 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"obsidian",
 			"installed, CD",
 			{
-				{ "Obsidian.exe",		 0, "0b50a779136ae6c9cc8bcfa3148c1127", 762368 },
-				{ "Obsidian.c95",		 0, "fea68ff30ff319cdab30b79d2850a480", 145920 },
-				{ "MCURSORS.C95",		 0, "dcbe480913eebf233d0cdc33809bf048", 87040 },
+				//{ "Obsidian.exe",		 0, "0b50a779136ae6c9cc8bcfa3148c1127", 762368 },
+				//{ "Obsidian.c95",		 0, "fea68ff30ff319cdab30b79d2850a480", 145920 },
+				//{ "MCURSORS.C95",		 0, "dcbe480913eebf233d0cdc33809bf048", 87040 },
 				{ "Obsidian Data 1.MPL", 0, "f96fc3a3a0a645009265c74c5fcb2c6a", 18972392 },
-				{ "Obsidian Data 2.MPX", 0, "b42a5a7bc36b2de2f9882e8a05435857", 559682181 },
-				{ "Obsidian Data 3.MPX", 0, "d4cb1a43d129019f8c2172a09cbedf2a", 614519546 },
-				{ "Obsidian Data 4.MPX", 0, "ae3095e5ac0a3a8984758ee76420e9b1", 591403514 },
-				{ "Obsidian Data 5.MPX", 0, "e8939423008a47c77735e16d7391a947", 578314080 },
-				{ "Obsidian Data 6.MPX", 0, "1295c1fe1a9113dbf2764b7024bf759d", 552452074 },
+				//{ "Obsidian Data 2.MPX", 0, "b42a5a7bc36b2de2f9882e8a05435857", 559682181 },
+				//{ "Obsidian Data 3.MPX", 0, "d4cb1a43d129019f8c2172a09cbedf2a", 614519546 },
+				//{ "Obsidian Data 4.MPX", 0, "ae3095e5ac0a3a8984758ee76420e9b1", 591403514 },
+				//{ "Obsidian Data 5.MPX", 0, "e8939423008a47c77735e16d7391a947", 578314080 },
+				//{ "Obsidian Data 6.MPX", 0, "1295c1fe1a9113dbf2764b7024bf759d", 552452074 },
 				AD_LISTEND
 			},
 			Common::DE_DEU,
@@ -133,7 +133,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_RETAIL_WIN_DE,
 	},
 
 	{ // Obsidian Macintosh demo from standalone CD titled "Demo v1.0 January 1997"
@@ -141,14 +141,14 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"obsidian",
 			"Demo",
 			{
-				{ "Obsidian Demo",		   0, "abd1b5e7ac133f4c4b8c45ac67a4c44d", 920832 },
-				{ "Basic.rPP",			   0, "cb567ec1423a35903d8d5f458409e681", 210432 },
-				{ "Experimental.rPP",	   0, "26aa5fe1a6a152ade74e23a706673c50", 102016 },
-				{ "Extras.rPP",			   0, "c0e4c0401f2107ba3a3b7d282a76d99b", 377600 },
-				{ "mCursors.cPP",		   0, "a52e2aaf3b1a5c7d93a2949693bca694", 13312 },
-				{ "mNet.rPP",			   0, "ed5d998e7db6daae1f24bb124cc269aa", 134784 },
-				{ "Obsidian.cPP",		   0, "6da7babae9725a716f27f9f4ea382e92", 7552 },
-				{ "RSGKit.rPP",			   0, "c359e3c932b09280d1ccf21f8fb52bd7", 668160 },
+				//{ "Obsidian Demo",	   0, "abd1b5e7ac133f4c4b8c45ac67a4c44d", 920832 },
+				//{ "Basic.rPP",		   0, "cb567ec1423a35903d8d5f458409e681", 210432 },
+				//{ "Experimental.rPP",	   0, "26aa5fe1a6a152ade74e23a706673c50", 102016 },
+				//{ "Extras.rPP",		   0, "c0e4c0401f2107ba3a3b7d282a76d99b", 377600 },
+				//{ "mCursors.cPP",		   0, "a52e2aaf3b1a5c7d93a2949693bca694", 13312 },
+				//{ "mNet.rPP",			   0, "ed5d998e7db6daae1f24bb124cc269aa", 134784 },
+				//{ "Obsidian.cPP",		   0, "6da7babae9725a716f27f9f4ea382e92", 7552 },
+				//{ "RSGKit.rPP",		   0, "c359e3c932b09280d1ccf21f8fb52bd7", 668160 },
 				{ "Obs Demo Large w Sega", 0, "4672fe8ba459811dea0744cf90063a35", 98954240 },
 				AD_LISTEND
 			},
@@ -159,7 +159,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_MAC_EN,
 	},
 
 	{ // Obsidian PC demo [1996-10-03], found on:
@@ -171,10 +171,10 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"Demo",
 			{
 				{ "OBSIDIAN.EXE",			0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
-				{ "OBSIDIAN.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "TEXTWORK.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "EXPRMNTL.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "MCURSORS.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "TEXTWORK.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "EXPRMNTL.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "MCURSORS.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDIAN DEMO DATA.MPL", 0, "643a989213b42cbac319d04676447624", 29096880 },
 				AD_LISTEND
 			},
@@ -185,7 +185,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_1,
 	},
 
 	{ // Obsidian PC demo (same as above, with 8.3 file names), found on PC Gamer Disc 2.12 (1997-01)
@@ -194,10 +194,10 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"Demo",
 			{
 				{ "OBSIDIAN.EXE",	0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
-				{ "OBSIDIAN.R95",	0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "TEXTWORK.R95",	0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "EXPRMNTL.R95",	0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "MCURSORS.C95",	0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN.R95",	0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "TEXTWORK.R95",	0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "EXPRMNTL.R95",	0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "MCURSORS.C95",	0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDI~1.MPL",	0, "643a989213b42cbac319d04676447624", 29096880 },
 				AD_LISTEND
 			},
@@ -208,7 +208,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_2,
 	},
 
 	{ // Obsidian PC demo [1996-10-11/22] found on:
@@ -219,10 +219,10 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"Demo",
 			{
 				{ "OBSIDIAN DEMO.EXE",		0, "1bac38af354fd79ae3285e6c737705b7", 751104 },
-				{ "OBSIDIAN1.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "OBSIDIAN2.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "OBSIDIAN3.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "OBSIDIAN4.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN1.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "OBSIDIAN2.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "OBSIDIAN3.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "OBSIDIAN4.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDIAN DEMO DATA.MPL", 0, "77d04f62825c9f424baba46922ffb60f", 29552976 },
 				AD_LISTEND
 			},
@@ -233,21 +233,21 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_3,
 	},
 
-	{ // Obsidian PC demo found on:
+	{ // Obsidian PC cinematic demo found on:
 	  // - Segasoft Demonstration Disk (Fall 1996)
 	  // - CD Review #67 (1997) [1996-10-03]
 		{
 			"obsidian",
 			"Demo",
 			{
-				{ "OBSIDIAN.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
-				{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
+				//{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDIAN.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
 				AD_LISTEND
 			},
@@ -258,19 +258,19 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_4,
 	},
 
-	{ // Obsidian PC demo found on Multimedia Live (PC World) (v2.11, May 1997) [1996-10-03]
+	{ // Obsidian PC cinematic demo found on Multimedia Live (PC World) (v2.11, May 1997) [1996-10-03]
 		{
 			"obsidian",
 			"Demo",
 			{
-				{ "OBSIDI~1.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
-				{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDI~1.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
+				//{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDI~1.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
 				AD_LISTEND
 			},
@@ -281,19 +281,19 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_5,
 	},
 
-	{ // Obsidian PC demo (identical to the above except for EXE name)
+	{ // Obsidian PC cinematic demo (identical to the above except for EXE name)
 		{
 			"obsidian",
 			"Demo",
 			{
 				{ "OBSIDIAN.EXE",			0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
-				{ "OBSIDIAN.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "TEXTWORK.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "EXPRMNTL.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "MCURSORS.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "TEXTWORK.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "EXPRMNTL.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "MCURSORS.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDIAN DEMO DATA.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
 				AD_LISTEND
 			},
@@ -304,19 +304,19 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_6,
 	},
 
-	{ // Obsidian PC demo
+	{ // Obsidian PC cinematic demo (identical to above, but different player version and renamed extensions)
 		{
 			"obsidian",
 			"Demo",
 			{
 				{ "OBSIDIAN DEMO.EXE",		0, "1bac38af354fd79ae3285e6c737705b7", 751104 },
-				{ "OBSIDIAN1.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
-				{ "OBSIDIAN2.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
-				{ "OBSIDIAN3.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
-				{ "OBSIDIAN4.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
+				//{ "OBSIDIAN1.R95",			0, "5361ef93e36d722665594b724e0018fd", 183296 },
+				//{ "OBSIDIAN2.R95",			0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
+				//{ "OBSIDIAN3.R95",			0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
+				//{ "OBSIDIAN4.C95",			0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
 				{ "OBSIDIAN DEMO DATA.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
 				AD_LISTEND
 			},
@@ -327,7 +327,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_OBSIDIAN,
 		0,
-		0,
+		MTBOOT_OBSIDIAN_DEMO_WIN_EN_7,
 	},
 
 	{ // Muppet Treasure Island
@@ -335,13 +335,13 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"mti",
 			"",
 			{
-				{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
-				{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
-				{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
+				//{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
+				//{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
+				//{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
 				{ "MTI1.MPL",		0, "cd0e1cd198fa2971371f42bb92b44972", 28500187 },
-				{ "MTI2.MPX",		0, "299929afb890398c385b13ee1446ece1", 431981661 },
-				{ "MTI3.MPX",		0, "90bd8dd40fcc65579f723eb75ad92799", 306575085 },
-				{ "MTI4.MPX",		0, "108628b01feb4d61ce40c9424de41b42", 201095285 },
+				//{ "MTI2.MPX",		0, "299929afb890398c385b13ee1446ece1", 431981661 },
+				//{ "MTI3.MPX",		0, "90bd8dd40fcc65579f723eb75ad92799", 306575085 },
+				//{ "MTI4.MPX",		0, "108628b01feb4d61ce40c9424de41b42", 201095285 },
 				AD_LISTEND
 			},
 			Common::EN_ANY,
@@ -351,7 +351,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_MTI,
 		0,
-		0,
+		MTBOOT_MTI_RETAIL_WIN,
 	},
 
 	{ // Los Muppets en la Isla del Tesoro (Mexican) [identical to Los Teleñecos en la Isla del Tesoro?]
@@ -359,13 +359,13 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"mti",
 			"",
 			{
-				{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
-				{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
-				{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
+				//{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
+				//{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
+				//{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
 				{ "MTI1.MPL",		0, "1a951860380f7a0a0e1b9abe6be45ccd", 28605614 },
-				{ "MTI2.MPX",		0, "29b21afc024dc56dc99b7eb1f056fe65", 433252845 },
-				{ "MTI3.MPX",		0, "a880d87116b787b6e8a39f7d522c723c", 306257034 },
-				{ "MTI4.MPX",		0, "9b41ca763935f288b1b97c4025568e1d", 201507336 },
+				//{ "MTI2.MPX",		0, "29b21afc024dc56dc99b7eb1f056fe65", 433252845 },
+				//{ "MTI3.MPX",		0, "a880d87116b787b6e8a39f7d522c723c", 306257034 },
+				//{ "MTI4.MPX",		0, "9b41ca763935f288b1b97c4025568e1d", 201507336 },
 				AD_LISTEND
 			},
 			Common::ES_ESP,
@@ -375,7 +375,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_MTI,
 		0,
-		0,
+		MTBOOT_MTI_RETAIL_WIN,
 	},
 
 	{ // I Muppet nell'Isola del Tesoro
@@ -383,13 +383,13 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"mti",
 			"",
 			{
-				{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
-				{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
-				{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
+				//{ "MTPLAY32.EXE",	0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
+				//{ "GROUP3.R95",		0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
+				//{ "MTIKIT.R95",		0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
 				{ "MTI1.MPL",		0, "49883a0d8c76db739449ac8b0c6bc0a9", 28280783 },
-				{ "MTI2.MPX",		0, "5b69bbcceaf221e6b4200a5a76f8373e", 431268421 },
-				{ "MTI3.MPX",		0, "43a145a5a498640804a2116f8418cbf6", 307241744 },
-				{ "MTI4.MPX",		0, "30cd478975003466c7dadf5f6c6f5408", 201100471 },
+				//{ "MTI2.MPX",		0, "5b69bbcceaf221e6b4200a5a76f8373e", 431268421 },
+				//{ "MTI3.MPX",		0, "43a145a5a498640804a2116f8418cbf6", 307241744 },
+				//{ "MTI4.MPX",		0, "30cd478975003466c7dadf5f6c6f5408", 201100471 },
 				AD_LISTEND
 			},
 			Common::IT_ITA,
@@ -399,7 +399,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_MTI,
 		0,
-		0,
+		MTBOOT_MTI_RETAIL_WIN,
 	},
 
 	{ // Muppet Treasure Island PC demo found on Score 38 (1997-02) [1996-07-17/19]
@@ -407,9 +407,9 @@ static const MTropolisGameDescription gameDescriptions[] = {
 			"mti",
 			"Demo",
 			{
-				{ "MTIWIN95.EXE", 0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
-				{ "GROUP3.R95",	  0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
-				{ "MTIKIT.R95",	  0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
+				//{ "MTIWIN95.EXE", 0, "aad51b462d0961fb02d9c1422a41937f", 840192 },
+				//{ "GROUP3.R95",	  0, "3b01850e511727aa270aff1d6cb1fcf8", 89088 },
+				//{ "MTIKIT.R95",	  0, "f7183d9ff845a3a607f764920fc23b18", 101376 },
 				{ "MUP_DATA.MPL", 0, "aea8ca15455991278213d09674a183ed", 51678610 },
 				AD_LISTEND
 			},
@@ -420,10 +420,10 @@ static const MTropolisGameDescription gameDescriptions[] = {
 		},
 		GID_MTI,
 		0,
-		0,
+		MTBOOT_MTI_DEMO_WIN,
 	},
 
-	{ AD_TABLE_END_MARKER, 0, 0, 0 }
+	{ AD_TABLE_END_MARKER, 0, 0, MTBOOT_INVALID }
 };
 
 } // End of namespace MTropolis
diff --git a/engines/mtropolis/metaengine.cpp b/engines/mtropolis/metaengine.cpp
index e98feb03602..ac2d898cfc9 100644
--- a/engines/mtropolis/metaengine.cpp
+++ b/engines/mtropolis/metaengine.cpp
@@ -52,10 +52,6 @@ Common::Platform MTropolisEngine::getPlatform() const {
 	return _gameDescription->desc.platform;
 }
 
-uint16 MTropolisEngine::getVersion() const {
-	return _gameDescription->version;
-}
-
 } // End of namespace MTropolis
 
 class MTropolisMetaEngine : public AdvancedMetaEngine {
diff --git a/engines/mtropolis/mtropolis.h b/engines/mtropolis/mtropolis.h
index 027e0966c35..0623ebe6bcd 100644
--- a/engines/mtropolis/mtropolis.h
+++ b/engines/mtropolis/mtropolis.h
@@ -56,7 +56,6 @@ public:
 
 	const MTropolisGameDescription *_gameDescription;
 	uint32 getGameID() const;
-	uint16 getVersion() const;
 	Common::Platform getPlatform() const;
 
 	bool promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) override;




More information about the Scummvm-git-logs mailing list