[Scummvm-cvs-logs] CVS: scummvm/common engine.cpp,1.33,1.34 engine.h,1.34,1.35 gameDetector.cpp,1.152,1.153 gameDetector.h,1.59,1.60 main.cpp,1.40,1.41 plugins.cpp,1.1,1.2 plugins.h,1.1,1.2 timer.cpp,1.12,1.13

Max Horn fingolfin at users.sourceforge.net
Mon Sep 8 20:18:25 CEST 2003


Update of /cvsroot/scummvm/scummvm/common
In directory sc8-pr-cvs1:/tmp/cvs-serv16383

Modified Files:
	engine.cpp engine.h gameDetector.cpp gameDetector.h main.cpp 
	plugins.cpp plugins.h timer.cpp 
Log Message:
more plugin related work

Index: engine.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/engine.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- engine.cpp	6 Sep 2003 03:41:12 -0000	1.33
+++ engine.cpp	8 Sep 2003 17:13:40 -0000	1.34
@@ -121,40 +121,6 @@
 	return dir;
 }
 
-Engine *Engine::createFromDetector(GameDetector *detector, OSystem *syst) {
-	Engine *engine = NULL;
-
-#ifndef DISABLE_SCUMM
-	if (detector->_game.id >= GID_SCUMM_FIRST && detector->_game.id <= GID_SCUMM_LAST) {
-		// Some kind of Scumm game
-		engine = Engine_SCUMM_create(detector, syst);
-	}
-#endif
-
-#ifndef DISABLE_SIMON
-	if (detector->_game.id >= GID_SIMON_FIRST && detector->_game.id <= GID_SIMON_LAST) {
-		// Simon the Sorcerer
-		engine = Engine_SIMON_create(detector, syst);
-	}
-#endif
-
-#ifndef DISABLE_SKY
-	if (detector->_game.id >= GID_SKY_FIRST && detector->_game.id <= GID_SKY_LAST) {
-		// Beneath a Steel Sky
-		engine = Engine_SKY_create(detector, syst);
-	}
-#endif
-
-#ifndef DISABLE_SWORD2
-	if (detector->_game.id >= GID_SWORD2_FIRST && detector->_game.id <= GID_SWORD2_LAST) {
-		// Broken Sword 2
-		engine = Engine_SWORD2_create(detector, syst);
-	}
-#endif
-	
-	return engine;
-}
-
 void NORETURN CDECL error(const char *s, ...) {
 #ifdef __PALM_OS__
 	char buf_input[256]; // 1024 is too big overflow the stack
@@ -274,3 +240,16 @@
 	}
 #endif
 }
+
+//
+// HACK: The following is done to pull in symbols from all the engine modules here.
+// If we don't do this, all sorts of linker problems may occur.
+//
+EngineFactory _factories[] =
+	{
+		Engine_SKY_create,
+		Engine_SCUMM_create,
+		Engine_SIMON_create,
+		Engine_SWORD2_create
+	};
+

Index: engine.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/engine.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- engine.h	8 Sep 2003 15:38:29 -0000	1.34
+++ engine.h	8 Sep 2003 17:13:40 -0000	1.35
@@ -74,10 +74,6 @@
 	const char *getSavePath() const;
 
 	virtual const char *getGameDataPath() const { return _gameDataPath; }
-
-	// Create a new engine object based on the detector - either 
-	// a Scumm or a SimonEngine object currently.
-	static Engine *createFromDetector(GameDetector *detector, OSystem *syst);
 	
 	// Specific for each engine preparare of erroe string
 	virtual void errorString(const char *buf_input, char *buf_output) = 0;
@@ -95,30 +91,6 @@
 
 void CDECL debug(int level, const char *s, ...);
 void checkHeap();
-
-// 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 TargetSettings *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 TargetSettings *Engine_SIMON_targetList();
-#endif
-
-#ifndef DISABLE_SKY
-extern const TargetSettings *Engine_SKY_targetList();
-extern Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst);
-#endif
-
-#ifndef DISABLE_SWORD2
-extern const TargetSettings *Engine_SWORD2_targetList();
-extern Engine *Engine_SWORD2_create(GameDetector *detector, OSystem *syst);
-#endif
 
 #endif
 

