[Scummvm-git-logs] scummvm-tools master -> c3494968416b8558ec0500c0f7d8bb3d4396077d

bgK bastien.bouclet at gmail.com
Fri Jul 27 10:54:12 CEST 2018


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

Summary:
c349496841 TOOLS: Rework the Mohawk tools


Commit: c3494968416b8558ec0500c0f7d8bb3d4396077d
    https://github.com/scummvm/scummvm-tools/commit/c3494968416b8558ec0500c0f7d8bb3d4396077d
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2018-07-27T10:51:48+02:00

Commit Message:
TOOLS: Rework the Mohawk tools

* Remove the deriven tool as it is entirely duplicated and superseded by
  the dumpCard and dumpStack in-engine debug commands.
* Change the extract_mohawk and construct_mohawk tools to use the shared
  file abstraction instead of their own.
* Change extract_mohawk and construct_mohawk to adjust the tMOV
  QuickTime stco atom offsets so extracted movies can be played with
  regular QT players and packed movies can be played by ScummVM. This
  way it's possible to repack Riven archives.

Changed paths:
  A engines/mohawk/utils.cpp
  A engines/mohawk/utils.h
  R engines/mohawk/deriven.cpp
  R engines/mohawk/utils/file.cpp
  R engines/mohawk/utils/file.h
  R engines/mohawk/utils/stream.h
    .gitignore
    Makefile
    Makefile.common
    dists/win32/ScummVM Tools.iss
    dists/win32/scummvm-tools.nsi
    dists/win32/scummvm-tools.nsi.in
    engines/mohawk/archive.cpp
    engines/mohawk/archive.h
    engines/mohawk/construct_mohawk.cpp
    engines/mohawk/extract_mohawk.cpp


diff --git a/.gitignore b/.gitignore
index 9dd78d8..2ced923 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,6 @@
 /degob
 /dekyra
 /deprince
-/deriven
 /descumm
 /desword2
 /extract_mohawk
diff --git a/Makefile b/Makefile
index 3ae1d26..dec383a 100644
--- a/Makefile
+++ b/Makefile
@@ -106,7 +106,6 @@ endif
 	$(STRIP) degob$(EXEEXT) -o $(WIN32PATH)/tools/degob$(EXEEXT)
 	$(STRIP) dekyra$(EXEEXT) -o $(WIN32PATH)/tools/dekyra$(EXEEXT)
 	$(STRIP) deprince$(EXEEXT) -o $(WIN32PATH)/tools/deprince$(EXEEXT)
-	$(STRIP) deriven$(EXEEXT) -o $(WIN32PATH)/tools/deriven$(EXEEXT)
 	$(STRIP) descumm$(EXEEXT) -o $(WIN32PATH)/tools/descumm$(EXEEXT)
 	$(STRIP) desword2$(EXEEXT) -o $(WIN32PATH)/tools/desword2$(EXEEXT)
 	$(STRIP) extract_mohawk$(EXEEXT) -o $(WIN32PATH)/tools/extract_mohawk$(EXEEXT)
@@ -145,7 +144,6 @@ endif
 	$(STRIP) degob$(EXEEXT)              -o $(srcdir)/$(WIN32BUILD)/degob$(EXEEXT)
 	$(STRIP) dekyra$(EXEEXT)             -o $(srcdir)/$(WIN32BUILD)/dekyra$(EXEEXT)
 	$(STRIP) deprince$(EXEEXT)           -o $(srcdir)/$(WIN32BUILD)/deprince$(EXEEXT)
-	$(STRIP) deriven$(EXEEXT)            -o $(srcdir)/$(WIN32BUILD)/deriven$(EXEEXT)
 	$(STRIP) descumm$(EXEEXT)            -o $(srcdir)/$(WIN32BUILD)/descumm$(EXEEXT)
 	$(STRIP) desword2$(EXEEXT)           -o $(srcdir)/$(WIN32BUILD)/desword2$(EXEEXT)
 	$(STRIP) extract_mohawk$(EXEEXT)     -o $(srcdir)/$(WIN32BUILD)/extract_mohawk$(EXEEXT)
@@ -248,7 +246,6 @@ endif
 	$(STRIP) degob$(EXEEXT) -o $(AMIGAOS4PATH)/tools/degob$(EXEEXT)
 	$(STRIP) dekyra$(EXEEXT) -o $(AMIGAOS4PATH)/tools/dekyra$(EXEEXT)
 	$(STRIP) deprince$(EXEEXT) -o $(AMIGAOS4PATH)/tools/deprince$(EXEEXT)
-	$(STRIP) deriven$(EXEEXT) -o $(AMIGAOS4PATH)/tools/deriven$(EXEEXT)
 	$(STRIP) descumm$(EXEEXT) -o $(AMIGAOS4PATH)/tools/descumm$(EXEEXT)
 	$(STRIP) desword2$(EXEEXT) -o $(AMIGAOS4PATH)/tools/desword2$(EXEEXT)
 	$(STRIP) extract_mohawk$(EXEEXT) -o $(AMIGAOS4PATH)/tools/extract_mohawk$(EXEEXT)
diff --git a/Makefile.common b/Makefile.common
index ca77142..08a95c4 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -27,7 +27,6 @@ PROGRAMS = \
 	degob \
 	dekyra \
 	deprince \
-	deriven \
 	descumm \
 	desword2 \
 	gob_loadcalc \
@@ -105,16 +104,6 @@ deprince_OBJS := \
 	engines/prince/utils.o \
 	$(UTILS)
 
-deriven_OBJS := \
-	engines/mohawk/archive.o \
-	engines/mohawk/deriven.o \
-	engines/mohawk/utils/file.o \
-	common/hashmap.o \
-	common/md5.o \
-	common/memorypool.o \
-	common/str.o \
-	common/util.o
-
 descumm_OBJS := \
 	engines/scumm/descumm.o \
 	engines/scumm/descumm6.o \
@@ -153,15 +142,12 @@ gob_loadcalc_OBJS := \
 extract_mohawk_OBJS := \
 	engines/mohawk/archive.o \
 	engines/mohawk/extract_mohawk.o \
-	engines/mohawk/utils/file.o \
-	common/hashmap.o \
-	common/md5.o \
-	common/memorypool.o \
-	common/str.o \
-	common/util.o
+	engines/mohawk/utils.o \
+	$(UTILS)
 
 construct_mohawk_OBJS := \
 	engines/mohawk/construct_mohawk.o \
+	engines/mohawk/utils.o \
 	$(UTILS)
 
 pegasus_save_types_OBJS := \
diff --git a/dists/win32/ScummVM Tools.iss b/dists/win32/ScummVM Tools.iss
index 8d48e81..1e4c593 100755
--- a/dists/win32/ScummVM Tools.iss	
+++ b/dists/win32/ScummVM Tools.iss	
@@ -29,7 +29,6 @@ Source: "tools\create_sjisfnt.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "tools\decine.exe"; DestDir: "{app}"; Flags: ignoreversion 
 Source: "tools\degob.exe"; DestDir: "{app}"; Flags: ignoreversion 
 Source: "tools\dekyra.exe"; DestDir: "{app}"; Flags: ignoreversion 
-Source: "tools\deriven.exe"; DestDir: "{app}"; Flags: ignoreversion 
 Source: "tools\descumm.exe"; DestDir: "{app}"; Flags: ignoreversion 
 Source: "tools\desword2.exe"; DestDir: "{app}"; Flags: ignoreversion 
 Source: "tools\extract_mohawk.exe"; DestDir: "{app}"; Flags: ignoreversion 
diff --git a/dists/win32/scummvm-tools.nsi b/dists/win32/scummvm-tools.nsi
index 9a34b6d..32f7b25 100644
--- a/dists/win32/scummvm-tools.nsi
+++ b/dists/win32/scummvm-tools.nsi
@@ -231,7 +231,6 @@ Section "ScummVM" SecMain
 	File "${build_dir}\decine.exe"
 	File "${build_dir}\degob.exe"
 	File "${build_dir}\dekyra.exe"
-	File "${build_dir}\deriven.exe"
 	File "${build_dir}\descumm.exe"
 	File "${build_dir}\desword2.exe"
 	File "${build_dir}\extract_mohawk.exe"
@@ -290,7 +289,6 @@ Section -un.Main SecUninstall
 	Delete /REBOOTOK $INSTDIR\decine.exe"
 	Delete /REBOOTOK $INSTDIR\degob.exe"
 	Delete /REBOOTOK $INSTDIR\dekyra.exe"
-	Delete /REBOOTOK $INSTDIR\deriven.exe"
 	Delete /REBOOTOK $INSTDIR\descumm.exe"
 	Delete /REBOOTOK $INSTDIR\desword2.exe"
 	Delete /REBOOTOK $INSTDIR\extract_mohawk.exe"
diff --git a/dists/win32/scummvm-tools.nsi.in b/dists/win32/scummvm-tools.nsi.in
index 551ce27..126da45 100644
--- a/dists/win32/scummvm-tools.nsi.in
+++ b/dists/win32/scummvm-tools.nsi.in
@@ -231,7 +231,6 @@ Section "ScummVM" SecMain
 	File "${build_dir}\decine.exe"
 	File "${build_dir}\degob.exe"
 	File "${build_dir}\dekyra.exe"
-	File "${build_dir}\deriven.exe"
 	File "${build_dir}\descumm.exe"
 	File "${build_dir}\desword2.exe"
 	File "${build_dir}\extract_mohawk.exe"
