[Scummvm-cvs-logs] SF.net SVN: scummvm:[40608] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Fri May 15 16:07:45 CEST 2009


Revision: 40608
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40608&view=rev
Author:   thebluegr
Date:     2009-05-15 14:07:45 +0000 (Fri, 15 May 2009)

Log Message:
-----------
- Moved all the files out of /sci/scicore and into /sci
- Moved /scicore/sciconsole.h into /engine, and renamed /engine/scriptconsole.cpp to /engine/sciconsole.cpp

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/console.h
    scummvm/trunk/engines/sci/engine/game.cpp
    scummvm/trunk/engines/sci/engine/grammar.cpp
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/kmenu.cpp
    scummvm/trunk/engines/sci/engine/kmovement.cpp
    scummvm/trunk/engines/sci/engine/kscripts.cpp
    scummvm/trunk/engines/sci/engine/kstring.cpp
    scummvm/trunk/engines/sci/engine/message.h
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/gfx/gfx_resmgr.h
    scummvm/trunk/engines/sci/module.mk
    scummvm/trunk/engines/sci/sci.cpp
    scummvm/trunk/engines/sci/sci.h
    scummvm/trunk/engines/sci/sfx/core.h
    scummvm/trunk/engines/sci/sfx/player.h
    scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp
    scummvm/trunk/engines/sci/tools.cpp
    scummvm/trunk/engines/sci/tools.h

Added Paths:
-----------
    scummvm/trunk/engines/sci/decompressor.cpp
    scummvm/trunk/engines/sci/decompressor.h
    scummvm/trunk/engines/sci/engine/sciconsole.cpp
    scummvm/trunk/engines/sci/engine/sciconsole.h
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/resource.h
    scummvm/trunk/engines/sci/vocab_debug.cpp
    scummvm/trunk/engines/sci/vocabulary.cpp
    scummvm/trunk/engines/sci/vocabulary.h

Removed Paths:
-------------
    scummvm/trunk/engines/sci/engine/scriptconsole.cpp
    scummvm/trunk/engines/sci/scicore/decompressor.cpp
    scummvm/trunk/engines/sci/scicore/decompressor.h
    scummvm/trunk/engines/sci/scicore/resource.cpp
    scummvm/trunk/engines/sci/scicore/resource.h
    scummvm/trunk/engines/sci/scicore/sciconsole.h
    scummvm/trunk/engines/sci/scicore/vocab_debug.cpp
    scummvm/trunk/engines/sci/scicore/vocabulary.cpp
    scummvm/trunk/engines/sci/scicore/vocabulary.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/console.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -27,8 +27,8 @@
 
 #include "sci/sci.h"
 #include "sci/console.h"
