[Scummvm-git-logs] scummvm master -> 2391ca83da989fb5d339a4604428e24e25abd760

dreammaster paulfgilbert at gmail.com
Sat Jun 27 02:47:27 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:
2a79ba3cf6 GLK: GLULXE: Implemented save and restore code
2391ca83da GLK: GLULXE: Mark GLULXE games as unstable


Commit: 2a79ba3cf6c6f6bb966ecd7809d1fedae9b1e671
    https://github.com/scummvm/scummvm/commit/2a79ba3cf6c6f6bb966ecd7809d1fedae9b1e671
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-26T18:43:32-07:00

Commit Message:
GLK: GLULXE: Implemented save and restore code

Changed paths:
    engines/glk/glulxe/glulxe.h
    engines/glk/glulxe/serial.cpp


diff --git a/engines/glk/glulxe/glulxe.h b/engines/glk/glulxe/glulxe.h
index 5166153753..c4252d8fe3 100644
--- a/engines/glk/glulxe/glulxe.h
+++ b/engines/glk/glulxe/glulxe.h
@@ -410,16 +410,32 @@ public:
 		return INTERPRETER_GLULXE;
 	}
 
+	/**
+	 * Loads Quetzal chunks from the passed savegame
+	 */
+	Common::Error loadGameChunks(QuetzalReader &quetzal) override;
+
+	/**
+	 * Writes out the Quetzal chunks within a savegame
+	 */
+	Common::Error saveGameChunks(QuetzalWriter &quetzal) override;
+
 	/**
 	 * Load a savegame from the passed Quetzal file chunk stream
 	 */
-	Common::Error readSaveData(Common::SeekableReadStream *rs) override;
+	Common::Error readSaveData(Common::SeekableReadStream *rs) override {
+		// Unused
+		return Common::kUnknownError;
+	}
 
 	/**
 	 * Save the game. The passed write stream represents access to the UMem chunk
 	 * in the Quetzal save file that will be created
 	 */
