aboutsummaryrefslogtreecommitdiff
path: root/base/options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'base/options.cpp')
-rw-r--r--base/options.cpp193
1 files changed, 166 insertions, 27 deletions
diff --git a/base/options.cpp b/base/options.cpp
index 315bc3a8a4..6988ee54b0 100644
--- a/base/options.cpp
+++ b/base/options.cpp
@@ -48,6 +48,12 @@
#define DEFAULT_SAVE_PATH "Savegames"
#endif
+#define DETECTOR_TESTING_HACK
+
+#ifdef DETECTOR_TESTING_HACK
+#include "backends/fs/fs.h"
+#endif
+
namespace Base {
static const char USAGE_STRING[] =
@@ -297,19 +303,20 @@ void registerDefaults() {
settings[longCmd] = option;
// Use this for options which never have a value, i.e. for 'commands', like "--help".
-#define DO_OPTION_CMD(shortCmd, longCmd) \
+#define DO_COMMAND(shortCmd, longCmd) \
if (isLongCmd ? (!strcmp(s+2, longCmd)) : (tolower(s[1]) == shortCmd)) { \
s += 2; \
if (isLongCmd) \
s += sizeof(longCmd) - 1; \
- if (*s != '\0') goto unknownOption;
+ if (*s != '\0') goto unknownOption; \
+ return longCmd;
-#define DO_LONG_OPTION_OPT(longCmd, d) DO_OPTION_OPT(0, longCmd, d)
-#define DO_LONG_OPTION(longCmd) DO_OPTION(0, longCmd)
-#define DO_LONG_OPTION_INT(longCmd) DO_OPTION_INT(0, longCmd)
-#define DO_LONG_OPTION_BOOL(longCmd) DO_OPTION_BOOL(0, longCmd)
-#define DO_LONG_OPTION_CMD(longCmd) DO_OPTION_CMD(0, longCmd)
+#define DO_LONG_OPTION_OPT(longCmd, d) DO_OPTION_OPT(0, longCmd, d)
+#define DO_LONG_OPTION(longCmd) DO_OPTION(0, longCmd)
+#define DO_LONG_OPTION_INT(longCmd) DO_OPTION_INT(0, longCmd)
+#define DO_LONG_OPTION_BOOL(longCmd) DO_OPTION_BOOL(0, longCmd)
+#define DO_LONG_COMMAND(longCmd) DO_COMMAND(0, longCmd)
// End an option handler
#define END_OPTION \
@@ -346,29 +353,20 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
bool isLongCmd = (s[0] == '-' && s[1] == '-');
- DO_OPTION_CMD('h', "help")
- printf(HELP_STRING, argv[0]);
- exit(0);
+ DO_COMMAND('h', "help")
END_OPTION
- DO_OPTION_CMD('v', "version")
- printf("%s\n", gScummVMFullVersion);
- printf("Features compiled in: %s\n", gScummVMFeatures);
- exit(0);
+ DO_COMMAND('v', "version")
END_OPTION
- DO_OPTION_CMD('t', "list-targets")
- return "list-targets";
+ DO_COMMAND('t', "list-targets")
END_OPTION
- DO_OPTION_CMD('z', "list-games")
- return "list-games";
+ DO_COMMAND('z', "list-games")
END_OPTION
-
- // HACK FIXME TODO: This switch is intentionally *not* documented!
- DO_LONG_OPTION_CMD("test-detector")
- return "test-detector";
+ // HACK FIXME TODO: This command is intentionally *not* documented!
+ DO_LONG_COMMAND("test-detector")
END_OPTION
@@ -520,17 +518,156 @@ unknownOption:
return Common::String::emptyString;
}
+/** List all supported game IDs, i.e. all games which any loaded plugin supports. */
+static void listGames() {
+ const PluginList &plugins = PluginManager::instance().getPlugins();
+
+ printf("Game ID Full Title \n"
+ "-------------------- ------------------------------------------------------\n");
+
+ PluginList::const_iterator iter = plugins.begin();
+ for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
+ GameList list = (*iter)->getSupportedGames();
+ for (GameList::iterator v = list.begin(); v != list.end(); ++v) {
+ printf("%-20s %s\n", v->gameid.c_str(), v->description.c_str());
+ }
+ }
+}
+
+/** List all targets which are configured in the config file. */
+static void listTargets() {
+ using namespace Common;
+ const ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
+
+ printf("Target Description \n"
+ "-------------------- ------------------------------------------------------\n");
+
+ ConfigManager::DomainMap::const_iterator iter = domains.begin();
+ for (iter = domains.begin(); iter != domains.end(); ++iter) {
+ Common::String name(iter->_key);
+ Common::String description(iter->_value.get("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.
+ Common::String gameid(name);
+ GameDescriptor g = Base::findGame(gameid);
+ if (g.description.size() > 0)
+ description = g.description;
+ }
+
+ printf("%-20s %s\n", name.c_str(), description.c_str());
+ }
+}
+
+#ifdef DETECTOR_TESTING_HACK
+static void runDetectorTest() {
+ // HACK: The following code can be used to test the detection code of our
+ // engines. Basically, it loops over all targets, and calls the detector
+ // for the given path. It then prints out the result and also checks
+ // whether the result agrees with the settings of the target.
+
+ const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
+ Common::ConfigManager::DomainMap::const_iterator iter = domains.begin();
+ int success = 0, failure = 0;
+ for (iter = domains.begin(); iter != domains.end(); ++iter) {
+ Common::String name(iter->_key);
+ Common::String gameid(iter->_value.get("gameid"));
+ Common::String path(iter->_value.get("path"));
+ printf("Looking at target '%s', gameid '%s', path '%s' ...\n",
+ name.c_str(), gameid.c_str(), path.c_str());
+ if (path.empty()) {
+ printf(" ... no path specified, skipping\n");
+ continue;
+ }
+ if (gameid.empty()) {
+ gameid = name;
+ }
+
+ FilesystemNode dir(path);
+ FSList files;
+ if (!dir.listDir(files, FilesystemNode::kListAll)) {
+ printf(" ... invalid path, skipping\n");
+ continue;
+ }
+
+ DetectedGameList candidates(PluginManager::instance().detectGames(files));
+ bool gameidDiffers = false;
+ for (DetectedGameList::iterator x = candidates.begin(); x != candidates.end(); ++x) {
+ gameidDiffers |= scumm_stricmp(gameid.c_str(), x->gameid.c_str());
+ }
+
+ if (candidates.empty()) {
+ printf(" FAILURE: No games detected\n");
+ failure++;
+ } else if (candidates.size() > 1) {
+ if (gameidDiffers) {
+ printf(" FAILURE: Multiple games detected, some/all with wrong gameid\n");
+ } else {
+ printf(" FAILURE: Multiple games detected, but all have the same gameid\n");
+ }
+ failure++;
+ } else if (gameidDiffers) {
+ printf(" FAILURE: Wrong gameid detected\n");
+ failure++;
+ } else {
+ printf(" SUCCESS: Game was detected correctly\n");
+ success++;
+ }
+
+ for (DetectedGameList::iterator x = candidates.begin(); x != candidates.end(); ++x) {
+ printf(" gameid '%s', desc '%s', language '%s', platform '%s'\n",
+ x->gameid.c_str(),
+ x->description.c_str(),
+ Common::getLanguageCode(x->language),
+ Common::getPlatformCode(x->platform));
+ }
+ }
+ int total = domains.size();
+ printf("Detector test run: %d fail, %d success, %d skipped, out of %d\n",
+ failure, success, total - failure - success, total);
+}
+#endif
+
+bool processSettings(Common::String &command, Common::StringMap &settings) {
+
+ // Handle commands passed via the command line (like --list-targets and
+ // --list-games). This must be done after the config file and the plugins
+ // have been loaded.
+ // FIXME: The way are are doing this is rather arbitrary at this time.
+ // E.g. --version and --help are very similar, but are still handled
+ // inside parseCommandLine. This should be unified.
+ if (command == "list-targets") {
+ listTargets();
+ return false;
+ } else if (command == "list-games") {
+ listGames();
+ return false;
+ } else if (command == "version") {
+ printf("%s\n", gScummVMFullVersion);
+ printf("Features compiled in: %s\n", gScummVMFeatures);
+ return false;
+ } else if (command == "help") {
+ printf(HELP_STRING, s_appName.c_str());
+ return false;
+ }
+#ifdef DETECTOR_TESTING_HACK
+ else if (command == "test-detector") {
+ runDetectorTest();
+ return false;
+ }
+#endif
-void processSettings(Common::String &target, Common::StringMap &settings) {
// If a target was specified, check whether there is either a game
// domain (i.e. a target) matching this argument, or alternatively
// whether there is a gameid matching that name.
- if (!target.empty()) {
- if (ConfMan.hasGameDomain(target) || Base::findGame(target).gameid.size() > 0) {
- Base::setTarget(target);
+ if (!command.empty()) {
+ if (ConfMan.hasGameDomain(command) || Base::findGame(command).gameid.size() > 0) {
+ Base::setTarget(command);
} else {
- usage("Unrecognized game target '%s'", target.c_str());
+ usage("Unrecognized game target '%s'", command.c_str());
}
}
@@ -563,6 +700,8 @@ void processSettings(Common::String &target, Common::StringMap &settings) {
// Store it into ConfMan.
ConfMan.set(key, value, Common::ConfigManager::kTransientDomain);
}
+
+ return true;
}
} // End of namespace Base