diff options
author | Max Horn | 2003-10-17 23:16:53 +0000 |
---|---|---|
committer | Max Horn | 2003-10-17 23:16:53 +0000 |
commit | 0694eed27393ee7d1cbeccd20e8641fa261f5642 (patch) | |
tree | f050bac8eda4b451100bffbc6aebf416070d7f7d /base | |
parent | 6eb03982170a625063c1e8be57e581a7f10d4cc9 (diff) | |
download | scummvm-rg350-0694eed27393ee7d1cbeccd20e8641fa261f5642.tar.gz scummvm-rg350-0694eed27393ee7d1cbeccd20e8641fa261f5642.tar.bz2 scummvm-rg350-0694eed27393ee7d1cbeccd20e8641fa261f5642.zip |
moved game detection code out to the plugins
svn-id: r10882
Diffstat (limited to 'base')
-rw-r--r-- | base/plugins.cpp | 204 | ||||
-rw-r--r-- | base/plugins.h | 41 |
2 files changed, 105 insertions, 140 deletions
diff --git a/base/plugins.cpp b/base/plugins.cpp index cd777e365d..d64593d952 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -29,6 +29,10 @@ /** Type of factory functions which make new Engine objects. */ typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst); +typedef const char *(*NameFunc)(); +typedef GameList (*TargetListFunc)(); +typedef GameList (*DetectFunc)(const FSList &fslist); + #ifdef DYNAMIC_MODULES @@ -38,37 +42,6 @@ typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst); #error No support for loading plugins on non-unix systems at this point! #endif -#else - -// Factory functions => no need to include the specific classes -// in this header. This serves two purposes: -// 1) Clean seperation from the game modules (scumm, simon) and the generic code -// 2) Faster (compiler doesn't have to parse lengthy header files) -#ifndef DISABLE_SCUMM -extern const GameSettings *Engine_SCUMM_targetList(); -extern Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst); -#endif - -#ifndef DISABLE_SIMON -extern Engine *Engine_SIMON_create(GameDetector *detector, OSystem *syst); -extern const GameSettings *Engine_SIMON_targetList(); -#endif - -#ifndef DISABLE_SKY -extern const GameSettings *Engine_SKY_targetList(); -extern Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst); -#endif - -#ifndef DISABLE_SWORD2 -extern const GameSettings *Engine_SWORD2_targetList(); -extern Engine *Engine_SWORD2_create(GameDetector *detector, OSystem *syst); -#endif - -#ifndef DISABLE_QUEEN -extern const GameSettings *Engine_QUEEN_targetList(); -extern Engine *Engine_QUEEN_create(GameDetector *detector, OSystem *syst); -#endif - #endif @@ -89,66 +62,21 @@ GameSettings Plugin::findGame(const char *gameName) const { return result; } + +#pragma mark - + + /** * 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; +private: + GameList _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; - } + GameSettingsPlugin(GameList games) : _games(games) { } + GameList getSupportedGames() const { return _games; } }; #pragma mark - @@ -157,9 +85,10 @@ public: class StaticPlugin : public GameSettingsPlugin { const char *_name; EngineFactory _ef; + DetectFunc _df; public: - StaticPlugin(const char *name, const GameSettings *games, EngineFactory ef) - : GameSettingsPlugin(games), _name(name), _ef(ef) { + StaticPlugin(const char *name, GameList games, EngineFactory ef, DetectFunc df) + : GameSettingsPlugin(games), _name(name), _ef(ef), _df(df) { } const char *getName() const { return _name; } @@ -167,6 +96,10 @@ public: Engine *createInstance(GameDetector *detector, OSystem *syst) const { return (*_ef)(detector, syst); } + + GameList detectGames(const FSList &fslist) const { + return (*_df)(fslist); + } }; @@ -181,12 +114,13 @@ class DynamicPlugin : public GameSettingsPlugin { Common::String _name; EngineFactory _ef; + DetectFunc _df; void *findSymbol(const char *symbol); public: DynamicPlugin(const char *filename) - : GameSettingsPlugin(0), _dlHandle(0), _filename(filename), _ef(0) {} + : GameSettingsPlugin(0), _dlHandle(0), _filename(filename), _ef(0), _df(0) {} const char *getName() const { return _name.c_str(); } @@ -195,6 +129,11 @@ public: return (*_ef)(detector, syst); } + GameList detectGames(const FSList &fslist) const { + assert(_df); + return (*_df)(fslist); + } + bool loadPlugin(); void unloadPlugin(); }; @@ -217,9 +156,6 @@ void *DynamicPlugin::findSymbol(const char *symbol) { #endif } -typedef const char *(*NameFunc)(); -typedef const GameSettings *(*TargetListFunc)(); - bool DynamicPlugin::loadPlugin() { assert(!_dlHandle); _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); @@ -238,20 +174,27 @@ bool DynamicPlugin::loadPlugin() { _name = nameFunc(); // Query the plugin for the targets it supports - TargetListFunc targetListFunc = (TargetListFunc)findSymbol("PLUGIN_getTargetList"); - if (!targetListFunc) { + TargetListFunc gameListFunc = (TargetListFunc)findSymbol("PLUGIN_getSupportedGames"); + if (!gameListFunc) { unloadPlugin(); return false; } - _games = targetListFunc(); + _games = gameListFunc(); - // Finally, retrieve the factory function + // Retrieve the factory function _ef = (EngineFactory)findSymbol("PLUGIN_createEngine"); if (!_ef) { unloadPlugin(); return false; } + // Retrieve the detector function + _df = (DetectFunc)findSymbol("PLUGIN_detectGames"); + if (!_df) { + unloadPlugin(); + return false; + } + return true; } @@ -276,29 +219,7 @@ PluginManager::~PluginManager() { } void PluginManager::loadPlugins() { -#ifndef DYNAMIC_MODULES - // "Load" the static plugins - #ifndef DISABLE_SCUMM - tryLoadPlugin(new StaticPlugin("scumm", Engine_SCUMM_targetList(), Engine_SCUMM_create)); - #endif - - #ifndef DISABLE_SIMON - tryLoadPlugin(new StaticPlugin("simon", Engine_SIMON_targetList(), Engine_SIMON_create)); - #endif - - #ifndef DISABLE_SKY - tryLoadPlugin(new StaticPlugin("sky", Engine_SKY_targetList(), Engine_SKY_create)); - #endif - - #ifndef DISABLE_SWORD2 - tryLoadPlugin(new StaticPlugin("sword2", Engine_SWORD2_targetList(), Engine_SWORD2_create)); - #endif - - #ifndef DISABLE_QUEEN - tryLoadPlugin(new StaticPlugin("queen", Engine_QUEEN_targetList(), Engine_QUEEN_create)); - #endif - -#else +#ifdef DYNAMIC_MODULES // Load dynamic plugins // TODO... this is right now just a nasty hack. // This should search one or multiple directories for all plugins it can @@ -313,26 +234,35 @@ void PluginManager::loadPlugins() { // Hence one more symbol should be exported by plugins which returns // the "ABI" version the plugin was built for, and we can compare that // to the ABI version of the executable. - #ifndef DISABLE_SCUMM - tryLoadPlugin(new DynamicPlugin("scumm/libscumm.so")); - #endif - - #ifndef DISABLE_SIMON - tryLoadPlugin(new DynamicPlugin("simon/libsimon.so")); - #endif - - #ifndef DISABLE_SKY - tryLoadPlugin(new DynamicPlugin("sky/libsky.so")); - #endif - - #ifndef DISABLE_SWORD2 - tryLoadPlugin(new DynamicPlugin("bs2/libbs2.so")); - #endif - - #ifndef DISABLE_QUEEN - tryLoadPlugin(new DynamicPlugin("queen/libqueen.so")); - #endif - + #define LOAD_MODULE(name, NAME) + tryLoadPlugin(new DynamicPlugin("scumm/lib" name ".so")); +#else + // "Loader" for the static plugins + #define LOAD_MODULE(name, NAME) \ + tryLoadPlugin(new StaticPlugin(name, Engine_##NAME##_gameList(), Engine_##NAME##_create, Engine_##NAME##_detectGames)); +#endif + + // Load all plugins. + // Right now the list is hardcoded. On the long run, of course it should + // automatically be determined. +#ifndef DISABLE_SCUMM + LOAD_MODULE("scumm", SCUMM); +#endif + +#ifndef DISABLE_SIMON + LOAD_MODULE("simon", SIMON); +#endif + +#ifndef DISABLE_SKY + LOAD_MODULE("sky", SKY); +#endif + +#ifndef DISABLE_SWORD2 + LOAD_MODULE("sword2", SWORD2); +#endif + +#ifndef DISABLE_QUEEN + LOAD_MODULE("queen", QUEEN); #endif } diff --git a/base/plugins.h b/base/plugins.h index eb380ec3a6..32946774e6 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -68,13 +68,14 @@ public: * @todo on Windows, we might need __declspec(dllexport) ? */ #ifndef DYNAMIC_MODULES -#define REGISTER_PLUGIN(name,targetListFactory,engineFactory) +#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) #else -#define REGISTER_PLUGIN(name,targetListFactory,engineFactory) \ +#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) \ extern "C" { \ const char *PLUGIN_name() { return name; } \ - const GameSettings *PLUGIN_getTargetList() { return targetListFactory(); } \ + GameList PLUGIN_getSupportedGames() { return gameListFactory(); } \ Engine *PLUGIN_createEngine(GameDetector *detector, OSystem *syst) { return engineFactory(detector, syst); } \ + GameList PLUGIN_detectGames(const FSList &fslist) { return detectGames(fslist); } } #endif @@ -107,4 +108,38 @@ public: const PluginList &getPlugins() { return _plugins; } }; + +#ifndef DYNAMIC_MODULES + +#define DECLARE_PLUGIN(name) \ + extern GameList Engine_##name##_gameList(); \ + extern Engine *Engine_##name##_create(GameDetector *detector, OSystem *syst); \ + extern GameList Engine_##name##_detectGames(const FSList &fslist); + +// Factory functions => no need to include the specific classes +// in this header. This serves two purposes: +// 1) Clean seperation from the game modules (scumm, simon) and the generic code +// 2) Faster (compiler doesn't have to parse lengthy header files) +#ifndef DISABLE_SCUMM +DECLARE_PLUGIN(SCUMM) +#endif + +#ifndef DISABLE_SIMON +DECLARE_PLUGIN(SIMON) +#endif + +#ifndef DISABLE_SKY +DECLARE_PLUGIN(SKY) +#endif + +#ifndef DISABLE_SWORD2 +DECLARE_PLUGIN(SWORD2) +#endif + +#ifndef DISABLE_QUEEN +DECLARE_PLUGIN(QUEEN) +#endif + +#endif + #endif |