[Scummvm-git-logs] scummvm master -> 3d299df77344fc580e17fd613fda9dfefc6c585f

dreammaster paulfgilbert at gmail.com
Sun Jun 16 07:32:45 CEST 2019


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
acc90002f6 GLK: ADVSYS: Added code for loading savegames from launcher
b6542b78fc GLK: Fix debug channels setup
1b6ac1a67c GLK: ADVSYS: Fix variable range checks
f3dc9a86b3 GLK: Added missing files to POTFILES
ec8409c115 GLK: Adding Quetzal classes to the base Glk namespace
c405203cde GLK: FROTZ: Change Quetzal saving to use new base Quetzal writer
3d299df773 GLK: FROTZ: Change Quetzal restoring to use new base Quetzal reader


Commit: acc90002f6937896e1f8063227b0423a653da0d2
    https://github.com/scummvm/scummvm/commit/acc90002f6937896e1f8063227b0423a653da0d2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: ADVSYS: Added code for loading savegames from launcher

Changed paths:
    engines/glk/advsys/advsys.cpp
    engines/glk/advsys/glk_interface.cpp
    engines/glk/advsys/glk_interface.h
    engines/glk/advsys/vm.cpp


diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index 26f298d..ad84128 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -22,11 +22,15 @@
 
 #include "glk/advsys/advsys.h"
 #include "common/translation.h"
