diff options
author | Max Horn | 2003-03-05 19:04:34 +0000 |
---|---|---|
committer | Max Horn | 2003-03-05 19:04:34 +0000 |
commit | 5ffeedb1cbea471b3d902da96767ffad168023c5 (patch) | |
tree | 5ba28837ca5499b4ae6edcab35d5522c63612a1b | |
parent | f02506f9931c3b4d7eb97887e16228623461011b (diff) | |
download | scummvm-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.common | 2 | ||||
-rw-r--r-- | common/engine.cpp | 3 | ||||
-rw-r--r-- | common/engine.h | 2 | ||||
-rw-r--r-- | common/gameDetector.cpp | 6 | ||||
-rw-r--r-- | common/gameDetector.h | 6 | ||||
-rw-r--r-- | sky/disk.cpp | 211 | ||||
-rw-r--r-- | sky/intro.cpp | 266 | ||||
-rw-r--r-- | sky/rnc_deco.cpp | 345 | ||||
-rw-r--r-- | sky/screen.cpp | 96 | ||||
-rw-r--r-- | sky/sky.cpp | 148 | ||||
-rw-r--r-- | sky/sky.h | 89 | ||||
-rw-r--r-- | sky/skydefs.h | 90 | ||||
-rw-r--r-- | sky/struc.h | 38 |
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; + |