-#include "sci/scicore/resource.h"
-#include "sci/scicore/vocabulary.h"
+#include "sci/resource.h"
+#include "sci/vocabulary.h"
 
 namespace Sci {
 

Modified: scummvm/trunk/engines/sci/console.h
===================================================================
--- scummvm/trunk/engines/sci/console.h	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/console.h	2009-05-15 14:07:45 UTC (rev 40608)
@@ -29,7 +29,7 @@
 #define SCI_CONSOLE_H
 
 #include "gui/debugger.h"
-#include "sci/scicore/sciconsole.h"
+#include "sci/engine/sciconsole.h"
 
 namespace Sci {
 

Copied: scummvm/trunk/engines/sci/decompressor.cpp (from rev 40607, scummvm/trunk/engines/sci/scicore/decompressor.cpp)
===================================================================
--- scummvm/trunk/engines/sci/decompressor.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/decompressor.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -0,0 +1,969 @@
+/* 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$
+ *
+ */
+
+// Resource library
+
+#include "common/util.h"
+#include "common/endian.h"
+#include "common/debug.h"
+
+#include "sci/decompressor.h"
+#include "sci/sci.h"
+
+namespace Sci {
+int Decompressor::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
+	uint32 chunk;
+	while (nPacked && !src->ioFailed()) {
+		chunk = MIN<uint32>(1024, nPacked);
+		src->read(dest, chunk);
+		nPacked -= chunk;
+		dest += chunk;
+	}
+	return src->ioFailed() ? 1 : 0;
+}
+
+void Decompressor::init(Common::ReadStream *src, byte *dest, uint32 nPacked,
+                        uint32 nUnpacked) {
+	_src = src;
+	_dest = dest;
+	_szPacked = nPacked;
+	_szUnpacked = nUnpacked;
+	_nBits = 0;
+	_dwRead = _dwWrote = 0;
+	_dwBits = 0;
+}
+
+void Decompressor::fetchBitsMSB() {
+	while (_nBits <= 24) {
+		_dwBits |= ((uint32)_src->readByte()) << (24 - _nBits);
+		_nBits += 8;
+		_dwRead++;
+	}
+}
+
+uint32 Decompressor::getBitsMSB(int n) {
+	// fetching more data to buffer if needed
+	if (_nBits < n)
+		fetchBitsMSB();
+	uint32 ret = _dwBits >> (32 - n);
+	_dwBits <<= n;
+	_nBits -= n;
+	return ret;
+}
+
+byte Decompressor::getByteMSB() {
+	return getBitsMSB(8);
+}
+
+void Decompressor::fetchBitsLSB() {
+	while (_nBits <= 24) {
+		_dwBits |= ((uint32)_src->readByte()) << _nBits;
+		_nBits += 8;
+		_dwRead++;
+	}
+}
+
+uint32 Decompressor::getBitsLSB(int n) {
+	// fetching more data to buffer if needed
+	if (_nBits < n)
+		fetchBitsLSB();
+	uint32 ret = (_dwBits & ~((~0) << n));
+	_dwBits >>= n;
+	_nBits -= n;
+	return ret;
+}
+
+byte Decompressor::getByteLSB() {
+	return getBitsLSB(8);
+}
+
+void Decompressor::putByte(byte b) {
+	_dest[_dwWrote++] = b;
+}
+//-------------------------------
+//  Huffman decompressor
+//-------------------------------
+int DecompressorHuffman::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
+								uint32 nUnpacked) {
+	init(src, dest, nPacked, nUnpacked);
+	byte numnodes;
+	int16 c;
+	uint16 terminator;
+
+	numnodes = _src->readByte();
+	terminator = _src->readByte() | 0x100;
+	_nodes = new byte [numnodes << 1];
+	_src->read(_nodes, numnodes << 1);
+
+	while ((c = getc2()) != terminator && (c >= 0) && !isFinished())
+		putByte(c);
+
+	delete[] _nodes;
+	return _dwWrote == _szUnpacked ? 0 : 1;
+}
+
+int16 DecompressorHuffman::getc2() {
+	byte *node = _nodes;
+	int16 next;
+	while (node[1]) {
+		if (getBitsMSB(1)) {
+			next = node[1] & 0x0F; // use lower 4 bits
+			if (next == 0)
+				return getByteMSB() | 0x100;
+		} else
+			next = node[1] >> 4; // use higher 4 bits
+		node += next << 1;
+	}
+	return (int16)(*node | (node[1] << 8));
+}
+
+//-------------------------------
+// LZW Decompressor for SCI0/01/1
+//-------------------------------
+void DecompressorLZW::init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
+	Decompressor::init(src, dest, nPacked, nUnpacked);
+
+	_numbits = 9;
+	_curtoken = 0x102;
+	_endtoken = 0x1ff;
+}
+
+int DecompressorLZW::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
+								uint32 nUnpacked) {
+	byte *buffer = NULL;
+
+	switch (_compression) {
+	case kCompLZW:	// SCI0 LZW compression
+		return unpackLZW(src, dest, nPacked, nUnpacked);
+		break;
+	case kCompLZW1: // SCI01/1 LZW compression
+		return unpackLZW1(src, dest, nPacked, nUnpacked);
+		break;
+	case kCompLZW1View:
+		buffer = new byte[nUnpacked];
+		unpackLZW1(src, buffer, nPacked, nUnpacked);
+		reorderView(buffer, dest);
+		break;
+	case kCompLZW1Pic:
+		buffer = new byte[nUnpacked];
+		unpackLZW1(src, buffer, nPacked, nUnpacked);
+		reorderPic(buffer, dest, nUnpacked);
+		break;
+	}
+	delete[] buffer;
+	return 0;
+}
+
+int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPacked,
+                                uint32 nUnpacked) {
+	init(src, dest, nPacked, nUnpacked);
+
+	uint16 token; // The last received value
+
+	uint16 tokenlist[4096]; // pointers to dest[]
+	uint16 tokenlengthlist[4096]; // char length of each token
+	uint16 tokenlastlength = 0;
+
+	while (!isFinished()) {
+		token = getBitsLSB(_numbits);
+
+		if (token == 0x101)
+			return 0; // terminator
+		if (token == 0x100) { // reset command
+			_numbits = 9;
+			_endtoken = 0x1FF;
+			_curtoken = 0x0102;
+		} else {
+			if (token > 0xff) {
+				if (token >= _curtoken) {
+					warning("unpackLZW: Bad token %x", token);
+					return SCI_ERROR_DECOMPRESSION_ERROR;
+				} 
+				tokenlastlength = tokenlengthlist[token] + 1;
+				if (_dwWrote + tokenlastlength > _szUnpacked) {
+					// For me this seems a normal situation, It's necessary to handle it
+					warning("unpackLZW: Trying to write beyond the end of array(len=%d, destctr=%d, tok_len=%d)",
+					        _szUnpacked, _dwWrote, tokenlastlength);
+					for (int i = 0; _dwWrote < _szUnpacked; i++)
+						putByte(dest[tokenlist[token] + i]);
+				} else
+					for (int i = 0; i < tokenlastlength; i++)
+						putByte(dest[tokenlist[token] + i]);
+			} else {
+				tokenlastlength = 1;
+				if (_dwWrote >= _szUnpacked)
+					warning("unpackLZW: Try to write single byte beyond end of array");
+				else
+					putByte(token);
+			}
+			if (_curtoken > _endtoken && _numbits < 12) {
+				_numbits++;
+				_endtoken = (_endtoken << 1) + 1;
+			}
+			if (_curtoken <= _endtoken) {
+				tokenlist[_curtoken] = _dwWrote - tokenlastlength;
+				tokenlengthlist[_curtoken] = tokenlastlength;
+				_curtoken++;
+			}
+
+		}
+	}
+
+	return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
+}
+
+int DecompressorLZW::unpackLZW1(Common::ReadStream *src, byte *dest, uint32 nPacked,
+                                uint32 nUnpacked) {
+	init(src, dest, nPacked, nUnpacked);
+
+	byte stak[0x1014];
+	byte lastchar = 0;
+	uint16 stakptr = 0, lastbits = 0;
+	Tokenlist tokens[0x1004];
+	memset(tokens, 0, sizeof(tokens));
+
+
+	byte decryptstart = 0;
+	uint16 bitstring;
+	uint16 token;
+	bool bExit = false;
+
+	while (!isFinished() && !bExit) {
+		switch (decryptstart) {
+		case 0:
+			bitstring = getBitsMSB(_numbits);
+			if (bitstring == 0x101) {// found end-of-data signal
+				bExit = true;
+				continue;
+			}
+			putByte(bitstring);
+			lastbits = bitstring;
+			lastchar = (bitstring & 0xff);
+			decryptstart = 1;
+			break;
+
+		case 1:
+			bitstring = getBitsMSB(_numbits);
+			if (bitstring == 0x101) { // found end-of-data signal
+				bExit = true;
+				continue;
+			}
+			if (bitstring == 0x100) { // start-over signal
+				_numbits = 9;
+				_curtoken = 0x102;
+				_endtoken = 0x1ff;
+				decryptstart = 0;
+				continue;
+			}
+
+			token = bitstring;
+			if (token >= _curtoken) { // index past current point
+				token = lastbits;
+				stak[stakptr++] = lastchar;
+			}
+			while ((token > 0xff) && (token < 0x1004)) { // follow links back in data
+				stak[stakptr++] = tokens[token].data;
+				token = tokens[token].next;
+			}
+			lastchar = stak[stakptr++] = token & 0xff;
+			// put stack in buffer
+			while (stakptr > 0) {
+				putByte(stak[--stakptr]);
+				if (_dwWrote == _szUnpacked) {
+					bExit = true;
+					continue;
+				}
+			}
+			// put token into record
+			if (_curtoken <= _endtoken) {
+				tokens[_curtoken].data = lastchar;
+				tokens[_curtoken].next = lastbits;
+				_curtoken++;
+				if (_curtoken == _endtoken && _numbits < 12) {
+					_numbits++;
+					_endtoken = (_endtoken << 1) + 1;
+				}
+			}
+			lastbits = bitstring;
+			break;
+		}
+	}
+	return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
+}
+
+#define PAL_SIZE 1284
+#define EXTRA_MAGIC_SIZE 15
+#define VIEW_HEADER_COLORS_8BIT 0x80
+
+void DecompressorLZW::decodeRLE(byte **rledata, byte **pixeldata, byte *outbuffer, int size) {
+	int pos = 0;
+	byte nextbyte;
+	byte *rd = *rledata;
+	byte *ob = outbuffer;
+	byte *pd = *pixeldata;
+
+	while (pos < size) {
+		nextbyte = *rd++;
+		*ob++ = nextbyte;
+		pos++;
+		switch (nextbyte & 0xC0) {
+		case 0x40:
+		case 0x00:
+			memcpy(ob, pd, nextbyte);
+			pd += nextbyte;
+			ob += nextbyte;
+			pos += nextbyte;
+			break;
+		case 0xC0:
+			break;
+		case 0x80:
+			nextbyte = *pd++;
+			*ob++ = nextbyte;
+			pos++;
+			break;
+		}
+	}
+
+	*rledata = rd;
+	*pixeldata = pd;
+}
+
+/**
+ * Does the same this as decodeRLE, only to determine the length of the
+ * compressed source data.
+ */
+int DecompressorLZW::getRLEsize(byte *rledata, int dsize) {
+	int pos = 0;
+	byte nextbyte;
+	int size = 0;
+
+	while (pos < dsize) {
+		nextbyte = *(rledata++);
+		pos++;
+		size++;
+
+		switch (nextbyte & 0xC0) {
+		case 0x40:
+		case 0x00:
+			pos += nextbyte;
+			break;
+		case 0xC0:
+			break;
+		case 0x80:
+			pos++;
+			break;
+		}
+	}
+
+	return size;
+}
+
+void DecompressorLZW::reorderPic(byte *src, byte *dest, int dsize) {
+	uint16 view_size, view_start, cdata_size;
+	int i;
+	byte *seeker = src;
+	byte *writer = dest;
+	char viewdata[7];
+	byte *cdata, *cdata_start;
+	
+	*writer++ = PIC_OP_OPX;
+	*writer++ = PIC_OPX_SET_PALETTE;
+
+	for (i = 0; i < 256; i++) /* Palette translation map */
+		*writer++ = i;
+
+	WRITE_LE_UINT32(writer, 0); /* Palette stamp */
+	writer += 4;
+
+	view_size = READ_LE_UINT16(seeker);
+	seeker += 2;
+	view_start = READ_LE_UINT16(seeker);
+	seeker += 2;
+	cdata_size = READ_LE_UINT16(seeker);
+	seeker += 2;
+
+	memcpy(viewdata, seeker, sizeof(viewdata));
+	seeker += sizeof(viewdata);
+	
+	memcpy(writer, seeker, 4*256); /* Palette */
+	seeker += 4*256;
+	writer += 4*256;
+
+	if (view_start != PAL_SIZE + 2) { /* +2 for the opcode */
+		memcpy(writer, seeker, view_start-PAL_SIZE-2);
+		seeker += view_start - PAL_SIZE - 2;
+		writer += view_start - PAL_SIZE - 2;
+	}
+
+	if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) {
+		memcpy(dest + view_size + view_start + EXTRA_MAGIC_SIZE, seeker, 
+		       dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
+		seeker += dsize - view_size - view_start - EXTRA_MAGIC_SIZE;
+	}
+
+	cdata_start = cdata = (byte *)malloc(cdata_size);
+	memcpy(cdata, seeker, cdata_size);
+	seeker += cdata_size;
+	
+	writer = dest + view_start;
+	*writer++ = PIC_OP_OPX;
+	*writer++ = PIC_OPX_EMBEDDED_VIEW;
+	*writer++ = 0;
+	*writer++ = 0;
+	*writer++ = 0;
+	WRITE_LE_UINT16(writer, view_size + 8);
+	writer += 2;
+
+	memcpy(writer, viewdata, sizeof(viewdata));
+	writer += sizeof(viewdata);
+
+	*writer++ = 0;
+
+	decodeRLE(&seeker, &cdata, writer, view_size);
+	
+	free(cdata_start);
+}
+
+void DecompressorLZW::buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
+	for (int c = 0; c < max; c++) {
+		memcpy(*writer, *seeker, 6);
+		*seeker += 6;
+		*writer += 6;
+		int w = *((*seeker)++);
+		WRITE_LE_UINT16(*writer, w); /* Zero extension */
+		*writer += 2;
+
+		*writer += cc_lengths[celindex];
+		celindex++;
+	}
+}
+
+void DecompressorLZW::reorderView(byte *src, byte *dest) {
+	byte *cellengths;
+	int loopheaders;
+	int lh_present;
+	int lh_mask;
+	int pal_offset;
+	int cel_total;
+	int unknown;
+	byte *seeker = src;
+	char celcounts[100];
+	byte *writer = dest;
+	byte *lh_ptr;
+	byte *rle_ptr, *pix_ptr;
+	int l, lb, c, celindex, lh_last = -1;
+	int chptr;
+	int w;
+	int *cc_lengths;
+	byte **cc_pos;
+
+	/* Parse the main header */
+	cellengths = src + READ_LE_UINT16(seeker) + 2;
+	seeker += 2;
+	loopheaders = *seeker++;
+	lh_present = *seeker++;
+	lh_mask = READ_LE_UINT16(seeker);
+	seeker += 2;
+	unknown = READ_LE_UINT16(seeker);
+	seeker += 2;
+	pal_offset = READ_LE_UINT16(seeker);
+	seeker += 2;
+	cel_total = READ_LE_UINT16(seeker);
+	seeker += 2;
+
+	cc_pos = (byte **) malloc(sizeof(byte *) * cel_total);
+	cc_lengths = (int *) malloc(sizeof(int) * cel_total);
+
+	for (c = 0; c < cel_total; c++)
+		cc_lengths[c] = READ_LE_UINT16(cellengths + 2 * c);
+
+	*writer++ = loopheaders;
+	*writer++ = VIEW_HEADER_COLORS_8BIT;
+	WRITE_LE_UINT16(writer, lh_mask);
+	writer += 2;
+	WRITE_LE_UINT16(writer, unknown);
+	writer += 2;
+	WRITE_LE_UINT16(writer, pal_offset);
+	writer += 2;
+
+	lh_ptr = writer;
+	writer += 2 * loopheaders; /* Make room for the loop offset table */
+
+	pix_ptr = writer;
+
+	memcpy(celcounts, seeker, lh_present);
+	seeker += lh_present;
+
+	lb = 1;
+	celindex = 0;
+
+	rle_ptr = pix_ptr = cellengths + (2 * cel_total);
+	w = 0;
+
+	for (l = 0; l < loopheaders; l++) {
+		if (lh_mask & lb) { /* The loop is _not_ present */
+			if (lh_last == -1) {
+				warning("Error: While reordering view: Loop not present, but can't re-use last loop");
+				lh_last = 0;
+			}
+			WRITE_LE_UINT16(lh_ptr, lh_last);
+			lh_ptr += 2;
+		} else {
+			lh_last = writer - dest;
+			WRITE_LE_UINT16(lh_ptr, lh_last);
+			lh_ptr += 2;
+			WRITE_LE_UINT16(writer, celcounts[w]);
+			writer += 2;
+			WRITE_LE_UINT16(writer, 0);
+			writer += 2;
+
+			/* Now, build the cel offset table */
+			chptr = (writer - dest) + (2 * celcounts[w]);
+
+			for (c = 0; c < celcounts[w]; c++) {
+				WRITE_LE_UINT16(writer, chptr);
+				writer += 2;
+				cc_pos[celindex+c] = dest + chptr;
+				chptr += 8 + READ_LE_UINT16(cellengths + 2 * (celindex + c));
+			}
+
+			buildCelHeaders(&seeker, &writer, celindex, cc_lengths, celcounts[w]);
+
+			celindex += celcounts[w];
+			w++;
+		}
+
+		lb = lb << 1;
+	}
+
+	if (celindex < cel_total) {
+		warning("View decompression generated too few (%d / %d) headers", celindex, cel_total);
+		return;
+	}
+
+	/* Figure out where the pixel data begins. */
+	for (c = 0; c < cel_total; c++)
+		pix_ptr += getRLEsize(pix_ptr, cc_lengths[c]);
+
+	rle_ptr = cellengths + (2 * cel_total);
+	for (c = 0; c < cel_total; c++)
+		decodeRLE(&rle_ptr, &pix_ptr, cc_pos[c] + 8, cc_lengths[c]);
+
+	*writer++ = 'P';
+	*writer++ = 'A';
+	*writer++ = 'L';
+
+	for (c = 0; c < 256; c++)
+		*writer++ = c;
+
+	seeker -= 4; /* The missing four. Don't ask why. */
+	memcpy(writer, seeker, 4*256 + 4);
+
+	free(cc_pos);
+	free(cc_lengths);
+}
+
+//----------------------------------------------
+// DCL decompressor for SCI1.1
+//----------------------------------------------
+#define HUFFMAN_LEAF 0x40000000
+// Branch node
+#define BN(pos, left, right)  ((left << 12) | (right)),
+// Leaf node
+#define LN(pos, value)  ((value) | HUFFMAN_LEAF),
+
+static int length_tree[] = {
+	BN(0, 1, 2)
+	BN(1, 3, 4)     BN(2, 5, 6)
+	BN(3, 7, 8)     BN(4, 9, 10)    BN(5, 11, 12)  LN(6, 1)
+	BN(7, 13, 14)   BN(8, 15, 16)   BN(9, 17, 18)  LN(10, 3)  LN(11, 2)  LN(12, 0)
+	BN(13, 19, 20)  BN(14, 21, 22)  BN(15, 23, 24) LN(16, 6)  LN(17, 5)  LN(18, 4)
+	BN(19, 25, 26)  BN(20, 27, 28)  LN(21, 10)     LN(22, 9)  LN(23, 8)  LN(24, 7)
+	BN(25, 29, 30)  LN(26, 13)      LN(27, 12)     LN(28, 11)
+	LN(29, 15)      LN(30, 14)
+	0 // We need something witout a comma at the end
+};
+
+static int distance_tree[] = {
+	BN(0, 1, 2)
+	BN(1, 3, 4)       BN(2, 5, 6)
+	//
+	BN(3, 7, 8)       BN(4, 9, 10)      BN(5, 11, 12)     LN(6, 0)
+	BN(7, 13, 14)     BN(8, 15, 16)     BN(9, 17, 18)     BN(10, 19, 20)
+	BN(11, 21, 22)    BN(12, 23, 24)
+	//
+	BN(13, 25, 26)    BN(14, 27, 28)    BN(15, 29, 30)    BN(16, 31, 32)
+	BN(17, 33, 34)    BN(18, 35, 36)    BN(19, 37, 38)    BN(20, 39, 40)
+	BN(21, 41, 42)    BN(22, 43, 44)    LN(23, 2)         LN(24, 1)
+	//
+	BN(25, 45, 46)    BN(26, 47, 48)    BN(27, 49, 50)    BN(28, 51, 52)
+	BN(29, 53, 54)    BN(30, 55, 56)    BN(31, 57, 58)    BN(32, 59, 60)
+	BN(33, 61, 62)	  BN(34, 63, 64)    BN(35, 65, 66)    BN(36, 67, 68)
+	BN(37, 69, 70)    BN(38, 71, 72)    BN(39, 73, 74)    BN(40, 75, 76)
+	LN(41, 6)         LN(42, 5)         LN(43, 4)         LN(44, 3)
+	//
+	BN(45, 77, 78)    BN(46, 79, 80)    BN(47, 81, 82)    BN(48, 83, 84)
+	BN(49, 85, 86)    BN(50, 87, 88)    BN(51, 89, 90)    BN(52, 91, 92)
+	BN(53, 93, 94)    BN(54, 95, 96)    BN(55, 97, 98)    BN(56, 99, 100)
+	BN(57, 101, 102)  BN(58, 103, 104)  BN(59, 105, 106)  BN(60, 107, 108)
+	BN(61, 109, 110)  LN(62, 21)        LN(63, 20)        LN(64, 19)
+	LN(65, 18)        LN(66, 17)        LN(67, 16)        LN(68, 15)
+	LN(69, 14)        LN(70, 13)        LN(71, 12)        LN(72, 11)
+	LN(73, 10)        LN(74, 9)         LN(75, 8)         LN(76, 7)
+	//
+	BN(77, 111, 112)  BN(78, 113, 114)  BN(79, 115, 116)  BN(80, 117, 118)
+	BN(81, 119, 120)  BN(82, 121, 122)  BN(83, 123, 124)  BN(84, 125, 126)
+	LN(85, 47)        LN(86, 46)        LN(87, 45)        LN(88, 44)
+	LN(89, 43)        LN(90, 42)        LN(91, 41)        LN(92, 40)
+	LN(93, 39)        LN(94, 38)        LN(95, 37)        LN(96, 36)
+	LN(97, 35)        LN(98, 34)        LN(99, 33)        LN(100, 32)
+	LN(101, 31)       LN(102, 30)       LN(103, 29)       LN(104, 28)
+	LN(105, 27)       LN(106, 26)       LN(107, 25)       LN(108, 24)
+	LN(109, 23)       LN(110, 22)       LN(111, 63)       LN(112, 62)
+	LN(113, 61)       LN(114, 60)       LN(115, 59)       LN(116, 58)
+	LN(117, 57)       LN(118, 56)       LN(119, 55)       LN(120, 54)
+	LN(121, 53)       LN(122, 52)       LN(123, 51)       LN(124, 50)
+	LN(125, 49)       LN(126, 48)
+	0 // We need something witout a comma at the end
+};
+
+static int ascii_tree[] = {
+	BN(0, 1, 2)       BN(1, 3, 4)       BN(2, 5, 6)       BN(3, 7, 8)
+	BN(4, 9, 10)      BN(5, 11, 12)     BN(6, 13, 14)     BN(7, 15, 16)
+	BN(8, 17, 18)     BN(9, 19, 20)     BN(10, 21, 22)    BN(11, 23, 24)
+	BN(12, 25, 26)    BN(13, 27, 28)    BN(14, 29, 30)    BN(15, 31, 32)
+	BN(16, 33, 34)    BN(17, 35, 36)    BN(18, 37, 38)    BN(19, 39, 40)
+	BN(20, 41, 42)    BN(21, 43, 44)    BN(22, 45, 46)    BN(23, 47, 48)
+	BN(24, 49, 50)    BN(25, 51, 52)    BN(26, 53, 54)    BN(27, 55, 56)
+	BN(28, 57, 58)    BN(29, 59, 60)    LN(30, 32)
+	//
+	BN(31, 61, 62)    BN(32, 63, 64)    BN(33, 65, 66)    BN(34, 67, 68)
+	BN(35, 69, 70)    BN(36, 71, 72)    BN(37, 73, 74)    BN(38, 75, 76)
+	BN(39, 77, 78)    BN(40, 79, 80)    BN(41, 81, 82)    BN(42, 83, 84)
+	BN(43, 85, 86)    BN(44, 87, 88)    BN(45, 89, 90)    BN(46, 91, 92)
+	BN(47, 93, 94)    BN(48, 95, 96)    BN(49, 97, 98)    LN(50, 117)
+	LN(51, 116)       LN(52, 115)       LN(53, 114)       LN(54, 111)
+	LN(55, 110)       LN(56, 108)       LN(57, 105)       LN(58, 101)
+	LN(59, 97)        LN(60, 69)
+	//
+	BN(61, 99, 100)   BN(62, 101, 102)  BN(63, 103, 104)  BN(64, 105, 106)
+	BN(65, 107, 108)  BN(66, 109, 110)	BN(67, 111, 112)  BN(68, 113, 114)
+	BN(69, 115, 116)  BN(70, 117, 118)  BN(71, 119, 120)  BN(72, 121, 122)
+	BN(73, 123, 124)  BN(74, 125, 126)  BN(75, 127, 128)  BN(76, 129, 130)
+	BN(77, 131, 132)  BN(78, 133, 134)  LN(79, 112)       LN(80, 109)
+	LN(81, 104)       LN(82, 103)       LN(83, 102)       LN(84, 100)
+	LN(85, 99)        LN(86, 98)        LN(87, 84)        LN(88, 83)
+	LN(89, 82)        LN(90, 79)        LN(91, 78)        LN(92, 76)
+	LN(93, 73)        LN(94, 68)        LN(95, 67)        LN(96, 65)
+	LN(97, 49)        LN(98, 45)
+	//
+	BN(99, 135, 136)  BN(100, 137, 138) BN(101, 139, 140) BN(102, 141, 142)
+	BN(103, 143, 144) BN(104, 145, 146)	BN(105, 147, 148) BN(106, 149, 150)
+	BN(107, 151, 152) BN(108, 153, 154) BN(109, 155, 156) BN(110, 157, 158)
+	BN(111, 159, 160) BN(112, 161, 162) BN(113, 163, 164) LN(114, 119)
+	LN(115, 107)      LN(116, 85)       LN(117, 80)       LN(118, 77)
+	LN(119, 70)       LN(120, 66)       LN(121, 61)       LN(122, 56)
+	LN(123, 55)       LN(124, 53)       LN(125, 52)       LN(126, 51)
+	LN(127, 50)       LN(128, 48)       LN(129, 46)       LN(130, 44)
+	LN(131, 41)       LN(132, 40)       LN(133, 13)       LN(134, 10)
+	//
+	BN(135, 165, 166) BN(136, 167, 168) BN(137, 169, 170) BN(138, 171, 172)
+	BN(139, 173, 174) BN(140, 175, 176) BN(141, 177, 178) BN(142, 179, 180)
+	BN(143, 181, 182) BN(144, 183, 184) BN(145, 185, 186) BN(146, 187, 188)
+	BN(147, 189, 190) BN(148, 191, 192) LN(149, 121)      LN(150, 120)
+	LN(151, 118)      LN(152, 95)       LN(153, 91)       LN(154, 87)
+	LN(155, 72)       LN(156, 71)       LN(157, 58)       LN(158, 57)
+	LN(159, 54)       LN(160, 47)       LN(161, 42)       LN(162, 39)
+	LN(163, 34)       LN(164, 9)
+	//
+	BN(165, 193, 194) BN(166, 195, 196) BN(167, 197, 198) BN(168, 199, 200)
+	BN(169, 201, 202) BN(170, 203, 204) BN(171, 205, 206) BN(172, 207, 208)
+	BN(173, 209, 210) BN(174, 211, 212) BN(175, 213, 214) BN(176, 215, 216)
+	BN(177, 217, 218) BN(178, 219, 220) BN(179, 221, 222) BN(180, 223, 224)
+	BN(181, 225, 226) BN(182, 227, 228)	BN(183, 229, 230) BN(184, 231, 232)
+	BN(185, 233, 234) LN(186, 93)       LN(187, 89)       LN(188, 88)
+	LN(189, 86)       LN(190, 75)       LN(191, 62)       LN(192, 43)
+	//
+	BN(193, 235, 236) BN(194, 237, 238) BN(195, 239, 240) BN(196, 241, 242)
+	BN(197, 243, 244) BN(198, 245, 246)	BN(199, 247, 248) BN(200, 249, 250)
+	BN(201, 251, 252) BN(202, 253, 254) BN(203, 255, 256) BN(204, 257, 258)
+	BN(205, 259, 260) BN(206, 261, 262) BN(207, 263, 264) BN(208, 265, 266)
+	BN(209, 267, 268) BN(210, 269, 270)	BN(211, 271, 272) BN(212, 273, 274)
+	BN(213, 275, 276) BN(214, 277, 278) BN(215, 279, 280) BN(216, 281, 282)
+	BN(217, 283, 284) BN(218, 285, 286) BN(219, 287, 288) BN(220, 289, 290)
+	BN(221, 291, 292) BN(222, 293, 294) BN(223, 295, 296) BN(224, 297, 298)
+	BN(225, 299, 300) BN(226, 301, 302) BN(227, 303, 304) BN(228, 305, 306)
+	BN(229, 307, 308) LN(230, 122)      LN(231, 113)      LN(232, 38)
+	LN(233, 36)       LN(234, 33)
+	//
+	BN(235, 309, 310) BN(236, 311, 312) BN(237, 313, 314) BN(238, 315, 316)
+	BN(239, 317, 318) BN(240, 319, 320) BN(241, 321, 322) BN(242, 323, 324)
+	BN(243, 325, 326) BN(244, 327, 328) BN(245, 329, 330) BN(246, 331, 332)
+	BN(247, 333, 334) BN(248, 335, 336) BN(249, 337, 338) BN(250, 339, 340)
+	BN(251, 341, 342) BN(252, 343, 344)	BN(253, 345, 346) BN(254, 347, 348)
+	BN(255, 349, 350) BN(256, 351, 352) BN(257, 353, 354) BN(258, 355, 356)
+	BN(259, 357, 358) BN(260, 359, 360) BN(261, 361, 362) BN(262, 363, 364)
+	BN(263, 365, 366) BN(264, 367, 368) BN(265, 369, 370) BN(266, 371, 372)
+	BN(267, 373, 374) BN(268, 375, 376) BN(269, 377, 378) BN(270, 379, 380)
+	BN(271, 381, 382) BN(272, 383, 384) BN(273, 385, 386) BN(274, 387, 388)
+	BN(275, 389, 390) BN(276, 391, 392) BN(277, 393, 394) BN(278, 395, 396)
+	BN(279, 397, 398) BN(280, 399, 400) BN(281, 401, 402) BN(282, 403, 404)
+	BN(283, 405, 406) BN(284, 407, 408) BN(285, 409, 410) BN(286, 411, 412)
+	BN(287, 413, 414) BN(288, 415, 416) BN(289, 417, 418) BN(290, 419, 420)
+	BN(291, 421, 422) BN(292, 423, 424) BN(293, 425, 426) BN(294, 427, 428)
+	BN(295, 429, 430) BN(296, 431, 432) BN(297, 433, 434) BN(298, 435, 436)
+	LN(299, 124)      LN(300, 123)      LN(301, 106)      LN(302, 92)
+	LN(303, 90)       LN(304, 81)       LN(305, 74)       LN(306, 63)
+	LN(307, 60)       LN(308, 0)
+	//
+	BN(309, 437, 438) BN(310, 439, 440) BN(311, 441, 442) BN(312, 443, 444)
+	BN(313, 445, 446) BN(314, 447, 448) BN(315, 449, 450) BN(316, 451, 452)
+	BN(317, 453, 454) BN(318, 455, 456) BN(319, 457, 458) BN(320, 459, 460)
+	BN(321, 461, 462) BN(322, 463, 464) BN(323, 465, 466) BN(324, 467, 468)
+	BN(325, 469, 470) BN(326, 471, 472)	BN(327, 473, 474) BN(328, 475, 476)
+	BN(329, 477, 478) BN(330, 479, 480) BN(331, 481, 482) BN(332, 483, 484)
+	BN(333, 485, 486) BN(334, 487, 488) BN(335, 489, 490) BN(336, 491, 492)
+	BN(337, 493, 494) BN(338, 495, 496) BN(339, 497, 498) BN(340, 499, 500)
+	BN(341, 501, 502) BN(342, 503, 504) BN(343, 505, 506) BN(344, 507, 508)
+	BN(345, 509, 510) LN(346, 244)      LN(347, 243)      LN(348, 242)
+	LN(349, 238)      LN(350, 233)      LN(351, 229)      LN(352, 225)
+	LN(353, 223)      LN(354, 222)      LN(355, 221)      LN(356, 220)
+	LN(357, 219)      LN(358, 218)      LN(359, 217)      LN(360, 216)
+	LN(361, 215)      LN(362, 214)      LN(363, 213)      LN(364, 212)
+	LN(365, 211)      LN(366, 210)      LN(367, 209)      LN(368, 208)
+	LN(369, 207)      LN(370, 206)      LN(371, 205)      LN(372, 204)
+	LN(373, 203)      LN(374, 202)      LN(375, 201)      LN(376, 200)
+	LN(377, 199)      LN(378, 198)      LN(379, 197)      LN(380, 196)
+	LN(381, 195)      LN(382, 194)      LN(383, 193)      LN(384, 192)
+	LN(385, 191)      LN(386, 190)      LN(387, 189)      LN(388, 188)
+	LN(389, 187)      LN(390, 186)      LN(391, 185)      LN(392, 184)
+	LN(393, 183)      LN(394, 182)      LN(395, 181)      LN(396, 180)
+	LN(397, 179)      LN(398, 178)      LN(399, 177)      LN(400, 176)
+	LN(401, 127)      LN(402, 126)      LN(403, 125)      LN(404, 96)
+	LN(405, 94)       LN(406, 64)       LN(407, 59)       LN(408, 37)
+	LN(409, 35)       LN(410, 31)       LN(411, 30)       LN(412, 29)
+	LN(413, 28)       LN(414, 27)       LN(415, 25)       LN(416, 24)
+	LN(417, 23)       LN(418, 22)       LN(419, 21)       LN(420, 20)
+	LN(421, 19)       LN(422, 18)       LN(423, 17)       LN(424, 16)
+	LN(425, 15)       LN(426, 14)       LN(427, 12)       LN(428, 11)
+	LN(429, 8)        LN(430, 7)        LN(431, 6)        LN(432, 5)
+	LN(433, 4)        LN(434, 3)        LN(435, 2)        LN(436, 1)
+	LN(437, 255)      LN(438, 254)      LN(439, 253)      LN(440, 252)
+	LN(441, 251)      LN(442, 250)      LN(443, 249)      LN(444, 248)
+	LN(445, 247)      LN(446, 246)      LN(447, 245)      LN(448, 241)
+	LN(449, 240)      LN(450, 239)      LN(451, 237)      LN(452, 236)
+	LN(453, 235)      LN(454, 234)      LN(455, 232)      LN(456, 231)
+	LN(457, 230)      LN(458, 228)      LN(459, 227)      LN(460, 226)
+	LN(461, 224)      LN(462, 175)      LN(463, 174)      LN(464, 173)
+	LN(465, 172)      LN(466, 171)      LN(467, 170)      LN(468, 169)
+	LN(469, 168)      LN(470, 167)      LN(471, 166)      LN(472, 165)
+	LN(473, 164)      LN(474, 163)      LN(475, 162)      LN(476, 161)
+	LN(477, 160)      LN(478, 159)      LN(479, 158)      LN(480, 157)
+	LN(481, 156)      LN(482, 155)      LN(483, 154)      LN(484, 153)
+	LN(485, 152)      LN(486, 151)      LN(487, 150)      LN(488, 149)
+	LN(489, 148)      LN(490, 147)      LN(491, 146)      LN(492, 145)
+	LN(493, 144)      LN(494, 143)      LN(495, 142)      LN(496, 141)
+	LN(497, 140)      LN(498, 139)      LN(499, 138)      LN(500, 137)
+	LN(501, 136)      LN(502, 135)      LN(503, 134)      LN(504, 133)
+	LN(505, 132)      LN(506, 131)      LN(507, 130)      LN(508, 129)
+	LN(509, 128)      LN(510, 26)
+};
+
+int DecompressorDCL::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
+                            uint32 nUnpacked) {
+	init(src, dest, nPacked, nUnpacked);
+	return unpackDCL(dest);
+}
+
+
+int DecompressorDCL::huffman_lookup(int *tree) {
+	int pos = 0;
+	int bit;
+
+	while (!(tree[pos] & HUFFMAN_LEAF)) {
+		bit = getBitsLSB(1);
+		debugC(kDebugLevelDclInflate, "[%d]:%d->", pos, bit);
+		pos = bit ? tree[pos] & 0xFFF : tree[pos] >> 12;
+	}
+	debugC(kDebugLevelDclInflate, "=%02x\n", tree[pos] & 0xffff);
+	return tree[pos] & 0xFFFF;
+}
+
+#define DCL_ASCII_MODE 1
+
+int DecompressorDCL::unpackDCL(byte* dest) {
+	int mode, length_param, value;
+	uint32 val_distance, val_length;
+
+	mode = getByteLSB();
+	length_param = getByteLSB();
+
+	if (mode == DCL_ASCII_MODE) {
+		//warning("DCL-INFLATE: Decompressing ASCII mode (untested)");
+	} else if (mode) {
+		warning("DCL-INFLATE: Error: Encountered mode %02x, expected 00 or 01\n", mode);
+		return -1;
+	}
+
+	if (length_param < 3 || length_param > 6)
+		warning("Unexpected length_param value %d (expected in [3,6])\n", length_param);
+
+	while (_dwWrote < _szUnpacked) {
+		if (getBitsLSB(1)) { // (length,distance) pair
+			value = huffman_lookup(length_tree);
+
+			if (value < 8)
+				val_length = value + 2;
+			else
+				val_length = 8 + (1 << (value - 7)) + getBitsLSB(value - 7);
+
+			debugC(kDebugLevelDclInflate, " | ");
+
+			value = huffman_lookup(distance_tree);
+
+			if (val_length == 2)
+				val_distance = (value << 2) | getBitsLSB(2);
+			else
+				val_distance = (value << length_param) | getBitsLSB(length_param);
+			val_distance ++;
+
+			debugC(kDebugLevelDclInflate, "\nCOPY(%d from %d)\n", val_length, val_distance);
+
+			if (val_length + _dwWrote > _szUnpacked) {
+				warning("DCL-INFLATE Error: Write out of bounds while copying %d bytes", val_length);
+				return SCI_ERROR_DECOMPRESSION_ERROR;
+			}
+
+			if (_dwWrote < val_distance) {
+				warning("DCL-INFLATE Error: Attempt to copy from before beginning of input stream");
+				return SCI_ERROR_DECOMPRESSION_ERROR;
+			}
+
+			while (val_length) {
+				uint32 copy_length = (val_length > val_distance) ? val_distance : val_length;
+				assert(val_distance >= copy_length);
+				uint32 pos = _dwWrote - val_distance;
+				for (uint32 i = 0; i < copy_length; i++)
+					putByte(dest[pos + i]);
+
+				if (Common::isDebugChannelEnabled(kDebugLevelDclInflate)) {
+					for (uint32 i = 0; i < copy_length; i++)
+						debugC(kDebugLevelDclInflate, "\33[32;31m%02x\33[37;37m ", dest[pos + i]);
+					debugC(kDebugLevelDclInflate, "\n");
+				}
+
+				val_length -= copy_length;
+				val_distance += copy_length;
+			}
+
+		} else { // Copy byte verbatim
+			value = (mode == DCL_ASCII_MODE) ? huffman_lookup(ascii_tree) : getByteLSB();
+			putByte(value);
+			debugC(kDebugLevelDclInflate, "\33[32;31m%02x \33[37;37m", value);
+		}
+	}
+
+	return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
+}
+
+#ifdef ENABLE_SCI32
+
+//----------------------------------------------
+// STACpack/LZS decompressor for SCI32
+// Based on Andre Beck's code from http://micky.ibh.de/~beck/stuff/lzs4i4l/
+//----------------------------------------------
+int DecompressorLZS::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
+	init(src, dest, nPacked, nUnpacked);
+	return unpackLZS();
+}
+
+int DecompressorLZS::unpackLZS() {
+	uint16 offs = 0, clen;
+
+	while (!isFinished()) {
+		if (getBitsMSB(1)) { // Compressed bytes follow 
+			if (getBitsMSB(1)) { // Seven bit offset follows
+				offs = getBitsMSB(7);
+				if (!offs) // This is the end marker - a 7 bit offset of zero 
+					break;
+				if (!(clen = getCompLen())) {
+					warning("lzsDecomp: length mismatch");
+					return SCI_ERROR_DECOMPRESSION_ERROR;
+				}
+				copyComp(offs, clen);
+			} else { // Eleven bit offset follows 
+				offs = getBitsMSB(11);
+				if (!(clen = getCompLen())) {
+					warning("lzsDecomp: length mismatch");
+					return SCI_ERROR_DECOMPRESSION_ERROR;
+				}
+				copyComp(offs, clen);
+			}
+		} else // Literal byte follows
+			putByte(getByteMSB());
+	} // end of while ()
+	return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
+}
+
+uint16 DecompressorLZS::getCompLen() {
+	int clen, nibble;
+	// The most probable cases are hardcoded
+	switch (getBitsMSB(2)) {
+	case 0:
+		return 2;
+	case 1:
+		return 3;
+	case 2:
+		return 4;
+	default:
+		switch (getBitsMSB(2)) {
+		case 0:
+			return 5;
+		case 1:
+			return 6;
+		case 2:
+			return 7;
+		default:
+		// Ok, no shortcuts anymore - just get nibbles and add up
+			clen = 8;
+			do {
+				nibble = getBitsMSB(4);
+				clen += nibble;
+			} while (nibble == 0xf);
+			return clen;
+		}
+	}
+}
+
+void DecompressorLZS::copyComp(int offs, int clen) {
+	int hpos = _dwWrote - offs;
+
+	while (clen--)
+		putByte(_dest[hpos++]);
+}
+
+#endif	// #ifdef ENABLE_SCI32
+
+} // End of namespace Sci


