[Scummvm-git-logs] scummvm branch-2-2 -> bfb9a6f73f24760200e3c872c80a106b239b2431

dreammaster paulfgilbert at gmail.com
Sun Oct 4 03:47:17 UTC 2020


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2589a58f3c GLK: ADRIFT: Savegame fixes
bfb9a6f73f GLK: LEVEL9: Fix savegames


Commit: 2589a58f3cf09b0442880e407efa9fe72a2069f1
    https://github.com/scummvm/scummvm/commit/2589a58f3cf09b0442880e407efa9fe72a2069f1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-03T20:47:07-07:00

Commit Message:
GLK: ADRIFT: Savegame fixes

Changed paths:
    engines/glk/adrift/adrift.cpp
    engines/glk/adrift/serialization.cpp


diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
index ed83944595..af404a5da2 100644
--- a/engines/glk/adrift/adrift.cpp
+++ b/engines/glk/adrift/adrift.cpp
@@ -46,6 +46,7 @@ Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
 
 Common::Error Adrift::writeGameData(Common::WriteStream *ws) {
 	SaveSerializer ser((sc_gameref_t)gsc_game, if_write_saved_game, ws);
+	ser.save();
 	return Common::kNoError;
 }
 
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
index 5f65e05196..b1769288b9 100644
--- a/engines/glk/adrift/serialization.cpp
+++ b/engines/glk/adrift/serialization.cpp
@@ -188,10 +188,6 @@ void SaveSerializer::flush(sc_bool is_final) {
 }
 
 void SaveSerializer::writeChar(sc_char character) {
-	// Validate the buffer hasn't exceeded the maximum allowable size
-	if (_buffer.size() == BUFFER_SIZE)
-		sc_error("Ran out of serialization buffer");
-
 	// Add to the buffer
 	_buffer.writeByte(character);
 }


Commit: bfb9a6f73f24760200e3c872c80a106b239b2431
    https://github.com/scummvm/scummvm/commit/bfb9a6f73f24760200e3c872c80a106b239b2431
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-03T20:47:07-07:00

Commit Message:
GLK: LEVEL9: Fix savegames

Changed paths:
    engines/glk/level9/level9.cpp
    engines/glk/level9/level9_main.cpp
    engines/glk/level9/level9_main.h
    engines/glk/level9/os_glk.cpp
    engines/glk/quetzal.cpp


