aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/scicore
diff options
context:
space:
mode:
authorFilippos Karapetis2009-05-15 14:07:45 +0000
committerFilippos Karapetis2009-05-15 14:07:45 +0000
commit87e8f94fde8330e1d5e600cc7b3e5c24225d6158 (patch)
tree2774c88f62f0491b480e0add2dd7e009546e7a74 /engines/sci/scicore
parentce29fec17a9316b5fee0349d013a4d7863af9c03 (diff)
downloadscummvm-rg350-87e8f94fde8330e1d5e600cc7b3e5c24225d6158.tar.gz
scummvm-rg350-87e8f94fde8330e1d5e600cc7b3e5c24225d6158.tar.bz2
scummvm-rg350-87e8f94fde8330e1d5e600cc7b3e5c24225d6158.zip
- 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 svn-id: r40608
Diffstat (limited to 'engines/sci/scicore')
-rw-r--r--engines/sci/scicore/decompressor.cpp969
-rw-r--r--engines/sci/scicore/decompressor.h201
-rw-r--r--engines/sci/scicore/resource.cpp1161
-rw-r--r--engines/sci/scicore/resource.h302
-rw-r--r--engines/sci/scicore/sciconsole.h130
-rw-r--r--engines/sci/scicore/vocab_debug.cpp518
-rw-r--r--engines/sci/scicore/vocabulary.cpp566
-rw-r--r--engines/sci/scicore/vocabulary.h359
8 files changed, 0 insertions, 4206 deletions
diff --git a/engines/sci/scicore/decompressor.cpp b/engines/sci/scicore/decompressor.cpp
deleted file mode 100644
index 91738aa1d8..0000000000
--- a/engines/sci/scicore/decompressor.cpp
+++ /dev/null
@@ -1,969 +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$
- *
- */
-
-// Resource library
-
-#include "common/util.h"
-#include "common/endian.h"
-#include "common/debug.h"
-
-#include "sci/scicore/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
diff --git a/engines/sci/scicore/decompressor.h b/engines/sci/scicore/decompressor.h
deleted file mode 100644
index 5f24b0f41d..0000000000
--- a/engines/sci/scicore/decompressor.h
+++ /dev/null
@@ -1,201 +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$
- *
- */
-
-#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
-
diff --git a/engines/sci/scicore/resource.cpp b/engines/sci/scicore/resource.cpp
deleted file mode 100644
index 9b7d7dca98..0000000000
--- a/engines/sci/scicore/resource.cpp
+++ /dev/null
@@ -1,1161 +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$
- *
- */
-
-// Resource library
-
-#include "common/util.h"
-#include "common/debug.h"
-
-#include "sci/sci.h"
-#include "sci/engine/state.h"
-#include "sci/engine/kernel.h"
-#include "sci/tools.h"
-#include "sci/scicore/resource.h"
-#include "sci/scicore/vocabulary.h"
-#include "sci/scicore/decompressor.h"
-
-namespace Sci {
-
-#undef SCI_REQUIRE_RESOURCE_FILES
-
-//#define SCI_VERBOSE_RESMGR 1
-
-const char *sci_version_types[] = {
- "SCI version undetermined (Autodetect failed / not run)",
- "SCI version 0.xxx",
- "SCI version 0.xxx w/ 1.000 compression",
- "SCI version 1.000 w/ 0.xxx resource.map",
- "SCI version 1.000 w/ special resource.map",
- "SCI version 1.000 (early)",
- "SCI version 1.000 (late)",
- "SCI version 1.001",
- "SCI WIN/32"
-};
-
-const int sci_max_resource_nr[] = {65536, 1000, 2048, 2048, 2048, 8192, 8192, 65536};
-
-const char *sci_error_types[] = {
- "No error",
- "I/O error",
- "Resource is empty (size 0)",
- "resource.map entry is invalid",
- "resource.map file not found",
- "No resource files found",
- "Unknown compression method",
- "Decompression failed: Decompression buffer overflow",
- "Decompression failed: Sanity check failed",
- "Decompression failed: Resource too big",
- "SCI version is unsupported"
-};
-
-// These are the 18 resource types supported by SCI1
-const char *resourceTypeNames[] = {
- "view", "pic", "script", "text", "sound",
- "memory", "vocab", "font", "cursor",
- "patch", "bitmap", "palette", "cdaudio",
- "audio", "sync", "message", "map", "heap"
-};
-
-const char *resourceTypeSuffixes[] = {
- "v56", "p56", "scr", "tex", "snd",
- " ", "voc", "fon", "cur", "pat",
- "bit", "pal", "cda", "aud", "syn",
- "msg", "map", "hep"
-};
-
-const char *getResourceTypeName(ResourceType restype) {
- return resourceTypeNames[restype];
-}
-
-const char *getResourceTypeSuffix(ResourceType restype) {
- return resourceTypeSuffixes[restype];
-}
-
-typedef int decomp_funct(Resource *result, Common::ReadStream &stream, int sci_version);
-typedef void patch_sprintf_funct(char *string, Resource *res);
-
-//-- Resource main functions --
-Resource::Resource() {
- data = NULL;
- number = 0;
- type = kResourceTypeInvalid;
- id = 0;
- size = 0;
- file_offset = 0;
- status = kResStatusNoMalloc;
- lockers = 0;
- source = NULL;
-}
-
-Resource::~Resource() {
- delete[] data;
- if (source && source->source_type == kSourcePatch)
- delete source;
-}
-
-void Resource::unalloc() {
- delete[] data;
- data = NULL;
- status = kResStatusNoMalloc;
-}
-
-//-- Resmgr helper functions --
-
-// Resource source list management
-
-ResourceSource *ResourceManager::addExternalMap(const char *file_name) {
- ResourceSource *newsrc = new ResourceSource();
-
- // Add the new source to the SLL of sources
- newsrc->next = _sources;
- _sources = newsrc;
-
- newsrc->source_type = kSourceExtMap;
- newsrc->location_name = file_name;
- newsrc->scanned = false;
- newsrc->associated_map = NULL;
-
- return newsrc;
-}
-
-ResourceSource *ResourceManager::addVolume(ResourceSource *map, const char *filename, int number, int extended_addressing) {
- ResourceSource *newsrc = new ResourceSource();
-
- // Add the new source to the SLL of sources
- newsrc->next = _sources;
- _sources = newsrc;
-
- newsrc->source_type = kSourceVolume;
- newsrc->scanned = false;
- newsrc->location_name = filename;
- newsrc->volume_number = number;
- newsrc->associated_map = map;
-
- return 0;
-}
-
-ResourceSource *ResourceManager::addPatchDir(const char *dirname) {
- ResourceSource *newsrc = new ResourceSource();
-
- // Add the new source to the SLL of sources
- newsrc->next = _sources;
- _sources = newsrc;
-
- newsrc->source_type = kSourceDirectory;
- newsrc->scanned = false;
- newsrc->location_name = dirname;
-
- return 0;
-}
-
-ResourceSource *ResourceManager::getVolume(ResourceSource *map, int volume_nr) {
- ResourceSource *seeker = _sources;
-
- while (seeker) {
- if (seeker->source_type == kSourceVolume && seeker->associated_map == map &&
- seeker->volume_number == volume_nr)
- return seeker;
- seeker = seeker->next;
- }
-
- return NULL;
-}
-
-// Resource manager constructors and operations
-
-bool ResourceManager::loadFromPatchFile(Resource *res) {
- Common::File file;
- const char *filename = res->source->location_name.c_str();
- if (file.open(filename) == false) {
- warning("Failed to open patch file %s", filename);
- res->unalloc();
- return false;
- }
- res->data = new byte[res->size];
-
- if (res->data == NULL) {
- error("Can't allocate %d bytes needed for loading %s!", res->size, filename);
- }
-
- file.seek(res->file_offset, SEEK_SET);
- unsigned int really_read = file.read(res->data, res->size);
- if (really_read != res->size) {
- error("Read %d bytes from %s but expected %d!", really_read, filename, res->size);
- }
- res->status = kResStatusAllocated;
- return true;
-}
-
-Common::File *ResourceManager::getVolumeFile(const char *filename) {
- Common::List<Common::File *>::iterator it = _volumeFiles.begin();
- Common::File *file;
-
- // check if file is already opened
- while (it != _volumeFiles.end()) {
- file = *it;
- if (scumm_stricmp(file->getName(), filename) == 0) {
- // move file to top
- if (it != _volumeFiles.begin()) {
- _volumeFiles.erase(it);
- _volumeFiles.push_front(file);
- }
- return file;
- }
- it ++;
- }
- // adding a new file
- file = new Common::File;
- if (file->open(filename)) {
- if (_volumeFiles.size() == MAX_OPENED_VOLUMES) {
- it = --_volumeFiles.end();
- delete *it;
- _volumeFiles.erase(it);
- }
- _volumeFiles.push_front(file);
- return file;
- }
- // failed
- delete file;
- return NULL;
-}
-
-void ResourceManager::loadResource(Resource *res) {
- Common::File *file;
-
- if (res->source->source_type == kSourcePatch && loadFromPatchFile(res))
- return;
- // Either loading from volume or patch loading failed
- file = getVolumeFile(res->source->location_name.c_str());
- if (!file) {
- warning("Failed to open %s", res->source->location_name.c_str());
- res->unalloc();
- return;
- }
- file->seek(res->file_offset, SEEK_SET);
- int error = decompress(res, file);
- if (error) {
- warning("Error %d occured while reading %s.%03d from resource file: %s\n",
- error, getResourceTypeName(res->type), res->number, sci_error_types[error]);
- res->unalloc();
- }
-
-}
-
-Resource *ResourceManager::testResource(ResourceType type, int number) {
- if (_resMap.contains(RESOURCE_HASH(type, number)))
- return _resMap.getVal(RESOURCE_HASH(type, number));
- return NULL;
-}
-
-int sci0_get_compression_method(Common::ReadStream &stream) {
- uint16 compressionMethod;
-
- stream.readUint16LE();
- stream.readUint16LE();
- stream.readUint16LE();
- compressionMethod = stream.readUint16LE();
- if (stream.err())
- return SCI_ERROR_IO_ERROR;
-
- return compressionMethod;
-}
-
-int sci_test_view_type(ResourceManager *mgr) {
- Common::File file;
- char filename[MAXPATHLEN];
- int compression;
- Resource *res;
- int i;
-
- for (i = 0; i < 1000; i++) {
- res = mgr->testResource(kResourceTypeView, i);
-
- if (!res)
- continue;
-
- if (res->source->source_type == kSourceDirectory)
- continue;
-
- strcpy(filename, res->source->location_name.c_str());
-
- if (!file.open(filename))
- continue;
- file.seek(res->file_offset, SEEK_SET);
-
- compression = sci0_get_compression_method(file);
- file.close();
-
- if (compression == 3) {
- return SCI_VERSION_01_VGA;
- }
- }
-
- // Try the same thing with pics
- for (i = 0; i < 1000; i++) {
- res = mgr->testResource(kResourceTypePic, i);
-
- if (!res)
- continue;
-
- if (res->source->source_type == kSourceDirectory)
- continue;
-
- strcpy(filename, res->source->location_name.c_str());
-
- if (!file.open(filename))
- continue;
- file.seek(res->file_offset, SEEK_SET);
-
- compression = sci0_get_compression_method(file);
- file.close();
-
- if (compression == 3) {
- return SCI_VERSION_01_VGA;
- }
- }
-
- return SCI_VERSION_AUTODETECT;
-}
-
-int ResourceManager::addAppropriateSources() {
- ResourceSource *map;
-
- if (!Common::File::exists("RESOURCE.MAP"))
- return 0;
- map = addExternalMap("RESOURCE.MAP");
-
- Common::ArchiveMemberList files;
- SearchMan.listMatchingMembers(files, "RESOURCE.0??");
-
- for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
- const Common::String name = (*x)->getName();
- const char *dot = strrchr(name.c_str(), '.');
- int number = atoi(dot + 1);
-
- addVolume(map, name.c_str(), number, 0);
- }
- addPatchDir("");
- // TODO: add RESOURCE.AUD and RESOURCE.SFX for SCI1.1 games
- if (Common::File::exists("MESSAGE.MAP"))
- addVolume(addExternalMap("MESSAGE.MAP"), "RESOURCE.MSG",0 ,0);
- return 1;
-}
-
-int ResourceManager::scanNewSources(ResourceSource *source) {
- if (!source)
- return SCI_ERROR_NO_RESOURCE_FILES_FOUND;
-
- int resource_error = 0;
- if (source->next)
- scanNewSources(source->next);
-
- if (!source->scanned) {
- source->scanned = true;
- switch (source->source_type) {
- case kSourceDirectory:
- readResourcePatches(source);
- break;
- case kSourceExtMap:
- if (_mapVersion < SCI_VERSION_1)
- resource_error = readResourceMapSCI0(source);
- else
- resource_error = readResourceMapSCI1(source);
-
- if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND) {
- // FIXME: Try reading w/o resource.map
- resource_error = SCI_ERROR_NO_RESOURCE_FILES_FOUND;
- }
-
- if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {
- // Initialize empty resource manager
- _resMap.clear();
- resource_error = 0;
- }
- break;
- default:
- break;
- }
- }
- return resource_error;
-}
-
-void ResourceManager::freeResourceSources(ResourceSource *rss) {
- if (rss) {
- freeResourceSources(rss->next);
- delete rss;
- }
-}
-
-ResourceManager::ResourceManager(int version, int maxMemory) {
- _maxMemory = maxMemory;
- _memoryLocked = 0;
- _memoryLRU = 0;
- _LRU.clear();
- _resMap.clear();
- _sources = NULL;
- _sciVersion = version;
-
- addAppropriateSources();
-
- if (version != SCI_VERSION_AUTODETECT) {
- _mapVersion = version;
- _volVersion = version;
- } else {
- _mapVersion = detectMapVersion();
- _volVersion = detectVolVersion();
- }
- debug("Using resource map version %d %s", _mapVersion, sci_version_types[_mapVersion]);
- debug("Using volume version %d %s", _volVersion, sci_version_types[_volVersion]);
-
- scanNewSources(_sources);
- if (version == SCI_VERSION_AUTODETECT)
- switch (_mapVersion) {
- case SCI_VERSION_0:
- if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB)) {
- version = sci_test_view_type(this) ? SCI_VERSION_01_VGA : SCI_VERSION_0;
- } else if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB)) {
- version = sci_test_view_type(this);
- if (version != SCI_VERSION_01_VGA) {
- version = testResource(kResourceTypeVocab, 912) ? SCI_VERSION_0 : SCI_VERSION_01;
- }
- } else {
- version = sci_test_view_type(this) ? SCI_VERSION_01_VGA : SCI_VERSION_0;
- }
- break;
- case SCI_VERSION_01_VGA_ODD:
- version = _mapVersion;
- break;
- case SCI_VERSION_1: {
- Resource *res = testResource(kResourceTypeScript, 0);
-
- _sciVersion = version = SCI_VERSION_1_EARLY;
- loadResource(res);
-
- if (res->status == kResStatusNoMalloc)
- version = SCI_VERSION_1_LATE;
- break;
- }
- case SCI_VERSION_1_1:
- // No need to handle SCI 1.1 here - it was done in resource_map.cpp
- version = SCI_VERSION_1_1;
- break;
- default:
- version = SCI_VERSION_AUTODETECT;
- }
-
- _sciVersion = version;
- // temporary version printout - should be reworked later
- switch (_sciVersion) {
- case SCI_VERSION_0:
- debug("Resmgr: Detected SCI0");
- break;
- case SCI_VERSION_01:
- debug("Resmgr: Detected SCI01");
- break;
- case SCI_VERSION_01_VGA:
- debug("Resmgr: Detected SCI01VGA - KQ5 or similar");
- break;
- case SCI_VERSION_01_VGA_ODD:
- debug("Resmgr: Detected SCI01VGA - Jones/CD or similar");
- break;
- case SCI_VERSION_1_EARLY:
- debug("Resmgr: Detected SCI1 Early");
- break;
- case SCI_VERSION_1_LATE:
- debug("Resmgr: Detected SCI1 Late");
- break;
- case SCI_VERSION_1_1:
- debug("Resmgr: Detected SCI1.1");
- break;
-#ifdef ENABLE_SCI32
- case SCI_VERSION_32:
- debug("Resmgr: Couldn't determine SCI version");
- break;
-#endif
- default:
- debug("Resmgr: Couldn't determine SCI version");
- break;
- }
-}
-
-ResourceManager::~ResourceManager() {
- // freeing resources
- Common::HashMap<uint32, Resource *>::iterator itr = _resMap.begin();
- while (itr != _resMap.end()) {
- delete itr->_value;
- itr ++;
- }
- freeResourceSources(_sources);
- _resMap.empty();
-
- Common::List<Common::File *>::iterator it = _volumeFiles.begin();
- while (it != _volumeFiles.end()) {
- delete *it;
- it ++;
- }
-}
-
-void ResourceManager::removeFromLRU(Resource *res) {
- if (res->status != kResStatusEnqueued) {
- sciprintf("Resmgr: Oops: trying to remove resource that isn't enqueued\n");
- return;
- }
- _LRU.remove(res);
- _memoryLRU -= res->size;
- res->status = kResStatusAllocated;
-}
-
-void ResourceManager::addToLRU(Resource *res) {
- if (res->status != kResStatusAllocated) {
- warning("Resmgr: Oops: trying to enqueue resource with state %d", res->status);
- return;
- }
- _LRU.push_front(res);
- _memoryLRU += res->size;
-#if (SCI_VERBOSE_RESMGR > 1)
- debug("Adding %s.%03d (%d bytes) to lru control: %d bytes total",
- getResourceTypeName(res->type), res->number, res->size,
- mgr->_memoryLRU);
-
-#endif
- res->status = kResStatusEnqueued;
-}
-
-void ResourceManager::printLRU() {
- int mem = 0;
- int entries = 0;
- Common::List<Resource *>::iterator it = _LRU.begin();
- Resource *res;
-
- while (it != _LRU.end()) {
- res = *it;
- debug("\t%s.%03d: %d bytes", getResourceTypeName(res->type),
- res->number, res->size);
- mem += res->size;
- entries ++;
- it ++;
- }
-
- debug("Total: %d entries, %d bytes (mgr says %d)", entries, mem, _memoryLRU);
-}
-
-void ResourceManager::freeOldResources(int last_invulnerable) {
- while (_maxMemory < _memoryLRU && (!last_invulnerable || !_LRU.empty())) {
- Resource *goner = *_LRU.reverse_begin();
- if (!goner) {
- debug("Internal error: mgr->lru_last is NULL!");
- debug("LRU-mem= %d", _memoryLRU);
- debug("lru_first = %p", (void *)*_LRU.begin());
- printLRU();
- }
- removeFromLRU(goner);
- goner->unalloc();
-#ifdef SCI_VERBOSE_RESMGR
- sciprintf("Resmgr-debug: LRU: Freeing %s.%03d (%d bytes)\n", getResourceTypeName(goner->type), goner->number, goner->size);
-#endif
- }
-}
-
-Resource *ResourceManager::findResource(ResourceType type, int number, int lock) {
- Resource *retval;
-
- if (number >= sci_max_resource_nr[_sciVersion]) {
- int modded_number = number % sci_max_resource_nr[_sciVersion];
- sciprintf("[resmgr] Requested invalid resource %s.%d, mapped to %s.%d\n",
- getResourceTypeName(type), number, getResourceTypeName(type), modded_number);
- number = modded_number;
- }
-
- retval = testResource(type, number);
-
- if (!retval)
- return NULL;
-
- if (retval->status == kResStatusNoMalloc)
- loadResource(retval);
- else if (retval->status == kResStatusEnqueued)
- removeFromLRU(retval);
- // Unless an error occured, the resource is now either
- // locked or allocated, but never queued or freed.
-
- if (lock) {
- if (retval->status == kResStatusAllocated) {
- retval->status = kResStatusLocked;
- retval->lockers = 0;
- _memoryLocked += retval->size;
- }
- retval->lockers++;
- } else if (retval->status != kResStatusLocked) { // Don't lock it
- if (retval->status == kResStatusAllocated)
- addToLRU(retval);
- }
-
- freeOldResources(retval->status == kResStatusAllocated);
-
- if (retval->data)
- return retval;
- else {
- sciprintf("Resmgr: Failed to read %s.%03d\n", getResourceTypeName(retval->type), retval->number);
- return NULL;
- }
-}
-
-void ResourceManager::unlockResource(Resource *res, int resnum, ResourceType restype) {
- if (!res) {
- if (restype == kResourceTypeInvalid)
- sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %03d.%03d!\n", restype, resnum);
- else
- sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %s.%03d!\n", getResourceTypeName(restype), resnum);
- return;
- }
-
- if (res->status != kResStatusLocked) {
- sciprintf("Resmgr: Warning: Attempt to unlock unlocked resource %s.%03d\n",
- getResourceTypeName(res->type), res->number);
- return;
- }
-
- if (!--res->lockers) { // No more lockers?
- res->status = kResStatusAllocated;
- _memoryLocked -= res->size;
- addToLRU(res);
- }
-
- freeOldResources(0);
-}
-
-int ResourceManager::detectMapVersion() {
- Common::File file;
- byte buff[6];
- ResourceSource *rsrc = _sources;
- // looking for extarnal map among sources
- while (rsrc) {
- if (rsrc->source_type == kSourceExtMap) {
- file.open(rsrc->location_name);
- break;
- }
- rsrc = rsrc->next;
- }
- if (file.isOpen() == false) {
- warning("Failed to open resource map file");
- return SCI_VERSION_AUTODETECT;
- }
- // detection
- // SCI0 and SCI01 maps have last 6 bytes set to FF
- file.seek(-4, SEEK_END);
- uint32 uEnd = file.readUint32LE();
- if (uEnd == 0xFFFFFFFF) {
- // check if 0 or 01 - try to read resources in SCI0 format and see if exists
- file.seek(0, SEEK_SET);
- while (file.read(buff, 6) == 6 && !(buff[0] == 0xFF && buff[1] == 0xFF && buff[2] == 0xFF)) {
- if (getVolume(rsrc, (buff[5] & 0xFC) >> 2) == NULL)
- return SCI_VERSION_01_VGA_ODD;
- }
- return SCI_VERSION_0;
- }
- // SCI1E/L and some SCI1.1 maps have last directory entry set to 0xFF
- // and offset set to filesize
- // SCI1 have 6-bytes entries, while SCI1.1 have 5-byte entries
- file.seek(1, SEEK_SET);
- uint16 off1, off = file.readUint16LE();
- uint16 nEntries = off / 3;
- file.seek(1, SEEK_CUR);
- file.seek(off - 3, SEEK_SET);
- if (file.readByte() == 0xFF && file.readUint16LE() == file.size()) {
- file.seek(3, SEEK_SET);
- for (int i = 0; i < nEntries; i++) {
- file.seek(1, SEEK_CUR);
- off1 = file.readUint16LE();
- if ((off1 - off) % 5 && (off1 - off) % 6 == 0)
- return SCI_VERSION_1;
- if ((off1 - off) % 5 == 0 && (off1 - off) % 6)
- return SCI_VERSION_1_1;
- off = off1;
- }
- return SCI_VERSION_1;
- }
-
-#ifdef ENABLE_SCI32
- // late SCI1.1 and SCI32 maps have last directory entry set to 0xFF
- // offset set to filesize and 4 more bytes
- file.seek(off - 7, SEEK_SET);
- if (file.readByte() == 0xFF && file.readUint16LE() == file.size())
- return SCI_VERSION_32; // TODO : check if there is a difference between these maps
-#endif
-
- return SCI_VERSION_AUTODETECT;
-}
-
-int ResourceManager::detectVolVersion() {
- Common::File file;
- ResourceSource *rsrc = _sources;
- // looking for a volume among sources
- while (rsrc) {
- if (rsrc->source_type == kSourceVolume) {
- file.open(rsrc->location_name);
- break;
- }
- rsrc = rsrc->next;
- }
- if (file.isOpen() == false) {
- warning("Failed to open volume file");
- return SCI_VERSION_AUTODETECT;
- }
- // SCI0 volume format: {wResId wPacked+4 wUnpacked wCompression} = 8 bytes
- // SCI1 volume format: {bResType wResNumber wPacked+4 wUnpacked wCompression} = 9 bytes
- // SCI1.1 volume format: {bResType wResNumber wPacked wUnpacked wCompression} = 9 bytes
- // SCI32 volume format : {bResType wResNumber dwPacked dwUnpacked wCompression} = 13 bytes
- // Try to parse volume with SCI0 scheme to see if it make sense
- // Checking 1MB of data should be enough to determine the version
- uint16 resId, wCompression;
- uint32 dwPacked, dwUnpacked;
- int curVersion = SCI_VERSION_0;
- bool failed = false;
-
- // Check for SCI0, SCI1, SCI1.1 and SCI32 v2 (Gabriel Knight 1 CD) formats
- while (!file.eos() && file.pos() < 0x100000) {
- if (curVersion > SCI_VERSION_0)
- file.readByte();
- resId = file.readUint16LE();
- dwPacked = (curVersion < SCI_VERSION_32) ? file.readUint16LE() : file.readUint32LE();
- dwUnpacked = (curVersion < SCI_VERSION_32) ? file.readUint16LE() : file.readUint32LE();
- wCompression = (curVersion < SCI_VERSION_32) ? file.readUint16LE() : file.readUint32LE();
- if (file.eos())
- return curVersion;
-
- int chk = (curVersion == SCI_VERSION_0) ? 4 : 20;
- int offs = curVersion < SCI_VERSION_1_1 ? 4 : 0;
- if ((curVersion < SCI_VERSION_32 && wCompression > chk)
- || (curVersion == SCI_VERSION_32 && wCompression != 0 && wCompression != 32)
- || (wCompression == 0 && dwPacked != dwUnpacked + offs)
- || (dwUnpacked < dwPacked - offs)) {
-
- // Retry with a newer SCI version
- if (curVersion == SCI_VERSION_0) {
- curVersion = SCI_VERSION_1;
- } else if (curVersion == SCI_VERSION_1) {
- curVersion = SCI_VERSION_1_1;
- } else if (curVersion == SCI_VERSION_1_1) {
- curVersion = SCI_VERSION_32;
- } else {
- // All version checks failed, exit loop
- failed = true;
- break;
- }
-
- file.seek(0, SEEK_SET);
- continue;
- }
-
- if (curVersion < SCI_VERSION_1_1)
- file.seek(dwPacked - 4, SEEK_CUR);
- else if (curVersion == SCI_VERSION_1_1)
- file.seek((9 + dwPacked) % 2 ? dwPacked + 1 : dwPacked, SEEK_CUR);
- else if (curVersion == SCI_VERSION_32)
- file.seek(dwPacked, SEEK_CUR);//(9 + wPacked) % 2 ? wPacked + 1 : wPacked, SEEK_CUR);
- }
-
- if (!failed)
- return curVersion;
-
- // Failed to detect volume version
- return SCI_VERSION_AUTODETECT;
-}
-
-// version-agnostic patch application
-void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, int resnumber) {
- Common::File file;
- Resource *newrsc;
- uint32 resId = RESOURCE_HASH(restype, resnumber);
- byte patchtype, patch_data_offset;
- int fsize;
-
- if (resnumber == -1)
- return;
- if (!file.open(source->location_name)) {
- perror("""__FILE__"": (""__LINE__""): failed to open");
- return;
- }
- fsize = file.size();
- if (fsize < 3) {
- debug("Patching %s failed - file too small", source->location_name.c_str());
- return;
- }
-
- patchtype = file.readByte() & 0x7F;
- patch_data_offset = file.readByte();
-
- if (patchtype != restype) {
- debug("Patching %s failed - resource type mismatch", source->location_name.c_str());
- return;
- }
- if (patch_data_offset + 2 >= fsize) {
- debug("Patching %s failed - patch starting at offset %d can't be in file of size %d",
- source->location_name.c_str(), patch_data_offset + 2, fsize);
- return;
- }
- // Prepare destination, if neccessary
- if (_resMap.contains(resId) == false) {
- newrsc = new Resource;
- _resMap.setVal(resId, newrsc);
- } else
- newrsc = _resMap.getVal(resId);
- // Overwrite everything, because we're patching
- newrsc->id = resId;
- newrsc->number = resnumber;
- newrsc->status = kResStatusNoMalloc;
- newrsc->type = restype;
- newrsc->source = source;
- newrsc->size = fsize - patch_data_offset - 2;
- newrsc->file_offset = 2 + patch_data_offset;
- debug("Patching %s - OK", source->location_name.c_str());
-}
-
-
-void ResourceManager::readResourcePatches(ResourceSource *source) {
-// Note: since some SCI1 games(KQ5 floppy, SQ4) might use SCI0 naming scheme for patch files
-// this function tries to read patch file with any supported naming scheme,
-// regardless of _sciVersion value
-
- Common::String mask, name;
- Common::ArchiveMemberList files;
- int number;
- const char *szResType;
- ResourceSource *psrcPatch;
- bool bAdd;
-
- for (int i = kResourceTypeView; i < kResourceTypeInvalid; i ++) {
- files.clear();
- szResType = getResourceTypeName((ResourceType)i);
- // SCI0 naming - type.nnn
- mask = szResType;
- mask += ".???";
- SearchMan.listMatchingMembers(files, mask);
- // SCI1 and later naming - nnn.typ
- mask = "*.";
- mask += getResourceTypeSuffix((ResourceType)i);
- SearchMan.listMatchingMembers(files, mask);
- for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); x++) {
- bAdd = false;
- name = (*x)->getName();
- // SCI1 scheme
- if (isdigit(name[0])) {
- number = atoi(name.c_str());
- bAdd = true;
- } else {
- // SCI0 scheme
- int resname_len = strlen(szResType);
- if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0
- && !isalpha(name[resname_len + 1])) {
- number = atoi(name.c_str() + resname_len + 1);
- bAdd = true;
- }
- }
-
- if (bAdd) {
- psrcPatch = new ResourceSource;
- psrcPatch->source_type = kSourcePatch;
- psrcPatch->location_name = name;
- processPatch(psrcPatch, (ResourceType)i, number);
- }
- }
- }
-}
-
-int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
- Common::File file;
- Resource *res;
- ResourceType type;
- uint16 number, id;
- uint32 offset;
-
- if (!file.open(map->location_name))
- return SCI_ERROR_RESMAP_NOT_FOUND;
-
- file.seek(0, SEEK_SET);
-
- byte bMask = 0xFC;
- // FIXME: The code above seems to give correct results for Jones
- //byte bMask = _mapVersion == SCI_VERSION_01_VGA_ODD ? 0xF0 : 0xFC;
- byte bShift = _mapVersion == SCI_VERSION_01_VGA_ODD ? 28 : 26;
-
- do {
- id = file.readUint16LE();
- offset = file.readUint32LE();
-
- if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
- return SCI_ERROR_RESMAP_NOT_FOUND;
- }
- if (offset == 0xFFFFFFFF)
- break;
-
- type = (ResourceType)(id >> 11);
- number = id & 0x7FF;
- uint32 resId = RESOURCE_HASH(type, number);
- // adding a new resource
- if (_resMap.contains(resId) == false) {
- res = new Resource;
- res->id = resId;//id;
- res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF);
- res->number = number;
- res->type = type;
- res->source = getVolume(map, offset >> bShift);
- _resMap.setVal(resId, res);
- }
- } while (!file.eos());
- return 0;
-}
-
-int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
- Common::File file;
- Resource *res;
- if (!file.open(map->location_name))
- return SCI_ERROR_RESMAP_NOT_FOUND;
-
- resource_index_t resMap[32];
- memset(resMap, 0, sizeof(resource_index_t) * 32);
- byte type = 0, prevtype = 0;
- byte nEntrySize = _mapVersion == SCI_VERSION_1_1 ? SCI11_RESMAP_ENTRIES_SIZE : SCI1_RESMAP_ENTRIES_SIZE;
- uint32 resId;
-
- // Read resource type and offsets to resource offsets block from .MAP file
- // The last entry has type=0xFF (0x1F) and offset equals to map file length
- do {
- type = file.readByte() & 0x1F;
- resMap[type].wOffset = file.readUint16LE();
- resMap[prevtype].wSize = (resMap[type].wOffset
- - resMap[prevtype].wOffset) / nEntrySize;
- prevtype = type;
- } while (type != 0x1F); // the last entry is FF
-
- // reading each type's offsets
- uint32 off = 0;
- for (type = 0; type < 32; type++) {
- if (resMap[type].wOffset == 0) // this resource does not exist in map
- continue;
- file.seek(resMap[type].wOffset);
- for (int i = 0; i < resMap[type].wSize; i++) {
- uint16 number = file.readUint16LE();
- int volume_nr = 0;
- if (_mapVersion == SCI_VERSION_1_1) {
- // offset stored in 3 bytes
- off = file.readUint16LE();
- off |= file.readByte() << 16;
- off <<= 1;
- } else {
- // offset/volume stored in 4 bytes
- off = file.readUint32LE();
- if (_mapVersion < SCI_VERSION_1_1) {
- volume_nr = off >> 28; // most significant 4 bits
- off &= 0x0FFFFFFF; // least significant 28 bits
- } else {
- // in SCI32 it's a plain offset
- }
- }
- if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
- return SCI_ERROR_RESMAP_NOT_FOUND;
- }
- resId = RESOURCE_HASH(type, number);
- // adding new resource only if it does not exist
- if (_resMap.contains(resId) == false) {
- res = new Resource;
- _resMap.setVal(resId, res);
- res->type = (ResourceType)type;
- res->number = number;
- res->id = resId;//res->number | (res->type << 16);
- res->source = getVolume(map, volume_nr);
- res->file_offset = off;
- }
- }
- }
- return 0;
-}
-
-int ResourceManager::readResourceInfo(Resource *res, Common::File *file,
- uint32&szPacked, ResourceCompression &compression) {
- // SCI0 volume format: {wResId wPacked+4 wUnpacked wCompression} = 8 bytes
- // SCI1 volume format: {bResType wResNumber wPacked+4 wUnpacked wCompression} = 9 bytes
- // SCI1.1 volume format: {bResType wResNumber wPacked wUnpacked wCompression} = 9 bytes
- // SCI32 volume format : {bResType wResNumber dwPacked dwUnpacked wCompression} = 13 bytes
- uint16 w, number, szUnpacked;
- uint32 wCompression;
- ResourceType type;
-
- switch (_volVersion) {
- case SCI_VERSION_0:
- w = file->readUint16LE();
- type = (ResourceType)(w >> 11);
- number = w & 0x7FF;
- szPacked = file->readUint16LE() - 4;
- szUnpacked = file->readUint16LE();
- wCompression = file->readUint16LE();
- break;
- case SCI_VERSION_1:
- type = (ResourceType)(file->readByte() & 0x7F);
- number = file->readUint16LE();
- szPacked = file->readUint16LE() - 4;
- szUnpacked = file->readUint16LE();
- wCompression = file->readUint16LE();
- break;
- case SCI_VERSION_1_1:
- type = (ResourceType)(file->readByte() & 0x7F);
- number = file->readUint16LE();
- szPacked = file->readUint16LE();
- szUnpacked = file->readUint16LE();
- wCompression = file->readUint16LE();
- break;
-#ifdef ENABLE_SCI32
- case SCI_VERSION_32:
- type = (ResourceType)(file->readByte() &0x7F);
- number = file->readUint16LE();
- szPacked = file->readUint32LE();
- szUnpacked = file->readUint32LE();
- wCompression = file->readUint16LE();
- break;
-#endif
- default:
- return SCI_ERROR_INVALID_RESMAP_ENTRY;
- }
- // check if there were errors while reading
- if (file->ioFailed())
- return SCI_ERROR_IO_ERROR;
- res->id = RESOURCE_HASH(type, number);
- res->type = type;
- res->number = number;
- res->size = szUnpacked;
- // checking compression method
- switch (wCompression) {
- case 0:
- compression = kCompNone;
- break;
- case 1:
- compression = (_sciVersion == SCI_VERSION_0) ? kCompLZW : kCompHuffman;
- break;
- case 2:
- compression = (_sciVersion == SCI_VERSION_0) ? kCompHuffman : kCompLZW1;
- break;
- case 3:
- compression = kCompLZW1View;
- break;
- case 4:
- compression = kCompLZW1Pic;
- break;
- case 18:
- case 19:
- case 20:
- compression = kCompDCL;
- break;
-#ifdef ENABLE_SCI32
- case 32:
- compression = kCompSTACpack;
- break;
-#endif
- default:
- compression = kCompUnknown;
- }
-
- return compression == kCompUnknown ? SCI_ERROR_UNKNOWN_COMPRESSION : 0;
-}
-
-int ResourceManager::decompress(Resource *res, Common::File *file) {
- int error;
- uint32 szPacked = 0;
- ResourceCompression compression = kCompUnknown;
-
- // fill resource info
- error = readResourceInfo(res, file, szPacked, compression);
- if (error)
- return error;
- // getting a decompressor
- Decompressor *dec = NULL;
- switch (compression) {
- case kCompNone:
- dec = new Decompressor;
- break;
- case kCompHuffman:
- dec = new DecompressorHuffman;
- break;
- case kCompLZW:
- case kCompLZW1:
- case kCompLZW1View:
- case kCompLZW1Pic:
- dec = new DecompressorLZW(compression);
- break;
- case kCompDCL:
- dec = new DecompressorDCL;
- break;
-#ifdef ENABLE_SCI32
- case kCompSTACpack:
- dec = new DecompressorLZS;
- break;
-#endif
- default:
- warning("Resource %s #%d: Compression method %d not supported",
- getResourceTypeName(res->type), res->number, compression);
- return SCI_ERROR_UNKNOWN_COMPRESSION;
- }
-
- res->data = new byte[res->size];
- res->status = kResStatusAllocated;
- error = res->data ? dec->unpack(file, res->data, szPacked, res->size) : SCI_ERROR_RESOURCE_TOO_BIG;
- if (error)
- res->unalloc();
-
- delete dec;
- return error;
-}
-
-void ResourceSync::startSync(EngineState *s, reg_t obj) {
- _syncTime = _syncCue = -1;
- PUT_SEL32V(obj, syncCue, 0);
- _ptr = (uint16 *)data;
- //syncStarted = true; // not used
-}
-
-void ResourceSync::nextSync(EngineState *s, reg_t obj) {
- if (_ptr) {
- _syncTime = (int16)READ_LE_UINT16(_ptr);
- if (_syncTime == -1) {
- stopSync();
- } else {
- _syncCue = (int16)READ_LE_UINT16(_ptr + 1);
- _ptr += 2;
- }
- PUT_SEL32V(obj, syncTime, _syncTime);
- PUT_SEL32V(obj, syncCue, _syncCue);
- }
-}
-//--------------------------------
-void ResourceSync::stopSync() {
- _ptr = 0;
- _syncCue = -1;
- //syncStarted = false; // not used
-}
-
-} // End of namespace Sci
diff --git a/engines/sci/scicore/resource.h b/engines/sci/scicore/resource.h
deleted file mode 100644
index e827152c57..0000000000
--- a/engines/sci/scicore/resource.h
+++ /dev/null
@@ -1,302 +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$
- *
- */
-
-#ifndef SCI_SCICORE_RESOURCE_H
-#define SCI_SCICORE_RESOURCE_H
-
-#include "common/str.h"
-#include "common/file.h"
-#include "common/archive.h"
-
-#include "sci/engine/vm.h" // for Object
-#include "sci/scicore/decompressor.h"
-
-namespace Common {
-class ReadStream;
-}
-
-namespace Sci {
-
-/** The maximum allowed size for a compressed or decompressed resource */
-#define SCI_MAX_RESOURCE_SIZE 0x0400000
-
-/*** RESOURCE STATUS TYPES ***/
-enum ResourceStatus {
- kResStatusNoMalloc = 0,
- kResStatusAllocated,
- kResStatusEnqueued, /* In the LRU queue */
- kResStatusLocked /* Allocated and in use */
-};
-
-/*** INITIALIZATION RESULT TYPES ***/
-#define SCI_ERROR_IO_ERROR 1
-#define SCI_ERROR_INVALID_RESMAP_ENTRY 2
-/* Invalid resource.map entry */
-#define SCI_ERROR_RESMAP_NOT_FOUND 3
-#define SCI_ERROR_NO_RESOURCE_FILES_FOUND 4
-/* No resource at all was found */
-#define SCI_ERROR_UNKNOWN_COMPRESSION 5
-#define SCI_ERROR_DECOMPRESSION_ERROR 6
-/* sanity checks failed during decompression */
-#define SCI_ERROR_RESOURCE_TOO_BIG 8
-/* Resource size exceeds SCI_MAX_RESOURCE_SIZE */
-
-/* the first critical error number */
-
-#define SCI_VERSION_1 SCI_VERSION_1_EARLY
-
-#define MAX_OPENED_VOLUMES 5 // Max number of simultaneously opened volumes
-
-enum ResSourceType {
- kSourceDirectory = 0,
- kSourcePatch = 1,
- kSourceVolume = 2,
- kSourceExtMap = 3,
- kSourceIntMap = 4,
- kSourceMask = 127
-};
-
-#define RESSOURCE_ADDRESSING_BASIC 0
-#define RESSOURCE_ADDRESSING_EXTENDED 128
-#define RESSOURCE_ADDRESSING_MASK 128
-
-#define RESOURCE_HASH(type, number) (uint32)((type<<16) | number)
-#define SCI0_RESMAP_ENTRIES_SIZE 6
-#define SCI1_RESMAP_ENTRIES_SIZE 6
-#define SCI11_RESMAP_ENTRIES_SIZE 5
-
-extern const char *sci_error_types[];
-extern const char *sci_version_types[];
-extern const int sci_max_resource_nr[]; /* Highest possible resource numbers */
-
-
-enum ResourceType {
- kResourceTypeView = 0,
- kResourceTypePic,
- kResourceTypeScript,
- kResourceTypeText,
- kResourceTypeSound,
- kResourceTypeMemory,
- kResourceTypeVocab,
- kResourceTypeFont,
- kResourceTypeCursor,
- kResourceTypePatch,
- kResourceTypeBitmap,
- kResourceTypePalette,
- kResourceTypeCdAudio,
- kResourceTypeAudio,
- kResourceTypeSync,
- kResourceTypeMessage,
- kResourceTypeMap,
- kResourceTypeHeap,
- kResourceTypeInvalid
-};
-
-const char *getResourceTypeName(ResourceType restype);
-// Suffixes for SCI1 patch files
-const char *getResourceTypeSuffix(ResourceType restype);
-
-#define sci0_last_resource kResourceTypePatch
-#define sci1_last_resource kResourceTypeHeap
-/* Used for autodetection */
-
-
-// resource type for SCI1 resource.map file
-struct resource_index_t {
- uint16 wOffset;
- uint16 wSize;
-};
-
-struct ResourceSource {
- ResSourceType source_type;
- bool scanned;
- Common::String location_name; // FIXME: Replace by FSNode ?
- int volume_number;
- ResourceSource *associated_map;
- ResourceSource *next;
-};
-
-/** Class for storing resources in memory */
-class Resource {
-public:
- Resource();
- ~Resource();
- void unalloc();
-
-// NOTE : Currently all member data has the same name and public visibility
-// to let the rest of the engine compile without changes
-public:
- byte *data;
- uint16 number;
- ResourceType type;
- uint32 id; // contains number and type.
- unsigned int size;
- unsigned int file_offset; /* Offset in file */
- ResourceStatus status;
- unsigned short lockers; /* Number of places where this resource was locked */
- ResourceSource *source;
-};
-
-
-class ResourceManager {
-public:
- int _sciVersion; /* SCI resource version to use */
- int _mapVersion; // RESOURCE.MAP version
- int _volVersion; // RESOURCE.0xx version
-
- /**
- * Creates a new SCI resource manager.
- * @param version The SCI version to look for; use SCI_VERSION_AUTODETECT
- * in the default case.
- * @param maxMemory Maximum number of bytes to allow allocated for resources
- *
- * @note maxMemory will not be interpreted as a hard limit, only as a restriction
- * for resources which are not explicitly locked. However, a warning will be
- * issued whenever this limit is exceeded.
- */
- ResourceManager(int version, int maxMemory);
- ~ResourceManager();
-
- //! Looks up a resource's data
- /** @param type: The resource type to look for
- * @param number: The resource number to search
- * @param lock: non-zero iff the resource should be locked
- * @return (Resource *): The resource, or NULL if it doesn't exist
- * @note Locked resources are guaranteed not to have their contents freed until
- * they are unlocked explicitly (by unlockResource).
- */
- Resource *findResource(ResourceType type, int number, int lock);
-
- /* Unlocks a previously locked resource
- ** (Resource *) res: The resource to free
- ** (int) number: Number of the resource to check (ditto)
- ** (ResourceType) type: Type of the resource to check (for error checking)
- ** Returns : (void)
- */
- void unlockResource(Resource *res, int restype, ResourceType resnum);
-
- /* Tests whether a resource exists
- ** (ResourceType) type: Type of the resource to check
- ** (int) number: Number of the resource to check
- ** Returns : (Resource *) non-NULL if the resource exists, NULL otherwise
- ** This function may often be much faster than finding the resource
- ** and should be preferred for simple tests.
- ** The resource object returned is, indeed, the resource in question, but
- ** it should be used with care, as it may be unallocated.
- ** Use scir_find_resource() if you want to use the data contained in the resource.
- */
- Resource *testResource(ResourceType type, int number);
-
-protected:
- int _maxMemory; // Config option: Maximum total byte number allocated
- ResourceSource *_sources;
- int _memoryLocked; // Amount of resource bytes in locked memory
- int _memoryLRU; // Amount of resource bytes under LRU control
- Common::List<Resource *> _LRU; // Last Resource Used list
- Common::HashMap<uint32, Resource *> _resMap;
- Common::List<Common::File *> _volumeFiles; // list of opened volume files
-
- /* Add a path to the resource manager's list of sources.
- ** Returns: A pointer to the added source structure, or NULL if an error occurred.
- */
- ResourceSource *addPatchDir(const char *path);
-
- ResourceSource *getVolume(ResourceSource *map, int volume_nr);
-
- //! Add a volume to the resource manager's list of sources.
- /** @param map The map associated with this volume
- * @param filename The name of the volume to add
- * @param extended_addressing 1 if this volume uses extended addressing,
- * 0 otherwise.
- * @return A pointer to the added source structure, or NULL if an error occurred.
- */
- ResourceSource *addVolume(ResourceSource *map, const char *filename,
- int number, int extended_addressing);
- //! Add an external (i.e. separate file) map resource to the resource manager's list of sources.
- /** @param file_name The name of the volume to add
- * @return A pointer to the added source structure, or NULL if an error occurred.
- */
- ResourceSource *addExternalMap(const char *file_name);
- //! Scans newly registered resource sources for resources, earliest addition first.
- /** @param detected_version: Pointer to the detected version number,
- * used during startup. May be NULL.
- * @return One of SCI_ERROR_*.
- */
- int scanNewSources(ResourceSource *source);
- int addAppropriateSources();
- void freeResourceSources(ResourceSource *rss);
-
- Common::File *getVolumeFile(const char *filename);
- void loadResource(Resource *res);
- bool loadFromPatchFile(Resource *res);
- void freeOldResources(int last_invulnerable);
- int decompress(Resource *res, Common::File *file);
- int readResourceInfo(Resource *res, Common::File *file, uint32&szPacked, ResourceCompression &compression);
-
- /**--- Resource map decoding functions ---*/
- int detectMapVersion();
- int detectVolVersion();
-
- /* Reads the SCI0 resource.map file from a local directory
- ** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
- */
- int readResourceMapSCI0(ResourceSource *map);
-
- /* Reads the SCI1 resource.map file from a local directory
- ** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
- */
- int readResourceMapSCI1(ResourceSource *map);
-
- /**--- Patch management functions ---*/
-
- //! Reads patch files from a local directory
- /** @paramParameters: ResourceSource *source
- */
- void readResourcePatches(ResourceSource *source);
- void processPatch(ResourceSource *source, ResourceType restype, int resnumber);
-
- void printLRU();
- void addToLRU(Resource *res);
- void removeFromLRU(Resource *res);
-};
-
-class ResourceSync : public Resource {
-public:
- ResourceSync() {}
- ~ResourceSync() {}
-
- void startSync(EngineState *s, reg_t obj);
- void nextSync(EngineState *s, reg_t obj);
- void stopSync();
-
-protected:
- uint16 *_ptr;
- int16 _syncTime, _syncCue;
- //bool _syncStarted; // not used
-};
-
-} // End of namespace Sci
-
-#endif // SCI_SCICORE_RESOURCE_H
diff --git a/engines/sci/scicore/sciconsole.h b/engines/sci/scicore/sciconsole.h
deleted file mode 100644
index b2060143aa..0000000000
--- a/engines/sci/scicore/sciconsole.h
+++ /dev/null
@@ -1,130 +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$
- *
- */
-
-/* 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
diff --git a/engines/sci/scicore/vocab_debug.cpp b/engines/sci/scicore/vocab_debug.cpp
deleted file mode 100644
index caafa32ca7..0000000000
--- a/engines/sci/scicore/vocab_debug.cpp
+++ /dev/null
@@ -1,518 +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$
- *
- */
-
-#include "sci/sci.h"
-#include "sci/engine/state.h"
-#include "sci/scicore/resource.h"
-
-namespace Sci {
-
-// Default kernel name table
-#define SCI0_KNAMES_WELL_DEFINED 0x6e
-#define SCI0_KNAMES_DEFAULT_ENTRIES_NR 0x72
-#define SCI1_KNAMES_DEFAULT_ENTRIES_NR 0x7E
-
-static const char *sci0_default_knames[SCI0_KNAMES_DEFAULT_ENTRIES_NR] = {
- /*0x00*/ "Load",
- /*0x01*/ "UnLoad",
- /*0x02*/ "ScriptID",
- /*0x03*/ "DisposeScript",
- /*0x04*/ "Clone",
- /*0x05*/ "DisposeClone",
- /*0x06*/ "IsObject",
- /*0x07*/ "RespondsTo",
- /*0x08*/ "DrawPic",
- /*0x09*/ "Show",
- /*0x0a*/ "PicNotValid",
- /*0x0b*/ "Animate",
- /*0x0c*/ "SetNowSeen",
- /*0x0d*/ "NumLoops",
- /*0x0e*/ "NumCels",
- /*0x0f*/ "CelWide",
- /*0x10*/ "CelHigh",
- /*0x11*/ "DrawCel",
- /*0x12*/ "AddToPic",
- /*0x13*/ "NewWindow",
- /*0x14*/ "GetPort",
- /*0x15*/ "SetPort",
- /*0x16*/ "DisposeWindow",
- /*0x17*/ "DrawControl",
- /*0x18*/ "HiliteControl",
- /*0x19*/ "EditControl",
- /*0x1a*/ "TextSize",
- /*0x1b*/ "Display",
- /*0x1c*/ "GetEvent",
- /*0x1d*/ "GlobalToLocal",
- /*0x1e*/ "LocalToGlobal",
- /*0x1f*/ "MapKeyToDir",
- /*0x20*/ "DrawMenuBar",
- /*0x21*/ "MenuSelect",
- /*0x22*/ "AddMenu",
- /*0x23*/ "DrawStatus",
- /*0x24*/ "Parse",
- /*0x25*/ "Said",
- /*0x26*/ "SetSynonyms",
- /*0x27*/ "HaveMouse",
- /*0x28*/ "SetCursor",
- /*0x29*/ "FOpen",
- /*0x2a*/ "FPuts",
- /*0x2b*/ "FGets",
- /*0x2c*/ "FClose",
- /*0x2d*/ "SaveGame",
- /*0x2e*/ "RestoreGame",
- /*0x2f*/ "RestartGame",
- /*0x30*/ "GameIsRestarting",
- /*0x31*/ "DoSound",
- /*0x32*/ "NewList",
- /*0x33*/ "DisposeList",
- /*0x34*/ "NewNode",
- /*0x35*/ "FirstNode",
- /*0x36*/ "LastNode",
- /*0x37*/ "EmptyList",
- /*0x38*/ "NextNode",
- /*0x39*/ "PrevNode",
- /*0x3a*/ "NodeValue",
- /*0x3b*/ "AddAfter",
- /*0x3c*/ "AddToFront",
- /*0x3d*/ "AddToEnd",
- /*0x3e*/ "FindKey",
- /*0x3f*/ "DeleteKey",
- /*0x40*/ "Random",
- /*0x41*/ "Abs",
- /*0x42*/ "Sqrt",
- /*0x43*/ "GetAngle",
- /*0x44*/ "GetDistance",
- /*0x45*/ "Wait",
- /*0x46*/ "GetTime",
- /*0x47*/ "StrEnd",
- /*0x48*/ "StrCat",
- /*0x49*/ "StrCmp",
- /*0x4a*/ "StrLen",
- /*0x4b*/ "StrCpy",
- /*0x4c*/ "Format",
- /*0x4d*/ "GetFarText",
- /*0x4e*/ "ReadNumber",
- /*0x4f*/ "BaseSetter",
- /*0x50*/ "DirLoop",
- /*0x51*/ "CanBeHere",
- /*0x52*/ "OnControl",
- /*0x53*/ "InitBresen",
- /*0x54*/ "DoBresen",
- /*0x55*/ "DoAvoider",
- /*0x56*/ "SetJump",
- /*0x57*/ "SetDebug",
- /*0x58*/ "InspectObj",
- /*0x59*/ "ShowSends",
- /*0x5a*/ "ShowObjs",
- /*0x5b*/ "ShowFree",
- /*0x5c*/ "MemoryInfo",
- /*0x5d*/ "StackUsage",
- /*0x5e*/ "Profiler",
- /*0x5f*/ "GetMenu",
- /*0x60*/ "SetMenu",
- /*0x61*/ "GetSaveFiles",
- /*0x62*/ "GetCWD",
- /*0x63*/ "CheckFreeSpace",
- /*0x64*/ "ValidPath",
- /*0x65*/ "CoordPri",
- /*0x66*/ "StrAt",
- /*0x67*/ "DeviceInfo",
- /*0x68*/ "GetSaveDir",
- /*0x69*/ "CheckSaveGame",
- /*0x6a*/ "ShakeScreen",
- /*0x6b*/ "FlushResources",
- /*0x6c*/ "SinMult",
- /*0x6d*/ "CosMult",
- /*0x6e*/ "SinDiv",
- /*0x6f*/ "CosDiv",
- /*0x70*/ "Graph",
- /*0x71*/ SCRIPT_UNKNOWN_FUNCTION_STRING
-};
-
-static const char *sci1_default_knames[SCI1_KNAMES_DEFAULT_ENTRIES_NR] = {
- /*0x00*/ "Load",
- /*0x01*/ "UnLoad",
- /*0x02*/ "ScriptID",
- /*0x03*/ "DisposeScript",
- /*0x04*/ "Clone",
- /*0x05*/ "DisposeClone",
- /*0x06*/ "IsObject",
- /*0x07*/ "RespondsTo",
- /*0x08*/ "DrawPic",
- /*0x09*/ "Show",
- /*0x0a*/ "PicNotValid",
- /*0x0b*/ "Animate",
- /*0x0c*/ "SetNowSeen",
- /*0x0d*/ "NumLoops",
- /*0x0e*/ "NumCels",
- /*0x0f*/ "CelWide",
- /*0x10*/ "CelHigh",
- /*0x11*/ "DrawCel",
- /*0x12*/ "AddToPic",
- /*0x13*/ "NewWindow",
- /*0x14*/ "GetPort",
- /*0x15*/ "SetPort",
- /*0x16*/ "DisposeWindow",
- /*0x17*/ "DrawControl",
- /*0x18*/ "HiliteControl",
- /*0x19*/ "EditControl",
- /*0x1a*/ "TextSize",
- /*0x1b*/ "Display",
- /*0x1c*/ "GetEvent",
- /*0x1d*/ "GlobalToLocal",
- /*0x1e*/ "LocalToGlobal",
- /*0x1f*/ "MapKeyToDir",
- /*0x20*/ "DrawMenuBar",
- /*0x21*/ "MenuSelect",
- /*0x22*/ "AddMenu",
- /*0x23*/ "DrawStatus",
- /*0x24*/ "Parse",
- /*0x25*/ "Said",
- /*0x26*/ "SetSynonyms",
- /*0x27*/ "HaveMouse",
- /*0x28*/ "SetCursor",
- /*0x29*/ "SaveGame",
- /*0x2a*/ "RestoreGame",
- /*0x2b*/ "RestartGame",
- /*0x2c*/ "GameIsRestarting",
- /*0x2d*/ "DoSound",
- /*0x2e*/ "NewList",
- /*0x2f*/ "DisposeList",
- /*0x30*/ "NewNode",
- /*0x31*/ "FirstNode",
- /*0x32*/ "LastNode",
- /*0x33*/ "EmptyList",
- /*0x34*/ "NextNode",
- /*0x35*/ "PrevNode",
- /*0x36*/ "NodeValue",
- /*0x37*/ "AddAfter",
- /*0x38*/ "AddToFront",
- /*0x39*/ "AddToEnd",
- /*0x3a*/ "FindKey",
- /*0x3b*/ "DeleteKey",
- /*0x3c*/ "Random",
- /*0x3d*/ "Abs",
- /*0x3e*/ "Sqrt",
- /*0x3f*/ "GetAngle",
- /*0x40*/ "GetDistance",
- /*0x41*/ "Wait",
- /*0x42*/ "GetTime",
- /*0x43*/ "StrEnd",
- /*0x44*/ "StrCat",
- /*0x45*/ "StrCmp",
- /*0x46*/ "StrLen",
- /*0x47*/ "StrCpy",
- /*0x48*/ "Format",
- /*0x49*/ "GetFarText",
- /*0x4a*/ "ReadNumber",
- /*0x4b*/ "BaseSetter",
- /*0x4c*/ "DirLoop",
- /*0x4d*/ "CanBeHere",
- /*0x4e*/ "OnControl",
- /*0x4f*/ "InitBresen",
- /*0x50*/ "DoBresen",
- /*0x51*/ SCRIPT_UNKNOWN_FUNCTION_STRING, // DoAvoider is not implemented in SCI1
- /*0x52*/ "SetJump",
- /*0x53*/ "SetDebug",
- /*0x54*/ "InspectObj",
- /*0x55*/ "ShowSends",
- /*0x56*/ "ShowObjs",
- /*0x57*/ "ShowFree",
- /*0x58*/ "MemoryInfo",
- /*0x59*/ "StackUsage",
- /*0x5a*/ "Profiler",
- /*0x5b*/ "GetMenu",
- /*0x5c*/ "SetMenu",
- /*0x5d*/ "GetSaveFiles",
- /*0x5e*/ "GetCWD",
- /*0x5f*/ "CheckFreeSpace",
- /*0x60*/ "ValidPath",
- /*0x61*/ "CoordPri",
- /*0x62*/ "StrAt",
- /*0x63*/ "DeviceInfo",
- /*0x64*/ "GetSaveDir",
- /*0x65*/ "CheckSaveGame",
- /*0x66*/ "ShakeScreen",
- /*0x67*/ "FlushResources",
- /*0x68*/ "SinMult",
- /*0x69*/ "CosMult",
- /*0x6a*/ "SinDiv",
- /*0x6b*/ "CosDiv",
- /*0x6c*/ "Graph",
- /*0x6d*/ "Joystick",
- /*0x6e*/ "ShiftScreen",
- /*0x6f*/ "Palette",
- /*0x70*/ "MemorySegment",
- /*0x71*/ "MoveCursor",
- /*0x72*/ "Memory",
- /*0x73*/ "ListOps",
- /*0x74*/ "FileIO",
- /*0x75*/ "DoAudio",
- /*0x76*/ "DoSync",
- /*0x77*/ "AvoidPath",
- /*0x78*/ "Sort",
- /*0x79*/ "ATan",
- /*0x7a*/ "Lock",
- /*0x7b*/ "StrSplit",
- /*0x7c*/ "Message",
- /*0x7d*/ "IsItSkip"
-};
-
-#if 0
-int *vocabulary_get_classes(ResourceManager *resmgr, int* count) {
- Resource* r;
- int *c;
- unsigned int i;
-
- if ((r = resmgr->findResource(kResourceTypeVocab, 996, 0)) == NULL)
- return 0;
-
- c = (int *)malloc(sizeof(int) * r->size / 2);
- for (i = 2; i < r->size; i += 4) {
- c[i/4] = READ_LE_UINT16(r->data + i);
- }
- *count = r->size / 4;
-
- return c;
-}
-
-int vocabulary_get_class_count(ResourceManager *resmgr) {
- Resource* r;
-
- if ((r = resmgr->findResource(kResourceTypeVocab, 996, 0)) == 0)
- return 0;
-
- return r->size / 4;
-}
-#endif
-
-bool vocabulary_get_snames(ResourceManager *resmgr, bool isOldSci0, Common::StringList &selectorNames) {
- int count;
-
- Resource *r = resmgr->findResource(kResourceTypeVocab, 997, 0);
-
- if (!r) // No such resource?
- return false;
-
- count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
-
- for (int i = 0; i < count; i++) {
- int offset = READ_LE_UINT16(r->data + 2 + i * 2);
- int len = READ_LE_UINT16(r->data + offset);
-
- Common::String tmp((const char *)r->data + offset + 2, len);
- selectorNames.push_back(tmp);
-
- // Early SCI versions used the LSB in the selector ID as a read/write
- // toggle. To compensate for that, we add every selector name twice.
- if (isOldSci0)
- selectorNames.push_back(tmp);
- }
-
- return true;
-}
-
-int vocabulary_lookup_sname(const Common::StringList &selectorNames, const char *sname) {
- for (uint pos = 0; pos < selectorNames.size(); ++pos) {
- if (selectorNames[pos] == sname)
- return pos;
- }
-
- return -1;
-}
-
-opcode* vocabulary_get_opcodes(ResourceManager *resmgr) {
- opcode* o;
- int count, i = 0;
- Resource* r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES, 0);
-
- // if the resource couldn't be loaded, leave
- if (r == NULL) {
- fprintf(stderr, "unable to load vocab.%03d\n", VOCAB_RESOURCE_OPCODES);
- return NULL;
- }
-
- count = READ_LE_UINT16(r->data);
-
- o = (opcode*)malloc(sizeof(opcode) * 256);
- for (i = 0; i < count; i++) {
- int offset = READ_LE_UINT16(r->data + 2 + i * 2);
- int len = READ_LE_UINT16(r->data + offset) - 2;
- o[i].type = READ_LE_UINT16(r->data + offset + 2);
- o[i].number = i;
- o[i].name = (char *)malloc(len + 1);
- memcpy(o[i].name, r->data + offset + 4, len);
- o[i].name[len] = '\0';
-#ifdef VOCABULARY_DEBUG
- printf("Opcode %02X: %s, %d\n", i, o[i].name, o[i].type);
-#endif
- }
- for (i = count; i < 256; i++) {
- o[i].type = 0;
- o[i].number = i;
- o[i].name = (char *)malloc(strlen("undefined") + 1);
- strcpy(o[i].name, "undefined");
- }
- return o;
-}
-
-void vocabulary_free_opcodes(opcode *opcodes) {
- int i;
- if (!opcodes)
- return;
-
- for (i = 0; i < 256; i++) {
- if (opcodes[i].name)
- free(opcodes[i].name);
- }
- free(opcodes);
-}
-
-// Alternative kernel func names retriever. Required for KQ1/SCI (at least).
-static void _vocabulary_get_knames0alt(const Resource *r, Common::StringList &names) {
- uint idx = 0;
-
- while (idx < r->size) {
- Common::String tmp((const char *)r->data + idx);
- names.push_back(tmp);
- idx += tmp.size() + 1;
- }
-
- // The mystery kernel function- one in each SCI0 package
- names.push_back(SCRIPT_UNKNOWN_FUNCTION_STRING);
-}
-
-static void vocabulary_get_knames0(ResourceManager *resmgr, Common::StringList &names) {
- int count, i, index = 2, empty_to_add = 1;
- Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0);
-
- if (!r) { // No kernel name table found? Fall back to default table
- names.resize(SCI0_KNAMES_DEFAULT_ENTRIES_NR);
- for (i = 0; i < SCI0_KNAMES_DEFAULT_ENTRIES_NR; i++)
- names[i] = sci0_default_knames[i];
- return;
- }
-
- count = READ_LE_UINT16(r->data);
-
- if (count > 1023) {
- _vocabulary_get_knames0alt(r, names);
- return;
- }
-
- if (count < SCI0_KNAMES_WELL_DEFINED) {
- empty_to_add = SCI0_KNAMES_WELL_DEFINED - count;
- sciprintf("Less than %d kernel functions; adding %d\n", SCI0_KNAMES_WELL_DEFINED, empty_to_add);
- }
-
- names.resize(count + 1 + empty_to_add);
-
- for (i = 0; i < count; i++) {
- int offset = READ_LE_UINT16(r->data + index);
- int len = READ_LE_UINT16(r->data + offset);
- //fprintf(stderr,"Getting name %d of %d...\n", i, count);
- index += 2;
- names[i] = Common::String((const char *)r->data + offset + 2, len);
- }
-
- for (i = 0; i < empty_to_add; i++) {
- names[count + i] = SCRIPT_UNKNOWN_FUNCTION_STRING;
- }
-}
-
-static void vocabulary_get_knames1(ResourceManager *resmgr, Common::StringList &names) {
- // vocab.999/999.voc is notoriously unreliable in SCI1 games, and should not be used
- // We hardcode the default SCI1 kernel names here (i.e. the ones inside the "special"
- // 999.voc file from FreeSCI). All SCI1 games seem to be working with this change, but
- // if any SCI1 game has different kernel vocabulary names, it might not work. It seems
- // that all SCI1 games use the same kernel vocabulary names though, so this seems to be
- // a safe change. If there's any SCI1 game with different kernel vocabulary names, we can
- // add special flags to it to our detector
-
- names.resize(SCI1_KNAMES_DEFAULT_ENTRIES_NR);
- for (int i = 0; i < SCI1_KNAMES_DEFAULT_ENTRIES_NR; i++)
- names[i] = sci1_default_knames[i];
-}
-
-#ifdef ENABLE_SCI32
-static void vocabulary_get_knames11(ResourceManager *resmgr, Common::StringList &names) {
-/*
- 999.voc format for SCI1.1 games:
- [b] # of kernel functions
- [w] unknown
- [offset to function name info]
- ...
- {[w name-len][function name]}
- ...
-*/
- //unsigned int size = 64, pos = 3;
- int len;
- Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0);
- if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos)
- return; // FIXME: should return a default table for this engine
- const byte nCnt = *r->data;
-
- names.resize(nCnt);
- for (int i = 0; i < nCnt; i++) {
- int off = READ_LE_UINT16(r->data + 2 * i + 2);
- len = READ_LE_UINT16(r->data + off);
- names[i] = Common::String((char *)r->data + off + 2, len);
- }
-}
-#endif
-
-void vocabulary_get_knames(ResourceManager *resmgr, Common::StringList &names) {
- names.clear();
-
- switch (resmgr->_sciVersion) {
- case SCI_VERSION_0:
- case SCI_VERSION_01:
- vocabulary_get_knames0(resmgr, names);
- break;
- case SCI_VERSION_01_VGA:
- case SCI_VERSION_01_VGA_ODD:
- // HACK: KQ5 needs the SCI1 default vocabulary names to work correctly.
- // Having more vocabulary names (like in SCI1) doesn't seem to have any
- // ill effects, other than resulting in unmapped functions towards the
- // end, which are never used by the game interpreter anyway
- // return vocabulary_get_knames0(resmgr, count);
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
- vocabulary_get_knames1(resmgr, names);
- break;
- case SCI_VERSION_1_1:
- vocabulary_get_knames1(resmgr, names);
- break;
-#ifdef ENABLE_SCI32
- case SCI_VERSION_32:
- vocabulary_get_knames11(resmgr, names);
-#endif
- break;
- default:
- break;
- }
-}
-
-} // End of namespace Sci
diff --git a/engines/sci/scicore/vocabulary.cpp b/engines/sci/scicore/vocabulary.cpp
deleted file mode 100644
index af63a9803a..0000000000
--- a/engines/sci/scicore/vocabulary.cpp
+++ /dev/null
@@ -1,566 +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$
- *
- */
-
-// Main vocabulary support functions and word lookup
-
-#include "sci/scicore/vocabulary.h"
-#include "sci/scicore/resource.h"
-#include "sci/engine/state.h"
-#include "sci/engine/kernel.h"
-
-namespace Sci {
-
-int vocab_version;
-
-#define VOCAB_RESOURCE_PARSE_TREE_BRANCHES vocab_version == 1 ? \
- VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES : \
- VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES
-
-#define VOCAB_RESOURCE_SUFFIX_VOCAB vocab_version==1 ? \
- VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB : \
- VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB
-
-
-/*
-// These strange names were taken from an SCI01 interpreter
-const char *class_names[] = {"",
- "",
- "conj", // conjunction
- "ass", // ?
- "pos", // preposition ?
- "art", // article
- "adj", // adjective
- "pron", // pronoun
- "noun", // noun
- "auxv", // auxillary verb
- "adv", // adverb
- "verb", // verb
- "",
- "",
- "",
- ""
- };
-*/
-
-bool vocab_get_words(ResourceManager *resmgr, WordMap &words) {
-
- char currentword[256] = ""; // They're not going to use words longer than 255 ;-)
- int currentwordpos = 0;
-
- Resource *resource;
-
- // First try to load the SCI0 vocab resource.
- resource = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB, 0);
- vocab_version = 0;
-
- if (!resource) {
- warning("SCI0: Could not find a main vocabulary, trying SCI01");
- resource = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB, 0);
- vocab_version = 1;
- }
-
- if (!resource) {
- warning("SCI1: Could not find a main vocabulary");
- return false; // NOT critical: SCI1 games and some demos don't have one!
- }
-
- unsigned int seeker;
- if (vocab_version == 1)
- seeker = 255 * 2; // vocab.900 starts with 255 16-bit pointers which we don't use
- else
- seeker = 26 * 2; // vocab.000 starts with 26 16-bit pointers which we don't use
-
- if (resource->size < seeker) {
- fprintf(stderr, "Invalid main vocabulary encountered: Too small\n");
- return false;
- // Now this ought to be critical, but it'll just cause parse() and said() not to work
- }
-
- words.clear();
-
- while (seeker < resource->size) {
- byte c;
-
- currentwordpos = resource->data[seeker++]; // Parts of previous words may be re-used
-
- if (vocab_version == 1) {
- c = 1;
- while (seeker < resource->size && currentwordpos < 255 && c) {
- c = resource->data[seeker++];
- currentword[currentwordpos++] = c;
- }
- if (seeker == resource->size) {
- warning("SCI1: Vocabulary not usable, disabling");
- words.clear();
- return false;
- }
- } else {
- do {
- c = resource->data[seeker++];
- currentword[currentwordpos++] = c & 0x7f; // 0x80 is used to terminate the string
- } while (c < 0x80);
- }
-
- currentword[currentwordpos] = 0;
-
- // Now decode class and group:
- c = resource->data[seeker + 1];
- ResultWord newWord;
- newWord._class = ((resource->data[seeker]) << 4) | ((c & 0xf0) >> 4);
- newWord._group = (resource->data[seeker + 2]) | ((c & 0x0f) << 8);
-
- // Add the word to the list
- words[currentword] = newWord;
-
- seeker += 3;
- }
-
- return true;
-}
-
-const char *vocab_get_any_group_word(int group, const WordMap &words) {
- if (group == VOCAB_MAGIC_NUMBER_GROUP)
- return "{number}";
-
- for (WordMap::const_iterator i = words.begin(); i != words.end(); ++i)
- if (i->_value._group == group)
- return i->_key.c_str();
-
- return "{invalid}";
-}
-
-bool vocab_get_suffixes(ResourceManager *resmgr, SuffixList &suffixes) {
- Resource *resource = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SUFFIX_VOCAB, 1);
- unsigned int seeker = 1;
-
- if (!resource) {
- warning("Could not find suffix vocabulary");
- return false; // Not critical
- }
-
- while ((seeker < resource->size - 1) && (resource->data[seeker + 1] != 0xff)) {
- suffix_t suffix;
-
- suffix.alt_suffix = (const char *)resource->data + seeker;
- suffix.alt_suffix_length = strlen(suffix.alt_suffix);
- seeker += suffix.alt_suffix_length + 1; // Hit end of string
-
- suffix.class_mask = (int16)READ_BE_UINT16(resource->data + seeker);
- seeker += 2;
-
- // Beginning of next string - skip leading '*'
- seeker++;
-
- suffix.word_suffix = (const char *)resource->data + seeker;
- suffix.word_suffix_length = strlen(suffix.word_suffix);
- seeker += suffix.word_suffix_length + 1;
-
- suffix.result_class = (int16)READ_BE_UINT16(resource->data + seeker);
- seeker += 3; // Next entry
-
- suffixes.push_back(suffix);
- }
-
- return true;
-}
-
-void vocab_free_suffixes(ResourceManager *resmgr, SuffixList &suffixes) {
- resmgr->unlockResource(resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SUFFIX_VOCAB, 0),
- VOCAB_RESOURCE_SUFFIX_VOCAB, kResourceTypeVocab);
-
- suffixes.clear();
-}
-
-bool vocab_get_branches(ResourceManager * resmgr, Common::Array<parse_tree_branch_t> &branches) {
- Resource *resource = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_PARSE_TREE_BRANCHES, 0);
-
- branches.clear();
-
- if (!resource) {
- fprintf(stderr, "No parser tree data found!\n");
- return false;
- }
-
- int branches_nr = resource->size / 20;
-
- if (branches_nr == 0) {
- fprintf(stderr, "Parser tree data is empty!\n");
- return false;
- }
-
- branches.resize(branches_nr);
-
- for (int i = 0; i < branches_nr; i++) {
- byte *base = resource->data + i * 20;
-
- branches[i].id = (int16)READ_LE_UINT16(base);
-
- for (int k = 0; k < 9; k++)
- branches[i].data[k] = READ_LE_UINT16(base + 2 + 2 * k);
-
- branches[i].data[9] = 0; // Always terminate
- }
-
- if (!branches[branches_nr - 1].id) // branch lists may be terminated by empty rules
- branches.remove_at(branches_nr - 1);
-
- return true;
-}
-
-
-ResultWord vocab_lookup_word(const char *word, int word_len, const WordMap &words, const SuffixList &suffixes) {
- Common::String tempword(word, word_len);
-
- // Remove all dashes from tempword
- for (uint i = 0; i < tempword.size(); ) {
- if (tempword[i] == '-')
- tempword.deleteChar(i);
- else
- ++i;
- }
-
- // Look it up:
- WordMap::iterator dict_word = words.find(tempword);
-
- // Match found? Return it!
- if (dict_word != words.end()) {
- return dict_word->_value;
- }
-
- // Now try all suffixes
- for (SuffixList::const_iterator suffix = suffixes.begin(); suffix != suffixes.end(); ++suffix)
- if (suffix->alt_suffix_length <= word_len) {
-
- int suff_index = word_len - suffix->alt_suffix_length;
- // Offset of the start of the suffix
-
- if (scumm_strnicmp(suffix->alt_suffix, word + suff_index, suffix->alt_suffix_length) == 0) { // Suffix matched!
- // Terminate word at suffix start position...:
- Common::String tempword2(word, MIN(word_len, suff_index));
-
- // ...and append "correct" suffix
- tempword2 += Common::String(suffix->word_suffix, suffix->word_suffix_length);
-
- dict_word = words.find(tempword2);
-
- if ((dict_word != words.end()) && (dict_word->_value._class & suffix->class_mask)) { // Found it?
- // Use suffix class
- ResultWord tmp = dict_word->_value;
- tmp._class = suffix->result_class;
- return tmp;
- }
- }
- }
-
- // No match so far? Check if it's a number.
-
- ResultWord retval = { -1, -1 };
- char *tester;
- if ((strtol(tempword.c_str(), &tester, 10) >= 0) && (*tester == '\0')) { // Do we have a complete number here?
- ResultWord tmp = { VOCAB_CLASS_NUMBER, VOCAB_MAGIC_NUMBER_GROUP };
- retval = tmp;
- }
-
- return retval;
-}
-
-void vocab_decypher_said_block(EngineState *s, byte *addr) {
- int nextitem;
-
- do {
- nextitem = *addr++;
-
- if (nextitem < 0xf0) {
- nextitem = nextitem << 8 | *addr++;
- sciprintf(" %s[%03x]", vocab_get_any_group_word(nextitem, s->_parserWords), nextitem);
-
- nextitem = 42; // Make sure that group 0xff doesn't abort
- } else switch (nextitem) {
- case 0xf0:
- sciprintf(" ,");
- break;
- case 0xf1:
- sciprintf(" &");
- break;
- case 0xf2:
- sciprintf(" /");
- break;
- case 0xf3:
- sciprintf(" (");
- break;
- case 0xf4:
- sciprintf(" )");
- break;
- case 0xf5:
- sciprintf(" [");
- break;
- case 0xf6:
- sciprintf(" ]");
- break;
- case 0xf7:
- sciprintf(" #");
- break;
- case 0xf8:
- sciprintf(" <");
- break;
- case 0xf9:
- sciprintf(" >");
- break;
- case 0xff:
- break;
- }
- } while (nextitem != 0xff);
-
- sciprintf("\n");
-}
-
-
-#ifdef SCI_SIMPLE_SAID_CODE
-
-static const short _related_words[][2] = { // 0 is backwards, 1 is forward
- {0x800, 0x180}, // preposition
- {0x000, 0x180}, // article
- {0x000, 0x180}, // adjective
- {0x800, 0x000}, // pronoun
- {0x800, 0x180}, // noun
- {0x000, 0x800}, // auxiliary verb
- {0x800, 0x800}, // adverb
- {0x000, 0x180}, // verb
- {0x000, 0x180} // number
-};
-
-int vocab_build_simple_parse_tree(parse_tree_node_t *nodes, WordMap &words) {
- int i, length, pos = 0;
-
- for (i = 0; i < words.size(); ++i) {
- if (words[i]._class != VOCAB_CLASS_ANYWORD) {
- nodes[pos].type = words[i]._class;
- nodes[pos].content.value = words[i]._group;
- pos += 2; // Link information is filled in below
- }
- }
- nodes[pos].type = -1; // terminate
- length = pos >> 1;
-
- // now find all referenced words
-#ifdef SCI_SIMPLE_SAID_DEBUG
- sciprintf("Semantic references:\n");
-#endif
-
- for (i = 0; i < length; i++) {
- int j;
- int searchmask;
- int type;
-
- pos = (i << 1);
- type = sci_ffs(nodes[pos].type);
-
- if (type) {
- int found = -1;
-
- type -= 5; // 1 because ffs starts counting at 1, 4 because nodes[pos].type is a nibble off
- if (type < 0)
- type = 0;
-#ifdef SCI_SIMPLE_SAID_DEBUG
- sciprintf("#%d: Word %04x: type %04x\n", i, nodes[pos].content.value, type);
-#endif
-
- // search backwards
- searchmask = _related_words[type][0];
- if (searchmask) {
- for (j = i - 1; j >= 0; j--)
- if (nodes[j << 1].type & searchmask) {
- found = j << 1;
- break;
- }
- }
- nodes[pos+1].content.branches[0] = found;
-#ifdef SCI_SIMPLE_SAID_DEBUG
- if (found > -1)
- sciprintf(" %d <\n", found >> 1);
-#endif
-
- // search forward
- found = -1;
- searchmask = _related_words[type][1];
- if (searchmask) {
- for (j = i + 1; j < length; j++)
- if (nodes[j << 1].type & searchmask) {
- found = j << 1;
- break;
- }
- }
-#ifdef SCI_SIMPLE_SAID_DEBUG
- if (found > -1)
- sciprintf(" > %d\n", found >> 1);
-#endif
- } else {
-#ifdef SCI_SIMPLE_SAID_DEBUG
- sciprintf("#%d: Untypified word\n", i); /* Weird, but not fatal */
-#endif
- nodes[pos + 1].content.branches[0] = -1;
- nodes[pos + 1].content.branches[1] = -1;
- }
- }
-#ifdef SCI_SIMPLE_SAID_DEBUG
- sciprintf("/Semantic references.\n");
-#endif
-
- return 0;
-}
-#endif
-
-bool vocab_tokenize_string(ResultWordList &retval, const char *sentence, const WordMap &words,
- const SuffixList &suffixes, char **error) {
- const char *lastword = sentence;
- int pos_in_sentence = 0;
- char c;
- int wordlen = 0;
-
- *error = NULL;
-
- do {
-
- c = sentence[pos_in_sentence++];
-
- if (isalnum(c) || (c == '-' && wordlen))
- ++wordlen;
- // Continue on this word */
- // Words may contain a '-', but may not
- // start with one.
- else {
- if (wordlen) { // Finished a word?
-
- ResultWord lookup_result =
- vocab_lookup_word(lastword, wordlen, words, suffixes);
- // Look it up
-
- if (lookup_result._class == -1) { // Not found?
- *error = (char *)calloc(wordlen + 1, 1);
- strncpy(*error, lastword, wordlen); // Set the offending word
- retval.clear();
- return false; // And return with error
- }
-
- // Copy into list
- retval.push_back(lookup_result);
- }
-
- lastword = sentence + pos_in_sentence;
- wordlen = 0;
- }
-
- } while (c); // Until terminator is hit
-
- return true;
-}
-
-void _vocab_recursive_ptree_dump_treelike(parse_tree_node_t *nodes, int nr, int prevnr) {
- if ((nr > VOCAB_TREE_NODES)/* || (nr < prevnr)*/) {
- sciprintf("Error(%04x)", nr);
- return;
- }
-
- if (nodes[nr].type == PARSE_TREE_NODE_LEAF)
- //sciprintf("[%03x]%04x", nr, nodes[nr].content.value);
- sciprintf("%x", nodes[nr].content.value);
- else {
- int lbranch = nodes[nr].content.branches[0];
- int rbranch = nodes[nr].content.branches[1];
- //sciprintf("<[%03x]", nr);
- sciprintf("<");
-
- if (lbranch)
- _vocab_recursive_ptree_dump_treelike(nodes, lbranch, nr);
- else
- sciprintf("NULL");
-
- sciprintf(",");
-
- if (rbranch)
- _vocab_recursive_ptree_dump_treelike(nodes, rbranch, nr);
- else
- sciprintf("NULL");
-
- sciprintf(">");
- }
-}
-
-void _vocab_recursive_ptree_dump(parse_tree_node_t *nodes, int nr, int prevnr, int blanks) {
- int lbranch = nodes[nr].content.branches[0];
- int rbranch = nodes[nr].content.branches[1];
- int i;
-
- if (nodes[nr].type == PARSE_TREE_NODE_LEAF) {
- sciprintf("vocab_dump_parse_tree: Error: consp is nil for element %03x\n", nr);
- return;
- }
-
- if ((nr > VOCAB_TREE_NODES)/* || (nr < prevnr)*/) {
- sciprintf("Error(%04x))", nr);
- return;
- }
-
- if (lbranch) {
- if (nodes[lbranch].type == PARSE_TREE_NODE_BRANCH) {
- sciprintf("\n");
- for (i = 0; i < blanks; i++)
- sciprintf(" ");
- sciprintf("(");
- _vocab_recursive_ptree_dump(nodes, lbranch, nr, blanks + 1);
- sciprintf(")\n");
- for (i = 0; i < blanks; i++)
- sciprintf(" ");
- } else
- sciprintf("%x", nodes[lbranch].content.value);
- sciprintf(" ");
- }/* else sciprintf ("nil");*/
-
- if (rbranch) {
- if (nodes[rbranch].type == PARSE_TREE_NODE_BRANCH)
- _vocab_recursive_ptree_dump(nodes, rbranch, nr, blanks);
- else
- sciprintf("%x", nodes[rbranch].content.value);
- }/* else sciprintf("nil");*/
-}
-
-void vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes) {
- //_vocab_recursive_ptree_dump_treelike(nodes, 0, 0);
- sciprintf("(setq %s \n'(", tree_name);
- _vocab_recursive_ptree_dump(nodes, 0, 0, 1);
- sciprintf("))\n");
-}
-
-void vocab_synonymize_tokens(ResultWordList &words, const SynonymList &synonyms) {
- if (synonyms.empty())
- return; // No synonyms: Nothing to check
-
- for (ResultWordList::iterator i = words.begin(); i != words.end(); ++i)
- for (SynonymList::const_iterator sync = synonyms.begin(); sync != synonyms.end(); ++sync)
- if (i->_group == sync->replaceant)
- i->_group = sync->replacement;
-}
-
-} // End of namespace Sci
diff --git a/engines/sci/scicore/vocabulary.h b/engines/sci/scicore/vocabulary.h
deleted file mode 100644
index d0c807aebf..0000000000
--- a/engines/sci/scicore/vocabulary.h
+++ /dev/null
@@ -1,359 +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$
- *
- */
-
-#ifndef SCI_SCICORE_VOCABULARY_H
-#define SCI_SCICORE_VOCABULARY_H
-
-#include "common/str.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/list.h"
-
-#include "sci/sci.h"
-
-namespace Sci {
-
-class ResourceManager;
-
-/*#define VOCABULARY_DEBUG */
-/*#define SCI_SIMPLE_SAID_CODE */ /* Whether the simplified Said() matching should be used */
-/*#define SCI_SIMPLE_SAID_DEBUG */ /* uncomment to enable simple said debugging */
-
-
-#define SCRIPT_UNKNOWN_FUNCTION_STRING "[Unknown]"
-/* The string used to identify the "unknown" SCI0 function for each game */
-
-#define PARSE_HEAP_SIZE 64
-/* Number of bytes allocated on the heap to store bad words if parsing fails */
-
-
-struct opcode {
- int type;
- int number;
- char* name;
-};
-
-#define VOCAB_RESOURCE_OPCODES 998
-#define VOCAB_RESOURCE_KNAMES 999
-
-#define VOCAB_RESOURCE_SCI0_MAIN_VOCAB 0
-#define VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES 900
-#define VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB 901
-
-#define VOCAB_RESOURCE_SCI1_MAIN_VOCAB 900
-#define VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES 901
-#define VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB 902
-#define VOCAB_RESOURCE_SCI1_CHAR_TRANSFORMS 913
-
-enum {
- VOCAB_CLASS_PREPOSITION = 0x01,
- VOCAB_CLASS_ARTICLE = 0x02,
- VOCAB_CLASS_ADJECTIVE = 0x04,
- VOCAB_CLASS_PRONOUN = 0x08,
- VOCAB_CLASS_NOUN = 0x10,
- VOCAB_CLASS_INDICATIVE_VERB = 0x20,
- VOCAB_CLASS_ADVERB = 0x40,
- VOCAB_CLASS_IMPERATIVE_VERB = 0x80,
- VOCAB_CLASS_NUMBER = 0x001
-};
-
-extern const char *class_names[]; /* Vocabulary class names */
-
-#define VOCAB_CLASS_ANYWORD 0xff
-/* Anywords are ignored by the parser */
-
-#define VOCAB_MAGIC_NUMBER_GROUP 0xffd /* 0xffe ? */
-/* This word class is used for numbers */
-
-#define VOCAB_TREE_NODES 500
-/* Number of nodes for each parse_tree_node structure */
-
-#define VOCAB_TREE_NODE_LAST_WORD_STORAGE 0x140
-#define VOCAB_TREE_NODE_COMPARE_TYPE 0x146
-#define VOCAB_TREE_NODE_COMPARE_GROUP 0x14d
-#define VOCAB_TREE_NODE_FORCE_STORAGE 0x154
-
-#define SAID_COMMA 0xf0
-#define SAID_AMP 0xf1
-#define SAID_SLASH 0xf2
-#define SAID_PARENO 0xf3
-#define SAID_PARENC 0xf4
-#define SAID_BRACKO 0xf5
-#define SAID_BRACKC 0xf6
-#define SAID_HASH 0xf7
-#define SAID_LT 0xf8
-#define SAID_GT 0xf9
-#define SAID_TERM 0xff
-
-#define SAID_FIRST SAID_COMMA
-
-/* There was no 'last matching word': */
-#define SAID_FULL_MATCH 0xffff
-#define SAID_NO_MATCH 0xfffe
-#define SAID_PARTIAL_MATCH 0xfffd
-
-#define SAID_LONG(x) ((x) << 8)
-
-struct ResultWord {
- int _class; /* Word class */
- int _group; /* Word group */
-};
-
-typedef Common::List<ResultWord> ResultWordList;
-
-typedef Common::HashMap<Common::String, ResultWord, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> WordMap;
-
-
-struct parse_rule_t {
- int id; /* non-terminal ID */
- int first_special; /* first terminal or non-terminal */
- int specials_nr; /* number of terminals and non-terminals */
- int length;
- int data[1]; /* actual data (size 1 to avoid compiler warnings) */
-};
-
-
-struct parse_rule_list_t {
- int terminal; /* Terminal character this rule matches against or 0 for a non-terminal rule */
- parse_rule_t *rule;
- parse_rule_list_t *next;
-};
-
-
-struct suffix_t {
-
- int class_mask; /* the word class this suffix applies to */
- int result_class; /* the word class a word is morphed to if it doesn't fail this check */
-
- int alt_suffix_length; /* String length of the suffix */
- int word_suffix_length; /* String length of the other suffix */
-
- const char *alt_suffix; /* The alternative suffix */
- const char *word_suffix; /* The suffix as used in the word vocabulary */
-
-};
-
-typedef Common::List<suffix_t> SuffixList;
-
-
-struct synonym_t {
- int replaceant; /* The word group to replace */
- int replacement; /* The replacement word group for this one */
-};
-
-typedef Common::List<synonym_t> SynonymList;
-
-struct parse_tree_branch_t {
- int id;
- int data[10];
-};
-
-#define PARSE_TREE_NODE_LEAF 0
-#define PARSE_TREE_NODE_BRANCH 1
-
-
-struct parse_tree_node_t {
- short type; /* leaf or branch */
- union {
- int value; /* For leaves */
- short branches[2]; /* For branches */
- } content;
-};
-
-
-
-/*FIXME: These need freeing functions...*/
-
-#if 0
-int *vocabulary_get_classes(ResourceManager *resmgr, int *count);
-int vocabulary_get_class_count(ResourceManager *resmgr);
-#endif
-
-/**
- * Fills the given StringList with selector names.
- * Returns true upon success, false oterwise.
- */
-bool vocabulary_get_snames(ResourceManager *resmgr, bool isOldSci0, Common::StringList &selectorNames);
-
-/* Look up a selector name in an array, return the index */
-int vocabulary_lookup_sname(const Common::StringList &selectorNames, const char *sname);
-
-
-/**
- * Returns a null terminated array of opcodes.
- */
-opcode *vocabulary_get_opcodes(ResourceManager *resmgr);
-
-void vocabulary_free_opcodes(opcode *opcodes);
-/* Frees a previously allocated list of opcodes
-** Parameters: (opcode *) opcodes: Opcodes to free
-*/
-
-/**
- * Fills a StringList with kernel function names.
- *
- * This function reads the kernel function name table from resource_map,
- * and fills the given StringList with them.
- * The resulting list has the same format regardless of the format of the
- * name table of the resource (the format changed between version 0 and 1).
- */
-void vocabulary_get_knames(ResourceManager *resmgr, Common::StringList &names);
-
-
-/**
- * Gets all words from the main vocabulary.
- * @param resmr The resource manager to read from
- * @param words A list of all words
- * @return true on success, false on failure
- */
-bool vocab_get_words(ResourceManager *resmgr, WordMap &words);
-
-
-bool vocab_get_suffixes(ResourceManager *resmgr, SuffixList &suffixes);
-/* Loads all suffixes from the suffix vocabulary.
-** Parameters: (ResourceManager*) resmgr: Resource manager the resources are
-** read from
-** Returns : true on success, false on failure
-*/
-
-void vocab_free_suffixes(ResourceManager *resmgr, SuffixList &suffixes);
-/* Frees all suffixes in the given list.
-** Parameters: (ResourceManager *) resmgr: The resource manager to free from
-** (SuffixList) suffixes: The suffixes to free
-*/
-
-/**
- * Retrieves all grammar rules from the resource data.
- * @param resmgr Resource manager the rules are read from
- * @param branches The rules are stored into this Array
- * @return true on success, false on error
- */
-bool vocab_get_branches(ResourceManager *resmgr, Common::Array<parse_tree_branch_t> &branches);
-
-ResultWord vocab_lookup_word(const char *word, int word_len,
- const WordMap &words, const SuffixList &suffixes);
-/* Looks up a single word in the words and suffixes list
-** Parameters: (char *) word: Pointer to the word to look up
-** (int) word_len: Length of the word to look up
-** (const WordMap &) words: List of words
-** (SuffixList) suffixes: List of suffixes
-** Returns : (const ResultWordList &) A list containing 1 or 0 words
-*/
-
-
-bool vocab_tokenize_string(ResultWordList &retval, const char *sentence,
- const WordMap &words, const SuffixList &suffixes, char **error);
-/* Tokenizes a string and compiles it into word_ts.
-** Parameters: (char *) sentence: The sentence to examine
-** (const WordMap &) words: The words to scan for
-** (SuffixList) suffixes: suffixes to scan for
-** (char **) error: Points to a malloc'd copy of the offending text or to NULL on error
-** (ResultWordList) retval: A list of word_ts containing the result, or NULL.
-** Returns : true on success, false on failure
-** On error, NULL is returned. If *error is NULL, the sentence did not contain any useful words;
-** if not, *error points to a malloc'd copy of the offending word.
-** The returned list may contain anywords.
-*/
-
-
-parse_rule_list_t *vocab_build_gnf(const Common::Array<parse_tree_branch_t> &branches);
-/* Constructs the Greibach Normal Form of the grammar supplied in 'branches'
-** Parameters: (parse_tree_branch_t *) branches: The parser's branches
-** Returns : (parse_rule_list_t *): Pointer to a list of singly linked
-** GNF rules describing the same language
-** that was described by 'branches'
-** The original SCI rules are in almost-CNF (Chomsky Normal Form). Note that
-** branch[0] is used only for a few magical incantations, as it is treated
-** specially by the SCI parser.
-*/
-
-
-void vocab_free_rule_list(parse_rule_list_t *rule_list);
-/* Frees a parser rule list as returned by vocab_build_gnf()
-** Parameters: (parse_rule_list_t *) rule_list: The rule list to free
-*/
-
-
-int vocab_build_parse_tree(parse_tree_node_t *nodes, const ResultWordList &words,
- const parse_tree_branch_t &branch0, parse_rule_list_t *rules);
-/* Builds a parse tree from a list of words
-** Parameters: (parse_tree_node_t *) nodes: A node list to store the tree in (must have
-** at least VOCAB_TREE_NODES entries)
-** (const ResultWordList &) words: The words to build the tree from
-** (parse_tree_branch_t *) branche0: The zeroeth original branch of the
-** original CNF parser grammar
-** (parse_rule_list *) rules: The GNF ruleset to parse with
-** Returns : 0 on success, 1 if the tree couldn't be built in VOCAB_TREE_NODES nodes
-** or if the sentence structure in 'words' is not part of the language
-** described by the grammar passed in 'rules'.
-*/
-
-void vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes);
-/* Prints a parse tree
-** Parameters: (const char *) tree_name: Name of the tree to dump (free-form)
-** (parse_tree_node_t *) nodes: The nodes containing the parse tree
-*/
-
-
-
-
-int said(EngineState *s, byte *spec, int verbose);
-/* Builds a parse tree from a spec and compares it to a parse tree
-** Parameters: (EngineState *) s: The affected state
-** (byte *) spec: Pointer to the spec to build
-** (int) verbose: Whether to display the parse tree after building it
-** Returns : (int) 1 on a match, 0 otherwise
-*/
-
-/**
- * Gets any word from the specified group. For debugging only.
- * @param group Group number
- * @param words List of words
- */
-const char *vocab_get_any_group_word(int group, const WordMap &words);
-
-
-void vocab_decypher_said_block(EngineState *s, byte *pos);
-/* Decyphers a said block and dumps its content via sciprintf.
-** Parameters: (EngineState *) s: The state to use
-** (byte *) pos: Pointer to the data to dump
-** For debugging only.
-*/
-
-
-void vocab_synonymize_tokens(ResultWordList &words, const SynonymList &synonyms);
-/* Synonymizes a token list
-** Parameters: (ResultWordList &) words: The word list to synonymize
-** (const SynonymList &) synonyms: Synonym list
-*/
-
-int vocab_gnf_parse(parse_tree_node_t *nodes, const ResultWordList &words,
- const parse_tree_branch_t &branch0, parse_rule_list_t *tlist, int verbose);
-
-void vocab_gnf_dump(const Common::Array<parse_tree_branch_t> &branches);
-
-} // End of namespace Sci
-
-#endif // SCI_SCICORE_VOCABULARY_H