Index: gameDetector.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/gameDetector.cpp,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- gameDetector.cpp	8 Sep 2003 15:38:29 -0000	1.152
+++ gameDetector.cpp	8 Sep 2003 17:13:40 -0000	1.153
@@ -25,6 +25,7 @@
 #include "common/config-file.h"
 #include "common/engine.h"
 #include "common/gameDetector.h"
+#include "common/plugins.h"
 #include "common/scaler.h"	// Only for gfx_modes
 #include "sound/mididrv.h"
 
@@ -99,8 +100,6 @@
 	"e.g. \"--no-aspect-ratio\".\n"
 ;
 #endif
-// This contains a pointer to a list of all supported games.
-const TargetSettings *version_settings = NULL;
 
 static const struct GraphicsMode gfx_modes[] = {
 	{"normal", "Normal (no scaling)", GFX_NORMAL},
@@ -159,12 +158,13 @@
 	{0, 0, 0}
 };
 
-static int countVersions(const TargetSettings *v) {
-	int count;
-	for (count = 0; v->targetName; v++, count++)
-		;
-	return count;
-}
+
+// This contains a pointer to a list of all supported games.
+// FIXME: Get rid of version_settings. The only reaons we still have it is
+// that launcher.cpp uses it. So let's convert launcher.cpp to use the new
+// Plugin API instead!
+const TargetSettings *version_settings = NULL;
+
 
 GameDetector::GameDetector() {
 	_fullScreen = false;
@@ -213,70 +213,37 @@
 	_gfx_mode = GFX_NORMAL;
 #endif
 	_default_gfx_mode = true;
-
+	
 	if (version_settings == NULL) {
-		int totalCount = 0;
+		assert(g_pluginManager);
+		const PluginList &_plugins = g_pluginManager->getPlugins();
+		int i;
+		int count = 0;
 		
 		// Gather & combine the target lists from the modules
+		for (i = 0; i < _plugins.size(); i++) {
+			count += _plugins[i]->countTargets();
+		}
 
-#ifndef DISABLE_SCUMM
-		const TargetSettings *scummVersions = Engine_SCUMM_targetList();
-		int scummCount = countVersions(scummVersions);
-		totalCount += scummCount;
-#endif
-
-#ifndef DISABLE_SIMON
-		const TargetSettings *simonVersions = Engine_SIMON_targetList();
-		int simonCount = countVersions(simonVersions);
-		totalCount += simonCount;
-#endif
-
-#ifndef DISABLE_SKY
-		const TargetSettings *skyVersions = Engine_SKY_targetList();
-		int skyCount = countVersions(skyVersions);
-		totalCount += skyCount;
-#endif
-
-#ifndef DISABLE_SWORD2
-		const TargetSettings *sword2Versions = Engine_SWORD2_targetList();
-		int sword2Count = countVersions(sword2Versions);
-		totalCount += sword2Count;
-#endif
-		
-		TargetSettings *v = (TargetSettings *)calloc(totalCount + 1, sizeof(TargetSettings));
+		TargetSettings *v = (TargetSettings *)calloc(count + 1, sizeof(TargetSettings));
 		version_settings = v;
 
-#ifndef DISABLE_SCUMM
-		memcpy(v, scummVersions, scummCount * sizeof(TargetSettings));
-		v += scummCount;
-#endif
-
-#ifndef DISABLE_SIMON
-		memcpy(v, simonVersions, simonCount * sizeof(TargetSettings));
-		v += simonCount;
-#endif
-
-#ifndef DISABLE_SKY
-		memcpy(v, skyVersions, skyCount * sizeof(TargetSettings));
-		v += skyCount;
-#endif
-
-#ifndef DISABLE_SWORD2
-		memcpy(v, sword2Versions, sword2Count * sizeof(TargetSettings));
-		v += sword2Count;
-#endif
-
+		for (i = 0; i < _plugins.size(); i++) {
+			count = _plugins[i]->countTargets();
+			memcpy(v, _plugins[i]->getTargets(), count * sizeof(TargetSettings));
+			v += count;
+		}
 	}
 }
 
