diff options
author | Paul Gilbert | 2019-09-22 19:37:35 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-09-25 20:13:27 -0700 |
commit | c098422a0d7d60893f4068af329e511699553e50 (patch) | |
tree | 0f722a2b6d9f28efbcc468318f821fd9706f8dd0 | |
parent | 41c7d31fb6fe55c8579242fffd0bd70a4b86aa20 (diff) | |
download | scummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.tar.gz scummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.tar.bz2 scummvm-rg350-c098422a0d7d60893f4068af329e511699553e50.zip |
GLK: ADRIFT: Fixes for loading savegames to work
-rw-r--r-- | engines/glk/adrift/scprotos.h | 1 | ||||
-rw-r--r-- | engines/glk/adrift/sctaffil.cpp | 39 | ||||
-rw-r--r-- | engines/glk/adrift/serialization.cpp | 22 |
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 |