aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-03-05 19:04:34 +0000
committerMax Horn2003-03-05 19:04:34 +0000
commit5ffeedb1cbea471b3d902da96767ffad168023c5 (patch)
tree5ba28837ca5499b4ae6edcab35d5522c63612a1b
parentf02506f9931c3b4d7eb97887e16228623461011b (diff)
downloadscummvm-rg350-5ffeedb1cbea471b3d902da96767ffad168023c5.tar.gz
scummvm-rg350-5ffeedb1cbea471b3d902da96767ffad168023c5.tar.bz2
scummvm-rg350-5ffeedb1cbea471b3d902da96767ffad168023c5.zip
Patch #697312: Beneath a Steel Sky interim/initial support patch
svn-id: r6691
-rw-r--r--Makefile.common2
-rw-r--r--common/engine.cpp3
-rw-r--r--common/engine.h2
-rw-r--r--common/gameDetector.cpp6
-rw-r--r--common/gameDetector.h6
-rw-r--r--sky/disk.cpp211
-rw-r--r--sky/intro.cpp266
-rw-r--r--sky/rnc_deco.cpp345
-rw-r--r--sky/screen.cpp96
-rw-r--r--sky/sky.cpp148
-rw-r--r--sky/sky.h89
-rw-r--r--sky/skydefs.h90
-rw-r--r--sky/struc.h38
13 files changed, 1299 insertions, 3 deletions
diff --git a/Makefile.common b/Makefile.common
index b2a72486a1..47447aa655 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -23,7 +23,7 @@ DEPDIR := .deps
# module.mk of their parents. In fact the only reason they are listed here is to ensure the
# DEPDIRS directive works correctly.
MODULES += \
- scumm common simon gui backends sound \
+ scumm common simon sky gui backends sound \
scumm/smush backends/fs/posix backends/fs/morphos backends/fs/windows backends/midi
# Include the build instructions for all modules
diff --git a/common/engine.cpp b/common/engine.cpp
index 69074d42d5..9602d24a59 100644
--- a/common/engine.cpp
+++ b/common/engine.cpp
@@ -87,6 +87,9 @@ Engine *Engine::createFromDetector(GameDetector *detector, OSystem *syst)
} else if (detector->_gameId >= GID_SCUMM_FIRST && detector->_gameId <= GID_SCUMM_LAST) {
// Some kind of Scumm game
engine = Engine_SCUMM_create(detector, syst);
+ } else if (detector->_gameId >= GID_SKY_FIRST && detector->_gameId <= GID_SKY_LAST) {
+ // Beneath a Steel Sky
+ engine = Engine_SKY_create(detector, syst);
} else {
// Unknown game
}
diff --git a/common/engine.h b/common/engine.h
index b71e42ac76..57306e5833 100644
--- a/common/engine.h
+++ b/common/engine.h
@@ -78,9 +78,11 @@ void checkHeap();
// 2) Faster (compiler doesn't have to parse lengthy header files)
extern Engine *Engine_SIMON_create(GameDetector *detector, OSystem *syst);
extern Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst);
+extern Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst);
extern const VersionSettings *Engine_SIMON_targetList();
extern const VersionSettings *Engine_SCUMM_targetList();
+extern const VersionSettings *Engine_SKY_targetList();
#endif
diff --git a/common/gameDetector.cpp b/common/gameDetector.cpp
index c9d1e37608..9feaf9dca0 100644
--- a/common/gameDetector.cpp
+++ b/common/gameDetector.cpp
@@ -191,12 +191,16 @@ GameDetector::GameDetector()
// Gather & combine the target lists from the modules
const VersionSettings *scummVersions = Engine_SCUMM_targetList();
const VersionSettings *simonVersions = Engine_SIMON_targetList();
+ const VersionSettings *skyVersions = Engine_SKY_targetList();
+
int scummCount = countVersions(scummVersions);
int simonCount = countVersions(simonVersions);
+ int skyCount = countVersions(skyVersions);
- VersionSettings *v = (VersionSettings *)calloc(scummCount + simonCount + 1, sizeof(VersionSettings));
+ VersionSettings *v = (VersionSettings *)calloc(scummCount + simonCount + skyCount + 1, sizeof(VersionSettings));
memcpy(v, scummVersions, scummCount * sizeof(VersionSettings));
memcpy(v+scummCount, simonVersions, simonCount * sizeof(VersionSettings));
+ memcpy(v+skyCount, skyVersions, skyCount * sizeof(VersionSettings));
version_settings = v;
}
}
diff --git a/common/gameDetector.h b/common/gameDetector.h
index 472d00ef33..fa27c75835 100644
--- a/common/gameDetector.h
+++ b/common/gameDetector.h
@@ -40,7 +40,11 @@ enum GameId {
// Simon the Sorcerer
GID_SIMON_FIRST,
- GID_SIMON_LAST = GID_SIMON_FIRST + 99
+ GID_SIMON_LAST = GID_SIMON_FIRST + 99,
+
+ // Beneath a Steel Sky
+ GID_SKY_FIRST,
+ GID_SKY_LAST = GID_SKY_FIRST + 99
};
// TODO: the GameFeatures really should be moved to scumm/scumm.h, too
diff --git a/sky/disk.cpp b/sky/disk.cpp
new file mode 100644
index 0000000000..8649b699b3
--- /dev/null
+++ b/sky/disk.cpp
@@ -0,0 +1,211 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/engine.h"
+#include "common/file.h"
+#include "sky/skydefs.h"
+#include "sky/sky.h"
+
+#define no_of_files_hd 1600
+#define no_of_files_cd 5200
+#define max_files_in_list 60
+
+extern uint16 UnpackM1(void *, void *, uint16);
+
+const char *data_file_name = "sky.dsk";
+const char *dinner_file_name = "sky.dnr";
+uint8 *dinner_table_area, *fixed_dest, *file_dest, *comp_dest;
+uint32 dinner_table_size, file_flags, file_offset, file_size, decomp_size, comp_file;
+uint16 build_list[max_files_in_list];
+uint32 loaded_file_list[max_files_in_list];
+
+File *data_disk_handle = new File();
+File *dnr_handle = new File();
+
+void SkyState::initialise_disk()
+{
+ uint32 entries_read;
+
+ dnr_handle->open(dinner_file_name, _gameDataPath);
+ if (dnr_handle->isOpen() == false)
+ error("Could not open %s%s!\n", _gameDataPath, dinner_file_name);
+
+ if (!(dinner_table_size = dnr_handle->readUint32LE()))
+ error("Error reading from sky.dnr!\n"); //even though it was opened correctly?!
+
+ debug(1, "Entries in dinner table: %d", dinner_table_size);
+
+ dinner_table_area = (uint8 *)malloc(dinner_table_size*8);
+ entries_read = dnr_handle->read(dinner_table_area, 8*dinner_table_size) / 8;
+
+ if (entries_read != dinner_table_size)
+ warning("bytes_read != dinner_table_entries. [%d/%d]\n", entries_read, dinner_table_size);
+
+ data_disk_handle->open(data_file_name, _gameDataPath);
+ if (data_disk_handle->isOpen() == false)
+ error("Error opening %s%s!\n", _gameDataPath, data_file_name);
+}
+
+//load in file file_nr to address dest
+//if dest == NULL, then allocate memory for this file
+uint16 *SkyState::load_file(uint16 file_nr, uint8 *dest)
+{
+ uint8 cflag;
+ uint32 eax, ecx;
+ int32 bytes_read;
+ uint8 *file_ptr, *esiptr, *ediptr;
+ s file_header;
+
+ #ifdef file_order_chk
+ warning("File order checking not implemented yet!\n");
+ #endif
+
+ comp_file = file_nr;
+ debug(1, "load file %d,%d (%d)", (file_nr>>11), (file_nr&2047), file_nr);
+
+
+ file_ptr = (uint8 *)get_file_info(file_nr);
+ if (file_ptr == NULL) {
+ printf("File %d not found!\n", file_nr);
+ return NULL;
+ }
+
+ eax = READ_LE_UINT32((file_ptr+5));
+ file_flags = eax;
+ eax &= 0x03fffff;
+ file_size = eax;
+
+ ecx = READ_LE_UINT32((file_ptr+2));
+ ecx &= 0x0ffffff;
+
+ cflag = (uint8)((ecx >> (23)) & 0x1);
+ ecx = (((1 << (23)) ^ 0xFFFFFFFF) & ecx);
+
+ if (cflag)
+ ecx = ecx << 4;
+
+ file_offset = ecx;
+ fixed_dest = dest;
+ file_dest = dest;
+ comp_dest = dest;
+
+ if (dest == NULL) //we need to allocate memory for this file
+ file_dest = (uint8 *)malloc(eax);
+
+ data_disk_handle->seek(file_offset, SEEK_SET);
+
+ #ifdef file_order_chk
+ warning("File order checking not implemented yet!\n");
+ #endif
+
+ //now read in the data
+ bytes_read = data_disk_handle->read(file_dest, 1*file_size);
+
+ if (bytes_read != (int32)file_size)
+ printf("ERROR: Unable to read %d bytes from datadisk (%d bytes read)\n", file_size, bytes_read);
+
+ cflag = (uint8)((file_flags >> (23)) & 0x1);
+
+ //if cflag == 0 then file is compressed, 1 == uncompressed
+
+ if (!cflag)
+ {
+ debug(1, "File is compressed...");
+
+ memcpy(&file_header, file_dest, sizeof(struct s));
+ if ( (uint8)((FROM_LE_16(file_header.flag) >> 7) & 0x1) ) {
+ debug(1, "with RNC!");
+
+ eax = FROM_LE_16(file_header.flag);
+ eax &= 0xFFFFFF00; //clear al
+ eax = eax << 8;
+ eax |= FROM_LE_16((uint16)file_header.s_tot_size);
+
+ decomp_size = eax;
+
+ if (fixed_dest == NULL) // is this valid?
+ comp_dest = (uint8 *)malloc(eax);
+
+ esiptr = file_dest;
+ ediptr = comp_dest;
+
+ if ( (uint8)(file_flags >> (22) & 0x1) ) //do we include the header?
+ esiptr += sizeof(struct s);
+ else {
+ memcpy(ediptr, esiptr, sizeof(struct s));
+ esiptr += sizeof(struct s);
+ ediptr += sizeof(struct s);
+ }
+
+ eax = UnpackM1(esiptr, ediptr, 0);
+
+ debug(2, "UnpackM1 returned: %d", eax);
+
+ if (eax == 0) { //Unpack returned 0: file was probably not packed.
+ if (fixed_dest == NULL)
+ free(comp_dest);
+
+ return (uint16 *)file_dest;
+ }
+
+ if (! (uint8)(file_flags >> (22) & 0x1) ) { //include header?
+ eax += sizeof(struct s);
+
+ if (eax != decomp_size)
+ {
+ debug(1, "ERROR: invalid decomp size! (was: %d, should be: %d)", eax, decomp_size);
+ }
+ }
+
+ if (fixed_dest == NULL)
+ free(file_dest);
+
+ }
+ else
+ debug(1, "but not with RNC! (?!)");
+
+ }
+ else
+ return (uint16 *)file_dest;
+
+ return (uint16 *)comp_dest;
+}
+
+uint16 *SkyState::get_file_info(uint16 file_nr)
+{
+ uint16 i;
+ uint16 *dnr_tbl_16_ptr = (uint16 *)dinner_table_area;
+
+ for (i = 0; i < dinner_table_size/2; i++)
+ {
+ if (READ_LE_UINT16(dnr_tbl_16_ptr+(i*4)) == file_nr)
+ {
+ debug(1, "file %d found!", file_nr);
+ return (dnr_tbl_16_ptr+(i*4));
+ }
+ }
+
+ //if file is speech file then return NULL if not found
+ printf("get_file_info() - speech file support not implemented yet!\n");
+ return (uint16 *)NULL;
+}
+
diff --git a/sky/intro.cpp b/sky/intro.cpp
new file mode 100644
index 0000000000..b13d8ebece
--- /dev/null
+++ b/sky/intro.cpp
@@ -0,0 +1,266 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <string.h>
+#include "common/scummsys.h"
+#include "sky/skydefs.h"
+#include "sky/sky.h"
+
+#define intro_text_width 128
+
+#define fn_a_pal 60080
+#define fn_1a_log 60081
+#define fn_1a 60082
+#define fn_1b 60083
+#define fn_1c 60084
+#define fn_1d 60085
+#define fn_1e 60086
+#define fn_4a 60087
+#define fn_4b_log 60088
+#define fn_4b 60089
+#define fn_4c_log 60090
+#define fn_4c 60091
+#define fn_5_pal 60092
+#define fn_5_log 60093
+#define fn_5 60094
+#define fn_6_pal 60095
+#define fn_6_log 60096
+#define fn_6a 60097
+#define fn_6b 60098
+
+#ifdef short_intro_start
+#define virgin_time_1 3
+#define viring_time_2 3
+#define rev_time 8
+#define gibb_time 6
+#else
+#define virgin_time_1 (3*50)
+#define virgin_time_2 ((3*50)+8)
+#define rev_time ((8*50)+8)
+#define gibb_time ((6*50)+8)
+#endif
+
+void prepare_text(void);
+void show_intro_text(void);
+void remove_text(void);
+void intro_fx(void);
+void intro_vol(void);
+
+uint8 *seq1a_data;
+uint8 *seq1b_data;
+uint8 *seq1c_data;
+uint8 *seq1d_data;
+uint8 *seq1e_data;
+uint8 *seq4a_data;
+uint8 *seq4b_data;
+uint8 *seq4c_data;
+uint8 *seq5_data;
+uint8 *seq6a_data;
+uint8 *seq6b_data;
+
+
+uint8 *vga_data;
+uint8 *diff_data;
+
+uint8 *work_base;
+uint8 *work_screen;
+uint8 *work_screen_end;
+
+uint8 *intro_text_space; //space for storing text messages
+uint8 *intro_text_save; //save screen data here
+
+uint8 *vga_pointer;
+uint8 *diff_pointer;
+
+uint32 no_frames; //number of frames in scrolling intro
+uint32 frame_counter;
+
+#define ic_prepare_text 0
+#define ic_show_text 1
+#define ic_remove_text 2
+#define ic_make_sound 3
+#define ic_fx_volume 4
+
+
+typedef void (*pfc)(void);
+pfc command_routines[] = { &prepare_text, &show_intro_text, &remove_text, &intro_fx, &intro_vol };
+
+uint32 cockpit_commands[] =
+{
+ 1000, //do straight away
+ ic_prepare_text,
+ 77,
+ 220,
+ ic_show_text, //radar detects jamming signal
+ 20,
+ 160,
+ 105,
+ ic_remove_text,
+ 81,
+ 105,
+ ic_show_text, //well switch to override you fool
+ 170,
+ 86,
+ 35,
+ ic_remove_text,
+ 35,
+ ic_prepare_text,
+ 477,
+ 35,
+ ic_show_text,
+ 30,
+ 160,
+ 3,
+ ic_remove_text
+};
+
+uint32 zero_commands[] = { 0 };
+
+uint32 anim5_commands[] =
+{
+ 31,
+ ic_make_sound,
+ 2,
+ 127,
+ 0
+};
+
+uint32 anim4a_commands[] =
+{
+ 136,
+ ic_make_sound,
+ 1,
+ 70,
+ 90,
+ ic_fx_volume,
+ 80,
+ 50,
+ ic_fx_volume,
+ 90,
+ 5,
+ ic_fx_volume,
+ 100,
+ 0
+};
+
+uint32 anim4c_commands[] =
+{
+ 1000,
+ ic_fx_volume,
+ 100,
+ 25,
+ ic_fx_volume,
+ 110,
+ 15,
+ ic_fx_volume,
+ 120,
+ 4,
+ ic_fx_volume,
+ 127,
+ 0
+};
+
+uint32 anim6a_commands[] =
+{
+ 1000,
+ ic_prepare_text,
+ 478,
+ 13,
+ ic_show_text,
+ 175,
+ 155,
+ 0
+};
+
+uint32 anim6b_commands[] =
+{
+ 131,
+ ic_remove_text,
+ 131,
+ ic_prepare_text,
+ 479,
+ 74,
+ ic_show_text,
+ 175,
+ 155,
+ 45,
+ ic_remove_text,
+ 45,
+ ic_prepare_text,
+ 162,
+ 44,
+ ic_show_text,
+ 175,
+ 155,
+ 4,
+ ic_remove_text,
+ 0
+};
+
+uint32 *command_pointer = (uint32 *)zero_commands;
+
+
+void SkyState::init_virgin()
+{
+ _temp_pal = (uint8 *)load_file(60111, NULL);
+ if (_temp_pal != NULL)
+ set_palette(_temp_pal);
+
+ _work_screen = (uint8 *)load_file(60110, NULL);
+
+ if (_work_screen != NULL)
+ show_screen();
+
+ //free the memory that was malloc'ed indirectly via load_file
+ free (_work_screen);
+ free (_temp_pal);
+}
+
+void SkyState::show_screen(void)
+{
+ _system->copy_rect(_work_screen, 320, 0, 0, 320, 200);
+ _system->update_screen();
+}
+
+void prepare_text(void)
+{
+
+}
+
+void show_intro_text(void)
+{
+
+}
+
+void remove_text(void)
+{
+
+}
+
+void intro_fx(void)
+{
+
+}
+
+void intro_vol(void)
+{
+
+}
diff --git a/sky/rnc_deco.cpp b/sky/rnc_deco.cpp
new file mode 100644
index 0000000000..975f3736da
--- /dev/null
+++ b/sky/rnc_deco.cpp
@@ -0,0 +1,345 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <string.h>
+#include "common/scummsys.h"
+
+#define ROL(x, n) (((x) << (n)) | ((x) >> (16-(n))))
+#define ROR(x, n) (((x) << (16-(n))) | ((x) >> (n)))
+#define XCHG(a, b) (a ^=b, b ^= a, a ^= b)
+
+//conditional flags
+#define CHECKSUMS 1
+#define PROTECTED 0
+
+//return codes
+#define NOT_PACKED 0
+#define PACKED_CRC -1
+#define UNPACKED_CRC -2
+
+//other defines
+#define TABLE_SIZE (16*8)
+#define MIN_LENGTH 2
+#define HEADER_LEN 18
+
+uint16 raw_table[TABLE_SIZE/2];
+uint16 pos_table[TABLE_SIZE/2];
+uint16 len_table[TABLE_SIZE/2];
+
+#ifdef CHECKSUMS
+uint16 crc_table[0x100];
+#endif
+
+uint32 unpack_len = 0;
+uint32 pack_len = 0;
+uint16 pack_paras = 0;
+uint16 counts = 0;
+uint16 bit_buffl = 0;
+uint16 bit_buffh = 0;
+uint8 blocks = 0;
+uint8 bit_count = 0;
+
+#ifdef CHECKSUMS
+uint16 crc_u = 0;
+uint16 crc_p = 0;
+#endif
+
+
+uint8 *esiptr, *ediptr; //these need to be global because input_bits() uses them
+
+void init_crc(void)
+{
+ uint16 cnt=0;
+ uint16 tmp1=0;
+ uint16 tmp2=0;
+
+ for (tmp2 = 0; tmp2 < 0x100; tmp2++) {
+ tmp1 = tmp2;
+ for (cnt = 8; cnt > 0; cnt--) {
+ if (tmp1 % 2) {
+ tmp1 /= 2;
+ tmp1 ^= 0x0a001;
+ }
+ else
+ tmp1 /= 2;
+ }
+ crc_table[tmp2] = tmp1;
+ }
+}
+
+//calculate 16 bit crc of a block of memory
+uint16 crc_block(uint8 *block, uint32 size)
+{
+ uint16 crc=0;
+ uint8 *crcTable8 = (uint8 *)crc_table; //make a uint8* to crc_table
+ uint8 tmp;
+ uint32 i;
+
+ for (i = 0; i < size; i++) {
+ tmp = *block++;
+ crc ^= tmp;
+ tmp = (uint8)((crc>>8)&0x00FF);
+ crc &= 0x00FF;
+ crc = crc << 1;
+ crc = *(uint16 *)&crcTable8[crc];
+ crc ^= tmp;
+ }
+
+ return crc;
+}
+
+uint16 input_bits(uint8 amount)
+{
+ uint16 newBitBuffh = bit_buffh;
+ uint16 newBitBuffl = bit_buffl;
+ int16 newBitCount = bit_count;
+ uint16 remBits, returnVal;
+
+ returnVal = ((1 << amount) - 1) & newBitBuffl;
+ newBitCount -= amount;
+
+ if (newBitCount < 0) {
+ newBitCount += amount;
+ XCHG(newBitCount, amount);
+ remBits = ROR((uint16)(((1 << amount) - 1) & newBitBuffh), amount);
+ newBitBuffh >>= amount;
+ newBitBuffl >>= amount;
+ newBitBuffl |= remBits;
+ esiptr += 2;
+ newBitBuffh = READ_LE_UINT16(esiptr);
+ XCHG(newBitCount, amount);
+ amount -= newBitCount;
+ newBitCount = 16 - amount;
+ }
+ remBits = ROR((uint16)(((1 << amount) - 1) & newBitBuffh), amount);
+ bit_buffh = newBitBuffh >> amount;
+ bit_buffl = (newBitBuffl >> amount) | remBits;
+ bit_count = newBitCount;
+
+ return returnVal;
+
+}
+
+// RCL/RCR functions..operate on 16 bit ints only
+uint16 rcl(uint16 reg, uint16 *cflag)
+{
+ uint16 lsb = *cflag;
+ *cflag = reg >> 15;
+ return (reg << 1) | lsb;
+}
+
+uint16 rcr(uint16 reg, uint16 *cflag)
+{
+ uint16 msb = *cflag << 15;
+ *cflag = reg & 1;
+ return (reg >> 1) | msb;
+}
+
+
+
+void make_huftable(uint16 *table)
+{
+ uint16 bitLength, i, j;
+ uint16 numCodes = input_bits(5);
+
+ if (!numCodes)
+ return;
+
+ uint8 huffLength[16];
+ for (i = 0; i < numCodes; i++)
+ huffLength[i] = (uint8)(input_bits(4) & 0x00FF);
+
+ uint16 huffCode = 0;
+
+ for (bitLength = 1; bitLength < 17; bitLength++) {
+ for (i = 0; i < numCodes; i++) {
+ if (huffLength[i] == bitLength) {
+ *table++ = (1 << bitLength) - 1;
+
+ uint16 b = huffCode >> (16 - bitLength);
+ uint16 a = 0;
+ uint16 carry = 0;
+
+ for (j = 0; j < bitLength; j++) {
+ b = rcr(b, &carry);
+ a = rcl(a, &carry);
+
+ }
+ *table++ = a;
+
+ *(table+0x1e) = (huffLength[i]<<8)|(i & 0x00FF);
+ huffCode += 1 << (16 - bitLength);
+ }
+ }
+ }
+}
+
+
+uint16 input_value(uint16 *table)
+{
+ uint16 valOne, valTwo, value = bit_buffl;
+
+ do {
+ valTwo = (*table++) & value;
+ valOne = *table++;
+
+ } while (valOne != valTwo);
+
+ value = *(table+0x1e);
+ input_bits((uint8)((value>>8)&0x00FF));
+ value &= 0x00FF;
+
+ if (value >= 2) {
+ value--;
+ valOne = input_bits((uint8)value&0x00FF);
+ valOne |= (1 << value);
+ value = valOne;
+ }
+
+ return value;
+}
+
+int UnpackM1(void *input, void *output, uint16 key)
+{
+ uint8 cl;
+ uint8 *inputHigh, *outputLow;
+ uint32 eax, ebx, ecx, edx;
+ uint8 *inputptr = (uint8 *)input;
+
+ if (CHECKSUMS)
+ init_crc();
+
+ //Check for "RNC "
+ if (READ_BE_UINT32(inputptr) != 0x524e4301)
+ return NOT_PACKED;
+
+ inputptr += 4;
+
+ // read unpacked/packed file length
+ unpack_len = READ_BE_UINT32(inputptr); inputptr += 4;
+ pack_len = READ_BE_UINT32(inputptr); inputptr += 4;
+
+ blocks = *(inputptr+5);
+
+ if (CHECKSUMS) {
+ //read CRC's
+ crc_u = READ_BE_UINT16(inputptr); inputptr += 2;
+ crc_p = READ_BE_UINT16(inputptr); inputptr += 2;
+
+ inputptr = (inputptr+HEADER_LEN-16);
+
+ if (crc_block(inputptr, pack_len) != crc_p)
+ return PACKED_CRC;
+
+ inputptr = (((uint8 *)input)+HEADER_LEN);
+ esiptr = inputptr;
+
+ }
+
+ inputHigh = ((uint8 *)input) + pack_len + HEADER_LEN;;
+ outputLow = (uint8 *)output;
+
+ eax = *(((uint8 *)input)+16) + unpack_len;
+
+ if (! ((inputHigh <= outputLow ) || ((outputLow+eax) <= inputHigh )) ) {
+ esiptr = inputHigh;
+ ediptr = (outputLow+eax);
+ memcpy((ediptr-pack_len), (esiptr-pack_len), pack_len);
+ esiptr = (ediptr-pack_len);
+ }
+
+
+ //unpack3:
+ ediptr = (uint8 *)output;
+ bit_count = 0;
+
+ bit_buffl = READ_LE_UINT16(esiptr);
+ /*eax =*/ input_bits(2);
+
+
+ //Argh! Labels!!
+ unpack4:
+ make_huftable(raw_table);
+ make_huftable(pos_table);
+ make_huftable(len_table);
+
+ counts = input_bits(16);
+
+ goto unpack6;
+
+ unpack5:
+
+ eax = input_value(pos_table) + 1; //input offset
+ ecx = input_value(len_table) + MIN_LENGTH; //input length
+
+ inputHigh = esiptr;
+ esiptr = (ediptr-eax);
+
+ //Don't use memcpy here! because input and output overlap
+ while (ecx) {
+ *ediptr++ = *esiptr++; ecx--;
+ }
+
+ esiptr = inputHigh;
+
+ unpack6:
+
+ ecx = input_value(raw_table);
+
+ if (ecx == 0)
+ goto unpack7;
+
+ memcpy(ediptr, esiptr, ecx); //memcpy is allowed here
+ ediptr += ecx;
+ esiptr += ecx;
+ cl = bit_count;
+ eax = READ_LE_UINT16(esiptr);
+ ebx = eax;
+ eax = ROL((uint16)eax, cl);
+ edx = ((1 << cl) - 1) & 0x0000FFFF; //make sure we only get 16bits
+ bit_buffl &= (uint16)edx;
+ edx &= eax;
+
+ eax = READ_LE_UINT16((esiptr+2));
+ ebx = (ebx << cl)&0x0000FFFF;
+ eax = (eax << cl)&0x0000FFFF;
+ eax |= edx;
+ bit_buffl |= (uint16)ebx;
+ bit_buffh = (uint16)eax;
+
+ unpack7:
+
+ counts--;
+ if (counts)
+ goto unpack5;
+
+ blocks--;
+ if (blocks)
+ goto unpack4;
+
+ if (CHECKSUMS) {
+ if (crc_block((uint8 *)output, unpack_len) != crc_u)
+ return UNPACKED_CRC;
+ }
+
+ // all is done..return the amount of unpacked bytes
+ return unpack_len;
+}
diff --git a/sky/screen.cpp b/sky/screen.cpp
new file mode 100644
index 0000000000..c262a7b434
--- /dev/null
+++ b/sky/screen.cpp
@@ -0,0 +1,96 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <string.h>
+#include "common/scummsys.h"
+#include "sky/skydefs.h"
+#include "sky/sky.h"
+
+#define fade_jump 2
+#define scroll_jump 16
+
+#define vga_colours 256
+#define game_colours 240
+
+uint8 top_16_colours[] =
+{
+ 0, 0, 0,
+ 38, 38, 38,
+ 63, 63, 63,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 54, 54, 54,
+ 45, 47, 49,
+ 32, 31, 41,
+ 29, 23, 37,
+ 23, 18, 30,
+ 49, 11, 11,
+ 39, 5, 5,
+ 29, 1, 1,
+ 63, 63, 63
+};
+
+void SkyState::initialise_screen(void)
+{
+ int i;
+ uint8 tmp_pal[1024];
+
+ _system->init_size(full_screen_width, full_screen_height);
+ _backscreen = (uint8 *)malloc(full_screen_width*full_screen_height);
+ _game_grid = (uint8 *)malloc(GRID_X*GRID_Y*2);
+ _work_palette = (uint8 *)malloc(vga_colours*3);
+
+ //blank the first 240 colors of the palette
+ bzero(tmp_pal, game_colours*4);
+
+ //set the remaining colors
+ for (i=0; i<(vga_colours-game_colours); i++) {
+ tmp_pal[game_colours+i*4] = (top_16_colours[i*3] << 2) + (top_16_colours[i*3] & 3);
+ tmp_pal[game_colours+i*4+1] = (top_16_colours[i*3+1] << 2) + (top_16_colours[i*3+1] & 3);
+ tmp_pal[game_colours+i*4+2] = (top_16_colours[i*3+2] << 2) + (top_16_colours[i*3+2] & 3);
+ tmp_pal[game_colours+i*4+3] = 0x00;
+ }
+
+ //set the palette
+ _system->set_palette(tmp_pal, 0, 256);
+
+}
+
+//set a new palette, pal is a pointer to dos vga rgb components 0..63
+void SkyState::set_palette(uint8 *pal)
+{
+ convert_palette(pal, _palette);
+ _system->set_palette(_palette, 0, 256);
+}
+
+void SkyState::convert_palette(uint8 *inpal, uint8* outpal) //convert 3 byte 0..63 rgb to 4byte 0..255 rgbx
+{
+ int i;
+
+ for (i = 0; i < vga_colours; i++) {
+ outpal[4*i] = (inpal[3*i] << 2) + (inpal[3*i] & 3);
+ outpal[4*i+1] = (inpal[3*i+1] << 2) + (inpal[3*i+1] & 3);
+ outpal[4*i+2] = (inpal[3*i+2] << 2) + (inpal[3*i+2] & 3);
+ outpal[4*i+3] = 0x00;
+ }
+}
diff --git a/sky/sky.cpp b/sky/sky.cpp
new file mode 100644
index 0000000000..2006c9aead
--- /dev/null
+++ b/sky/sky.cpp
@@ -0,0 +1,148 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "sky/sky.h"
+#include "sky/skydefs.h" //game specific defines
+#include "common/file.h"
+#include "common/gameDetector.h"
+#include <errno.h>
+#include <time.h>
+
+#ifdef _WIN32_WCE
+
+extern bool toolbar_drawn;
+extern bool draw_keyboard;
+
+#endif
+
+static const VersionSettings sky_settings[] = {
+ /* Beneath a Steel Sky */
+ {"sky", "Beneath a Steel Sky", GID_SKY_FIRST, 99, 99, 99, 0, "sky.dsk" },
+ {NULL, NULL, 0, 0, 0, 0, 0, NULL}
+};
+
+const VersionSettings *Engine_SKY_targetList()
+{
+ return sky_settings;
+}
+
+Engine *Engine_SKY_create(GameDetector *detector, OSystem *syst)
+{
+ return new SkyState(detector, syst);
+}
+
+SkyState::SkyState(GameDetector *detector, OSystem *syst)
+ : Engine(detector, syst)
+{
+ _game = detector->_gameId;
+
+ _debugMode = detector->_debugMode;
+ _debugLevel = detector->_debugLevel;
+ _language = detector->_language;
+}
+
+SkyState::~SkyState()
+{
+
+}
+
+void SkyState::pollMouseXY()
+{
+ _mouse_x = _sdl_mouse_x;
+ _mouse_y = _sdl_mouse_y;
+}
+
+void SkyState::go()
+{
+ if (!_dump_file)
+ _dump_file = stdout;
+
+ initialise();
+
+ while (1) {
+ delay(100);
+ }
+}
+
+void SkyState::initialise(void)
+{
+ //initialise_memory();
+ //init_timer();
+ //init_music();
+ initialise_disk();
+ initialise_screen();
+ init_virgin();
+
+}
+
+void SkyState::delay(uint amount) //copied and mutilated from Simon.cpp
+{
+ OSystem::Event event;
+
+ uint32 start = _system->get_msecs();
+ uint32 cur = start;
+
+ _rnd.getRandomNumber(2);
+
+ do {
+ while (_system->poll_event(&event)) {
+ switch (event.event_code) {
+ case OSystem::EVENT_KEYDOWN:
+ // Make sure backspace works right (this fixes a small issue on OS X)
+ if (event.kbd.keycode == 8)
+ _key_pressed = 8;
+ else
+ _key_pressed = (byte)event.kbd.ascii;
+ break;
+
+ case OSystem::EVENT_MOUSEMOVE:
+ _sdl_mouse_x = event.mouse.x;
+ _sdl_mouse_y = event.mouse.y;
+ _mouse_pos_changed = true;
+ break;
+
+ case OSystem::EVENT_LBUTTONDOWN:
+ _left_button_down++;
+#ifdef _WIN32_WCE
+ _sdl_mouse_x = event.mouse.x;
+ _sdl_mouse_y = event.mouse.y;
+#endif
+ break;
+
+ case OSystem::EVENT_RBUTTONDOWN:
+
+ break;
+ }
+ }
+
+ if (amount == 0)
+ break;
+
+ {
+ uint this_delay = 20; // 1?
+ if (this_delay > amount)
+ this_delay = amount;
+ _system->delay_msecs(this_delay);
+ }
+ cur = _system->get_msecs();
+ } while (cur < start + amount);
+}
+
diff --git a/sky/sky.h b/sky/sky.h
new file mode 100644
index 0000000000..89b2417e71
--- /dev/null
+++ b/sky/sky.h
@@ -0,0 +1,89 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef SKYMAIN_H
+#define SKYMAIN_H
+
+#include <stdio.h>
+#include "common/engine.h"
+#include "common/util.h"
+
+class SkyState : public Engine {
+public:
+
+ byte _game;
+ byte _key_pressed;
+
+ uint16 _debugMode;
+ uint16 _debugLevel;
+ uint16 _language;
+ uint _mouse_x, _mouse_y;
+ uint _mouse_x_old, _mouse_y_old;
+ bool _mouse_pos_changed;
+ uint _left_button_down;
+
+ uint8 _palette[1024];
+
+ int _num_screen_updates;
+
+// int _timer_id;
+
+ FILE *_dump_file;
+
+ int _number_of_savegames;
+
+ int _sdl_mouse_x, _sdl_mouse_y;
+
+ byte *_work_screen;
+ byte *_backscreen;
+ byte *_temp_pal;
+ byte *_work_palette;
+ byte *_half_palette;
+
+ byte *_game_grid;
+
+ SkyState(GameDetector *detector, OSystem *syst);
+ virtual ~SkyState();
+
+ void delay(uint amount);
+ void pollMouseXY();
+ void go();
+ void convert_palette(uint8 *inpal, uint8* outpal);
+
+ void initialise();
+ void initialise_disk();
+ void initialise_screen();
+ void set_palette(uint8 *pal);
+ uint16 *load_file(uint16 file_nr, uint8 *dest);
+ uint16 *get_file_info(uint16 file_nr);
+ void init_virgin();
+ void show_screen();
+
+ static int CDECL game_thread_proc(void *param);
+
+ void shutdown();
+
+ RandomSource _rnd;
+
+
+};
+
+#endif
diff --git a/sky/skydefs.h b/sky/skydefs.h
new file mode 100644
index 0000000000..292dce6523
--- /dev/null
+++ b/sky/skydefs.h
@@ -0,0 +1,90 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "struc.h"
+
+//This file is incomplete, several flags still missing.
+
+#define key_buffer_size 80
+#define sequence_count 3
+
+//screen/grid defines
+#define game_screen_width 320
+#define game_screen_height 192
+#define full_screen_width 320
+#define full_screen_height 200
+
+#define tot_no_grids 70
+
+#define grid_size 120
+
+#define GRID_X 20
+#define GRID_Y 24
+#define GRID_W 16
+#define GRID_H 8
+
+#define GRID_W_SHIFT 4
+#define GRID_H_SHIFT 3
+
+#define top_left_x 128
+#define top_left_y 136
+
+//item list defines
+#define section_0_item 119
+
+#define c_base_mode 0
+#define c_base_mode56 56
+#define c_action_mode 4
+#define c_sp_colour 90
+#define c_mega_set 112
+#define c_grid_width 114
+
+//#define next_mega_set
+
+#define send_sync -1
+#define lf_start_fx -2
+#define safe_start_screen 0
+
+//autoroute defines
+#define upy 0
+#define downy 1
+#define lefty 2
+#define righty 3
+
+#define route_space 64
+
+#define l_script 1
+#define l_ar 2
+#define l_ar_anim 3
+#define l_ar_turning 4
+#define l_alt 5
+#define l_mod_animate 6
+#define l_turning 7
+#define l_cursor 8
+#define l_talk 9
+#define l_listen 10
+#define l_stopped 11
+#define l_choose 12
+#define l_frames 13
+#define l_pause 14
+#define l_wait_synch 15
+#define l_simple_mod 16
+
diff --git a/sky/struc.h b/sky/struc.h
new file mode 100644
index 0000000000..56d1a305ab
--- /dev/null
+++ b/sky/struc.h
@@ -0,0 +1,38 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+typedef struct s
+{
+ uint16 flag; // bit 0: set for colour data, clear for not
+ // bit 1: set for compressed, clear for uncompressed
+ // bit 2: set for 32 colours, clear for 16 colours
+ uint16 s_x;
+ uint16 s_y;
+ uint16 s_width;
+ uint16 s_height;
+ uint16 s_sp_size;
+ uint16 s_tot_size;
+ uint16 s_n_sprites;
+ uint16 s_offset_x;
+ uint16 s_offset_y;
+ uint16 s_compressed_size;
+}s;
+