Added an experimental '--upgrade-targets' option (to be refined; and possibly hooked to the GUI eventually). This updates the guioptions,platform and lang for all your targets (and with a source change, also the descriptions)

svn-id: r41332
This commit is contained in:
Max Horn 2009-06-07 12:47:10 +00:00
parent ed44e68f9d
commit 985bc454b2
2 changed files with 132 additions and 1 deletions

View file

@ -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