+#include "common/config-manager.h"
 
 namespace Glk {
 namespace AdvSys {
 
 void AdvSys::runGame() {
+	// Check for savegame
+	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
 	if (!initialize()) {
 		GUIErrorMessage(_("Could not start AdvSys game"));
 		return;
@@ -37,6 +41,13 @@ void AdvSys::runGame() {
 		// Run game startup
 		execute(_initCodeOffset);
 
+		if (_saveSlot != -1) {
+			Common::ErrorCode err = loadGameState(_saveSlot).getCode();
+			_saveSlot = -1;
+			if (err != Common::kNoError)
+				print(_("Sorry, the savegame couldn't be restored"));
+		}
+
 		// Gameplay loop
 		while (!shouldQuit() && !shouldRestart()) {
 			// Run update code
diff --git a/engines/glk/advsys/glk_interface.cpp b/engines/glk/advsys/glk_interface.cpp
index 01abd2f..20f9f4d 100644
--- a/engines/glk/advsys/glk_interface.cpp
+++ b/engines/glk/advsys/glk_interface.cpp
@@ -31,7 +31,10 @@ bool GlkInterface::initialize() {
 }
 
 void GlkInterface::print(const Common::String &msg) {
-	glk_put_string_stream(glk_window_get_stream(_window), msg.c_str());
+	// Don't print out text if loading a savegame directly from the launcher, since we don't
+	// want any of the intro text displayed by the startup code to show
+	if (_saveSlot == -1)
+		glk_put_string_stream(glk_window_get_stream(_window), msg.c_str());
 }
 
 void GlkInterface::print(int number) {
diff --git a/engines/glk/advsys/glk_interface.h b/engines/glk/advsys/glk_interface.h
index 95dcfa8..9048818 100644
--- a/engines/glk/advsys/glk_interface.h
+++ b/engines/glk/advsys/glk_interface.h
@@ -36,6 +36,8 @@ class GlkInterface : public GlkAPI {
 private:
 	winid_t _window;
 protected:
+	int _saveSlot;
+protected:
 	/**
 	 * GLK initialization
 	 */
@@ -61,7 +63,8 @@ public:
 	/**
 	 * Constructor
 	 */
-	GlkInterface(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc) {}
+	GlkInterface(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
+		_saveSlot(-1) {}
 };
 
 } // End of namespace AdvSys
diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp
index 8c6072c..33712bc 100644
--- a/engines/glk/advsys/vm.cpp
+++ b/engines/glk/advsys/vm.cpp
@@ -310,12 +310,12 @@ void VM::opYORN() {
 
 void VM::opSAVE() {
 	if (saveGame().getCode() != Common::kNoError)
-		print("Sorry, the savegame couldn't be created");
+		print(_("Sorry, the savegame couldn't be created"));
 }
 
 void VM::opRESTORE() {
 	if (saveGame().getCode() != Common::kNoError)
-		print("Sorry, the savegame couldn't be restored");
+		print(_("Sorry, the savegame couldn't be restored"));
 }
 
 void VM::opARG() {


Commit: b6542b78fcb2270ab29839f16c2eb5ac1d904c7e
    https://github.com/scummvm/scummvm/commit/b6542b78fcb2270ab29839f16c2eb5ac1d904c7e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: Fix debug channels setup

Changed paths:
    engines/glk/glk.cpp


diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp
index 5d99fc9..7155cd8 100644
--- a/engines/glk/glk.cpp
+++ b/engines/glk/glk.cpp
@@ -50,6 +50,12 @@ GlkEngine::GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc) :
 		_copySelect(false), _terminated(false), _pcSpeaker(nullptr),
 		gli_register_obj(nullptr), gli_unregister_obj(nullptr), gli_register_arr(nullptr),
 		gli_unregister_arr(nullptr) {
+	// Set up debug channels
+	DebugMan.addDebugChannel(kDebugCore, "core", "Core engine debug level");
+	DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
+	DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
+	DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling");
+
 	g_vm = this;
 }
 
@@ -68,12 +74,6 @@ GlkEngine::~GlkEngine() {
 }
 
 void GlkEngine::initialize() {
-	// Set up debug channels
-	DebugMan.addDebugChannel(kDebugCore, "core", "Core engine debug level");
-	DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
-	DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
-	DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling");
-
 	initGraphicsMode();
 
 	_conf = new Conf(getInterpreterType());


Commit: 1b6ac1a67cc65ca5fcb5c076f3f48b7ce8c6e6a8
    https://github.com/scummvm/scummvm/commit/1b6ac1a67cc65ca5fcb5c076f3f48b7ce8c6e6a8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: ADVSYS: Fix variable range checks

Changed paths:
    engines/glk/advsys/game.cpp


diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index 3b6133d..d051a35 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -250,12 +250,16 @@ int Game::getActionLocation(int action) const {
 }
 
 int Game::getVariable(int variableNum) {
-	assert(variableNum < _variableCount);
+	if (variableNum < 1 || variableNum > _variableCount)
+		error("Invalid ariable number %d", variableNum);
+
 	return READ_LE_UINT16(_variableTable + variableNum * 2);
 }
 
 void Game::setVariable(int variableNum, int value) {
-	assert(variableNum < _variableCount);
+	if (variableNum < 1 || variableNum > _variableCount)
+		error("Invalid ariable number %d", variableNum);
+
 	WRITE_LE_UINT16(_variableTable + variableNum * 2, value);
 }
 


Commit: f3dc9a86b3d5e12c564a7e764eba7239f3872359
    https://github.com/scummvm/scummvm/commit/f3dc9a86b3d5e12c564a7e764eba7239f3872359
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: Added missing files to POTFILES

Changed paths:
    engines/glk/POTFILES


diff --git a/engines/glk/POTFILES b/engines/glk/POTFILES
index 935c263..895fabd 100644
--- a/engines/glk/POTFILES
+++ b/engines/glk/POTFILES
@@ -1,4 +1,9 @@
+engines/glk/glk_api.cpp
 engines/glk/streams.cpp
-engines/glk/scott/scott.cpp
+engines/glk/advsys/advsys.cpp
+engines/glk/advsys/vm.cpp
+engines/glk/alan2/alan2.cpp
 engines/glk/frotz/detection.cpp
 engines/glk/glulxe/glulxe.cpp
+engines/glk/magnetic/magnetic.cpp
+engines/glk/scott/scott.cpp


Commit: ec8409c115d7fe99e9d917e81218e3677ba9a18f
    https://github.com/scummvm/scummvm/commit/ec8409c115d7fe99e9d917e81218e3677ba9a18f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: Adding Quetzal classes to the base Glk namespace

Changed paths:
  A engines/glk/quetzal.cpp
  A engines/glk/quetzal.h
    engines/glk/frotz/quetzal.h
    engines/glk/module.mk


diff --git a/engines/glk/frotz/quetzal.h b/engines/glk/frotz/quetzal.h
index 98765b8..10effff 100644
--- a/engines/glk/frotz/quetzal.h
+++ b/engines/glk/frotz/quetzal.h
@@ -24,22 +24,12 @@
 #define GLK_FROTZ_QUETZAL
 
 #include "glk/glk_types.h"
+#include "glk/quetzal.h"
 #include "glk/frotz/frotz_types.h"
 
 namespace Glk {
 namespace Frotz {
 
-enum QueztalTag {
-	ID_FORM = MKTAG('F', 'O', 'R', 'M'),
-	ID_IFZS = MKTAG('I', 'F', 'Z', 'S'),
-	ID_IFhd = MKTAG('I', 'F', 'h', 'd'),
-	ID_UMem = MKTAG('U', 'M', 'e', 'm'),
-	ID_CMem = MKTAG('C', 'M', 'e', 'm'),
-	ID_Stks = MKTAG('S', 't', 'k', 's'),
-	ID_ANNO = MKTAG('A', 'N', 'N', 'O'),
-	ID_SCVM = MKTAG('S', 'C', 'V', 'M')
-};
-
 class Processor;
 
 class Quetzal {
@@ -63,7 +53,7 @@ private:
 	void write_word(zword w) { _out->writeUint16BE(w); }
 	void write_long(uint l) { _out->writeUint32BE(l); }
 	void write_run(zword run) { write_byte(0); write_byte(run); }
-	void write_chnk(QueztalTag id, zword len) {
+	void write_chnk(uint32 id, zword len) {
 		_out->writeUint32BE(id);
 		_out->writeUint32BE(len);
 	}
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index b599f02..19dc6c9 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS := \
 	glk_dispa.o \
 	pc_speaker.o \
 	picture.o \
+	quetzal.o \
 	raw_decoder.o \
 	screen.o \
 	selection.o \
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
new file mode 100644
index 0000000..7a53e59
--- /dev/null
+++ b/engines/glk/quetzal.cpp
@@ -0,0 +1,105 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/quetzal.h"
+#include "common/memstream.h"
+
+namespace Glk {
+
+bool QuetzalReader::open(Common::SeekableReadStream *stream, uint32 formType) {
+	_chunks.clear();
+	stream->seek(0);
+	if (stream->readUint32BE() != ID_FORM)
+		return false;
+
+	uint32 size = stream->readUint32BE();
+	uint32 fileFormType = stream->readUint32BE();
+
+	if (formType != ID_IFSF && fileFormType != formType)
+		return false;
+	if ((int)size > stream->size() || (size & 1) || (size < 4))
+		return false;
+	size -= 4;
+
+	// Iterate through reading chunk headers
+	while (size > 0) {
+		if (size < 8)
+			// Couldn't contain a chunk
+			return false;
+
+		// Get in the chunk header
+		Chunk c;
+		c._id = stream->readUint32BE();
+		c._size = stream->readUint32BE() - 8;
+		c._offset = stream->pos();
+		_chunks.push_back(c);
+
+		int chunkRemainder = c._size + (c._size & 1);
+		if ((stream->pos() + chunkRemainder) > stream->size())
+			// Chunk goes beyond the file size
+			return false;
+
+		size -= 8 + chunkRemainder;
+		stream->skip(chunkRemainder);
+	}
+
+	return true;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Common::WriteStream &QuetzalWriter::add(uint32 chunkId) {
+	// Sanity check to prevent adding the same chunk multiple times
+	for (uint idx = 0; idx < _chunks.size(); ++idx) {
+		if (_chunks[idx]._id == chunkId)
+			error("Duplicate chunk added");
+	}
+
+	_chunks.push_back(Chunk());
+	return _chunks.back()._stream;
+}
+
+void QuetzalWriter::save(Common::WriteStream *out, uint32 formType) {
+	// Calculate the size of the chunks
+	uint size = 4;
+	for (uint idx = 0; idx < _chunks.size(); ++idx)
+		size += _chunks[idx]._stream.size();
+
+	// Write out the header
+	out->writeUint32BE(ID_FORM);
+	out->writeUint32BE(size);
+	out->writeUint32BE(formType);
+
+	// Loop through writing the chunks
+	for (uint idx = 0; idx < _chunks.size(); ++idx) {
+		Common::MemoryWriteStreamDynamic &s = _chunks[idx]._stream;
+		uint chunkSize = s.size() + (s.size() & 1);
+
+		out->writeUint32BE(_chunks[idx]._id);
+		out->writeUint32BE(chunkSize);
+		out->write(s.getData(), s.size());
+		if (s.size() & 1)
+			out->writeByte(0);
+	}
+}
+
+} // End of namespace Glk
diff --git a/engines/glk/quetzal.h b/engines/glk/quetzal.h
new file mode 100644
index 0000000..2badf35
--- /dev/null
+++ b/engines/glk/quetzal.h
@@ -0,0 +1,144 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_QUETZAL
+#define GLK_QUETZAL
+
+#include "common/array.h"
+#include "common/endian.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+#include "glk/blorb.h"
+
+namespace Glk {
+
+enum QueztalTag {
+	ID_IFSF = MKTAG('I', 'F', 'S', 'F'),
+	ID_IFZS = MKTAG('I', 'F', 'Z', 'S'),
+	ID_IFhd = MKTAG('I', 'F', 'h', 'd'),
+	ID_UMem = MKTAG('U', 'M', 'e', 'm'),
+	ID_CMem = MKTAG('C', 'M', 'e', 'm'),
+	ID_Stks = MKTAG('S', 't', 'k', 's'),
+	ID_SCVM = MKTAG('S', 'C', 'V', 'M')
+};
+
+/**
+ * Quetzal save file reader
+ */
+class QuetzalReader {
+	struct Chunk {
+		uint32 _id;
+		size_t _offset, _size;
+	};
+public:
+	/**
+	 * Iterator for the chunks list
+	 */
+	struct Iterator : public Chunk {
+	private:
+		Common::SeekableReadStream *_stream;
+		Common::Array<Chunk> &_chunks;
+		int _index;
+		int _size;
+	public:
+		/**
+		 * Constructor
+		 */
+		Iterator(Common::SeekableReadStream *stream, Common::Array<Chunk> &chunks, int index, int size) :
+			_stream(stream), _chunks(chunks), _index(index), _size(size) {}
+
+		/**
+		 * Incrementer
+		 */
+		Iterator &operator++() { ++_index; }
+		
+		/**
+		 * Decrementer
+		 */
+		Iterator &operator--() { --_index; }
+
+		/**
+		 * Get a read stream for the contents of a chunk
+		 */
+		Common::SeekableReadStream *getStream() {
+			_stream->seek(_offset);
+			return _stream->readStream(_size);
+		}
+	};
+private:
+	Common::SeekableReadStream *_stream;
+	Common::Array<Chunk> _chunks;
+public:
+	/**
+	 * Constructor
+	 */
+	QuetzalReader() : _stream(nullptr) {}
+
+	/**
+	 * Opens a Quetzal file for access
+	 */
+	bool open(Common::SeekableReadStream *stream, uint32 formType = ID_IFSF);
+
+	/**
+	 * Return an iterator for the beginning of the chunks list
+	 */
+	Iterator begin() { return Iterator(_stream, _chunks, 0, _chunks.size()); }
+
+	/**
+	 * Return an iterator for the beginning of the chunks list
+	 */
+	Iterator end() { return Iterator(_stream, _chunks, 0, _chunks.size()); }
+};
+
+/**
+ * Quetzal save file writer
+ */
+class QuetzalWriter {
+	/**
+	 * Chunk entry
+	 */
+	struct Chunk {
+		uint32 _id;
+		Common::MemoryWriteStreamDynamic _stream;
+
+		/**
+		 * Constructor
+		 */
+		Chunk() : _id(0), _stream(DisposeAfterUse::YES) {}
+	};
+private:
+	Common::Array<Chunk> _chunks;
+public:
+	/**
+	 * Add a chunk
+	 */
+	Common::WriteStream &add(uint32 chunkId);
+
+	/**
+	 * Save the added chunks to file
+	 */
+	void save(Common::WriteStream *out, uint32 formType = ID_IFSF);
+};
+
+} // End of namespace Glk
+
+#endif


Commit: c405203cdeb9310325a3db8ec698d09f86c9a0a1
    https://github.com/scummvm/scummvm/commit/c405203cdeb9310325a3db8ec698d09f86c9a0a1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: FROTZ: Change Quetzal saving to use new base Quetzal writer

Changed paths:
    engines/glk/frotz/quetzal.cpp
    engines/glk/frotz/quetzal.h
    engines/glk/quetzal.cpp
    engines/glk/quetzal.h


diff --git a/engines/glk/frotz/quetzal.cpp b/engines/glk/frotz/quetzal.cpp
index e025b2b..0ae6d2f 100644
--- a/engines/glk/frotz/quetzal.cpp
+++ b/engines/glk/frotz/quetzal.cpp
@@ -39,178 +39,139 @@ enum ParseState {
 	GOT_ERROR  = 0x80
 };
 
-
-bool Quetzal::read_word(Common::ReadStream *f, zword *result) {
-	*result = f->readUint16BE();
-	return true;
-}
-
-bool Quetzal::read_long(Common::ReadStream *f, uint *result) {
-	*result = f->readUint32BE();
-	return true;
-}
+#define WRITE_RUN(RUN) ws.writeByte(0); ws.writeByte((byte)(RUN))
 
 bool Quetzal::save(Common::WriteStream *svf, Processor *proc, const Common::String &desc) {
 	Processor &p = *proc;
-	uint ifzslen = 0, cmemlen = 0, stkslen = 0, descLen = 0;
 	offset_t pc;
 	zword i, j, n;
 	zword nvars, nargs, nstk;
 	zbyte var;
-	long cmempos, stkspos;
 	int c;
 
-	// Set a temporary memory stream for writing out the data. This is needed, since we need to
-	// do some seeking within it at the end to fill out totals before properly writing it all out
-	Common::MemoryWriteStreamDynamic saveData(DisposeAfterUse::YES);
-	_out = &saveData;
-
-	// Write `IFZS' header.
-	write_chnk(ID_FORM, 0);
-	write_long(ID_IFZS);
+	// Reset Quetzal writer
+	_writer.clear();
 
 	// Write `IFhd' chunk
-	pc = p.getPC();
-	write_chnk(ID_IFhd, 13);
-	write_word(p.h_release);
-	for (i = H_SERIAL; i<H_SERIAL + 6; ++i)
-		write_byte(p[i]);
-
-	write_word(p.h_checksum);
-	write_long(pc << 8);		// Includes pad
+	{
+		Common::WriteStream &ws = _writer.add(ID_IFhd);
+		pc = p.getPC();
+		ws.writeUint16BE(p.h_release);
+		ws.write(&p[H_SERIAL], 6);
+		ws.writeUint16BE(p.h_checksum);
+
+		ws.writeByte((pc >> 16) & 0xff);
+		ws.writeByte((pc >> 8) & 0xff);
+		ws.writeByte(pc & 0xff);
+	}
 
 	// Write 'ANNO' chunk
-	descLen = desc.size() + 1;
-	write_chnk(ID_ANNO, descLen);
-	saveData.write(desc.c_str(), desc.size());
-	write_byte(0);
-	if ((desc.size() % 2) == 0) {
-		write_byte(0);
-		++descLen;
+	{
+		Common::WriteStream &ws = _writer.add(ID_ANNO);
+		ws.write(desc.c_str(), desc.size());
+		ws.writeByte(0);
 	}
 
 	// Write `CMem' chunk.
-	cmempos = saveData.pos();
-	write_chnk(ID_CMem, 0);
-	_storyFile->seek(0);
-
-	// j holds current run length.
-	for (i = 0, j = 0, cmemlen = 0; i < p.h_dynamic_size; ++i) {
-		c = _storyFile->readByte();
-		c ^= p[i];
-
-		if (c == 0) {
-			// It's a run of equal bytes
-			++j;
-		} else {
-			// Write out any run there may be.
-			if (j > 0) {
-				for (; j > 0x100; j -= 0x100) {
-					write_run(0xFF);
-					cmemlen += 2;
-				}
-				write_run(j - 1);
-				cmemlen += 2;
-				j = 0;
+	{
+		Common::WriteStream &ws = _writer.add(ID_CMem);
+		_storyFile->seek(0);
+
+		// j holds current run length.
+		for (i = 0, j = 0; i < p.h_dynamic_size; ++i) {
+			c = _storyFile->readByte();
+			c ^= p[i];
+
+			if (c == 0) {
+				// It's a run of equal bytes
+				++j;
 			}
+			else {
+				// Write out any run there may be.
+				if (j > 0) {
+					for (; j > 0x100; j -= 0x100) {
+						WRITE_RUN(0xFF);
+					}
+					WRITE_RUN(j - 1);
+					j = 0;
+				}
 
-			// Any runs are now written. Write this (nonzero) byte
-			write_byte((zbyte)c);
-			++cmemlen;
+				// Any runs are now written. Write this (nonzero) byte
+				ws.writeByte(c);
+			}
 		}
 	}
 
-	// Reached end of dynamic memory. We ignore any unwritten run there may be at this point.
-	if (cmemlen & 1)
-		// Chunk length must be even.
-		write_byte(0);
-
 	// Write `Stks' chunk. You are not expected to understand this. ;)
-	stkspos = saveData.pos();
-	write_chnk(ID_Stks, 0);
-
-	// We construct a list of frame indices, most recent first, in `frames'.
-	// These indices are the offsets into the `stack' array of the word before
-	// the first word pushed in each frame.
-	frames[0] = p._sp - p._stack;	// The frame we'd get by doing a call now.
-	for (i = p._fp - p._stack + 4, n = 0; i < STACK_SIZE + 4; i = p._stack[i - 3] + 5)
-		frames[++n] = i;
-
-	// All versions other than V6 can use evaluation stack outside a function
-	// context. We write a faked stack frame (most fields zero) to cater for this.
-	if (p.h_version != V6) {
-		for (i = 0; i < 6; ++i)
-			write_byte(0);
-		nstk = STACK_SIZE - frames[n];
-		write_word(nstk);
-		for (j = STACK_SIZE - 1; j >= frames[n]; --j)
-			write_word(p._stack[j]);
-		stkslen = 8 + 2 * nstk;
-	}
-
-	// Write out the rest of the stack frames.
-	for (i = n; i > 0; --i) {
-		zword *pf = p._stack + frames[i] - 4;	// Points to call frame
-		nvars = (pf[0] & 0x0F00) >> 8;
-		nargs = pf[0] & 0x00FF;
-		nstk = frames[i] - frames[i - 1] - nvars - 4;
-		pc = ((uint)pf[3] << 9) | pf[2];
-
-		// Check type of call
-		switch (pf[0] & 0xF000)	{
-		case 0x0000:
-			// Function
-			var = p[pc];
-			pc = ((pc + 1) << 8) | nvars;
-			break;
-
-		case 0x1000:
-			// Procedure
-			var = 0;
-			pc = (pc << 8) | 0x10 | nvars;	// Set procedure flag
-			break;
-
-		default:
-			p.runtimeError(ERR_SAVE_IN_INTER);
-			return 0;
+	{
+		Common::WriteStream &ws = _writer.add(ID_Stks);
+
+		// We construct a list of frame indices, most recent first, in `frames'.
+		// These indices are the offsets into the `stack' array of the word before
+		// the first word pushed in each frame.
+		frames[0] = p._sp - p._stack;	// The frame we'd get by doing a call now.
+		for (i = p._fp - p._stack + 4, n = 0; i < STACK_SIZE + 4; i = p._stack[i - 3] + 5)
+			frames[++n] = i;
+
+		// All versions other than V6 can use evaluation stack outside a function
+		// context. We write a faked stack frame (most fields zero) to cater for this.
+		if (p.h_version != V6) {
+			for (i = 0; i < 6; ++i)
+				ws.writeByte(0);
+			nstk = STACK_SIZE - frames[n];
+			ws.writeUint16BE(nstk);
+			for (j = STACK_SIZE - 1; j >= frames[n]; --j)
+				ws.writeUint16BE(p._stack[j]);
 		}
-		if (nargs != 0)
-			nargs = (1 << nargs) - 1;	// Make args into bitmap
 
-		// Write the main part of the frame...
-		write_long(pc);
-		write_byte(var);
-		write_byte(nargs);
-		write_word(nstk);
+		// Write out the rest of the stack frames.
+		for (i = n; i > 0; --i) {
+			zword *pf = p._stack + frames[i] - 4;	// Points to call frame
+			nvars = (pf[0] & 0x0F00) >> 8;
+			nargs = pf[0] & 0x00FF;
+			nstk = frames[i] - frames[i - 1] - nvars - 4;
+			pc = ((uint)pf[3] << 9) | pf[2];
+
+			// Check type of call
+			switch (pf[0] & 0xF000) {
+			case 0x0000:
+				// Function
+				var = p[pc];
+				pc = ((pc + 1) << 8) | nvars;
+				break;
 
-		// Write the variables and eval stack
-		for (j = 0, --pf; j<nvars + nstk; ++j, --pf)
-			write_word(*pf);
+			case 0x1000:
+				// Procedure
+				var = 0;
+				pc = (pc << 8) | 0x10 | nvars;	// Set procedure flag
+				break;
 
-		// Calculate length written thus far
-		stkslen += 8 + 2 * (nvars + nstk);
+			default:
+				p.runtimeError(ERR_SAVE_IN_INTER);
+				return 0;
+			}
+			if (nargs != 0)
+				nargs = (1 << nargs) - 1;	// Make args into bitmap
+
+			// Write the main part of the frame...
+			ws.writeUint32BE(pc);
+			ws.writeByte(var);
+			ws.writeByte(nargs);
+			ws.writeUint16BE(nstk);
+
+			// Write the variables and eval stack
+			for (j = 0, --pf; j<nvars + nstk; ++j, --pf)
+				ws.writeUint16BE(*pf);
+		}
 	}
 
-	// Fill in variable chunk lengths
-	ifzslen = 4 * 8 + 4 + 14 + cmemlen + stkslen + descLen;
-	if (cmemlen & 1)
-		++ifzslen;
-
-	saveData.seek(4);
-	saveData.writeUint32BE(ifzslen);
-	saveData.seek(cmempos + 4);
-	saveData.writeUint32BE(cmemlen);
-	saveData.seek(stkspos + 4);
-	saveData.writeUint32BE(stkslen);
-
 	// Write the save data out
-	svf->write(saveData.getData(), saveData.size());
+	_writer.save(svf, ID_IFZS);
 
 	// After all that, still nothing went wrong!
 	return true;
 }
 
-
 int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 	Processor &p = *proc;
 	uint ifzslen, currlen, tmpl;
diff --git a/engines/glk/frotz/quetzal.h b/engines/glk/frotz/quetzal.h
index 10effff..ce6b1bd 100644
--- a/engines/glk/frotz/quetzal.h
+++ b/engines/glk/frotz/quetzal.h
@@ -35,19 +35,11 @@ class Processor;
 class Quetzal {
 private:
 	Common::SeekableReadStream *_storyFile;
-	Common::WriteStream *_out;
+	QuetzalReader _reader;
+	QuetzalWriter _writer;
 	zword frames[STACK_SIZE / 4 + 1];
+/*
 private:
-	/**
-	 * Read a 16-bit value from the file
-	 */
-	bool read_word(Common::ReadStream *f, zword *result);
-
-	/**
-	 * Read  32-bit value from the file
-	 */
-	bool read_long(Common::ReadStream *f, uint *result);
-
 	void write_byte(zbyte b) { _out->writeByte(b); }
 	void write_bytx(zword b) { _out->writeByte(b & 0xFF); }
 	void write_word(zword w) { _out->writeUint16BE(w); }
@@ -57,6 +49,7 @@ private:
 		_out->writeUint32BE(id);
 		_out->writeUint32BE(len);
 	}
+	*/
 public:
 	/**
 	 * Constructor
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 7a53e59..4a3ea8b 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -25,6 +25,11 @@
 
 namespace Glk {
 
+void QuetzalReader::clear() {
+	_chunks.clear();
+	_stream = nullptr;
+}
+
 bool QuetzalReader::open(Common::SeekableReadStream *stream, uint32 formType) {
 	_chunks.clear();
 	stream->seek(0);
@@ -74,7 +79,7 @@ Common::WriteStream &QuetzalWriter::add(uint32 chunkId) {
 			error("Duplicate chunk added");
 	}
 
-	_chunks.push_back(Chunk());
+	_chunks.push_back(Chunk(chunkId));
 	return _chunks.back()._stream;
 }
 
@@ -82,7 +87,7 @@ void QuetzalWriter::save(Common::WriteStream *out, uint32 formType) {
 	// Calculate the size of the chunks
 	uint size = 4;
 	for (uint idx = 0; idx < _chunks.size(); ++idx)
-		size += _chunks[idx]._stream.size();
+		size += 8 + _chunks[idx]._stream.size() + (_chunks[idx]._stream.size() & 1);
 
 	// Write out the header
 	out->writeUint32BE(ID_FORM);
@@ -92,10 +97,9 @@ void QuetzalWriter::save(Common::WriteStream *out, uint32 formType) {
 	// Loop through writing the chunks
 	for (uint idx = 0; idx < _chunks.size(); ++idx) {
 		Common::MemoryWriteStreamDynamic &s = _chunks[idx]._stream;
-		uint chunkSize = s.size() + (s.size() & 1);
 
 		out->writeUint32BE(_chunks[idx]._id);
-		out->writeUint32BE(chunkSize);
+		out->writeUint32BE(s.size());
 		out->write(s.getData(), s.size());
 		if (s.size() & 1)
 			out->writeByte(0);
diff --git a/engines/glk/quetzal.h b/engines/glk/quetzal.h
index 2badf35..706fb9f 100644
--- a/engines/glk/quetzal.h
+++ b/engines/glk/quetzal.h
@@ -94,6 +94,11 @@ public:
 	QuetzalReader() : _stream(nullptr) {}
 
 	/**
+	 * Clear
+	 */
+	void clear();
+
+	/**
 	 * Opens a Quetzal file for access
 	 */
 	bool open(Common::SeekableReadStream *stream, uint32 formType = ID_IFSF);
@@ -124,11 +129,21 @@ class QuetzalWriter {
 		 * Constructor
 		 */
 		Chunk() : _id(0), _stream(DisposeAfterUse::YES) {}
+
+		/**
+		 * Constructor
+		 */
+		Chunk(uint32 id) : _id(id), _stream(DisposeAfterUse::YES) {}
 	};
 private:
 	Common::Array<Chunk> _chunks;
 public:
 	/**
+	 * Clear
+	 */
+	void clear() { _chunks.clear(); }
+
+	/**
 	 * Add a chunk
 	 */
 	Common::WriteStream &add(uint32 chunkId);


Commit: 3d299df77344fc580e17fd613fda9dfefc6c585f
    https://github.com/scummvm/scummvm/commit/3d299df77344fc580e17fd613fda9dfefc6c585f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-15T22:31:50-07:00

Commit Message:
GLK: FROTZ: Change Quetzal restoring to use new base Quetzal reader

Changed paths:
    engines/glk/frotz/quetzal.cpp
    engines/glk/frotz/quetzal.h
    engines/glk/quetzal.cpp
    engines/glk/quetzal.h


diff --git a/engines/glk/frotz/quetzal.cpp b/engines/glk/frotz/quetzal.cpp
index 0ae6d2f..d12d41d 100644
--- a/engines/glk/frotz/quetzal.cpp
+++ b/engines/glk/frotz/quetzal.cpp
@@ -172,47 +172,27 @@ bool Quetzal::save(Common::WriteStream *svf, Processor *proc, const Common::Stri
 	return true;
 }
 
-int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
+int Quetzal::restore(Common::SeekableReadStream *sv, Processor *proc) {
 	Processor &p = *proc;
-	uint ifzslen, currlen, tmpl;
+	uint tmpl, currlen;
 	offset_t pc;
-	zword i, tmpw;
+	zword tmpw;
 	int fatal = 0;	// Set to -1 when errors must be fatal.
-	zbyte skip, progress = GOT_NONE;
-	int x, y;
-
-	// Check it's really an `IFZS' file.
-	tmpl = svf->readUint32BE();
-	ifzslen = svf->readUint32BE();
-	currlen = svf->readUint32BE();
-	if (tmpl != ID_FORM || currlen != ID_IFZS) {
+	zbyte progress = GOT_NONE;
+	int i, x, y;
+
+	// Load the savefile for reading
+	if (!_reader.open(sv, ID_IFZS)) {
 		p.print_string("This is not a saved game file!\n");
 		return 0;
 	}
-	if ((ifzslen & 1) || ifzslen<4)
-		// Sanity checks
-		return 0;
-	ifzslen -= 4;
 
 	// Read each chunk and process it
-	while (ifzslen > 0) {
-		// Read chunk header
-		if (ifzslen < 8)
-			// Couldn't contain a chunk
-			return 0;
-
-		tmpl = svf->readUint32BE();
-		currlen = svf->readUint32BE();
-		ifzslen -= 8;	// Reduce remaining by size of header
-
-		// Handle chunk body
-		if (ifzslen < currlen)
-			// Chunk goes past EOF?!
-			return 0;
-		skip = currlen & 1;
-		ifzslen -= currlen + (uint)skip;
-
-		switch (tmpl) {
+	for (QuetzalReader::Iterator it = _reader.begin(); it != _reader.end(); ++it) {
+		Common::SeekableReadStream *s = it.getStream();
+		currlen = (*it)._size;
+
+		switch ((*it)._id) {
 		// `IFhd' header chunk; must be first in file
 		case ID_IFhd:
 			if (progress & GOT_HEADER) {
@@ -223,17 +203,17 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 			if (currlen < 13)
 				return fatal;
 
-			tmpw = svf->readUint16BE();
+			tmpw = s->readUint16BE();
 			if (tmpw != p.h_release)
 				progress = GOT_ERROR;
 
-			for (i = H_SERIAL; i < H_SERIAL + 6; ++i) {
-				x = svf->readByte();
-				if (x != p[i])
+			for (int idx = H_SERIAL; idx < H_SERIAL + 6; ++idx) {
+				x = s->readByte();
+				if (x != p[idx])
 					progress = GOT_ERROR;
 			}
 
-			tmpw = svf->readUint16BE();
+			tmpw = s->readUint16BE();
 			if (tmpw != p.h_checksum)
 				progress = GOT_ERROR;
 
@@ -242,17 +222,15 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				return fatal;
 			}
 
-			x = svf->readByte();
+			x = s->readByte();
 			pc = (uint)x << 16;
-			x = svf->readByte();
+			x = s->readByte();
 			pc |= (uint)x << 8;
-			x = svf->readByte();
+			x = s->readByte();
 			pc |= (uint)x;
 
 			fatal = -1;		// Setting PC means errors must be fatal
 			p.setPC(pc);
-
-			svf->skip(currlen - 13);	// Skip rest of chunk
 			break;
 
 		// `Stks' stacks chunk; restoring this is quite complex. ;)
@@ -273,8 +251,8 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				if (currlen < 8)
 					return fatal;
 
-				svf->skip(6);
-				tmpw = svf->readUint16BE();
+				s->skip(6);
+				tmpw = s->readUint16BE();
 
 				if (tmpw > STACK_SIZE) {
 					p.print_string("Save-file has too much stack (and I can't cope).\n");
@@ -285,7 +263,7 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				if (currlen < (uint)tmpw * 2)
 					return fatal;
 				for (i = 0; i < tmpw; ++i)
-					*--p._sp = svf->readUint16BE();
+					*--p._sp = s->readUint16BE();
 				currlen -= tmpw * 2;
 			}
 
@@ -300,12 +278,12 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				}
 
 				// Read PC, procedure flag and formal param count
-				tmpl = svf->readUint32BE();
+				tmpl = s->readUint32BE();
 				y = (int)(tmpl & 0x0F);		// Number of formals
 				tmpw = y << 8;
 
 				// Read result variable
-				x = svf->readByte();
+				x = s->readByte();
 
 				// Check the procedure flag...
 				if (tmpl & 0x10) {
@@ -328,7 +306,7 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				*--p._sp = (zword)(p._fp - p._stack - 1);	// FP
 
 				// Read and process argument mask
-				x = svf->readByte();
+				x = s->readByte();
 				++x;		// Should now be a power of 2
 				for (i = 0; i<8; ++i)
 					if (x & (1 << i))
@@ -343,7 +321,7 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				p._fp = p._sp;	// FP for next frame
 
 				// Read amount of eval stack used
-				tmpw = svf->readUint16BE();
+				tmpw = s->readUint16BE();
 
 				tmpw += y;	// Amount of stack + number of locals
 				if (p._sp - p._stack <= tmpw) {
@@ -354,14 +332,13 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 					return fatal;
 				
 				for (i = 0; i < tmpw; ++i)
-					--*p._sp = svf->readUint16BE();
+					--*p._sp = s->readUint16BE();
 				currlen -= tmpw * 2;
 			}
 
 			// End of `Stks' processing...
 			break;
 
-		// Any more special chunk types must go in HERE or ABOVE
 		// `CMem' compressed memory chunk; uncompress it
 		case ID_CMem:
 			if (!(progress & GOT_MEMORY)) {
@@ -369,13 +346,13 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				
 				i = 0;	// Bytes written to data area
 				for (; currlen > 0; --currlen) {
-					x = svf->readByte();
+					x = s->readByte();
 					if (x == 0) {
 						// Start of run
 						// Check for bogus run
 						if (currlen < 2) {
 							p.print_string("File contains bogus `CMem' chunk.\n");
-							svf->skip(currlen);
+							s->skip(currlen);
 
 							currlen = 1;
 							i = 0xFFFF;
@@ -384,7 +361,7 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 
 						// Copy story file to memory during the run
 						--currlen;
-						x = svf->readByte();
+						x = s->readByte();
 						for (; x >= 0 && i < p.h_dynamic_size; --x, ++i)
 							p[i] = _storyFile->readByte();
 					} else {
@@ -397,7 +374,7 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 					// Make sure we don't load too much
 					if (i > p.h_dynamic_size) {
 						p.print_string("warning: `CMem' chunk too long!\n");
-						svf->skip(currlen);
+						s->skip(currlen);
 						break;	// Keep going; there may be a `UMem' too
 					}
 				}
@@ -410,14 +387,14 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 					progress |= GOT_MEMORY;		// Only if succeeded
 				break;
 			}
+			break;
 
-			// fall through
-
+		// 'UMem' Uncompressed memory chunk
 		case ID_UMem:
 			if (!(progress & GOT_MEMORY)) {
 				// Must be exactly the right size
 				if (currlen == p.h_dynamic_size) {
-					if (svf->read(p.zmp, currlen) == currlen) {
+					if (s->read(p.zmp, currlen) == currlen) {
 						progress |= GOT_MEMORY;	// Only on success
 						break;
 					}
@@ -427,16 +404,13 @@ int Quetzal::restore(Common::SeekableReadStream *svf, Processor *proc) {
 				
 				// Fall into default action (skip chunk) on errors
 			}
-
-			// fall through
+			break;
 
 		default:
-			svf->seek(currlen, SEEK_CUR);		// Skip chunk
 			break;
 		}
 
-		if (skip)
-			svf->skip(1);						// Skip pad byte
+		delete s;
 	}
 
 	// We've reached the end of the file. For the restoration to have been a
diff --git a/engines/glk/frotz/quetzal.h b/engines/glk/frotz/quetzal.h
index ce6b1bd..ee3f3b3 100644
--- a/engines/glk/frotz/quetzal.h
+++ b/engines/glk/frotz/quetzal.h
@@ -38,18 +38,6 @@ private:
 	QuetzalReader _reader;
 	QuetzalWriter _writer;
 	zword frames[STACK_SIZE / 4 + 1];
-/*
-private:
-	void write_byte(zbyte b) { _out->writeByte(b); }
-	void write_bytx(zword b) { _out->writeByte(b & 0xFF); }
-	void write_word(zword w) { _out->writeUint16BE(w); }
-	void write_long(uint l) { _out->writeUint32BE(l); }
-	void write_run(zword run) { write_byte(0); write_byte(run); }
-	void write_chnk(uint32 id, zword len) {
-		_out->writeUint32BE(id);
-		_out->writeUint32BE(len);
-	}
-	*/
 public:
 	/**
 	 * Constructor
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 4a3ea8b..fb2f70c 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -31,8 +31,10 @@ void QuetzalReader::clear() {
 }
 
 bool QuetzalReader::open(Common::SeekableReadStream *stream, uint32 formType) {
-	_chunks.clear();
+	clear();
 	stream->seek(0);
+	_stream = stream;
+
 	if (stream->readUint32BE() != ID_FORM)
 		return false;
 
@@ -54,7 +56,7 @@ bool QuetzalReader::open(Common::SeekableReadStream *stream, uint32 formType) {
 		// Get in the chunk header
 		Chunk c;
 		c._id = stream->readUint32BE();
-		c._size = stream->readUint32BE() - 8;
+		c._size = stream->readUint32BE();
 		c._offset = stream->pos();
 		_chunks.push_back(c);
 
diff --git a/engines/glk/quetzal.h b/engines/glk/quetzal.h
index 706fb9f..19dd939 100644
--- a/engines/glk/quetzal.h
+++ b/engines/glk/quetzal.h
@@ -53,35 +53,55 @@ public:
 	/**
 	 * Iterator for the chunks list
 	 */
-	struct Iterator : public Chunk {
+	struct Iterator {
 	private:
 		Common::SeekableReadStream *_stream;
 		Common::Array<Chunk> &_chunks;
 		int _index;
-		int _size;
 	public:
 		/**
 		 * Constructor
 		 */
-		Iterator(Common::SeekableReadStream *stream, Common::Array<Chunk> &chunks, int index, int size) :
-			_stream(stream), _chunks(chunks), _index(index), _size(size) {}
+		Iterator(Common::SeekableReadStream *stream, Common::Array<Chunk> &chunks, int index) :
+			_stream(stream), _chunks(chunks), _index(index) {}
+
+		/**
+		 * Deference
+		 */
+		Chunk &operator*() const { return _chunks[_index]; }
 
 		/**
 		 * Incrementer
 		 */
-		Iterator &operator++() { ++_index; }
+		Iterator &operator++() {
+			++_index;
+			return *this;
+		}
 		
 		/**
 		 * Decrementer
 		 */
-		Iterator &operator--() { --_index; }
+		Iterator &operator--() {
+			--_index;
+			return *this;
+		}
+
+		/**
+		 * Equality test
+		 */
+		bool operator==(const Iterator &rhs) { return _index == rhs._index; }
+
+		/**
+		 * Inequality test
+		 */
+		bool operator!=(const Iterator &rhs) { return _index != rhs._index; }
 
 		/**
 		 * Get a read stream for the contents of a chunk
 		 */
 		Common::SeekableReadStream *getStream() {
-			_stream->seek(_offset);
-			return _stream->readStream(_size);
+			_stream->seek(_chunks[_index]._offset);
+			return _stream->readStream(_chunks[_index]._size);
 		}
 	};
 private:
@@ -106,12 +126,12 @@ public:
 	/**
 	 * Return an iterator for the beginning of the chunks list
 	 */
-	Iterator begin() { return Iterator(_stream, _chunks, 0, _chunks.size()); }
+	Iterator begin() { return Iterator(_stream, _chunks, 0); }
 
 	/**
 	 * Return an iterator for the beginning of the chunks list
 	 */
-	Iterator end() { return Iterator(_stream, _chunks, 0, _chunks.size()); }
+	Iterator end() { return Iterator(_stream, _chunks, _chunks.size()); }
 };
 
 /**





More information about the Scummvm-git-logs mailing list