aboutsummaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
Diffstat (limited to 'base')
-rw-r--r--base/commandLine.cpp20
-rw-r--r--base/internal_version.h2
-rw-r--r--base/internal_version.h.in2
-rw-r--r--base/main.cpp33
-rw-r--r--base/plugins.cpp155
-rw-r--r--base/plugins.h44
-rw-r--r--base/version.cpp4
7 files changed, 207 insertions, 53 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 5a45ed74a1..b1610feb2e 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -157,6 +157,7 @@ void registerDefaults() {
// Graphics
ConfMan.registerDefault("fullscreen", false);
ConfMan.registerDefault("aspect_ratio", false);
+ ConfMan.registerDefault("disable_dithering", false);
ConfMan.registerDefault("gfx_mode", "normal");
ConfMan.registerDefault("render_mode", "default");
ConfMan.registerDefault("desired_screen_aspect_ratio", "auto");
@@ -219,6 +220,14 @@ void registerDefaults() {
ConfMan.registerDefault("record_file_name", "record.bin");
ConfMan.registerDefault("record_temp_file_name", "record.tmp");
ConfMan.registerDefault("record_time_file_name", "record.time");
+
+#if 0
+ // NEW CODE TO HIDE CONSOLE FOR WIN32
+#ifdef WIN32
+ // console hiding for win32
+ ConfMan.registerDefault("show_console", false);
+#endif
+#endif
}
//
@@ -546,6 +555,15 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
END_OPTION
#endif
+#if 0
+ // NEW CODE TO HIDE CONSOLE FOR WIN32
+#ifdef WIN32
+ // console hiding for win32
+ DO_LONG_OPTION_BOOL("show-console")
+ END_OPTION
+#endif
+#endif
+
unknownOption:
// If we get till here, the option is unhandled and hence unknown.
usage("Unrecognized option '%s'", argv[i]);
@@ -596,7 +614,7 @@ static void listTargets() {
description = g.description();
}
- targets.push_back(Common::String::printf("%-20s %s", name.c_str(), description.c_str()));
+ targets.push_back(Common::String::format("%-20s %s", name.c_str(), description.c_str()));
}
Common::sort(targets.begin(), targets.end());
diff --git a/base/internal_version.h b/base/internal_version.h
index 5a049b0bb8..2b00ce60d2 100644
--- a/base/internal_version.h
+++ b/base/internal_version.h
@@ -3,7 +3,7 @@
#endif
#ifndef SCUMMVM_SVN_REVISION
-#define SCUMMVM_SVN_REVISION
+#define SCUMMVM_SVN_REVISION ""
#endif
#ifdef RELEASE_BUILD
diff --git a/base/internal_version.h.in b/base/internal_version.h.in
index adf5f94d21..dacaf72d40 100644
--- a/base/internal_version.h.in
+++ b/base/internal_version.h.in
@@ -3,7 +3,7 @@
#endif
#ifndef SCUMMVM_SVN_REVISION
-#define SCUMMVM_SVN_REVISION
+#define SCUMMVM_SVN_REVISION "@SVN_REVISION@"
#endif
#ifdef RELEASE_BUILD
diff --git a/base/main.cpp b/base/main.cpp
index 7afba3db37..3e4af53065 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -104,7 +104,12 @@ static const EnginePlugin *detectPlugin() {
// Query the plugins and find one that will handle the specified gameid
printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str());
printf("%s", " Looking for a plugin supporting this gameid... ");
- GameDescriptor game = EngineMan.findGame(gameid, &plugin);
+
+#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES)
+ GameDescriptor game = EngineMan.findGameOnePluginAtATime(gameid, &plugin);
+#else
+ GameDescriptor game = EngineMan.findGame(gameid, &plugin);
+#endif
if (plugin == 0) {
printf("failed\n");
@@ -210,6 +215,11 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
// Run the engine
Common::Error result = engine->run();
+#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES)
+ // do our best to prevent fragmentation by unloading as soon as we can
+ PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
+#endif
+
// Inform backend that the engine finished
system.engineDone();
@@ -309,7 +319,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
Common::StringMap settings;
command = Base::parseCommandLine(settings, argc, argv);
- // Load the config file (possibly overriden via command line):
+ // Load the config file (possibly overridden via command line):
if (settings.contains("config")) {
ConfMan.loadConfigFile(settings["config"]);
settings.erase("config");
@@ -335,8 +345,13 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
settings.erase("debugflags");
}
- // Load the plugins.
- PluginManager::instance().loadPlugins();
+#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES)
+ // Only load non-engine plugins and first engine plugin initially in this case.
+ PluginManager::instance().loadNonEnginePluginsAndEnumerate();
+#else
+ // Load the plugins.
+ PluginManager::instance().loadPlugins();
+#endif
// If we received an invalid music parameter via command line we check this here.
// We can't check this before loading the music plugins.
@@ -352,6 +367,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// config file and the plugins have been loaded.
Common::Error res;
+ // TODO: deal with settings that require plugins to be loaded
if ((res = Base::processSettings(command, settings)) != Common::kArgumentNotProcessed)
return res;
@@ -419,11 +435,11 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
ConfMan.setActiveDomain("");
// PluginManager::instance().unloadPlugins();
+
+#if !defined(ONE_PLUGIN_AT_A_TIME)
PluginManager::instance().loadPlugins();
+#endif
} else {
- // A dialog would be nicer, but we don't have any
- // screen to draw on yet.
- warning("%s", _("Could not find any engine capable of running the selected game"));
GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));
}
@@ -433,9 +449,10 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
}
PluginManager::instance().unloadPlugins();
PluginManager::destroy();
+ GUI::GuiManager::destroy();
Common::ConfigManager::destroy();
Common::SearchManager::destroy();
- GUI::GuiManager::destroy();
+ Common::TranslationManager::destroy();
return 0;
}
diff --git a/base/plugins.cpp b/base/plugins.cpp
index e2af9328a7..41e213a53a 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -121,6 +121,9 @@ public:
#if PLUGIN_ENABLED_STATIC(KYRA)
LINK_PLUGIN(KYRA)
#endif
+ #if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
+ LINK_PLUGIN(LASTEXPRESS)
+ #endif
#if PLUGIN_ENABLED_STATIC(LURE)
LINK_PLUGIN(LURE)
#endif
@@ -320,6 +323,62 @@ void PluginManager::addPluginProvider(PluginProvider *pp) {
_providers.push_back(pp);
}
+//
+// This should only be run once
+void PluginManager::loadNonEnginePluginsAndEnumerate() {
+ unloadPlugins();
+ _allEnginePlugins.clear();
+
+ // We need to resize our pluginsInMem list to prevent fragmentation
+ // Otherwise, as soon as we add our 1 engine plugin (which is all we'll have in memory at a time)
+ // We'll get an allocation in memory that will never go away
+ _pluginsInMem[PLUGIN_TYPE_ENGINE].resize(2); // more than we need
+
+ for (ProviderList::iterator pp = _providers.begin();
+ pp != _providers.end();
+ ++pp) {
+ PluginList pl((*pp)->getPlugins());
+ for (PluginList::iterator p = pl.begin(); p != pl.end(); ++p) {
+ // To find out which are engine plugins, we have to load them. This is inefficient
+ // Hopefully another way can be found (e.g. if the music plugins are all static,
+ // we can use only the static provider
+ if ((*p)->loadPlugin()) {
+ if ((*p)->getType() == PLUGIN_TYPE_ENGINE) {
+ (*p)->unloadPlugin(); // to prevent fragmentation
+ _allEnginePlugins.push_back(*p);
+ } else { // add non-engine plugins to the 'in-memory' list
+ // these won't ever get unloaded (in this implementation)
+ addToPluginsInMemList(*p);
+ }
+ }
+ }
+ }
+}
+
+void PluginManager::loadFirstPlugin() {
+ unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
+
+ // let's try to find one we can load
+ for (_currentPlugin = _allEnginePlugins.begin(); _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) {
+ if ((*_currentPlugin)->loadPlugin()) {
+ addToPluginsInMemList(*_currentPlugin);
+ break;
+ }
+ }
+}
+
+bool PluginManager::loadNextPlugin() {
+ unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
+
+ for (++_currentPlugin; _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) {
+ if ((*_currentPlugin)->loadPlugin()) {
+ addToPluginsInMemList(*_currentPlugin);
+ return true;
+ }
+ }
+ return false; // no more in list
+}
+
void PluginManager::loadPlugins() {
for (ProviderList::iterator pp = _providers.begin();
pp != _providers.end();
@@ -327,7 +386,6 @@ void PluginManager::loadPlugins() {
PluginList pl((*pp)->getPlugins());
Common::for_each(pl.begin(), pl.end(), Common::bind1st(Common::mem_fun(&PluginManager::tryLoadPlugin), this));
}
-
}
void PluginManager::unloadPlugins() {
@@ -335,19 +393,20 @@ void PluginManager::unloadPlugins() {
unloadPluginsExcept((PluginType)i, NULL);
}
-void PluginManager::unloadPluginsExcept(PluginType type, const Plugin *plugin) {
+void PluginManager::unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin /*=true*/) {
Plugin *found = NULL;
- for (PluginList::iterator p = _plugins[type].begin(); p != _plugins[type].end(); ++p) {
+ for (PluginList::iterator p = _pluginsInMem[type].begin(); p != _pluginsInMem[type].end(); ++p) {
if (*p == plugin) {
found = *p;
} else {
(*p)->unloadPlugin();
- delete *p;
+ if (deletePlugin)
+ delete *p;
}
}
- _plugins[type].clear();
+ _pluginsInMem[type].clear();
if (found != NULL) {
- _plugins[type].push_back(found);
+ _pluginsInMem[type].push_back(found);
}
}
@@ -355,27 +414,7 @@ bool PluginManager::tryLoadPlugin(Plugin *plugin) {
assert(plugin);
// Try to load the plugin
if (plugin->loadPlugin()) {
- // The plugin is valid, see if it provides the same module as an
- // already loaded one and should replace it.
- bool found = false;
-
- PluginList::iterator pl = _plugins[plugin->getType()].begin();
- while (!found && pl != _plugins[plugin->getType()].end()) {
- if (!strcmp(plugin->getName(), (*pl)->getName())) {
- // Found a duplicated module. Replace the old one.
- found = true;
- delete *pl;
- *pl = plugin;
- debug(1, "Replaced the duplicated plugin: '%s'", plugin->getName());
- }
- pl++;
- }
-
- if (!found) {
- // If it provides a new module, just add it to the list of known plugins.
- _plugins[plugin->getType()].push_back(plugin);
- }
-
+ addToPluginsInMemList(plugin);
return true;
} else {
// Failed to load the plugin
@@ -384,6 +423,28 @@ bool PluginManager::tryLoadPlugin(Plugin *plugin) {
}
}
+void PluginManager::addToPluginsInMemList(Plugin *plugin) {
+ bool found = false;
+ // The plugin is valid, see if it provides the same module as an
+ // already loaded one and should replace it.
+
+ PluginList::iterator pl = _pluginsInMem[plugin->getType()].begin();
+ while (!found && pl != _pluginsInMem[plugin->getType()].end()) {
+ if (!strcmp(plugin->getName(), (*pl)->getName())) {
+ // Found a duplicated module. Replace the old one.
+ found = true;
+ delete *pl;
+ *pl = plugin;
+ debug(1, "Replaced the duplicated plugin: '%s'", plugin->getName());
+ }
+ pl++;
+ }
+
+ if (!found) {
+ // If it provides a new module, just add it to the list of known plugins in memory.
+ _pluginsInMem[plugin->getType()].push_back(plugin);
+ }
+}
// Engine plugins
@@ -391,6 +452,18 @@ bool PluginManager::tryLoadPlugin(Plugin *plugin) {
DECLARE_SINGLETON(EngineManager)
+GameDescriptor EngineManager::findGameOnePluginAtATime(const Common::String &gameName, const EnginePlugin **plugin) const {
+ GameDescriptor result;
+ PluginManager::instance().loadFirstPlugin();
+ do {
+ result = findGame(gameName, plugin);
+ if (!result.gameid().empty()) {
+ break;
+ }
+ } while (PluginManager::instance().loadNextPlugin());
+ return result;
+}
+
GameDescriptor EngineManager::findGame(const Common::String &gameName, const EnginePlugin **plugin) const {
// Find the GameDescriptor for this target
const EnginePlugin::List &plugins = getPlugins();
@@ -399,13 +472,14 @@ GameDescriptor EngineManager::findGame(const Common::String &gameName, const Eng
if (plugin)
*plugin = 0;
- EnginePlugin::List::const_iterator iter = plugins.begin();
+ EnginePlugin::List::const_iterator iter;
+
for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
result = (**iter)->findGame(gameName.c_str());
if (!result.gameid().empty()) {
if (plugin)
*plugin = *iter;
- break;
+ return result;
}
}
return result;
@@ -413,16 +487,21 @@ GameDescriptor EngineManager::findGame(const Common::String &gameName, const Eng
GameList EngineManager::detectGames(const Common::FSList &fslist) const {
GameList candidates;
-
- const EnginePlugin::List &plugins = getPlugins();
-
- // Iterate over all known games and for each check if it might be
- // the game in the presented directory.
+ EnginePlugin::List plugins;
EnginePlugin::List::const_iterator iter;
- for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
- candidates.push_back((**iter)->detectGames(fslist));
- }
-
+#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES)
+ PluginManager::instance().loadFirstPlugin();
+ do {
+#endif
+ plugins = getPlugins();
+ // Iterate over all known games and for each check if it might be
+ // the game in the presented directory.
+ for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
+ candidates.push_back((**iter)->detectGames(fslist));
+ }
+#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES)
+ } while (PluginManager::instance().loadNextPlugin());
+#endif
return candidates;
}
diff --git a/base/plugins.h b/base/plugins.h
index a4c7f114f9..fc8adbf0d4 100644
--- a/base/plugins.h
+++ b/base/plugins.h
@@ -30,6 +30,7 @@
#include "common/error.h"
#include "common/singleton.h"
#include "common/util.h"
+#include "backends/plugins/elf/version.h"
namespace Common {
class FSList;
@@ -90,6 +91,21 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX];
#define PLUGIN_ENABLED_DYNAMIC(ID) \
(ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN) && DYNAMIC_MODULES)
+// see comments in backends/plugins/elf/elf-provider.cpp
+#if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
+#define PLUGIN_DYNAMIC_DSO_HANDLE \
+ uint32 __dso_handle __attribute__((visibility("hidden"))) = 0;
+#else
+#define PLUGIN_DYNAMIC_DSO_HANDLE
+#endif
+
+#ifdef USE_ELF_LOADER
+#define PLUGIN_DYNAMIC_BUILD_DATE \
+ PLUGIN_EXPORT const char *PLUGIN_getBuildDate() { return gScummVMPluginBuildDate; }
+#else
+#define PLUGIN_DYNAMIC_BUILD_DATE
+#endif
+
/**
* REGISTER_PLUGIN_STATIC is a convenience macro which is used to declare
* the plugin interface for static plugins. Code (such as game engines)
@@ -119,6 +135,8 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX];
*/
#define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \
extern "C" { \
+ PLUGIN_DYNAMIC_DSO_HANDLE \
+ PLUGIN_DYNAMIC_BUILD_DATE \
PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \
PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \
PLUGIN_EXPORT int32 PLUGIN_getTypeVersion() { return TYPE##_VERSION; } \
@@ -212,6 +230,11 @@ public:
* @return a list of Plugin instances
*/
virtual PluginList getPlugins() = 0;
+
+ /**
+ * @return whether or not object is a FilePluginProvider.
+ */
+ virtual bool isFilePluginProvider() { return false; }
};
#ifdef DYNAMIC_MODULES
@@ -234,6 +257,11 @@ public:
*/
virtual PluginList getPlugins();
+ /**
+ * @return whether or not object is a FilePluginProvider.
+ */
+ bool isFilePluginProvider() { return true; }
+
protected:
/**
* Create a Plugin instance from a loadable code module with the specified name.
@@ -273,11 +301,15 @@ protected:
class PluginManager : public Common::Singleton<PluginManager> {
typedef Common::Array<PluginProvider *> ProviderList;
private:
- PluginList _plugins[PLUGIN_TYPE_MAX];
+ PluginList _pluginsInMem[PLUGIN_TYPE_MAX];
ProviderList _providers;
- bool tryLoadPlugin(Plugin *plugin);
+ PluginList _allEnginePlugins;
+ PluginList::iterator _currentPlugin;
+ bool tryLoadPlugin(Plugin *plugin);
+ void addToPluginsInMemList(Plugin *plugin);
+
friend class Common::Singleton<SingletonBaseType>;
PluginManager();
@@ -286,11 +318,15 @@ public:
void addPluginProvider(PluginProvider *pp);
+ void loadNonEnginePluginsAndEnumerate();
+ void loadFirstPlugin();
+ bool loadNextPlugin();
+
void loadPlugins();
void unloadPlugins();
- void unloadPluginsExcept(PluginType type, const Plugin *plugin);
+ void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true);
- const PluginList &getPlugins(PluginType t) { return _plugins[t]; }
+ const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; }
};
#endif
diff --git a/base/version.cpp b/base/version.cpp
index 2a6d1bb0c0..6967263f5c 100644
--- a/base/version.cpp
+++ b/base/version.cpp
@@ -111,5 +111,9 @@ const char *gScummVMFeatures = ""
#ifdef USE_FLUIDSYNTH
"FluidSynth "
#endif
+
+#ifdef USE_THEORADEC
+ "Theora "
+#endif
;