aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/plugins.cpp95
-rw-r--r--base/plugins.h80
-rw-r--r--common.rules3
-rw-r--r--kyra/kyra.cpp2
-rw-r--r--queen/queen.cpp2
-rw-r--r--saga/saga.cpp2
-rw-r--r--scumm/scumm.cpp2
-rw-r--r--simon/simon.cpp2
-rw-r--r--sky/sky.cpp2
-rw-r--r--sword1/sword1.cpp2
-rw-r--r--sword2/sword2.cpp2
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 {