[Scummvm-cvs-logs] SF.net SVN: scummvm: [31661] scummvm/trunk/engines/made

john_doe at users.sourceforge.net john_doe at users.sourceforge.net
Wed Apr 23 10:08:37 CEST 2008


Revision: 31661
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31661&view=rev
Author:   john_doe
Date:     2008-04-23 01:08:37 -0700 (Wed, 23 Apr 2008)

Log Message:
-----------
Implemented direct loading of rtzcd.dat from the archive rtzcd.red, i.e. the game doesn't have to be installed first to get rtzcd.dat. Also added the respective detection entry.

Modified Paths:
--------------
    scummvm/trunk/engines/made/database.cpp
    scummvm/trunk/engines/made/database.h
    scummvm/trunk/engines/made/detection.cpp
    scummvm/trunk/engines/made/module.mk

Added Paths:
-----------
    scummvm/trunk/engines/made/redreader.cpp
    scummvm/trunk/engines/made/redreader.h

Modified: scummvm/trunk/engines/made/database.cpp
===================================================================
--- scummvm/trunk/engines/made/database.cpp	2008-04-22 22:36:09 UTC (rev 31660)
+++ scummvm/trunk/engines/made/database.cpp	2008-04-23 08:08:37 UTC (rev 31661)
@@ -117,6 +117,16 @@
 		return NULL;
 }
 
+void Object::setString(const char *str) {
+	if (getClass() == 0x7FFF) {
+		char *objStr = (char*)getData();
+		if (str)
+			strncpy(objStr, str, getSize());
+		else
+			objStr[0] = '\0';
+	}
+}
+
 bool Object::isObject() {
 	return getClass() < 0x7FFE;
 }
