aboutsummaryrefslogtreecommitdiff
path: root/sky/disk.cpp
diff options
context:
space:
mode:
authorMax Horn2003-03-05 19:04:34 +0000
committerMax Horn2003-03-05 19:04:34 +0000
commit5ffeedb1cbea471b3d902da96767ffad168023c5 (patch)
tree5ba28837ca5499b4ae6edcab35d5522c63612a1b /sky/disk.cpp
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
Diffstat (limited to 'sky/disk.cpp')
-rw-r--r--sky/disk.cpp211
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;
+}
+