SCUMM: Add a "chained games manager"

This replaces the somewhat ugly use of the config manager to store
the chained games.
This commit is contained in:
Torbjörn Andersson 2014-12-30 10:47:51 +01:00
parent f74ba29753
commit cc916625d9
4 changed files with 69 additions and 31 deletions

View File

@ -529,43 +529,21 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// 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;
Common::String chainedGame;
int saveSlot = -1;
if (ConfMan.hasKey("chained_games", Common::ConfigManager::kTransientDomain)) {
chainedGames = ConfMan.get("chained_games", Common::ConfigManager::kTransientDomain);
}
ChainedGamesMan.pop(chainedGame, saveSlot);
// 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();
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 (!chainedGame.empty()) {
if (saveSlot != -1) {
ConfMan.setInt("save_slot", saveSlot, 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);
// Start the chained game
ConfMan.setActiveDomain(chainedGame);
} else {
// Clear the active config domain
ConfMan.setActiveDomain("");

View File

@ -45,6 +45,7 @@
#include "common/taskbar.h"
#include "common/textconsole.h"
#include "common/translation.h"
#include "common/singleton.h"
#include "backends/keymapper/keymapper.h"
@ -101,6 +102,36 @@ static void defaultErrorHandler(const char *msg) {
}
}
// Chained games manager
ChainedGamesManager::ChainedGamesManager() {
clear();
}
void ChainedGamesManager::clear() {
_chainedGames.clear();
}
void ChainedGamesManager::push(const Common::String target, const int slot) {
Game game;
game.target = target;
game.slot = slot;
_chainedGames.push(game);
}
bool ChainedGamesManager::pop(Common::String &target, int &slot) {
if (_chainedGames.empty()) {
return false;
}
Game game = _chainedGames.pop();
target = game.target;
slot = game.slot;
return true;
}
namespace Common {
DECLARE_SINGLETON(ChainedGamesManager);
}
Engine::Engine(OSystem *syst)
: _system(syst),

View File

@ -27,6 +27,8 @@
#include "common/str.h"
#include "common/language.h"
#include "common/platform.h"
#include "common/queue.h"
#include "common/singleton.h"
class OSystem;
@ -334,6 +336,32 @@ protected:
};
// Chained games
/**
* Singleton class which manages chained games. A chained game is one that
* starts automatically, optionally loading a saved game, instead of returning
* to the launcher.
*/
class ChainedGamesManager : public Common::Singleton<ChainedGamesManager> {
private:
struct Game {
Common::String target;
int slot;
};
Common::Queue<Game> _chainedGames;
public:
ChainedGamesManager();
void clear();
void push(const Common::String target, const int slot = -1);
bool pop(Common::String &target, int &slot);
};
/** Convenience shortcut for accessing the chained games manager. */
#define ChainedGamesMan ChainedGamesManager::instance()
// FIXME: HACK for MidiEmu & error()
extern Engine *g_engine;

View File

@ -2625,7 +2625,8 @@ bool ScummEngine::startManiac() {
// 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);
ChainedGamesMan.push(maniacTarget);
ChainedGamesMan.push(ConfMan.getActiveDomainName(), 100);
// Force a return to the launcher. This will start the first
// chained game.