diff options
| -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  | 