Property changes on: scummvm/trunk/engines/sci/decompressor.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: scummvm/trunk/engines/sci/decompressor.h (from rev 40601, scummvm/trunk/engines/sci/scicore/decompressor.h)
===================================================================
--- scummvm/trunk/engines/sci/decompressor.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/decompressor.h	2009-05-15 14:07:45 UTC (rev 40608)
@@ -0,0 +1,201 @@
+/* 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 SCI_SCICORE_DECOMPRESSOR_H
+#define SCI_SCICORE_DECOMPRESSOR_H
+
+#include "common/file.h"
+
+namespace Sci {
+enum ResourceCompression {
+	kCompUnknown = -1,
+	kCompNone = 0,
+	kCompLZW,
+	kCompHuffman,
+	kCompLZW1,			// LZW-like compression used in SCI01 and SCI1
+	kCompLZW1View,		// Comp3 + view Post-processing
+	kCompLZW1Pic,		// Comp3 + pic Post-processing
+#ifdef ENABLE_SCI32
+	kCompSTACpack,	// ? Used in SCI32
+#endif
+	kCompDCL
+};
+//----------------------------------------------
+// Base class for decompressors
+// Simply copies nPacked bytes from src to dest
+//----------------------------------------------
+class Decompressor {
+public:
+	Decompressor() {}
+	virtual ~Decompressor() {}
+
+
+	virtual int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+
+protected:
+	/**
+	 * Initialize decompressor.
+	 * @param src		source stream to read from
+	 * @param dest		destination stream to write to
+	 * @param nPacked	size of packed data
+	 * @param nUnpacket	size of unpacked data
+	 * @return 0 on success, non-zero on error
+	 */
+	virtual void init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);	
+
+	/**
+	 * Get a number of bits from _src stream, starting with the most
+	 * significant unread bit of the current four byte block.
+	 * @param n		number of bits to get
+	 * @return n-bits number
+	 */
+	uint32 getBitsMSB(int n);
+
+	/**
+	 * Get a number of bits from _src stream, starting with the least
+	 * significant unread bit of the current four byte block.
+	 * @param n		number of bits to get
+	 * @return n-bits number
+	 */
+	uint32 getBitsLSB(int n);
+
+	/**
+	 * Get one byte from _src stream.
+	 * @return byte
+	 */
+	byte getByteMSB();
+	byte getByteLSB();
+
+	void fetchBitsMSB();
+	void fetchBitsLSB(); 
+
+	/**
+	 * Write one byte into _dest stream
+	 * @param b byte to put
+	 */
+
+	virtual void putByte(byte b);
+
+	/**
+	 * Returns true if all expected data has been unpacked to _dest
+	 * and there is no more data in _src.
+	 */
+	bool isFinished() {
+		return (_dwWrote == _szUnpacked) && (_dwRead >= _szPacked);
+	}
+
+	uint32 _dwBits;		//!< bits buffer
+	byte _nBits;		//!< number of unread bits in _dwBits
+	uint32 _szPacked;	//!< size of the compressed data
+	uint32 _szUnpacked;	//!< size of the decompressed data
+	uint32 _dwRead;		//!< number of bytes read from _src
+	uint32 _dwWrote;	//!< number of bytes written to _dest
+	Common::ReadStream *_src;
+	byte *_dest;
+};
+
+//----------------------------------------------
+// Huffman decompressor
+//----------------------------------------------
+class DecompressorHuffman : public Decompressor {
+public:
+	int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+
+protected:
+	int16 getc2();
+
+	byte *_nodes;
+};
+
+//----------------------------------------------
+// LZW-like decompressor for SCI01/SCI1
+// TODO: Needs clean-up of post-processing fncs
+//----------------------------------------------
+class DecompressorLZW : public Decompressor {
+public:
+	DecompressorLZW(int nCompression) {
+		_compression = nCompression;
+	}
+	void init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+	int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+
+protected:
+	enum {
+		PIC_OPX_EMBEDDED_VIEW = 1,
+		PIC_OPX_SET_PALETTE = 2,
+		PIC_OP_OPX = 0xfe
+	};
+	// unpacking procedures
+	// TODO: unpackLZW and unpackLZW1 are similar and should be merged
+	int unpackLZW1(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+	int unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+
+	// functions to post-process view and pic resources
+	void reorderPic(byte *src, byte *dest, int dsize);
+	void reorderView(byte *src, byte *dest);
+	void decodeRLE(byte **rledata, byte **pixeldata, byte *outbuffer, int size);
+	int getRLEsize(byte *rledata, int dsize);
+	void buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max);
+	
+	// decompressor data
+	struct Tokenlist {
+		byte data;
+		uint16 next;
+	};
+	uint16 _numbits;
+	uint16 _curtoken, _endtoken;
+	int _compression;
+};
+
+//----------------------------------------------
+// DCL decompressor for SCI1.1
+//----------------------------------------------
+class DecompressorDCL : public Decompressor {
+public:
+	int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+
+protected:
+	int unpackDCL(byte *dest);
+	int huffman_lookup(int *tree);
+};
+
+#ifdef ENABLE_SCI32
+//----------------------------------------------
+// STACpack decompressor for SCI32
+//----------------------------------------------
+class DecompressorLZS : public Decompressor {
+public:
+	int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+protected:
+	int unpackLZS();
+	uint16 getCompLen();
+	void copyComp(int offs, int clen);
+};
+#endif
+
+} // End of namespace Sci
+
+#endif // SCI_SCICORE_DECOMPRESSOR_H
+


