From c098422a0d7d60893f4068af329e511699553e50 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Sep 2019 19:37:35 -0700 Subject: GLK: ADRIFT: Fixes for loading savegames to work --- engines/glk/adrift/scprotos.h | 1 + engines/glk/adrift/sctaffil.cpp | 39 ++++++++++++++++++++++++++++++++---- engines/glk/adrift/serialization.cpp | 22 +++++++++++--------- 3 files changed, 49 insertions(+), 13 deletions(-) (limited to 'engines/glk') 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 -- cgit v1.2.3