diff options
author | Paul Gilbert | 2019-09-08 12:25:46 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-09-25 20:13:27 -0700 |
commit | c03b7a50eafe3c6a559c55746ec88d5a37885e9a (patch) | |
tree | be028fbaead87b7d1445f9fe74dc1ad731239e3d /engines/glk/adrift | |
parent | 855b75f6dfd602879b7153e576124749d8c47c92 (diff) | |
download | scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.gz scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.bz2 scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.zip |
GLK: ADRIFT: Implement zlib decompression
Diffstat (limited to 'engines/glk/adrift')
-rw-r--r-- | engines/glk/adrift/os_glk.cpp | 7 | ||||
-rw-r--r-- | engines/glk/adrift/sctaffil.cpp | 155 |
2 files changed, 39 insertions, 123 deletions
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp index 41409cb2eb..243aca63ae 100644 --- a/engines/glk/adrift/os_glk.cpp +++ b/engines/glk/adrift/os_glk.cpp @@ -3112,12 +3112,10 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream if (!gsc_game) { gsc_game = nullptr; - gsc_game_message = "Unable to load an Adrift game from the" - " requested file."; + gsc_game_message = "Unable to load an Adrift game from the requested file."; } else gsc_game_message = nullptr; - delete game_stream; /* * If the game was created successfully and there is a restore stream, try @@ -3129,8 +3127,7 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream { sc_free_game(gsc_game); gsc_game = nullptr; - gsc_game_message = "Unable to restore this Adrift game from the" - " requested file."; + gsc_game_message = "Unable to restore this Adrift game from the requested file."; } else gsc_game_message = nullptr; diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp index 6f0ebae171..6868580b5b 100644 --- a/engines/glk/adrift/sctaffil.cpp +++ b/engines/glk/adrift/sctaffil.cpp @@ -23,6 +23,20 @@ #include "glk/adrift/scare.h" #include "glk/adrift/scprotos.h" #include "common/textconsole.h" +#include "common/zlib.h" +#include "common/memstream.h" + +#if defined(USE_ZLIB) + #ifdef __SYMBIAN32__ + #include <zlib\zlib.h> + #else + #include <zlib.h> + #endif + + #if ZLIB_VERNUM < 0x1204 + #error Version 1.2.0.4 or newer of zlib is required for this code + #endif +#endif namespace Glk { namespace Adrift { @@ -426,130 +440,35 @@ taf_unobfuscate (sc_tafref_t taf, sc_read_callbackref_t callback, return TRUE; } +#define BUFFER_SIZE 16384 /* * taf_decompress() * - * Decompress a version 4.0 TAF file from data read by repeated calls to the - * callback() function. Callback() should return the count of bytes placed - * in the buffer, 0 if no more (end of file). Assumes that the file has been - * read past the header. + * Decompress a version 4.0 TAF */ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback, - void *opaque, sc_bool is_gamefile) -{ - error("TODO: decompress"); -#ifdef TODO - sc_byte *in_buffer, *out_buffer; -// z_stream stream; - sc_int status; - sc_bool is_first_block; - - /* - * Malloc buffers, done this way rather than as stack variables for systems - * such as PalmOS that may have limited stacks. - */ - in_buffer = sc_malloc (IN_BUFFER_SIZE); - out_buffer = sc_malloc (OUT_BUFFER_SIZE); - - /* Initialize Zlib inflation functions. */ - stream.next_out = out_buffer; - stream.avail_out = OUT_BUFFER_SIZE; - stream.next_in = in_buffer; - stream.avail_in = 0; - - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - status = inflateInit (&stream); - if (status != Z_OK) - { - sc_error ("taf_decompress: inflateInit: error %ld\n", status); - sc_free (in_buffer); - sc_free (out_buffer); - return FALSE; - } - - /* - * Attempts to restore non-savefiles can arrive here, because there's no - * up-front header check, like the one for TAF files, applied to them. The - * first we see of the problem is when the first inflate() fails, so it's - * handy to use a flag here to block the error report for such cases. - */ - is_first_block = TRUE; - - /* Inflate the input buffers. */ - while (TRUE) - { - sc_int in_bytes, out_bytes; - - /* If the input buffer is empty, try to obtain more data. */ - if (stream.avail_in == 0) - { - in_bytes = callback (opaque, in_buffer, IN_BUFFER_SIZE); - stream.next_in = in_buffer; - stream.avail_in = in_bytes; - } - - /* Decompress as much stream data as we can. */ - status = inflate (&stream, Z_SYNC_FLUSH); - if (status != Z_STREAM_END && status != Z_OK) - { - if (is_gamefile || !is_first_block) - sc_error ("taf_decompress: inflate: error %ld\n", status); - sc_free (in_buffer); - sc_free (out_buffer); - return FALSE; - } - out_bytes = OUT_BUFFER_SIZE - stream.avail_out; - - /* See if decompressed data is available. */ - if (out_bytes > 0) - { - sc_int consumed; - - /* Add lines from this buffer to the TAF. */ - consumed = taf_append_buffer (taf, out_buffer, out_bytes); - - /* Move unused buffer data to buffer start. */ - memmove (out_buffer, - out_buffer + consumed, OUT_BUFFER_SIZE - consumed); - - /* Reset inflation stream for available space. */ - stream.next_out = out_buffer + out_bytes - consumed; - stream.avail_out += consumed; - } - - /* Enable full error reporting for non-gamefiles. */ - is_first_block = FALSE; - - /* If at inflation stream end and output is empty, leave loop. */ - if (status == Z_STREAM_END && stream.avail_out == OUT_BUFFER_SIZE) - break; - } - - /* - * Decompression completed, note the total bytes read for use when locating - * resources later on in the file. For what it's worth, this value is only - * used in version 4.0 games. - */ - taf->total_in_bytes = stream.total_in; - if (is_gamefile) - taf->total_in_bytes += VERSION_HEADER_SIZE + V400_HEADER_EXTRA; - - /* End inflation. */ - status = inflateEnd (&stream); - if (status != Z_OK) - sc_error ("taf_decompress: warning: inflateEnd: error %ld\n", status); - - if (taf->is_unterminated) - sc_fatal ("taf_decompress: unterminated final data slab\n"); - - /* Return successfully. */ - sc_free (in_buffer); - sc_free (out_buffer); - return TRUE; + void *opaque, sc_bool is_gamefile) { +#if USE_ZLIB + Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque; + assert(src); + Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES); + + if (!Common::inflateZlibHeaderless(&dest, src)) + return false; + + // Iterate through pushing data out to the taf file + const byte *pTemp = dest.getData(); + int bytesRemaining = dest.size(); + + while (bytesRemaining > 0) { + int consumed = taf_append_buffer(taf, pTemp, bytesRemaining); + bytesRemaining -= consumed; + } + + return true; +#else + return true; #endif } |