aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/commandLine.cpp1
-rw-r--r--base/main.cpp2
-rw-r--r--base/plugins.cpp84
-rw-r--r--engines/metaengine.h7
-rw-r--r--gui/editgamedialog.cpp2
-rw-r--r--gui/launcher.cpp2
6 files changed, 98 insertions, 0 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 74a5982f32..5c823b2425 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -769,6 +769,7 @@ static Common::Error listSaves(const Common::String &target) {
const Plugin *plugin = nullptr;
PlainGameDescriptor game;
if (domain) {
+ EngineMan.upgradeTargetIfNecessary(target);
game = EngineMan.findTarget(target, &plugin);
} else {
game = EngineMan.findGame(target, &plugin);
diff --git a/base/main.cpp b/base/main.cpp
index 45c8e393b7..85fdbb2986 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -545,6 +545,8 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
while (0 != ConfMan.getActiveDomain()) {
saveLastLaunchedTarget(ConfMan.getActiveDomainName());
+ EngineMan.upgradeTargetIfNecessary(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 a64dbdd65c..ac98de4d15 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -675,6 +675,90 @@ PlainGameDescriptor EngineManager::findTarget(const Common::String &target, cons
return desc;
}
+void EngineManager::upgradeTargetIfNecessary(const Common::String &target) const {
+ Common::ConfigManager::Domain *domain = ConfMan.getDomain(target);
+ assert(domain);
+
+ if (!domain->contains("engineid")) {
+ upgradeTargetForEngineId(target);
+ }
+}
+
+void EngineManager::upgradeTargetForEngineId(const Common::String &target) const {
+ Common::ConfigManager::Domain *domain = ConfMan.getDomain(target);
+ assert(domain);
+
+ debug("Target '%s' lacks an engine ID, upgrading...", target.c_str());
+
+ Common::String oldGameId = domain->getVal("gameid");
+ Common::String path = domain->getVal("path");
+
+ // At this point the game ID and game path must be known
+ if (oldGameId.empty()) {
+ warning("The game ID is required to upgrade target '%s'", target.c_str());
+ return;
+ }
+ if (path.empty()) {
+ warning("The game path is required to upgrade target '%s'", target.c_str());
+ return;
+ }
+
+ // Game descriptor for the upgraded target
+ Common::String engineId;
+ Common::String newGameId;
+
+ // First, try to update entries for engines that previously used the "single id" system
+ // Search for an engine whose ID is the game ID
+ const Plugin *plugin = findPlugin(oldGameId);
+ if (plugin) {
+ // Run detection on the game path
+ Common::FSNode dir(path);
+ Common::FSList files;
+ if (!dir.getChildren(files, Common::FSNode::kListAll)) {
+ warning("Failed to access path '%s' when upgrading target '%s'", path.c_str(), target.c_str());
+ return;
+ }
+
+ // Take the first detection entry
+ const MetaEngine &metaEngine = plugin->get<MetaEngine>();
+ DetectedGames candidates = metaEngine.detectGames(files);
+ if (candidates.empty()) {
+ warning("No games supported by the engine '%s' were found in path '%s' when upgrading target '%s'",
+ metaEngine.getEngineId(), path.c_str(), target.c_str());
+ return;
+ }
+
+ engineId = candidates[0].engineId;
+ newGameId = candidates[0].gameId;
+ }
+
+ // Next, try to find an engine with the game ID in its supported games list
+ if (engineId.empty()) {
+ PlainGameDescriptor pgd = findGame(oldGameId, &plugin);
+ if (plugin) {
+ engineId = plugin->get<MetaEngine>().getEngineId();
+ newGameId = pgd.gameId;
+ }
+ }
+
+ if (engineId.empty() || newGameId.empty()) {
+ warning("No matching engine was found when upgrading target '%s'", target.c_str());
+ return;
+ }
+
+ domain->setVal("engineid", engineId);
+ domain->setVal("gameid", newGameId);
+
+ // Save a backup of the pre-upgrade gameId to the config file
+ if (newGameId != oldGameId) {
+ domain->setVal("oldgameid", oldGameId);
+ }
+
+ debug("Upgrade complete (engine ID '%s', game ID '%s')", engineId.c_str(), newGameId.c_str());
+
+ ConfMan.flushToDisk();
+}
+
// Music plugins
#include "audio/musicplugin.h"
diff --git a/engines/metaengine.h b/engines/metaengine.h
index 89f786f7b0..a6c2c067e2 100644
--- a/engines/metaengine.h
+++ b/engines/metaengine.h
@@ -295,12 +295,19 @@ public:
* Returns the created target name.
*/
Common::String createTargetForGame(const DetectedGame &game);
+
+ /** Upgrade a target to the current configuration format */
+ void upgradeTargetIfNecessary(const Common::String &target) const;
+
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;
+
+ /** Use heuristics to complete a target lacking an engine ID */
+ void upgradeTargetForEngineId(const Common::String &target) const;
};
/** Convenience shortcut for accessing the engine manager. */
diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index ac030d7678..4f3c1647a1 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -100,6 +100,8 @@ protected:
EditGameDialog::EditGameDialog(const String &domain)
: OptionsDialog(domain, "GameOptions") {
+ EngineMan.upgradeTargetIfNecessary(domain);
+
// Retrieve all game specific options.
const Plugin *plugin = nullptr;
// To allow for game domains without a gameid.
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index c8c2cc0583..a3151a0455 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -481,6 +481,8 @@ void LauncherDialog::loadGame(int item) {
String target = _domains[item];
target.toLowercase();
+ EngineMan.upgradeTargetIfNecessary(target);
+
// Look for the plugin
const Plugin *plugin = nullptr;
EngineMan.findTarget(target, &plugin);