diff options
author | Max Horn | 2003-10-17 12:18:58 +0000 |
---|---|---|
committer | Max Horn | 2003-10-17 12:18:58 +0000 |
commit | 116dbee1fc1a7d8d2c22abf886d0b8e8fd93db53 (patch) | |
tree | 0960f331e9b7c2d5b59f896b4ab9cc2959417682 | |
parent | 79e681282e7c5e84d8d6bbd595bce455ebf4e8f1 (diff) | |
download | scummvm-rg350-116dbee1fc1a7d8d2c22abf886d0b8e8fd93db53.tar.gz scummvm-rg350-116dbee1fc1a7d8d2c22abf886d0b8e8fd93db53.tar.bz2 scummvm-rg350-116dbee1fc1a7d8d2c22abf886d0b8e8fd93db53.zip |
factored out the game detection code into the Plugin class; this is the first step towards allowing more powerful, plugin specific detection code; also, moved the Plugin GameSettings APIs to a slightly higher level
svn-id: r10858
-rw-r--r-- | base/gameDetector.cpp | 26 | ||||
-rw-r--r-- | base/gameDetector.h | 3 | ||||
-rw-r--r-- | base/plugins.cpp | 112 | ||||
-rw-r--r-- | base/plugins.h | 12 | ||||
-rw-r--r-- | gui/launcher.cpp | 91 | ||||
-rw-r--r-- | gui/launcher.h | 2 |
6 files changed, 123 insertions, 123 deletions
diff --git a/base/gameDetector.cpp b/base/gameDetector.cpp index 9c8dd4d8e2..d3a2ecc5a9 100644 --- a/base/gameDetector.cpp +++ b/base/gameDetector.cpp @@ -240,41 +240,39 @@ void GameDetector::list_games() { // 2) List all available (configured) targets, including those with custom // names, e.g. "monkey-mac", "skycd-demo", ... const PluginList &plugins = PluginManager::instance().getPlugins(); - const GameSettings *v; printf("Game Full Title \n" "---------------- ------------------------------------------------------\n"); PluginList::ConstIterator iter = plugins.begin(); for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - v = (*iter)->getSupportedGames(); - while (v->gameName && v->description) { + GameList list = (*iter)->getSupportedGames(); + for (GameList::Iterator v = list.begin(); v != list.end(); ++v) { #if 1 printf("%-17s%-56s\n", v->gameName, v->description); #else const char *config = (g_config->has_domain(v->gameName)) ? "Yes" : ""; printf("%-17s%-56s%s\n", v->gameName, v->description, config); #endif - v++; } } } -const GameSettings *GameDetector::findGame(const String &gameName, const Plugin **plugin) const { +GameSettings GameDetector::findGame(const String &gameName, const Plugin **plugin) { // Find the GameSettings for this target - const GameSettings *target; const PluginList &plugins = PluginManager::instance().getPlugins(); + GameSettings result = {NULL, NULL, 0, 0, MDT_NONE, 0, NULL}; PluginList::ConstIterator iter = plugins.begin(); for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - target = (*iter)->findGame(gameName.c_str()); - if (target) { + result = (*iter)->findGame(gameName.c_str()); + if (result.gameName) { if (plugin) *plugin = *iter; - return target; + break; } } - return 0; + return result; } void GameDetector::parseCommandLine(int argc, char **argv) { @@ -454,7 +452,7 @@ void GameDetector::parseCommandLine(int argc, char **argv) { // To verify this, check if there is either a game domain (i.e // a configured target) matching this argument, or if we can // find any target with that name. - if (i == (argc - 1) && (ConfMan.hasGameDomain(s) || findGame(s))) { + if (i == (argc - 1) && (ConfMan.hasGameDomain(s) || findGame(s).gameName)) { setTarget(s); } else { if (current_option == NULL) @@ -543,7 +541,6 @@ int GameDetector::parseMusicDriver(const String &str) { } bool GameDetector::detectGame() { - const GameSettings *target; String realGame; if (ConfMan.hasKey("gameid")) @@ -552,10 +549,9 @@ bool GameDetector::detectGame() { realGame = _targetName; printf("Looking for %s\n", realGame.c_str()); - target = findGame(realGame, &_plugin); + _game = findGame(realGame, &_plugin); - if (target) { - _game = *target; + if (_game.gameName) { printf("Trying to start game '%s'\n", _game.description); return true; } else { diff --git a/base/gameDetector.h b/base/gameDetector.h index fcb127036f..81213a3836 100644 --- a/base/gameDetector.h +++ b/base/gameDetector.h @@ -23,6 +23,7 @@ #ifndef GAMEDETECTOR_H #define GAMEDETECTOR_H +#include "base/plugins.h" #include "common/str.h" class Engine; @@ -117,7 +118,7 @@ public: static Language parseLanguage(const String &s); static Platform parsePlatform(const String &s); - const GameSettings *findGame(const String &gameName, const Plugin **plugin = NULL) const; + static GameSettings findGame(const String &gameName, const Plugin **plugin = NULL); protected: bool detectGame(void); diff --git a/base/plugins.cpp b/base/plugins.cpp index 518b588a69..cd777e365d 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -20,12 +20,13 @@ * */ +#include "backends/fs/fs.h" #include "base/gameDetector.h" #include "base/plugins.h" #include "base/engine.h" #include "common/util.h" - +/** Type of factory functions which make new Engine objects. */ typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst); @@ -74,47 +75,95 @@ extern Engine *Engine_QUEEN_create(GameDetector *detector, OSystem *syst); #pragma mark - -int Plugin::countSupportedGames() const { - const GameSettings *target = getSupportedGames(); - int count; - for (count = 0; target->gameName; target++, count++) - ; - return count; -} - -const GameSettings *Plugin::findGame(const char *gameName) const { - // Find the GameSettings for this target - const GameSettings *target = getSupportedGames(); +GameSettings Plugin::findGame(const char *gameName) const { + // Find the GameSettings for this game assert(gameName); - while (target->gameName) { - if (!scumm_stricmp(target->gameName, gameName)) { - return target; + GameList games = getSupportedGames(); + GameSettings result = {NULL, NULL, 0, 0, MDT_NONE, 0, NULL}; + for (GameList::Iterator g = games.begin(); g != games.end(); ++g) { + if (!scumm_stricmp(g->gameName, gameName)) { + result = *g; + break; } - target++; } - return 0; + return result; } +/** + * Auxillary class to simplify transition from old plugin interface to the + * new one (which provides an API for game detection). To be removed once + * the transition is complete. + */ +class GameSettingsPlugin : public Plugin { + const GameSettings *_games; +public: + GameSettingsPlugin(const GameSettings *games) : _games(games) { } + GameList getSupportedGames() const { + GameList games; + const GameSettings *g; + for (g = _games; g->gameName; ++g) { + games.push_back(*g); + } + return games; + } + GameList detectGames(const FSList &fslist) const { + GameList games; + const GameSettings *g; + char detectName[128]; + char detectName2[128]; + char detectName3[128]; + + for (g = _games; g->gameName; ++g) { + // Determine the 'detectname' for this game, that is, the name of a + // file that *must* be presented if the directory contains the data + // for this game. For example, FOA requires atlantis.000 + if (g->detectname) { + strcpy(detectName, g->detectname); + strcpy(detectName2, g->detectname); + strcat(detectName2, "."); + detectName3[0] = '\0'; + } else { + strcpy(detectName, g->gameName); + strcpy(detectName2, g->gameName); + strcpy(detectName3, g->gameName); + strcat(detectName, ".000"); + if (g->version >= 7) { + strcat(detectName2, ".la0"); + } else + strcat(detectName2, ".sm0"); + strcat(detectName3, ".he0"); + } + + // Iterate over all files in the given directory + for (FSList::ConstIterator file = fslist.begin(); file != fslist.end(); ++file) { + const char *gameName = file->displayName().c_str(); + + if ((0 == scumm_stricmp(detectName, gameName)) || + (0 == scumm_stricmp(detectName2, gameName)) || + (0 == scumm_stricmp(detectName3, gameName))) { + // Match found, add to list of candidates, then abort inner loop. + games.push_back(*g); + break; + } + } + } + return games; + } +}; #pragma mark - -class StaticPlugin : public Plugin { +class StaticPlugin : public GameSettingsPlugin { const char *_name; - const GameSettings *_targets; - int _targetCount; EngineFactory _ef; public: - StaticPlugin(const char *name, const GameSettings *targets, EngineFactory ef) - : _name(name), _targets(targets), _ef(ef) { - _targetCount = Plugin::countSupportedGames(); + StaticPlugin(const char *name, const GameSettings *games, EngineFactory ef) + : GameSettingsPlugin(games), _name(name), _ef(ef) { } const char *getName() const { return _name; } - int countSupportedGames() const { return _targetCount; } - const GameSettings *getSupportedGames() const { return _targets; } - Engine *createInstance(GameDetector *detector, OSystem *syst) const { return (*_ef)(detector, syst); } @@ -126,26 +175,21 @@ public: #ifdef DYNAMIC_MODULES -class DynamicPlugin : public Plugin { +class DynamicPlugin : public GameSettingsPlugin { void *_dlHandle; Common::String _filename; Common::String _name; - const GameSettings *_targets; - int _targetCount; EngineFactory _ef; void *findSymbol(const char *symbol); public: DynamicPlugin(const char *filename) - : _dlHandle(0), _filename(filename), _targets(0), _targetCount(0), _ef(0) {} + : GameSettingsPlugin(0), _dlHandle(0), _filename(filename), _ef(0) {} const char *getName() const { return _name.c_str(); } - int countSupportedGames() const { return _targetCount; } - const GameSettings *getSupportedGames() const { return _targets; } - Engine *createInstance(GameDetector *detector, OSystem *syst) const { assert(_ef); return (*_ef)(detector, syst); @@ -199,7 +243,7 @@ bool DynamicPlugin::loadPlugin() { unloadPlugin(); return false; } - _targets = targetListFunc(); + _games = targetListFunc(); // Finally, retrieve the factory function _ef = (EngineFactory)findSymbol("PLUGIN_createEngine"); diff --git a/base/plugins.h b/base/plugins.h index 77b5e90708..eb380ec3a6 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -27,16 +27,19 @@ #include "common/singleton.h" class Engine; +class FSList; class GameDetector; class OSystem; struct GameSettings; +/** List of GameSettings- */ +typedef Common::List<GameSettings> GameList; + /** * Abstract base class for the plugin system. * Subclasses for this can be used to wrap both static and dynamic * plugins. */ -//typedef Common::List<GameSettings> GameList; class Plugin { public: virtual ~Plugin() {} @@ -47,10 +50,9 @@ public: virtual const char *getName() const = 0; virtual int getVersion() const { return 0; } // TODO! - virtual int countSupportedGames() const; - virtual const GameSettings *getSupportedGames() const = 0; - virtual const GameSettings *findGame(const char *gameName) const; - //virtual GameList detectGames(const FSList &fslist) const; + virtual GameList getSupportedGames() const = 0; + virtual GameSettings findGame(const char *gameName) const; + virtual GameList detectGames(const FSList &fslist) const = 0; virtual Engine *createInstance(GameDetector *detector, OSystem *syst) const = 0; }; diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 322a7fd839..537f482d53 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -50,8 +50,6 @@ enum { kQuitCmd = 'QUIT' }; -typedef Common::List<const GameSettings *> GameList; - /* * A dialog that allows the user to edit a config game entry. * TODO: add widgets for some/all of the following @@ -80,7 +78,7 @@ class EditGameDialog : public Dialog { typedef Common::String String; typedef Common::StringList StringList; public: - EditGameDialog(NewGui *gui, const String &domain, const GameSettings *target); + EditGameDialog(NewGui *gui, const String &domain, GameSettings target); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); @@ -92,19 +90,19 @@ protected: CheckboxWidget *_amigaCheckbox; }; -EditGameDialog::EditGameDialog(NewGui *gui, const String &domain, const GameSettings *target) +EditGameDialog::EditGameDialog(NewGui *gui, const String &domain, GameSettings target) : Dialog(gui, 8, 50, 320 - 2 * 8, 200 - 2 * 40), _domain(domain) { // Determine the description string String description(ConfMan.get("description", domain)); - if (description.isEmpty() && target) { - description = target->description; + if (description.isEmpty() && target.description) { + description = target.description; } // Determine whether this is a SCUMM game // FIXME: This check is evil, as it requires us to hard code GIDs. - bool isScumm = target && (GID_SCUMM_FIRST <= target->id && target->id <= GID_SCUMM_LAST); + bool isScumm = (GID_SCUMM_FIRST <= target.id && target.id <= GID_SCUMM_LAST); // Label & edit widget for the game ID @@ -247,9 +245,9 @@ void LauncherDialog::updateListing() { if (name.isEmpty()) name = iter->_key; if (description.isEmpty()) { - const GameSettings *v = _detector.findGame(name); - if (v && v->description) - description = v->description; + GameSettings g = _detector.findGame(name); + if (g.description) + description = g.description; } if (!name.isEmpty() && !description.isEmpty()) { @@ -270,61 +268,20 @@ void LauncherDialog::updateListing() { /* * Return a list of all games which might be the game in the specified directory. */ -GameList findGame(FilesystemNode *dir) { - GameList list; +GameList detectGames(FilesystemNode *dir) { + GameList detectedGames; FSList *files = dir->listDir(FilesystemNode::kListFilesOnly); - const int size = files->size(); - char detectName[128]; - char detectName2[128]; - char detectName3[128]; // Iterate over all known games and for each check if it might be // the game in the presented directory. const PluginList &plugins = PluginManager::instance().getPlugins(); - int p; - for (p = 0; p < plugins.size(); p++) { - const GameSettings *v = plugins[p]->getSupportedGames(); - while (v->gameName && v->description) { - - // Determine the 'detectname' for this game, that is, the name of a - // file that *must* be presented if the directory contains the data - // for this game. For example, FOA requires atlantis.000 - if (v->detectname) { - strcpy(detectName, v->detectname); - strcpy(detectName2, v->detectname); - strcat(detectName2, "."); - detectName3[0] = '\0'; - } else { - strcpy(detectName, v->gameName); - strcpy(detectName2, v->gameName); - strcpy(detectName3, v->gameName); - strcat(detectName, ".000"); - if (v->version >= 7) { - strcat(detectName2, ".la0"); - } else - strcat(detectName2, ".sm0"); - strcat(detectName3, ".he0"); - } - - // Iterate over all files in the given directory - for (int i = 0; i < size; i++) { - const char *gameName = (*files)[i].displayName().c_str(); - - if ((0 == scumm_stricmp(detectName, gameName)) || - (0 == scumm_stricmp(detectName2, gameName)) || - (0 == scumm_stricmp(detectName3, gameName))) { - // Match found, add to list of candidates, then abort inner loop. - list.push_back(v); - break; - } - } - - v++; - } + PluginList::ConstIterator iter = plugins.begin(); + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { + detectedGames.push_back((*iter)->detectGames(*files)); } - return list; + return detectedGames; } void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { @@ -349,8 +306,8 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat // ...so let's determine a list of candidates, games that // could be contained in the specified directory. - GameList candidates = findGame(dir); - const GameSettings *v = 0; + GameList candidates = detectGames(dir); + GameSettings result = {NULL, NULL, 0, 0, MDT_NONE, 0, NULL}; if (candidates.isEmpty()) { // No game was found in the specified directory @@ -358,25 +315,25 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat alert.runModal(); } else if (candidates.size() == 1) { // Exact match - v = candidates[0]; + result = candidates[0]; } else { // Display the candidates to the user and let her/him pick one StringList list; int i; for (i = 0; i < candidates.size(); i++) - list.push_back(candidates[i]->description); + list.push_back(candidates[i].description); ChooserDialog dialog(_gui, "Pick the game:", list); i = dialog.runModal(); if (0 <= i && i < candidates.size()) - v = candidates[i]; + result = candidates[i]; } - if (v != 0) { + if (result.gameName != 0) { // The auto detector or the user made a choice. // Pick a domain name which does not yet exist (after all, we // are *adding* a game to the config, not replacing). - String domain(v->gameName); + String domain(result.gameName); if (ConfMan.hasGameDomain(domain)) { char suffix = 'a'; domain += suffix; @@ -385,13 +342,13 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat suffix++; domain += suffix; } - ConfMan.set("gameid", v->gameName, domain); - ConfMan.set("description", v->description, domain); + ConfMan.set("gameid", result.gameName, domain); + ConfMan.set("description", result.description, domain); } ConfMan.set("path", dir->path(), domain); // Display edit dialog for the new entry - EditGameDialog editDialog(_gui, domain, v); + EditGameDialog editDialog(_gui, domain, result); if (editDialog.runModal()) { // User pressed OK, so make changes permanent diff --git a/gui/launcher.h b/gui/launcher.h index 4aae8bd9e3..f65c7cb1a4 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -21,7 +21,7 @@ #ifndef LAUNCHER_DIALOG_H #define LAUNCHER_DIALOG_H -#include "dialog.h" +#include "gui/dialog.h" #include "common/str.h" #include "common/list.h" |