[Scummvm-git-logs] scummvm master -> ba246982259866316218ac8b82c5b96fffc7ff03
AndywinXp
noreply at scummvm.org
Wed Nov 30 23:30:31 UTC 2022
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
ba24698225 SCUMM: v3: Implement ability to rename savestate before loading on the original menu
Commit: ba246982259866316218ac8b82c5b96fffc7ff03
https://github.com/scummvm/scummvm/commit/ba246982259866316218ac8b82c5b96fffc7ff03
Author: AndywinXp (andywinxp at gmail.com)
Date: 2022-12-01T00:04:46+01:00
Commit Message:
SCUMM: v3: Implement ability to rename savestate before loading on the original menu
As much as this seems bad design, it's a real possibility in the original interpreters, furthermore
confirmed by the menu messages which are shown when the user tries to do that, so here we are...
Changed paths:
engines/scumm/saveload.cpp
engines/scumm/script_v4.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index ae793e2c81c..f6fc24620ca 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1173,6 +1173,97 @@ static void sync2DArray(Common::Serializer &s, T (&array)[N][M], const size_t di
}
}
+bool ScummEngine::changeSavegameName(int slot, char *newName) {
+ Common::String filename;
+ SaveGameHeader hdr;
+
+ // In order to do this, we're going to:
+ // - Open the savegame file;
+ // - Load its header and check if there's a necessity to change the name or not;
+ // - Construct a new header;
+ // - Build a buffer with the remaining data of the savestate and then close the input:
+ // stream: this is done since we are not copying data from one file to another, but we
+ // are performing an intervention on a single file;
+ // - Open the output stream for the same file;
+ // - Save the new header and then pour the data buffer in the stream;
+ // - Finalize the stream.
+
+ Common::SeekableReadStream *in = openSaveFileForReading(slot, false, filename);
+
+ if (!in) {
+ warning("ScummEngine::changeSavegameName(): Could not open savegame '%s', aborting...", filename.c_str());
+ return false;
+ }
+
+ if (!loadSaveGameHeader(in, hdr)) {
+ warning("ScummEngine::changeSavegameName(): Invalid savegame '%s', aborting...", filename.c_str());
+ delete in;
+ return false;
+ }
+
+ if (!scumm_strnicmp(newName, hdr.name, sizeof(hdr.name))) {
+ // No name to change, abort...
+ delete in;
+ return true;
+ }
+
+ Common::strlcpy(hdr.name, newName, sizeof(hdr.name));
+
+ size_t bufferSizeNoHdr = in->size() - sizeof(hdr);
+ byte *saveBuffer = (byte *)malloc(bufferSizeNoHdr * sizeof(byte));
+
+ if (!saveBuffer) {
+ warning("ScummEngine::changeSavegameName(): Couldn't create save buffer, aborting...");
+ delete in;
+ return false;
+ }
+
+ in->seek(sizeof(hdr), SEEK_SET);
+
+ for (int i = 0; i < bufferSizeNoHdr; i++) {
+ saveBuffer[i] = in->readByte();
+
+ if (in->err()) {
+ warning("ScummEngine::changeSavegameName(): Error in input file stream, aborting...");
+ delete in;
+ return false;
+ }
+ }
+
+ delete in;
+
+ Common::WriteStream *out = openSaveFileForWriting(slot, false, filename);
+ saveSaveGameHeader(out, hdr);
+
+ if (!out) {
+ warning("ScummEngine::changeSavegameName(): Couldn't open output file, aborting...");
+ return false;
+ }
+
+ for (int i = 0; i < bufferSizeNoHdr; i++) {
+ out->writeByte(saveBuffer[i]);
+
+ if (out->err()) {
+ warning("ScummEngine::changeSavegameName(): Error in output file stream, aborting...");
+ delete out;
+ return false;
+ }
+ }
+
+ out->finalize();
+
+ if (out->err()) {
+ warning("ScummEngine::changeSavegameName(): Error in output file stream after finalizing...");
+ delete out;
+ return false;
+ }
+
+ delete out;
+
+ return true;
+}
+
+
void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
int i;
int var120Backup;
diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp
index b638cd2dad7..8d5d7d2db38 100644
--- a/engines/scumm/script_v4.cpp
+++ b/engines/scumm/script_v4.cpp
@@ -419,6 +419,20 @@ void ScummEngine_v4::o4_saveLoadGame() {
break;
case 0x40: // load
_lastLoadedRoom = -1;
+
+ // The original interpreter allowed you to change the name of the
+ // savegame before loading it. As weird as that is, let's allow it...
+ if (_game.version == 3) {
+ char *ptr;
+ int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1;
+ ptr = (char *)getStringAddress(slot + firstSlot - 1);
+ if (ptr) {
+ if (!changeSavegameName(slot, ptr)) {
+ warning("o4_saveLoadGame: Couldn't change savegame name");
+ }
+ }
+ }
+
if (loadState(slot, false))
result = 3; // Success
else
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 624f2815d51..90d90458cde 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -854,6 +854,7 @@ protected:
void loadResourceOLD(Common::Serializer &ser, ResType type, ResId idx); // "Obsolete"
void copyHeapSaveGameToFile(int slot, const char *saveName);
+ bool changeSavegameName(int slot, char *newName);
virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName);
virtual Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName);
More information about the Scummvm-git-logs
mailing list