aboutsummaryrefslogtreecommitdiff
path: root/engines/adl/adl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/adl/adl.cpp')
-rw-r--r--engines/adl/adl.cpp105
1 files changed, 94 insertions, 11 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 3c405b67b5..8ffb929e7a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -43,13 +43,31 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
Engine(syst),
_gameDescription(gd),
_display(nullptr),
- _isRestarting(false) {
+ _isRestarting(false),
+ _isRestoring(false),
+ _saveVerb(0),
+ _saveNoun(0),
+ _restoreVerb(0),
+ _restoreNoun(0),
+ _canSaveNow(false),
+ _canRestoreNow(false) {
}
AdlEngine::~AdlEngine() {
delete _display;
}
+bool AdlEngine::hasFeature(EngineFeature f) const {
+ switch (f) {
+ case kSupportsLoadingDuringRuntime:
+ case kSupportsSavingDuringRuntime:
+ case kSupportsRTL:
+ return true;
+ default:
+ return false;
+ }
+}
+
Common::Error AdlEngine::run() {
initGraphics(560, 384, true);
@@ -71,6 +89,7 @@ Common::Error AdlEngine::run() {
if (!loadState(saveSlot))
error("Failed to load save game from slot %i", saveSlot);
_display->setCursorPos(Common::Point(0, 23));
+ _isRestoring = true;
} else {
runIntro();
initState();
@@ -162,6 +181,16 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
if (stream.eos() || stream.err())
error("Failed to read commands");
+ if (command.numCond == 0 && command.script[0] == IDO_ACT_SAVE) {
+ _saveVerb = command.verb;
+ _saveNoun = command.noun;
+ }
+
+ if (command.numCond == 0 && command.script[0] == IDO_ACT_LOAD) {
+ _restoreVerb = command.verb;
+ _restoreNoun = command.noun;
+ }
+
commands.push_back(command);
}
}
@@ -278,7 +307,15 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
break;
case IDO_ACT_RESTART: {
_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
+
+ // We allow restoring via GMM here
+ _canRestoreNow = true;
Common::String input = inputString();
+ _canRestoreNow = false;
+
+ if (_isRestoring)
+ return;
+
if (input.size() == 0 || input[0] != APPLECHAR('N')) {
_isRestarting = true;
_display->clear(0x00);
@@ -341,7 +378,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
}
}
-bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
+bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, bool run) {
if (command.room != IDI_NONE && command.room != _state.room)
return false;
@@ -384,7 +421,8 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
}
}
- doActions(command, noun, offset);
+ if (run)
+ doActions(command, noun, offset);
return true;
}
@@ -395,7 +433,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
- if (checkCommand(*cmd, verb, noun))
+ if (matchCommand(*cmd, verb, noun))
return true;
return false;
@@ -403,14 +441,43 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
+ bool oldIsRestoring = _isRestoring;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
- checkCommand(*cmd, verb, noun);
- if (_isRestarting)
- return;
+ matchCommand(*cmd, verb, noun);
+
+ // We assume no restarts happen in this command group. This
+ // simplifies enabling GMM savegame loading on the restart
+ // prompt.
+ if (_isRestarting || _isRestoring != oldIsRestoring)
+ error("Unexpected restart action encountered");
}
}
+bool AdlEngine::canSaveGameStateCurrently() {
+ if (!_canSaveNow)
+ return false;
+
+ Commands::const_iterator cmd;
+
+ // Here we check whether or not the game currently accepts the command
+ // "SAVE GAME". This prevents saving via the GMM in situations where
+ // it wouldn't otherwise be possible to do so.
+ for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
+ if (matchCommand(*cmd, _saveVerb, _saveNoun, false)) {
+ if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
+ return false;
+ return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
+ }
+ }
+
+ return false;
+}
+
+bool AdlEngine::canLoadGameStateCurrently() {
+ return _canRestoreNow;
+}
+
void AdlEngine::clearScreen() {
_display->setMode(Display::kModeMixed);
_display->clear(0x00);
@@ -654,7 +721,7 @@ Common::String AdlEngine::getLine() {
while (1) {
Common::String line = inputString(APPLECHAR('?'));
- if (shouldQuit())
+ if (shouldQuit() || _isRestoring)
return "";
if ((byte)line[0] == ('\r' | 0x80)) {
@@ -703,7 +770,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
_display->printString(getEngineString(IDI_STR_ENTER_COMMAND));
Common::String line = getLine();
- if (shouldQuit())
+ if (shouldQuit() || _isRestoring)
return;
uint index = 0;
@@ -755,7 +822,7 @@ Common::String AdlEngine::inputString(byte prompt) {
while (1) {
byte b = inputKey();
- if (g_engine->shouldQuit())
+ if (g_engine->shouldQuit() || _isRestoring)
return 0;
if (b == 0)
@@ -805,7 +872,7 @@ byte AdlEngine::inputKey() {
_display->showCursor(true);
- while (!g_engine->shouldQuit() && key == 0) {
+ while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
Common::Event event;
if (ev->pollEvent(event)) {
if (event.type != Common::EVENT_KEYDOWN)
@@ -863,6 +930,22 @@ void AdlEngine::delay(uint32 ms) {
}
}
+Common::Error AdlEngine::loadGameState(int slot) {
+ if (loadState(slot)) {
+ _isRestoring = true;
+ return Common::kNoError;
+ }
+
+ return Common::kUnknownError;
+}
+
+Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
+ if (saveState(slot, &desc))
+ return Common::kNoError;
+
+ return Common::kUnknownError;
+}
+
AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
switch(type) {
case kGameTypeHires1: