aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/detection.cpp46
-rw-r--r--engines/sci/exereader.cpp451
-rw-r--r--engines/sci/exereader.h (renamed from engines/sci/scicore/exe_raw.cpp)45
-rw-r--r--engines/sci/include/versions.h6
-rw-r--r--engines/sci/module.mk4
-rw-r--r--engines/sci/scicore/exe.cpp80
-rw-r--r--engines/sci/scicore/exe.h58
-rw-r--r--engines/sci/scicore/exe_dec.h64
-rw-r--r--engines/sci/scicore/exe_lzexe.cpp328
-rw-r--r--engines/sci/scicore/versions.cpp190
10 files changed, 499 insertions, 773 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 61139122d2..90f8954c33 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -27,6 +27,7 @@
#include "base/plugins.h"
#include "sci/sci.h"
+#include "sci/exereader.h"
#include "sci/include/versions.h"
// Titles of the games
@@ -1053,7 +1054,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{},
SCI_VERSION(0, 000, 000) // FIXME: add version here
},
-#if 0
+
// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org)
{{"sq1sci", "VGA Remake", {
{"resource.map", 0, "106484b372af1d4cbf866472cc2813dc", 6396},
@@ -1094,7 +1095,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{},
SCI_VERSION(1, 000, 510)
},
-#endif
+
// Space Quest 3 - English Amiga (from www.back2roots.org)
{{"sq3", "", {
{"resource.map", 0, "bad41385acde6d677a8d55a7b20437e3", 5868},
@@ -1387,6 +1388,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
int exeVersion = 0;
bool foundResMap = false;
bool foundRes000 = false;
+ bool foundExe = false;
// First grab all filenames
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
@@ -1401,18 +1403,46 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
|| filename.contains("ressci.000") || filename.contains("ressci.001"))
foundRes000 = true;
- // FIXME: This is all quite hackish
+ // Check if it's a known executable name
if (filename.contains("scidhuv") || filename.contains("sciv") ||
filename.contains("sierra") || filename.contains("sciw")) {
- exeVersion = version_detect_from_executable((char *)file->getPath().c_str());
- break;
- }
+ // Is it really an executable file?
+ Common::SeekableReadStream *fileStream = file->createReadStream();
+ bool isExe = isGameExe(fileStream);
+ int exeVersion = -1;
+
+ if (isExe) {
+ if (!readSciVersionFromExe(fileStream, &exeVersion)) {
+ printf("Error while reading SCI version from the game executable\n");
+ delete fileStream;
+ return 0;
+ } else {
+ // All ok, we got the version from the executable successfully
+ foundExe = true;
+ delete fileStream;
+ break;
+ }
+ } else {
+ printf("The original game executable seems to be corrupted\n");
+ delete fileStream;
+ return 0;
+ }
+
+ }
+
}
+ if (!foundExe) {
+ printf("The original game executable wasn't found\n");
+ return 0;
+ }
+
// If these files aren't found, it can't be SCI
- if (!foundResMap && !foundRes000)
+ if (!foundResMap && !foundRes000) {
+ printf("Necessary data files are missing, or this isn't a SCI game\n");
return 0;
-
+ }
+
// Set some defaults
g_fallbackDesc.desc.gameid = "sci";
g_fallbackDesc.desc.extra = "";
diff --git a/engines/sci/exereader.cpp b/engines/sci/exereader.cpp
new file mode 100644
index 0000000000..111e1f2931
--- /dev/null
+++ b/engines/sci/exereader.cpp
@@ -0,0 +1,451 @@
+/* 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 "common/endian.h"
+
+#include "sci/exereader.h"
+#include "sci/include/versions.h"
+
+//namespace Sci {
+
+#define VERSION_DETECT_BUF_SIZE 4096
+
+// LZEXE related defines
+// The LZEXE code is based on public domain code by Mitugu Kurizono
+
+/* The amount of most recent data (in bytes) that we need to keep in the
+** buffer. lzexe compression is based on copying chunks of previous data to
+** form new data.
+*/
+#define LZEXE_WINDOW VERSION_DETECT_BUF_SIZE * 2
+
+/* Buffer size. */
+#define LZEXE_BUFFER_SIZE VERSION_DETECT_BUF_SIZE * 3
+
+/* Maximum amount of data (in bytes) that can be in the buffer at the start
+** of the decompression loop. The maximum amount of data that can be added
+** to the buffer during a single step of the loop is 256 bytes.
+*/
+#define LZEXE_BUFFER_MAX (LZEXE_BUFFER_SIZE - 256)
+
+int curBits;
+byte lzexeBuf[2];
+
+bool isGameExe(Common::SeekableReadStream *exeStream) {
+ byte magic[4];
+ if (exeStream->size() < VERSION_DETECT_BUF_SIZE)
+ return false;
+
+ // Read exe header
+ exeStream->read(magic, 4);
+
+ // Check if the header contains known magic bytes
+
+ // Information obtained from http://magicdb.org/magic.db
+ // Check if it's a DOS executable
+ if (magic[0] == 'M' && magic[1] == 'Z') {
+ return true;
+ }
+
+ // Check if it's an Amiga executable
+ if ((magic[0] == 0x03 && magic[1] == 0xF3) ||
+ (magic[0] == 0x7F && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F')) {
+ return true;
+ }
+
+ // Check if it's an Atari executable
+ if ((magic[0] == 0x60 && magic[1] == 0x1A))
+ return true;
+
+ // Check if it's a Mac exe
+ // Is there a better way to do this?
+ int32 offset = MKID_BE(magic) + 28; // Resource map offset
+ if (exeStream->size() <= offset)
+ return false;
+
+ // Skip number of types in map
+ exeStream->skip(2);
+ uint16 val = exeStream->readUint16BE() + 1;
+
+ // Keep reading till we find the "CODE" bit
+ while (!exeStream->eos()) {
+ exeStream->skip(4);
+ if (exeStream->eos())
+ return false;
+
+ exeStream->read(magic, 4);
+ if (exeStream->eos())
+ return false;
+
+ if (!memcmp(magic, "CODE", 4)) {
+ return true;
+ }
+ // Skip to the next list entry
+ exeStream->skip(4);
+ if (exeStream->eos())
+ return false;
+ }
+
+ // If we've reached here, the file type is unknown
+ return false;
+}
+
+bool isLZEXECompressed(Common::SeekableReadStream *exeStream) {
+ uint32 filepos = 0;
+
+ exeStream->seek(0, SEEK_SET);
+
+ // First 2 bytes should be "MZ" (0x5A4D)
+ if (exeStream->readUint16LE() != 0x5A4D) // at pos 0, +2
+ return false;
+
+ exeStream->skip(6);
+
+ // Header size should be 2
+ filepos = exeStream->readUint16LE();
+ if (filepos != 2) // at pos 8, +2
+ return false;
+
+ exeStream->skip(12);
+
+ // Calculate code segment offset in exe file
+ filepos += exeStream->readUint16LE(); // at pos 22, +2
+
+ // First relocation item offset should be 0x1c
+ if (exeStream->readUint16LE() != 0x1c) // at pos 24, +2
+ return false;
+
+ // Number of overlays should be 0
+ if (exeStream->readUint16LE() != 0) // at pos 26, +2
+ return false;
+
+ // Look for LZEXE signature
+ byte magic[4];
+ exeStream->read(magic, 4);
+
+ if (memcmp(magic, "LZ09", 4) && memcmp(magic, "LZ91", 4))
+ return false;
+
+ // Seek to offset 8 of info table at start of code segment
+ exeStream->seek(filepos + 8, SEEK_SET);
+ if (exeStream->err())
+ return false;
+
+ // Read size of compressed data in paragraphs
+ uint16 size = exeStream->readUint16LE();
+
+ // Move file pointer to start of compressed data
+ filepos -= size << 4;
+ exeStream->seek(filepos, SEEK_SET);
+ if (exeStream->err())
+ return false;
+
+ // All conditions met, this is an LZEXE packed file
+ // We are currently at the start of the compressed file data
+ return true;
+}
+
+byte getBitFromlzexe(Common::SeekableReadStream *exeStream) {
+ byte result = lzexeBuf[1] & 1;
+
+ if (--curBits == 0) {
+ lzexeBuf[0] = exeStream->readByte();
+ lzexeBuf[1] = exeStream->readByte();
+ curBits = 16;
+ } else {
+ // Shift buffer to the right by 1 bit
+ uint16 curBuffer = (lzexeBuf[0] << 8) | lzexeBuf[1];
+ curBuffer >>= 1;
+ lzexeBuf[0] = (curBuffer >> 8) & 0xFF;
+ lzexeBuf[1] = curBuffer & 0xFF;
+ }
+
+ return result;
+}
+
+void readLzexe(Common::SeekableReadStream *exeStream, byte *buffer) {
+ // TODO: finish this (from lzexe_read)
+ printf("TODO: LZEXE support\n");
+ return;
+#if 0
+ int done = 0;
+
+ while (done != VERSION_DETECT_BUF_SIZE) {
+ int size, copy, i;
+ int left = count - done;
+
+ if (!lzexe_decompress(exeStream))
+ return done;
+
+ /* Total amount of bytes in buffer. */
+ //size = handle->bufptr - handle->buffer;
+
+ // If we're not at end of data we need to maintain the window
+ if (!exeStream->eos())
+ copy = size - LZEXE_WINDOW;
+ else {
+ if (size == 0)
+ /* No data left. */
+ return done;
+
+ copy = size;
+ }
+
+ /* Do not copy more than requested. */
+ if (copy > left)
+ copy = left;
+
+ memcpy((char *) buffer + done, handle->buffer, copy);
+
+ /* Move remaining data to start of buffer. */
+ for (i = copy; i < size; i++)
+ handle->buffer[i - copy] = handle->buffer[i];
+
+ handle->bufptr -= copy;
+ done += copy;
+ }
+
+ return done;
+#endif
+}
+
+void readExe(Common::SeekableReadStream *exeStream, byte *buffer) {
+ bool isLZEXE = isLZEXECompressed(exeStream);
+
+ if (!isLZEXE) {
+ exeStream->seek(0, SEEK_SET);
+ exeStream->read(buffer, VERSION_DETECT_BUF_SIZE);
+ } else {
+ // Read the two initial bytes
+ lzexeBuf[0] = exeStream->readByte();
+ lzexeBuf[1] = exeStream->readByte();
+
+ curBits = 16;
+
+ readLzexe(exeStream, buffer);
+ }
+}
+
+bool readSciVersionFromExe(Common::SeekableReadStream *exeStream, int *version) {
+ byte buffer[VERSION_DETECT_BUF_SIZE];
+ char result_string[10]; /* string-encoded result, copied from buf */
+ int state = 0;
+ /* 'state' encodes how far we have matched the version pattern
+ ** "n.nnn.nnn"
+ **
+ ** n.nnn.nnn
+ ** 0123456789
+ **
+ ** Since we cannot be certain that the pattern does not begin with an
+ ** alphanumeric character, some states are ambiguous.
+ ** The pattern is expected to be terminated with a non-alphanumeric
+ ** character.
+ */
+
+ readExe(exeStream, buffer);
+
+ int accept;
+
+ for (int i = 0; i < VERSION_DETECT_BUF_SIZE; i++) {
+ const char ch = buffer[i];
+ accept = 0; /* By default, we don't like this character */
+
+ if (isalnum((unsigned char) ch)) {
+ accept = (state != 1
+ && state != 5
+ && state != 9);
+ } else if (ch == '.') {
+ accept = (state == 1
+ || state == 5);
+ } else if (state == 9) {
+ result_string[9] = 0; /* terminate string */
+
+ if (!version_parse(result_string, version)) {
+ return true; // success
+ }
+
+ // Continue searching
+ }
+
+ if (accept)
+ result_string[state++] = ch;
+ else
+ state = 0;
+ }
+
+ return false; // failure
+}
+
+#if 0
+//TODO
+// Code from exe_lzexe.cpp (left for reference, to be converted)
+
+static int
+lzexe_decompress(exe_handle_t *handle) {
+ while (!handle->eod
+ && handle->bufptr - handle->buffer <= LZEXE_BUFFER_MAX) {
+ int bit;
+ int len, span;
+
+ if (!lzexe_get_bit(handle, &bit))
+ return 0;
+
+ if (bit) {
+ /* 1: copy byte verbatim. */
+
+ int data;
+
+ if (!lzexe_read_uint8(handle->f, &data))
+ return 0;
+
+ *handle->bufptr++ = data;
+
+ continue;
+ }
+
+ if (!lzexe_get_bit(handle, &bit))
+ return 0;
+
+ if (!bit) {
+ /* 00: copy small block. */
+
+ /* Next two bits indicate block length - 2. */
+ if (!lzexe_get_bit(handle, &bit))
+ return 0;
+
+ len = bit << 1;
+
+ if (!lzexe_get_bit(handle, &bit))
+ return 0;
+
+ len |= bit;
+ len += 2;
+
+ /* Read span byte. This forms the low byte of a
+ ** negative two's compliment value.
+ */
+ if (!lzexe_read_uint8(handle->f, &span))
+ return 0;
+
+ /* Convert to negative integer. */
+ span -= 256;
+ } else {
+ /* 01: copy large block. */
+ int data;
+
+ /* Read low byte of span value. */
+ if (!lzexe_read_uint8(handle->f, &span))
+ return 0;
+
+ /* Read next byte. Bits [7..3] contain bits [12..8]
+ ** of span value. Bits [2..0] contain block length -
+ ** 2.
+ */
+ if (!lzexe_read_uint8(handle->f, &data))
+ return 0;
+ span |= (data & 0xf8) << 5;
+ /* Convert to negative integer. */
+ span -= 8192;
+
+ len = (data & 7) + 2;
+
+ if (len == 2) {
+ /* Next byte is block length value - 1. */
+ if (!lzexe_read_uint8(handle->f, &len))
+ return 0;
+
+ if (len == 0) {
+ /* End of data reached. */
+ handle->eod = 1;
+ break;
+ }
+
+ if (len == 1)
+ /* Segment change marker. */
+ continue;
+
+ len++;
+ }
+ }
+
+ assert(handle->bufptr + span >= handle->buffer);
+
+ /* Copy block. */
+ while (len-- > 0) {
+ *handle->bufptr = *(handle->bufptr + span);
+ handle->bufptr++;
+ }
+ }
+
+ return 1;
+}
+
+static int
+lzexe_read(exe_handle_t *handle, void *buf, int count) {
+ int done = 0;
+
+ while (done != count) {
+ int size, copy, i;
+ int left = count - done;
+
+ if (!lzexe_decompress(handle))
+ return done;
+
+ /* Total amount of bytes in buffer. */
+ size = handle->bufptr - handle->buffer;
+
+ /* If we're not at end of data we need to maintain the
+ ** window.
+ */
+ if (!handle->eod)
+ copy = size - LZEXE_WINDOW;
+ else {
+ if (size == 0)
+ /* No data left. */
+ return done;
+
+ copy = size;
+ }
+
+ /* Do not copy more than requested. */
+ if (copy > left)
+ copy = left;
+
+ memcpy((char *) buf + done, handle->buffer, copy);
+
+ /* Move remaining data to start of buffer. */
+ for (i = copy; i < size; i++)
+ handle->buffer[i - copy] = handle->buffer[i];
+
+ handle->bufptr -= copy;
+ done += copy;
+ }
+
+ return done;
+}
+
+#endif
+
+//} // End of namespace Sci
diff --git a/engines/sci/scicore/exe_raw.cpp b/engines/sci/exereader.h
index 69daaca45f..32f070a59a 100644
--- a/engines/sci/scicore/exe_raw.cpp
+++ b/engines/sci/exereader.h
@@ -23,44 +23,17 @@
*
*/
-#include "sci/include/sci_memory.h"
+#ifndef EXEREADER_H
+#define EXEREADER_H
-struct _exe_handle {
- FILE *f;
-};
+#include "common/file.h"
+#include "common/str.h"
-#include "sci/scicore/exe_dec.h"
+//namespace Sci {
-static exe_handle_t *
-raw_open(const char *filename) {
- FILE *f = fopen(filename, "rb");
- exe_handle_t *handle;
+bool isGameExe(Common::SeekableReadStream *exeStream);
+bool readSciVersionFromExe(Common::SeekableReadStream *exeStream, int *version);
- if (!f)
- return NULL;
+//} // End of namespace Sci
- handle = (exe_handle_t*)sci_malloc(sizeof(exe_handle_t));
- handle->f = f;
-
- return handle;
-}
-
-static int
-raw_read(exe_handle_t *handle, void *buf, int count) {
- return fread(buf, 1, count, handle->f);
-}
-
-static void
-raw_close(exe_handle_t *handle) {
- fclose(handle->f);
-
- free(handle);
-}
-
-exe_decompressor_t
-exe_decompressor_raw = {
- "raw",
- raw_open,
- raw_read,
- raw_close
-};
+#endif // SCI_H
diff --git a/engines/sci/include/versions.h b/engines/sci/include/versions.h
index 15c7e332e9..c18840598a 100644
--- a/engines/sci/include/versions.h
+++ b/engines/sci/include/versions.h
@@ -147,10 +147,4 @@ version_parse(const char *vn, sci_version_t *result);
** (sci_version_t) *result: The resulting version number on success
*/
-int
-version_detect_from_executable(char *filename);
-/* Try to detect version from Sierra executable in cwd
-** Returns : (int) The version number detected, or 0 if we weren't successful
-*/
-
#endif /* !_SCI_VERSIONS_H_ */
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 9cb5241b3d..9911375eb3 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/sci
MODULE_OBJS = \
detection.o \
+ exereader.o \
sci.o \
engine/game.o \
engine/gc.o \
@@ -55,9 +56,6 @@ MODULE_OBJS = \
scicore/decompress01.o \
scicore/decompress1.o \
scicore/decompress11.o \
- scicore/exe.o \
- scicore/exe_lzexe.o \
- scicore/exe_raw.o \
scicore/resource.o \
scicore/resource_map.o \
scicore/resource_patch.o \
diff --git a/engines/sci/scicore/exe.cpp b/engines/sci/scicore/exe.cpp
deleted file mode 100644
index 518818ff33..0000000000
--- a/engines/sci/scicore/exe.cpp
+++ /dev/null
@@ -1,80 +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/include/sci_memory.h"
-
-#include "sci/scicore/exe.h"
-#include "sci/scicore/exe_dec.h"
-
-extern exe_decompressor_t exe_decompressor_lzexe;
-extern exe_decompressor_t exe_decompressor_raw;
-
-exe_decompressor_t *exe_decompressors[] = {
- &exe_decompressor_lzexe,
- &exe_decompressor_raw,
- NULL
-};
-
-struct _exe_file {
- struct _exe_decompressor *decompressor;
- struct _exe_handle *handle;
-};
-
-exe_file_t *
-exe_open(const char *filename) {
- int i = 0;
- exe_decompressor_t *dec;
-
- while ((dec = exe_decompressors[i])) {
- exe_handle_t *handle = dec->open(filename);
-
- if (handle) {
- exe_file_t *file = (exe_file_t*)sci_malloc(sizeof(exe_file_t));
-
- sciprintf("Scanning '%s' with decompressor '%s'\n",
- filename, dec->name);
-
- file->handle = handle;
- file->decompressor = dec;
- return file;
- }
-
- i++;
- }
-
- return NULL;
-}
-
-int
-exe_read(exe_file_t *file, void *buf, int count) {
- return file->decompressor->read(file->handle, buf, count);
-}
-
-void
-exe_close(exe_file_t *file) {
- file->decompressor->close(file->handle);
-
- free(file);
-}
diff --git a/engines/sci/scicore/exe.h b/engines/sci/scicore/exe.h
deleted file mode 100644
index db40d3689c..0000000000
--- a/engines/sci/scicore/exe.h
+++ /dev/null
@@ -1,58 +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_EXE_H_
-#define _SCI_EXE_H_
-
-typedef struct _exe_file exe_file_t;
-
-exe_file_t *
-exe_open(const char *filename);
-/* Opens an executable file
-** Parameters: (const char *) filename: Filename of executable to open
-** Returns : (exe_file_t *) File handle, or NULL on error
-** This function will try to find a decompressor that can handle this type
-** of executable
-*/
-
-int
-exe_read(exe_file_t *file, void *buf, int count);
-/* Reads from an executable file
-** Parameters: (exe_file_t *) file: File handle
-** (void *) buf: Buffer to store decompressed data
-** (int) count: Size of decompressed data requested, in bytes
-** Returns : (int) Number of bytes of decompressed data that was stored in
-** buf. If this value is less than count an error has
-** occured, or end-of-file was reached.
-*/
-
-void
-exe_close(exe_file_t *handle);
-/* Closes an executable file
-** Parameters: (exe_file_t *) file: File handle
-** Returns : (void)
-*/
-
-#endif /* !_SCI_EXE_H_ */
diff --git a/engines/sci/scicore/exe_dec.h b/engines/sci/scicore/exe_dec.h
deleted file mode 100644
index 45c1f58382..0000000000
--- a/engines/sci/scicore/exe_dec.h
+++ /dev/null
@@ -1,64 +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_EXE_DEC_H_
-#define _SCI_EXE_DEC_H_
-
-typedef struct _exe_handle exe_handle_t;
-
-typedef struct _exe_decompressor {
- const char *name; /* Decompressor name. Unique identifier, should consist
- ** of lower-case (where applicable) alphanumerics
- */
-
- exe_handle_t * (*open)(const char *filename);
- /* Opens an executable file
- ** Parameters: (const char *) filename: Filename of executable to open.
- ** Returns : (exe_handle_t *) Decompressor file handle, or NULL on
- ** error.
- ** This function will verify that the file can be handled by the
- ** decompressor. If this is not the case the function will fail.
- */
-
- int (*read)(exe_handle_t *handle, void *buf, int count);
- /* Reads from executable file
- ** Parameters: (exe_handle_t *) handle: Decompressor file handle.
- ** (void *) buf: Buffer to store decompressed data.
- ** (int) count: Size of decompressed data requested, in
- ** bytes.
- ** Returns : (int) Number of bytes of decompressed data that was
- ** stored in buf. If this value is less than count
- ** an error has occured, or end-of-file was
- ** reached.
- */
-
- void (*close)(exe_handle_t *handle);
- /* Closes a decompressor file handle.
- ** Parameters: (exe_handle_t *) handle: Decompressor file handle.
- ** Returns : (void)
- */
-} exe_decompressor_t;
-
-#endif /* !_SCI_EXE_DEC_H_ */
diff --git a/engines/sci/scicore/exe_lzexe.cpp b/engines/sci/scicore/exe_lzexe.cpp
deleted file mode 100644
index a7a1c31a08..0000000000
--- a/engines/sci/scicore/exe_lzexe.cpp
+++ /dev/null
@@ -1,328 +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$
- *
- */
-
-/* Based on public domain code by Mitugu Kurizono. */
-
-#include "sci/include/sci_memory.h"
-#include "sci/scicore/exe_dec.h"
-
-/* Macro to interpret two sequential bytes as an unsigned integer. */
-#define UINT16(A) ((*((A) + 1) << 8) + *(A))
-
-/* The amount of most recent data (in bytes) that we need to keep in the
-** buffer. lzexe compression is based on copying chunks of previous data to
-** form new data.
-*/
-#define LZEXE_WINDOW 8192
-
-/* Buffer size. */
-#define LZEXE_BUFFER_SIZE (LZEXE_WINDOW + 4096)
-
-/* Maximum amount of data (in bytes) that can be in the buffer at the start
-** of the decompression loop. The maximum amount of data that can be added
-** to the buffer during a single step of the loop is 256 bytes.
-*/
-#define LZEXE_BUFFER_MAX (LZEXE_BUFFER_SIZE - 256)
-
-struct _exe_handle {
- FILE *f;
-
- /* Output buffer. */
- guint8 buffer[LZEXE_BUFFER_SIZE];
- guint8 *bufptr;
-
- /* Bit buffer. Bits [0..count) still contain unprocessed data. */
- int buf;
- int count;
-
- /* End of data flag. */
- int eod;
-};
-
-static int
-lzexe_read_uint16(FILE *f, int *value) {
- int data;
-
- if ((*value = fgetc(f)) == EOF)
- return 0;
-
- if ((data = fgetc(f)) == EOF)
- return 0;
-
- *value |= data << 8;
- return 1;
-}
-
-static int
-lzexe_read_uint8(FILE *f, int *value) {
- if ((*value = fgetc(f)) == EOF)
- return 0;
-
- return 1;
-}
-
-static int
-lzexe_init(exe_handle_t *handle, FILE *f) {
- handle->f = f;
- handle->bufptr = handle->buffer;
- handle->eod = 0;
-
- if (!lzexe_read_uint16(handle->f, &handle->buf))
- return 0;
-
- handle->count = 16;
- return 1;
-}
-
-static int
-lzexe_get_bit(exe_handle_t *handle, int *bit) {
- *bit = handle->buf & 1;
-
- if (--handle->count == 0) {
- if (!lzexe_read_uint16(handle->f, &handle->buf))
- return 0;
- handle->count = 16;
- } else
- handle->buf >>= 1;
-
- return 1;
-}
-
-static int
-lzexe_decompress(exe_handle_t *handle) {
- while (!handle->eod
- && handle->bufptr - handle->buffer <= LZEXE_BUFFER_MAX) {
- int bit;
- int len, span;
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- if (bit) {
- /* 1: copy byte verbatim. */
-
- int data;
-
- if (!lzexe_read_uint8(handle->f, &data))
- return 0;
-
- *handle->bufptr++ = data;
-
- continue;
- }
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- if (!bit) {
- /* 00: copy small block. */
-
- /* Next two bits indicate block length - 2. */
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- len = bit << 1;
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- len |= bit;
- len += 2;
-
- /* Read span byte. This forms the low byte of a
- ** negative two's compliment value.
- */
- if (!lzexe_read_uint8(handle->f, &span))
- return 0;
-
- /* Convert to negative integer. */
- span -= 256;
- } else {
- /* 01: copy large block. */
- int data;
-
- /* Read low byte of span value. */
- if (!lzexe_read_uint8(handle->f, &span))
- return 0;
-
- /* Read next byte. Bits [7..3] contain bits [12..8]
- ** of span value. Bits [2..0] contain block length -
- ** 2.
- */
- if (!lzexe_read_uint8(handle->f, &data))
- return 0;
- span |= (data & 0xf8) << 5;
- /* Convert to negative integer. */
- span -= 8192;
-
- len = (data & 7) + 2;
-
- if (len == 2) {
- /* Next byte is block length value - 1. */
- if (!lzexe_read_uint8(handle->f, &len))
- return 0;
-
- if (len == 0) {
- /* End of data reached. */
- handle->eod = 1;
- break;
- }
-
- if (len == 1)
- /* Segment change marker. */
- continue;
-
- len++;
- }
- }
-
- assert(handle->bufptr + span >= handle->buffer);
-
- /* Copy block. */
- while (len-- > 0) {
- *handle->bufptr = *(handle->bufptr + span);
- handle->bufptr++;
- }
- }
-
- return 1;
-}
-
-static exe_handle_t *
-lzexe_open(const char *filename) {
- exe_handle_t *handle;
- guint8 head[0x20];
- guint8 size[2];
- off_t fpos;
-
- FILE *f = fopen(filename, "rb");
-
- if (!f)
- return NULL;
-
- /* Read exe header plus possible lzexe signature. */
- if (fread(head, 1, 0x20, f) != 0x20)
- return NULL;
-
- /* Verify "MZ" signature, header size == 2 paragraphs and number of
- ** overlays == 0.
- */
- if (UINT16(head) != 0x5a4d || UINT16(head + 8) != 2
- || UINT16(head + 0x1a) != 0)
- return NULL;
-
- /* Verify that first relocation item offset is 0x1c. */
- if (UINT16(head + 0x18) != 0x1c)
- return NULL;
-
- /* Look for lzexe signature. */
- if (memcmp(head + 0x1c, "LZ09", 4)
- && memcmp(head + 0x1c, "LZ91", 4)) {
- return NULL;
- }
-
- /* Calculate code segment offset in exe file. */
- fpos = (UINT16(head + 0x16) + UINT16(head + 8)) << 4;
- /* Seek to offset 8 of info table at start of code segment. */
- if (fseek(f, fpos + 8, SEEK_SET) == -1)
- return NULL;
-
- /* Read size of compressed data in paragraphs. */
- if (fread(size, 1, 2, f) != 2)
- return NULL;
-
- /* Move file pointer to start of compressed data. */
- fpos -= UINT16(size) << 4;
- if (fseek(f, fpos, SEEK_SET) == -1)
- return NULL;
-
- handle = (exe_handle_t*)sci_malloc(sizeof(exe_handle_t));
-
- if (!lzexe_init(handle, f)) {
- free(handle);
- return NULL;
- }
-
- return handle;
-}
-
-static int
-lzexe_read(exe_handle_t *handle, void *buf, int count) {
- int done = 0;
-
- while (done != count) {
- int size, copy, i;
- int left = count - done;
-
- if (!lzexe_decompress(handle))
- return done;
-
- /* Total amount of bytes in buffer. */
- size = handle->bufptr - handle->buffer;
-
- /* If we're not at end of data we need to maintain the
- ** window.
- */
- if (!handle->eod)
- copy = size - LZEXE_WINDOW;
- else {
- if (size == 0)
- /* No data left. */
- return done;
-
- copy = size;
- }
-
- /* Do not copy more than requested. */
- if (copy > left)
- copy = left;
-
- memcpy((char *) buf + done, handle->buffer, copy);
-
- /* Move remaining data to start of buffer. */
- for (i = copy; i < size; i++)
- handle->buffer[i - copy] = handle->buffer[i];
-
- handle->bufptr -= copy;
- done += copy;
- }
-
- return done;
-}
-
-static void
-lzexe_close(exe_handle_t *handle) {
- fclose(handle->f);
-
- free(handle);
-}
-
-exe_decompressor_t
-exe_decompressor_lzexe = {
- "lzexe",
- lzexe_open,
- lzexe_read,
- lzexe_close
-};
diff --git a/engines/sci/scicore/versions.cpp b/engines/sci/scicore/versions.cpp
index 6680fcb430..e05106ce88 100644
--- a/engines/sci/scicore/versions.cpp
+++ b/engines/sci/scicore/versions.cpp
@@ -31,7 +31,6 @@
#include "sci/include/versions.h"
#include "sci/include/engine.h"
#include "sci/include/resource.h"
-#include "sci/scicore/exe.h" // for reading version from the executable
void
version_require_earlier_than(state_t *s, sci_version_t version) {
@@ -88,193 +87,4 @@ version_parse(const char *vn, sci_version_t *result) {
return 0;
}
-// Exe scanning functions
-
-/* Maxmimum number of bytes to hash from start of file */
-#define VERSION_DETECT_HASH_SIZE 1000000
-
-#define VERSION_DETECT_BUF_SIZE 4096
-
-static int
-scan_file(char *filename, sci_version_t *version) {
- char buf[VERSION_DETECT_BUF_SIZE];
- char result_string[10]; /* string-encoded result, copied from buf */
- int characters_left;
- int state = 0;
- /* 'state' encodes how far we have matched the version pattern
- ** "n.nnn.nnn"
- **
- ** n.nnn.nnn
- ** 0123456789
- **
- ** Since we cannot be certain that the pattern does not begin with an
- ** alphanumeric character, some states are ambiguous.
- ** The pattern is expected to be terminated with a non-alphanumeric
- ** character.
- */
-
- exe_file_t *f = exe_open(filename);
-
- if (!f)
- return 1;
-
- do {
- int i;
- int accept;
-
- characters_left = exe_read(f, buf, VERSION_DETECT_BUF_SIZE);
-
- for (i = 0; i < characters_left; i++) {
- const char ch = buf[i];
- accept = 0; /* By default, we don't like this character */
-
- if (isalnum((unsigned char) ch)) {
- accept = (state != 1
- && state != 5
- && state != 9);
- } else if (ch == '.') {
- accept = (state == 1
- || state == 5);
- } else if (state == 9) {
- result_string[9] = 0; /* terminate string */
-
- if (!version_parse(result_string, version)) {
- exe_close(f);
- return 0; /* success! */
- }
-
- /* Continue searching. */
- }
-
- if (accept)
- result_string[state++] = ch;
- else
- state = 0;
-
- }
-
- } while (characters_left == VERSION_DETECT_BUF_SIZE);
-
- exe_close(f);
- return 1; /* failure */
-}
-
-static guint32
-read_uint32(byte *data) {
- return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
-}
-
-static guint16
-read_uint16(byte *data) {
- return (data[0] << 8) | data[1];
-}
-
-static int
-is_mac_exe(char *filename) {
- FILE *file;
- byte buf[4];
- guint32 val;
- unsigned int i;
-
- /* Mac executables have no extension */
- if (strchr(filename, '.'))
- return 0;
-
- file = fopen(filename, "rb");
- if (!file)
- return 0;
-
- if (fseek(file, 4, SEEK_SET) == -1) {
- fclose(file);
- return 0;
- }
-
- /* Read resource map offset */
- if (fread(buf, 1, 4, file) < 4) {
- fclose(file);
- return 0;
- }
-
- val = read_uint32(buf);
-
- if (fseek(file, val + 28, SEEK_SET) == -1) {
- fclose(file);
- return 0;
- }
-
- /* Read number of types in map */
- if (fread(buf, 1, 2, file) < 2) {
- fclose(file);
- return 0;
- }
-
- val = read_uint16(buf) + 1;
-
- for (i = 0; i < val; i++) {
- if (fread(buf, 1, 4, file) < 4) {
- fclose(file);
- return 0;
- }
-
- /* Look for executable code */
- if (!memcmp(buf, "CODE", 4)) {
- fclose(file);
- return 1;
- }
-
- /* Skip to next list entry */
- if (fseek(file, 4, SEEK_CUR) == -1) {
- fclose(file);
- return 0;
- }
- }
-
- fclose(file);
- return 0;
-}
-
-static int
-is_exe(char *filename) {
- FILE *file;
- char buf[4];
- unsigned char header[] = {0x00, 0x00, 0x03, 0xf3};
-
- /* PC and Atari ST executable extensions */
- if (strstr(filename, ".exe") || strstr(filename, ".EXE")
- || strstr(filename, ".prg") || strstr(filename, ".PRG"))
- return 1;
-
- /* Check for Amiga executable */
- if (strchr(filename, '.'))
- return 0;
-
- file = fopen(filename, "rb");
- if (!file)
- return 0;
-
- if (fread(buf, 1, 4, file) < 4) {
- fclose(file);
- return 0;
- }
-
- fclose(file);
-
- /* Check header bytes */
- return memcmp(buf, header, 4) == 0;
-}
-
-int
-version_detect_from_executable(char *filename) {
- int mac = 0;
- int result;
-
- if (mac ? is_mac_exe(filename) : is_exe(filename)) {
- if (scan_file(filename, &result) == 0) {
- return result;
- }
- }
-
- return 0;
-}
-
#undef VERSION_DETECT_BUF_SIZE