aboutsummaryrefslogtreecommitdiff
path: root/engines/glk
diff options
context:
space:
mode:
authorPaul Gilbert2019-09-22 19:37:35 -0700
committerPaul Gilbert2019-09-25 20:13:27 -0700
commitc098422a0d7d60893f4068af329e511699553e50 (patch)
tree0f722a2b6d9f28efbcc468318f821fd9706f8dd0 /engines/glk
parent41c7d31fb6fe55c8579242fffd0bd70a4b86aa20 (diff)
downloadscummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.tar.gz
scummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.tar.bz2
scummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.zip
GLK: ADRIFT: Fixes for loading savegames to work
Diffstat (limited to 'engines/glk')
-rw-r--r--engines/glk/adrift/scprotos.h1
-rw-r--r--engines/glk/adrift/sctaffil.cpp39
-rw-r--r--engines/glk/adrift/serialization.cpp22
3 files changed, 49 insertions, 13 deletions
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 37d2bdc19d..753359703a 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -96,6 +96,7 @@ extern sc_uint sc_hash(const sc_char *string);
/* TAF file reader/decompressor enumerations, opaque typedef and functions. */
enum {
TAF_VERSION_NONE = 0,
+ TAF_VERSION_500 = 500,
TAF_VERSION_400 = 400,
TAF_VERSION_390 = 390,
TAF_VERSION_380 = 380
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 4bee7694d0..321f08a192 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -22,7 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
-#include "common/textconsole.h"
+#include "common/algorithm.h"
#include "common/zlib.h"
#include "common/memstream.h"
@@ -441,10 +441,37 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
return true;
#else
- return true;
+ return false;
#endif
}
+/*
+ * taf_read_raw()
+ *
+ * Read an uncompressed version 4.0 TAF save chunk used by ScummVM
+ */
+static sc_bool taf_read_raw(sc_tafref_t taf, sc_read_callbackref_t callback,
+ void *opaque, sc_bool is_gamefile) {
+ byte *buffer = new byte[BUFFER_SIZE];
+ size_t bytesRead, bytesLeft = 0;
+ size_t totalBytes, bytesWritten;
+
+ for (;;) {
+ bytesRead = callback(opaque, buffer + bytesLeft, BUFFER_SIZE - bytesLeft);
+ if ((bytesLeft + bytesRead) == 0)
+ break;
+
+ totalBytes = bytesLeft + bytesRead;
+ bytesWritten = taf_append_buffer(taf, buffer, totalBytes);
+
+ bytesLeft = totalBytes - bytesWritten;
+ if (bytesLeft)
+ Common::copy(buffer + bytesWritten, buffer + totalBytes, buffer);
+ }
+
+ delete[] buffer;
+ return true;
+}
/*
* taf_create_from_callback()
@@ -506,8 +533,8 @@ static sc_tafref_t taf_create_from_callback(sc_read_callbackref_t callback,
return NULL;
}
} else {
- /* Saved games are always considered to be version 4.0. */
- taf->version = TAF_VERSION_400;
+ /* Saved games are always considered to be for ScummVM, version 5.0. */
+ taf->version = TAF_VERSION_500;
}
/*
@@ -516,6 +543,10 @@ static sc_tafref_t taf_create_from_callback(sc_read_callbackref_t callback,
* it's obfuscated with the Visual Basic PRNG.
*/
switch (taf->version) {
+ case TAF_VERSION_500:
+ status = taf_read_raw(taf, callback, opaque, is_gamefile);
+ break;
+
case TAF_VERSION_400:
status = taf_decompress(taf, callback, opaque, is_gamefile);
break;
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
index 5a855e797c..c0fa81bf3a 100644
--- a/engines/glk/adrift/serialization.cpp
+++ b/engines/glk/adrift/serialization.cpp
@@ -242,6 +242,7 @@ bool LoadSerializer::load() {
sc_var_setref_t new_vars = nullptr;
sc_gameref_t new_game = nullptr;
Context context;
+ sc_int count = 0;
// Create a TAF (TAS) reference from callbacks, for reader functions
ser_tas = taf_create_tas(_callback, _opaque);
@@ -291,13 +292,15 @@ bool LoadSerializer::load() {
(void)readInt(context); CHECK;
(void)readInt(context); CHECK;
- // Restore rooms information.
- for (index_ = 0; index_ < gs_room_count(new_game); index_++) {
+ // Restore rooms information
+ count = gs_room_count(new_game);
+ for (index_ = 0; index_ < count; ++index_) {
gs_set_room_seen(new_game, index_, readBool(context)); CHECK;
}
- // Restore objects information.
- for (index_ = 0; index_ < gs_object_count(new_game); index_++) {
+ // Restore objects information
+ count = gs_object_count(new_game);
+ for (index_ = 0; index_ < count; ++index_) {
sc_int openable, currentstate;
// Bypass mutators for position and parent. Fix later?
@@ -325,8 +328,9 @@ bool LoadSerializer::load() {
gs_set_task_scored(new_game, index_, readBool(context)); CHECK;
}
- // Restore events information.
- for (index_ = 0; index_ < gs_event_count(new_game); index_++) {
+ // Restore events information
+ count = gs_event_count(new_game);
+ for (index_ = 0; index_ < count; index_++) {
sc_int startertype, task;
// Restore first event details.
@@ -350,8 +354,9 @@ bool LoadSerializer::load() {
}
}
- // Restore NPCs information.
- for (index_ = 0; index_ < gs_npc_count(new_game); index_++) {
+ // Restore NPCs information
+ count = gs_npc_count(new_game);
+ for (index_ = 0; index_ < count; index_++) {
sc_int walk;
gs_set_npc_location(new_game, index_, readInt(context)); CHECK;
@@ -483,7 +488,6 @@ sc_bool LoadSerializer::readBool(CONTEXT) {
// Get line, and scan for a single integer; check it's a valid-looking flag, and return it.
R0FUNC0(readString, string)
- string = readString(context);
if (sscanf(string, "%lu", &value) != 1) {
sc_error("readBool: invalid boolean at line %ld\n", ser_tasline - 1);
LONG_JUMP0