@@ -290,7 +289,6 @@ Section -un.Main SecUninstall
 	Delete /REBOOTOK $INSTDIR\decine.exe"
 	Delete /REBOOTOK $INSTDIR\degob.exe"
 	Delete /REBOOTOK $INSTDIR\dekyra.exe"
-	Delete /REBOOTOK $INSTDIR\deriven.exe"
 	Delete /REBOOTOK $INSTDIR\descumm.exe"
 	Delete /REBOOTOK $INSTDIR\desword2.exe"
 	Delete /REBOOTOK $INSTDIR\extract_mohawk.exe"
diff --git a/engines/mohawk/archive.cpp b/engines/mohawk/archive.cpp
index 794f5ac..59a3d7c 100644
--- a/engines/mohawk/archive.cpp
+++ b/engines/mohawk/archive.cpp
@@ -23,12 +23,6 @@
 
 #include "engines/mohawk/archive.h"
 
-inline uint32 SWAP_BYTES_32(uint32 a) {
-	const uint16 low = (uint16)a, high = (uint16)(a >> 16);
-	return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16)
-		   | (uint16)((high >> 8) | (high << 8));
-}
-
 Common::String MohawkArchive::tag2string(uint32 tag) {
 	char str[5];
 	str[0] = (char)(tag >> 24);
@@ -54,7 +48,7 @@ MohawkArchive::MohawkArchive() {
 }
 
 void MohawkArchive::close() {
-	delete _mhk; _mhk = NULL;
+	_mhk = NULL;
 	delete[] _types; _types = NULL;
 	delete[] _fileTable; _fileTable = NULL;
 
@@ -63,7 +57,7 @@ void MohawkArchive::close() {
 	_curExTypeIndex = 0;
 }
 
-void MohawkArchive::open(Common::SeekableReadStream *stream) {
+void MohawkArchive::open(Common::File *stream) {
 	// Make sure no other file is open...
 	close();
 	_mhk = stream;
@@ -94,7 +88,7 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 	/////////////////////////////////
 
 	// Type Table
-	_mhk->seek(_rsrc.abs_offset);
+	_mhk->seek(_rsrc.abs_offset, SEEK_SET);
 	_typeTable.name_offset = _mhk->readUint16BE();
 	_typeTable.resource_types = _mhk->readUint16BE();
 
@@ -114,7 +108,7 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 			debug (3, "Type[%02d]: Tag = \'%s\' ResTable Offset = %04x  NameTable Offset = %04x", i, tag2str(_types[i].tag), _types[i].resource_table_offset, _types[i].name_table_offset);
 
 		//Resource Table
-		_mhk->seek(_rsrc.abs_offset + _types[i].resource_table_offset);
+		_mhk->seek(_rsrc.abs_offset + _types[i].resource_table_offset, SEEK_SET);
 		_types[i].resTable.resources = _mhk->readUint16BE();
 
 		debug (3, "Resources = %04x", _types[i].resTable.resources);
@@ -129,7 +123,7 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 		}
 
 		// Name Table
-		_mhk->seek(_rsrc.abs_offset + _types[i].name_table_offset);
+		_mhk->seek(_rsrc.abs_offset + _types[i].name_table_offset, SEEK_SET);
 		_types[i].nameTable.num = _mhk->readUint16BE();
 
 		debug (3, "Names = %04x", _types[i].nameTable.num);
@@ -144,7 +138,7 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 
 			// Name List
 			uint32 pos = _mhk->pos();
-			_mhk->seek(_rsrc.abs_offset + _typeTable.name_offset + _types[i].nameTable.entries[j].offset);
+			_mhk->seek(_rsrc.abs_offset + _typeTable.name_offset + _types[i].nameTable.entries[j].offset, SEEK_SET);
 			char c = (char)_mhk->readByte();
 			while (c != 0) {
 				_types[i].nameTable.entries[j].name += c;
@@ -154,16 +148,16 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 			debug (3, "Name = \'%s\'", _types[i].nameTable.entries[j].name.c_str());
 
 			// Get back to next entry
-			_mhk->seek(pos);
+			_mhk->seek(pos, SEEK_SET);
 		}
 
 		// Return to next TypeTable entry
-		_mhk->seek(_rsrc.abs_offset + (i + 1) * 8 + 4);
+		_mhk->seek(_rsrc.abs_offset + (i + 1) * 8 + 4, SEEK_SET);
 
 		debug (3, "\n");
 	}
 
-	_mhk->seek(_rsrc.abs_offset + _rsrc.file_table_offset);
+	_mhk->seek(_rsrc.abs_offset + _rsrc.file_table_offset, SEEK_SET);
 	_fileTableAmount = _mhk->readUint32BE();
 	_fileTable = new FileTable[_fileTableAmount];
 
@@ -182,20 +176,8 @@ void MohawkArchive::open(Common::SeekableReadStream *stream) {
 	}
 }
 
-bool MohawkArchive::hasResource(uint32 tag, uint16 id) {
-	if (!_mhk)
-		return false;
-
-	int16 typeIndex = getTypeIndex(tag);
-
-	if (typeIndex < 0)
-		return false;
-
-	return (getIdIndex(typeIndex, id) >= 0);
-}
-
 MohawkOutputStream MohawkArchive::getRawData(uint32 tag, uint16 id) {
-	MohawkOutputStream output = { 0, 0, 0, 0, 0, "" };
+	MohawkOutputStream output = { 0, 0, 0, 0, 0, 0, 0, "" };
 
 	if (!_mhk)
 		return output;
@@ -215,20 +197,32 @@ MohawkOutputStream MohawkArchive::getRawData(uint32 tag, uint16 id) {
 
 	// WORKAROUND: tMOV resources pretty much ignore the size part of the file table,
 	// as the original just passed the full Mohawk file to QuickTime and the offset.
+	// We set the resource size to the number of bytes till the beginning of the next
+	// resource in the archive.
 	// We need to do this because of the way Mohawk is set up (this is much more "proper"
-	// than passing _mhk at the right offset). We may want to do that in the future, though.
-	if (_types[typeIndex].tag == ID_TMOV) {
-		if (fileTableIndex == _fileTableAmount - 1)
-			output.stream = new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _mhk->size());
-		else
-			output.stream = new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _fileTable[fileTableIndex + 1].offset);
+	// than passing _stream at the right offset). We may want to do that in the future, though.
+	if (_types[_curExType].tag == ID_TMOV) {
+		uint16 nextFileIndex = fileTableIndex + 1;
+		output.size = 0;
+		while (output.size == 0) {
+			if (nextFileIndex == _fileTableAmount)
+				output.size = _mhk->size() - _fileTable[fileTableIndex].offset;
+			else
+				output.size = _fileTable[nextFileIndex].offset - _fileTable[fileTableIndex].offset;
+
+			// Loop because two entries in the file table may point to the same data
+			// in the archive.
+			nextFileIndex++;
+		}
 	} else
-		output.stream = new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _fileTable[fileTableIndex].offset + _fileTable[fileTableIndex].dataSize);
+		output.size = _fileTable[fileTableIndex].dataSize;
 
 	output.tag = tag;
 	output.id = id;
 	output.index = fileTableIndex;
 	output.flags = _fileTable[fileTableIndex].flags;
+	output.offset = _fileTable[fileTableIndex].offset;
+
 	for (uint16 i = 0; i < _types[typeIndex].nameTable.num; i++) {
 		if (_types[typeIndex].nameTable.entries[i].index == fileTableIndex+1) {
 			output.name = _types[typeIndex].nameTable.entries[i].name;
@@ -236,11 +230,14 @@ MohawkOutputStream MohawkArchive::getRawData(uint32 tag, uint16 id) {
 		}
 	}
 
+	output.stream = _mhk;
+	output.stream->seek(output.offset, SEEK_SET);
+
 	return output;
 }
 
 MohawkOutputStream MohawkArchive::getNextFile() {
-	MohawkOutputStream output = { 0, 0, 0, 0, 0, "" };
+	MohawkOutputStream output = { 0, 0, 0, 0, 0, 0, 0, "" };
 
 	if (_curExType >= _typeTable.resource_types) // No more!
 		return output;
@@ -255,21 +252,35 @@ MohawkOutputStream MohawkArchive::getNextFile() {
 
 	uint16 fileTableIndex = _types[_curExType].resTable.entries[_curExTypeIndex].index - 1;
 
-	// For some unknown reason, all tMOV resources have incorrect sizes. We correct this by getting the differences between offsets.
-	uint32 dataSize = 0;
+	// WORKAROUND: tMOV resources pretty much ignore the size part of the file table,
+	// as the original just passed the full Mohawk file to QuickTime and the offset.
+	// We set the resource size to the number of bytes till the beginning of the next
+	// resource in the archive.
+	// We need to do this because of the way Mohawk is set up (this is much more "proper"
+	// than passing _stream at the right offset). We may want to do that in the future, though.
 	if (_types[_curExType].tag == ID_TMOV) {
-		if (fileTableIndex == _fileTableAmount - 1)
-			dataSize = _mhk->size() - _fileTable[fileTableIndex].offset;
-		else
-			dataSize = _fileTable[fileTableIndex + 1].offset - _fileTable[fileTableIndex].offset;
+		uint16 nextFileIndex = fileTableIndex + 1;
+		output.size = 0;
+		while (output.size == 0) {
+			if (nextFileIndex == _fileTableAmount)
+				output.size = _mhk->size() - _fileTable[fileTableIndex].offset;
+			else
+				output.size = _fileTable[nextFileIndex].offset - _fileTable[fileTableIndex].offset;
+
+			// Loop because two entries in the file table may point to the same data
+			// in the archive.
+			nextFileIndex++;
+		}
 	} else
-		dataSize = _fileTable[fileTableIndex].dataSize;
+		output.size = _fileTable[fileTableIndex].dataSize;
 
-	output.stream = new Common::SeekableSubReadStream(_mhk, _fileTable[fileTableIndex].offset, _fileTable[fileTableIndex].offset + dataSize, false);
 	output.tag = _types[_curExType].tag;
 	output.id = _types[_curExType].resTable.entries[_curExTypeIndex].id;
 	output.index = fileTableIndex;
 	output.flags = _fileTable[fileTableIndex].flags;
+	output.offset = _fileTable[fileTableIndex].offset;
+	output.stream = _mhk;
+	output.stream->seek(output.offset, SEEK_SET);
 
 	for (uint16 i = 0; i < _types[_curExType].nameTable.num; i++) {
 		if (_types[_curExType].nameTable.entries[i].index == fileTableIndex+1) {
@@ -282,7 +293,7 @@ MohawkOutputStream MohawkArchive::getNextFile() {
 	return output;
 }
 
-void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
+void LivingBooksArchive_v1::open(Common::File *stream) {
 	close();
 	_mhk = stream;
 
@@ -313,7 +324,7 @@ void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
 			uint32 oldPos = _mhk->pos();
 
 			// Resource Table/File Table
-			_mhk->seek(_types[i].resource_table_offset);
+			_mhk->seek(_types[i].resource_table_offset, SEEK_SET);
 			_types[i].resTable.resources = _mhk->readUint16BE();
 			_types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
 
@@ -322,15 +333,15 @@ void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
 				_types[i].resTable.entries[j].offset = _mhk->readUint32BE();
 				_types[i].resTable.entries[j].size = _mhk->readByte() << 16;
 				_types[i].resTable.entries[j].size += _mhk->readUint16BE();
-				_mhk->skip(5); // Unknown (always 0?)
+				_mhk->seek(5, SEEK_CUR); // Unknown (always 0?)
 
 				debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
 			}
 
-			_mhk->seek(oldPos);
+			_mhk->seek(oldPos, SEEK_SET);
 			debug (3, "\n");
 		}
-	} else if (SWAP_BYTES_32(headerSize) == 6) { // We're in Little Endian mode (Windows)
+	} else if (SWAP_32(headerSize) == 6) { // We're in Little Endian mode (Windows)
 		_mhk->readUint16LE(); // Resource Table Size
 		_typeTable.resource_types = _mhk->readUint16LE();
 		_types = new OldType[_typeTable.resource_types];
@@ -347,7 +358,7 @@ void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
 			uint32 oldPos = _mhk->pos();
 
 			// Resource Table/File Table
-			_mhk->seek(_types[i].resource_table_offset);
+			_mhk->seek(_types[i].resource_table_offset, SEEK_SET);
 			_types[i].resTable.resources = _mhk->readUint16LE();
 			_types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
 
@@ -360,7 +371,7 @@ void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
 				debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
 			}
 
-			_mhk->seek(oldPos);
+			_mhk->seek(oldPos, SEEK_SET);
 			debug (3, "\n");
 		}
 	} else
@@ -369,7 +380,7 @@ void LivingBooksArchive_v1::open(Common::SeekableReadStream *stream) {
 }
 
 MohawkOutputStream LivingBooksArchive_v1::getRawData(uint32 tag, uint16 id) {
-	MohawkOutputStream output = { 0, 0, 0, 0, 0, "" };
+	MohawkOutputStream output = { 0, 0, 0, 0, 0, 0, 0, "" };
 
 	if (!_mhk)
 		return output;
@@ -384,16 +395,19 @@ MohawkOutputStream LivingBooksArchive_v1::getRawData(uint32 tag, uint16 id) {
 	if (idIndex < 0)
 		return output;
 
-	output.stream = new Common::SeekableSubReadStream(_mhk, _types[typeIndex].resTable.entries[idIndex].offset, _types[typeIndex].resTable.entries[idIndex].offset + _types[typeIndex].resTable.entries[idIndex].size);
+	output.offset = _types[typeIndex].resTable.entries[idIndex].offset;
+	output.size   = _types[typeIndex].resTable.entries[idIndex].size;
 	output.tag = tag;
 	output.id = id;
 	output.index = idIndex;
+	output.stream = _mhk;
+	output.stream->seek(output.offset, SEEK_SET);
 
 	return output;
 }
 
 MohawkOutputStream LivingBooksArchive_v1::getNextFile() {
-	MohawkOutputStream output = { 0, 0, 0, 0, 0, "" };
+	MohawkOutputStream output = { 0, 0, 0, 0, 0, 0, 0, "" };
 
 	if (_curExType >= _typeTable.resource_types) // No more!
 		return output;
@@ -406,16 +420,19 @@ MohawkOutputStream LivingBooksArchive_v1::getNextFile() {
 			return output;
 	}
 
-	output.stream = new Common::SeekableSubReadStream(_mhk, _types[_curExType].resTable.entries[_curExTypeIndex].offset, _types[_curExType].resTable.entries[_curExTypeIndex].offset + _types[_curExType].resTable.entries[_curExTypeIndex].size);
+	output.offset = _types[_curExType].resTable.entries[_curExTypeIndex].offset;
+	output.size   = _types[_curExType].resTable.entries[_curExTypeIndex].size;
 	output.tag = _types[_curExType].tag;
 	output.id = _types[_curExType].resTable.entries[_curExTypeIndex].id;
 	output.index = _curExType;
+	output.stream = _mhk;
+	output.stream->seek(output.offset, SEEK_SET);
 
 	_curExTypeIndex++;
 	return output;
 }
 
-void CSWorldDeluxeArchive::open(Common::SeekableReadStream *stream) {
+void CSWorldDeluxeArchive::open(Common::File *stream) {
 	close();
 	_mhk = stream;
 
@@ -425,7 +442,7 @@ void CSWorldDeluxeArchive::open(Common::SeekableReadStream *stream) {
 
 	uint32 typeTableOffset = _mhk->readUint32LE();
 
-	_mhk->seek(typeTableOffset);
+	_mhk->seek(typeTableOffset, SEEK_SET);
 
 	_typeTable.resource_types = _mhk->readUint16LE();
 	_types = new OldType[_typeTable.resource_types];
@@ -441,7 +458,7 @@ void CSWorldDeluxeArchive::open(Common::SeekableReadStream *stream) {
 		uint32 oldPos = _mhk->pos();
 
 		// Resource Table/File Table
-		_mhk->seek(_types[i].resource_table_offset + typeTableOffset);
+		_mhk->seek(_types[i].resource_table_offset + typeTableOffset, SEEK_SET);
 		_types[i].resTable.resources = _mhk->readUint16LE();
 		_types[i].resTable.entries = new OldType::ResourceTable::Entries[_types[i].resTable.resources];
 
@@ -454,12 +471,12 @@ void CSWorldDeluxeArchive::open(Common::SeekableReadStream *stream) {
 			debug (4, "Entry[%02x]: ID = %04x (%d)\tOffset = %08x, Size = %08x", j, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].id, _types[i].resTable.entries[j].offset, _types[i].resTable.entries[j].size);
 		}
 
-		_mhk->seek(oldPos);
+		_mhk->seek(oldPos, SEEK_SET);
 		debug (3, "\n");
 	}
 }
 
-MohawkArchive *MohawkArchive::createMohawkArchive(Common::SeekableReadStream *stream) {
+MohawkArchive *MohawkArchive::createMohawkArchive(Common::File *stream) {
 	uint32 headerTag = stream->readUint32BE();
 
 	MohawkArchive *mohawkArchive = 0;
@@ -469,17 +486,17 @@ MohawkArchive *MohawkArchive::createMohawkArchive(Common::SeekableReadStream *st
 		headerTag = stream->readUint32BE();
 		if (headerTag == ID_RSRC)
 			mohawkArchive = new MohawkArchive();
-	} else if (headerTag == 6 || SWAP_BYTES_32(headerTag) == 6) {
+	} else if (headerTag == 6 || SWAP_32(headerTag) == 6) {
 		// Assume the Living Books v1 archive format
 		mohawkArchive = new LivingBooksArchive_v1();
 	} else {
-		headerTag = SWAP_BYTES_32(headerTag);
+		headerTag = SWAP_32(headerTag);
 		// Use a simple heuristic for testing if it's a CSWorld Deluxe file
 		if (headerTag + 2 < stream->size()) {
-			stream->seek(headerTag);
+			stream->seek(headerTag, SEEK_SET);
 			uint16 typeCount = stream->readUint16LE();
 
-			if (typeCount * 6 + stream->pos() < stream->size()) {
+			if (typeCount * 6 + (uint32)stream->pos() < stream->size()) {
 				bool isDeluxeArchive = true;
 
 				for (uint16 i = 0; i < typeCount; i++) {
@@ -496,7 +513,7 @@ MohawkArchive *MohawkArchive::createMohawkArchive(Common::SeekableReadStream *st
 		}
 	}
 
-	stream->seek(0);
+	stream->seek(0, SEEK_SET);
 
 	if (mohawkArchive)
 		mohawkArchive->open(stream);
diff --git a/engines/mohawk/archive.h b/engines/mohawk/archive.h
index 4d508b3..732ec37 100644
--- a/engines/mohawk/archive.h
+++ b/engines/mohawk/archive.h
@@ -27,7 +27,7 @@
 #include "common/str.h"
 #include "common/endian.h"
 #include "common/util.h"
-#include "engines/mohawk/utils/stream.h"
+#include "common/file.h"
 
 // Main FourCC's
 #define ID_MHWK MKID_BE('MHWK') // Main FourCC
@@ -122,10 +122,12 @@
 #define tag2str(x)	MohawkArchive::tag2string(x).c_str()
 
 struct MohawkOutputStream {
-	Common::SeekableSubReadStream *stream;
+	Common::File *stream;
 	uint32 tag;
 	uint32 id;
 	uint32 index;
+	uint32 offset;
+	uint32 size;
 	byte flags;
 	Common::String name;
 };
@@ -185,19 +187,18 @@ public:
 	virtual ~MohawkArchive() { close(); }
 
 	// Detect new/old Mohawk archive format. Return NULL if the file is neither.
-	static MohawkArchive *createMohawkArchive(Common::SeekableReadStream *stream);
+	static MohawkArchive *createMohawkArchive(Common::File *stream);
 
-	virtual void open(Common::SeekableReadStream *stream);
+	virtual void open(Common::File *stream);
 	void close();
 
-	bool hasResource(uint32 tag, uint16 id);
 	virtual MohawkOutputStream getRawData(uint32 tag, uint16 id);
 	virtual MohawkOutputStream getNextFile();
 
 	static Common::String tag2string(uint32 tag);
 
 protected:
-	Common::SeekableReadStream *_mhk;
+	Common::File *_mhk;
 	TypeTable _typeTable;
 	Common::String _curFile;
 
@@ -236,7 +237,7 @@ public:
 	LivingBooksArchive_v1() : MohawkArchive() {}
 	~LivingBooksArchive_v1() {}
 
-	virtual void open(Common::SeekableReadStream *stream);
+	virtual void open(Common::File *stream);
 	MohawkOutputStream getRawData(uint32 tag, uint16 id);
 	MohawkOutputStream getNextFile();
 
@@ -273,7 +274,7 @@ class CSWorldDeluxeArchive : public LivingBooksArchive_v1 {
 public:
 	CSWorldDeluxeArchive() : LivingBooksArchive_v1() {}
 	~CSWorldDeluxeArchive() {}
-	void open(Common::SeekableReadStream *stream);
+	void open(Common::File *stream);
 };
 
 #endif
diff --git a/engines/mohawk/construct_mohawk.cpp b/engines/mohawk/construct_mohawk.cpp
index ca49d77..4ab8352 100644
--- a/engines/mohawk/construct_mohawk.cpp
+++ b/engines/mohawk/construct_mohawk.cpp
@@ -26,7 +26,9 @@
 #include "common/file.h"
 #include "common/str.h"
 #include "common/util.h"
-#include "archive.h"
+
+#include "engines/mohawk/archive.h"
+#include "engines/mohawk/utils.h"
 
 uint32 _fileSize;
 
@@ -71,10 +73,19 @@ struct TypeConstruct {
 	} nameTable;
 };
 
+struct ResourceFile {
+	Common::Filename filename;
+
+	uint32 index;
+	int flags;
+	Common::String typeTagStr;
+	uint32 typeTag;
+	uint16 id;
+	Common::String name;
+	uint32 size;
+};
+
 Common::Array<TypeConstruct> _types;
-uint16 _nameTableAmount;
-uint16 _resourceTableAmount;
-uint16 _fileTableAmount;
 Common::Array<FileTable> _fileTable;
 
 int16 getTypeIndex(uint32 tag) {
@@ -115,12 +126,7 @@ uint32 string2tag(const char *str) {
 	return ret;
 }
 
-// Have a maximum buffer size
-#define MAX_BUF_SIZE 16384
-
-static byte *outputBuffer = NULL;
-
-void initMohawkArchive(void) {
+void initMohawkArchive() {
 	// Initialize Mohawk Archive Parameters with parameters for empty archive
 	_fileSize = 28;
 
@@ -134,13 +140,9 @@ void initMohawkArchive(void) {
 
 	_typeTable.name_offset = 4;
 	_typeTable.resource_types = 0;
-
-	_nameTableAmount = 0;
-	_resourceTableAmount = 0;
-	_fileTableAmount = 0;
 }
 
-void updateTypeTableOffsets(void) {
+void updateTypeTableOffsets() {
 	for (uint16 i = 0; i < _typeTable.resource_types; i++) {
 		_types[i].resource_table_offset = 4 + (_typeTable.resource_types * 8);
 
@@ -172,23 +174,23 @@ void addTypeToMohawkArchive(const char *resourceTag) {
 	updateTypeTableOffsets();
 }
 
-void addFileToMohawkArchive(int fileId, byte fileFlags, const char *resourceTag, int resourceId, const char *resourceName, uint32 fileSize) {
-	int16 typeIndex = getTypeIndex(string2tag(resourceTag));
+void addFileToMohawkArchive(const ResourceFile &file) {
+	int16 typeIndex = getTypeIndex(file.typeTag);
 	if (typeIndex == -1) {
 		// Add New Type to typeTable
-		addTypeToMohawkArchive(resourceTag);
-		typeIndex = getTypeIndex(string2tag(resourceTag));
+		addTypeToMohawkArchive(file.typeTagStr.c_str());
+		typeIndex = getTypeIndex(file.typeTag);
 	} else {
-		if (getIdIndex(typeIndex, resourceId) != -1) {
-			printf("Error : Duplicate Resource Type \'%s\' Id %d\n", resourceTag, resourceId);
+		if (getIdIndex(typeIndex, file.id) != -1) {
+			printf("Error : Duplicate Resource Type \'%s\' Id %d\n", file.typeTagStr.c_str(), file.id);
 			return;
 		}
 	}
 
 	// Update Resource Table
 	TypeConstructResourceEntries newTypeResource;
-	newTypeResource.id = resourceId;
-	newTypeResource.index = fileId + 1;
+	newTypeResource.id = file.id;
+	newTypeResource.index = file.index + 1;
 
 	_fileSize += 4;
 	_rsrc.filesize += 4;
@@ -208,8 +210,7 @@ void addFileToMohawkArchive(int fileId, byte fileFlags, const char *resourceTag,
 	updateTypeTableOffsets();
 
 	// Update Name Table if name is present
-	int nameSize = strlen(resourceName);
-	if (nameSize != 0) {
+	if (!file.name.empty()) {
 		TypeConstructNameEntries newTypeName;
 
 		if (_types[typeIndex].nameTable.entries.empty())
@@ -217,12 +218,12 @@ void addFileToMohawkArchive(int fileId, byte fileFlags, const char *resourceTag,
 		else
 			newTypeName.offset = _types[typeIndex].nameTable.entries.back().offset + _types[typeIndex].nameTable.entries.back().name.size() + 1;
 
-		newTypeName.index = fileId + 1;
-		newTypeName.name += resourceName;
+		newTypeName.index = file.index + 1;
+		newTypeName.name = file.name;
 
-		_fileSize += 4 + nameSize + 1;
-		_rsrc.filesize += 4 + nameSize + 1;
-		_rsrc.file_table_offset += 4 + nameSize + 1;
+		_fileSize += 4 + file.name.size() + 1;
+		_rsrc.filesize += 4 + file.name.size() + 1;
+		_rsrc.file_table_offset += 4 + file.name.size() + 1;
 		_typeTable.name_offset += 4;
 
 		_types[typeIndex].nameTable.num++;
@@ -236,25 +237,24 @@ void addFileToMohawkArchive(int fileId, byte fileFlags, const char *resourceTag,
 
 	// Add file data parameters to fileTable
 	uint32 fileItemOffset = 36;
-	for (uint16 i = 0; i < _fileTableAmount; i++)
+	for (uint16 i = 0; i < _fileTable.size(); i++)
 		fileItemOffset += _fileTable[i].dataSize;
 
 	FileTable fileTableItem;
 	fileTableItem.offset = fileItemOffset;
-	fileTableItem.dataSize = fileSize;
-	fileTableItem.flags = fileFlags;
+	fileTableItem.dataSize = file.size;
+	fileTableItem.flags = file.flags;
 	fileTableItem.unk = 0;
 
 	_fileSize += 10;
 	_rsrc.filesize += 10;
 	_rsrc.file_table_size += 10;
 
-	_fileTableAmount++;
 	_fileTable.push_back(fileTableItem);
 
-	_fileSize += fileSize;
-	_rsrc.filesize += fileSize;
-	_rsrc.abs_offset += fileSize;
+	_fileSize += file.size;
+	_rsrc.filesize += file.size;
+	_rsrc.abs_offset += file.size;
 }
 
 void sortTypeTable(Common::Array<TypeConstruct> *tempTypeTable) {
@@ -306,7 +306,11 @@ void sortNameTable(Common::Array<TypeConstructNameEntries> *tempNameTable, uint1
 	assert(tempNameTable->size() == _types[i].nameTable.num);
 }
 
-void writeMohawkArchive(int argc, char **argv, int archiveArg, Common::File *mohawkFile) {
+void rewriteMovieOffsets(Common::File *resourceIn, Common::File *mohawkFile) {
+	adjustQuickTimeAtomOffsets(resourceIn, resourceIn->size(), mohawkFile->pos(), mohawkFile);
+}
+
+void writeMohawkArchive(const Common::Array<ResourceFile> &files, Common::File *mohawkFile) {
 	// Gap between RSRC and File Data..
 	_fileSize += 8;
 	_rsrc.filesize += 8;
@@ -329,19 +333,19 @@ void writeMohawkArchive(int argc, char **argv, int archiveArg, Common::File *moh
 	mohawkFile->writeUint16BE(0);
 	mohawkFile->writeUint16BE(0);
 
-	for (int i = archiveArg + 1; i < argc; i++) {
-		Common::Filename resourceFile = Common::Filename(argv[i]);
-
-		Common::File *resourceIn = new Common::File(resourceFile, "rb");
+	for (uint i = 0; i < files.size(); i++) {
+		const ResourceFile &file = files[i];
+		Common::File *resourceIn = new Common::File(file.filename, "rb");
 		if (!resourceIn->isOpen()) {
-			printf("Could not open file \"%s\"\n", resourceFile.getName().c_str());
+			printf("Could not open file \"%s\"\n", file.filename.getName().c_str());
 			delete resourceIn;
 			return;
 		}
 
-		while (resourceIn->pos() < (int)resourceIn->size()) {
-			uint32 size = resourceIn->read_noThrow(outputBuffer, MAX_BUF_SIZE);
-			mohawkFile->write(outputBuffer, size);
+		if (file.typeTag == ID_TMOV) {
+			rewriteMovieOffsets(resourceIn, mohawkFile);
+		} else {
+			copyBytes(resourceIn, mohawkFile, resourceIn->size());
 		}
 
 		resourceIn->close();
@@ -389,8 +393,8 @@ void writeMohawkArchive(int argc, char **argv, int archiveArg, Common::File *moh
 	}
 
 	// _rsrc.file_table_offset is added to _rsrc.abs_offset to get here...
-	mohawkFile->writeUint32BE(_fileTableAmount);
-	for (uint32 i = 0; i < _fileTableAmount; i++) {
+	mohawkFile->writeUint32BE(_fileTable.size());
+	for (uint32 i = 0; i < _fileTable.size(); i++) {
 		mohawkFile->writeUint32BE(_fileTable[i].offset);
 		mohawkFile->writeUint16BE(_fileTable[i].dataSize & 0xFFFF);
 		mohawkFile->writeByte((_fileTable[i].dataSize >> 16) & 0xFF);
@@ -439,46 +443,44 @@ int main(int argc, char *argv[]) {
 		return 1;
 	}
 
-	initMohawkArchive();
-
-	// Allocate a buffer for the output
-	outputBuffer = (byte *)malloc(MAX_BUF_SIZE);
+	Common::Array<ResourceFile> inputFiles;
 
 	// Loop over remaining parameters, treating them as resource filenames
 	for (int i = archiveArg + 1; i < argc; i++) {
 		printf("Resource %d : \"%s\"\n", i - archiveArg - 1, argv[i]);
 
-		Common::Filename resourceFile = Common::Filename(argv[i]);
+		ResourceFile file;
+		file.filename = Common::Filename(argv[i]);
 
-		if (!resourceFile.exists()) {
+		if (!file.filename.exists()) {
 			printf("Can not open resource file \"%s\"\n", argv[i]);
 			return 1;
 		}
 
-		if (!resourceFile.hasExtension("bin")) {
+		if (!file.filename.hasExtension("bin")) {
 			printf("Resource file \"%s\" not in raw binary format\n", argv[i]);
 			return 1;
 		}
 
 		char resourceFilename[100];
-		strncpy(resourceFilename, resourceFile.getName().c_str(), sizeof(resourceFilename));
+		strncpy(resourceFilename, file.filename.getName().c_str(), sizeof(resourceFilename));
 
 		// Parse for file index, Resource Type, Resource Id and Name
-		int fileIndex = atoi(Common::String(resourceFilename, 4).c_str());
-		printf("fileIndex : %d\n", fileIndex);
+		file.index = atoi(Common::String(resourceFilename, 4).c_str());
+		printf("fileIndex : %d\n", file.index);
 
 		if (resourceFilename[4] != '_')
 			printf("Filename format mismatch\n");
 
-		unsigned int fileFlags;
-		sscanf(resourceFilename+5, "%02x", &fileFlags);
-		printf("fileFlags : 0x%02x\n", fileFlags);
+		sscanf(resourceFilename+5, "%02x", &file.flags);
+		printf("fileFlags : 0x%02x\n", file.flags);
 
 		if (resourceFilename[7] != '_')
 			printf("Filename format mismatch\n");
 
-		Common::String resourceTag = Common::String(resourceFilename+8, 4);
-		printf("resourceTag : \"%s\"\n", resourceTag.c_str());
+		file.typeTagStr = Common::String(resourceFilename+8, 4);
+		file.typeTag = string2tag(file.typeTagStr.c_str());
+		printf("resourceTag : \"%s\"\n", file.typeTagStr.c_str());
 
 		if (resourceFilename[12] != '_')
 			printf("Filename format mismatch\n");
@@ -487,45 +489,47 @@ int main(int argc, char *argv[]) {
 		while (resourceFilename[nameStart] != '\0' && resourceFilename[nameStart] != '_')
 			nameStart++;
 
-		int resourceId = atoi(Common::String(resourceFilename+13, nameStart-12).c_str());
-		printf("resourceId : %d\n", resourceId);
+		file.id = atoi(Common::String(resourceFilename+13, nameStart-12).c_str());
+		printf("resourceId : %d\n", file.id);
 
-		Common::String resourceName;
 		if (resourceFilename[nameStart] == '_') {
-			resourceName = Common::String(resourceFilename+nameStart+1, resourceFilename+strlen(resourceFilename));
+			file.name = Common::String(resourceFilename+nameStart+1, resourceFilename+strlen(resourceFilename));
 
-			for (uint j = 0; j < resourceName.size(); j++) {
+			for (uint j = 0; j < file.name.size(); j++) {
 				//printf("DEBUG: j: %d resourceName[j]: %c\n", j, resourceName[j]);
-				if (resourceName[j] == '\\') {
-					if (j+1 < resourceName.size() && resourceName[j+1] == '\\') {
+				if (file.name[j] == '\\') {
+					if (j+1 < file.name.size() && file.name[j+1] == '\\') {
 						//printf("\tUnpadded \ at %d\n", j);
-						resourceName.deleteChar(j);
+						file.name.deleteChar(j);
 					} else {
 						//printf("\tReplaced \ at %d with %c\n", j, '/');
-						resourceName.setChar('/', j);
+						file.name.setChar('/', j);
 					}
 				}
 			}
 		}
-		printf("resourceName : \"%s\"\n", resourceName.c_str());
+		printf("resourceName : \"%s\"\n", file.name.c_str());
 
-		Common::File *resourceIn = new Common::File(resourceFile, "rb");
-		if (!resourceIn->isOpen()) {
-			printf("Could not open file \"%s\"\n", resourceFile.getName().c_str());
-			delete resourceIn;
+		Common::File resourceIn(file.filename, "rb");
+		if (!resourceIn.isOpen()) {
+			printf("Could not open file \"%s\"\n", file.filename.getName().c_str());
 			return 1;
 		}
+		file.size = resourceIn.size();
+		resourceIn.close();
 
-		addFileToMohawkArchive(fileIndex, (byte) fileFlags, resourceTag.c_str(), resourceId, resourceName.c_str(), resourceIn->size());
+		inputFiles.push_back(file);
+	}
 
-		resourceIn->close();
-		delete resourceIn;
+	initMohawkArchive();
+
+	for (uint i = 0; i < inputFiles.size(); i++) {
+		addFileToMohawkArchive(inputFiles[i]);
 	}
 
-	writeMohawkArchive(argc, argv, archiveArg, mohawkFile);
+	writeMohawkArchive(inputFiles, mohawkFile);
 
 	printf("Done!\n");
-	free(outputBuffer);
 	mohawkFile->close();
 	delete mohawkFile;
 	return 0;
diff --git a/engines/mohawk/deriven.cpp b/engines/mohawk/deriven.cpp
deleted file mode 100644
index 6f1ccf5..0000000
--- a/engines/mohawk/deriven.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/* ScummVM Tools
- *
- * ScummVM Tools 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.
- */
-
-/* Riven script decompiler */
-
-#include "engines/mohawk/archive.h"
-#include "common/util.h"
-#include "engines/mohawk/utils/file.h"
-
-#include <assert.h>
-
-#define NO_OP "empty"
-
-static const char *opcode_names[] = {
-	// 0x00 (0 decimal)
-	NO_OP,
-	"drawBitmap",
-	"switchCard",
-	"playScriptSLST",
-	// 0x04 (4 decimal)
-	"playSound",
-	NO_OP,
-	NO_OP,
-	"setVariable",
-	// 0x08 (8 decimal)
-	"mohawkSwitch",
-	"enableHotspot",
-	"disableHotspot",
-	NO_OP,
-	// 0x0C (12 decimal)
-	"stopSound",
-	"changeCursor",
-	"delay",
-	NO_OP,
-	// 0x10 (16 decimal)
-	NO_OP,
-	"runExternalCommand",
-	"transition",
-	"refreshCard",
-	// 0x14 (20 decimal)
-	"disableScreenUpdate",
-	"enableScreenUpdate",
-	NO_OP,
-	NO_OP,
-	// 0x18 (24 decimal)
-	"incrementVariable",
-	NO_OP,
-	NO_OP,
-	"changeStack",
-	// 0x1C (28 decimal)
-	"disableMovie",
-	"disableAllMovies",
-	NO_OP,
-	"enableMovie",
-	// 0x20 (32 decimal)
-	"playMovieBlocking",
-	"playMovie",
-	"stopMovie",
-	NO_OP,
-	// 0x24 (36 decimal)
-	"unk_36",						// Unknown
-	"fadeAmbientSounds",
-	"storeMovieOpcode",
-	"activatePLST",
-	// 0x28 (40 decimal)
-	"activateSLST",
-	"activateMLSTAndPlay",
-	NO_OP,
-	"activateBLST",
-	// 0x2C (44 decimal)
-	"activateFLST",
-	"zipMode",
-	"activateMLST"
-};
-
-void printUsage(const char *appName) {
-	printf("Usage: %s <mohawk archive> [CARD or HSPT] [id]\n", appName);
-}
-
-Common::StringList getNameList(MohawkArchive *mohawkArchive, uint16 id) {
-	MohawkOutputStream nameResource = mohawkArchive->getRawData(ID_NAME, id);
-	Common::StringList nameList;
-
-	uint16 namesCount = nameResource.stream->readUint16BE();
-	uint16 *stringOffsets = new uint16[namesCount];
-	for (uint16 i = 0; i < namesCount; i++)
-		stringOffsets[i] = nameResource.stream->readUint16BE();
-	nameResource.stream->seek(namesCount * 2, SEEK_CUR);
-	int32 curNamesPos = nameResource.stream->pos();
-
-	for (uint32 i = 0; i < namesCount; i++) {
-		nameResource.stream->seek(curNamesPos + stringOffsets[i]);
-
-		Common::String name;
-		name.clear();
-		for (char c = nameResource.stream->readByte(); c; c = nameResource.stream->readByte())
-			name += c;
-		nameList.push_back(name);
-	}
-
-	delete nameResource.stream;
-	delete[] stringOffsets;
-
-	return nameList;
-}
-
-static void printTabs(byte tabs) {
-	for (byte i = 0; i < tabs; i++)
-		printf ("\t");
-}
-
-void dumpCommands(Common::SeekableReadStream *script, Common::StringList varNames, Common::StringList exNames, byte tabs) {
-	uint16 commandCount = script->readUint16BE();
-
-	for (uint16 i = 0; i < commandCount; i++) {
-		uint16 command = script->readUint16BE();
-
-		if (command == 8) { // "Switch" Statement
-			if (script->readUint16BE() != 2)
-				warning ("if-then-else unknown value is not 2");
-			uint16 var = script->readUint16BE();
-			printTabs(tabs); printf("switch (%s) {\n", varNames[var].c_str());
-			uint16 logicBlockCount = script->readUint16BE();
-			for (uint16 j = 0; j < logicBlockCount; j++) {
-				uint16 varCheck = script->readUint16BE();
-				printTabs(tabs + 1);
-				if (varCheck == 0xFFFF)
-					printf("default:\n");
-				else
-					printf("case %d:\n", varCheck);
-				dumpCommands(script, varNames, exNames, tabs + 2);
-				printTabs(tabs + 2); printf("break;\n");
-			}
-			printTabs(tabs); printf("}\n");
-		} else if (command == 7) { // Use the variable name
-			script->readUint16BE(); // Skip the opcode var count
-			printTabs(tabs);
-			uint16 varIndex = script->readUint16BE();
-			printf("%s = %d;\n", varNames[varIndex].c_str(), script->readUint16BE());
-		} else if (command == 17) { // Use the external command name
-			script->readUint16BE(); // Skip the opcode var count
-			printTabs(tabs);
-			printf("%s(", exNames[script->readUint16BE()].c_str());
-			uint16 varCount = script->readUint16BE();
-			for (uint16 j = 0; j < varCount; j++) {
-				printf("%d", script->readUint16BE());
-				if (j != varCount - 1)
-					printf(", ");
-			}
-			printf (");\n");
-		} else if (command == 24) { // Use the variable name
-			script->readUint16BE(); // Skip the opcode var count
-			printTabs(tabs);
-			uint16 varIndex = script->readUint16BE();
-			printf ("%s += %d;\n", varNames[varIndex].c_str(), script->readUint16BE());
-		} else {
-			printTabs(tabs);
-			uint16 varCount = script->readUint16BE();
-			printf("%s(", opcode_names[command]);
-			for (uint16 j = 0; j < varCount; j++) {
-				printf("%d", script->readUint16BE());
-				if (j != varCount - 1)
-					printf(", ");
-			}
-			printf(");\n");
-		}
-	}
-}
-
-void dumpScript(Common::SeekableReadStream *script, Common::StringList varNames, Common::StringList exNames, byte tabs) {
-	uint16 scriptCount = script->readUint16BE();
-
-	for (uint16 i = 0; i < scriptCount; i++) {
-		printTabs(tabs); printf ("Stream Type %d:\n", script->readUint16BE());
-		dumpCommands(script, varNames, exNames, tabs + 1);
-	}
-}
-
-int main(int argc, char *argv[]) {
-	if (argc != 4) {
-		printUsage(argv[0]);
-		return 1;
-	}
-
-	FILE *file = fopen(argv[1], "rb");
-	if (!file) {
-		printf ("Could not open \'%s\'\n", argv[1]);
-		return 1;
-	}
-
-	// Open the file as a Mohawk archive
-	MohawkArchive *mohawkArchive = new MohawkArchive();
-	mohawkArchive->open(new Common::File(file));
-
-	// Load in Variable/External Command Names'
-	Common::StringList exNames = getNameList(mohawkArchive, 3);
-	Common::StringList varNames = getNameList(mohawkArchive, 4);
-
-	uint32 tag = READ_BE_UINT32(argv[2]);
-	uint32 cardId = (uint16)atoi(argv[3]);
-
-	if (tag == ID_CARD) {
-		printf("\n\nDumping scripts for card %d!\n", cardId);
-		printf("==================================\n\n");
-
-		MohawkOutputStream cardStream = mohawkArchive->getRawData(ID_CARD, cardId);
-		cardStream.stream->readUint32BE(); // Skip first 4 bytes
-
-		dumpScript(cardStream.stream, varNames, exNames, 0);
-
-		delete cardStream.stream;
-	} else if (tag == ID_HSPT) {
-		printf("\n\nDumping scripts for card %d hotspots!\n", cardId);
-		printf("===========================================\n\n");
-
-		MohawkOutputStream hsptStream = mohawkArchive->getRawData(ID_HSPT, cardId);
-		uint16 hotspotCount = hsptStream.stream->readUint16BE();
-
-		for (uint16 i = 0; i < hotspotCount; i++) {
-			printf("Hotspot %d:\n", i);
-			hsptStream.stream->seek(22, SEEK_CUR); // Skip non-script related stuff
-			dumpScript(hsptStream.stream, varNames, exNames, 1);
-		}
-
-		delete hsptStream.stream;
-	} else {
-		printf("That resource (if it exists) doesn't contain script data!\n");
-	}
-
-	exNames.clear();
-	varNames.clear();
-
-	return 0;
-}
diff --git a/engines/mohawk/extract_mohawk.cpp b/engines/mohawk/extract_mohawk.cpp
index 2e264a0..528451b 100644
--- a/engines/mohawk/extract_mohawk.cpp
+++ b/engines/mohawk/extract_mohawk.cpp
@@ -21,52 +21,32 @@
 
 /* Mohawk file extractor */
 
-#include "engines/mohawk/archive.h"
+#include "common/file.h"
 #include "common/util.h"
-#include "engines/mohawk/utils/file.h"
-
-#include <assert.h>
-
-// Have a maximum buffer size
-#define MAX_BUF_SIZE 16384
 
-static byte *outputBuffer = NULL;
+#include "engines/mohawk/archive.h"
+#include "engines/mohawk/utils.h"
 
-bool fileExists(const char *filename) {
-	FILE *outputFile = fopen(filename, "rb");
-	if (outputFile != NULL) {
-		fclose(outputFile);
-		return true;
-	}
-	return false;
-}
+#include <assert.h>
 
 void dumpRawResource(MohawkOutputStream output) {
 	// Change the extension to bin
-	output.name += ".bin";
-
-	const char* outputCStr = output.name.c_str();
+	Common::Filename filename(output.name + ".bin");
 
-	printf ("Extracting \'%s\'...\n", outputCStr);
+	printf("Extracting \'%s\'...\n", filename.getName().c_str());
 
-	if(fileExists(outputCStr)) {
-		printf ("File \'%s\' already exists!\n", outputCStr);
+	if (filename.exists()) {
+		printf ("File \'%s\' already exists!\n", filename.getName().c_str());
 		return;
 	}
-	FILE *outputFile = fopen(outputCStr, "wb");
-	if (!outputFile) {
+
+	Common::File outputFile(filename, "wb");
+	if (!outputFile.isOpen()) {
 		printf ("Could not open file for output!\n");
 		return;
 	}
 
-	assert(outputBuffer);
-
-	while (output.stream->pos() < output.stream->size()) {
-		uint32 size = output.stream->read(outputBuffer, MAX_BUF_SIZE);
-		fwrite(outputBuffer, 1, size, outputFile);
-	}
-
-	fclose(outputFile);
+	copyBytes(output.stream, &outputFile, output.size);
 }
 
 void convertSoundResource(MohawkOutputStream output) {
@@ -75,25 +55,38 @@ void convertSoundResource(MohawkOutputStream output) {
 }
 
 void convertMovieResource(MohawkOutputStream output) {
-	printf ("Converting movies not yet supported. Dumping instead...\n");
-	dumpRawResource(output);
+	Common::Filename filename(output.name + ".bin");
+
+	printf("Extracting '%s'...\n", filename.getName().c_str());
+
+	if (filename.exists()) {
+		printf ("File '%s' already exists!\n", filename.getName().c_str());
+		return;
+	}
+
+	Common::File outputFile(filename, "wb");
+	if (!outputFile.isOpen()) {
+		printf ("Could not open file '%s' for output!\n", filename.getName().c_str());
+		return;
+	}
+
+	adjustQuickTimeAtomOffsets(output.stream, output.size, -output.offset, &outputFile);
 }
 
 void convertMIDIResource(MohawkOutputStream output) {
 	// Change the extension to midi
-	output.name += ".mid";
-
-	const char* outputCStr = output.name.c_str();
+	Common::Filename filename(output.name + ".mid");
 
-	printf ("Extracting \'%s\'...\n", outputCStr);
+	printf("Extracting '%s'...\n", filename.getName().c_str());
 
-	if(fileExists(outputCStr)) {
-		printf ("File \'%s\' already exists!\n", outputCStr);
+	if (filename.exists()) {
+		printf ("File '%s' already exists!\n", filename.getName().c_str());
 		return;
 	}
-	FILE *outputFile = fopen(outputCStr, "wb");
-	if (!outputFile) {
-		printf ("Could not open file for output!\n");
+
+	Common::File outputFile(filename, "wb");
+	if (!outputFile.isOpen()) {
+		printf ("Could not open file '%s' for output!\n", filename.getName().c_str());
 		return;
 	}
 
@@ -107,21 +100,19 @@ void convertMIDIResource(MohawkOutputStream output) {
 	byte *midiData = (byte *)malloc(size);
 
 	// Read the MThd Data
-	output.stream->read(midiData, 14);
+	output.stream->read_noThrow(midiData, 14);
 
 	// Skip the unknown Prg# section
 	assert(output.stream->readUint32BE() == ID_PRG);
-	output.stream->skip(output.stream->readUint32BE());
+	output.stream->seek(output.stream->readUint32BE(), SEEK_CUR);
 
 	// Read the MTrk Data
 	uint32 mtrkSize = output.stream->size() - output.stream->pos();
-	output.stream->read(midiData + 14, mtrkSize);
+	output.stream->read_noThrow(midiData + 14, mtrkSize);
 
 	// Output the data to the file.
-	fwrite(midiData, 1, 14 + mtrkSize, outputFile);
+	outputFile.write(midiData, 14 + mtrkSize);
 	free(midiData);
-
-	fclose(outputFile);
 }
 
 void outputMohawkStream(MohawkOutputStream output, bool doConversion, bool fileTableIndex, bool fileTableFlags) {
@@ -228,24 +219,20 @@ int main(int argc, char *argv[]) {
 		return 1;
 	}
 
-	FILE *file = fopen(argv[archiveArg], "rb");
-	if (!file) {
+	Common::File file(argv[archiveArg], "rb");
+	if (!file.isOpen()) {
 		printf ("Could not open \'%s\'\n", argv[archiveArg]);
 		return 1;
 	}
 
 	// Open the file as a Mohawk archive
-	MohawkArchive *mohawkArchive = MohawkArchive::createMohawkArchive(new Common::File(file));
+	MohawkArchive *mohawkArchive = MohawkArchive::createMohawkArchive(&file);
 
 	if (!mohawkArchive) {
 		printf("\'%s\' is not a valid Mohawk archive\n", argv[archiveArg]);
-		fclose(file);
 		return 1;
 	}
 
-	// Allocate a buffer for the output
-	outputBuffer = (byte *)malloc(MAX_BUF_SIZE);
-
 	if (argc == archiveArg - 2 - 1) {
 		uint32 tag = READ_BE_UINT32(argv[archiveArg + 1]);
 		uint16 id = (uint16)atoi(argv[archiveArg + 2]);
@@ -254,7 +241,6 @@ int main(int argc, char *argv[]) {
 
 		if (output.stream) {
 			outputMohawkStream(output, doConversion, fileTableIndex, fileTableFlags);
-			delete output.stream;
 		} else {
 			printf ("Could not find specified data!\n");
 		}
@@ -262,15 +248,12 @@ int main(int argc, char *argv[]) {
 		MohawkOutputStream output = mohawkArchive->getNextFile();
 		while (output.stream) {
 			outputMohawkStream(output, doConversion, fileTableIndex, fileTableFlags);
-			delete output.stream;
 			output = mohawkArchive->getNextFile();
 		}
 	}
 
 	printf("Done!\n");
-	free(outputBuffer);
 	mohawkArchive->close();
-	fclose(file);
 	delete mohawkArchive;
 	return 0;
 }
diff --git a/engines/mohawk/utils.cpp b/engines/mohawk/utils.cpp
new file mode 100644
index 0000000..8e8680e
--- /dev/null
+++ b/engines/mohawk/utils.cpp
@@ -0,0 +1,95 @@
+/* ScummVM Tools
+ *
+ * ScummVM Tools 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 "engines/mohawk/utils.h"
+
+#include "common/endian.h"
+#include "common/util.h"
+
+#define ATOM_STCO MKID_BE('stco')
+#define ATOM_MOOV MKID_BE('moov')
+#define ATOM_TRAK MKID_BE('trak')
+#define ATOM_MDIA MKID_BE('mdia')
+#define ATOM_MINF MKID_BE('minf')
+#define ATOM_STBL MKID_BE('stbl')
+
+#define BUF_SIZE 8192
+
+void copyBytes(Common::File *src, Common::File *outputFile, uint32 bytesToCopy) {
+	byte tempBuffer[BUF_SIZE];
+
+	if (src->pos() + bytesToCopy > src->size()) {
+		error("Unexpected end of stream (pos: %d + bytesToCopy: %d > totalSize: %d",
+		      src->pos(), bytesToCopy, src->size());
+	}
+
+	while (bytesToCopy > 0) {
+		size_t bytesCopied = src->read_noThrow(tempBuffer, MIN<uint32>(bytesToCopy, BUF_SIZE));
+		outputFile->write(tempBuffer, bytesCopied);
+		bytesToCopy -= bytesCopied;
+	}
+}
+
+void adjustQuickTimeAtomOffsets(Common::File *src, uint32 parentSize, int32 offset, Common::File *outputFile) {
+	static const int kAtomHeaderSize = sizeof(uint32) + sizeof(uint32); // size, type
+	uint32 totalSize = 0;
+
+	while (totalSize + kAtomHeaderSize < parentSize) {
+		uint32 atomSize = src->readUint32BE();
+		uint32 atomType = src->readUint32BE();
+		outputFile->writeUint32BE(atomSize);
+		outputFile->writeUint32BE(atomType);
+
+		if (atomSize == 1) {
+			error("64 bit extended size is not supported in QuickTime");
+		}
+
+		if (atomSize < kAtomHeaderSize) {
+			error("Invalid atom size %d", atomSize);
+		}
+
+		if (atomType == ATOM_MOOV || atomType == ATOM_TRAK
+		    || atomType == ATOM_MDIA || atomType == ATOM_MINF
+		    || atomType == ATOM_STBL) {
+			// Recurse into container atom types
+			adjustQuickTimeAtomOffsets(src, atomSize - kAtomHeaderSize, offset, outputFile);
+
+		} else if (atomType == ATOM_STCO) {
+			copyBytes(src, outputFile, 4); // Copy flags
+
+			uint32 chunkCount = src->readUint32BE();
+			outputFile->writeUint32BE(chunkCount);
+
+			for (uint32 i = 0; i < chunkCount; i++) {
+				uint32 chunkOffset = src->readUint32BE() + offset;
+				outputFile->writeUint32BE(chunkOffset);
+			}
+
+		} else {
+			copyBytes(src, outputFile, atomSize - kAtomHeaderSize);
+		}
+
+		totalSize += atomSize;
+	}
+
+	if (totalSize != parentSize)
+		error("Unexpected position in atom %d (expected %d)", totalSize, parentSize);
+}
\ No newline at end of file
diff --git a/engines/mohawk/utils.h b/engines/mohawk/utils.h
new file mode 100644
index 0000000..e2c2234
--- /dev/null
+++ b/engines/mohawk/utils.h
@@ -0,0 +1,30 @@
+/* ScummVM Tools
+ *
+ * ScummVM Tools 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 MOHAWK_UTILS_H
+#define MOHAWK_UTILS_H
+
+#include "common/file.h"
+
+void copyBytes(Common::File *src, Common::File *outputFile, uint32 bytesToCopy);
+void adjustQuickTimeAtomOffsets(Common::File *src, uint32 parentSize, int32 offset, Common::File *outputFile);
+
+#endif // MOHAWK_UTILS_H
diff --git a/engines/mohawk/utils/file.cpp b/engines/mohawk/utils/file.cpp
deleted file mode 100644
index 5e8f526..0000000
--- a/engines/mohawk/utils/file.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Scumm Tools
- *
- * ScummVM Tools 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 "common/util.h"
-#include "engines/mohawk/utils/file.h"
-
-
-namespace Common {
-
-
-File::File(FILE*file)
-	: _handle(file), _ioFailed(false) {
-}
-
-
-File::~File() {
-	close();
-}
-
-void File::close() {
-	_handle = NULL;
-}
-
-bool File::isOpen() const {
-	return _handle != NULL;
-}
-
-bool File::ioFailed() const {
-	return _ioFailed != 0;
-}
-
-void File::clearIOFailed() {
-	_ioFailed = false;
-}
-
-bool File::eof() const {
-	if (_handle == NULL) {
-		error("File::eof: File is not open!");
-		return false;
-	}
-
-	return feof(_handle) != 0;
-}
-
-uint32 File::pos() const {
-	if (_handle == NULL) {
-		error("File::pos: File is not open!");
-		return 0;
-	}
-
-	return ftell(_handle);
-}
-
-uint32 File::size() const {
-	if (_handle == NULL) {
-		error("File::size: File is not open!");
-		return 0;
-	}
-
-	uint32 oldPos = ftell(_handle);
-	fseek(_handle, 0, SEEK_END);
-	uint32 length = ftell(_handle);
-	fseek(_handle, oldPos, SEEK_SET);
-
-	return length;
-}
-
-void File::seek(int32 offs, int whence) {
-	if (_handle == NULL) {
-		error("File::seek: File is not open!");
-		return;
-	}
-
-	if (fseek(_handle, offs, whence) != 0)
-		clearerr(_handle);
-}
-
-uint32 File::read(void *ptr, uint32 len) {
-	byte *ptr2 = (byte *)ptr;
-	size_t real_len;
-
-	if (_handle == NULL) {
-		error("File::read: File is not open!");
-		return 0;
-	}
-
-	if (len == 0)
-		return 0;
-
-	real_len = fread(ptr2, 1, len, _handle);
-	if (real_len < len) {
-		_ioFailed = true;
-	}
-
-	return (uint32)real_len;
-}
-
-}	// End of namespace Common
diff --git a/engines/mohawk/utils/file.h b/engines/mohawk/utils/file.h
deleted file mode 100644
index 812d375..0000000
--- a/engines/mohawk/utils/file.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Scumm Tools
- *
- * ScummVM Tools 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 COMMON_FILE_H
-#define COMMON_FILE_H
-
-#include "stream.h"
-
-namespace Common {
-
-class File : public SeekableReadStream {
-protected:
-	/** POSIX file handle to the actual file; 0 if no file is open. */
-	FILE *_handle;
-
-	/** Status flag which tells about recent I/O failures. */
-	bool _ioFailed;
-
-private:
-	// Disallow copying File objects. There is not strict reason for this,
-	// except that so far we never had real need for such a feature, and
-	// code that accidentally copied File objects tended to break in strange
-	// ways.
-	File(const File &f);
-	File &operator  =(const File &f);
-
-public:
-
-	File(FILE*file);
-	virtual ~File();
-
-	virtual void close();
-	bool isOpen() const;
-	bool ioFailed() const;
-	void clearIOFailed();
-	bool eos() const { return eof(); }
-	bool eof() const;
-	uint32 pos() const;
-	uint32 size() const;
-	void seek(int32 offs, int whence = SEEK_SET);
-	uint32 read(void *dataPtr, uint32 dataSize);
-};
-
-} // End of namespace Common
-
-#endif
diff --git a/engines/mohawk/utils/stream.h b/engines/mohawk/utils/stream.h
deleted file mode 100644
index 22639f9..0000000
--- a/engines/mohawk/utils/stream.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Scumm Tools
- *
- * ScummVM Tools 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 COMMON_STREAM_H
-#define COMMON_STREAM_H
-
-#include "common/scummsys.h"
-
-namespace Common {
-
-/**
- * Virtual base class for both ReadStream and WriteStream.
- */
-class Stream {
-public:
-	virtual ~Stream() {}
-
-	/**
-	 * Returns true if any I/O failure occurred.
-	 * This flag is never cleared automatically. In order to clear it,
-	 * client code has to call clearIOFailed() explicitly.
-	 *
-	 * @todo Instead of returning a plain bool, maybe we should define
-	 *       a list of error codes which can be returned here.
-	 */
-	virtual bool ioFailed() const { return false; }
-
-	/**
-	 * Reset the I/O error status.
-	 */
-	virtual void clearIOFailed() {}
-};
-
-
-/**
- * Generic interface for a readable data stream.
- */
-class ReadStream : virtual public Stream {
-public:
-	/**
-	 * Returns true if the end of the stream has been reached.
-	 */
-	virtual bool eos() const = 0;
-
-	/**
-	 * Read data from the stream. Subclasses must implement this
-	 * method; all other read methods are implemented using it.
-	 *
-	 * @param dataPtr	pointer to a buffer into which the data is read
-	 * @param dataSize	number of bytes to be read
-	 * @return the number of bytes which were actually read.
-	 */
-	virtual uint32 read(void *dataPtr, uint32 dataSize) = 0;
-
-
-	// The remaining methods all have default implementations; subclasses
-	// need not (and should not) overload them.
-
-	byte readByte() {
-		byte b = 0;
-		read(&b, 1);
-		return b;
-	}
-
-	int8 readSByte() {
-		int8 b = 0;
-		read(&b, 1);
-		return b;
-	}
-
-	uint16 readUint16LE() {
-		uint16 a = readByte();
-		uint16 b = readByte();
-		return a | (b << 8);
-	}
-
-	uint32 readUint32LE() {
-		uint32 a = readUint16LE();
-		uint32 b = readUint16LE();
-		return (b << 16) | a;
-	}
-
-	uint16 readUint16BE() {
-		uint16 b = readByte();
-		uint16 a = readByte();
-		return a | (b << 8);
-	}
-
-	uint32 readUint32BE() {
-		uint32 b = readUint16BE();
-		uint32 a = readUint16BE();
-		return (b << 16) | a;
-	}
-
-	int16 readSint16LE() {
-		return (int16)readUint16LE();
-	}
-
-	int32 readSint32LE() {
-		return (int32)readUint32LE();
-	}
-
-	int16 readSint16BE() {
-		return (int16)readUint16BE();
-	}
-
-	int32 readSint32BE() {
-		return (int32)readUint32BE();
-	}
-};
-
-
-/**
- * Interface for a seekable & readable data stream.
- *
- * @todo We really need better error handling here!
- *       Like seek should somehow indicate whether it failed.
- */
-class SeekableReadStream : virtual public ReadStream {
-public:
-
-	virtual uint32 pos() const = 0;
-	virtual uint32 size() const = 0;
-
-	virtual void seek(int32 offset, int whence = SEEK_SET) = 0;
-
-	void skip(uint32 offset) { seek(offset, SEEK_CUR); }
-};
-
-/**
- * SubReadStream provides access to a ReadStream restricted to the range
- * [currentPosition, currentPosition+end).
- * Manipulating the parent stream directly /will/ mess up a substream.
- * Likewise, manipulating two substreams of a parent stream will cause them to
- * step on each others toes.
- */
-class SubReadStream : virtual public ReadStream {
-protected:
-	ReadStream *_parentStream;
-	bool _disposeParentStream;
-	uint32 _pos;
-	uint32 _end;
-	bool _eos;
-public:
-	SubReadStream(ReadStream *parentStream, uint32 end, bool disposeParentStream = false)
-		: _parentStream(parentStream),
-		  _disposeParentStream(disposeParentStream),
-		  _pos(0),
-		  _end(end),
-		  _eos(false) {
-		assert(parentStream);
-	}
-
-	~SubReadStream() {
-		if (_disposeParentStream) delete _parentStream;
-	}
-
-	virtual bool eos() const { return _eos; }
-
-	virtual uint32 read(void *dataPtr, uint32 dataSize) {
-		if (dataSize > _end - _pos) {
-			dataSize = _end - _pos;
-			_eos = true;
-		}
-
-		dataSize = _parentStream->read(dataPtr, dataSize);
-		_eos |= _parentStream->eos();
-		_pos += dataSize;
-
-		return dataSize;
-	}
-};
-
-/*
- * SeekableSubReadStream provides access to a SeekableReadStream restricted to
- * the range [begin, end).
- * The same caveats apply to SeekableSubReadStream as do to SeekableReadStream.
- */
-class SeekableSubReadStream : public SubReadStream, public SeekableReadStream {
-protected:
-	SeekableReadStream *_parentStream;
-	uint32 _begin;
-public:
-	SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool disposeParentStream = false)
-		: SubReadStream(parentStream, end, disposeParentStream),
-		_parentStream(parentStream),
-		_begin(begin) {
-		assert(_begin <= _end);
-		_pos = _begin;
-		_parentStream->seek(_pos);
-		_eos = false;
-	}
-
-	virtual uint32 pos() const { return _pos - _begin; }
-	virtual uint32 size() const { return _end - _begin; }
-	virtual bool eos() const { return _parentStream->eos(); }
-
-	virtual void seek(int32 offset, int whence = SEEK_SET) {
-		assert(_pos >= _begin);
-		assert(_pos <= _end);
-
-		switch(whence) {
-		case SEEK_END:
-			offset = size() + offset;
-			// fallthrough
-		case SEEK_SET:
-			_pos = _begin + offset;
-			break;
-		case SEEK_CUR:
-			_pos += offset;
-		}
-
-		assert(_pos >= _begin);
-		assert(_pos <= _end);
-
-		_parentStream->seek(_pos);
-	}
-
-	virtual uint32 read(void *dataPtr, uint32 dataSize) {
-		return SubReadStream::read(dataPtr, dataSize);
-	}
-};
-
-
-}	// End of namespace Common
-
-#endif





More information about the Scummvm-git-logs mailing list