diff options
30 files changed, 247 insertions, 231 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp index b4a9174802..74a5982f32 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -705,9 +705,8 @@ static void listTargets() { printf("Target Description \n" "-------------------- ------------------------------------------------------\n"); - using namespace Common; - const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); - ConfigManager::DomainMap::const_iterator iter; + const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); + Common::ConfigManager::DomainMap::const_iterator iter; Common::Array<Common::String> targets; targets.reserve(domains.size()); @@ -716,15 +715,15 @@ static void listTargets() { Common::String name(iter->_key); Common::String description(iter->_value.getVal("description")); + // If there's no description, fallback on the default description. if (description.empty()) { - // FIXME: At this point, we should check for a "gameid" override - // to find the proper desc. In fact, the platform probably should - // be taken into account, too. - const Common::String &gameid = name; - PlainGameDescriptor g = EngineMan.findGame(gameid); + PlainGameDescriptor g = EngineMan.findTarget(name); if (g.description) description = g.description; } + // If there's still no description, we cannot come up with one. Insert some dummy text. + if (description.empty()) + description = "<Unknown game>"; targets.push_back(Common::String::format("%-20s %s", name.c_str(), description.c_str())); } @@ -766,24 +765,21 @@ static Common::Error listSaves(const Common::String &target) { // target specific savepath will be checked ConfMan.setActiveDomain(*i); - // Grab the gameid from the domain resp. use the target as gameid - Common::String gameid; - if (domain) - gameid = domain->getVal("gameid"); - if (gameid.empty()) - gameid = *i; - gameid.toLowercase(); // Normalize it to lower case - - // Find the plugin that will handle the specified gameid + // Look for a game matching the target const Plugin *plugin = nullptr; - EngineMan.findGame(gameid, &plugin); + PlainGameDescriptor game; + if (domain) { + game = EngineMan.findTarget(target, &plugin); + } else { + game = EngineMan.findGame(target, &plugin); + } if (!plugin) { // If the target was specified, treat this as an error, and otherwise skip it. if (!target.empty()) return Common::Error(Common::kEnginePluginNotFound, - Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str())); - printf("Plugin could not be loaded for target '%s', gameid '%s", i->c_str(), gameid.c_str()); + Common::String::format("target '%s', gameid '%s", i->c_str(), game.gameId)); + printf("Plugin could not be loaded for target '%s', gameid '%s", i->c_str(), game.gameId); continue; } @@ -794,7 +790,7 @@ static Common::Error listSaves(const Common::String &target) { if (!target.empty()) // TODO: Include more info about the target (desc, engine name, ...) ??? return Common::Error(Common::kEnginePluginNotSupportSaves, - Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str())); + Common::String::format("target '%s', gameid '%s", i->c_str(), game.gameId)); continue; } @@ -805,7 +801,7 @@ static Common::Error listSaves(const Common::String &target) { // TODO: Include more info about the target (desc, engine name, ...) ??? if (atLeastOneFound) printf("\n"); - printf("Save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str()); + printf("Save states for target '%s' (gameid '%s'):\n", i->c_str(), game.gameId); printf(" Slot Description \n" " ---- ------------------------------------------------------\n"); @@ -817,7 +813,7 @@ static Common::Error listSaves(const Common::String &target) { } else { // If the target was specified, indicate no save games were found for it. Otherwise just skip it. if (!target.empty()) - printf("There are no save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str()); + printf("There are no save states for target '%s' (gameid '%s'):\n", i->c_str(), game.gameId); } } @@ -916,10 +912,14 @@ static Common::String detectGames(const Common::String &path, const Common::Stri return Common::String(); } // TODO this is not especially pretty - printf("ID Description Full Path\n"); - printf("-------------- ---------------------------------------------------------- ---------------------------------------------------------\n"); + printf("EngineID GameID Description Full Path\n"); + printf("-------------- -------------- ---------------------------------------------------------- ---------------------------------------------------------\n"); for (DetectedGames::const_iterator v = candidates.begin(); v != candidates.end(); ++v) { - printf("%-14s %-58s %s\n", v->gameId.c_str(), v->description.c_str(), v->path.c_str()); + printf("%-14s %-14s %-58s %s\n", + v->engineId.c_str(), + v->gameId.c_str(), + v->description.c_str(), + v->path.c_str()); } return candidates[0].gameId; @@ -1010,7 +1010,7 @@ static void runDetectorTest() { bool gameidDiffers = false; DetectedGames::const_iterator x; for (x = candidates.begin(); x != candidates.end(); ++x) { - gameidDiffers |= (scumm_stricmp(gameid.c_str(), x->gameId.c_str()) != 0); + gameidDiffers |= !gameid.equalsIgnoreCase(x->gameId); } if (candidates.empty()) { @@ -1120,7 +1120,8 @@ void upgradeTargets() { // At this point, g points to a GameDescriptor which we can use to update // the target referred to by dom. We update several things - // Always set the gameid explicitly (in case of legacy targets) + // Always set the engine ID and game ID explicitly (in case of legacy targets) + dom["engineid"] = g->engineId; dom["gameid"] = g->gameId; // Always set the GUI options. The user should not modify them, and engines might @@ -1149,7 +1150,7 @@ void upgradeTargets() { // ScummVM still generates an incorrect description string. So, the description // should only be updated if the user explicitly requests this. #if 0 - if (desc != g->description()) { + if (desc != g->description) { printf(" -> update desc from '%s' to\n '%s' ?\n", desc.c_str(), g->description.c_str()); dom["description"] = g->description; } @@ -1248,9 +1249,17 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo // domain (i.e. a target) matching this argument, or alternatively // whether there is a gameid matching that name. if (!command.empty()) { - PlainGameDescriptor gd = EngineMan.findGame(command); - if (ConfMan.hasGameDomain(command) || gd.gameId) { - bool idCameFromCommandLine = false; + PlainGameDescriptor gd; + const Plugin *plugin = nullptr; + if (ConfMan.hasGameDomain(command)) { + // Command is a known target + ConfMan.setActiveDomain(command); + } else if (gd = EngineMan.findGame(command, &plugin), gd.gameId) { + // Command is a known game ID + ConfMan.setActiveDomain(command); + + ConfMan.set("gameid", gd.gameId); + ConfMan.set("engineid", plugin->get<MetaEngine>().getEngineId()); // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching // undefined target adds launcher entry" @@ -1258,15 +1267,7 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo // We designate gameids which come strictly from command line // so AdvancedDetector will not save config file with invalid // gameid in case target autoupgrade was performed - if (!ConfMan.hasGameDomain(command)) { - idCameFromCommandLine = true; - } - - ConfMan.setActiveDomain(command); - - if (idCameFromCommandLine) - ConfMan.set("id_came_from_command_line", "1"); - + ConfMan.set("id_came_from_command_line", "1"); } else { #ifndef DISABLE_COMMAND_LINE usage("Unrecognized game target '%s'", command.c_str()); diff --git a/base/main.cpp b/base/main.cpp index 750e09ee87..45c8e393b7 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -108,39 +108,50 @@ static bool launcherDialog() { } static const Plugin *detectPlugin() { - const Plugin *plugin = nullptr; + // Figure out the engine ID and game ID + Common::String engineId = ConfMan.get("engineid"); + Common::String gameId = ConfMan.get("gameid"); - // Make sure the gameid is set in the config manager, and that it is lowercase. - Common::String gameid(ConfMan.getActiveDomainName()); - assert(!gameid.empty()); - if (ConfMan.hasKey("gameid")) { - gameid = ConfMan.get("gameid"); + // Print text saying what's going on + printf("User picked target '%s' (engine ID '%s', game ID '%s')...\n", ConfMan.getActiveDomainName().c_str(), engineId.c_str(), gameId.c_str()); - // Set last selected game, that the game will be highlighted - // on RTL - ConfMan.set("lastselectedgame", ConfMan.getActiveDomainName(), Common::ConfigManager::kApplicationDomain); - ConfMan.flushToDisk(); + // At this point the engine ID and game ID must be known + if (engineId.empty()) { + warning("The engine ID is not set for target '%s'", ConfMan.getActiveDomainName().c_str()); + return 0; } - gameid.toLowercase(); - ConfMan.set("gameid", gameid); - - // Query the plugins and find one that will handle the specified gameid - printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str()); - printf(" Looking for a plugin supporting this gameid... "); + if (gameId.empty()) { + warning("The game ID is not set for target '%s'", ConfMan.getActiveDomainName().c_str()); + return 0; + } - PlainGameDescriptor game = EngineMan.findGame(gameid, &plugin); + const Plugin *plugin = EngineMan.findPlugin(engineId); + if (!plugin) { + warning("'%s' is an invalid engine ID. Use the --list-engines command to list supported engine IDs", engineId.c_str()); + return 0; + } - if (plugin == 0) { - printf("failed\n"); - warning("%s is an invalid gameid. Use the --list-games option to list supported gameid", gameid.c_str()); - } else { - printf("%s\n Starting '%s'\n", plugin->getName(), game.description); + // Query the plugin for the game descriptor + printf(" Looking for a plugin supporting this target... %s\n", plugin->getName()); + PlainGameDescriptor game = plugin->get<MetaEngine>().findGame(gameId.c_str()); + if (!game.gameId) { + warning("'%s' is an invalid game ID for the engine '%s'. Use the --list-games option to list supported game IDs", gameId.c_str(), engineId.c_str()); + return 0; } return plugin; } +void saveLastLaunchedTarget(const Common::String &target) { + if (ConfMan.hasGameDomain(target)) { + // Set the last selected game, so the game will be highlighted next time the user + // returns to the launcher. + ConfMan.set("lastselectedgame", target, Common::ConfigManager::kApplicationDomain); + ConfMan.flushToDisk(); + } +} + // TODO: specify the possible return values here static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) { // Determine the game data path, for validation and error messages @@ -208,7 +219,7 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common Common::String caption(ConfMan.get("description")); if (caption.empty()) { - PlainGameDescriptor game = EngineMan.findGame(ConfMan.get("gameid")); + PlainGameDescriptor game = EngineMan.findTarget(ConfMan.getActiveDomainName()); if (game.description) { caption = game.description; } @@ -532,6 +543,8 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // work as well as it should. In theory everything should be destroyed // cleanly, so this is now enabled to encourage people to fix bits :) while (0 != ConfMan.getActiveDomain()) { + saveLastLaunchedTarget(ConfMan.getActiveDomainName()); + // Try to find a plugin which feels responsible for the specified game. const Plugin *plugin = detectPlugin(); if (plugin) { diff --git a/base/plugins.cpp b/base/plugins.cpp index ac217ab960..a64dbdd65c 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -287,14 +287,14 @@ void PluginManagerUncached::init() { /** * Try to load the plugin by searching in the ConfigManager for a matching - * gameId under the domain 'plugin_files'. + * engine ID under the domain 'engine_plugin_files'. **/ -bool PluginManagerUncached::loadPluginFromGameId(const Common::String &gameId) { - Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); +bool PluginManagerUncached::loadPluginFromEngineId(const Common::String &engineId) { + Common::ConfigManager::Domain *domain = ConfMan.getDomain("engine_plugin_files"); if (domain) { - if (domain->contains(gameId)) { - Common::String filename = (*domain)[gameId]; + if (domain->contains(engineId)) { + Common::String filename = (*domain)[engineId]; if (loadPluginByFileName(filename)) { return true; @@ -326,17 +326,17 @@ bool PluginManagerUncached::loadPluginByFileName(const Common::String &filename) /** * Update the config manager with a plugin file name that we found can handle - * the game. + * the engine. **/ -void PluginManagerUncached::updateConfigWithFileName(const Common::String &gameId) { +void PluginManagerUncached::updateConfigWithFileName(const Common::String &engineId) { // Check if we have a filename for the current plugin if ((*_currentPlugin)->getFileName()) { - if (!ConfMan.hasMiscDomain("plugin_files")) - ConfMan.addMiscDomain("plugin_files"); + if (!ConfMan.hasMiscDomain("engine_plugin_files")) + ConfMan.addMiscDomain("engine_plugin_files"); - Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); + Common::ConfigManager::Domain *domain = ConfMan.getDomain("engine_plugin_files"); assert(domain); - (*domain)[gameId] = (*_currentPlugin)->getFileName(); + (*domain)[engineId] = (*_currentPlugin)->getFileName(); ConfMan.flushToDisk(); } @@ -490,24 +490,12 @@ PlainGameDescriptor EngineManager::findGame(const Common::String &gameName, cons return result; } - // Now look for the game using the gameId. This is much faster than scanning plugin - // by plugin - if (PluginMan.loadPluginFromGameId(gameName)) { - result = findGameInLoadedPlugins(gameName, plugin); - if (result.gameId) { - return result; - } - } - - // We failed to find it using the gameid. Scan the list of plugins + // We failed to find it in memory. Scan the list of plugins PluginMan.loadFirstPlugin(); do { result = findGameInLoadedPlugins(gameName, plugin); - if (result.gameId) { - // Update with new plugin file name - PluginMan.updateConfigWithFileName(gameName); + if (result.gameId) break; - } } while (PluginMan.loadNextPlugin()); return result; @@ -551,7 +539,6 @@ DetectionResults EngineManager::detectGames(const Common::FSList &fslist) const DetectedGames engineCandidates = metaEngine.detectGames(fslist); for (uint i = 0; i < engineCandidates.size(); i++) { - engineCandidates[i].engineName = metaEngine.getName(); engineCandidates[i].path = fslist.begin()->getParent().getPath(); engineCandidates[i].shortPath = fslist.begin()->getParent().getDisplayName(); candidates.push_back(engineCandidates[i]); @@ -597,6 +584,7 @@ Common::String EngineManager::createTargetForGame(const DetectedGame &game) { ConfMan.addGameDomain(domain); // Copy all non-empty relevant values into the new domain + addStringToConf("engineid", game.engineId, domain); addStringToConf("gameid", game.gameId, domain); addStringToConf("description", game.description, domain); addStringToConf("language", Common::getLanguageCode(game.language), domain); @@ -623,6 +611,70 @@ Common::String EngineManager::createTargetForGame(const DetectedGame &game) { return domain; } +const Plugin *EngineManager::findLoadedPlugin(const Common::String &engineId) const { + const PluginList &plugins = getPlugins(); + + for (PluginList::const_iterator iter = plugins.begin(); iter != plugins.end(); iter++) + if (engineId == (*iter)->get<MetaEngine>().getEngineId()) + return *iter; + + return 0; +} + +const Plugin *EngineManager::findPlugin(const Common::String &engineId) const { + // First look for the game using the plugins in memory. This is critical + // for calls coming from inside games + const Plugin *plugin = findLoadedPlugin(engineId); + if (plugin) + return plugin; + + // Now look for the plugin using the engine ID. This is much faster than scanning plugin + // by plugin + if (PluginMan.loadPluginFromEngineId(engineId)) { + plugin = findLoadedPlugin(engineId); + if (plugin) + return plugin; + } + + // We failed to find it using the engine ID. Scan the list of plugins + PluginMan.loadFirstPlugin(); + do { + plugin = findLoadedPlugin(engineId); + if (plugin) { + // Update with new plugin file name + PluginMan.updateConfigWithFileName(engineId); + return plugin; + } + } while (PluginMan.loadNextPlugin()); + + return 0; +} + +PlainGameDescriptor EngineManager::findTarget(const Common::String &target, const Plugin **plugin) const { + // Ignore empty targets + if (target.empty()) + return PlainGameDescriptor(); + + // Lookup the domain. If we have no domain, fallback on the old function [ultra-deprecated]. + const Common::ConfigManager::Domain *domain = ConfMan.getDomain(target); + if (!domain || !domain->contains("gameid") || !domain->contains("engineid")) + return PlainGameDescriptor(); + + // Look for the engine ID + const Plugin *foundPlugin = findPlugin(domain->getVal("engineid")); + if (!foundPlugin) { + return PlainGameDescriptor(); + } + + // Make sure it does support the game ID + PlainGameDescriptor desc = foundPlugin->get<MetaEngine>().findGame(domain->getVal("gameid").c_str()); + + if (desc.gameId && plugin) + *plugin = foundPlugin; + + return desc; +} + // Music plugins #include "audio/musicplugin.h" diff --git a/base/plugins.h b/base/plugins.h index 1daa426202..ccb1acf3fb 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -315,8 +315,8 @@ public: virtual void init() {} virtual void loadFirstPlugin() {} virtual bool loadNextPlugin() { return false; } - virtual bool loadPluginFromGameId(const Common::String &gameId) { return false; } - virtual void updateConfigWithFileName(const Common::String &gameId) {} + virtual bool loadPluginFromEngineId(const Common::String &engineId) { return false; } + virtual void updateConfigWithFileName(const Common::String &engineId) {} // Functions used only by the cached PluginManager virtual void loadAllPlugins(); @@ -345,8 +345,8 @@ public: virtual void init(); virtual void loadFirstPlugin(); virtual bool loadNextPlugin(); - virtual bool loadPluginFromGameId(const Common::String &gameId); - virtual void updateConfigWithFileName(const Common::String &gameId); + virtual bool loadPluginFromEngineId(const Common::String &engineId); + virtual void updateConfigWithFileName(const Common::String &engineId); virtual void loadAllPlugins() {} // we don't allow these virtual void loadAllPluginsOfType(PluginType type) {} diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index 10ddb0d073..4cc05aef32 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -82,8 +82,6 @@ static Common::String generatePreferredTarget(const ADGameDescription *desc) { DetectedGame AdvancedMetaEngine::toDetectedGame(const ADDetectedGame &adGame) const { const ADGameDescription *desc = adGame.desc; - const char *gameId = _singleId ? _singleId : desc->gameId; - const char *title; const char *extra; if (desc->flags & ADGF_USEEXTRAASTITLE) { @@ -99,7 +97,7 @@ DetectedGame AdvancedMetaEngine::toDetectedGame(const ADDetectedGame &adGame) co extra = desc->extra; } - DetectedGame game(gameId, title, desc->language, desc->platform, extra); + DetectedGame game(getEngineId(), desc->gameId, title, desc->language, desc->platform, extra); game.hasUnknownFiles = adGame.hasUnknownFiles; game.matchedFiles = adGame.matchedFiles; game.preferredTarget = generatePreferredTarget(desc); @@ -264,7 +262,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) ADDetectedGame agdDesc; for (uint i = 0; i < matches.size(); i++) { - if ((_singleId || matches[i].desc->gameId == gameid) && !matches[i].hasUnknownFiles) { + if (matches[i].desc->gameId == gameid && !matches[i].hasUnknownFiles) { agdDesc = matches[i]; break; } @@ -277,7 +275,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) if (agdDesc.desc) { // Seems we found a fallback match. But first perform a basic // sanity check: the gameid must match. - if (!_singleId && agdDesc.desc->gameId != gameid) + if (agdDesc.desc->gameId != gameid) agdDesc = ADDetectedGame(); } } @@ -556,21 +554,6 @@ ADDetectedGame AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles, } PlainGameList AdvancedMetaEngine::getSupportedGames() const { - if (_singleId != NULL) { - PlainGameList gl; - - const PlainGameDescriptor *g = _gameIds; - while (g->gameId) { - if (0 == scumm_stricmp(_singleId, g->gameId)) { - gl.push_back(*g); - - return gl; - } - g++; - } - error("Engine %s doesn't have its singleid specified in ids list", _singleId); - } - return PlainGameList(_gameIds); } @@ -589,7 +572,6 @@ AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, con _extraGuiOptions(extraGuiOptions) { _md5Bytes = 5000; - _singleId = NULL; _flags = 0; _guiOptions = GUIO_NONE; _maxScanDepth = 1; diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index 326cb79c49..088dfeae41 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -206,19 +206,6 @@ protected: uint _md5Bytes; /** - * Name of single gameid (optional). - * - * Used to override gameid. - * This is a recommended setting to prevent global gameid pollution. - * With this option set, the gameid effectively turns into engineid. - * - * FIXME: This field actually removes a feature (gameid) in order to - * address a more generic problem. We should find a better way to - * disambiguate gameids. - */ - const char *_singleId; - - /** * A bitmask of flags which can be used to configure the behavior * of the AdvancedDetector. Refer to ADFlags for a list of flags * that can be ORed together and passed here. diff --git a/engines/engine.cpp b/engines/engine.cpp index 30cbb0be40..bee51778c9 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -673,12 +673,7 @@ bool Engine::shouldQuit() { /* EnginePlugin *Engine::getMetaEnginePlugin() const { - - const EnginePlugin *plugin = 0; - Common::String gameid = ConfMan.get("gameid"); - gameid.toLowercase(); - EngineMan.findGame(gameid, &plugin); - return plugin; + return EngineMan.findPlugin(ConfMan.get("engineid")); } */ diff --git a/engines/game.cpp b/engines/game.cpp index 24e125825f..13c24a0477 100644 --- a/engines/game.cpp +++ b/engines/game.cpp @@ -50,7 +50,6 @@ PlainGameDescriptor PlainGameDescriptor::of(const char *gameId, const char *desc } DetectedGame::DetectedGame() : - engineName(nullptr), hasUnknownFiles(false), canBeAdded(true), language(Common::UNK_LANG), @@ -58,8 +57,8 @@ DetectedGame::DetectedGame() : gameSupportLevel(kStableGame) { } -DetectedGame::DetectedGame(const PlainGameDescriptor &pgd) : - engineName(nullptr), +DetectedGame::DetectedGame(const Common::String &engine, const PlainGameDescriptor &pgd) : + engineId(engine), hasUnknownFiles(false), canBeAdded(true), language(Common::UNK_LANG), @@ -71,8 +70,8 @@ DetectedGame::DetectedGame(const PlainGameDescriptor &pgd) : description = pgd.description; } -DetectedGame::DetectedGame(const Common::String &id, const Common::String &d, Common::Language l, Common::Platform p, const Common::String &ex) : - engineName(nullptr), +DetectedGame::DetectedGame(const Common::String &engine, const Common::String &id, const Common::String &d, Common::Language l, Common::Platform p, const Common::String &ex) : + engineId(engine), hasUnknownFiles(false), canBeAdded(true), gameSupportLevel(kStableGame) { @@ -178,20 +177,20 @@ Common::String generateUnknownGameReport(const DetectedGames &detectedGames, boo FilePropertiesMap matchedFiles; - const char *currentEngineName = nullptr; + Common::String currentEngineId; for (uint i = 0; i < detectedGames.size(); i++) { const DetectedGame &game = detectedGames[i]; if (!game.hasUnknownFiles) continue; - if (!currentEngineName || strcmp(currentEngineName, game.engineName) != 0) { - currentEngineName = game.engineName; + if (currentEngineId.empty() || currentEngineId != game.engineId) { + currentEngineId = game.engineId; // If the engine is not the same as for the previous entry, print an engine line header report += "\n"; report += Common::String::format( translate ? _(reportEngineHeader) : reportEngineHeader, - game.engineName + game.engineId.c_str() ); report += " "; diff --git a/engines/game.h b/engines/game.h index 8a678cfd2c..92fce635af 100644 --- a/engines/game.h +++ b/engines/game.h @@ -98,8 +98,8 @@ typedef Common::HashMap<Common::String, FileProperties, Common::IgnoreCase_Hash, */ struct DetectedGame { DetectedGame(); - explicit DetectedGame(const PlainGameDescriptor &pgd); - DetectedGame(const Common::String &id, + DetectedGame(const Common::String &engine, const PlainGameDescriptor &pgd); + DetectedGame(const Common::String &engine, const Common::String &id, const Common::String &description, Common::Language language = Common::UNK_LANG, Common::Platform platform = Common::kPlatformUnknown, @@ -109,10 +109,7 @@ struct DetectedGame { void appendGUIOptions(const Common::String &str); Common::String getGUIOptions() const { return _guiOptions; } - /** - * The name of the engine supporting the detected game - */ - const char *engineName; + Common::String engineId; /** * A game was detected, but some files were not recognized diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp index b4d5bff84c..1e465e9827 100644 --- a/engines/glk/detection.cpp +++ b/engines/glk/detection.cpp @@ -104,27 +104,27 @@ namespace Glk { GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename) : - DetectedGame(id, desc, Common::EN_ANY, Common::kPlatformUnknown) { + DetectedGame("glk", id, desc, Common::EN_ANY, Common::kPlatformUnknown) { setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES)); addExtraEntry("filename", filename); } GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename, - Common::Language lang) : DetectedGame(id, desc, lang, Common::kPlatformUnknown) { + Common::Language lang) : DetectedGame("glk", id, desc, lang, Common::kPlatformUnknown) { setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES)); addExtraEntry("filename", filename); } GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const char *xtra, const Common::String &filename, Common::Language lang) : - DetectedGame(id, desc, lang, Common::kPlatformUnknown, xtra) { + DetectedGame("glk", id, desc, lang, Common::kPlatformUnknown, xtra) { setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES)); addExtraEntry("filename", filename); } GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename, const Common::String &md5, size_t filesize) : - DetectedGame(id, desc, Common::UNK_LANG, Common::kPlatformUnknown) { + DetectedGame("glk", id, desc, Common::UNK_LANG, Common::kPlatformUnknown) { setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES)); addExtraEntry("filename", filename); diff --git a/engines/glk/frotz/detection.cpp b/engines/glk/frotz/detection.cpp index d4ffee33a3..f699c832a9 100644 --- a/engines/glk/frotz/detection.cpp +++ b/engines/glk/frotz/detection.cpp @@ -123,7 +123,7 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize)); } else { GameDescriptor gameDesc = findGame(p->_gameId); - DetectedGame gd = DetectedGame(p->_gameId, gameDesc._description, p->_language, Common::kPlatformUnknown, p->_extra); + DetectedGame gd = DetectedGame("glk", p->_gameId, gameDesc._description, p->_language, Common::kPlatformUnknown, p->_extra); gd.setGUIOptions(p->_guiOptions); gd.addExtraEntry("filename", filename); diff --git a/engines/glk/level9/detection.cpp b/engines/glk/level9/detection.cpp index 5788c0f95c..a366bc0f9b 100644 --- a/engines/glk/level9/detection.cpp +++ b/engines/glk/level9/detection.cpp @@ -752,7 +752,7 @@ bool Level9MetaEngine::detectGames(const Common::FSList &fslist, DetectedGames & continue; // Found the game, add a detection entry - DetectedGame gd = DetectedGame(game->gameId, game->name, Common::UNK_LANG, + DetectedGame gd = DetectedGame("glk", game->gameId, game->name, Common::UNK_LANG, Common::kPlatformUnknown, game->extra); gd.addExtraEntry("filename", filename); gameList.push_back(gd); diff --git a/engines/glk/tads/detection.cpp b/engines/glk/tads/detection.cpp index 7bca1bb83b..9c0c5eb6bf 100644 --- a/engines/glk/tads/detection.cpp +++ b/engines/glk/tads/detection.cpp @@ -110,7 +110,7 @@ bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga gameList.push_back(GlkDetectedGame(desc._gameId, desc._description, filename, md5, filesize)); } else { PlainGameDescriptor gameDesc = findGame(p->_gameId); - gd = DetectedGame(p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra); + gd = DetectedGame("glk", p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra); gd.addExtraEntry("filename", filename); gameList.push_back(gd); } diff --git a/engines/illusions/menusystem.cpp b/engines/illusions/menusystem.cpp index f61adb42bd..72cdeeeade 100644 --- a/engines/illusions/menusystem.cpp +++ b/engines/illusions/menusystem.cpp @@ -673,14 +673,12 @@ MenuActionLoadGame::MenuActionLoadGame(BaseMenuSystem *menuSystem, uint choiceIn } void MenuActionLoadGame::execute() { - const Plugin *plugin = NULL; - EngineMan.findGame(ConfMan.get("gameid"), &plugin); GUI::SaveLoadChooser *dialog; Common::String desc; int slot; dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); delete dialog; @@ -698,14 +696,12 @@ MenuActionSaveGame::MenuActionSaveGame(BaseMenuSystem *menuSystem, uint choiceIn } void MenuActionSaveGame::execute() { - const Plugin *plugin = NULL; - EngineMan.findGame(ConfMan.get("gameid"), &plugin); GUI::SaveLoadChooser *dialog; Common::String desc; int slot; dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); desc = dialog->getResultString().c_str(); delete dialog; diff --git a/engines/macventure/detection.cpp b/engines/macventure/detection.cpp index 5c419e8934..d258ea05ea 100644 --- a/engines/macventure/detection.cpp +++ b/engines/macventure/detection.cpp @@ -63,10 +63,6 @@ public: _md5Bytes = 5000000; // TODO: Upper limit, adjust it once all games are added } - const char *getName() const { - return "MacVenture"; - } - const char *getEngineId() const override { return "macventure"; } diff --git a/engines/metaengine.h b/engines/metaengine.h index a95ff1593e..89f786f7b0 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -65,6 +65,9 @@ class MetaEngine : public PluginObject { public: virtual ~MetaEngine() {} + /** Get the engine ID */ + virtual const char *getEngineId() const = 0; + /** Returns some copyright information about the original engine. */ virtual const char *getOriginalCopyright() const = 0; @@ -267,17 +270,37 @@ public: */ class EngineManager : public Common::Singleton<EngineManager> { public: - PlainGameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const Plugin **plugin = NULL) const; - PlainGameDescriptor findGame(const Common::String &gameName, const Plugin **plugin = NULL) const; + /** + * Given a list of FSNodes in a given directory, detect a set of games contained within + * + * Returns an empty list if none are found. + */ DetectionResults detectGames(const Common::FSList &fslist) const; + + /** Find a plugin by its engine ID */ + const Plugin *findPlugin(const Common::String &engineId) const; + + /** Get the list of all engine plugins */ const PluginList &getPlugins() const; + /** Find a target */ // TODO: Expand on description + PlainGameDescriptor findTarget(const Common::String &target, const Plugin **plugin = NULL) const; + + /** Find a game across all plugins */ // TODO: Naming, this should be gameId + PlainGameDescriptor findGame(const Common::String &gameName, const Plugin **plugin = NULL) const; + /** * Create a target from the supplied game descriptor * * Returns the created target name. */ Common::String createTargetForGame(const DetectedGame &game); +private: + /** Find a game across all loaded plugins */ + PlainGameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const Plugin **plugin = NULL) const; + + /** Find a loaded plugin with the given engine ID */ + const Plugin *findLoadedPlugin(const Common::String &engineId) const; }; /** Convenience shortcut for accessing the engine manager. */ diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp index b64f4dcdd2..3c16122b8d 100644 --- a/engines/neverhood/menumodule.cpp +++ b/engines/neverhood/menumodule.cpp @@ -870,8 +870,6 @@ void SavegameListBox::pageDown() { } int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) { - const Plugin *plugin = nullptr; - EngineMan.findGame(ConfMan.get("gameid"), &plugin); GUI::SaveLoadChooser *dialog; Common::String desc; int slot; @@ -879,7 +877,7 @@ int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) if (isSave) { dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); desc = dialog->getResultString(); if (desc.empty()) @@ -891,7 +889,7 @@ int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) saveDesc = desc; } else { dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); } delete dialog; diff --git a/engines/obsolete.cpp b/engines/obsolete.cpp index ea96cff42e..40fe8323f1 100644 --- a/engines/obsolete.cpp +++ b/engines/obsolete.cpp @@ -58,8 +58,7 @@ void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList) { PlainGameDescriptor findGameID( const char *gameid, const PlainGameDescriptor *gameids, - const ObsoleteGameID *obsoleteList - ) { + const ObsoleteGameID *obsoleteList) { // First search the list of supported gameids for a match. const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, gameids); if (g) diff --git a/engines/obsolete.h b/engines/obsolete.h index 7c7249e52b..c1bbad6a8c 100644 --- a/engines/obsolete.h +++ b/engines/obsolete.h @@ -69,8 +69,7 @@ void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList); PlainGameDescriptor findGameID( const char *gameid, const PlainGameDescriptor *gameids, - const ObsoleteGameID *obsoleteList = 0 - ); + const ObsoleteGameID *obsoleteList = 0); } // End of namespace Engines diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 043fddc03c..a1aa5bead1 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -354,12 +354,7 @@ void PegasusEngine::runIntro() { Common::Error PegasusEngine::showLoadDialog() { GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false); - Common::String gameId = ConfMan.get("gameid"); - - const Plugin *plugin = nullptr; - EngineMan.findGame(gameId, &plugin); - - int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = slc.runModalWithCurrentTarget(); Common::Error result; @@ -378,12 +373,7 @@ Common::Error PegasusEngine::showLoadDialog() { Common::Error PegasusEngine::showSaveDialog() { GUI::SaveLoadChooser slc(_("Save game:"), _("Save"), true); - Common::String gameId = ConfMan.get("gameid"); - - const Plugin *plugin = nullptr; - EngineMan.findGame(gameId, &plugin); - - int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = slc.runModalWithCurrentTarget(); if (slot >= 0) return saveGameState(slot, slc.getResultString()); diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index adfc7a3449..1576ee39f2 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -1049,7 +1049,7 @@ DetectedGames ScummMetaEngine::detectGames(const Common::FSList &fslist) const { const PlainGameDescriptor *g = findPlainGameDescriptor(x->game.gameid, gameDescriptions); assert(g); - DetectedGame game = DetectedGame(x->game.gameid, g->description, x->language, x->game.platform, x->extra); + DetectedGame game = DetectedGame(getEngineId(), x->game.gameid, g->description, x->language, x->game.platform, x->extra); // Compute and set the preferred target name for this game. // Based on generateComplexID() in advancedDetector.cpp. diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp index 1934d84dfa..9ce13a654f 100644 --- a/engines/sky/detection.cpp +++ b/engines/sky/detection.cpp @@ -189,12 +189,12 @@ DetectedGames SkyMetaEngine::detectGames(const Common::FSList &fslist) const { if (sv->dinnerTableEntries) { Common::String extra = Common::String::format("v0.0%d %s", sv->version, sv->extraDesc); - DetectedGame game = DetectedGame(skySetting.gameId, skySetting.description, Common::UNK_LANG, Common::kPlatformUnknown, extra); + DetectedGame game = DetectedGame(getEngineId(), skySetting.gameId, skySetting.description, Common::UNK_LANG, Common::kPlatformUnknown, extra); game.setGUIOptions(sv->guioptions); detectedGames.push_back(game); } else { - detectedGames.push_back(DetectedGame(skySetting.gameId, skySetting.description)); + detectedGames.push_back(DetectedGame(getEngineId(), skySetting.gameId, skySetting.description)); } } diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp index a02b02b437..2d39a2d4ea 100644 --- a/engines/sword1/detection.cpp +++ b/engines/sword1/detection.cpp @@ -218,17 +218,17 @@ DetectedGames SwordMetaEngine::detectGames(const Common::FSList &fslist) const { DetectedGame game; if (mainFilesFound && pcFilesFound && demoFilesFound) - game = DetectedGame(sword1DemoSettings); + game = DetectedGame(getEngineId(), sword1DemoSettings); else if (mainFilesFound && pcFilesFound && psxFilesFound) - game = DetectedGame(sword1PSXSettings); + game = DetectedGame(getEngineId(), sword1PSXSettings); else if (mainFilesFound && pcFilesFound && psxDemoFilesFound) - game = DetectedGame(sword1PSXDemoSettings); + game = DetectedGame(getEngineId(), sword1PSXDemoSettings); else if (mainFilesFound && pcFilesFound && !psxFilesFound) - game = DetectedGame(sword1FullSettings); + game = DetectedGame(getEngineId(), sword1FullSettings); else if (mainFilesFound && macFilesFound) - game = DetectedGame(sword1MacFullSettings); + game = DetectedGame(getEngineId(), sword1MacFullSettings); else if (mainFilesFound && macDemoFilesFound) - game = DetectedGame(sword1MacDemoSettings); + game = DetectedGame(getEngineId(), sword1MacDemoSettings); else return detectedGames; diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp index 4e67f0d65d..2c682bc87c 100644 --- a/engines/sword2/sword2.cpp +++ b/engines/sword2/sword2.cpp @@ -196,7 +196,7 @@ DetectedGames detectGamesImpl(const Common::FSList &fslist, bool recursion = fal continue; // Match found, add to list of candidates, then abort inner loop. - DetectedGame game = DetectedGame(g->gameid, g->description); + DetectedGame game = DetectedGame("sword2", g->gameid, g->description); game.setGUIOptions(GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)); detectedGames.push_back(game); diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index d249ea4eff..a7f6e1be65 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -599,7 +599,7 @@ void EventRecorder::setFileHeader() { return; } TimeDate t; - PlainGameDescriptor desc = EngineMan.findGame(ConfMan.getActiveDomainName()); + PlainGameDescriptor desc = EngineMan.findTarget(ConfMan.getActiveDomainName()); g_system->getTimeAndDate(t); if (_author.empty()) { setAuthor("Unknown Author"); @@ -618,9 +618,7 @@ SDL_Surface *EventRecorder::getSurface(int width, int height) { } bool EventRecorder::switchMode() { - const Common::String gameId = ConfMan.get("gameid"); - const Plugin *plugin = nullptr; - EngineMan.findGame(gameId, &plugin); + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); bool metaInfoSupport = plugin->get<MetaEngine>().hasFeature(MetaEngine::kSavesSupportMetaInfo); bool featuresSupport = metaInfoSupport && g_engine->canSaveGameStateCurrently() && @@ -630,8 +628,10 @@ bool EventRecorder::switchMode() { return false; } + const Common::String target = ConfMan.getActiveDomainName(); + SaveStateList saveList = plugin->get<MetaEngine>().listSaves(target.c_str()); + int emptySlot = 1; - SaveStateList saveList = plugin->get<MetaEngine>().listSaves(gameId.c_str()); for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { int saveSlot = x->getSaveSlot(); if (saveSlot == 0) { @@ -666,10 +666,9 @@ bool EventRecorder::checkForContinueGame() { void EventRecorder::deleteTemporarySave() { if (_temporarySlot == -1) return; - const Common::String gameId = ConfMan.get("gameid"); - const Plugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - plugin->get<MetaEngine>().removeSaveState(gameId.c_str(), _temporarySlot); + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); + const Common::String target = ConfMan.getActiveDomainName(); + plugin->get<MetaEngine>().removeSaveState(target.c_str(), _temporarySlot); _temporarySlot = -1; } diff --git a/gui/launcher.cpp b/gui/launcher.cpp index ac414e0fa1..c8c2cc0583 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -269,8 +269,9 @@ void LauncherDialog::updateListing() { if (gameid.empty()) gameid = iter->_key; + if (description.empty()) { - PlainGameDescriptor g = EngineMan.findGame(gameid); + PlainGameDescriptor g = EngineMan.findTarget(iter->_key); if (g.description) description = g.description; } @@ -416,9 +417,6 @@ void LauncherDialog::editGame(int item) { // This is useful because e.g. MonkeyVGA needs AdLib music to have decent // music support etc. assert(item >= 0); - String gameId(ConfMan.get("gameid", _domains[item])); - if (gameId.empty()) - gameId = _domains[item]; EditGameDialog editDialog(_domains[item]); if (editDialog.runModal() > 0) { @@ -480,17 +478,13 @@ void LauncherDialog::recordGame(int item) { #endif void LauncherDialog::loadGame(int item) { - String gameId = ConfMan.get("gameid", _domains[item]); - if (gameId.empty()) - gameId = _domains[item]; - - const Plugin *plugin = nullptr; - - EngineMan.findGame(gameId, &plugin); - String target = _domains[item]; target.toLowercase(); + // Look for the plugin + const Plugin *plugin = nullptr; + EngineMan.findTarget(target, &plugin); + if (plugin) { const MetaEngine &metaEngine = plugin->get<MetaEngine>(); if (metaEngine.hasFeature(MetaEngine::kSupportsListSaves) && diff --git a/gui/massadd.cpp b/gui/massadd.cpp index f4d857a528..1d1d119303 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -207,7 +207,7 @@ void MassAddDialog::handleTickle() { while (path != "/" && path.lastChar() == '/') path.deleteLastChar(); - // Check for existing config entries for this path/gameid/lang/platform combination + // Check for existing config entries for this path/engineid/gameid/lang/platform combination if (_pathToTargets.contains(path)) { Common::String resultPlatformCode = Common::getPlatformCode(result.platform); Common::String resultLanguageCode = Common::getLanguageCode(result.language); @@ -215,11 +215,12 @@ void MassAddDialog::handleTickle() { bool duplicate = false; const StringArray &targets = _pathToTargets[path]; for (StringArray::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) { - // If the gameid, platform and language match -> skip it + // If the engineid, gameid, platform and language match -> skip it Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter); assert(dom); - if ((*dom)["gameid"] == result.gameId && + if ((*dom)["engineid"] == result.engineId && + (*dom)["gameid"] == result.gameId && (*dom)["platform"] == resultPlatformCode && (*dom)["language"] == resultLanguageCode) { duplicate = true; diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index 7a2cd048f4..ced5bcbc5b 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -166,8 +166,7 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat break; case kRecordCmd: { TimeDate t; - Common::String gameId = ConfMan.get("gameid", _target); - PlainGameDescriptor desc = EngineMan.findGame(gameId); + PlainGameDescriptor desc = EngineMan.findTarget(_target); g_system->getTimeAndDate(t); EditRecordDialog editDlg(_("Unknown Author"), Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description, ""); if (editDlg.runModal() != kOKCmd) { diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 6de8be97d8..4e2525a7c6 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -76,11 +76,7 @@ Common::String SaveLoadChooser::createDefaultSaveDescription(const int slot) con } int SaveLoadChooser::runModalWithCurrentTarget() { - const Common::String gameId = ConfMan.get("gameid"); - - const Plugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); return runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); } diff --git a/gui/unknown-game-dialog.cpp b/gui/unknown-game-dialog.cpp index 790f724948..cdbfcd4e97 100644 --- a/gui/unknown-game-dialog.cpp +++ b/gui/unknown-game-dialog.cpp @@ -193,13 +193,13 @@ Common::String UnknownGameDialog::generateBugtrackerURL() { Common::String report = generateUnknownGameReport(_detectedGame, false, false); report = encodeUrlString(report); - Common::String engineName = encodeUrlString(_detectedGame.engineName); + Common::String engineId = encodeUrlString(_detectedGame.engineId); return Common::String::format( "https://www.scummvm.org/unknowngame?" "engine=%s" "&description=%s", - engineName.c_str(), + engineId.c_str(), report.c_str()); } |