diff --git a/engines/glk/level9/level9.cpp b/engines/glk/level9/level9.cpp
index 31caeedaa1..4ca524553d 100644
--- a/engines/glk/level9/level9.cpp
+++ b/engines/glk/level9/level9.cpp
@@ -29,6 +29,9 @@ namespace Level9 {
 
 Level9 *g_vm = nullptr;
 
+extern GameState workspace;
+extern byte *acodeptr, *codeptr;
+
 Level9::Level9(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
 		_detection(startdata, FileSize) {
 	g_vm = this;
@@ -52,12 +55,16 @@ void Level9::deinitialize() {
 }
 
 Common::Error Level9::readSaveData(Common::SeekableReadStream *rs) {
-	// TODO
+	Common::Serializer s(rs, nullptr);
+	workspace.synchronize(s);
+	codeptr = acodeptr + workspace.codeptr;
+
 	return Common::kNoError;
 }
 
 Common::Error Level9::writeGameData(Common::WriteStream *ws) {
-	// TODO
+	Common::Serializer s(nullptr, ws);
+	workspace.synchronize(s);
 	return Common::kNoError;
 }
 
diff --git a/engines/glk/level9/level9_main.cpp b/engines/glk/level9/level9_main.cpp
index 49f3fb6c9e..d9346e7664 100644
--- a/engines/glk/level9/level9_main.cpp
+++ b/engines/glk/level9/level9_main.cpp
@@ -1251,58 +1251,35 @@ void L9Random() {
 #endif
 }
 
-void save() {
+L9BOOL CheckFile(GameState *gs) {
 	L9UINT16 checksum;
-	int i;
-#ifdef L9DEBUG
-	printf("function - save");
-#endif
-	/* does a full save, workpace, stack, codeptr, stackptr, game name, checksum */
 
-	workspace.Id = L9_ID;
-	workspace.codeptr = codeptr - acodeptr;
-	workspace.listsize = LISTAREASIZE;
-	workspace.stacksize = STACKSIZE;
-	workspace.filenamesize = MAX_PATH;
-	workspace.checksum = 0;
-	strcpy(workspace.filename, LastGame);
+	if (gs->Id != L9_ID)
+		return FALSE;
+	checksum = gs->checksum;
+	gs->calculateChecksum();
 
-	checksum = 0;
-	for (i = 0; i < (int)sizeof(GameState); i++) checksum += ((L9BYTE *) &workspace)[i];
-	workspace.checksum = checksum;
+	if (checksum != gs->checksum)
+		return FALSE;
 
-	if (os_save_file((L9BYTE *) &workspace, sizeof(workspace))) printstring("\rGame saved.\r");
-	else printstring("\rUnable to save game.\r");
+	return TRUE;
 }
 
-L9BOOL CheckFile(GameState *gs) {
-	L9UINT16 checksum;
-	int i;
-	char c = 'Y';
-
-	if (gs->Id != L9_ID) return FALSE;
-	checksum = gs->checksum;
-	gs->checksum = 0;
-	for (i = 0; i < (int)sizeof(GameState); i++)
-		checksum -= *((L9BYTE *) gs + i);
-	if (checksum) return FALSE;
-	if (scumm_stricmp(gs->filename, LastGame)) {
-		printstring("\rWarning: game path name does not match, you may be about to load this position file into the wrong story file.\r");
-		printstring("Are you sure you want to restore? (Y/N)");
-		os_flush();
+void save() {
+	if (g_vm->saveGame().getCode() == Common::kNoError)
+		printstring("\rGame saved.\r");
+	else
+		printstring("\rUnable to save game.\r");
+}
 
-		c = '\0';
-		while ((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N'))
-			c = os_readchar(20);
-	}
-	if ((c == 'y') || (c == 'Y'))
-		return TRUE;
-	return FALSE;
+void restore() {
+	if (g_vm->loadGame().getCode() == Common::kNoError)
+		printstring("\rGame restored.\r");
+	else
+		printstring("\rUnable to restore game.\r");
 }
 
 void NormalRestore() {
-	GameState temp;
-	int Bytes;
 #ifdef L9DEBUG
 	printf("function - restore");
 #endif
@@ -1312,39 +1289,7 @@ void NormalRestore() {
 		error("\rWord is: %s\r", ibuff);
 	}
 
-	if (os_load_file((L9BYTE *) &temp, &Bytes, sizeof(GameState))) {
-		if (Bytes == V1FILESIZE) {
-			printstring("\rGame restored.\r");
-			memset(workspace.listarea, 0, LISTAREASIZE);
-			memmove(workspace.vartable, &temp, V1FILESIZE);
-		} else if (CheckFile(&temp)) {
-			printstring("\rGame restored.\r");
-			/* only copy in workspace */
-			memmove(workspace.vartable, temp.vartable, sizeof(SaveStruct));
-		} else {
-			printstring("\rSorry, unrecognised format. Unable to restore\r");
-		}
-	} else printstring("\rUnable to restore game.\r");
-}
-
-void restore() {
-	int Bytes;
-	GameState temp;
-	if (os_load_file((L9BYTE *) &temp, &Bytes, sizeof(GameState))) {
-		if (Bytes == V1FILESIZE) {
-			printstring("\rGame restored.\r");
-			/* only copy in workspace */
-			memset(workspace.listarea, 0, LISTAREASIZE);
-			memmove(workspace.vartable, &temp, V1FILESIZE);
-		} else if (CheckFile(&temp)) {
-			printstring("\rGame restored.\r");
-			/* full restore */
-			memmove(&workspace, &temp, sizeof(GameState));
-			codeptr = acodeptr + workspace.codeptr;
-		} else {
-			printstring("\rSorry, unrecognised format. Unable to restore\r");
-		}
-	} else printstring("\rUnable to restore game.\r");
+	restore();
 }
 
 void playback() {
@@ -3099,5 +3044,51 @@ void RestoreGame(char *filename) {
 		printstring("\rUnable to restore game.\r");
 }
 
+/*----------------------------------------------------------------------*/
+
+void GameState::synchronize(Common::Serializer &s) {
+	if (s.isSaving()) {
+		Id = L9_ID;
+		this->codeptr = ::Glk::Level9::codeptr - ::Glk::Level9::acodeptr;
+		listsize = LISTAREASIZE;
+		stacksize = STACKSIZE;
+		calculateChecksum();
+	}
+
+	s.syncAsUint32LE(Id);
+	s.syncAsUint16LE(codeptr);
+	s.syncAsUint16LE(stackptr);
+	s.syncAsUint16LE(listsize);
+	s.syncAsUint16LE(stacksize);
+	s.syncAsUint16LE(checksum);
+
+	for (int i = 0; i < 256; ++i)
+		s.syncAsUint16LE(vartable[i]);
+
+	s.syncBytes(listarea, LISTAREASIZE);
+
+	for (int i = 0; i < STACKSIZE; ++i)
+		s.syncAsUint16LE(stack[i]);
+}
+
+#define CHECKSUMW(V) checksum += (V & 0xff) + (V >> 8) & 0xff
+#define CHECKSUML(V) checksum += (V & 0xff) + (V >> 8) & 0xff \
+	+ (V >> 16) & 0xff + (V >> 24) & 0xff
+
+void GameState::calculateChecksum() {
+	checksum = 0;
+	CHECKSUML(Id);
+	CHECKSUMW(codeptr);
+	CHECKSUMW(stackptr);
+	CHECKSUMW(listsize);
+	CHECKSUMW(stacksize);
+	for (int i = 0; i < 256; ++i)
+		CHECKSUMW(vartable[i]);
+	for (int i = 0; i < LISTAREASIZE; ++i)
+		checksum += listarea[i];
+	for (int i = 0; i < STACKSIZE; ++i)
+		CHECKSUMW(stack[i]);
+}
+
 } // End of namespace Level9
 } // End of namespace Glk
diff --git a/engines/glk/level9/level9_main.h b/engines/glk/level9/level9_main.h
index 5bd1dffc06..ace638519d 100644
--- a/engines/glk/level9/level9_main.h
+++ b/engines/glk/level9/level9_main.h
@@ -26,6 +26,7 @@
 #include "common/scummsys.h"
 #include "common/endian.h"
 #include "common/stream.h"
+#include "common/serializer.h"
 
 namespace Glk {
 namespace Level9 {
@@ -48,11 +49,15 @@ typedef bool L9BOOL;
 
 struct GameState {
 	L9UINT32 Id;
-	L9UINT16 codeptr, stackptr, listsize, stacksize, filenamesize, checksum;
+	L9UINT16 codeptr, stackptr, listsize, stacksize;
 	L9UINT16 vartable[256];
 	L9BYTE listarea[LISTAREASIZE];
 	L9UINT16 stack[STACKSIZE];
-	char filename[MAX_PATH];
+	uint16 checksum;
+
+	void synchronize(Common::Serializer &s);
+
+	void calculateChecksum();
 };
 
 enum BitmapType {
@@ -90,6 +95,7 @@ extern byte *startdata;
 extern uint32 FileSize;
 
 extern void level9_initialize();
+extern void printstring(const char *buf);
 
 /* routines provided by os dependent code */
 extern void os_printchar(char c);
@@ -97,8 +103,6 @@ extern L9BOOL os_input(char *ibuff, int size);
 extern char os_readchar(int millis);
 extern L9BOOL os_stoplist(void);
 extern void os_flush(void);
-extern L9BOOL os_save_file(L9BYTE *Ptr, int Bytes);
-extern L9BOOL os_load_file(L9BYTE *Ptr, int *Bytes, int Max);
 extern L9BOOL os_get_game_file(char *NewName, int Size);
 extern void os_set_filenumber(char *NewName, int Size, int n);
 extern void os_graphics(int mode);
diff --git a/engines/glk/level9/os_glk.cpp b/engines/glk/level9/os_glk.cpp
index c215251df5..f29457d85f 100644
--- a/engines/glk/level9/os_glk.cpp
+++ b/engines/glk/level9/os_glk.cpp
@@ -23,6 +23,7 @@
 #include "glk/level9/os_glk.h"
 #include "glk/level9/level9_main.h"
 #include "glk/level9/level9.h"
+#include "common/config-manager.h"
 #include "common/textconsole.h"
 
 namespace Glk {
@@ -4278,92 +4279,6 @@ static void gln_event_wait(glui32 wait_type, event_t *event) {
 	gln_event_wait_2(wait_type, evtype_None, event);
 }
 
-
-/*---------------------------------------------------------------------*/
-/*  Glk port file functions                                            */
-/*---------------------------------------------------------------------*/
-
-/*
- * os_save_file ()
- * os_load_file ()
- *
- * Save the current game state to a file, and load a game state.
- */
-gln_bool os_save_file(gln_byte *ptr, int bytes) {
-	frefid_t fileref;
-	strid_t stream;
-	assert(ptr);
-
-	/* Flush any pending buffered output. */
-	gln_output_flush();
-
-	fileref = g_vm->glk_fileref_create_by_prompt(fileusage_SavedGame,
-	          filemode_Write, 0);
-	if (!fileref) {
-		gln_watchdog_tick();
-		return FALSE;
-	}
-
-	stream = g_vm->glk_stream_open_file(fileref, filemode_Write, 0);
-	if (!stream) {
-		g_vm->glk_fileref_destroy(fileref);
-		gln_watchdog_tick();
-		return FALSE;
-	}
-
-	/* Write game state. */
-	g_vm->glk_put_buffer_stream(stream, (const char *)ptr, bytes);
-
-	g_vm->glk_stream_close(stream, nullptr);
-	g_vm->glk_fileref_destroy(fileref);
-
-	gln_watchdog_tick();
-	return TRUE;
-}
-
-gln_bool os_load_file(gln_byte *ptr, int *bytes, int max) {
-	frefid_t fileref;
-	strid_t stream;
-	assert(ptr && bytes);
-
-	/* Flush any pending buffered output. */
-	gln_output_flush();
-
-	fileref = g_vm->glk_fileref_create_by_prompt(fileusage_SavedGame,
-	          filemode_Read, 0);
-	if (!fileref) {
-		gln_watchdog_tick();
-		return FALSE;
-	}
-
-	/*
-	 * Reject the file reference if we're expecting to read from it, and the
-	 * referenced file doesn't exist.
-	 */
-	if (!g_vm->glk_fileref_does_file_exist(fileref)) {
-		g_vm->glk_fileref_destroy(fileref);
-		gln_watchdog_tick();
-		return FALSE;
-	}
-
-	stream = g_vm->glk_stream_open_file(fileref, filemode_Read, 0);
-	if (!stream) {
-		g_vm->glk_fileref_destroy(fileref);
-		gln_watchdog_tick();
-		return FALSE;
-	}
-
-	/* Restore saved game data. */
-	*bytes = g_vm->glk_get_buffer_stream(stream, (char *)ptr, max);
-
-	g_vm->glk_stream_close(stream, nullptr);
-	g_vm->glk_fileref_destroy(fileref);
-
-	gln_watchdog_tick();
-	return TRUE;
-}
-
-
 /*---------------------------------------------------------------------*/
 /*  Glk port multi-file game functions                                 */
 /*---------------------------------------------------------------------*/
@@ -4729,6 +4644,7 @@ int gln_startup_code(int argc, char *argv[]) {
 void gln_main(const char *filename) {
 	char *graphics_file = nullptr;
 	int is_running;
+	int saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
 
 	/* Create the main Glk window, and set its stream as current. */
 	gln_main_window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
@@ -4820,6 +4736,16 @@ void gln_main(const char *filename) {
 		/* Start, or restart, watchdog checking. */
 		gln_watchdog_start(GLN_WATCHDOG_TIMEOUT, GLN_WATCHDOG_PERIOD);
 
+		/* Load any savegame selected directly from the ScummVM launcher */
+		if (saveSlot != -1) {
+			if (g_vm->loadGameState(saveSlot).getCode() == Common::kNoError)
+				printstring("\rGame restored.\r");
+			else
+				printstring("\rUnable to restore game.\r");
+
+			saveSlot = -1;
+		}
+
 		/* Run the game until StopGame called, or RunGame() returns FALSE. */
 		do {
 			is_running = RunGame();
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 67a576f745..33bd522639 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -254,7 +254,11 @@ void QuetzalWriter::addCommonChunks(const Common::String &saveName) {
 		// Write out intrepreter type, language, and game Id
 		ws.writeUint32BE(getInterpreterTag(g_vm->getInterpreterType()));
 		const char *langCode = getLanguageCode(g_vm->getLanguage());
-		ws.write(langCode, strlen(langCode) + 1);
+		if (langCode)
+			ws.write(langCode, strlen(langCode) + 1);
+		else
+			ws.writeByte('\0');
+
 		Common::String md5 = g_vm->getGameMD5();
 		ws.write(md5.c_str(), md5.size());
 		ws.writeByte('\0');




More information about the Scummvm-git-logs mailing list