diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/commandLine.cpp | 20 | ||||
-rw-r--r-- | base/internal_version.h | 2 | ||||
-rw-r--r-- | base/internal_version.h.in | 2 | ||||
-rw-r--r-- | base/main.cpp | 33 | ||||
-rw-r--r-- | base/plugins.cpp | 155 | ||||
-rw-r--r-- | base/plugins.h | 44 | ||||
-rw-r--r-- | base/version.cpp | 4 |
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 ; |