aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsluicebox2019-09-12 11:58:20 -0700
committersluicebox2019-09-12 11:58:20 -0700
commit698ca464d7d9c020374c1c80c98df70150083072 (patch)
tree6718fcf79995e546fe37c60f760270ce7eefeb5b
parent5c5130814bfa8d602eb8677b40d1b5ab4ed86bbe (diff)
downloadscummvm-rg350-698ca464d7d9c020374c1c80c98df70150083072.tar.gz
scummvm-rg350-698ca464d7d9c020374c1c80c98df70150083072.tar.bz2
scummvm-rg350-698ca464d7d9c020374c1c80c98df70150083072.zip
SCI32: Fix loading autosaves (slot 0)
Fixes bugs in trac #11029: - Slot 1 loading when user selects slot 0 in ScummVM UI - Slot 1 loading when slot 0 specified on command line - QFG4 slot 0 not appearing in game's original Restore UI
-rw-r--r--engines/sci/engine/file.cpp10
-rw-r--r--engines/sci/engine/file.h7
-rw-r--r--engines/sci/engine/guest_additions.cpp12
-rw-r--r--engines/sci/engine/kfile.cpp12
4 files changed, 27 insertions, 14 deletions
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index c311810997..8d93269604 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -349,9 +349,13 @@ void listSavegames(Common::Array<SavegameDesc> &saves) {
const Common::String &filename = *iter;
#ifdef ENABLE_SCI32
- const int id = strtol(filename.end() - 3, NULL, 10);
- if (id == kNewGameId || id == kAutoSaveId) {
- continue;
+ // exclude new game and autosave slots, except for QFG4,
+ // whose autosave should appear as a normal saved game
+ if (g_sci->getGameId() != GID_QFG4) {
+ const int id = strtol(filename.end() - 3, NULL, 10);
+ if (id == kNewGameId || id == kAutoSaveId) {
+ continue;
+ }
}
#endif
diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h
index b94caa039f..aafa881245 100644
--- a/engines/sci/engine/file.h
+++ b/engines/sci/engine/file.h
@@ -47,8 +47,11 @@ enum {
// SCI engine expects game IDs to start at 0, but slot 0 in ScummVM is
// reserved for autosave, so non-autosave games get their IDs shifted up
- // when saving or restoring, and shifted down when enumerating save games
- kSaveIdShift = 1
+ // when saving or restoring, and shifted down when enumerating save games.
+ // ScummVM slot 0 can't be shifted down as -1 is an illegal SCI save ID
+ // so it is instead wrapped around to 99 and then back to 0 when shifting up.
+ kSaveIdShift = 1,
+ kMaxShiftedSaveId = 99
};
#endif
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index f07fb4ce5f..7f5a11cb63 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -698,13 +698,15 @@ int GuestAdditions::runSaveRestore(const bool isSave, reg_t outDescription, cons
description.fromString(descriptionString);
}
+ // The autosave slot in ScummVM takes up slot 0, but in SCI the first
+ // non-autosave save game number needs to be 0, so reduce the save
+ // number here to match what would come from the normal SCI save/restore
+ // dialog. Wrap slot 0 around to kMaxShiftedSaveId so that it remains
+ // a legal SCI value.
if (saveNo > 0) {
- // The autosave slot in ScummVM takes up slot 0, but in SCI the first
- // non-autosave save game number needs to be 0, so reduce the save
- // number here to match what would come from the normal SCI save/restore
- // dialog. There is additional special code for handling the autosave
- // game inside of kRestoreGame32.
saveNo -= kSaveIdShift;
+ } else if (saveNo == 0) {
+ saveNo = kMaxShiftedSaveId;
}
return saveNo;
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 5edac18bc0..e3d4fb2afd 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -1333,6 +1333,8 @@ reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv) {
// Autosave slot 1 is a "new game" save
saveNo = kNewGameId;
}
+ } else if (saveNo == kMaxShiftedSaveId) {
+ saveNo = 0;
} else {
saveNo += kSaveIdShift;
}
@@ -1394,6 +1396,8 @@ reg_t kRestoreGame32(EngineState *s, int argc, reg_t *argv) {
// Autosave slot 1 is a "new game" save
saveNo = kNewGameId;
}
+ } else if (saveNo == kMaxShiftedSaveId) {
+ saveNo = 0;
} else {
saveNo += kSaveIdShift;
}
@@ -1419,13 +1423,12 @@ reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv) {
int16 saveNo = argv[1].toSint16();
const Common::String gameVersion = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
-
if (gameName == "Autosave" || gameName == "Autosv") {
if (saveNo == 1) {
saveNo = kNewGameId;
}
+ } else if (saveNo == kMaxShiftedSaveId) {
+ saveNo = 0;
} else {
saveNo += kSaveIdShift;
}
@@ -1488,7 +1491,8 @@ reg_t kGetSaveFiles32(EngineState *s, int argc, reg_t *argv) {
// At least Phant2 requires use of strncpy, since it creates save game
// names of exactly kMaxSaveNameLength
strncpy(target, save.name, kMaxSaveNameLength);
- saveIds.setFromInt16(i, save.id - kSaveIdShift);
+ int16 sciSaveId = (save.id == 0) ? kMaxShiftedSaveId : (save.id - kSaveIdShift);
+ saveIds.setFromInt16(i, sciSaveId);
}
descriptions.charAt(kMaxSaveNameLength * saves.size()) = '\0';