[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