aboutsummaryrefslogtreecommitdiff
path: root/engines/glk
diff options
context:
space:
mode:
authorPaul Gilbert2019-09-08 12:25:46 -0700
committerPaul Gilbert2019-09-25 20:13:27 -0700
commitc03b7a50eafe3c6a559c55746ec88d5a37885e9a (patch)
treebe028fbaead87b7d1445f9fe74dc1ad731239e3d /engines/glk
parent855b75f6dfd602879b7153e576124749d8c47c92 (diff)
downloadscummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.gz
scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.bz2
scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.zip
GLK: ADRIFT: Implement zlib decompression
Diffstat (limited to 'engines/glk')
-rw-r--r--engines/glk/adrift/os_glk.cpp7
-rw-r--r--engines/glk/adrift/sctaffil.cpp155
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
}