Property changes on: scummvm/trunk/engines/sci/decompressor.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/sci/engine/game.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/game.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/game.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -27,7 +27,7 @@
 #include "common/file.h"
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/engine/kernel_types.h"

Modified: scummvm/trunk/engines/sci/engine/grammar.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/grammar.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/grammar.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -29,8 +29,8 @@
 */
 
 #include "sci/tools.h"
-#include "sci/scicore/vocabulary.h"
-#include "sci/scicore/sciconsole.h"
+#include "sci/vocabulary.h"
+#include "sci/engine/sciconsole.h"
 
 namespace Sci {
 

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -31,7 +31,7 @@
 #include "sci/engine/intmap.h"
 #include "sci/engine/gc.h"
 #include "sci/engine/kernel.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/gfx/operations.h"
 #include "sci/engine/kernel_types.h"

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -26,7 +26,7 @@
 #include "common/system.h"
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/gfx/gfx_gui.h"

Modified: scummvm/trunk/engines/sci/engine/kmenu.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmenu.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kmenu.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -24,7 +24,7 @@
  */
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/gfx/gfx_gui.h"

Modified: scummvm/trunk/engines/sci/engine/kmovement.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmovement.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kmovement.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -24,7 +24,7 @@
  */
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 

Modified: scummvm/trunk/engines/sci/engine/kscripts.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -24,7 +24,7 @@
  */
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel_types.h"
 #include "sci/engine/kernel.h"

Modified: scummvm/trunk/engines/sci/engine/kstring.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kstring.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/kstring.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -25,7 +25,7 @@
 
 /* String and parser handling */
 
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "sci/engine/message.h"
 #include "sci/engine/kernel.h"

Modified: scummvm/trunk/engines/sci/engine/message.h
===================================================================
--- scummvm/trunk/engines/sci/engine/message.h	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/message.h	2009-05-15 14:07:45 UTC (rev 40608)
@@ -26,7 +26,7 @@
 #ifndef SCI_ENGINE_MESSAGE_H
 #define SCI_ENGINE_MESSAGE_H
 
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "common/stack.h"
 
 namespace Sci {

Copied: scummvm/trunk/engines/sci/engine/sciconsole.cpp (from rev 40601, scummvm/trunk/engines/sci/engine/scriptconsole.cpp)
===================================================================
--- scummvm/trunk/engines/sci/engine/sciconsole.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/engine/sciconsole.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -0,0 +1,956 @@
+/* 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$
+ *
+ */
+
+/* Second half of the console implementation: VM dependent stuff */
+/* Remember, it doesn't have to be fast. */
+
+#include "sci/engine/state.h"
+#include "sci/engine/sciconsole.h"
+
+#include "sci/sci.h"	// For _console only
+#include "sci/console.h"	// For _console only
+
+namespace Sci {
+
+#ifdef SCI_CONSOLE
+
+// console commands
+
+static int c_list(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // lists various types of things
+static int c_man(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // 'manual page'
+static int c_set(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // sets an int variable
+static int c_print(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // prints a variable
+static int c_size(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // displays the size of a resource
+static int c_dump(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // gives a hex dump of a resource
+//static int c_objinfo(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // shows some info about one class
+//static int c_objmethods(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Disassembles all methods of a class
+static int c_hexgrep(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Searches a string in one resource or resource class
+static int c_dissectscript(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Splits a script into objects and explains them
+
+struct cmd_mm_entry_t {
+	const char *name;
+	const char *description;
+}; // All later structures must "extend" this
+
+// Simple info page
+struct cmd_page_t : public cmd_mm_entry_t {
+};
+
+struct cmd_command_t : public cmd_mm_entry_t {
+	ConCommand command;
+	const char *param;
+};
+
+struct cmd_var_t : public cmd_mm_entry_t {
+	union {
+		int *intp;
+		char **charpp;
+		reg_t *reg;
+	} var;
+};
+
+
+typedef void printfunc_t(cmd_mm_entry_t *data, int full);
+
+struct cmd_mm_struct_t {
+	const char *name;
+	void *data; // cmd_mm_entry_t
+	size_t size_per_entry;
+	printfunc_t *print;
+	int entries; // Number of used entries
+	int allocated;  // Number of allocated entries
+};
+
+#define CMD_MM_ENTRIES 3 // command console memory and manual page manager
+#define CMD_MM_DEFAULT_ALLOC 4 // Number of table entries to allocate per default
+
+#define CMD_MM_CMD 0 // Commands
+#define CMD_MM_VAR 1 // Variables
+#define CMD_MM_DOC 2 // Misc. documentation
+
+static const char *cmd_mm_names[CMD_MM_ENTRIES] = {
+	"Commands",
+	"Variables",
+	"Documentation"
+};
+static size_t cmd_mm_sizes_per_entry[CMD_MM_ENTRIES] = {
+	sizeof(cmd_command_t),
+	sizeof(cmd_var_t),
+	sizeof(cmd_page_t)
+};
+
+static void _cmd_print_command(cmd_mm_entry_t *data, int full);
+static void _cmd_print_var(cmd_mm_entry_t *data, int full);
+static void _cmd_print_page(cmd_mm_entry_t *data, int full);
+
+static printfunc_t *cmd_mm_printers[CMD_MM_ENTRIES] = {
+	_cmd_print_command,
+	_cmd_print_var,
+	_cmd_print_page
+};
+
+static cmd_mm_struct_t cmd_mm[CMD_MM_ENTRIES];
+
+static int _cmd_initialized = 0;
+static int _lists_need_sorting = 0;
+
+void _cmd_exit() {
+	int t;
+
+	for (t = 0; t < CMD_MM_ENTRIES; t++)
+		free(cmd_mm[t].data);
+}
+
+static cmd_mm_entry_t *cmd_mm_find(const char *name, int type) {
+	int i;
+
+	for (i = 0; i < cmd_mm[type].entries; i++) {
+		cmd_mm_entry_t *tmp = (cmd_mm_entry_t *)((byte *)cmd_mm[type].data + i * cmd_mm[type].size_per_entry);
+		if (!strcmp(tmp->name, name))
+			return tmp;
+	}
+
+	return NULL;
+}
+
+static int _cmd_mm_comp(const void *a, const void *b) {
+	return strcmp(((cmd_mm_entry_t *) a)->name, ((cmd_mm_entry_t *) b)->name);
+}
+
+void con_sort_all() {
+	int i;
+
+	for (i = 0; i < CMD_MM_ENTRIES; i++)
+		if (cmd_mm[i].entries && _lists_need_sorting & (1 << i))
+			qsort(cmd_mm[i].data, cmd_mm[i].entries, cmd_mm[i].size_per_entry, _cmd_mm_comp);
+
+	_lists_need_sorting = 0;
+}
+
+void con_init() {
+	if (!_cmd_initialized) {
+		int i;
+
+		_cmd_initialized = 1;
+		for (i = 0; i < CMD_MM_ENTRIES; i++) {
+			cmd_mm[i].name = cmd_mm_names[i];
+			cmd_mm[i].size_per_entry = cmd_mm_sizes_per_entry[i];
+			cmd_mm[i].entries = 0;
+			cmd_mm[i].allocated = CMD_MM_DEFAULT_ALLOC;
+			cmd_mm[i].data = calloc(cmd_mm[i].allocated, cmd_mm[i].size_per_entry);
+			cmd_mm[i].print = cmd_mm_printers[i];
+		}
+
+		atexit(_cmd_exit);
+
+		// Hook up some commands
+		con_hook_command(&c_list, "list", "s*", "Lists various things (try 'list')");
+		con_hook_command(&c_man, "man", "s", "Gives a short description of something");
+		con_hook_command(&c_print, "print", "s", "Prints an int variable");
+		con_hook_command(&c_set, "set", "si", "Sets an int variable");
+		con_hook_command(&c_size, "size", "si", "Displays the size of a resource");
+		con_hook_command(&c_dump, "dump", "si", "HexDumps a resource");
+		con_hook_command(&c_hexgrep, "hexgrep", "shh*", "Searches some resources for a\n"
+		                 "  particular sequence of bytes, re-\n  presented as hexadecimal numbers.\n\n"
+		                 "EXAMPLES:\n  hexgrep script e8 03 c8 00\n  hexgrep pic.042 fe");
+		con_hook_command(&c_dissectscript, "dissectscript", "i", "Examines a script.");
+
+		con_hook_page("addresses", "Passing address parameters\n\n"
+		              "  Address parameters may be passed in one of\n"
+		              "  three forms:\n"
+		              "  - ssss:oooo -- where 'ssss' denotes a\n"
+		              "    segment and 'oooo' an offset. Example:\n"
+		              "    \"a:c5\" would address something in seg-\n"
+		              "    ment 0xa at offset 0xc5.\n"
+		              "  - &scr:oooo -- where 'scr' is a script number\n"
+		              "    and oooo an offset within that script; will\n"
+		              "    fail if the script is not currently loaded\n"
+		              "  - $REG -- where 'REG' is one of 'PC', 'ACC',\n"
+		              "    'PREV' or 'OBJ': References the address\n"
+		              "    indicated by the register of this name.\n"
+		              "  - $REG+n (or -n) -- Like $REG, but modifies\n"
+		              "    the offset part by a specific amount (which\n"
+		              "    is specified in hexadecimal).\n"
+		              "  - ?obj -- Looks up an object with the specified\n"
+		              "    name, uses its address. This will abort if\n"
+		              "    the object name is ambiguous; in that case,\n"
+		              "    a list of addresses and indices is provided.\n"
+		              "    ?obj.idx may be used to disambiguate 'obj'\n"
+		              "    by the index 'idx'.\n");
+	}
+}
+
+static inline int clone_is_used(CloneTable *t, int idx) {
+	return ENTRY_IS_VALID(t, idx);
+}
+
+int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on success
+	int rel_offsetting = 0;
+	const char *offsetting = NULL;
+	// Non-NULL: Parse end of string for relative offsets
+	char *endptr;
+
+	if (!s) {
+		sciprintf("Addresses can only be parsed if a global state is present");
+		return 1; // Requires a valid state
+	}
+
+	if (*str == '$') { // Register
+		rel_offsetting = 1;
+
+		if (!scumm_strnicmp(str + 1, "PC", 2)) {
+			*dest = s->_executionStack[s->execution_stack_pos].addr.pc;
+			offsetting = str + 3;
+		} else if (!scumm_strnicmp(str + 1, "P", 1)) {
+			*dest = s->_executionStack[s->execution_stack_pos].addr.pc;
+			offsetting = str + 2;
+		} else if (!scumm_strnicmp(str + 1, "PREV", 4)) {
+			*dest = s->r_prev;
+			offsetting = str + 5;
+		} else if (!scumm_strnicmp(str + 1, "ACC", 3)) {
+			*dest = s->r_acc;
+			offsetting = str + 4;
+		} else if (!scumm_strnicmp(str + 1, "A", 1)) {
+			*dest = s->r_acc;
+			offsetting = str + 2;
+		} else if (!scumm_strnicmp(str + 1, "OBJ", 3)) {
+			*dest = s->_executionStack[s->execution_stack_pos].objp;
+			offsetting = str + 4;
+		} else if (!scumm_strnicmp(str + 1, "O", 1)) {
+			*dest = s->_executionStack[s->execution_stack_pos].objp;
+			offsetting = str + 2;
+		} else
+			return 1; // No matching register
+
+		if (!*offsetting)
+			offsetting = NULL;
+		else if (*offsetting != '+' && *offsetting != '-')
+			return 1;
+	} else if (*str == '&') {
+		int script_nr;
+		// Look up by script ID
+		char *colon = (char *)strchr(str, ':');
+
+		if (!colon)
+			return 1;
+		*colon = 0;
+		offsetting = colon + 1;
+
+		script_nr = strtol(str + 1, &endptr, 10);
+
+		if (*endptr)
+			return 1;
+
+		dest->segment = s->seg_manager->segGet(script_nr);
+
+		if (!dest->segment) {
+			return 1;
+		}
+	} else if (*str == '?') {
+		int index = -1;
+		int times_found = 0;
+		char *tmp;
+		const char *str_objname;
+		char *str_suffix;
+		char suffchar = 0;
+		uint i;
+		// Parse obj by name
+
+		tmp = (char *)strchr(str, '+');
+		str_suffix = (char *)strchr(str, '-');
+		if (tmp < str_suffix)
+			str_suffix = tmp;
+		if (str_suffix) {
+			suffchar = (*str_suffix);
+			*str_suffix = 0;
+		}
+
+		tmp = (char *)strchr(str, '.');
+
+		if (tmp) {
+			*tmp = 0;
+			index = strtol(tmp + 1, &endptr, 16);
+			if (*endptr)
+				return -1;
+		}
+
+		str_objname = str + 1;
+
+		// Now all values are available; iterate over all objects.
+		for (i = 0; i < s->seg_manager->_heap.size(); i++) {
+			MemObject *mobj = s->seg_manager->_heap[i];
+			int idx = 0;
+			int max_index = 0;
+
+			if (mobj) {
+				if (mobj->getType() == MEM_OBJ_SCRIPT)
+					max_index = (*(Script *)mobj)._objects.size();
+				else if (mobj->getType() == MEM_OBJ_CLONES)
+					max_index = (*(CloneTable *)mobj)._table.size();
+			}
+
+			while (idx < max_index) {
+				int valid = 1;
+				Object *obj = NULL;
+				reg_t objpos;
+				objpos.offset = 0;
+				objpos.segment = i;
+
+				if (mobj->getType() == MEM_OBJ_SCRIPT) {
+					obj = &(*(Script *)mobj)._objects[idx];
+					objpos.offset = obj->pos.offset;
+				} else if (mobj->getType() == MEM_OBJ_CLONES) {
+					obj = &((*(CloneTable *)mobj)._table[idx]);
+					objpos.offset = idx;
+					valid = clone_is_used((CloneTable *)mobj, idx);
+				}
+
+				if (valid) {
+					char *objname = (char *)obj->base
+					                + obj->_variables[SCRIPT_NAME_SELECTOR].offset;
+					if (!strcmp(objname, str_objname)) {
+						// Found a match!
+						if (index < 0 ||
+						        times_found == index)
+							*dest = objpos;
+						else if (times_found < 0 && index) {
+							if (index == 1) {
+								// First time we realized the ambiguity
+								sciprintf("Ambiguous:\n");
+								sciprintf("  %3x: ["PREG"] %s\n", 0, PRINT_REG(*dest), str_objname);
+							}
+							sciprintf("  %3x: ["PREG"] %s\n", index, PRINT_REG(objpos), str_objname);
+						}
+						++times_found;
+					}
+				}
+				++idx;
+			}
+
+		}
+
+		if (!times_found)
+			return 1;
+
+		if (times_found > 1 && index < 0) {
+			sciprintf("Ambiguous: Aborting.\n");
+			return 1; // Ambiguous
+		}
+
+		if (times_found <= index)
+			return 1; // Not found
+
+		offsetting = str_suffix;
+		if (offsetting)
+			*str_suffix = suffchar;
+		rel_offsetting = 1;
+	} else {
+		char *colon = (char *)strchr(str, ':');
+
+		if (!colon) {
+			offsetting = str;
+			dest->segment = 0;
+		} else {
+			*colon = 0;
+			offsetting = colon + 1;
+
+			dest->segment = strtol(str, &endptr, 16);
+			if (*endptr)
+				return 1;
+		}
+	}
+	if (offsetting) {
+		int val = strtol(offsetting, &endptr, 16);
+
+		if (rel_offsetting)
+			dest->offset += val;
+		else
+			dest->offset = val;
+
+		if (*endptr)
+			return 1;
+	}
+
+	return 0;
+}
+
+void con_parse(EngineState *s, const char *command) {
+	char *cmd = (command && command[0]) ? (char *)strdup(command) : (char *)strdup(" ");
+	char *_cmd = cmd;
+	int pos = 0;
+
+	if (!_cmd_initialized)
+		con_init();
+
+	bool done = false;		// are we done yet?
+	while (!done) {
+		cmd_command_t *command_todo;
+		bool quote = false;		// quoting?
+		bool cdone = false;		// Done with the current command?
+		bool onvar = true;		// currently working on a variable?
+		cdone = 0;
+		pos = 0;
+
+		Common::Array<cmd_param_t> cmdParams;
+
+		while (*cmd == ' ')
+			cmd++;
+
+		while (!cdone) {
+			switch (cmd[pos]) {
+			case 0:
+				cdone = done = true;
+			case ';':
+				if (!quote)
+					cdone = true;
+			case ' ':
+				if (!quote) {
+					cmd[pos] = 0;
+					onvar = false;
+				}
+				break;
+			case '\\':		// don't check next char for special meaning
+				memmove(cmd + pos, cmd + pos + 1, strlen(cmd + pos) - 1);
+				break;
+			case '"':
+				quote = !quote;
+				memmove(cmd + pos, cmd + pos + 1, strlen(cmd + pos));
+				pos--;
+				break;
+			default:
+				if (!onvar) {
+					onvar = true;
+					cmd_param_t tmp;
+					tmp.str = cmd + pos;
+					cmdParams.push_back(tmp);
+				}
+				break;
+			}
+			pos++;
+		}
+
+		if (quote)
+			sciprintf("unbalanced quotes\n");
+		else if (strcmp(cmd, "") != 0) {
+			command_todo = (cmd_command_t *) cmd_mm_find(cmd, CMD_MM_CMD);
+			if (!command_todo)
+				sciprintf("%s: not found\n", cmd);
+			else {
+				uint minparams;
+				int need_state = 0;
+
+				const char *paramt = command_todo->param;	// parameter types
+				if (command_todo->param[0] == '!') {
+					need_state = 1;
+					paramt++;
+				}
+
+				minparams = strlen(paramt);
+
+				if ((paramt[0] != 0) && (paramt[strlen(paramt) - 1] == '*'))
+					minparams -= 2;
+
+				if (cmdParams.size() < minparams)
+					sciprintf("%s: needs more than %d parameters\n", cmd, cmdParams.size());
+
+				else if ((cmdParams.size() > strlen(paramt)) && ((strlen(paramt) == 0) || paramt[strlen(paramt) - 1] != '*'))
+					sciprintf("%s: too many parameters", cmd);
+				else {
+					int do_execute = !need_state || s; // /me wants an implication arrow
+					char paramtype;
+					int paramtypepos = 0;
+					char *endptr;
+
+					for (uint i = 0; i < cmdParams.size(); i++) {
+						paramtype = paramt[paramtypepos];
+
+						if ((paramt[paramtypepos + 1]) && (paramt[paramtypepos + 1] != '*'))
+							paramtypepos++;
+						// seek next param type unless end of string or '*						   '
+
+						switch (paramtype) {
+							// Now turn the parameters into variables of the appropriate types,
+							// unless they're strings, and store them into the cmdParams array
+
+						case 'a': {
+							const char *oldname = cmdParams[i].str;
+							if (parse_reg_t(s, oldname, &(cmdParams[i].reg))) {
+								sciprintf("%s: '%s' is not an address or object\n", cmd, oldname);
+								do_execute = 0;
+							}
+							break;
+						}
+
+						case 'i': {
+							const char *orgstr = cmdParams[i].str;
+
+							cmdParams[i].val = strtol(orgstr, &endptr, 0);
+							if (*endptr != '\0') {
+								do_execute = 0;
+								sciprintf("%s: '%s' is not an int\n", cmd, orgstr);
+							}
+						}
+						break;
+
+						case 'h': {
+							const char *orgstr = cmdParams[i].str;
+
+							cmdParams[i].val = strtol(orgstr, &endptr, 16);
+
+							if (*endptr != '\0') {
+								do_execute = 0;
+								sciprintf("%s: '%s' is not a hex number\n", cmd, orgstr);
+							}
+
+							cmdParams[i].val &= 0xff;	// Clip hex numbers to 0x00 ... 0xff
+						}
+						break;
+
+						case 's':
+							break;
+
+						default:
+							warning("Internal error: Heap corruption or prior assertion failed: "
+							        "Unknown parameter type '%c' for function", paramtype);
+
+						}
+					}
+
+					if (do_execute) {
+						command_todo->command(s, cmdParams);
+					} else
+						fprintf(stderr, "Skipping command...\n");
+				}
+			}
+		}
+		cmd += pos;
+	}
+
+	free(_cmd);
+}
+
+/* (unused)
+static cmd_mm_entry_t *con_iterate_entry(int ID, int *counter) {
+	byte *retval;
+	con_init();
+
+	if (*counter >= cmd_mm[ID].entries)
+		return 0;
+	retval = cmd_mm[ID].data;
+	retval += (*counter) * cmd_mm[ID].size_per_entry;
+
+	(*counter)++;
+
+	return (cmd_mm_entry_t *)retval;
+}*/
+
+static cmd_mm_entry_t *con_alloc_page_entry(int ID) {
+	int entry;
+
+	con_init();
+
+	if (cmd_mm[ID].entries >= cmd_mm[ID].allocated) {
+		int nextsize = cmd_mm[ID].allocated;
+		if (nextsize >= 64)
+			nextsize += 16;
+		else
+			nextsize <<= 1;
+
+		cmd_mm[ID].data = realloc(cmd_mm[ID].data, nextsize * cmd_mm[ID].size_per_entry);
+		cmd_mm[ID].allocated = nextsize;
+	}
+
+	_lists_need_sorting |= (1 << ID);
+
+	entry = cmd_mm[ID].entries++;
+	return (cmd_mm_entry_t *)(((byte *)cmd_mm[ID].data) + entry * cmd_mm[ID].size_per_entry);
+}
+
+int con_hook_page(const char *name, const char *body) {
+	cmd_page_t *page = (cmd_page_t *)con_alloc_page_entry(CMD_MM_DOC);
+
+	page->name = name;
+	page->description = body;
+
+	return 0;
+}
+
+int con_hook_command(ConCommand command, const char *name, const char *param, const char *description) {
+	cmd_command_t *cmd = NULL;
+	unsigned int i;
+
+	if (NULL == name) {
+		sciprintf("console.c: con_hook_command(): NULL passed for name\n");
+		return -1;
+	}
+
+	if (command == NULL)
+		return 1;
+
+	if (param == NULL)
+		param = "";
+
+	if (description == NULL)
+		description = "";
+
+	i = 0;
+	while (param[i] != 0) {
+		switch (param[i]) {
+		case '*':
+			if (param[i + 1] != 0)
+				return 1;
+			if (i == 0)
+				return 1;
+		case 'h':
+		case '!':
+		case 'i':
+		case 'a':
+		case 's':
+		case 'r':
+			break;
+		default:
+			return 1;
+		}
+		i++;
+	}
+	cmd = (cmd_command_t *)con_alloc_page_entry(CMD_MM_CMD);
+
+	cmd->command = command;
+	cmd->name = name;
+	cmd->param = param;
+	cmd->description = description;
+
+	((SciEngine *)g_engine)->_console->con_hook_command(command, name, param, description);
+
+	return 0;
+}
+
+int con_hook_int(int *pointer, const char *name, const char *description) {
+	cmd_var_t *var;
+
+	if (pointer == NULL)
+		return 1;
+
+	if (description == NULL)
+		description = "";
+
+	var = (cmd_var_t *) con_alloc_page_entry(CMD_MM_VAR);
+
+	var->var.intp = pointer;
+	var->name = name;
+	var->description = description;
+
+	return 0;
+}
+
+// Console commands and support functions
+
+static ResourceType parseResourceType(const char *resid) {
+	// Gets the resource number of a resource string, or returns -1
+	ResourceType res = kResourceTypeInvalid;
+
+	for (int i = 0; i < kResourceTypeInvalid; i++)
+		if (strcmp(getResourceTypeName((ResourceType)i), resid) == 0)
+			res = (ResourceType)i;
+
+	return res;
+}
+
+static void _cmd_print_command(cmd_mm_entry_t *data, int full) {
+	const char *paramseeker = ((cmd_command_t *)data)->param;
+
+	if (full) {
+		sciprintf("SYNOPSIS\n\n  %s (%s) ", data->name, paramseeker);
+
+		while (*paramseeker) {
+			switch (*paramseeker) {
+			case '!':
+				break;
+			case 'i':
+				sciprintf(" (int)");
+				break;
+			case 'a':
+				sciprintf(" (addr)");
+				break;
+			case 's':
+				sciprintf(" (string)");
+				break;
+			case 'h':
+				sciprintf(" (hexbyte)");
+				break;
+			case '*':
+				sciprintf("*");
+				break;
+			default:
+				sciprintf(" (Unknown(%c))", *paramseeker);
+			}
+			paramseeker++;
+		}
+
+		sciprintf("\n\nDESCRIPTION\n\n  %s", data->description);
+	} else
+		sciprintf(" %s", data->name);
+}
+
+static void _cmd_print_var(cmd_mm_entry_t *data, int full) {
+	cmd_var_t *var = (cmd_var_t *) data;
+	if (full)
+		sciprintf("VALUE\n\n");
+	sciprintf("  %s = %d\n", var->name, *(var->var.intp));
+
+	if (full)
+		sciprintf("\n\nDESCRIPTION\n\n  %s", data->description);
+}
+
+static void _cmd_print_page(cmd_mm_entry_t *data, int full) {
+	if (full)
+		sciprintf("\n\nDESCRIPTION\n\n  %s\n", data->description);
+	else
+		sciprintf("%s\n", data->name);
+}
+
+static int c_list(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	if (_lists_need_sorting)
+		con_sort_all();
+
+	if (cmdParams.size() == 0) {
+		sciprintf("usage: list [type]\nwhere type is one of the following:\n"
+		          "cmds       - lists all commands\n"
+		          "vars       - lists all variables\n"
+		          "docs       - lists all misc. documentation\n"
+		          "\n"
+		          "restypes   - lists all resource types\n"
+		          "[resource] - lists all [resource]s");
+	} else if (cmdParams.size() == 1) {
+		const char *mm_subsects[3] = {"cmds", "vars", "docs"};
+		int mm_found = -1;
+		int i;
+
+		for (i = 0; i < 3; i++)
+			if (mm_subsects[i] && !strcmp(mm_subsects[i], cmdParams[0].str))
+				mm_found = i;
+
+		if (mm_found >= 0)
+			for (i = 0; i < cmd_mm[mm_found].entries; i++)
+				cmd_mm[mm_found].print((cmd_mm_entry_t *)(((byte *)cmd_mm[mm_found].data) + i * cmd_mm[mm_found].size_per_entry), 0);
+		else {
+			if (!s) {
+				sciprintf("You need a state to do that!\n");
+				return 1;
+			}
+
+			else if (strcmp("restypes", cmdParams[0].str) == 0) {
+				for (i = 0; i < kResourceTypeInvalid; i++)
+					sciprintf("%s\n", getResourceTypeName((ResourceType)i));
+			} else {
+				ResourceType res = parseResourceType(cmdParams[0].str);
+				if (res == kResourceTypeInvalid)
+					sciprintf("Unknown resource type: '%s'\n", cmdParams[0].str);
+				else {
+					for (i = 0; i < sci_max_resource_nr[s->resmgr->_sciVersion]; i++)
+						if (s->resmgr->testResource(res, i))
+							sciprintf("%s.%03d\n", getResourceTypeName((ResourceType)res), i);
+				}
+			}
+		}
+	} else
+		sciprintf("list can only be used with one argument");
+	return 0;
+}
+
+static int c_man(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	int section = 0;
+	uint i;
+	Common::String name = cmdParams[0].str;
+	const char *c = strchr(name.c_str(), '.');
+	cmd_mm_entry_t *entry = 0;
+
+	if (c) {
+		section = atoi(c + 1);
+		name = Common::String(name.begin(), c);
+	}
+
+	if (section < 0 || section >= CMD_MM_ENTRIES) {
+		sciprintf("Invalid section %d\n", section);
+		return 1;
+	}
+
+	sciprintf("section:%d\n", section);
+	if (section)
+		entry = cmd_mm_find(name.c_str(), section - 1);
+	else
+		for (i = 0; i < CMD_MM_ENTRIES && !section; i++) {
+			if ((entry = cmd_mm_find(name.c_str(), i)))
+				section = i + 1;
+		}
+
+	if (!entry) {
+		sciprintf("No manual entry\n");
+		return 1;
+	}
+
+	sciprintf("-- %s: %s.%d\n", cmd_mm[section - 1].name, name.c_str(), section);
+	cmd_mm[section - 1].print(entry, 1);
+
+	return 0;
+}
+
+static int c_set(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	cmd_var_t *var = (cmd_var_t *)cmd_mm_find(cmdParams[0].str, CMD_MM_VAR);
+
+	if (var)
+		*(var->var.intp) = cmdParams[1].val;
+
+	return 0;
+}
+
+static int c_print(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	cmd_var_t *var = (cmd_var_t *)cmd_mm_find(cmdParams[0].str, CMD_MM_VAR);
+
+	if (var)
+		sciprintf("%d", *(var->var.intp));
+	else
+		sciprintf("Not defined.");
+
+	return 0;
+}
+
+static int c_size(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	ResourceType res = parseResourceType(cmdParams[0].str);
+	if (res == kResourceTypeInvalid)
+		sciprintf("Resource type '%s' is not valid\n", cmdParams[0].str);
+	else {
+		Resource *resource = s->resmgr->findResource(res, cmdParams[1].val, 0);
+		if (resource) {
+			sciprintf("Size: %d\n", resource->size);
+		} else
+			sciprintf("Resource %s.%03d not found\n", cmdParams[0].str, cmdParams[1].val);
+	}
+
+	return 0;
+}
+
+static int c_dump(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	ResourceType res = parseResourceType(cmdParams[0].str);
+
+	if (res == kResourceTypeInvalid)
+		sciprintf("Resource type '%s' is not valid\n", cmdParams[0].str);
+	else {
+		Resource *resource = s->resmgr->findResource(res, cmdParams[1].val, 0);
+		if (resource)
+			Common::hexdump(resource->data, resource->size, 16, 0);
+		else
+			sciprintf("Resource %s.%03d not found\n", cmdParams[0].str, cmdParams[1].val);
+	}
+
+	return 0;
+}
+
+static int c_hexgrep(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	int i, seeklen, resnr, resmax;
+	unsigned char *seekstr = NULL;
+	Resource *script = NULL;
+	char *dot = (char *)strchr(cmdParams[0].str, '.');
+	ResourceType restype;
+
+	if (NULL == s) {
+		fprintf(stderr, "console.c: c_hexgrep(): NULL passed for s\r\n");
+		return(-1);
+	}
+
+	seeklen = cmdParams.size() - 1;
+	seekstr = (unsigned char *)malloc(seeklen);
+
+	if (NULL == seekstr) {
+		fprintf(stderr, "console.c: c_hexgrep(): malloc failed for seekstr\r\n");
+		return(-1);
+	}
+
+	for (i = 0; i < seeklen; i++)
+		seekstr[i] = (byte)cmdParams[i + 1].val;
+
+	if (dot) {
+		*dot = 0;
+		resmax = resnr = atoi(dot + 1);
+	} else {
+		resnr = 0;
+		resmax = 999;
+	}
+
+	restype = parseResourceType(cmdParams[0].str);
+	if (restype == kResourceTypeInvalid) {
+		sciprintf("Unknown resource type \"%s\"\n", cmdParams[0].str);
+		free(seekstr);
+		return 1;
+	}
+
+	for (; resnr <= resmax; resnr++)
+		if ((script = s->resmgr->findResource(restype, resnr, 0))) {
+			unsigned int seeker = 0, seekerold = 0;
+			int comppos = 0;
+			int output_script_name = 0;
+
+			while (seeker < script->size) {
+				if (script->data[seeker] == seekstr[comppos]) {
+					if (comppos == 0)
+						seekerold = seeker;
+
+					comppos++;
+
+					if (comppos == seeklen) {
+						comppos = 0;
+						seeker = seekerold + 1;
+
+						if (!output_script_name) {
+							sciprintf("\nIn %s.%03d:\n", getResourceTypeName((ResourceType)restype), resnr);
+							output_script_name = 1;
+						}
+						sciprintf("   0x%04x\n", seekerold);
+					}
+				} else
+					comppos = 0;
+
+				seeker++;
+			}
+		}
+
+	free(seekstr);
+
+	return 0;
+}
+
+static int c_dissectscript(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
+	if (NULL == s) {
+		sciprintf("console.c: c_dissectscript(): NULL passed for parameter s\n");
+		return -1;
+	}
+
+	script_dissect(s->resmgr, cmdParams[0].val, s->_selectorNames);
+	return 0;
+}
+
+#endif // SCI_CONSOLE
+
+} // End of namespace Sci


Property changes on: scummvm/trunk/engines/sci/engine/sciconsole.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: scummvm/trunk/engines/sci/engine/sciconsole.h (from rev 40601, scummvm/trunk/engines/sci/scicore/sciconsole.h)
===================================================================
--- scummvm/trunk/engines/sci/engine/sciconsole.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/engine/sciconsole.h	2009-05-15 14:07:45 UTC (rev 40608)
@@ -0,0 +1,130 @@
+/* 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$
+ *
+ */
+
+/* Header file for the SCI console.
+** Please note that the console does not use the priority field; the console
+** should therefore be drawn after everything else has been drawn (with the
+** possible exception of the mouse pointer).
+*/
+
+#ifndef SCI_SCICORE_SCICONSOLE_H
+#define SCI_SCICORE_SCICONSOLE_H
+
+#include "common/scummsys.h"
+
+#include "sci/tools.h"
+#include "sci/engine/state.h"
+#include "sci/engine/vm_types.h"
+
+#define SCI_CONSOLE
+
+namespace Sci {
+
+struct gfx_pixmap_t;
+
+union cmd_param_t {
+	int32 val;
+	const char *str;
+	reg_t reg;
+};
+
+
+typedef int (*ConCommand)(EngineState *s, const Common::Array<cmd_param_t> &cmdParams);
+
+/*** FUNCTION DEFINITIONS ***/
+
+void con_init();
+/* Initializes the command parser
+** Parameters: (void)
+** Returns   : (void)
+** This function will initialize hook up a few commands to the parser.
+** It must be called before cmdParse() is used.
+*/
+
+
+void con_parse(EngineState *s, const char *command);
+/* Parses a command and summons appropriate facilities to handle it
+** Parameters: (EngineState *) s: The EngineState to use
+**             command: The command to execute
+** Returns   : (void)
+*/
+
+
+int con_hook_command(ConCommand command, const char *name, const char *param, const char *description);
+/* Adds a command to the parser's command list
+** Parameters: command: The command to add
+**             name: The command's name
+**             param: A description of the parameters it takes
+**             description: A short description of what it does
+** Returns   : 0 if successful, 1 if appending failed because
+**             of an incorrect *param string, 'command'==0, or
+**             'name' already being in use.
+** A valid param string is either empty (no parameters allowed)
+** or contains one of the following tokens:
+**   ! Special token: EngineState* must be set for this function to be called
+**   i (an int)
+**   s (a 'string' (char *))
+**   h (a byte, described in hexadecimal digits)
+**   a (a heap address, register or object name)
+**   r (any register value)
+**   x* (an arbitrary (possibly 0) number of 'x' tokens)
+** The '*' token may only be used as the last token of the list.
+** Another way to specify optional parameters is by means of the
+** '-opt:t' notation, which allows an optional parameter of type 't'
+** to be specified as 'opt:<value>' when calling. See also the
+** con_hasopt() and con_getopt() calls.
+**
+** Please note that the 'h' type does accept hexadecimal numbers greater
+** than 0xff and less than 0x00, but clips them to this range.
+**
+** Example: "isi*" would define the function to take an int, a
+** string, and an arbitrary number of ints as parameters (in that sequence).
+**
+** When the function is called, it can retrieve its parameters from cmd_params;
+** the actual number of parameters is stored in cmd_paramlength.
+** It is allowed to modify the char*s from a cmd_params[] element, as long
+** as no element beyond strlen(cmd_params[x].str)+1 is accessed.
+*/
+
+int con_hook_page(const char *topic, const char *body);
+/* Hooks a general information page to the manual page system
+** Parameters: (const char *) topic: The topic name
+**             (const char *) body: The text body to assign to the topic
+** Returns   : (int) 0 on success
+*/
+
+int con_hook_int(int *pointer, const char *name, const char *description);
+/* Adds an int to the list of modifyable ints.
+** Parameters: pointer: Pointer to the int to add to the list
+**             name: Name for this value
+**             description: A short description for the value
+** Returns   : 0 on success, 1 if either value has already been added
+**             or if name is already being used for a different value.
+** The internal list of int references is used by some of the basic commands.
+*/
+
+} // End of namespace Sci
+
+#endif // SCI_SCICORE_SCICONSOLE_H


Property changes on: scummvm/trunk/engines/sci/engine/sciconsole.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -24,7 +24,7 @@
  */
 
 #include "sci/sci.h"
-#include "sci/scicore/resource.h"
+#include "sci/resource.h"
 #include "sci/engine/state.h"
 #include "common/util.h"
 

Deleted: scummvm/trunk/engines/sci/engine/scriptconsole.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptconsole.cpp	2009-05-15 13:52:22 UTC (rev 40607)
+++ scummvm/trunk/engines/sci/engine/scriptconsole.cpp	2009-05-15 14:07:45 UTC (rev 40608)
@@ -1,956 +0,0 @@
-/* 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$
- *
- */
-
-/* Second half of the console implementation: VM dependent stuff */
-/* Remember, it doesn't have to be fast. */
-
-#include "sci/engine/state.h"
-#include "sci/scicore/sciconsole.h"
-
-#include "sci/sci.h"	// For _console only
-#include "sci/console.h"	// For _console only
-
-namespace Sci {
-
-#ifdef SCI_CONSOLE
-
-// console commands
-
-static int c_list(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // lists various types of things
-static int c_man(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // 'manual page'
-static int c_set(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // sets an int variable
-static int c_print(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // prints a variable
-static int c_size(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // displays the size of a resource
-static int c_dump(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // gives a hex dump of a resource
-//static int c_objinfo(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // shows some info about one class
-//static int c_objmethods(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Disassembles all methods of a class
-static int c_hexgrep(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Searches a string in one resource or resource class
-static int c_dissectscript(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); // Splits a script into objects and explains them
-
-struct cmd_mm_entry_t {
-	const char *name;
-	const char *description;
-}; // All later structures must "extend" this
-
-// Simple info page
-struct cmd_page_t : public cmd_mm_entry_t {
-};
-
-struct cmd_command_t : public cmd_mm_entry_t {
-	ConCommand command;
-	const char *param;
-};
-
-struct cmd_var_t : public cmd_mm_entry_t {
-	union {
-		int *intp;
-		char **charpp;
-		reg_t *reg;
-	} var;
-};
-
-
-typedef void printfunc_t(cmd_mm_entry_t *data, int full);
-
-struct cmd_mm_struct_t {
-	const char *name;
-	void *data; // cmd_mm_entry_t
-	size_t size_per_entry;
-	printfunc_t *print;
-	int entries; // Number of used entries
-	int allocated;  // Number of allocated entries
-};
-
-#define CMD_MM_ENTRIES 3 // command console memory and manual page manager
-#define CMD_MM_DEFAULT_ALLOC 4 // Number of table entries to allocate per default
-
-#define CMD_MM_CMD 0 // Commands
-#define CMD_MM_VAR 1 // Variables
-#define CMD_MM_DOC 2 // Misc. documentation
-
-static const char *cmd_mm_names[CMD_MM_ENTRIES] = {
-	"Commands",
-	"Variables",
-	"Documentation"
-};
-static size_t cmd_mm_sizes_per_entry[CMD_MM_ENTRIES] = {
-	sizeof(cmd_command_t),
-	sizeof(cmd_var_t),
-	sizeof(cmd_page_t)
-};
-
-static void _cmd_print_command(cmd_mm_entry_t *data, int full);
-static void _cmd_print_var(cmd_mm_entry_t *data, int full);
-static void _cmd_print_page(cmd_mm_entry_t *data, int full);
-
-static printfunc_t *cmd_mm_printers[CMD_MM_ENTRIES] = {
-	_cmd_print_command,
-	_cmd_print_var,
-	_cmd_print_page
-};
-
-static cmd_mm_struct_t cmd_mm[CMD_MM_ENTRIES];
-
-static int _cmd_initialized = 0;
-static int _lists_need_sorting = 0;
-
-void _cmd_exit() {
-	int t;
-
-	for (t = 0; t < CMD_MM_ENTRIES; t++)
-		free(cmd_mm[t].data);
-}
-
-static cmd_mm_entry_t *cmd_mm_find(const char *name, int type) {
-	int i;
-
-	for (i = 0; i < cmd_mm[type].entries; i++) {
-		cmd_mm_entry_t *tmp = (cmd_mm_entry_t *)((byte *)cmd_mm[type].data + i * cmd_mm[type].size_per_entry);
-		if (!strcmp(tmp->name, name))
-			return tmp;
-	}
-
-	return NULL;
-}
-
-static int _cmd_mm_comp(const void *a, const void *b) {
-	return strcmp(((cmd_mm_entry_t *) a)->name, ((cmd_mm_entry_t *) b)->name);
-}
-
-void con_sort_all() {
-	int i;
-
-	for (i = 0; i < CMD_MM_ENTRIES; i++)
-		if (cmd_mm[i].entries && _lists_need_sorting & (1 << i))
-			qsort(cmd_mm[i].data, cmd_mm[i].entries, cmd_mm[i].size_per_entry, _cmd_mm_comp);
-
-	_lists_need_sorting = 0;
-}
-
-void con_init() {
-	if (!_cmd_initialized) {
-		int i;
-
-		_cmd_initialized = 1;
-		for (i = 0; i < CMD_MM_ENTRIES; i++) {
-			cmd_mm[i].name = cmd_mm_names[i];
-			cmd_mm[i].size_per_entry = cmd_mm_sizes_per_entry[i];
-			cmd_mm[i].entries = 0;
-			cmd_mm[i].allocated = CMD_MM_DEFAULT_ALLOC;
-			cmd_mm[i].data = calloc(cmd_mm[i].allocated, cmd_mm[i].size_per_entry);
-			cmd_mm[i].print = cmd_mm_printers[i];
-		}
-
-		atexit(_cmd_exit);
-
-		// Hook up some commands
-		con_hook_command(&c_list, "list", "s*", "Lists various things (try 'list')");
-		con_hook_command(&c_man, "man", "s", "Gives a short description of something");
-		con_hook_command(&c_print, "print", "s", "Prints an int variable");
-		con_hook_command(&c_set, "set", "si", "Sets an int variable");
-		con_hook_command(&c_size, "size", "si", "Displays the size of a resource");
-		con_hook_command(&c_dump, "dump", "si", "HexDumps a resource");
-		con_hook_command(&c_hexgrep, "hexgrep", "shh*", "Searches some resources for a\n"
-		                 "  particular sequence of bytes, re-\n  presented as hexadecimal numbers.\n\n"
-		                 "EXAMPLES:\n  hexgrep script e8 03 c8 00\n  hexgrep pic.042 fe");
-		con_hook_command(&c_dissectscript, "dissectscript", "i", "Examines a script.");
-
-		con_hook_page("addresses", "Passing address parameters\n\n"
-		              "  Address parameters may be passed in one of\n"
-		              "  three forms:\n"
-		              "  - ssss:oooo -- where 'ssss' denotes a\n"
-		              "    segment and 'oooo' an offset. Example:\n"
-		              "    \"a:c5\" would address something in seg-\n"
-		              "    ment 0xa at offset 0xc5.\n"
-		              "  - &scr:oooo -- where 'scr' is a script number\n"
-		              "    and oooo an offset within that script; will\n"
-		              "    fail if the script is not currently loaded\n"
-		              "  - $REG -- where 'REG' is one of 'PC', 'ACC',\n"
-		              "    'PREV' or 'OBJ': References the address\n"
-		              "    indicated by the register of this name.\n"
-		              "  - $REG+n (or -n) -- Like $REG, but modifies\n"
-		              "    the offset part by a specific amount (which\n"
-		              "    is specified in hexadecimal).\n"
-		              "  - ?obj -- Looks up an object with the specified\n"
-		              "    name, uses its address. This will abort if\n"
-		              "    the object name is ambiguous; in that case,\n"
-		              "    a list of addresses and indices is provided.\n"
-		              "    ?obj.idx may be used to disambiguate 'obj'\n"
-		              "    by the index 'idx'.\n");
-	}
-}
-
-static inline int clone_is_used(CloneTable *t, int idx) {
-	return ENTRY_IS_VALID(t, idx);
-}
-
-int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on success
-	int rel_offsetting = 0;
-	const char *offsetting = NULL;
-	// Non-NULL: Parse end of string for relative offsets
-	char *endptr;
-
-	if (!s) {
-		sciprintf("Addresses can only be parsed if a global state is present");
-		return 1; // Requires a valid state
-	}
-
-	if (*str == '$') { // Register
-		rel_offsetting = 1;
-
-		if (!scumm_strnicmp(str + 1, "PC", 2)) {
-			*dest = s->_executionStack[s->execution_stack_pos].addr.pc;
-			offsetting = str + 3;
-		} else if (!scumm_strnicmp(str + 1, "P", 1)) {
-			*dest = s->_executionStack[s->execution_stack_pos].addr.pc;
-			offsetting = str + 2;
-		} else if (!scumm_strnicmp(str + 1, "PREV", 4)) {
-			*dest = s->r_prev;
-			offsetting = str + 5;
-		} else if (!scumm_strnicmp(str + 1, "ACC", 3)) {
-			*dest = s->r_acc;
-			offsetting = str + 4;
-		} else if (!scumm_strnicmp(str + 1, "A", 1)) {
-			*dest = s->r_acc;
-			offsetting = str + 2;
-		} else if (!scumm_strnicmp(str + 1, "OBJ", 3)) {
-			*dest = s->_executionStack[s->execution_stack_pos].objp;
-			offsetting = str + 4;
-		} else if (!scumm_strnicmp(str + 1, "O", 1)) {
-			*dest = s->_executionStack[s->execution_stack_pos].objp;
-			offsetting = str + 2;
-		} else
-			return 1; // No matching register
-
-		if (!*offsetting)
-			offsetting = NULL;
-		else if (*offsetting != '+' && *offsetting != '-')
-			return 1;
-	} else if (*str == '&') {
-		int script_nr;
-		// Look up by script ID
-		char *colon = (char *)strchr(str, ':');
-
-		if (!colon)
-			return 1;
-		*colon = 0;
-		offsetting = colon + 1;
-
-		script_nr = strtol(str + 1, &endptr, 10);
-
-		if (*endptr)
-			return 1;
-
-		dest->segment = s->seg_manager->segGet(script_nr);
-
-		if (!dest->segment) {
-			return 1;
-		}
-	} else if (*str == '?') {
-		int index = -1;
-		int times_found = 0;
-		char *tmp;
-		const char *str_objname;
-		char *str_suffix;
-		char suffchar = 0;
-		uint i;
-		// Parse obj by name
-
-		tmp = (char *)strchr(str, '+');
-		str_suffix = (char *)strchr(str, '-');
-		if (tmp < str_suffix)
-			str_suffix = tmp;
-		if (str_suffix) {
-			suffchar = (*str_suffix);
-			*str_suffix = 0;
-		}
-
-		tmp = (char *)strchr(str, '.');
-
-		if (tmp) {
-			*tmp = 0;
-			index = strtol(tmp + 1, &endptr, 16);
-			if (*endptr)
-				return -1;
-		}
-
-		str_objname = str + 1;
-
-		// Now all values are available; iterate over all objects.
-		for (i = 0; i < s->seg_manager->_heap.size(); i++) {
-			MemObject *mobj = s->seg_manager->_heap[i];
-			int idx = 0;
-			int max_index = 0;
-
-			if (mobj) {
-				if (mobj->getType() == MEM_OBJ_SCRIPT)
-					max_index = (*(Script *)mobj)._objects.size();
-				else if (mobj->getType() == MEM_OBJ_CLONES)
-					max_index = (*(CloneTable *)mobj)._table.size();
-			}
-
-			while (idx < max_index) {
-				int valid = 1;
-				Object *obj = NULL;
-				reg_t objpos;
-				objpos.offset = 0;
-				objpos.segment = i;
-
-				if (mobj->getType() == MEM_OBJ_SCRIPT) {
-					obj = &(*(Script *)mobj)._objects[idx];
-					objpos.offset = obj->pos.offset;
-				} else if (mobj->getType() == MEM_OBJ_CLONES) {
-					obj = &((*(CloneTable *)mobj)._table[idx]);
-					objpos.offset = idx;
-					valid = clone_is_used((CloneTable *)mobj, idx);
-				}
-
-				if (valid) {
-					char *objname = (char *)obj->base
-					                + obj->_variables[SCRIPT_NAME_SELECTOR].offset;
-					if (!strcmp(objname, str_objname)) {
-						// Found a match!
-						if (index < 0 ||
-						        times_found == index)
-							*dest = objpos;
-						else if (times_found < 0 && index) {
-							if (index == 1) {
-								// First time we realized the ambiguity
-								sciprintf("Ambiguous:\n");
-								sciprintf("  %3x: ["PREG"] %s\n", 0, PRINT_REG(*dest), str_objname);
-							}
-							sciprintf("  %3x: ["PREG"] %s\n", index, PRINT_REG(objpos), str_objname);
-						}
-						++times_found;
-					}
-				}
-				++idx;
-			}
-
-		}
-
-		if (!times_found)
-			return 1;
-
-		if (times_found > 1 && index < 0) {
-			sciprintf("Ambiguous: Aborting.\n");
-			return 1; // Ambiguous
-		}
-
-		if (times_found <= index)
-			return 1; // Not found
-
-		offsetting = str_suffix;
-		if (offsetting)
-			*str_suffix = suffchar;
-		rel_offsetting = 1;
-	} else {
-		char *colon = (char *)strchr(str, ':');
-
-		if (!colon) {
-			offsetting = str;
-			dest->segment = 0;
-		} else {
-			*colon = 0;
-			offsetting = colon + 1;
-
-			dest->segment = strtol(str, &endptr, 16);
-			if (*endptr)
-				return 1;
-		}
-	}
-	if (offsetting) {
-		int val = strtol(offsetting, &endptr, 16);
-
-		if (rel_offsetting)
-			dest->offset += val;
-		else
-			dest->offset = val;
-
-		if (*endptr)
-			return 1;
-	}
-
-	return 0;
-}
-
-void con_parse(EngineState *s, const char *command) {
-	char *cmd = (command && command[0]) ? (char *)strdup(command) : (char *)strdup(" ");
-	char *_cmd = cmd;
-	int pos = 0;
-
-	if (!_cmd_initialized)
-		con_init();
-
-	bool done = false;		// are we done yet?
-	while (!done) {
-		cmd_command_t *command_todo;
-		bool quote = false;		// quoting?
-		bool cdone = false;		// Done with the current command?
-		bool onvar = true;		// currently working on a variable?
-		cdone = 0;
-		pos = 0;
-
-		Common::Array<cmd_param_t> cmdParams;
-
-		while (*cmd == ' ')
-			cmd++;
-
-		while (!cdone) {
-			switch (cmd[pos]) {
-			case 0:
-				cdone = done = true;
-			case ';':
-				if (!quote)
-					cdone = true;
-			case ' ':
-				if (!quote) {
-					cmd[pos] = 0;
-					onvar = false;
-				}
-				break;
-			case '\\':		// don't check next char for special meaning
-				memmove(cmd + pos, cmd + pos + 1, strlen(cmd + pos) - 1);
-				break;
-			case '"':
-				quote = !quote;
-				memmove(cmd + pos, cmd + pos + 1, strlen(cmd + pos));
-				pos--;
-				break;
-			default:
-				if (!onvar) {
-					onvar = true;
-					cmd_param_t tmp;
-					tmp.str = cmd + pos;
-					cmdParams.push_back(tmp);
-				}
-				break;
-			}
-			pos++;
-		}
-
-		if (quote)
-			sciprintf("unbalanced quotes\n");
-		else if (strcmp(cmd, "") != 0) {
-			command_todo = (cmd_command_t *) cmd_mm_find(cmd, CMD_MM_CMD);
-			if (!command_todo)
-				sciprintf("%s: not found\n", cmd);
-			else {
-				uint minparams;
-				int need_state = 0;
-
-				const char *paramt = command_todo->param;	// parameter types
-				if (command_todo->param[0] == '!') {
-					need_state = 1;
-					paramt++;
-				}
-
-				minparams = strlen(paramt);
-
-				if ((paramt[0] != 0) && (paramt[strlen(paramt) - 1] == '*'))
-					minparams -= 2;
-
-				if (cmdParams.size() < minparams)
-					sciprintf("%s: needs more than %d parameters\n", cmd, cmdParams.size());
-
-				else if ((cmdParams.size() > strlen(paramt)) && ((strlen(paramt) == 0) || paramt[strlen(paramt) - 1] != '*'))
-					sciprintf("%s: too many parameters", cmd);
-				else {
-					int do_execute = !need_state || s; // /me wants an implication arrow
-					char paramtype;
-					int paramtypepos = 0;
-					char *endptr;
-
-					for (uint i = 0; i < cmdParams.size(); i++) {
-						paramtype = paramt[paramtypepos];
-
-						if ((paramt[paramtypepos + 1]) && (paramt[paramtypepos + 1] != '*'))
-							paramtypepos++;
-						// seek next param type unless end of string or '*						   '
-
-						switch (paramtype) {
-							// Now turn the parameters into variables of the appropriate types,
-							// unless they're strings, and store them into the cmdParams array
-
-						case 'a': {
-							const char *oldname = cmdParams[i].str;
-							if (parse_reg_t(s, oldname, &(cmdParams[i].reg))) {
-								sciprintf("%s: '%s' is not an address or object\n", cmd, oldname);
-								do_execute = 0;
-							}
-							break;
-						}
-
-						case 'i': {
-							const char *orgstr = cmdParams[i].str;
-
-							cmdParams[i].val = strtol(orgstr, &endptr, 0);
-							if (*endptr != '\0') {
-								do_execute = 0;
-								sciprintf("%s: '%s' is not an int\n", cmd, orgstr);
-							}
-						}
-						break;
-
-						case 'h': {
-							const char *orgstr = cmdParams[i].str;
-
-							cmdParams[i].val = strtol(orgstr, &endptr, 16);
-
-							if (*endptr != '\0') {
-								do_execute = 0;
-								sciprintf("%s: '%s' is not a hex number\n", cmd, orgstr);
-							}
-
-							cmdParams[i].val &= 0xff;	// Clip hex numbers to 0x00 ... 0xff
-						}
-						break;
-
-						case 's':
-							break;
-
-						default:
-							warning("Internal error: Heap corruption or prior assertion failed: "
-							        "Unknown parameter type '%c' for function", paramtype);
-
-						}
-					}
-
-					if (do_execute) {
-						command_todo->command(s, cmdParams);
-					} else
-						fprintf(stderr, "Skipping command...\n");
-				}
-			}
-		}
-		cmd += pos;
-	}
-
-	free(_cmd);
-}
-
-/* (unused)
-static cmd_mm_entry_t *con_iterate_entry(int ID, int *counter) {
-	byte *retval;
-	con_init();
-
-	if (*counter >= cmd_mm[ID].entries)
-		return 0;
-	retval = cmd_mm[ID].data;
-	retval += (*counter) * cmd_mm[ID].size_per_entry;
-
-	(*counter)++;
-
-	return (cmd_mm_entry_t *)retval;
-}*/
-
-static cmd_mm_entry_t *con_alloc_page_entry(int ID) {
-	int entry;
-
-	con_init();
-
-	if (cmd_mm[ID].entries >= cmd_mm[ID].allocated) {
-		int nextsize = cmd_mm[ID].allocated;
-		if (nextsize >= 64)
-			nextsize += 16;
-		else
-			nextsize <<= 1;
-
-		cmd_mm[ID].data = realloc(cmd_mm[ID].data, nextsize * cmd_mm[ID].size_per_entry);
-		cmd_mm[ID].allocated = nextsize;
-	}
-
-	_lists_need_sorting |= (1 << ID);
-
-	entry = cmd_mm[ID].entries++;
-	return (cmd_mm_entry_t *)(((byte *)cmd_mm[ID].data) + entry * cmd_mm[ID].size_per_entry);
-}
-
-int con_hook_page(const char *name, const char *body) {
-	cmd_page_t *page = (cmd_page_t *)con_alloc_page_entry(CMD_MM_DOC);
-
-	page->name = name;
-	page->description = body;
-
-	return 0;
-}
-
-int con_hook_command(ConCommand command, const char *name, const char *param, const char *description) {
-	cmd_command_t *cmd = NULL;
-	unsigned int i;
-
-	if (NULL == name) {
-		sciprintf("console.c: con_hook_command(): NULL passed for name\n");
-		return -1;
-	}
-
-	if (command == NULL)
-		return 1;
-
-	if (param == NULL)
-		param = "";
-
-	if (description == NULL)
-		description = "";
-
-	i = 0;
-	while (param[i] != 0) {
-		switch (param[i]) {
-		case '*':
-			if (param[i + 1] != 0)
-				return 1;
-			if (i == 0)
-				return 1;
-		case 'h':
-		case '!':
-		case 'i':
-		case 'a':
-		case 's':
-		case 'r':
-			break;
-		default:
-			return 1;
-		}
-		i++;
-	}
-	cmd = (cmd_command_t *)con_alloc_page_entry(CMD_MM_CMD);
-
-	cmd->command = command;
-	cmd->name = name;
-	cmd->param = param;
-	cmd->description = description;
-
-	((SciEngine *)g_engine)->_console->con_hook_command(command, name, param, description);
-
-	return 0;
-}
-
-int con_hook_int(int *pointer, const char *name, const char *description) {
-	cmd_var_t *var;
-
-	if (pointer == NULL)
-		return 1;
-
-	if (description == NULL)
-		description = "";
-
-	var = (cmd_var_t *) con_alloc_page_entry(CMD_MM_VAR);
-
-	var->var.intp = pointer;
-	var->name = name;
-	var->description = description;
-
-	return 0;
-}
-
-// Console commands and support functions
-
-static ResourceType parseResourceType(const char *resid) {
-	// Gets the resource number of a resource string, or returns -1
-	ResourceType res = kResourceTypeInvalid;
-
-	for (int i = 0; i < kResourceTypeInvalid; i++)
-		if (strcmp(getResourceTypeName((ResourceType)i), resid) == 0)
-			res = (ResourceType)i;
-
-	return res;
-}
-
-static void _cmd_print_command(cmd_mm_entry_t *data, int full) {
-	const char *paramseeker = ((cmd_command_t *)data)->param;
-
-	if (full) {
-		sciprintf("SYNOPSIS\n\n  %s (%s) ", data->name, paramseeker);
-
-		while (*paramseeker) {
-			switch (*paramseeker) {
-			case '!':
-				break;
-			case 'i':
-				sciprintf(" (int)");
-				break;
-			case 'a':
-				sciprintf(" (addr)");
-				break;
-			case 's':
-				sciprintf(" (string)");
-				break;
-			case 'h':
-				sciprintf(" (hexbyte)");
-				break;
-			case '*':
-				sciprintf("*");
-				break;
-			default:
-				sciprintf(" (Unknown(%c))", *paramseeker);
-			}
-			paramseeker++;
-		}
-
-		sciprintf("\n\nDESCRIPTION\n\n  %s", data->description);
-	} else
-		sciprintf(" %s", data->name);
-}
-
-static void _cmd_print_var(cmd_mm_entry_t *data, int full) {
-	cmd_var_t *var = (cmd_var_t *) data;
-	if (full)
-		sciprintf("VALUE\n\n");
-	sciprintf("  %s = %d\n", var->name, *(var->var.intp));
-
-	if (full)
-		sciprintf("\n\nDESCRIPTION\n\n  %s", data->description);
-}
-
-static void _cmd_print_page(cmd_mm_entry_t *data, int full) {
-	if (full)
-		sciprintf("\n\nDESCRIPTION\n\n  %s\n", data->description);
-	else
-		sciprintf("%s\n", data->name);
-}
-
-static int c_list(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	if (_lists_need_sorting)
-		con_sort_all();
-
-	if (cmdParams.size() == 0) {
-		sciprintf("usage: list [type]\nwhere type is one of the following:\n"
-		          "cmds       - lists all commands\n"
-		          "vars       - lists all variables\n"
-		          "docs       - lists all misc. documentation\n"
-		          "\n"
-		          "restypes   - lists all resource types\n"
-		          "[resource] - lists all [resource]s");
-	} else if (cmdParams.size() == 1) {
-		const char *mm_subsects[3] = {"cmds", "vars", "docs"};
-		int mm_found = -1;
-		int i;
-
-		for (i = 0; i < 3; i++)
-			if (mm_subsects[i] && !strcmp(mm_subsects[i], cmdParams[0].str))
-				mm_found = i;
-
-		if (mm_found >= 0)
-			for (i = 0; i < cmd_mm[mm_found].entries; i++)
-				cmd_mm[mm_found].print((cmd_mm_entry_t *)(((byte *)cmd_mm[mm_found].data) + i * cmd_mm[mm_found].size_per_entry), 0);
-		else {
-			if (!s) {
-				sciprintf("You need a state to do that!\n");
-				return 1;
-			}
-
-			else if (strcmp("restypes", cmdParams[0].str) == 0) {
-				for (i = 0; i < kResourceTypeInvalid; i++)
-					sciprintf("%s\n", getResourceTypeName((ResourceType)i));
-			} else {
-				ResourceType res = parseResourceType(cmdParams[0].str);
-				if (res == kResourceTypeInvalid)
-					sciprintf("Unknown resource type: '%s'\n", cmdParams[0].str);
-				else {
-					for (i = 0; i < sci_max_resource_nr[s->resmgr->_sciVersion]; i++)
-						if (s->resmgr->testResource(res, i))
-							sciprintf("%s.%03d\n", getResourceTypeName((ResourceType)res), i);
-				}
-			}
-		}
-	} else
-		sciprintf("list can only be used with one argument");
-	return 0;
-}
-
-static int c_man(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	int section = 0;
-	uint i;
-	Common::String name = cmdParams[0].str;
-	const char *c = strchr(name.c_str(), '.');
-	cmd_mm_entry_t *entry = 0;
-
-	if (c) {
-		section = atoi(c + 1);
-		name = Common::String(name.begin(), c);
-	}
-
-	if (section < 0 || section >= CMD_MM_ENTRIES) {
-		sciprintf("Invalid section %d\n", section);
-		return 1;
-	}
-
-	sciprintf("section:%d\n", section);
-	if (section)
-		entry = cmd_mm_find(name.c_str(), section - 1);
-	else
-		for (i = 0; i < CMD_MM_ENTRIES && !section; i++) {
-			if ((entry = cmd_mm_find(name.c_str(), i)))
-				section = i + 1;
-		}
-
-	if (!entry) {
-		sciprintf("No manual entry\n");
-		return 1;
-	}
-
-	sciprintf("-- %s: %s.%d\n", cmd_mm[section - 1].name, name.c_str(), section);
-	cmd_mm[section - 1].print(entry, 1);
-
-	return 0;
-}
-
-static int c_set(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	cmd_var_t *var = (cmd_var_t *)cmd_mm_find(cmdParams[0].str, CMD_MM_VAR);
-
-	if (var)
-		*(var->var.intp) = cmdParams[1].val;
-
-	return 0;
-}
-
-static int c_print(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	cmd_var_t *var = (cmd_var_t *)cmd_mm_find(cmdParams[0].str, CMD_MM_VAR);
-
-	if (var)
-		sciprintf("%d", *(var->var.intp));
-	else
-		sciprintf("Not defined.");
-
-	return 0;
-}
-
-static int c_size(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	ResourceType res = parseResourceType(cmdParams[0].str);
-	if (res == kResourceTypeInvalid)
-		sciprintf("Resource type '%s' is not valid\n", cmdParams[0].str);
-	else {
-		Resource *resource = s->resmgr->findResource(res, cmdParams[1].val, 0);
-		if (resource) {
-			sciprintf("Size: %d\n", resource->size);
-		} else
-			sciprintf("Resource %s.%03d not found\n", cmdParams[0].str, cmdParams[1].val);
-	}
-
-	return 0;
-}
-
-static int c_dump(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	ResourceType res = parseResourceType(cmdParams[0].str);
-
-	if (res == kResourceTypeInvalid)
-		sciprintf("Resource type '%s' is not valid\n", cmdParams[0].str);
-	else {
-		Resource *resource = s->resmgr->findResource(res, cmdParams[1].val, 0);
-		if (resource)
-			Common::hexdump(resource->data, resource->size, 16, 0);
-		else
-			sciprintf("Resource %s.%03d not found\n", cmdParams[0].str, cmdParams[1].val);
-	}
-
-	return 0;
-}
-
-static int c_hexgrep(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-	int i, seeklen, resnr, resmax;
-	unsigned char *seekstr = NULL;
-	Resource *script = NULL;
-	char *dot = (char *)strchr(cmdParams[0].str, '.');
-	ResourceType restype;
-
-	if (NULL == s) {
-		fprintf(stderr, "console.c: c_hexgrep(): NULL passed for s\r\n");
-		return(-1);
-	}
-
-	seeklen = cmdParams.size() - 1;
-	seekstr = (unsigned char *)malloc(seeklen);
-
-	if (NULL == seekstr) {
-		fprintf(stderr, "console.c: c_hexgrep(): malloc failed for seekstr\r\n");
-		return(-1);
-	}
-
-	for (i = 0; i < seeklen; i++)
-		seekstr[i] = (byte)cmdParams[i + 1].val;
-
-	if (dot) {
-		*dot = 0;
-		resmax = resnr = atoi(dot + 1);

@@ Diff output truncated at 100000 characters. @@

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