-#ifdef __PALM_OS__
 GameDetector::~GameDetector() {
+#ifdef __PALM_OS__
 	// This is a previously allocated chunck (line 224)
 	// so we need to free it to prevent memory leak
 	TargetSettings *v = (TargetSettings *)version_settings;
 	free(v);
-}
 #endif
+}
 
 void GameDetector::updateconfig() {
 	const char *val;
@@ -349,29 +316,33 @@
 }
 
 void GameDetector::list_games() {
-	const TargetSettings *v = version_settings;
+	const PluginList &_plugins = g_pluginManager->getPlugins();
+	const TargetSettings *v;
 	const char *config;
 
 	printf("Game             Full Title                                             Config\n"
 	       "---------------- ------------------------------------------------------ -------\n");
 
-	while (v->targetName && v->description) {
-		config = (g_config->has_domain(v->targetName)) ? "Yes" : "";
-		printf("%-17s%-56s%s\n", v->targetName, v->description, config);
-		v++;
+	for (int i = 0; i < _plugins.size(); i++) {
+		v = _plugins[i]->getTargets();
+		while (v->targetName && v->description) {
+			config = (g_config->has_domain(v->targetName)) ? "Yes" : "";
+			printf("%-17s%-56s%s\n", v->targetName, v->description, config);
+			v++;
+		}
 	}
-		
 }
 
 const TargetSettings *GameDetector::findTarget(const char *targetName) const {
 	// Find the TargetSettings for this target
-	const TargetSettings *target = version_settings;
 	assert(targetName);
-	while (target->targetName) {
-		if (!scumm_stricmp(target->targetName, targetName)) {
+	const TargetSettings *target;
+	const PluginList &_plugins = g_pluginManager->getPlugins();
+	
+	for (int i = 0; i < _plugins.size(); i++) {
+		target = _plugins[i]->findTarget(targetName);
+		if (target)
 			return target;
-		}
-		target++;
 	}
 	return 0;
 }
@@ -800,6 +771,47 @@
 	/* SDL is the default driver for now */
 	return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatio);
 #endif
+}
+
+Engine *GameDetector::createEngine(OSystem *system) {
+	Engine *engine = NULL;
+
+	// FIXME: These checks are evil, as they require us to hard code GIDs.
+	// Much better would be to e.g. put a pointer to the instance creation
+	// method into the TargetSettings or so. That way, in addition to
+	// simplifying this code, GIDs wouldn't have to be unique globally
+	// anymore - only locally for each plugin. And it would be trivial
+	// to add new plugins, without touching the code here.
+
+#ifndef DISABLE_SCUMM
+	if (_game.id >= GID_SCUMM_FIRST && _game.id <= GID_SCUMM_LAST) {
+		// Some kind of Scumm game
+		engine = Engine_SCUMM_create(this, system);
+	}
+#endif
+
+#ifndef DISABLE_SIMON
+	if (_game.id >= GID_SIMON_FIRST && _game.id <= GID_SIMON_LAST) {
+		// Simon the Sorcerer
+		engine = Engine_SIMON_create(this, system);
+	}
+#endif
+
+#ifndef DISABLE_SKY
+	if (_game.id >= GID_SKY_FIRST && _game.id <= GID_SKY_LAST) {
+		// Beneath a Steel Sky
+		engine = Engine_SKY_create(this, system);
+	}
+#endif
+
+#ifndef DISABLE_SWORD2
+	if (_game.id >= GID_SWORD2_FIRST && _game.id <= GID_SWORD2_LAST) {
+		// Broken Sword 2
+		engine = Engine_SWORD2_create(this, system);
+	}
+#endif
+	
+	return engine;
 }
 
 int GameDetector::getMidiDriverType() {

Index: gameDetector.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/gameDetector.h,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- gameDetector.h	8 Sep 2003 15:38:30 -0000	1.59
+++ gameDetector.h	8 Sep 2003 17:13:40 -0000	1.60
@@ -25,6 +25,8 @@
 
 #include "common/str.h"
 
+class Engine;
+class GameDetector;
 class OSystem;
 class MidiDriver;
 
@@ -96,6 +98,33 @@
 	int id;
 };
 
+typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst);
+
+// 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 TargetSettings *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 TargetSettings *Engine_SIMON_targetList();
+#endif
+
+#ifndef DISABLE_SKY
+extern const TargetSettings *Engine_SKY_targetList();
+extern Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst);
+#endif
+
+#ifndef DISABLE_SWORD2
+extern const TargetSettings *Engine_SWORD2_targetList();
+extern Engine *Engine_SWORD2_create(GameDetector *detector, OSystem *syst);
+#endif
+
+
 class GameDetector {
 	typedef ScummVM::String String;
 
@@ -105,14 +134,15 @@
 
 public:
 	GameDetector();
-#ifdef __PALM_OS__
 	~GameDetector();
-#endif
 
 	void parseCommandLine(int argc, char **argv);
 	int detectMain();
 	void setGame(const String &name);
 	const String& getGameName(void);
+
+	String _gameFileName;
+	TargetSettings _game;
 	
 	bool _fullScreen;
 	bool _aspectRatio;
@@ -138,9 +168,6 @@
 	int _gameTempo;
 	int _midi_driver;
 
-	String _gameFileName;
-	TargetSettings _game;
-
 	int _gfx_mode;
 	bool _default_gfx_mode;
 
@@ -155,6 +182,8 @@
 
 public:
 	OSystem *createSystem();
+	Engine *createEngine(OSystem *system);
+
 	MidiDriver *createMidi();
 	int getMidiDriverType();
 

Index: main.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/main.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- main.cpp	6 Sep 2003 22:32:34 -0000	1.40
+++ main.cpp	8 Sep 2003 17:13:40 -0000	1.41
@@ -32,13 +32,14 @@
 #include "common/config-file.h"
 #include "common/engine.h"
 #include "common/gameDetector.h"
+#include "common/plugins.h"
 #include "common/scaler.h"	// For GFX_NORMAL
 #include "gui/newgui.h"
 #include "gui/launcher.h"
 #include "gui/message.h"
 
-Config *g_config = 0;
-NewGui *g_gui = 0;
+Config	*g_config = 0;
+NewGui	*g_gui = 0;
 
 #if defined(QTOPIA)
 // FIXME - why exactly is this needed?
@@ -151,7 +152,6 @@
 }
 
 int main(int argc, char *argv[]) {
-	GameDetector detector;
 	OSystem::Property prop;
 
 #if defined(UNIX)
@@ -179,8 +179,13 @@
 	// Read the config file
 	g_config = new Config(scummhome, "scummvm");
 	g_config->set("versioninfo", gScummVMVersion);
+	
+	// Load the plugins
+	g_pluginManager = new PluginManager();
+	g_pluginManager->loadPlugins();
 
 	// Parse the command line information
+	GameDetector detector;
 	detector._saveconfig = false;
 	detector.updateconfig();
 	detector.parseCommandLine(argc, argv);	
@@ -215,7 +220,7 @@
 		}
 
 		// Create the game engine
-		Engine *engine = Engine::createFromDetector(&detector, system);
+		Engine *engine = detector.createEngine(system);
 
 		// print a message if gameid is invalid
 		if (engine == NULL)

Index: plugins.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/plugins.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- plugins.cpp	8 Sep 2003 15:38:30 -0000	1.1
+++ plugins.cpp	8 Sep 2003 17:13:40 -0000	1.2
@@ -22,6 +22,64 @@
 
 #include "common/plugins.h"
 #include "common/engine.h"