@@ -181,31 +191,48 @@
 }
 
 void GameDatabase::open(const char *filename) {
-	_fd.open(filename);
+	debug(1, "GameDatabase::open() Loading from %s", filename);
+	Common::File fd;
+	if (!fd.open(filename))
+		error("GameDatabase::open() Could not open %s", filename);
+	load(fd);
+	fd.close();
+}
+
+void GameDatabase::openFromRed(const char *redFilename, const char *filename) {
+	debug(1, "GameDatabase::openFromRed() Loading from %s->%s", redFilename, filename);
+	Common::MemoryReadStream *fileS = RedReader::loadFromRed(redFilename, filename);
+	if (!fileS)
+		error("GameDatabase::openFromRed() Could not load %s from %s", filename, redFilename);
+	load(*fileS);
+	delete fileS;
+}
+
+void GameDatabase::load(Common::SeekableReadStream &sourceS) {
 	
 	// TODO: Read/verifiy header
 	
-	_fd.seek(0x1E);
+	sourceS.seek(0x1E);
 	
-	uint32 objectIndexOffs = _fd.readUint32LE();
-	uint16 objectCount = _fd.readUint16LE();
-	uint32 gameStateOffs = _fd.readUint32LE();
-	_gameStateSize = _fd.readUint32LE();
-	uint32 objectsOffs = _fd.readUint32LE();
-	uint32 objectsSize = _fd.readUint32LE();
-	_mainCodeObjectIndex = _fd.readUint16LE();
+	uint32 objectIndexOffs = sourceS.readUint32LE();
+	uint16 objectCount = sourceS.readUint16LE();
+	uint32 gameStateOffs = sourceS.readUint32LE();
+	_gameStateSize = sourceS.readUint32LE();
+	uint32 objectsOffs = sourceS.readUint32LE();
+	uint32 objectsSize = sourceS.readUint32LE();
+	_mainCodeObjectIndex = sourceS.readUint16LE();
 	
 	debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n",
 		objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
 
 	_gameState = new byte[_gameStateSize];
-	_fd.seek(gameStateOffs);
-	_fd.read(_gameState, _gameStateSize);
+	sourceS.seek(gameStateOffs);
+	sourceS.read(_gameState, _gameStateSize);
 
 	Common::Array<uint32> objectOffsets;
-	_fd.seek(objectIndexOffs);
+	sourceS.seek(objectIndexOffs);
 	for (uint32 i = 0; i < objectCount; i++)
-		objectOffsets.push_back(_fd.readUint32LE());
+		objectOffsets.push_back(sourceS.readUint32LE());
 
 	for (uint32 i = 0; i < objectCount; i++) {
 		Object *obj = new Object();
@@ -218,8 +245,8 @@
 		
 		if (objectOffsets[i] & 1) {
 			debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
-			_fd.seek(objectsOffs + objectOffsets[i] - 1);
-			obj->load(_fd);
+			sourceS.seek(objectsOffs + objectOffsets[i] - 1);
+			obj->load(sourceS);
 		} else {
 			debug(2, "-> var\n");
 			obj->load(_gameState + objectOffsets[i]);
@@ -253,11 +280,11 @@
 	while (count2-- > 0) {
 		if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
 			if (READ_LE_UINT16(prop) & 0x4000) {
-				debug(2, "! L1.1\n");
+				//debug(2, "! L1.1\n");
 				propertyFlag = 1;
 				return (int16*)_gameState + READ_LE_UINT16(propPtr1);
 			} else {
-				debug(2, "! L1.2\n");
+				//debug(2, "! L1.2\n");
 				propertyFlag = obj->getFlags() & 1;
 				return propPtr1;
 			}
@@ -269,13 +296,13 @@
 	// Now check in the object hierarchy of the given object
 	int16 parentObjectIndex = obj->getClass();
 	if (parentObjectIndex == 0) {
-		debug(2, "! NULL(np)\n");
+		//debug(2, "! NULL(np)\n");
 		return NULL;
 	}
 		
 	while (parentObjectIndex != 0) {
 	
-		debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
+		//debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
 
 		obj = getObject(parentObjectIndex);
 		
@@ -290,11 +317,11 @@
 			if (!(READ_LE_UINT16(prop) & 0x8000)) {
 				if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
 					if (*prop & 0x4000) {
-						debug(2, "! L2.1\n");
+						//debug(2, "! L2.1\n");
 						propertyFlag = 1;
 						return (int16*)_gameState + READ_LE_UINT16(propPtr1);
 					} else {
-						debug(2, "! L2.2\n");
+						//debug(2, "! L2.2\n");
 						propertyFlag = obj->getFlags() & 1;
 						return propPtr1;
 					}
@@ -304,11 +331,11 @@
 			} else {
 				if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
 					if (*prop & 0x4000) {
-						debug(2, "! L3.1\n");
+						//debug(2, "! L3.1\n");
 						propertyFlag = 1;
 						return (int16*)_gameState + READ_LE_UINT16(propertyPtr);
 					} else {
-						debug(2, "! L3.2\n");
+						//debug(2, "! L3.2\n");
 						propertyFlag = obj->getFlags() & 1;
 						return propertyPtr;
 					}
@@ -322,7 +349,7 @@
 		
 	}
 
-	debug(2, "! NULL(nf)\n");
+	//debug(2, "! NULL(nf)\n");
 	return NULL;
 	
 }

Modified: scummvm/trunk/engines/made/database.h
===================================================================
--- scummvm/trunk/engines/made/database.h	2008-04-22 22:36:09 UTC (rev 31660)
+++ scummvm/trunk/engines/made/database.h	2008-04-23 08:08:37 UTC (rev 31661)
@@ -31,6 +31,8 @@
 #include "common/file.h"
 #include "common/stream.h"
 
+#include "made/redreader.h"
+
 namespace Made {
 
 class Object {
@@ -49,6 +51,7 @@
 
 	byte *getData();
 	const char *getString();
+	void setString(const char *str);
 
 	bool isObject();
 	bool isVector();
@@ -73,6 +76,7 @@
 	~GameDatabase();
 
 	void open(const char *filename);
+	void openFromRed(const char *redFilename, const char *filename);
 
 	Object *getObject(int16 index) const { 
 		if (index >= 1)
@@ -93,11 +97,11 @@
 	void dumpObject(int16 index);
 	
 protected:
-	Common::File _fd;
 	Common::Array<Object*> _objects;
 	byte *_gameState;
 	uint32 _gameStateSize;
 	int16 _mainCodeObjectIndex;
+	void load(Common::SeekableReadStream &sourceS);
 };
 
 } // End of namespace Made

Modified: scummvm/trunk/engines/made/detection.cpp
===================================================================
--- scummvm/trunk/engines/made/detection.cpp	2008-04-22 22:36:09 UTC (rev 31660)
+++ scummvm/trunk/engines/made/detection.cpp	2008-04-23 08:08:37 UTC (rev 31661)
@@ -73,6 +73,8 @@
 
 	{
 		// Return to Zork - English CD version
+		// NOTE: This detects the game via the rtzcd.dat which is inside rtzcd.red.
+		// The entry below detects via rtzcd.red directly, which is the "official" way.
 		{
 			"rtz",
 			"CD",
@@ -88,6 +90,22 @@
 	},
 
 	{
+		// Return to Zork - English CD version
+		{
+			"rtz",
+			"CD",
+			AD_ENTRY1("rtzcd.red", "c4e2430e6b6c6ff1562a80fb4a9df24c"),
+			Common::EN_ANY,
+			Common::kPlatformPC,
+			Common::ADGF_NO_FLAGS
+		},
+		0,
+		0,
+		0,
+		0,
+	},
+
+	{
 		// Return to Zork - Demo
 		{
 			"rtz",

Modified: scummvm/trunk/engines/made/module.mk
===================================================================
--- scummvm/trunk/engines/made/module.mk	2008-04-22 22:36:09 UTC (rev 31660)
+++ scummvm/trunk/engines/made/module.mk	2008-04-23 08:08:37 UTC (rev 31661)
@@ -6,6 +6,7 @@
 	graphics.o \
 	made.o \
 	pmvplayer.o \
+	redreader.o \
 	resource.o \
 	screen.o \
 	script.o \

Added: scummvm/trunk/engines/made/redreader.cpp
===================================================================
--- scummvm/trunk/engines/made/redreader.cpp	                        (rev 0)
+++ scummvm/trunk/engines/made/redreader.cpp	2008-04-23 08:08:37 UTC (rev 31661)
@@ -0,0 +1,422 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "made/redreader.h"
+
+namespace Made {
+
+
+Common::MemoryReadStream *RedReader::load(const char *redFilename, const char *filename) {
+
+	Common::File fd;
+	FileEntry fileEntry;
+
+	if (!fd.open(redFilename))
+		error("RedReader::RedReader() Could not open %s", redFilename);
+
+	if (!seekFile(fd, fileEntry, filename))
+		error("RedReader::RedReader() Could not find %s in archive %s", filename, redFilename);
+
+	byte *fileBuf = new byte[fileEntry.origSize];
+	
+	LzhDecompressor lzhDec;
+	lzhDec.decompress(fd, fileBuf, fileEntry.compSize, fileEntry.origSize);
+	
+	return new Common::MemoryReadStream(fileBuf, fileEntry.origSize, true);
+
+}
+
+Common::MemoryReadStream *RedReader::loadFromRed(const char *redFilename, const char *filename) {
+	RedReader redReader;
+	return redReader.load(redFilename, filename);
+}
+
+bool RedReader::seekFile(Common::File &fd, FileEntry &fileEntry, const char *filename) {
+	char arcFilename[13];
+	while (!fd.eof()) {
+		fd.skip(8); // skip unknown
+		fileEntry.compSize = fd.readUint32LE();
+		fileEntry.origSize = fd.readUint32LE();
+		fd.skip(10); // skip unknown
+		fd.read(arcFilename, 13);
+		fd.skip(2); // skip unknown
+		// Check if we have found the file
+		if (!scumm_stricmp(arcFilename, filename))
+			return true;
+		// Skip compressed data
+		fd.skip(fileEntry.compSize);
+	}
+	return false;
+}
+
+LzhDecompressor::LzhDecompressor() {
+}
+
+LzhDecompressor::~LzhDecompressor() {
+}
+
+int LzhDecompressor::decompress(Common::SeekableReadStream &source, byte *dest, uint32 sourceLen, uint32 destLen) {
+
+	int bufsize;
+	byte buffer[DICSIZ];
+
+	_source = &source;
+	_compSize = sourceLen;
+
+	count_len_depth = 0;
+
+	_blockPos = 0;
+
+	decode_start();
+	while (destLen > 0) {
+		bufsize = ((destLen > DICSIZ) ? DICSIZ : destLen);
+		decode(bufsize, buffer);
+		memcpy(dest, buffer, bufsize);
+		dest += bufsize;
+		destLen -= bufsize;
+	}
+
+	return 0;
+}
+
+byte LzhDecompressor::readByte() {
+	if (_blockPos == 0xFFE) {
+		_blockPos = 0;
+		_source->skip(2); // skip unknown value
+	}
+	byte temp = _source->readByte();
+	_blockPos++;
+	return temp;
+}
+
+void LzhDecompressor::fillbuf(int count) {
+	_bitbuf <<= count;
+	while (count > _bitcount) {
+		_bitbuf |= _subbitbuf << (count -= _bitcount);
+		if (_compSize != 0) {
+			_compSize--;
+			_subbitbuf = readByte();
+		} else _subbitbuf = 0;
+		_bitcount = 8;
+	}
+	_bitbuf |= _subbitbuf >> (_bitcount -= count);
+}
+
+uint LzhDecompressor::getbits(int count) {
+	uint x;
+	x = _bitbuf >> (BITBUFSIZ - count);
+	fillbuf(count);
+	return x;
+}
+
+void LzhDecompressor::init_getbits() {
+	_bitbuf = 0;
+	_subbitbuf = 0;
+	_bitcount = 0;
+	fillbuf(BITBUFSIZ);
+}
+
+void LzhDecompressor::decode_start() {
+	huf_decode_start();
+	decode_j = 0;
+}
+
+void LzhDecompressor::decode(uint count, byte buffer[]) {
+	uint r, c;
+	r = 0;
+	while (--decode_j >= 0) {
+		buffer[r] = buffer[decode_i];
+		decode_i = (decode_i + 1) & (DICSIZ - 1);
+		if (++r == count) return;
+	}
+	for ( ; ; ) {
+		c = decode_c();
+		if (c <= 255) {
+			buffer[r] = c;
+			if (++r == count) return;
+		} else {
+			decode_j = c - (255 + 1 - THRESHOLD);
+			decode_i = (r - decode_p() - 1) & (DICSIZ - 1);
+			while (--decode_j >= 0) {
+				buffer[r] = buffer[decode_i];
+				decode_i = (decode_i + 1) & (DICSIZ - 1);
+				if (++r == count) return;
+			}
+		}
+	}
+}
+
+void LzhDecompressor::read_pt_len(int nn, int nbit, int i_special) {
+	int i, c, v;
+	unsigned int mask;
+	v = getbits(nbit);
+	if (v == 0) {
+		c = getbits(nbit);
+		for (i = 0; i < nn; i++) _pt_len[i] = 0;
+		for (i = 0; i < 256; i++) _pt_table[i] = c;
+	} else {
+		i = 0;
+		while (i < v) {
+			c = _bitbuf >> (BITBUFSIZ - 3);
+			if (c == 7) {
+				mask = 1U << (BITBUFSIZ - 1 - 3);
+				while (mask & _bitbuf) {  mask >>= 1;  c++;  }
+			}
+			fillbuf((c < 7) ? 3 : c - 3);
+			_pt_len[i++] = c;
+			if (i == i_special) {
+				c = getbits(2);
+				while (--c >= 0) _pt_len[i++] = 0;
+			}
+		}
+		while (i < nn) _pt_len[i++] = 0;
+		make_table(nn, _pt_len, 8, _pt_table);
+	}
+}
+
+void LzhDecompressor::read_c_len() {
+	uint i, v;
+	int c;
+	unsigned int mask;
+	v = getbits(CBIT);
+	if (v == 0) {
+		c = getbits(CBIT);
+		for (i = 0; i < NC; i++) _c_len[i] = 0;
+		for (i = 0; i < 4096; i++) _c_table[i] = c;
+	} else {
+		i = 0;
+		while (i < v) {
+			c = _pt_table[_bitbuf >> (BITBUFSIZ - 8)];
+			if (c >= NT) {
+				mask = 1U << (BITBUFSIZ - 1 - 8);
+				do {
+					if (_bitbuf & mask) c = _right[c];
+					else			   c = _left [c];
+					mask >>= 1;
+				} while (c >= NT);
+			}
+			fillbuf(_pt_len[c]);
+			if (c <= 2) {
+				if	  (c == 0) c = 1;
+				else if (c == 1) c = getbits(4) + 3;
+				else			 c = getbits(CBIT) + 20;
+				while (--c >= 0) _c_len[i++] = 0;
+			} else _c_len[i++] = c - 2;
+		}
+		while (i < NC) _c_len[i++] = 0;
+		make_table(NC, _c_len, 12, _c_table);
+	}
+}
+
+unsigned int LzhDecompressor::decode_c(void) {
+	uint j, mask;
+	if (_blocksize == 0) {
+		_blocksize = getbits(16);
+		read_pt_len(NT, TBIT, 3);
+		read_c_len();
+		read_pt_len(NP, PBIT, -1);
+	}
+	_blocksize--;
+	j = _c_table[_bitbuf >> (BITBUFSIZ - 12)];
+	if (j >= NC) {
+		mask = 1U << (BITBUFSIZ - 1 - 12);
+		do {
+			if (_bitbuf & mask) j = _right[j];
+			else			   j = _left [j];
+			mask >>= 1;
+		} while (j >= NC);
+	}
+	fillbuf(_c_len[j]);
+	return j;
+}
+
+unsigned int LzhDecompressor::decode_p() {
+	unsigned int j, mask;
+	j = _pt_table[_bitbuf >> (BITBUFSIZ - 8)];
+	if (j >= NP) {
+		mask = 1U << (BITBUFSIZ - 1 - 8);
+		do {
+			if (_bitbuf & mask) j = _right[j];
+			else			   j = _left [j];
+			mask >>= 1;
+		} while (j >= NP);
+	}
+	fillbuf(_pt_len[j]);
+	if (j != 0) j = (1U << (j - 1)) + getbits(j - 1);
+	return j;
+}
+
+void LzhDecompressor::huf_decode_start() {
+	init_getbits();
+	_blocksize = 0;
+}
+
+void LzhDecompressor::make_table(uint nchar, byte bitlen[], uint tablebits, uint16 table[]) {
+	uint16 count[17], weight[17], start[18], *p;
+	uint i, k, len, ch, jutbits, avail, nextcode, mask;
+	for (i = 1; i <= 16; i++) count[i] = 0;
+	for (i = 0; i < nchar; i++) count[bitlen[i]]++;
+	start[1] = 0;
+	for (i = 1; i <= 16; i++)
+		start[i + 1] = start[i] + (count[i] << (16 - i));
+	if (start[17] != (uint16)(1U << 16))
+		error("LzhDecompressor::make_table() Bad table\n");
+	jutbits = 16 - tablebits;
+	for (i = 1; i <= tablebits; i++) {
+		start[i] >>= jutbits;
+		weight[i] = 1U << (tablebits - i);
+	}
+	while (i <= 16) weight[i++] = 1U << (16 - i);
+	i = start[tablebits + 1] >> jutbits;
+	if (i != (uint16)(1U << 16)) {
+		k = 1U << tablebits;
+		while (i != k) table[i++] = 0;
+	}
+	avail = nchar;
+	mask = 1U << (15 - tablebits);
+	for (ch = 0; ch < nchar; ch++) {
+		if ((len = bitlen[ch]) == 0) continue;
+		nextcode = start[len] + weight[len];
+		if (len <= tablebits) {
+			for (i = start[len]; i < nextcode; i++) table[i] = ch;
+		} else {
+			k = start[len];
+			p = &table[k >> jutbits];
+			i = len - tablebits;
+			while (i != 0) {
+				if (*p == 0) {
+					_right[avail] = _left[avail] = 0;
+					*p = avail++;
+				}
+				if (k & mask) p = &_right[*p];
+				else		  p = &_left[*p];
+				k <<= 1;  i--;
+			}
+			*p = ch;
+		}
+		start[len] = nextcode;
+	}
+}
+
+/* call with i = root */
+void LzhDecompressor::count_len(int i) {
+	if (i < tree_n)
+		len_cnt[(count_len_depth < 16) ? count_len_depth : 16]++;
+	else {
+		count_len_depth++;
+		count_len(_left [i]);
+		count_len(_right[i]);
+		count_len_depth--;
+	}
+}
+
+void LzhDecompressor::make_len(int root) {
+	int i, k;
+	uint cum;
+	for (i = 0; i <= 16; i++) len_cnt[i] = 0;
+	count_len(root);
+	cum = 0;
+	for (i = 16; i > 0; i--)
+		cum += len_cnt[i] << (16 - i);
+	while (cum != (1U << 16)) {
+		len_cnt[16]--;
+		for (i = 15; i > 0; i--) {
+			if (len_cnt[i] != 0) {
+				len_cnt[i]--;
+				len_cnt[i+1] += 2;
+				break;
+			}
+		}
+		cum--;
+	}
+	for (i = 16; i > 0; i--) {
+		k = len_cnt[i];
+		while (--k >= 0) len_table[*sortptr++] = i;
+	}
+}
+
+void LzhDecompressor::downheap(int i) {
+	int j, k;
+	k = heap[i];
+	while ((j = 2 * i) <= heapsize) {
+		if (j < heapsize && freq[heap[j]] > freq[heap[j + 1]])
+		 	j++;
+		if (freq[k] <= freq[heap[j]]) break;
+		heap[i] = heap[j];  i = j;
+	}
+	heap[i] = k;
+}
+
+void LzhDecompressor::make_code(int n, byte len[], uint16 code[]) {
+	int	i;
+	uint16 start[18];
+	start[1] = 0;
+	for (i = 1; i <= 16; i++)
+		start[i + 1] = (start[i] + len_cnt[i]) << 1;
+	for (i = 0; i < n; i++) code[i] = start[len[i]]++;
+}
+
+/* make tree, calculate len[], return root */
+int LzhDecompressor::make_tree(int nparm, uint16 freqparm[], byte lenparm[], uint16 codeparm[]) {
+	int i, j, k, avail;
+
+	tree_n = nparm;
+	freq = freqparm;
+	len_table = lenparm;
+	avail = tree_n;
+	heapsize = 0;
+	heap[1] = 0;
+	for (i = 0; i < tree_n; i++) {
+		len_table[i] = 0;
+		if (freq[i]) heap[++heapsize] = i;
+	}
+	if (heapsize < 2) {
+		codeparm[heap[1]] = 0;
+		return heap[1];
+	}
+	for (i = heapsize / 2; i >= 1; i--)
+		downheap(i);  /* make priority queue */
+	sortptr = codeparm;
+	do {  /* while queue has at least two entries */
+		i = heap[1];  /* take out least-freq entry */
+		if (i < tree_n) *sortptr++ = i;
+		heap[1] = heap[heapsize--];
+		downheap(1);
+		j = heap[1];  /* next least-freq entry */
+		if (j < tree_n) *sortptr++ = j;
+		k = avail++;  /* generate new node */
+		freq[k] = freq[i] + freq[j];
+		heap[1] = k;
+		downheap(1);  /* put into queue */
+		_left[k] = i;
+		_right[k] = j;
+	} while (heapsize > 1);
+	sortptr = codeparm;
+	make_len(k);
+	make_code(nparm, lenparm, codeparm);
+	return k;  /* return root */
+}
+
+}


Property changes on: scummvm/trunk/engines/made/redreader.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/made/redreader.h
===================================================================
--- scummvm/trunk/engines/made/redreader.h	                        (rev 0)
+++ scummvm/trunk/engines/made/redreader.h	2008-04-23 08:08:37 UTC (rev 31661)
@@ -0,0 +1,108 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef MADE_REDREADER_H
+#define MADE_REDREADER_H
+
+#include "common/util.h"
+#include "common/file.h"
+#include "common/stream.h"
+
+namespace Made {
+
+class RedReader {
+public:
+	Common::MemoryReadStream *load(const char *redFilename, const char *filename);
+	static Common::MemoryReadStream *loadFromRed(const char *redFilename, const char *filename);
+private:
+	struct FileEntry {
+		uint32 compSize, origSize;
+	};
+	bool seekFile(Common::File &fd, FileEntry &fileEntry, const char *filename);
+};
+
+const uint BITBUFSIZ = 16;
+const uint DICBIT = 13;
+const uint DICSIZ = 1 << DICBIT;
+const uint MATCHBIT = 8;
+const uint MAXMATCH = 256;
+const uint THRESHOLD = 3;
+const uint NC = 255 + MAXMATCH + 2 - THRESHOLD;
+const uint CBIT = 9;
+const uint CODE_BIT = 16;
+const uint NP = DICBIT + 1;
+const int NT = CODE_BIT + 3;
+const uint PBIT = 4;
+const uint TBIT = 5;
+const uint NPT = NT;
+
+class LzhDecompressor {
+public:
+	LzhDecompressor();
+	~LzhDecompressor();
+	int decompress(Common::SeekableReadStream &source, byte *dest, uint32 compSize, uint32 origSize);
+private:
+	Common::SeekableReadStream *_source;
+	uint32 _compSize, _blockPos;
+
+	uint16 _bitbuf;
+	uint _subbitbuf;
+	int _bitcount;
+	uint16 _left[2 * NC - 1], _right[2 * NC - 1];
+	byte _c_len[NC], _pt_len[NPT];
+	uint _blocksize;
+	uint16 _c_table[4096], _pt_table[256];
+	int tree_n, heapsize;
+	short heap[NC + 1];
+	uint16 *freq, *sortptr, len_cnt[17];
+	byte *len_table;
+
+	int decode_i, decode_j;
+	int count_len_depth;
+
+	byte readByte();
+
+	void fillbuf(int count);
+	uint getbits(int count);
+	void init_getbits(void);
+	void decode_start(void);
+	void decode(uint count, byte text[]);
+	void huf_decode_start(void);
+	unsigned int decode_c(void);
+	unsigned int decode_p();
+	void read_pt_len(int nn, int nbit, int i_special);
+	void read_c_len();
+	void count_len(int i);
+	void make_len(int root);
+	void downheap(int i);
+	void make_code(int n, byte len[], uint16 code[]);
+	void make_table(uint nchar, byte bitlen[], uint tablebits, uint16 table[]);
+	int make_tree(int nparm, uint16 freqparm[], byte lenparm[], uint16 codeparm[]);
+
+};
+
+} // End of namespace Made
+
+#endif /* MADE_H */


Property changes on: scummvm/trunk/engines/made/redreader.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list