diff options
-rw-r--r-- | engines/sci/engine/kfile.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 4508a481a0..bb86e693f2 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -688,7 +688,7 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) { #endif reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id; + Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : ""; int16 virtualId = argv[1].toSint16(); int16 savegameId = -1; Common::String game_description; @@ -703,6 +703,13 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } + // Torin has two sets of saves: autosave.### and torinsg.###, both with + // their own slots and .cat file. + // The autosave system uses autosave.000 and autosave.001. + // It also checks the presence of autosave.cat to determine if it should + // show the chapter selection menu on startup. + bool torinAutosave = g_sci->getGameId() == GID_TORIN && game_id == "Autosave"; + if (argv[0].isNull()) { // Direct call, from a patched Game::save if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull())) @@ -722,9 +729,15 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { if (savegameId < 0) return NULL_REG; + } else if (torinAutosave) { + if (argv[2].isNull()) + error("kSaveGame: called with description being NULL"); + game_description = s->_segMan->getString(argv[2]); + savegameId = virtualId; + + debug(3, "kSaveGame(%s,%d,%s,%s) [Torin autosave]", game_id.c_str(), virtualId, game_description.c_str(), version.c_str()); } else { // Real call from script - game_id = s->_segMan->getString(argv[0]); if (argv[2].isNull()) error("kSaveGame: called with description being NULL"); game_description = s->_segMan->getString(argv[2]); @@ -798,6 +811,10 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); Common::OutSaveFile *out; + if (torinAutosave) { + filename = g_sci->wrapFilename(Common::String::format("autosave.%03d", savegameId)); + } + out = saveFileMan->openForSaving(filename); if (!out) { warning("Error opening savegame \"%s\" for writing", filename.c_str()); @@ -816,6 +833,14 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { delete out; } + if (torinAutosave && !s->r_acc.isNull()) { + // Create autosave.cat so that the game can detect the presence + // of autosaves. + Common::WriteStream *t; + t = saveFileMan->openForSaving(g_sci->wrapFilename("autosave.cat")); + delete t; + } + return s->r_acc; } @@ -826,6 +851,10 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId); + + // See comment in kSaveGame + bool torinAutosave = g_sci->getGameId() == GID_TORIN && game_id == "Autosave"; + if (argv[0].isNull()) { // Direct call, either from launcher or from a patched Game::restore if (savegameId == -1) { @@ -841,7 +870,7 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { pausedMusic = true; } // don't adjust ID of the saved game, it's already correct - } else { + } else if (!torinAutosave) { if (g_sci->getGameId() == GID_JONES) { // Jones has one save slot only savegameId = 0; @@ -858,8 +887,9 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { s->r_acc = NULL_REG; // signals success Common::Array<SavegameDesc> saves; - listSavegames(saves); - if (findSavegame(saves, savegameId) == -1) { + if (!torinAutosave) + listSavegames(saves); + if (!torinAutosave && findSavegame(saves, savegameId) == -1) { s->r_acc = TRUE_REG; warning("Savegame ID %d not found", savegameId); } else { @@ -867,6 +897,10 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { Common::String filename = g_sci->getSavegameName(savegameId); Common::SeekableReadStream *in; + if (torinAutosave) { + filename = g_sci->wrapFilename(Common::String::format("autosave.%03d", savegameId)); + } + in = saveFileMan->openForLoading(filename); if (in) { // found a savegame file |