import some code from scummvm to allow implement later multi engine support
This commit is contained in:
parent
697af45d7a
commit
ac7307728b
23 changed files with 3705 additions and 0 deletions
275
base/main.cpp
Normal file
275
base/main.cpp
Normal file
|
@ -0,0 +1,275 @@
|
|||
/* Residual - Virtual machine to run LucasArts' 3D adventure games
|
||||
*
|
||||
* Residual is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the AUTHORS
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \mainpage %Residual Source Reference
|
||||
*
|
||||
* These pages contains a cross referenced documentation for the %Residual source code,
|
||||
* generated with Doxygen (http://www.doxygen.org) directly from the source.
|
||||
* Currently not much is actually properly documented, but at least you can get an overview
|
||||
* of almost all the classes, methods and variables, and how they interact.
|
||||
*/
|
||||
|
||||
#include "engines/engine.h"
|
||||
#include "engines/metaengine.h"
|
||||
#include "base/commandLine.h"
|
||||
#include "base/plugins.h"
|
||||
#include "base/version.h"
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/system.h"
|
||||
|
||||
|
||||
static const EnginePlugin *detectPlugin() {
|
||||
const EnginePlugin *plugin = 0;
|
||||
|
||||
// Make sure the gameid is set in the config manager, and that it is lowercase.
|
||||
Common::String gameid(ConfMan.getActiveDomainName());
|
||||
assert(!gameid.empty());
|
||||
if (ConfMan.hasKey("gameid"))
|
||||
gameid = ConfMan.get("gameid");
|
||||
gameid.toLowercase();
|
||||
ConfMan.set("gameid", gameid);
|
||||
|
||||
// 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(" Looking for a plugin supporting this gameid... ");
|
||||
GameDescriptor game = EngineMan.findGame(gameid, &plugin);
|
||||
|
||||
if (plugin == 0) {
|
||||
printf("failed\n");
|
||||
warning("%s is an invalid gameid. Use the --list-games option to list supported gameid", gameid.c_str());
|
||||
return 0;
|
||||
} else {
|
||||
printf("%s\n", plugin->getName());
|
||||
}
|
||||
|
||||
// FIXME: Do we really need this one?
|
||||
printf(" Starting '%s'\n", game.description().c_str());
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
// TODO: specify the possible return values here
|
||||
static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) {
|
||||
// Determine the game data path, for validation and error messages
|
||||
Common::FSNode dir(ConfMan.get("path"));
|
||||
Common::Error err = Common::kNoError;
|
||||
Engine *engine = 0;
|
||||
|
||||
// Verify that the game path refers to an actual directory
|
||||
if (!(dir.exists() && dir.isDirectory()))
|
||||
err = Common::kInvalidPathError;
|
||||
|
||||
// Create the game engine
|
||||
if (err == Common::kNoError)
|
||||
err = (*plugin)->createInstance(&system, &engine);
|
||||
|
||||
// Check for errors
|
||||
if (!engine || err != Common::kNoError) {
|
||||
const char *errMsg = 0;
|
||||
switch (err) {
|
||||
case Common::kInvalidPathError:
|
||||
errMsg = "Invalid game path";
|
||||
break;
|
||||
case Common::kNoGameDataFoundError:
|
||||
errMsg = "Unable to locate game data";
|
||||
break;
|
||||
default:
|
||||
errMsg = "Unknown error";
|
||||
}
|
||||
|
||||
warning("%s failed to instantiate engine: %s (target '%s', path '%s')",
|
||||
plugin->getName(),
|
||||
errMsg,
|
||||
ConfMan.getActiveDomainName().c_str(),
|
||||
dir.getPath().c_str()
|
||||
);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Set the window caption to the game name
|
||||
Common::String caption(ConfMan.get("description"));
|
||||
|
||||
Common::String desc = EngineMan.findGame(ConfMan.get("gameid")).description();
|
||||
if (caption.empty() && !desc.empty())
|
||||
caption = desc;
|
||||
if (caption.empty())
|
||||
caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name
|
||||
if (!caption.empty()) {
|
||||
system.setWindowCaption(caption.c_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Setup various paths in the SearchManager
|
||||
//
|
||||
|
||||
// Add the game path to the directory search list
|
||||
SearchMan.addDirectory(dir.getPath(), dir, 0, 4);
|
||||
|
||||
// Add extrapath (if any) to the directory search list
|
||||
if (ConfMan.hasKey("extrapath")) {
|
||||
dir = Common::FSNode(ConfMan.get("extrapath"));
|
||||
SearchMan.addDirectory(dir.getPath(), dir);
|
||||
}
|
||||
|
||||
// If a second extrapath is specified on the app domain level, add that as well.
|
||||
if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) {
|
||||
dir = Common::FSNode(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain));
|
||||
SearchMan.addDirectory(dir.getPath(), dir);
|
||||
}
|
||||
|
||||
// On creation the engine should have set up all debug levels so we can use
|
||||
// the command line arugments here
|
||||
Common::StringTokenizer tokenizer(edebuglevels, " ,");
|
||||
while (!tokenizer.empty()) {
|
||||
Common::String token = tokenizer.nextToken();
|
||||
// if (!enableDebugChannel(token))
|
||||
// warning("Engine does not support debug level '%s'", token.c_str());
|
||||
}
|
||||
|
||||
// Inform backend that the engine is about to be run
|
||||
system.engineInit();
|
||||
|
||||
// Run the engine
|
||||
Common::Error result = engine->run();
|
||||
|
||||
// Inform backend that the engine finished
|
||||
system.engineDone();
|
||||
|
||||
// Free up memory
|
||||
delete engine;
|
||||
|
||||
// Reset the file/directory mappings
|
||||
SearchMan.clear();
|
||||
|
||||
// Return result (== 0 means no error)
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int residual_main(int argc, const char * const argv[]) {
|
||||
Common::String specialDebug;
|
||||
Common::String command;
|
||||
|
||||
// Verify that the backend has been initialized (i.e. g_system has been set).
|
||||
assert(g_system);
|
||||
OSystem &system = *g_system;
|
||||
|
||||
// Register config manager defaults
|
||||
Base::registerDefaults();
|
||||
|
||||
// Parse the command line
|
||||
Common::StringMap settings;
|
||||
command = Base::parseCommandLine(settings, argc, argv);
|
||||
|
||||
// Load the config file (possibly overriden via command line):
|
||||
if (settings.contains("config")) {
|
||||
ConfMan.loadConfigFile(settings["config"]);
|
||||
settings.erase("config");
|
||||
} else {
|
||||
ConfMan.loadDefaultConfigFile();
|
||||
}
|
||||
|
||||
// Update the config file
|
||||
ConfMan.set("versioninfo", gResidualVersion, Common::ConfigManager::kApplicationDomain);
|
||||
|
||||
|
||||
// Load and setup the debuglevel and the debug flags. We do this at the
|
||||
// soonest possible moment to ensure debug output starts early on, if
|
||||
// requested.
|
||||
if (settings.contains("debuglevel")) {
|
||||
gDebugLevel = (enDebugLevels)strtol(settings["debuglevel"].c_str(), 0, 10);
|
||||
printf("Debuglevel (from command line): %d\n", gDebugLevel);
|
||||
settings.erase("debuglevel"); // This option should not be passed to ConfMan.
|
||||
} else if (ConfMan.hasKey("debuglevel"))
|
||||
gDebugLevel = (enDebugLevels)ConfMan.getInt("debuglevel");
|
||||
|
||||
if (settings.contains("debugflags")) {
|
||||
specialDebug = settings["debugflags"];
|
||||
settings.erase("debugflags");
|
||||
}
|
||||
|
||||
// Load the plugins.
|
||||
PluginManager::instance().loadPlugins();
|
||||
|
||||
// Process the remaining command line settings. Must be done after the
|
||||
// config file and the plugins have been loaded.
|
||||
if (!Base::processSettings(command, settings))
|
||||
return 0;
|
||||
|
||||
// Init the backend. Must take place after all config data (including
|
||||
// the command line params) was read.
|
||||
system.initBackend();
|
||||
|
||||
// Init the event manager. As the virtual keyboard is loaded here, it must
|
||||
// take place after the backend is initiated and the screen has been setup
|
||||
system.getEventManager()->init();
|
||||
|
||||
// Try to find a plugin which feels responsible for the specified game.
|
||||
const EnginePlugin *plugin = detectPlugin();
|
||||
if (plugin) {
|
||||
// Unload all plugins not needed for this game,
|
||||
// to save memory
|
||||
PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin);
|
||||
|
||||
// Try to run the game
|
||||
Common::Error result = runGame(plugin, system, specialDebug);
|
||||
|
||||
// Did an error occur ?
|
||||
if (result != Common::kNoError) {
|
||||
// TODO: Show an informative error dialog if starting the selected game failed.
|
||||
}
|
||||
|
||||
// Quit unless an error occurred
|
||||
if (result == 0)
|
||||
goto exit;
|
||||
|
||||
// Discard any command line options. It's unlikely that the user
|
||||
// wanted to apply them to *all* games ever launched.
|
||||
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
|
||||
|
||||
// Clear the active config domain
|
||||
ConfMan.setActiveDomain("");
|
||||
|
||||
// PluginManager::instance().unloadPlugins();
|
||||
PluginManager::instance().loadPlugins();
|
||||
} else {
|
||||
// A dialog would be nicer, but we don't have any
|
||||
// screen to draw on yet.
|
||||
warning("Could not find any engine capable of running the selected game");
|
||||
}
|
||||
|
||||
exit:
|
||||
PluginManager::instance().unloadPlugins();
|
||||
PluginManager::destroy();
|
||||
Common::ConfigManager::destroy();
|
||||
Common::SearchManager::destroy();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue