[Scummvm-git-logs] scummvm master -> 6aeda1224741b4b07935f6932355c5decc7ce0b9
sev-
sev at scummvm.org
Mon Aug 23 11:34:40 UTC 2021
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7adad5aaf5 ENGINES: Streamline auto-save write/delete protection
fb8f233ed7 BACKENDS: Replace virtual with override in SaveFileManager subclasses
a0c818bde6 COMMON: Introduce SaveFileManager::exists
6aeda12247 ENGINES: Warn when overwriting a non-autosave on autosave
Commit: 7adad5aaf5831dc5adcee140f38aacc4a5db2518
https://github.com/scummvm/scummvm/commit/7adad5aaf5831dc5adcee140f38aacc4a5db2518
Author: Orgad Shaneh (orgads at gmail.com)
Date: 2021-08-23T13:34:35+02:00
Commit Message:
ENGINES: Streamline auto-save write/delete protection
Some engines call setAutosave and some don't. isAutosave is used to
determine if a saved game is an autosave, but in fact, on most cases it
just falls back to comparing the name to "Autosave".
This is wrong for several reasons:
* Older versions of ScummVM used Autosave 0.
* The name "Autosave" is translated, so if you change the language, it
won't be detected.
Instead of relying on the name, use the well-known getAutosaveSlot() from
Engine/MetaEngine.
Fixes #12735.
Changed paths:
engines/agi/metaengine.cpp
engines/ags/metaengine.cpp
engines/bbvs/metaengine.cpp
engines/cge/metaengine.cpp
engines/cge2/metaengine.cpp
engines/cine/metaengine.cpp
engines/dragons/metaengine.cpp
engines/drascula/metaengine.cpp
engines/drascula/saveload.cpp
engines/hugo/metaengine.cpp
engines/illusions/metaengine.cpp
engines/kyra/metaengine.cpp
engines/lab/metaengine.cpp
engines/lilliput/metaengine.cpp
engines/macventure/metaengine.cpp
engines/macventure/saveload.cpp
engines/metaengine.cpp
engines/mohawk/myst_state.cpp
engines/mortevielle/saveload.cpp
engines/neverhood/metaengine.cpp
engines/savestate.cpp
engines/savestate.h
engines/sci/metaengine.cpp
engines/scumm/metaengine.cpp
engines/startrek/metaengine.cpp
engines/trecision/metaengine.cpp
engines/zvision/metaengine.cpp
diff --git a/engines/agi/metaengine.cpp b/engines/agi/metaengine.cpp
index a1d9b5c162..b67652ed6a 100644
--- a/engines/agi/metaengine.cpp
+++ b/engines/agi/metaengine.cpp
@@ -263,16 +263,6 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl
SaveStateDescriptor descriptor(slotNr, description);
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- if (slotNr == 0) {
- descriptor.setWriteProtectedFlag(true);
- descriptor.setDeletableFlag(false);
- } else {
- descriptor.setWriteProtectedFlag(false);
- descriptor.setDeletableFlag(true);
- }
-
char saveVersion = in->readByte();
if (saveVersion >= 4) {
Graphics::Surface *thumbnail;
@@ -313,6 +303,7 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl
SaveStateDescriptor emptySave;
// Do not allow save slot 0 (used for auto-saving) to be overwritten.
if (slotNr == 0) {
+ emptySave.setAutosave(true);
emptySave.setWriteProtectedFlag(true);
} else {
emptySave.setWriteProtectedFlag(false);
diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp
index a5696a2229..2663e24146 100644
--- a/engines/ags/metaengine.cpp
+++ b/engines/ags/metaengine.cpp
@@ -69,13 +69,7 @@ SaveStateList AGSMetaEngine::listSaves(const char *target) const {
if (slotNum > maxSlot)
continue;
- SaveStateDescriptor desc;
- desc.setSaveSlot(slotNum);
- desc.setDescription(rich_media_header.getSaveName());
-
- if (slotNum == getAutosaveSlot())
- desc.setWriteProtectedFlag(true);
-
+ SaveStateDescriptor desc(slotNum, rich_media_header.getSaveName());
saveList.push_back(desc);
}
}
@@ -117,12 +111,7 @@ SaveStateDescriptor AGSMetaEngine::querySaveMetaInfos(const char *target, int sl
rich_media_header.ReadFromFile(&saveFile);
if (rich_media_header.dwMagicNumber == RM_MAGICNUMBER) {
- SaveStateDescriptor desc;
- desc.setSaveSlot(slot);
- if (slot == getAutosaveSlot()) {
- desc.setAutosave(true);
- desc.setWriteProtectedFlag(true);
- }
+ SaveStateDescriptor desc(slot, Common::U32String());
// Thumbnail handling
if (rich_media_header.dwThumbnailOffsetLowerDword != 0 &&
diff --git a/engines/bbvs/metaengine.cpp b/engines/bbvs/metaengine.cpp
index ead8186c7a..d161ef09eb 100644
--- a/engines/bbvs/metaengine.cpp
+++ b/engines/bbvs/metaengine.cpp
@@ -108,9 +108,6 @@ SaveStateDescriptor BbvsMetaEngine::querySaveMetaInfos(const char *target, int s
delete in;
if (error == Bbvs::BbvsEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
- // Slot 0 is used for the "Continue" save
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
desc.setThumbnail(header.thumbnail);
desc.setSaveDate(header.saveDate & 0xFFFF, (header.saveDate >> 16) & 0xFF, (header.saveDate >> 24) & 0xFF);
desc.setSaveTime((header.saveTime >> 16) & 0xFF, (header.saveTime >> 8) & 0xFF);
diff --git a/engines/cge/metaengine.cpp b/engines/cge/metaengine.cpp
index ede99e9129..ff1c023664 100644
--- a/engines/cge/metaengine.cpp
+++ b/engines/cge/metaengine.cpp
@@ -141,11 +141,6 @@ SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int sl
desc.setPlayTime(header.playTime * 1000);
}
- // Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
- // we prevent it from being deleted or overwritten by accident.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
return desc;
}
}
diff --git a/engines/cge2/metaengine.cpp b/engines/cge2/metaengine.cpp
index 336e52d2cb..3bb447ce76 100644
--- a/engines/cge2/metaengine.cpp
+++ b/engines/cge2/metaengine.cpp
@@ -141,11 +141,6 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
desc.setPlayTime(header.playTime * 1000);
}
- // Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
- // we prevent it from being deleted or overwritten by accident.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
return desc;
}
}
diff --git a/engines/cine/metaengine.cpp b/engines/cine/metaengine.cpp
index 9783596027..074ad73579 100644
--- a/engines/cine/metaengine.cpp
+++ b/engines/cine/metaengine.cpp
@@ -128,8 +128,6 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
saveDesc[sizeof(CommandeType) - 1] = 0;
SaveStateDescriptor saveStateDesc(slotNum, saveDesc);
- saveStateDesc.setAutosave(slotNum == getAutosaveSlot());
- saveStateDesc.setWriteProtectedFlag(saveStateDesc.isAutosave());
if (saveStateDesc.getDescription().empty()) {
if (saveStateDesc.isAutosave()) {
@@ -152,10 +150,7 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
// No saving on empty autosave slot
if (!foundAutosave) {
- SaveStateDescriptor desc;
- desc.setDescription(_("Empty autosave"));
- desc.setSaveSlot(getAutosaveSlot());
- desc.setWriteProtectedFlag(true);
+ SaveStateDescriptor desc(getAutosaveSlot(), _("Empty autosave"));
saveList.push_back(desc);
}
@@ -184,7 +179,7 @@ SaveStateDescriptor CineMetaEngine::querySaveMetaInfos(const char *target, int s
if (f) {
// Create the return descriptor
- SaveStateDescriptor desc;
+ SaveStateDescriptor desc(slot, Common::U32String());
ExtendedSavegameHeader header;
if (readSavegameHeader(f.get(), &header, false)) {
@@ -213,21 +208,12 @@ SaveStateDescriptor CineMetaEngine::querySaveMetaInfos(const char *target, int s
desc.setDescription(_("Unnamed savegame"));
}
- desc.setSaveSlot(slot);
- desc.setAutosave(slot == getAutosaveSlot());
- desc.setWriteProtectedFlag(desc.isAutosave());
-
return desc;
}
// No saving on empty autosave slot
if (slot == getAutosaveSlot()) {
- SaveStateDescriptor desc;
- desc.setDescription(_("Empty autosave"));
- desc.setSaveSlot(slot);
- desc.setAutosave(true);
- desc.setWriteProtectedFlag(true);
- return desc;
+ return SaveStateDescriptor(slot, _("Empty autosave"));
}
return SaveStateDescriptor();
diff --git a/engines/dragons/metaengine.cpp b/engines/dragons/metaengine.cpp
index d841644a09..f3d2bc2a69 100644
--- a/engines/dragons/metaengine.cpp
+++ b/engines/dragons/metaengine.cpp
@@ -100,9 +100,6 @@ SaveStateDescriptor DragonsMetaEngine::querySaveMetaInfos(const char *target, in
delete in;
if (error == Dragons::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
- // Slot 0 is used for the "Continue" save
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
desc.setThumbnail(header.thumbnail);
desc.setSaveDate(header.saveDate & 0xFFFF, (header.saveDate >> 16) & 0xFF, (header.saveDate >> 24) & 0xFF);
desc.setSaveTime((header.saveTime >> 16) & 0xFF, (header.saveTime >> 8) & 0xFF);
diff --git a/engines/drascula/metaengine.cpp b/engines/drascula/metaengine.cpp
index a1cd28b40d..de743cb934 100644
--- a/engines/drascula/metaengine.cpp
+++ b/engines/drascula/metaengine.cpp
@@ -124,12 +124,7 @@ SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, i
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
- SaveStateDescriptor desc;
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
+ SaveStateDescriptor desc(slot, Common::U32String());
if (in) {
desc = Drascula::loadMetaData(in, slot, false);
if (desc.getSaveSlot() != slot) {
diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp
index 7305f92197..3da19af000 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -105,7 +105,7 @@ SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot, bool setPlayTi
uint32 sig = s->readUint32BE();
byte version = s->readByte();
- SaveStateDescriptor desc(-1, ""); // init to an invalid save slot
+ SaveStateDescriptor desc; // init to an invalid save slot
if (sig != MAGIC_HEADER || version > SAVEGAME_VERSION)
return desc;
diff --git a/engines/hugo/metaengine.cpp b/engines/hugo/metaengine.cpp
index 731bc5e479..ae48574d30 100644
--- a/engines/hugo/metaengine.cpp
+++ b/engines/hugo/metaengine.cpp
@@ -164,11 +164,6 @@ SaveStateDescriptor HugoMetaEngine::querySaveMetaInfos(const char *target, int s
desc.setSaveTime(hour, minutes);
- // Slot 0 is used for the 'restart game' save in all Hugo games, thus
- // we prevent it from being deleted.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
delete file;
return desc;
}
diff --git a/engines/illusions/metaengine.cpp b/engines/illusions/metaengine.cpp
index 0c84a87483..3ac5efa25d 100644
--- a/engines/illusions/metaengine.cpp
+++ b/engines/illusions/metaengine.cpp
@@ -114,9 +114,6 @@ SaveStateDescriptor IllusionsMetaEngine::querySaveMetaInfos(const char *target,
delete in;
if (error == Illusions::IllusionsEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
- // Slot 0 is used for the "Continue" save
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
desc.setThumbnail(header.thumbnail);
desc.setSaveDate(header.saveDate & 0xFFFF, (header.saveDate >> 16) & 0xFF, (header.saveDate >> 24) & 0xFF);
desc.setSaveTime((header.saveTime >> 16) & 0xFF, (header.saveTime >> 8) & 0xFF);
diff --git a/engines/kyra/metaengine.cpp b/engines/kyra/metaengine.cpp
index f2c1686ac8..f931ff17d1 100644
--- a/engines/kyra/metaengine.cpp
+++ b/engines/kyra/metaengine.cpp
@@ -212,6 +212,8 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
+ if (slot == 0 && !nonKyraGame)
+ desc.setAutosave(true);
desc.setThumbnail(header.thumbnail);
return desc;
@@ -224,6 +226,8 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
+ if (slot == 0 && !nonKyraGame)
+ desc.setAutosave(true);
return desc;
}
diff --git a/engines/lab/metaengine.cpp b/engines/lab/metaengine.cpp
index edc35a7042..ed3325c4a4 100644
--- a/engines/lab/metaengine.cpp
+++ b/engines/lab/metaengine.cpp
@@ -131,11 +131,6 @@ SaveStateDescriptor LabMetaEngine::querySaveMetaInfos(const char *target, int sl
if (successfulRead) {
SaveStateDescriptor desc(slot, header._descr.getDescription());
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- //desc.setDeletableFlag(slot != 0);
- //desc.setWriteProtectedFlag(slot == 0);
-
return header._descr;
}
}
diff --git a/engines/lilliput/metaengine.cpp b/engines/lilliput/metaengine.cpp
index a33b44833b..72836cc895 100644
--- a/engines/lilliput/metaengine.cpp
+++ b/engines/lilliput/metaengine.cpp
@@ -156,9 +156,6 @@ SaveStateDescriptor LilliputMetaEngine::querySaveMetaInfos(const char *target, i
}
desc.setThumbnail(thumbnail);
- desc.setDeletableFlag(true);
- desc.setWriteProtectedFlag(false);
-
uint32 saveDate = file->readUint32BE();
uint16 saveTime = file->readUint16BE();
@@ -173,11 +170,6 @@ SaveStateDescriptor LilliputMetaEngine::querySaveMetaInfos(const char *target, i
desc.setSaveTime(hour, minutes);
- // Slot 0 is used for the 'restart game' save in all Robin games, thus
- // we prevent it from being deleted.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
delete file;
return desc;
}
diff --git a/engines/macventure/metaengine.cpp b/engines/macventure/metaengine.cpp
index 42bed3b36b..aa76d77ac8 100644
--- a/engines/macventure/metaengine.cpp
+++ b/engines/macventure/metaengine.cpp
@@ -85,12 +85,7 @@ SaveStateList MacVentureMetaEngine::listSaves(const char *target) const {
SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
int slotNum = atoi(file->c_str() + file->size() - 3);
- SaveStateDescriptor desc;
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- desc.setDeletableFlag(slotNum != 0);
- desc.setWriteProtectedFlag(slotNum == 0);
-
+ SaveStateDescriptor desc(slotNum, Common::U32String());
if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
@@ -143,7 +138,7 @@ SaveStateDescriptor MacVentureMetaEngine::querySaveMetaInfos(const char *target,
delete in;
return desc;
}
- return SaveStateDescriptor(-1, "");
+ return SaveStateDescriptor();
}
} // End of namespace MacVenture
diff --git a/engines/macventure/saveload.cpp b/engines/macventure/saveload.cpp
index 687b96a020..c4f9fbea8a 100644
--- a/engines/macventure/saveload.cpp
+++ b/engines/macventure/saveload.cpp
@@ -52,7 +52,7 @@ SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool s
uint32 sig = s->readUint32BE();
byte version = s->readByte();
- SaveStateDescriptor desc(-1, ""); // init to an invalid save slot
+ SaveStateDescriptor desc; // init to an invalid save slot
if (sig != MACVENTURE_SAVE_HEADER || version > MACVENTURE_SAVE_VERSION)
return desc;
diff --git a/engines/metaengine.cpp b/engines/metaengine.cpp
index 0ef1431dc0..4821ca0066 100644
--- a/engines/metaengine.cpp
+++ b/engines/metaengine.cpp
@@ -331,21 +331,14 @@ SaveStateList MetaEngine::listSaves(const char *target, bool saveMode) const {
// Check to see if an autosave is present
for (SaveStateList::iterator it = saveList.begin(); it != saveList.end(); ++it) {
- int slot = it->getSaveSlot();
- if (slot == autosaveSlot) {
- // It has an autosave
- it->setWriteProtectedFlag(true);
+ // It has an autosave
+ if (it->isAutosave())
return saveList;
- }
}
// No autosave yet. We want to add a dummy one in so that it can be marked as'
// write protected, and thus be prevented from being saved in
- SaveStateDescriptor desc;
- desc.setDescription(_("Autosave"));
- desc.setSaveSlot(autosaveSlot);
- desc.setWriteProtectedFlag(true);
-
+ SaveStateDescriptor desc(autosaveSlot, _("Autosave"));
saveList.push_back(desc);
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
@@ -393,16 +386,9 @@ SaveStateDescriptor MetaEngine::querySaveMetaInfos(const char *target, int slot)
}
// Create the return descriptor
- SaveStateDescriptor desc;
-
+ SaveStateDescriptor desc(slot, Common::U32String());
parseSavegameHeader(&header, &desc);
-
- desc.setSaveSlot(slot);
desc.setThumbnail(header.thumbnail);
- desc.setAutosave(header.isAutosave);
- if (slot == getAutosaveSlot())
- desc.setWriteProtectedFlag(true);
-
return desc;
}
diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp
index 574f6c32a8..d3115d1bd7 100644
--- a/engines/mohawk/myst_state.cpp
+++ b/engines/mohawk/myst_state.cpp
@@ -269,8 +269,7 @@ bool MystGameState::saveMetadata(int slot, const Graphics::Surface *thumbnail) {
}
SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) {
- SaveStateDescriptor desc;
- desc.setWriteProtectedFlag(slot == kAutoSaveSlot);
+ SaveStateDescriptor desc(slot, Common::U32String());
// Open the save file
Common::String filename = buildSaveFilename(slot);
@@ -281,8 +280,6 @@ SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) {
delete saveFile;
// There is a save in the slot
- desc.setSaveSlot(slot);
-
// Open the metadata file
filename = buildMetadataFilename(slot);
Common::InSaveFile *metadataFile = g_system->getSavefileManager()->openForLoading(filename);
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index d96ecbb0b0..598c706869 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -303,10 +303,7 @@ SaveStateDescriptor SavegameManager::querySaveMetaInfos(const Common::String &fi
// Original savegame perhaps?
delete f;
- SaveStateDescriptor desc(slot, Common::String::format("Savegame - %03d", slot));
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
- return desc;
+ return SaveStateDescriptor(slot, Common::String::format("Savegame - %03d", slot));
} else {
// Get the savegame header information
SavegameHeader header;
diff --git a/engines/neverhood/metaengine.cpp b/engines/neverhood/metaengine.cpp
index b0da9288c2..6aad3daf43 100644
--- a/engines/neverhood/metaengine.cpp
+++ b/engines/neverhood/metaengine.cpp
@@ -148,8 +148,6 @@ SaveStateDescriptor NeverhoodMetaEngine::querySaveMetaInfos(const char *target,
if (error == Neverhood::NeverhoodEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
- desc.setDeletableFlag(false);
- desc.setWriteProtectedFlag(false);
desc.setThumbnail(header.thumbnail);
int day = (header.saveDate >> 24) & 0xFF;
int month = (header.saveDate >> 16) & 0xFF;
diff --git a/engines/savestate.cpp b/engines/savestate.cpp
index e63a89a3e1..83d5bccb79 100644
--- a/engines/savestate.cpp
+++ b/engines/savestate.cpp
@@ -21,7 +21,9 @@
*/
#include "engines/savestate.h"
+#include "engines/engine.h"
#include "graphics/surface.h"
+#include "common/config-manager.h"
#include "common/textconsole.h"
#include "common/translation.h"
@@ -32,16 +34,24 @@ SaveStateDescriptor::SaveStateDescriptor()
_thumbnail(), _saveType(kSaveTypeUndetermined) {
}
-SaveStateDescriptor::SaveStateDescriptor(int s, const Common::U32String &d)
- : _slot(s), _description(d), _isDeletable(true), _isWriteProtected(false),
- _isLocked(false), _saveDate(), _saveTime(), _playTime(), _playTimeMSecs(0),
- _thumbnail(), _saveType(kSaveTypeUndetermined) {
+SaveStateDescriptor::SaveStateDescriptor(int slot, const Common::U32String &d)
+ : _slot(slot), _description(d), _isLocked(false), _playTimeMSecs(0) {
+ initSaveType();
}
-SaveStateDescriptor::SaveStateDescriptor(int s, const Common::String &d)
- : _slot(s), _description(Common::U32String(d)), _isDeletable(true), _isWriteProtected(false),
- _isLocked(false), _saveDate(), _saveTime(), _playTime(), _playTimeMSecs(0),
- _thumbnail(), _saveType(kSaveTypeUndetermined) {
+SaveStateDescriptor::SaveStateDescriptor(int slot, const Common::String &d)
+ : _slot(slot), _description(Common::U32String(d)), _isLocked(false), _playTimeMSecs(0) {
+ initSaveType();
+}
+
+void SaveStateDescriptor::initSaveType()
+{
+ // Do not allow auto-save slot to be deleted or overwritten.
+ const bool autosave =
+ g_engine && ConfMan.getInt("autosave_period") && _slot == g_engine->getAutosaveSlot();
+ _isWriteProtected = autosave;
+ _saveType = autosave ? kSaveTypeAutosave : kSaveTypeRegular;
+ _isDeletable = !autosave;
}
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
diff --git a/engines/savestate.h b/engines/savestate.h
index 59532040e5..fa126877b4 100644
--- a/engines/savestate.h
+++ b/engines/savestate.h
@@ -59,10 +59,12 @@ private:
kSaveTypeRegular,
kSaveTypeAutosave
};
+
+ void initSaveType();
public:
SaveStateDescriptor();
- SaveStateDescriptor(int s, const Common::U32String &d);
- SaveStateDescriptor(int s, const Common::String &d);
+ SaveStateDescriptor(int slot, const Common::U32String &d);
+ SaveStateDescriptor(int slot, const Common::String &d);
/**
* @param slot The saveslot id, as it would be passed to the "-x" command line switch.
diff --git a/engines/sci/metaengine.cpp b/engines/sci/metaengine.cpp
index 1edd321699..2b4e22ed9d 100644
--- a/engines/sci/metaengine.cpp
+++ b/engines/sci/metaengine.cpp
@@ -353,12 +353,8 @@ SaveStateList SciMetaEngine::listSaves(const char *target) const {
}
SaveStateDescriptor descriptor(slotNr, meta.name);
- if (slotNr == 0) {
- // ScummVM auto-save slot
- descriptor.setWriteProtectedFlag(true);
+ if (descriptor.isAutosave()) {
hasAutosave = true;
- } else {
- descriptor.setWriteProtectedFlag(false);
}
saveList.push_back(descriptor);
@@ -383,15 +379,6 @@ SaveStateDescriptor SciMetaEngine::querySaveMetaInfos(const char *target, int sl
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
SaveStateDescriptor descriptor(slotNr, "");
- if (slotNr == 0) {
- // ScummVM auto-save slot
- descriptor.setWriteProtectedFlag(true);
- descriptor.setDeletableFlag(false);
- } else {
- descriptor.setWriteProtectedFlag(false);
- descriptor.setDeletableFlag(true);
- }
-
if (in) {
SavegameMetadata meta;
diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index 904ed55798..2ab4cc051d 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -505,14 +505,6 @@ SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int
}
SaveStateDescriptor desc(slot, saveDesc);
-
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- if (slot == 0) {
- desc.setWriteProtectedFlag(true);
- desc.setDeletableFlag(false);
- }
-
desc.setThumbnail(thumbnail);
if (infoPtr) {
diff --git a/engines/startrek/metaengine.cpp b/engines/startrek/metaengine.cpp
index e6902e091b..ceba864b2a 100644
--- a/engines/startrek/metaengine.cpp
+++ b/engines/startrek/metaengine.cpp
@@ -163,16 +163,6 @@ SaveStateDescriptor StarTrekMetaEngine::querySaveMetaInfos(const char *target, i
SaveStateDescriptor descriptor(slotNr, meta.description);
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- if (slotNr == 0) {
- descriptor.setWriteProtectedFlag(true);
- descriptor.setDeletableFlag(false);
- } else {
- descriptor.setWriteProtectedFlag(false);
- descriptor.setDeletableFlag(true);
- }
-
if (meta.thumbnail == nullptr) {
return SaveStateDescriptor();
}
@@ -185,13 +175,7 @@ SaveStateDescriptor StarTrekMetaEngine::querySaveMetaInfos(const char *target, i
return descriptor;
} else {
- SaveStateDescriptor emptySave;
- // Do not allow save slot 0 (used for auto-saving) to be overwritten.
- if (slotNr == 0) {
- emptySave.setWriteProtectedFlag(true);
- } else {
- emptySave.setWriteProtectedFlag(false);
- }
+ SaveStateDescriptor emptySave(slotNr, Common::U32String());
return emptySave;
}
}
diff --git a/engines/trecision/metaengine.cpp b/engines/trecision/metaengine.cpp
index 0e751e7d45..165bfd6d05 100644
--- a/engines/trecision/metaengine.cpp
+++ b/engines/trecision/metaengine.cpp
@@ -62,9 +62,6 @@ SaveStateDescriptor TrecisionMetaEngine::querySaveMetaInfos(const char *target,
Common::String saveName = saveFile->readString(0, 40);
SaveStateDescriptor desc(slot, saveName);
- desc.setAutosave(false);
- if (slot == getAutosaveSlot())
- desc.setWriteProtectedFlag(true);
// This is freed inside SaveStateDescriptor
const Graphics::PixelFormat kImageFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
diff --git a/engines/zvision/metaengine.cpp b/engines/zvision/metaengine.cpp
index dd6cbf494a..31feac4360 100644
--- a/engines/zvision/metaengine.cpp
+++ b/engines/zvision/metaengine.cpp
@@ -297,11 +297,6 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in
if (successfulRead) {
SaveStateDescriptor desc(slot, header.saveName);
- // Do not allow save slot 0 (used for auto-saving) to be deleted or
- // overwritten.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
desc.setThumbnail(header.thumbnail);
if (header.version >= 1) {
Commit: fb8f233ed7a75f0df982807c13465198be45a2ed
https://github.com/scummvm/scummvm/commit/fb8f233ed7a75f0df982807c13465198be45a2ed
Author: Orgad Shaneh (orgads at gmail.com)
Date: 2021-08-23T13:34:35+02:00
Commit Message:
BACKENDS: Replace virtual with override in SaveFileManager subclasses
Changed paths:
backends/platform/dc/vmsave.cpp
backends/platform/n64/framfs_save_manager.h
backends/platform/n64/pakfs_save_manager.h
backends/saves/default/default-saves.h
diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp
index ab5a3e77a2..2c98b65dd2 100644
--- a/backends/platform/dc/vmsave.cpp
+++ b/backends/platform/dc/vmsave.cpp
@@ -306,7 +306,7 @@ public:
vmsfs_name_compare_function = nameCompare;
}
- virtual Common::InSaveFile *openRawFile(const Common::String &filename) {
+ Common::InSaveFile *openRawFile(const Common::String &filename) override {
InVMSave *s = new InVMSave();
if (s->readSaveGame(filename.c_str())) {
return s;
@@ -316,26 +316,26 @@ public:
}
}
- virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) {
+ Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) override {
OutVMSave *s = new OutVMSave(filename.c_str());
return new Common::OutSaveFile(compress ? Common::wrapCompressedWriteStream(s) : s);
}
- virtual Common::InSaveFile *openForLoading(const Common::String &filename) {
- InVMSave *s = new InVMSave();
- if (s->readSaveGame(filename.c_str())) {
- return Common::wrapCompressedReadStream(s);
- } else {
- delete s;
- return NULL;
+ Common::InSaveFile *openForLoading(const Common::String &filename) override {
+ InVMSave *s = new InVMSave();
+ if (s->readSaveGame(filename.c_str())) {
+ return Common::wrapCompressedReadStream(s);
+ } else {
+ delete s;
+ return NULL;
+ }
}
- }
- virtual bool removeSavefile(const Common::String &filename) {
- return ::deleteSaveGame(filename.c_str());
- }
+ bool removeSavefile(const Common::String &filename) override {
+ return ::deleteSaveGame(filename.c_str());
+ }
- virtual Common::StringArray listSavefiles(const Common::String &pattern);
+ Common::StringArray listSavefiles(const Common::String &pattern) override;
};
void OutVMSave::finalize()
diff --git a/backends/platform/n64/framfs_save_manager.h b/backends/platform/n64/framfs_save_manager.h
index 209d53a08b..b7c5ebfbd2 100644
--- a/backends/platform/n64/framfs_save_manager.h
+++ b/backends/platform/n64/framfs_save_manager.h
@@ -102,13 +102,13 @@ public:
class FRAMSaveManager : public Common::SaveFileManager {
public:
- virtual void updateSavefilesList(Common::StringArray &lockedFiles) {
+ void updateSavefilesList(Common::StringArray &lockedFiles) override {
// this method is used to lock saves while cloud syncing
// as there is no network on N64, this method wouldn't be used
// thus it's not implemtented
}
- virtual Common::InSaveFile *openRawFile(const Common::String &filename) {
+ Common::InSaveFile *openRawFile(const Common::String &filename) override {
InFRAMSave *s = new InFRAMSave();
if (s->readSaveGame(filename.c_str())) {
return s;
@@ -118,7 +118,7 @@ public:
}
}
- virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) {
+ Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) override {
OutFRAMSave *s = new OutFRAMSave(filename.c_str());
if (!s->err()) {
return new Common::OutSaveFile(compress ? Common::wrapCompressedWriteStream(s) : s);
@@ -128,7 +128,7 @@ public:
}
}
- virtual Common::InSaveFile *openForLoading(const Common::String &filename) {
+ Common::InSaveFile *openForLoading(const Common::String &filename) override {
InFRAMSave *s = new InFRAMSave();
if (s->readSaveGame(filename.c_str())) {
return Common::wrapCompressedReadStream(s);
@@ -138,11 +138,11 @@ public:
}
}
- virtual bool removeSavefile(const Common::String &filename) {
+ bool removeSavefile(const Common::String &filename) override {
return ::fram_deleteSaveGame(filename.c_str());
}
- virtual Common::StringArray listSavefiles(const Common::String &pattern);
+ Common::StringArray listSavefiles(const Common::String &pattern) override;
};
diff --git a/backends/platform/n64/pakfs_save_manager.h b/backends/platform/n64/pakfs_save_manager.h
index 56b49ebcf8..d6f33e597a 100644
--- a/backends/platform/n64/pakfs_save_manager.h
+++ b/backends/platform/n64/pakfs_save_manager.h
@@ -104,13 +104,13 @@ public:
class PAKSaveManager : public Common::SaveFileManager {
public:
- virtual void updateSavefilesList(Common::StringArray &lockedFiles) {
+ void updateSavefilesList(Common::StringArray &lockedFiles) override {
// this method is used to lock saves while cloud syncing
// as there is no network on N64, this method wouldn't be used
// thus it's not implemtented
}
- virtual Common::InSaveFile *openRawFile(const Common::String &filename) {
+ Common::InSaveFile *openRawFile(const Common::String &filename) override {
InPAKSave *s = new InPAKSave();
if (s->readSaveGame(filename.c_str())) {
return s;
@@ -120,7 +120,7 @@ public:
}
}
- virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) {
+ Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) override {
OutPAKSave *s = new OutPAKSave(filename.c_str());
if (!s->err()) {
return new Common::OutSaveFile(compress ? Common::wrapCompressedWriteStream(s) : s);
@@ -130,7 +130,7 @@ public:
}
}
- virtual Common::InSaveFile *openForLoading(const Common::String &filename) {
+ Common::InSaveFile *openForLoading(const Common::String &filename) override {
InPAKSave *s = new InPAKSave();
if (s->readSaveGame(filename.c_str())) {
return Common::wrapCompressedReadStream(s);
@@ -140,11 +140,11 @@ public:
}
}
- virtual bool removeSavefile(const Common::String &filename) {
+ bool removeSavefile(const Common::String &filename) override {
return ::pakfs_deleteSaveGame(filename.c_str());
}
- virtual Common::StringArray listSavefiles(const Common::String &pattern);
+ Common::StringArray listSavefiles(const Common::String &pattern) override;
};
diff --git a/backends/saves/default/default-saves.h b/backends/saves/default/default-saves.h
index 2801dd5e01..1bd8e3d618 100644
--- a/backends/saves/default/default-saves.h
+++ b/backends/saves/default/default-saves.h
@@ -38,12 +38,12 @@ public:
DefaultSaveFileManager();
DefaultSaveFileManager(const Common::String &defaultSavepath);
- virtual void updateSavefilesList(Common::StringArray &lockedFiles);
- virtual Common::StringArray listSavefiles(const Common::String &pattern);
- virtual Common::InSaveFile *openRawFile(const Common::String &filename);
- virtual Common::InSaveFile *openForLoading(const Common::String &filename);
- virtual Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true);
- virtual bool removeSavefile(const Common::String &filename);
+ void updateSavefilesList(Common::StringArray &lockedFiles) override;
+ Common::StringArray listSavefiles(const Common::String &pattern) override;
+ Common::InSaveFile *openRawFile(const Common::String &filename) override;
+ Common::InSaveFile *openForLoading(const Common::String &filename) override;
+ Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) override;
+ bool removeSavefile(const Common::String &filename) override;
#ifdef USE_LIBCURL
Commit: a0c818bde6c472130eaead85f2f2bc3cdf0ce997
https://github.com/scummvm/scummvm/commit/a0c818bde6c472130eaead85f2f2bc3cdf0ce997
Author: Orgad Shaneh (orgads at gmail.com)
Date: 2021-08-23T13:34:35+02:00
Commit Message:
COMMON: Introduce SaveFileManager::exists
Checks if a savefile with given name exists.
Implement on all backends.
Changed paths:
backends/platform/dc/vmsave.cpp
backends/platform/n64/framfs_save_manager.h
backends/platform/n64/pakfs_save_manager.h
backends/saves/default/default-saves.cpp
backends/saves/default/default-saves.h
common/savefile.h
diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp
index 2c98b65dd2..44daba90a4 100644
--- a/backends/platform/dc/vmsave.cpp
+++ b/backends/platform/dc/vmsave.cpp
@@ -336,6 +336,10 @@ public:
}
Common::StringArray listSavefiles(const Common::String &pattern) override;
+
+ bool exists(const Common::String &filename) override {
+ return InVMSave().readSaveGame(filename.c_str());
+ }
};
void OutVMSave::finalize()
diff --git a/backends/platform/n64/framfs_save_manager.h b/backends/platform/n64/framfs_save_manager.h
index b7c5ebfbd2..7b92cc874d 100644
--- a/backends/platform/n64/framfs_save_manager.h
+++ b/backends/platform/n64/framfs_save_manager.h
@@ -143,6 +143,10 @@ public:
}
Common::StringArray listSavefiles(const Common::String &pattern) override;
+
+ bool exists(const Common::String &filename) override {
+ return InFRAMSave().readSaveGame(filename.c_str());
+ }
};
diff --git a/backends/platform/n64/pakfs_save_manager.h b/backends/platform/n64/pakfs_save_manager.h
index d6f33e597a..0ee2d8b4c0 100644
--- a/backends/platform/n64/pakfs_save_manager.h
+++ b/backends/platform/n64/pakfs_save_manager.h
@@ -145,6 +145,10 @@ public:
}
Common::StringArray listSavefiles(const Common::String &pattern) override;
+
+ bool exists(const Common::String &filename) override {
+ return InPAKSave().readSaveGame(filename.c_str());
+ }
};
diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp
index eb5e89bf63..d6129a224c 100644
--- a/backends/saves/default/default-saves.cpp
+++ b/backends/saves/default/default-saves.cpp
@@ -222,6 +222,20 @@ bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) {
}
}
+bool DefaultSaveFileManager::exists(const Common::String &filename) {
+ // Assure the savefile name cache is up-to-date.
+ assureCached(getSavePath());
+ if (getError().getCode() != Common::kNoError)
+ return false;
+
+ for (Common::StringArray::const_iterator i = _lockedFiles.begin(), end = _lockedFiles.end(); i != end; ++i) {
+ if (filename == *i)
+ return true;
+ }
+
+ return _saveFileCache.contains(filename);
+}
+
Common::String DefaultSaveFileManager::getSavePath() const {
Common::String dir;
diff --git a/backends/saves/default/default-saves.h b/backends/saves/default/default-saves.h
index 1bd8e3d618..0557ffdc38 100644
--- a/backends/saves/default/default-saves.h
+++ b/backends/saves/default/default-saves.h
@@ -44,6 +44,7 @@ public:
Common::InSaveFile *openForLoading(const Common::String &filename) override;
Common::OutSaveFile *openForSaving(const Common::String &filename, bool compress = true) override;
bool removeSavefile(const Common::String &filename) override;
+ bool exists(const Common::String &filename) override;
#ifdef USE_LIBCURL
diff --git a/common/savefile.h b/common/savefile.h
index 0894022c8c..4253d715b0 100644
--- a/common/savefile.h
+++ b/common/savefile.h
@@ -268,6 +268,15 @@ public:
* for saving or loading because they are being synced by CloudManager.
*/
virtual void updateSavefilesList(StringArray &lockedFiles) = 0;
+
+ /**
+ * Checks if the savefile exists.
+ *
+ * @param name Name of the save file.
+ *
+ * @return true if the file exists. false otherwise.
+ */
+ virtual bool exists(const String &name) = 0;
};
/** @} */
Commit: 6aeda1224741b4b07935f6932355c5decc7ce0b9
https://github.com/scummvm/scummvm/commit/6aeda1224741b4b07935f6932355c5decc7ce0b9
Author: Orgad Shaneh (orgads at gmail.com)
Date: 2021-08-23T13:34:35+02:00
Commit Message:
ENGINES: Warn when overwriting a non-autosave on autosave
Changed paths:
engines/engine.cpp
engines/engine.h
engines/metaengine.cpp
engines/metaengine.h
engines/savestate.cpp
engines/savestate.h
diff --git a/engines/engine.cpp b/engines/engine.cpp
index b3877c24c9..89ef64c5db 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -149,6 +149,7 @@ Engine::Engine(OSystem *syst)
_pauseLevel(0),
_pauseStartTime(0),
_saveSlotToLoad(-1),
+ _autoSaving(false),
_engineStartTime(_system->getMillis()),
_mainMenuDialog(NULL),
_debugger(NULL),
@@ -541,34 +542,68 @@ void Engine::handleAutoSave() {
}
}
-void Engine::saveAutosaveIfEnabled() {
- // Reset the last autosave time first.
- // Doing it here rather than after saving the game prevents recursive calls if saving the game
- // causes the engine to poll events (as is the case with the AGS engine for example).
- _lastAutosaveTime = _system->getMillis();
-
- if (_autosaveInterval != 0) {
- bool saveFlag = canSaveAutosaveCurrently();
-
- if (saveFlag) {
- // First check for an existing savegame in the slot, and if present, if it's an autosave
- SaveStateDescriptor desc = getMetaEngine()->querySaveMetaInfos(
- _targetName.c_str(), getAutosaveSlot());
- saveFlag = desc.getSaveSlot() == -1 || desc.isAutosave();
+bool Engine::warnBeforeOverwritingAutosave() {
+ SaveStateDescriptor desc = getMetaEngine()->querySaveMetaInfos(
+ _targetName.c_str(), getAutosaveSlot());
+ if (desc.getSaveSlot() == -1)
+ return true;
+ if (desc.hasAutosaveName())
+ return true;
+ Common::U32StringArray altButtons;
+ altButtons.push_back(_("Overwrite"));
+ altButtons.push_back(_("Cancel autosave"));
+ const Common::U32String message = Common::U32String::format(
+ _("WARNING: The autosave slot has a saved game named %s. "
+ "You can either move the existing save to a new slot, "
+ "Overwrite the existing save, "
+ "or cancel autosave (will not prompt again until restart)"), desc.getDescription().c_str());
+ GUI::MessageDialog warn(message, _("Move"), altButtons);
+ switch (runDialog(warn)) {
+ case GUI::kMessageOK:
+ if (!getMetaEngine()->copySaveFileToFreeSlot(_targetName.c_str(), getAutosaveSlot())) {
+ GUI::MessageDialog error(_("ERROR: Could not copy the savegame to a new slot"));
+ error.runModal();
+ return false;
}
+ return true;
+ case GUI::kMessageAlt: // Overwrite
+ return true;
+ case GUI::kMessageAlt + 1: // Cancel autosave
+ _autosaveInterval = 0;
+ return false;
+ default: // Hitting Escape returns -1. On this case, don't save but do prompt again later.
+ return false;
+ }
+}
- if (saveFlag && saveGameState(getAutosaveSlot(), Common::convertFromU32String(_("Autosave")), true).getCode() != Common::kNoError) {
- // Couldn't autosave at the designated time
- g_system->displayMessageOnOSD(_("Error occurred making autosave"));
- saveFlag = false;
- }
+void Engine::saveAutosaveIfEnabled() {
+ // Prevents recursive calls if saving the game causes the engine to poll events
+ // (as is the case with the AGS engine for example, or when showing a prompt).
+ if (_autoSaving || _autosaveInterval == 0)
+ return;
+ _autoSaving = true;
- if (!saveFlag) {
- // Set the next autosave interval to be in 5 minutes, rather than whatever
- // full autosave interval the user has selected
- _lastAutosaveTime += (5 * 60 * 1000) - _autosaveInterval;
- }
+ bool saveFlag = canSaveAutosaveCurrently();
+ const Common::String autoSaveName = Common::convertFromU32String(_("Autosave"));
+
+ // First check for an existing savegame in the slot, and if present, if it's an autosave
+ if (saveFlag)
+ saveFlag = warnBeforeOverwritingAutosave();
+
+ if (saveFlag && saveGameState(getAutosaveSlot(), autoSaveName, true).getCode() != Common::kNoError) {
+ // Couldn't autosave at the designated time
+ g_system->displayMessageOnOSD(_("Error occurred making autosave"));
+ saveFlag = false;
+ }
+
+ if (saveFlag) {
+ _lastAutosaveTime = _system->getMillis();
+ } else {
+ // Set the next autosave interval to be in 5 minutes, rather than whatever
+ // full autosave interval the user has selected
+ _lastAutosaveTime += (5 * 60 * 1000) - _autosaveInterval;
}
+ _autoSaving = false;
}
void Engine::errorString(const char *buf1, char *buf2, int size) {
diff --git a/engines/engine.h b/engines/engine.h
index 33d62c5c78..01d57ccff1 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -203,7 +203,7 @@ private:
/**
* Autosave interval.
*/
- const int _autosaveInterval;
+ int _autosaveInterval;
/**
* The last time an autosave was done.
@@ -218,6 +218,11 @@ private:
*/
int _saveSlotToLoad;
+ /**
+ * Used for preventing recursion during autosave.
+ */
+ bool _autoSaving;
+
/**
* Optional debugger for the engine.
*/
@@ -526,6 +531,13 @@ private:
*/
friend class PauseToken;
+ /**
+ * Warns before overwriting autosave.
+ *
+ * @return true if it is safe to save, false to avoid saving.
+ */
+ bool warnBeforeOverwritingAutosave();
+
public:
/**
diff --git a/engines/metaengine.cpp b/engines/metaengine.cpp
index 4821ca0066..c9eb46c92c 100644
--- a/engines/metaengine.cpp
+++ b/engines/metaengine.cpp
@@ -209,6 +209,15 @@ void MetaEngine::appendExtendedSaveToStream(Common::WriteStream *saveFile, uint3
saveFile->writeUint32LE(headerPos); // Store where the header starts
}
+bool MetaEngine::copySaveFileToFreeSlot(const char *target, int slot)
+{
+ const int emptySlot = findEmptySaveSlot(target);
+ if (emptySlot == -1)
+ return false;
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ return saveFileMan->copySavefile(getSavegameFile(slot, target), getSavegameFile(emptySlot, target));
+}
+
void MetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
::createThumbnailFromScreen(&thumb);
}
@@ -295,6 +304,23 @@ WARN_UNUSED_RESULT bool MetaEngine::readSavegameHeader(Common::InSaveFile *in, E
// MetaEngine default implementations
//////////////////////////////////////////////
+int MetaEngine::findEmptySaveSlot(const char *target) {
+ if (!hasFeature(kSavesUseExtendedFormat))
+ return -1;
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ const int maxSaveSlot = getMaximumSaveSlot();
+ const int autosaveSlot = getAutosaveSlot();
+ for (int slot = 0; slot <= maxSaveSlot; ++slot) {
+ if (slot == autosaveSlot)
+ continue;
+ const Common::String filename = getSavegameFile(slot, target);
+ if (!saveFileMan->exists(filename))
+ return slot;
+ }
+ return -1;
+}
+
SaveStateList MetaEngine::listSaves(const char *target) const {
if (!hasFeature(kSavesUseExtendedFormat))
return SaveStateList();
@@ -336,7 +362,7 @@ SaveStateList MetaEngine::listSaves(const char *target, bool saveMode) const {
return saveList;
}
- // No autosave yet. We want to add a dummy one in so that it can be marked as'
+ // No autosave yet. We want to add a dummy one in so that it can be marked as
// write protected, and thus be prevented from being saved in
SaveStateDescriptor desc(autosaveSlot, _("Autosave"));
saveList.push_back(desc);
diff --git a/engines/metaengine.h b/engines/metaengine.h
index 0c33c9b236..a0c72bac10 100644
--- a/engines/metaengine.h
+++ b/engines/metaengine.h
@@ -232,6 +232,15 @@ protected:
* dialog so that it won't appear in the thumbnail.
*/
virtual void getSavegameThumbnail(Graphics::Surface &thumb);
+
+ /**
+ * Finds the first empty save slot that can be used for this target
+ * @param target Name of a config manager target.
+ *
+ * @return The first empty save slot, or -1 if all are occupied.
+ */
+ int findEmptySaveSlot(const char *target);
+
public:
virtual ~MetaEngine() {}
@@ -520,6 +529,15 @@ public:
*/
void appendExtendedSaveToStream(Common::WriteStream *saveFile, uint32 playtime, Common::String desc, bool isAutosave, uint32 offset = 0);
+ /**
+ * Copies an existing save file to the first empty slot which is not autosave
+ * @param target Name of a config manager target.
+ * @param slot Slot number of the save state.
+ *
+ * @return true if an empty slot was found and the save state was copied. false otherwise.
+ */
+ bool copySaveFileToFreeSlot(const char *target, int slot);
+
/**
* Parse the extended savegame header to retrieve the SaveStateDescriptor information.
*/
diff --git a/engines/savestate.cpp b/engines/savestate.cpp
index 83d5bccb79..08d4394bb4 100644
--- a/engines/savestate.cpp
+++ b/engines/savestate.cpp
@@ -44,8 +44,7 @@ SaveStateDescriptor::SaveStateDescriptor(int slot, const Common::String &d)
initSaveType();
}
-void SaveStateDescriptor::initSaveType()
-{
+void SaveStateDescriptor::initSaveType() {
// Do not allow auto-save slot to be deleted or overwritten.
const bool autosave =
g_engine && ConfMan.getInt("autosave_period") && _slot == g_engine->getAutosaveSlot();
@@ -88,6 +87,11 @@ bool SaveStateDescriptor::isAutosave() const {
if (_saveType != kSaveTypeUndetermined) {
return _saveType == kSaveTypeAutosave;
} else {
- return _description == _("Autosave");
+ return hasAutosaveName();
}
}
+
+bool SaveStateDescriptor::hasAutosaveName() const
+{
+ return _description.contains(_("Autosave"));
+}
diff --git a/engines/savestate.h b/engines/savestate.h
index fa126877b4..c537ebb8d3 100644
--- a/engines/savestate.h
+++ b/engines/savestate.h
@@ -214,6 +214,11 @@ public:
* Returns true whether the save is an autosave
*/
bool isAutosave() const;
+
+ /**
+ * Returns true if the save has an autosave name
+ */
+ bool hasAutosaveName() const;
private:
/**
* The saveslot id, as it would be passed to the "-x" command line switch.
More information about the Scummvm-git-logs
mailing list