-	Common::Error writeGameData(Common::WriteStream *ws) override;
+	Common::Error writeGameData(Common::WriteStream *ws) override {
+		// Unused
+		return Common::kUnknownError;
+	}
 
 	/**
 	 * \defgroup Main access methods
diff --git a/engines/glk/glulxe/serial.cpp b/engines/glk/glulxe/serial.cpp
index 0fc9ab794f..10d7133efb 100644
--- a/engines/glk/glulxe/serial.cpp
+++ b/engines/glk/glulxe/serial.cpp
@@ -225,252 +225,94 @@ uint Glulxe::perform_restoreundo() {
 	return res;
 }
 
-Common::Error Glulxe::writeGameData(Common::WriteStream *ws) {
-#ifdef TODO
-	dest_t dest;
-	int ix;
-	uint res = 0, lx, val;
-	uint memstart = 0, memlen = 0, stackstart = 0, stacklen = 0;
-	uint heapstart = 0, heaplen = 0, filestart = 0, filelen = 0;
-	stream_get_iosys(&val, &lx);
-	if (val != 2) {
-		/* Not using the Glk I/O system, so bail. This function only
-		   knows how to write to a Glk stream. */
-		fatal_error("Streams are only available in Glk I/O system.");
-	}
-
-	if (ws == nullptr)
-		return Common::kUnknownError;
-
-	dest._isMem = false;
-	dest._size = 0;
-	dest._pos = 0;
-	dest._ptr = nullptr;
-	dest._str = ws;
-
-	res = 0;
+Common::Error Glulxe::loadGameChunks(QuetzalReader &quetzal) {
+	uint res = 0;
+	uint heapsumlen = 0;
+	uint *heapsumarr = nullptr;
 
-	/* Quetzal header. */
-	if (res == 0) {
-		res = write_long(&dest, IFFID('F', 'O', 'R', 'M'));
-	}
-	if (res == 0) {
-		res = write_long(&dest, 0); /* space for file length */
-		filestart = dest._pos;
-	}
+	for (QuetzalReader::Iterator it = quetzal.begin();
+			it != quetzal.end() && !res; ++it) {
+		Common::SeekableReadStream *rs = it.getStream();
+		dest_t dest;
+		dest._src = rs;
+
+		switch ((*it)._id) {
+		case ID_IFhd:
+			for (int ix = 0; ix < 128 && !res; ix++) {
+				byte v = rs->readByte();
+				if (Mem1(ix) != v)
+					// ### non-matching header
+					res = 1;
+			}
+			break;
 
-	if (res == 0) {
-		res = write_long(&dest, IFFID('I', 'F', 'Z', 'S')); /* ### ? */
-	}
+		case ID_CMem:
+			res = read_memstate(&dest, rs->size());
+			break;
 
-	/* Header chunk. This is the first 128 bytes of memory. */
-	if (res == 0) {
-		res = write_long(&dest, IFFID('I', 'F', 'h', 'd'));
-	}
-	if (res == 0) {
-		res = write_long(&dest, 128);
-	}
-	for (ix = 0; res == 0 && ix < 128; ix++) {
-		res = write_byte(&dest, Mem1(ix));
-	}
-	/* Always even, so no padding necessary. */
+		case MKTAG('M', 'A', 'l', 'l'):
+			res = read_heapstate(&dest, rs->size(), true, &heapsumlen, &heapsumarr);
+			break;
 
-	/* Memory chunk. */
-	if (res == 0) {
-		res = write_long(&dest, IFFID('C', 'M', 'e', 'm'));
-	}
-	if (res == 0) {
-		res = write_long(&dest, 0); /* space for chunk length */
-	}
-	if (res == 0) {
-		memstart = dest._pos;
-		res = write_memstate(&dest);
-		memlen = dest._pos - memstart;
-	}
-	if (res == 0 && (memlen & 1) != 0) {
-		res = write_byte(&dest, 0);
-	}
+		case ID_Stks:
+			res = read_stackstate(&dest, rs->size(), true);
+			break;
 
-	/* Heap chunk. */
-	if (res == 0) {
-		res = write_long(&dest, IFFID('M', 'A', 'l', 'l'));
-	}
-	if (res == 0) {
-		res = write_long(&dest, 0); /* space for chunk length */
-	}
-	if (res == 0) {
-		heapstart = dest._pos;
-		res = write_heapstate(&dest, true);
-		heaplen = dest._pos - heapstart;
-	}
-	/* Always even, so no padding necessary. */
+		default:
+			break;
+		}
 
-	/* Stack chunk. */
-	if (res == 0) {
-		res = write_long(&dest, IFFID('S', 't', 'k', 's'));
-	}
-	if (res == 0) {
-		res = write_long(&dest, 0); /* space for chunk length */
-	}
-	if (res == 0) {
-		stackstart = dest._pos;
-		res = write_stackstate(&dest, true);
-		stacklen = dest._pos - stackstart;
-	}
-	if (res == 0 && (stacklen & 1) != 0) {
-		res = write_byte(&dest, 0);
+		delete rs;
 	}
 
-	filelen = dest._pos - filestart;
-
-	/* Okay, fill in all the lengths. */
-	if (res == 0) {
-		res = reposition_write(&dest, memstart - 4);
-	}
-	if (res == 0) {
-		res = write_long(&dest, memlen);
-	}
-	if (res == 0) {
-		res = reposition_write(&dest, heapstart - 4);
-	}
-	if (res == 0) {
-		res = write_long(&dest, heaplen);
-	}
-	if (res == 0) {
-		res = reposition_write(&dest, stackstart - 4);
-	}
-	if (res == 0) {
-		res = write_long(&dest, stacklen);
-	}
-	if (res == 0) {
-		res = reposition_write(&dest, filestart - 4);
-	}
-	if (res == 0) {
-		res = write_long(&dest, filelen);
+	if (!res) {
+		if (heapsumarr) {
+			/* The summary might have come from any interpreter, so it could
+			   be out of order. We'll sort it. */
+			glulx_sort(heapsumarr + 2, (heapsumlen - 2) / 2, 2 * sizeof(uint), &sort_heap_summary);
+			res = heap_apply_summary(heapsumlen, heapsumarr);
+		}
 	}
 
-	/* All done. */
-	return res ? Common::kUnknownError : Common::kNoError;
-#endif
-	return Common::kUnknownError;
+	return res ? Common::kReadingFailed : Common::kNoError;
 }
 
-Common::Error Glulxe::readSaveData(Common::SeekableReadStream *rs) {
-#ifdef TODO
-	dest_t dest;
-	int ix;
-	uint lx = 0, res, val;
-	uint filestart, filelen = 0;
-	uint heapsumlen = 0;
-	uint *heapsumarr = nullptr;
-	bool fromshell = false;
-	/* If profiling is enabled and active then fail. */
-#if VM_PROFILING
-	if (profile_profiling_active())
-		return 1;
-#endif /* VM_PROFILING */
-
-	stream_get_iosys(&val, &lx);
-	if (val != 2 && !fromshell) {
-		/* Not using the Glk I/O system, so bail. This function only
-		   knows how to read from a Glk stream. (But in the autorestore
-		   case, iosys hasn't been set yet, so ignore this test.) */
-		fatal_error("Streams are only available in Glk I/O system.");
-	}
-
-	if (str == 0)
-		return Common::kUnknownError;
-
-	dest._isMem = false;
-	dest._size = 0;
-	dest._pos = 0;
-	dest._ptr = nullptr;
-	dest._str = str;
-
-	res = 0;
-
-	/* ### the format errors checked below should send error messages to
-	   the current stream. */
+Common::Error Glulxe::saveGameChunks(QuetzalWriter &quetzal) {
+	uint res = 0;
 
-	if (res == 0) {
-		res = read_long(&dest, &val);
-	}
-	if (res == 0 && val != IFFID('F', 'O', 'R', 'M')) {
-		/* ### bad header */
-		return Common::kUnknownError;
-	}
-	if (res == 0) {
-		res = read_long(&dest, &filelen);
+	// IFHd
+	if (!res) {
+		Common::WriteStream &ws = quetzal.add(ID_IFhd);
+		for (int ix = 0; res == 0 && ix < 128; ix++)
+			ws.writeByte(Mem1(ix));
 	}
-	filestart = dest._pos;
 
-	if (res == 0) {
-		res = read_long(&dest, &val);
-	}
-	if (res == 0 && val != IFFID('I', 'F', 'Z', 'S')) { /* ### ? */
-		/* ### bad header */
-		return Common::kUnknownError;
+	// CMem
+	if (!res) {
+		Common::WriteStream &ws = quetzal.add(ID_CMem);
+		dest_t dest;
+		dest._dest = &ws;
+		res = write_memstate(&dest);
 	}
 
-	while (res == 0 && dest._pos < filestart + filelen) {
-		/* Read a chunk and deal with it. */
-		uint chunktype = 0, chunkstart = 0, chunklen = 0;
-		unsigned char dummy;
-
-		if (res == 0) {
-			res = read_long(&dest, &chunktype);
-		}
-		if (res == 0) {
-			res = read_long(&dest, &chunklen);
-		}
-		chunkstart = dest._pos;
-
-		if (chunktype == IFFID('I', 'F', 'h', 'd')) {
-			for (ix = 0; res == 0 && ix < 128; ix++) {
-				res = read_byte(&dest, &dummy);
-				if (res == 0 && Mem1(ix) != dummy) {
-					/* ### non-matching header */
-					return Common::kUnknownError;
-				}
-			}
-		} else if (chunktype == IFFID('C', 'M', 'e', 'm')) {
-			res = read_memstate(&dest, chunklen);
-		} else if (chunktype == IFFID('M', 'A', 'l', 'l')) {
-			res = read_heapstate(&dest, chunklen, true, &heapsumlen, &heapsumarr);
-		} else if (chunktype == IFFID('S', 't', 'k', 's')) {
-			res = read_stackstate(&dest, chunklen, true);
-		} else {
-			/* Unknown chunk type. Skip it. */
-			for (lx = 0; res == 0 && lx < chunklen; lx++) {
-				res = read_byte(&dest, &dummy);
-			}
-		}
-
-		if (chunkstart + chunklen != dest._pos) {
-			/* ### funny chunk length */
-			return Common::kUnknownError;
-		}
-
-		if ((chunklen & 1) != 0) {
-			if (res == 0) {
-				res = read_byte(&dest, &dummy);
-			}
-		}
+	// MAll
+	if (!res) {
+		Common::WriteStream &ws = quetzal.add(MKTAG('M', 'A', 'l', 'l'));
+		dest_t dest;
+		dest._dest = &ws;
+		res = write_heapstate(&dest, true);
 	}
 
-	if (res == 0) {
-		if (heapsumarr) {
-			/* The summary might have come from any interpreter, so it could
-			   be out of order. We'll sort it. */
-			glulx_sort(heapsumarr + 2, (heapsumlen - 2) / 2, 2 * sizeof(uint), &sort_heap_summary);
-			res = heap_apply_summary(heapsumlen, heapsumarr);
-		}
+	// Stks
+	if (!res) {
+		Common::WriteStream &ws = quetzal.add(ID_Stks);
+		dest_t dest;
+		dest._dest = &ws;
+		res = write_stackstate(&dest, true);
 	}
 
-	if (res)
-		return Common::kUnknownError;
-#endif
-	return Common::kNoError;
+	// All done
+	return res ? Common::kUnknownError : Common::kNoError;
 }
 
 int Glulxe::reposition_write(dest_t *dest, uint pos) {


Commit: 2391ca83da989fb5d339a4604428e24e25abd760
    https://github.com/scummvm/scummvm/commit/2391ca83da989fb5d339a4604428e24e25abd760
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-26T19:47:10-07:00

Commit Message:
GLK: GLULXE: Mark GLULXE games as unstable

Changed paths:
    engines/glk/glulxe/detection.cpp
    engines/glk/glulxe/exec.cpp


diff --git a/engines/glk/glulxe/detection.cpp b/engines/glk/glulxe/detection.cpp
index 23855d6a33..5a6ed68566 100644
--- a/engines/glk/glulxe/detection.cpp
+++ b/engines/glk/glulxe/detection.cpp
@@ -39,8 +39,11 @@ void GlulxeMetaEngine::getSupportedGames(PlainGameList &games) {
 
 GameDescriptor GlulxeMetaEngine::findGame(const char *gameId) {
 	for (const PlainGameDescriptor *pd = GLULXE_GAME_LIST; pd->gameId; ++pd) {
-		if (!strcmp(gameId, pd->gameId))
-			return *pd;
+		if (!strcmp(gameId, pd->gameId)) {
+			GameDescriptor gd = *pd;
+			gd._supportLevel = kUnstableGame;
+			return gd;
+		}
 	}
 
 	return GameDescriptor::empty();
diff --git a/engines/glk/glulxe/exec.cpp b/engines/glk/glulxe/exec.cpp
index a48efb1c75..5540e1f72d 100644
--- a/engines/glk/glulxe/exec.cpp
+++ b/engines/glk/glulxe/exec.cpp
@@ -703,7 +703,7 @@ PerformJump: /* goto label for successful jumping... ironic, no? */
 					pop_callstub(value);
 				} else {
 					/* We've failed, so we must store the failure in this opcode's
-					   operand. */
+		 			   operand. */
 					store_operand(inst[1].desttype, inst[1].value, value);
 				}
 				break;




More information about the Scummvm-git-logs mailing list