diff options
| author | Filippos Karapetis | 2009-02-19 12:42:32 +0000 |
|---|---|---|
| committer | Filippos Karapetis | 2009-02-19 12:42:32 +0000 |
| commit | 6f4a8dedbe8142d81e6b35a9010005887ea8d1ce (patch) | |
| tree | d6233e37bc12d0303d003ff2f36ba2582d5b274d /engines/sci/scicore | |
| parent | 59db1e85f3dfcad29a6e030aedce039cb2a67661 (diff) | |
| download | scummvm-rg350-6f4a8dedbe8142d81e6b35a9010005887ea8d1ce.tar.gz scummvm-rg350-6f4a8dedbe8142d81e6b35a9010005887ea8d1ce.tar.bz2 scummvm-rg350-6f4a8dedbe8142d81e6b35a9010005887ea8d1ce.zip | |
Rewrote the EXE reading routines (the LZEXE compression stuff is still not completed, and will be implemented in a follow-up commit)
svn-id: r38543
Diffstat (limited to 'engines/sci/scicore')
| -rw-r--r-- | engines/sci/scicore/exe.cpp | 80 | ||||
| -rw-r--r-- | engines/sci/scicore/exe.h | 58 | ||||
| -rw-r--r-- | engines/sci/scicore/exe_dec.h | 64 | ||||
| -rw-r--r-- | engines/sci/scicore/exe_lzexe.cpp | 328 | ||||
| -rw-r--r-- | engines/sci/scicore/exe_raw.cpp | 66 | ||||
| -rw-r--r-- | engines/sci/scicore/versions.cpp | 190 |
6 files changed, 0 insertions, 786 deletions
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/exe_raw.cpp b/engines/sci/scicore/exe_raw.cpp deleted file mode 100644 index 69daaca45f..0000000000 --- a/engines/sci/scicore/exe_raw.cpp +++ /dev/null @@ -1,66 +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" - -struct _exe_handle { - FILE *f; -}; - -#include "sci/scicore/exe_dec.h" - -static exe_handle_t * -raw_open(const char *filename) { - FILE *f = fopen(filename, "rb"); - exe_handle_t *handle; - - if (!f) - return NULL; - - 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 -}; 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 |
