aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2016-09-15 09:02:55 -0500
committerColin Snover2016-09-29 19:39:16 -0500
commitc8516ff9ebc7480c2303b4ab2c151b46444e1911 (patch)
treee9496848a21736f0911ca7bb35b474467dd40289
parent1eb6d90eec4aa2dab3532e9630c81b6b3dbddafb (diff)
downloadscummvm-rg350-c8516ff9ebc7480c2303b4ab2c151b46444e1911.tar.gz
scummvm-rg350-c8516ff9ebc7480c2303b4ab2c151b46444e1911.tar.bz2
scummvm-rg350-c8516ff9ebc7480c2303b4ab2c151b46444e1911.zip
SCI32: Add handling for save catalogues
-rw-r--r--engines/sci/engine/kfile.cpp106
1 files changed, 52 insertions, 54 deletions
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 50560be7d1..cfb829bab2 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -229,6 +229,45 @@ reg_t kGetSavedCD(EngineState *s, int argc, reg_t *argv) {
// ---- FileIO operations -----------------------------------------------------
+#ifdef ENABLE_SCI32
+static bool isSaveCatalogue(const Common::String &name) {
+ return name == "autosave.cat" || name.hasSuffix("sg.cat");
+}
+
+// SCI32 save game scripts check for, and write directly to, the save game
+// catalogue. Since ScummVM does not use these catalogues, when looking for a
+// catalogue, we instead check for save games within ScummVM that are logically
+// equivalent to the behaviour of SSCI.
+static bool saveCatalogueExists(const Common::String &name) {
+ bool exists = false;
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+
+ // There will always be one save game in some games, the "new game"
+ // game, which should be ignored when deciding if there are any save
+ // games available
+ uint numPermanentSaves;
+ switch (g_sci->getGameId()) {
+ case GID_TORIN:
+ case GID_LSL7:
+ case GID_LIGHTHOUSE:
+ numPermanentSaves = 1;
+ break;
+ default:
+ numPermanentSaves = 0;
+ break;
+ }
+
+ // Torin uses autosave.cat; LSL7 uses autosvsg.cat
+ if (name == "autosave.cat" || name == "autosvsg.cat") {
+ exists = !saveFileMan->listSavefiles(g_sci->getSavegameName(0)).empty();
+ } else {
+ exists = saveFileMan->listSavefiles(g_sci->getSavegamePattern()).size() > numPermanentSaves;
+ }
+
+ return exists;
+}
+#endif
+
reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
if (!s)
return make_reg(0, getSciVersion());
@@ -264,30 +303,11 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, VIRTUALFILE_HANDLE_SCI32SAVE);
}
- // Torin's autosave system checks for the presence of autosave.cat
- // by opening it. Since we don't use .cat files, we instead check
- // for the autosave game.
- //
- // Similar logic is needed for torinsg.cat - this shows the "Open..." button
- // when continuing a game if it exists.
- //
- // TODO: Other games with autosave built in should be included here
- if (g_sci->getGameId() == GID_TORIN && (name == "autosave.cat" || name == "torinsg.cat")) {
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
-
- bool exists;
- if (name == "autosave.cat") {
- exists = !saveFileMan->listSavefiles(g_sci->getSavegameName(0)).empty();
- } else {
- // There will always be one save game in Torin, the "new game" game,
- // which should be ignored when deciding if there are any save games
- // to open
- exists = saveFileMan->listSavefiles(g_sci->getSavegamePattern()).size() > 1;
- }
-
+ if (isSaveCatalogue(name)) {
+ const bool exists = saveCatalogueExists(name);
if (exists) {
- // Dummy handle. Torin only checks if this is SIGNAL_REG,
- // and calls kFileIOClose on it.
+ // Dummy handle is used to represent the catalogue and ignore any
+ // direct game script writes
return make_reg(0, VIRTUALFILE_HANDLE_SCI32SAVE);
} else {
return SIGNAL_REG;
@@ -614,6 +634,12 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
+#ifdef ENABLE_SCI32
+ if (isSaveCatalogue(name)) {
+ return saveCatalogueExists(name) ? TRUE_REG : NULL_REG;
+ }
+#endif
+
// TODO: It may apparently be worth caching the existence of
// phantsg.dir, and possibly even keeping it open persistently
@@ -776,13 +802,6 @@ 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. (See kFileIOOpen.)
- 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()))
@@ -801,14 +820,6 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
g_sci->_soundCmd->pauseAll(false); // unpause music (we can't have it paused during save)
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
if (argv[2].isNull())
@@ -884,10 +895,6 @@ 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());
@@ -916,10 +923,6 @@ 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) {
@@ -935,7 +938,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 if (!torinAutosave) {
+ } else {
if (g_sci->getGameId() == GID_JONES) {
// Jones has one save slot only
savegameId = 0;
@@ -952,9 +955,8 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
s->r_acc = NULL_REG; // signals success
Common::Array<SavegameDesc> saves;
- if (!torinAutosave)
- listSavegames(saves);
- if (!torinAutosave && findSavegame(saves, savegameId) == -1) {
+ listSavegames(saves);
+ if (findSavegame(saves, savegameId) == -1) {
s->r_acc = TRUE_REG;
warning("Savegame ID %d not found", savegameId);
} else {
@@ -962,10 +964,6 @@ 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