aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/commandLine.cpp132
-rw-r--r--common/config-manager.h1
2 files changed, 132 insertions, 1 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index b58c3d320d..e3d3437c73 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -37,6 +37,7 @@
#include "gui/ThemeEngine.h"
#define DETECTOR_TESTING_HACK
+#define UPGRADE_ALL_TARGETS_HACK
namespace Base {
@@ -322,9 +323,17 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_COMMAND('z', "list-games")
END_OPTION
+#ifdef DETECTOR_TESTING_HACK
// HACK FIXME TODO: This command is intentionally *not* documented!
DO_LONG_COMMAND("test-detector")
END_OPTION
+#endif
+
+#ifdef UPGRADE_ALL_TARGETS_HACK
+ // HACK FIXME TODO: This command is intentionally *not* documented!
+ DO_LONG_COMMAND("upgrade-targets")
+ END_OPTION
+#endif
DO_LONG_OPTION("list-saves")
// FIXME: Need to document this.
@@ -685,7 +694,7 @@ static void runDetectorTest() {
if (gameidDiffers) {
printf(" WARNING: Multiple games detected, some/all with wrong gameid\n");
} else {
- printf(" WARNING: Multiple games detected, but all have the same gameid\n");
+ printf(" WARNING: Multiple games detected, but all have matching gameid\n");
}
failure++;
} else if (gameidDiffers) {
@@ -710,6 +719,121 @@ static void runDetectorTest() {
}
#endif
+#ifdef UPGRADE_ALL_TARGETS_HACK
+void upgradeTargets() {
+ // HACK: The following upgrades all your targets to the latest and
+ // greatest. Right now that means updating the guioptions and (optionally)
+ // also the game descriptions.
+ // Basically, it loops over all targets, and calls the detector for the
+ // given path. It then compares the result with the settings of the target.
+ // If the basics seem to match, it updates the guioptions.
+
+ printf("Upgrading all your existing targets\n");
+
+ Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
+ Common::ConfigManager::DomainMap::iterator iter = domains.begin();
+ for (iter = domains.begin(); iter != domains.end(); ++iter) {
+ Common::ConfigManager::Domain &dom = iter->_value;
+ Common::String name(iter->_key);
+ Common::String gameid(dom.get("gameid"));
+ Common::String path(dom.get("path"));
+ printf("Looking at target '%s', gameid '%s' ...\n",
+ name.c_str(), gameid.c_str());
+ if (path.empty()) {
+ printf(" ... no path specified, skipping\n");
+ continue;
+ }
+ if (gameid.empty()) {
+ gameid = name;
+ }
+ gameid.toLowercase(); // TODO: Is this paranoia? Maybe we should just assume all lowercase, always?
+
+ Common::FSNode dir(path);
+ Common::FSList files;
+ if (!dir.getChildren(files, Common::FSNode::kListAll)) {
+ printf(" ... invalid path, skipping\n");
+ continue;
+ }
+
+ Common::Language lang = Common::parseLanguage(dom.get("language"));
+ Common::Platform plat = Common::parsePlatform(dom.get("platform"));
+ Common::String desc(dom.get("description"));
+
+ GameList candidates(EngineMan.detectGames(files));
+ GameDescriptor *g = 0;
+
+ // We proceed as follows:
+ // * If detection failed to produce candidates, skip.
+ // * If there is a unique detector match, trust it.
+ // * If there are multiple match, run over them comparing gameid, language and platform.
+ // If we end up with a unique match, use it. Otherwise, skip.
+ if (candidates.size() == 0) {
+ printf(" ... failed to detect game, skipping\n");
+ continue;
+ }
+ if (candidates.size() > 1) {
+ // Scan over all candidates, check if there is a unique match for gameid, language and platform
+ GameList::iterator x;
+ int matchesFound = 0;
+ for (x = candidates.begin(); x != candidates.end(); ++x) {
+ if (x->gameid() == gameid && x->language() == lang && x->platform() == plat) {
+ matchesFound++;
+ g = &(*x);
+ }
+ }
+ if (matchesFound != 1) {
+ printf(" ... detected multiple games, could not establish unique match, skipping\n");
+ continue;
+ }
+ } else {
+ // Unique match -> use it
+ g = &candidates[0];
+ }
+
+ // 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)
+ dom["gameid"] = g->gameid();
+
+ // Always set the GUI options. The user should not modify them, and engines might
+ // gain more features over time, so we want to keep this list up-to-date.
+ if (g->contains("guioptions")) {
+ printf(" -> update guioptions to '%s'\n", (*g)["guioptions"].c_str());
+ dom["guioptions"] = (*g)["guioptions"];
+ } else if (dom.contains("guioptions")) {
+ dom.erase("guioptions");
+ }
+
+ // Update the language setting but only if none has been set yet.
+ if (lang == Common::UNK_LANG && g->language() != Common::UNK_LANG) {
+ printf(" -> set lang to '%s'\n", Common::getLanguageCode(g->language()));
+ dom["language"] = (*g)["language"];
+ }
+
+ // Update the platform setting but only if none has been set yet.
+ if (plat == Common::kPlatformUnknown && g->platform() != Common::kPlatformUnknown) {
+ printf(" -> set plat to '%s'\n", Common::getPlatformCode(g->platform()));
+ dom["platform"] = (*g)["platform"];
+ }
+
+ // TODO: We could also update the description. But not everybody will want that.
+ // Esp. because for some games (e.g. the combined Zak/Loom FM-TOWNS demo etc.)
+ // 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()) {
+ printf(" -> update desc from '%s' to\n '%s' ?\n", desc.c_str(), g->description().c_str());
+ dom["description"] = (*g)["description"];
+ }
+#endif
+ }
+
+ // Finally, save our changes to disk
+ ConfMan.flushToDisk();
+}
+#endif
+
#else // DISABLE_COMMAND_LINE
@@ -754,6 +878,12 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
return false;
}
#endif
+#ifdef UPGRADE_ALL_TARGETS_HACK
+ else if (command == "upgrade-targets") {
+ upgradeTargets();
+ return false;
+ }
+#endif
#endif // DISABLE_COMMAND_LINE
diff --git a/common/config-manager.h b/common/config-manager.h
index d86431be2f..bc734dbdc3 100644
--- a/common/config-manager.h
+++ b/common/config-manager.h
@@ -155,6 +155,7 @@ public:
void renameGameDomain(const String &oldName, const String &newName);
bool hasGameDomain(const String &domName) const;
const DomainMap & getGameDomains() const { return _gameDomains; }
+ DomainMap & getGameDomains() { return _gameDomains; }
private:
friend class Singleton<SingletonBaseType>;