aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2014-12-30 03:45:14 +0100
committerTorbjörn Andersson2014-12-30 03:45:14 +0100
commitf74ba29753de23bad9a07f531fc4c03ea3375594 (patch)
tree6ef69cc19956d168c7e468ec959b6708b9ecc244
parent6c3af3c2e7b8d2852669c141944964c82a11ce1b (diff)
downloadscummvm-rg350-f74ba29753de23bad9a07f531fc4c03ea3375594.tar.gz
scummvm-rg350-f74ba29753de23bad9a07f531fc4c03ea3375594.tar.bz2
scummvm-rg350-f74ba29753de23bad9a07f531fc4c03ea3375594.zip
SCUMM: Enable Day of the Tentacle easter egg
Instead of returning to the launcher, a game may now specify a list of "chained" games and optional save slots. The first game is popped from the list and started. Quitting still quits the entire ScummVM. It seemed like the sensible thing to do.
-rw-r--r--base/main.cpp50
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/script_v6.cpp6
-rw-r--r--engines/scumm/scumm.cpp44
-rw-r--r--engines/scumm/scumm.h2
5 files changed, 94 insertions, 10 deletions
diff --git a/base/main.cpp b/base/main.cpp
index b5de7d94d2..b9bd97dbef 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -523,22 +523,64 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
}
#endif
+ // At this point, we usually return to the launcher. However, the
+ // game may have requested that one or more other games be "chained"
+ // to the current one, with optional save slots to start the games
+ // at. At the time of writing, this is used for the Maniac Mansion
+ // easter egg in Day of the Tentacle.
+
+ Common::String chainedGames, nextGame, saveSlot;
+
+ if (ConfMan.hasKey("chained_games", Common::ConfigManager::kTransientDomain)) {
+ chainedGames = ConfMan.get("chained_games", Common::ConfigManager::kTransientDomain);
+ }
+
// 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("");
+ if (!chainedGames.empty()) {
+ if (chainedGames.contains(',')) {
+ for (uint i = 0; i < chainedGames.size(); i++) {
+ if (chainedGames[i] == ',') {
+ chainedGames.erase(0, i + 1);
+ break;
+ }
+ nextGame += chainedGames[i];
+ }
+ ConfMan.set("chained_games", chainedGames, Common::ConfigManager::kTransientDomain);
+ } else {
+ nextGame = chainedGames;
+ chainedGames.clear();
+ ConfMan.removeKey("chained_games", Common::ConfigManager::kTransientDomain);
+ }
+ if (nextGame.contains(':')) {
+ for (int i = nextGame.size() - 1; i >= 0; i--) {
+ if (nextGame[i] == ':') {
+ nextGame.erase(i);
+ break;
+ }
+ saveSlot = nextGame[i] + saveSlot;
+ }
+ ConfMan.setInt("save_slot", atoi(saveSlot.c_str()), Common::ConfigManager::kTransientDomain);
+ }
+ // Start the next game
+ ConfMan.setActiveDomain(nextGame);
+ } else {
+ // Clear the active config domain
+ ConfMan.setActiveDomain("");
+ }
PluginManager::instance().loadAllPlugins(); // only for cached manager
-
} else {
GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));
}
// reset the graphics to default
setupGraphics(system);
- launcherDialog();
+ if (0 == ConfMan.getActiveDomain()) {
+ launcherDialog();
+ }
}
PluginManager::instance().unloadAllPlugins();
PluginManager::destroy();
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 0c0f6be73b..e5673c1803 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -149,7 +149,7 @@ void ScummEngine::requestSave(int slot, const Common::String &name) {
void ScummEngine::requestLoad(int slot) {
_saveLoadSlot = slot;
- _saveTemporaryState = false;
+ _saveTemporaryState = (slot == 100);
_saveLoadFlag = 2; // 2 for load
}
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index d2f4133f74..6c81f17f2f 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2597,7 +2597,11 @@ void ScummEngine_v6::o6_kernelSetFunctions() {
fadeIn(args[1]);
break;
case 8:
- startManiac();
+ if (startManiac()) {
+ // This is so that the surprised exclamation happens
+ // after we return to the game again, not before.
+ o6_breakHere();
+ }
break;
case 9:
killAllScriptsExceptCurrent();
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 6040344c2c..34ae957951 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2597,9 +2597,47 @@ void ScummEngine_v90he::runBootscript() {
}
#endif
-void ScummEngine::startManiac() {
- debug(0, "stub startManiac()");
- displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory."));
+bool ScummEngine::startManiac() {
+ Common::String currentPath = ConfMan.get("path");
+ Common::String maniacTarget;
+
+ // Look for a game with a game path pointing to a 'Maniac' directory
+ // as a subdirectory to the current game.
+ Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
+ for (; iter != ConfMan.endGameDomains(); ++iter) {
+ Common::ConfigManager::Domain &dom = iter->_value;
+ Common::String path = dom.getVal("path");
+
+ if (path.hasPrefix(currentPath)) {
+ path.erase(0, currentPath.size() + 1);
+ if (path.equalsIgnoreCase("maniac")) {
+ maniacTarget = dom.getVal("gameid");
+ break;
+ }
+ }
+ }
+
+ if (!maniacTarget.empty()) {
+ // Request a temporary save game to be made.
+ _saveLoadFlag = 1;
+ _saveLoadSlot = 100;
+ _saveTemporaryState = true;
+
+ // Set up the chanined games to Maniac Mansion, and then back
+ // to the current game again with that save slot.
+ ConfMan.set("chained_games", maniacTarget + "," + ConfMan.getActiveDomainName() + ":100", Common::ConfigManager::kTransientDomain);
+
+ // Force a return to the launcher. This will start the first
+ // chained game.
+ Common::EventManager *eventMan = g_system->getEventManager();
+ Common::Event event;
+ event.type = Common::EVENT_RTL;
+ eventMan->pushEvent(event);
+ return true;
+ } else {
+ displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But for that to work, the game files for Maniac Mansion have to be in the 'Maniac' directory inside the Tentacle game directory, and the game has to be added to ScummVM."));
+ return false;
+ }
}
#pragma mark -
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 967909e505..30b4d61880 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -654,7 +654,7 @@ protected:
int getScriptSlot();
void startScene(int room, Actor *a, int b);
- void startManiac();
+ bool startManiac();
public:
void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle = 0);