aboutsummaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
Diffstat (limited to 'base')
-rw-r--r--base/commandLine.cpp16
-rw-r--r--base/game.cpp12
-rw-r--r--base/game.h24
-rw-r--r--base/internal_version.h2
-rw-r--r--base/main.cpp33
5 files changed, 76 insertions, 11 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 1fe54d629d..20249e758b 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -659,7 +659,23 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
if (!command.empty()) {
GameDescriptor gd = Base::findGame(command);
if (ConfMan.hasGameDomain(command) || !gd.gameid().empty()) {
+ bool idCameFromCommandLine = false;
+
+ // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching
+ // undefined target adds launcher entry"
+ //
+ // We designate gameids which come strictly from command line
+ // so AdvancedDetector will not save config file with invalid
+ // gameid in case target autoupgrade was performed
+ if (!ConfMan.hasGameDomain(command)) {
+ idCameFromCommandLine = true;
+ }
+
ConfMan.setActiveDomain(command);
+
+ if (idCameFromCommandLine)
+ ConfMan.set("id_came_from_command_line", "1");
+
} else {
usage("Unrecognized game target '%s'", command.c_str());
}
diff --git a/base/game.cpp b/base/game.cpp
index 960d9ef9f1..9aaaf3a6af 100644
--- a/base/game.cpp
+++ b/base/game.cpp
@@ -26,6 +26,16 @@
#include "base/game.h"
#include "base/plugins.h"
+const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) {
+ const PlainGameDescriptor *g = list;
+ while (g->gameid) {
+ if (0 == scumm_stricmp(gameid, g->gameid))
+ break;
+ g++;
+ }
+ return g;
+}
+
void GameDescriptor::updateDesc(const char *extra) {
// TODO: The format used here (LANG/PLATFORM/EXTRA) is not set in stone.
// We may want to change the order (PLATFORM/EXTRA/LANG, anybody?), or
@@ -58,7 +68,7 @@ void GameDescriptor::updateDesc(const char *extra) {
namespace Base {
-// TODO: Find a better place for this function.
+// TODO: Find a better name & place for this function.
GameDescriptor findGame(const Common::String &gameName, const Plugin **plugin) {
// Find the GameDescriptor for this target
const PluginList &plugins = PluginManager::instance().getPlugins();
diff --git a/base/game.h b/base/game.h
index 9fd997c241..ab52601752 100644
--- a/base/game.h
+++ b/base/game.h
@@ -31,11 +31,31 @@
#include "common/array.h"
#include "common/hash-str.h"
+/**
+ * A simple structure used to map gameids (like "monkey", "sword1", ...) to
+ * nice human readable and descriptive game titles (like "The Secret of Monkey Island").
+ * This is a plain struct to make it possible to declare NULL-terminated C arrays
+ * consisting of PlainGameDescriptors.
+ */
struct PlainGameDescriptor {
const char *gameid;
- const char *description; // TODO: Rename this to "title" or so
+ const char *description;
};
+/**
+ * Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
+ * matching the given gameid. If not match is found return 0.
+ * The end of the list marked by a PlainGameDescriptor with gameid equal to 0.
+ */
+const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
+
+/**
+ * A hashmap describing details about a given game. In a sense this is a refined
+ * version of PlainGameDescriptor, as it also contains a gameid and a description string.
+ * But in addition, platform and language settings, as well as arbitrary other settings,
+ * can be contained in a GameDescriptor.
+ * This is an essential part of the glue between the game engines and the launcher code.
+ */
class GameDescriptor : public Common::StringMap {
public:
GameDescriptor() {
@@ -90,7 +110,7 @@ class Plugin;
namespace Base {
-// TODO: Find a better place for this function.
+// TODO: Find a better name & place for this function.
GameDescriptor findGame(const Common::String &gameName, const Plugin **plugin = NULL);
} // End of namespace Base
diff --git a/base/internal_version.h b/base/internal_version.h
index 210b4fb95c..8f92fd8af7 100644
--- a/base/internal_version.h
+++ b/base/internal_version.h
@@ -1 +1 @@
-#define SCUMMVM_VERSION "0.10.0svn"
+#define SCUMMVM_VERSION "0.11.0svn"
diff --git a/base/main.cpp b/base/main.cpp
index 38e93e2961..85e711bce1 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -82,7 +82,7 @@ static bool launcherDialog(OSystem &system) {
return (dlg.runModal() != -1);
}
-static const Plugin *detectMain() {
+static const Plugin *detectPlugin() {
const Plugin *plugin = 0;
// Make sure the gameid is set in the config manager, and that it is lowercase.
@@ -109,6 +109,7 @@ static const Plugin *detectMain() {
return plugin;
}
+// TODO: specify the possible return values here
static int runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) {
Common::String gameDataPath(ConfMan.get("path"));
if (gameDataPath.empty()) {
@@ -121,8 +122,11 @@ static int runGame(const Plugin *plugin, OSystem &system, const Common::String &
ConfMan.set("path", gameDataPath, Common::ConfigManager::kTransientDomain);
}
- // We add it here, so MD5-based detection will be able to
- // read mixed case files
+ // We add the game "path" to the file search path via File::addDefaultDirectory(),
+ // so that MD5-based detection will be able to properly find files with mixed case
+ // filenames.
+ // FIXME/TODO: Fingolfin still doesn't like this; if those MD5-based detectors used
+ // FSNodes instead of File::open, they wouldn't have to do this.
Common::String path;
if (ConfMan.hasKey("path")) {
path = ConfMan.get("path");
@@ -190,18 +194,26 @@ static int runGame(const Plugin *plugin, OSystem &system, const Common::String &
if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain))
Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain));
+#ifdef DATA_PATH
+ // Add the global DATA_PATH to the directory search list
+ Common::File::addDefaultDirectoryRecursive(DATA_PATH);
+#endif
+
// On creation the engine should've set up all debug levels so we can use
// the command line arugments here
Common::enableSpecialDebugLevelList(edebuglevels);
int result;
- // Init the engine (this might change the screen parameters
+ // Init the engine (this might change the screen parameters)
+ // TODO: We should specify what return values
result = engine->init();
// Run the game engine if the initialization was successful.
if (result == 0) {
result = engine->go();
+ } else {
+ // TODO: Set an error flag, notify user about the problem
}
// We clear all debug levels again even though the engine should do it
@@ -213,7 +225,7 @@ static int runGame(const Plugin *plugin, OSystem &system, const Common::String &
// Reset the file/directory mappings
Common::File::resetDefaultDirectories();
- return result;
+ return 0;
}
@@ -289,14 +301,18 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
// work as well as it should. In theory everything should be destroyed
// cleanly, so this is now enabled to encourage people to fix bits :)
while (0 != ConfMan.getActiveDomain()) {
- // Verify the given game name is a valid supported game
- const Plugin *plugin = detectMain();
+ // Try to find a plugin which feels responsible for the specified game.
+ const Plugin *plugin = detectPlugin();
if (plugin) {
// Unload all plugins not needed for this game,
// to save memory
PluginManager::instance().unloadPluginsExcept(plugin);
+ // Try to run the game
int result = runGame(plugin, system, specialDebug);
+ // TODO: We should keep running if starting the selected game failed
+ // (so instead of just quitting, show a nice error dialog to the
+ // user and let him pick another game).
if (result == 0)
break;
@@ -309,6 +325,9 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
// PluginManager::instance().unloadPlugins();
PluginManager::instance().loadPlugins();
+ } else {
+ GUI::MessageDialog alert("Could not find any engine capable of running the selected game!");
+ alert.runModal();
}
launcherDialog(system);