diff options
-rw-r--r-- | base/plugins.cpp | 95 | ||||
-rw-r--r-- | base/plugins.h | 80 | ||||
-rw-r--r-- | common.rules | 3 | ||||
-rw-r--r-- | kyra/kyra.cpp | 2 | ||||
-rw-r--r-- | queen/queen.cpp | 2 | ||||
-rw-r--r-- | saga/saga.cpp | 2 | ||||
-rw-r--r-- | scumm/scumm.cpp | 2 | ||||
-rw-r--r-- | simon/simon.cpp | 2 | ||||
-rw-r--r-- | sky/sky.cpp | 2 | ||||
-rw-r--r-- | sword1/sword1.cpp | 2 | ||||
-rw-r--r-- | sword2/sword2.cpp | 2 |
11 files changed, 95 insertions, 99 deletions
diff --git a/base/plugins.cpp b/base/plugins.cpp index 05c9ec84b1..6f2fefb8a2 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -39,16 +39,25 @@ typedef DetectedGameList (*DetectFunc)(const FSList &fslist); #ifdef UNIX #include <dlfcn.h> -#define DYNAMIC_PLUGIN_PATH(name) (name "/" PLUGIN_PREFIX name PLUGIN_SUFFIX) +#define PLUGIN_DIRECTORY "plugins/" #else #ifdef __DC__ #include "dcloader.h" -#define DYNAMIC_PLUGIN_PATH(name) (name ".plg") +#define PLUGIN_DIRECTORY "" +#define PLUGIN_PREFIX "" +#define PLUGIN_SUFFIX ".plg" #else #error No support for loading plugins on non-unix systems at this point! #endif #endif +#else + +PluginRegistrator::PluginRegistrator(const char *name, GameList games, EngineFactory ef, DetectFunc df) + : _name(name), _ef(ef), _df(df), _games(games) { + //printf("Automatically registered plugin '%s'\n", name); +} + #endif @@ -108,7 +117,7 @@ class DynamicPlugin : public Plugin { void *findSymbol(const char *symbol); public: - DynamicPlugin(const char *filename) + DynamicPlugin(const Common::String &filename) : _dlHandle(0), _filename(filename), _ef(0), _df(0), _games() {} const char *getName() const { return _name.c_str(); } @@ -222,48 +231,56 @@ 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. - #define LOAD_MODULE(name, NAME) \ - tryLoadPlugin(new DynamicPlugin(DYNAMIC_PLUGIN_PATH(name))); -#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_SWORD1 - LOAD_MODULE("sword1", SWORD1); -#endif - -#ifndef DISABLE_SWORD2 - LOAD_MODULE("sword2", SWORD2); -#endif + // Scan for all plugins in this directory + FilesystemNode dir(PLUGIN_DIRECTORY); + FSList files(dir.listDir(FilesystemNode::kListFilesOnly)); + + for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) { + Common::String name(i->displayName()); + if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) { + tryLoadPlugin(new DynamicPlugin(i->path())); + } + } -#ifndef DISABLE_QUEEN - LOAD_MODULE("queen", QUEEN); -#endif +#else + #define LINK_PLUGIN(ID) \ + extern PluginRegistrator g_##ID##_PluginReg; \ + plugin = &g_##ID##_PluginReg; \ + tryLoadPlugin(new StaticPlugin(plugin->_name, plugin->_games, plugin->_ef, plugin->_df)); + + // "Loader" for the static plugins. + // Iterate over all registered (static) plugins and load them. + PluginRegistrator *plugin; + + #ifndef DISABLE_SIMON + LINK_PLUGIN(SCUMM) + #endif + #ifndef DISABLE_SKY + LINK_PLUGIN(SKY) + #endif + #ifndef DISABLE_SWORD1 + LINK_PLUGIN(SWORD1) + #endif + #ifndef DISABLE_SWORD2 + LINK_PLUGIN(SWORD2) + #endif + #ifndef DISABLE_SIMON + LINK_PLUGIN(SIMON) + #endif + #ifndef DISABLE_QUEEN + LINK_PLUGIN(QUEEN) + #endif + #ifndef DISABLE_SAGA + LINK_PLUGIN(SAGA) + #endif + #ifndef DISABLE_KYRA + //LINK_PLUGIN(KYRA) + #endif -#ifndef DISABLE_KYRA - LOAD_MODULE("kyra", KYRA); #endif -#ifndef DISABLE_SAGA - LOAD_MODULE("saga", SAGA); -#endif } void PluginManager::unloadPlugins() { diff --git a/base/plugins.h b/base/plugins.h index 04c90ddf0c..d8276800c8 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -78,7 +78,7 @@ public: /** - * The REGISTER_PLUGIN is a convenience macro meant to ease writing + * REGISTER_PLUGIN is a convenience macro meant to ease writing * the plugin interface for our modules. In particular, using it * makes it possible to compile the very same code in a module * both as a static and a dynamic plugin. @@ -87,17 +87,40 @@ public: * @todo on Windows, we might need __declspec(dllexport) ? */ #ifndef DYNAMIC_MODULES -#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) +#define REGISTER_PLUGIN(ID,name) \ + PluginRegistrator g_##ID##_PluginReg(name, Engine_##ID##_gameList(), Engine_##ID##_create, Engine_##ID##_detectGames); #else -#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) \ +#define REGISTER_PLUGIN(ID,name) \ extern "C" { \ const char *PLUGIN_name() { return name; } \ - GameList PLUGIN_getSupportedGames() { return gameListFactory(); } \ - Engine *PLUGIN_createEngine(GameDetector *detector, OSystem *syst) { return engineFactory(detector, syst); } \ - DetectedGameList PLUGIN_detectGames(const FSList &fslist) { return detectGames(fslist); } \ + GameList PLUGIN_getSupportedGames() { return Engine_##ID##_gameList(); } \ + Engine *PLUGIN_createEngine(GameDetector *detector, OSystem *syst) { return Engine_##ID##_create(detector, syst); } \ + DetectedGameList PLUGIN_detectGames(const FSList &fslist) { return Engine_##ID##_detectGames(fslist); } \ } #endif +#ifndef DYNAMIC_MODULES +/** + * The PluginRegistrator class is used by the static version of REGISTER_PLUGIN + * to allow static 'plugins' to register with the PluginManager. + */ +class PluginRegistrator { + friend class PluginManager; +public: + typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst); + typedef DetectedGameList (*DetectFunc)(const FSList &fslist); + +protected: + const char *_name; + EngineFactory _ef; + DetectFunc _df; + GameList _games; + +public: + PluginRegistrator(const char *name, GameList games, EngineFactory ef, DetectFunc df); +}; +#endif + /** List of plugins. */ typedef Common::Array<Plugin *> PluginList; @@ -133,49 +156,4 @@ public: }; -#ifndef DYNAMIC_MODULES - -#define DECLARE_PLUGIN(name) \ - extern GameList Engine_##name##_gameList(); \ - extern Engine *Engine_##name##_create(GameDetector *detector, OSystem *syst); \ - extern DetectedGameList Engine_##name##_detectGames(const FSList &fslist); - -// Factory functions => no need to include the specific classes -// in this header. This serves two purposes: -// 1) Clean separation 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_SWORD1 -DECLARE_PLUGIN(SWORD1) -#endif - -#ifndef DISABLE_SWORD2 -DECLARE_PLUGIN(SWORD2) -#endif - -#ifndef DISABLE_QUEEN -DECLARE_PLUGIN(QUEEN) -#endif - -#ifndef DISABLE_KYRA -DECLARE_PLUGIN(KYRA) -#endif - -#ifndef DISABLE_SAGA -DECLARE_PLUGIN(SAGA) -#endif - -#endif - #endif diff --git a/common.rules b/common.rules index 9a1e4a56ba..927e8e1cce 100644 --- a/common.rules +++ b/common.rules @@ -10,8 +10,9 @@ ifdef PLUGIN # TODO: Right now, for Mac OS X only. We either will have to generate this # via the configure script, or put in some 'if' statements to choose from # one of several build rules -PLUGIN-$(MODULE) := $(MODULE)/$(PLUGIN_PREFIX)$(MODULE)$(PLUGIN_SUFFIX) +PLUGIN-$(MODULE) := plugins/$(PLUGIN_PREFIX)$(MODULE)$(PLUGIN_SUFFIX) $(PLUGIN-$(MODULE)): $(MODULE_OBJS) $(PLUGIN_EXTRA_DEPS) + $(MKDIR) plugins $(CXX) $(PLUGIN_LDFLAGS) $(filter-out $(PLUGIN_EXTRA_DEPS),$+) -o $@ PLUGIN:= plugins: $(PLUGIN-$(MODULE)) diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index e96c861b7f..2aed994d55 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -95,7 +95,7 @@ Engine *Engine_KYRA_create(GameDetector *detector, OSystem *syst) { return new Kyra::KyraEngine(detector, syst); } -REGISTER_PLUGIN("Legend of Kyrandia Engine", Engine_KYRA_gameList, Engine_KYRA_create, Engine_KYRA_detectGames) +REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine") namespace Kyra { KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst) diff --git a/queen/queen.cpp b/queen/queen.cpp index 91446723cb..9fb5da6dd9 100644 --- a/queen/queen.cpp +++ b/queen/queen.cpp @@ -128,7 +128,7 @@ Engine *Engine_QUEEN_create(GameDetector *detector, OSystem *syst) { return new Queen::QueenEngine(detector, syst); } -REGISTER_PLUGIN("Flight of the Amazon Queen", Engine_QUEEN_gameList, Engine_QUEEN_create, Engine_QUEEN_detectGames) +REGISTER_PLUGIN(QUEEN, "Flight of the Amazon Queen") namespace Queen { diff --git a/saga/saga.cpp b/saga/saga.cpp index 7042f38b51..52882b2df5 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -105,7 +105,7 @@ Engine *Engine_SAGA_create(GameDetector *detector, OSystem *syst) { return new Saga::SagaEngine(detector, syst); } -REGISTER_PLUGIN("SAGA Engine", Engine_SAGA_gameList, Engine_SAGA_create, Engine_SAGA_detectGames) +REGISTER_PLUGIN(SAGA, "SAGA Engine") namespace Saga { diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index ecb50c0a82..6ea7a3ba0a 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -3204,7 +3204,7 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { return engine; } -REGISTER_PLUGIN("Scumm Engine", Engine_SCUMM_gameList, Engine_SCUMM_create, Engine_SCUMM_detectGames) +REGISTER_PLUGIN(SCUMM, "Scumm Engine") #ifdef __PALM_OS__ #include "scumm_globals.h" diff --git a/simon/simon.cpp b/simon/simon.cpp index cb12bce8b4..2f3147c109 100644 --- a/simon/simon.cpp +++ b/simon/simon.cpp @@ -159,7 +159,7 @@ Engine *Engine_SIMON_create(GameDetector *detector, OSystem *syst) { return new Simon::SimonEngine(detector, syst); } -REGISTER_PLUGIN("Simon the Sorcerer", Engine_SIMON_gameList, Engine_SIMON_create, Engine_SIMON_detectGames) +REGISTER_PLUGIN(SIMON, "Simon the Sorcerer") namespace Simon { diff --git a/sky/sky.cpp b/sky/sky.cpp index b9f4895c12..0209c7cd37 100644 --- a/sky/sky.cpp +++ b/sky/sky.cpp @@ -106,7 +106,7 @@ Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst) { return new Sky::SkyEngine(detector, syst); } -REGISTER_PLUGIN("Beneath a Steel Sky", Engine_SKY_gameList, Engine_SKY_create, Engine_SKY_detectGames) +REGISTER_PLUGIN(SKY, "Beneath a Steel Sky") namespace Sky { diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index abfc98a528..8be47448bc 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -112,7 +112,7 @@ Engine *Engine_SWORD1_create(GameDetector *detector, OSystem *syst) { return new SwordEngine(detector, syst); } -REGISTER_PLUGIN("Broken Sword", Engine_SWORD1_gameList, Engine_SWORD1_create, Engine_SWORD1_detectGames) +REGISTER_PLUGIN(SWORD1, "Broken Sword") namespace Sword1 { diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index b77ddc60d1..2603f09bfb 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -103,7 +103,7 @@ Engine *Engine_SWORD2_create(GameDetector *detector, OSystem *syst) { return new Sword2::Sword2Engine(detector, syst); } -REGISTER_PLUGIN("Broken Sword II", Engine_SWORD2_gameList, Engine_SWORD2_create, Engine_SWORD2_detectGames) +REGISTER_PLUGIN(SWORD2, "Broken Sword II") namespace Sword2 { |