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 /sky/disk.cpp | |
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
Diffstat (limited to 'sky/disk.cpp')
-rw-r--r-- | sky/disk.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
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; +} + |