aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/commandLine.cpp2
-rw-r--r--base/main.cpp2
-rw-r--r--common/error.cpp3
-rw-r--r--common/error.h2
-rw-r--r--engines/advancedDetector.cpp23
-rw-r--r--engines/advancedDetector.h3
-rw-r--r--engines/engine.cpp11
-rw-r--r--engines/engine.h7
-rw-r--r--engines/game.cpp31
-rw-r--r--engines/game.h18
10 files changed, 97 insertions, 5 deletions
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index e34cde4779..61853a1ebc 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -186,6 +186,8 @@ void registerDefaults() {
ConfMan.registerDefault("cdrom", 0);
+ ConfMan.registerDefault("enable_unsupported_game_warning", true);
+
// Game specific
ConfMan.registerDefault("path", "");
ConfMan.registerDefault("platform", Common::kPlatformPC);
diff --git a/base/main.cpp b/base/main.cpp
index 906f4c9242..395ba8344c 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -427,7 +427,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
#endif
// Did an error occur ?
- if (result.getCode() != Common::kNoError) {
+ if (result.getCode() != Common::kNoError && result.getCode() != Common::kUserCanceled) {
// Shows an informative error dialog if starting the selected game failed.
GUI::displayErrorDialog(result, _("Error running game:"));
}
diff --git a/common/error.cpp b/common/error.cpp
index a6c52a0ce9..78178f8e27 100644
--- a/common/error.cpp
+++ b/common/error.cpp
@@ -67,6 +67,9 @@ static String errorToString(ErrorCode errorCode) {
case kEnginePluginNotSupportSaves:
return _s("Engine plugin does not support save states");
+ case kUserCanceled:
+ return _s("User canceled");
+
case kUnknownError:
default:
return _s("Unknown error");
diff --git a/common/error.h b/common/error.h
index 23c12b67e4..7043862eea 100644
--- a/common/error.h
+++ b/common/error.h
@@ -62,6 +62,8 @@ enum ErrorCode {
kEnginePluginNotFound, ///< Failed to find plugin to handle target
kEnginePluginNotSupportSaves, ///< Failed if plugin does not support listing save states
+ kUserCanceled, ///< User has canceled the launching of the game
+
kUnknownError ///< Catch-all error, used if no other error code matches
};
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index 7ae4d7718a..d864fe8b52 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -51,7 +51,13 @@ static GameDescriptor toGameDescriptor(const ADGameDescription &g, const PlainGa
extra = g.extra;
}
- GameDescriptor gd(g.gameid, title, g.language, g.platform);
+ GameSupportLevel gsl = kStableGame;
+ if (g.flags & ADGF_UNSTABLE)
+ gsl = kUnstableGame;
+ else if (g.flags & ADGF_TESTING)
+ gsl = kTestingGame;
+
+ GameDescriptor gd(g.gameid, title, g.language, g.platform, 0, gsl);
gd.updateDesc(extra);
return gd;
}
@@ -253,8 +259,21 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
Common::updateGameGUIOptions(agdDesc->guioptions | _guioptions, lang);
+ GameDescriptor gameDescriptor = toGameDescriptor(*agdDesc, _gameids);
+
+ bool showTestingWarning = false;
+
+#ifdef RELEASE_BUILD
+ showTestingWarning = true;
+#endif
+
+ if (((gameDescriptor.getSupportLevel() == kUnstableGame
+ || (gameDescriptor.getSupportLevel() == kTestingGame
+ && showTestingWarning)))
+ && !Engine::warnUserAboutUnsupportedGame())
+ return Common::kUserCanceled;
- debug(2, "Running %s", toGameDescriptor(*agdDesc, _gameids).description().c_str());
+ debug(2, "Running %s", gameDescriptor.description().c_str());
if (!createInstance(syst, engine, agdDesc))
return Common::kNoGameDataFoundError;
else
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 5360d23ac1..cbdfdf39d8 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -24,6 +24,7 @@
#define ENGINES_ADVANCED_DETECTOR_H
#include "engines/metaengine.h"
+#include "engines/engine.h"
namespace Common {
class Error;
@@ -62,6 +63,8 @@ struct ADGameFileDescription {
enum ADGameFlags {
ADGF_NO_FLAGS = 0,
+ ADGF_UNSTABLE = (1 << 21), // flag to designate not yet officially-supported games that are not fit for public testing
+ ADGF_TESTING = (1 << 22), // flag to designate not yet officially-supported games that are fit for public testing
ADGF_PIRATED = (1 << 23), ///< flag to designate well known pirated versions with cracks
ADGF_ADDENGLISH = (1 << 24), ///< always add English as language option
ADGF_MACRESFORK = (1 << 25), ///< the md5 for this entry will be calculated from the resource fork
diff --git a/engines/engine.cpp b/engines/engine.cpp
index dc30b4bd0d..0797bafc27 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -400,6 +400,17 @@ void Engine::openMainMenuDialog() {
syncSoundSettings();
}
+bool Engine::warnUserAboutUnsupportedGame() {
+ if (ConfMan.getBool("enable_unsupported_game_warning")) {
+ GUI::MessageDialog alert("WARNING: The game you are about to start is"
+ " not yet fully supported by ScummVM. As such, it is likely to be"
+ " unstable, and any saves you make might not work in future"
+ " versions of ScummVM.", "Start anyway", "Cancel");
+ return alert.runModal() == GUI::kMessageOK;
+ }
+ return true;
+}
+
uint32 Engine::getTotalPlayTime() const {
if (!_pauseLevel)
return _system->getMillis() - _engineStartTime;
diff --git a/engines/engine.h b/engines/engine.h
index d7d971ad97..06b7f7dedd 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -252,6 +252,13 @@ public:
void openMainMenuDialog();
/**
+ * Display a warning to the user that the game is not fully supported.
+ *
+ * @return true if the user chose to start anyway, false otherwise
+ */
+ static bool warnUserAboutUnsupportedGame();
+
+ /**
* Get the total play time.
*
* @return How long the player has been playing in ms.
diff --git a/engines/game.cpp b/engines/game.cpp
index c6d9905b52..cbd5a802c6 100644
--- a/engines/game.cpp
+++ b/engines/game.cpp
@@ -46,7 +46,7 @@ GameDescriptor::GameDescriptor(const PlainGameDescriptor &pgd, uint32 guioptions
setVal("guioptions", Common::getGameGUIOptionsDescription(guioptions));
}
-GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l, Common::Platform p, uint32 guioptions) {
+GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l, Common::Platform p, uint32 guioptions, GameSupportLevel gsl) {
setVal("gameid", g);
setVal("description", d);
if (l != Common::UNK_LANG)
@@ -55,6 +55,8 @@ GameDescriptor::GameDescriptor(const Common::String &g, const Common::String &d,
setVal("platform", Common::getPlatformCode(p));
if (guioptions != 0)
setVal("guioptions", Common::getGameGUIOptionsDescription(guioptions));
+
+ setSupportLevel(gsl);
}
void GameDescriptor::setGUIOptions(uint32 guioptions) {
@@ -97,3 +99,30 @@ void GameDescriptor::updateDesc(const char *extra) {
setVal("description", descr);
}
}
+
+GameSupportLevel GameDescriptor::getSupportLevel() {
+ GameSupportLevel gsl = kStableGame;
+ if (contains("gsl")) {
+ Common::String gslString = getVal("gsl");
+ if (gslString.equals("unstable"))
+ gsl = kUnstableGame;
+ else if (gslString.equals("testing"))
+ gsl = kTestingGame;
+ }
+ return gsl;
+}
+
+void GameDescriptor::setSupportLevel(GameSupportLevel gsl) {
+ switch (gsl) {
+ case kUnstableGame:
+ setVal("gsl", "unstable");
+ break;
+ case kTestingGame:
+ setVal("gsl", "testing");
+ break;
+ case kStableGame:
+ // Fall Through intended
+ default:
+ erase("gsl");
+ }
+}
diff --git a/engines/game.h b/engines/game.h
index 3216cfb628..9798954437 100644
--- a/engines/game.h
+++ b/engines/game.h
@@ -47,6 +47,15 @@ struct PlainGameDescriptor {
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
/**
+ * Ths is an enum to describe how done a game is. This also indicates what level of support is expected.
+ */
+enum GameSupportLevel {
+ kStableGame = 0, // the game is fully supported
+ kTestingGame, // the game is not supposed to end up in releases yet but is ready for public testing
+ kUnstableGame // the game is not even ready for public testing yet
+};
+
+/**
* 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,
@@ -61,7 +70,8 @@ public:
const Common::String &description,
Common::Language language = Common::UNK_LANG,
Common::Platform platform = Common::kPlatformUnknown,
- uint32 guioptions = 0);
+ uint32 guioptions = 0,
+ GameSupportLevel gsl = kStableGame);
/**
* Update the description string by appending (LANG/PLATFORM/EXTRA) to it.
@@ -71,6 +81,12 @@ public:
void setGUIOptions(uint32 options);
void appendGUIOptions(const Common::String &str);
+ /**
+ * What level of support is expected of this game
+ */
+ GameSupportLevel getSupportLevel();
+ void setSupportLevel(GameSupportLevel gsl);
+
Common::String &gameid() { return getVal("gameid"); }
Common::String &description() { return getVal("description"); }
const Common::String &gameid() const { return getVal("gameid"); }