+#include "common/gameDetector.h"
+
+
+PluginManager	*g_pluginManager = 0;
+
+
+#pragma mark -
+
+
+int Plugin::countTargets() const {
+	const TargetSettings *target = getTargets();
+	int count;
+	for (count = 0; target->targetName; target++, count++)
+		;
+	return count;
+}
+
+const TargetSettings *Plugin::findTarget(const char *targetName) const {
+	// Find the TargetSettings for this target
+	const TargetSettings *target = getTargets();
+	assert(targetName);
+	while (target->targetName) {
+		if (!scumm_stricmp(target->targetName, targetName)) {
+			return target;
+		}
+		target++;
+	}
+	return 0;
+}
+
+
+#pragma mark -
+
+
+class StaticPlugin : public Plugin {
+	const char *_name;
+	const TargetSettings *_targets;
+	int _targetCount;
+	EngineFactory _ef;
+public:
+	StaticPlugin(const char *name, const TargetSettings *targets, EngineFactory ef)
+		: _name(name), _targets(targets), _ef(ef) {
+		_targetCount = Plugin::countTargets();
+	}
+
+	const char *getName() const					{ return _name; }
+	int getVersion() const						{ return 0; }
+
+	int countTargets() const					{ return _targetCount; }
+	const TargetSettings *getTargets() const	{ return _targets; }
+
+	Engine *createInstance(GameDetector *detector, OSystem *syst) const {
+		return (*_ef)(detector, syst);
+	}
+};
+
+
+#pragma mark -
 
 
 PluginManager::PluginManager() {
@@ -33,7 +91,21 @@
 }
 
 void PluginManager::loadPlugins() {
-	// TODO
+#ifndef DISABLE_SCUMM
+	_plugins.push_back(new StaticPlugin("scumm", Engine_SCUMM_targetList(), Engine_SCUMM_create));
+#endif
+
+#ifndef DISABLE_SIMON
+	_plugins.push_back(new StaticPlugin("simon", Engine_SIMON_targetList(), Engine_SIMON_create));
+#endif
+
+#ifndef DISABLE_SKY
+	_plugins.push_back(new StaticPlugin("sky", Engine_SKY_targetList(), Engine_SKY_create));
+#endif
+
+#ifndef DISABLE_SWORD2
+	_plugins.push_back(new StaticPlugin("sword2", Engine_SWORD2_targetList(), Engine_SWORD2_create));
+#endif
 }
 
 void PluginManager::unloadPlugins() {

Index: plugins.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/plugins.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- plugins.h	8 Sep 2003 15:38:30 -0000	1.1
+++ plugins.h	8 Sep 2003 17:13:40 -0000	1.2
@@ -43,10 +43,18 @@
 	virtual const char *getName() const = 0;
 	virtual int getVersion() const = 0;
 	
+	virtual int countTargets() const;
 	virtual const TargetSettings *getTargets() const = 0;
+	virtual const TargetSettings *findTarget(const char *targetName) const;
+
 	virtual Engine *createInstance(GameDetector *detector, OSystem *syst) const = 0;
 };
 
+
+/** List of plugins. */
+typedef ScummVM::List<Plugin *> PluginList;
+
+
 /**
  * Instances of this class manage all plugins, including loading them,
  * making wrapper objects of class Plugin available, and unloading them.
@@ -55,8 +63,6 @@
  */
 class PluginManager {
 protected:
-	typedef ScummVM::List<Plugin *> PluginList;
-
 	PluginList _plugins;
 	
 public:
@@ -69,5 +75,9 @@
 	const PluginList &getPlugins()	{ return _plugins; }
 };
 
+/**
+ * Global, shared plugin manager.
+ */
+extern PluginManager	*g_pluginManager;
 
 #endif

Index: timer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/timer.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- timer.cpp	1 Aug 2003 12:18:35 -0000	1.12
+++ timer.cpp	8 Sep 2003 17:13:40 -0000	1.13
@@ -91,7 +91,7 @@
 			_timerSlots[l].counter -= interval;
 			if (_timerSlots[l].counter <= 0) {
 				_timerSlots[l].counter += _timerSlots[l].interval;
-				_timerSlots[l].procedure (_engine);
+				_timerSlots[l].procedure(_engine);
 			}
 		}
 	}





More information about the Scummvm-git-logs mailing list