[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