diff options
| -rw-r--r-- | engines/sci/engine/kfile.cpp | 112 | ||||
| -rw-r--r-- | engines/sci/include/sciresource.h | 119 | ||||
| -rw-r--r-- | engines/sci/sci.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/scicore/decompress0.cpp | 22 | ||||
| -rw-r--r-- | engines/sci/scicore/decompress01.cpp | 12 | ||||
| -rw-r--r-- | engines/sci/scicore/decompress1.cpp | 20 | ||||
| -rw-r--r-- | engines/sci/scicore/decompress11.cpp | 17 | ||||
| -rw-r--r-- | engines/sci/scicore/resource.cpp | 320 | ||||
| -rw-r--r-- | engines/sci/scicore/resource_map.cpp | 137 | ||||
| -rw-r--r-- | engines/sci/scicore/resource_patch.cpp | 169 | ||||
| -rw-r--r-- | engines/sci/scicore/tools.cpp | 84 | 
11 files changed, 399 insertions, 617 deletions
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 291fda4208..b66e8fd272 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -58,6 +58,30 @@ static FILE *f_open_mirrored(state_t *s, char *fname) {  	char *buf = NULL;  	int fsize; + +	printf("f_open_mirrored(%s)\n", fname); +#if 0 +	// TODO/FIXME: Use s->resource_dir to locate the file??? +	File file; +	if (!file.open(fname)) +		return NULL; + +	fsize = file.size(); +	if (fsize > 0) { +		buf = (char *)sci_malloc(fsize); +		file.read(buf, fsize); +	} + +	file.close(); + +	.... +	copy the file to a savegame -> only makes sense to perform this change +	if we at the same time change the code for loading files to look among the +	savestates, and also change *all* file writing code to write to savestates, +	as it should +	... +#endif +  	chdir(s->resource_dir);  	fd = sci_open(fname, O_RDONLY | O_BINARY);  	if (!IS_VALID_FD(fd)) { @@ -155,20 +179,28 @@ reg_t kFOpen(state_t *s, int funct_nr, int argc, reg_t *argv) {  	return s->r_acc;  } -void file_close(state_t *s, int handle) { -	SCIkdebug(SCIkFILE, "Closing file %d\n", handle); - +static FILE *getFileFromHandle(state_t *s, int handle) {  	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt to close file handle 0\n"); -		return; +		SCIkwarn(SCIkERROR, "Attempt to use file handle 0\n"); +		return 0;  	}  	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt to close invalid/unused file handle %d\n", handle); -		return; +		SCIkwarn(SCIkERROR, "Attempt to use invalid/unused file handle %d\n", handle); +		return 0;  	} +	 +	return s->file_handles[handle]; +} + +void file_close(state_t *s, int handle) { +	SCIkdebug(SCIkFILE, "Closing file %d\n", handle); -	fclose(s->file_handles[handle]); +	FILE *f = getFileFromHandle(s, handle); +	if (!f) +		return; + +	fclose(f);  	s->file_handles[handle] = NULL;  } @@ -181,33 +213,17 @@ reg_t kFClose(state_t *s, int funct_nr, int argc, reg_t *argv) {  void fputs_wrapper(state_t *s, int handle, int size, char *data) {  	SCIkdebug(SCIkFILE, "FPuts'ing \"%s\" to handle %d\n", data, handle); -	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt to write to file handle 0\n"); -		return; -	} - -	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt to write to invalid/unused file handle %d\n", handle); -		return; -	} - -	fwrite(data, 1, size, s->file_handles[handle]); +	FILE *f = getFileFromHandle(s, handle); +	if (f) +		fwrite(data, 1, size, f);  }  void fwrite_wrapper(state_t *s, int handle, char *data, int length) {  	SCIkdebug(SCIkFILE, "fwrite()'ing \"%s\" to handle %d\n", data, handle); -	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt to write to file handle 0\n"); -		return; -	} - -	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt to write to invalid/unused file handle %d\n", handle); -		return; -	} - -	fwrite(data, 1, length, s->file_handles[handle]); +	FILE *f = getFileFromHandle(s, handle); +	if (f) +		fwrite(data, 1, length, f);  }  reg_t kFPuts(state_t *s, int funct_nr, int argc, reg_t *argv) { @@ -221,17 +237,11 @@ reg_t kFPuts(state_t *s, int funct_nr, int argc, reg_t *argv) {  static void fgets_wrapper(state_t *s, char *dest, int maxsize, int handle) {  	SCIkdebug(SCIkFILE, "FGets'ing %d bytes from handle %d\n", maxsize, handle); -	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt to read from file handle 0\n"); +	FILE *f = getFileFromHandle(s, handle); +	if (!f)  		return; -	} -	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt to read from invalid/unused file handle %d\n", handle); -		return; -	} - -	fgets(dest, maxsize, s->file_handles[handle]); +	fgets(dest, maxsize, f);  	SCIkdebug(SCIkFILE, "FGets'ed \"%s\"\n", dest);  } @@ -239,31 +249,19 @@ static void fgets_wrapper(state_t *s, char *dest, int maxsize, int handle) {  static void fread_wrapper(state_t *s, char *dest, int bytes, int handle) {  	SCIkdebug(SCIkFILE, "fread()'ing %d bytes from handle %d\n", bytes, handle); -	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt to read from file handle 0\n"); +	FILE *f = getFileFromHandle(s, handle); +	if (!f)  		return; -	} - -	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt to read from invalid/unused file handle %d\n", handle); -		return; -	} -	s->r_acc = make_reg(0, fread(dest, 1, bytes, s->file_handles[handle])); +	s->r_acc = make_reg(0, fread(dest, 1, bytes, f));  }  static void fseek_wrapper(state_t *s, int handle, int offset, int whence) { -	if (handle == 0) { -		SCIkwarn(SCIkERROR, "Attempt seek on file handle 0\n"); -		return; -	} - -	if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) { -		SCIkwarn(SCIkERROR, "Attempt seek on invalid/unused file handle %d\n", handle); +	FILE *f = getFileFromHandle(s, handle); +	if (!f)  		return; -	} -	s->r_acc = make_reg(0, fseek(s->file_handles[handle], offset, whence)); +	s->r_acc = make_reg(0, fseek(f, offset, whence));  }  static char *_chdir_savedir(state_t *s) { diff --git a/engines/sci/include/sciresource.h b/engines/sci/include/sciresource.h index c75e295ca9..fc9bec41e8 100644 --- a/engines/sci/include/sciresource.h +++ b/engines/sci/include/sciresource.h @@ -29,6 +29,9 @@  /*#define _SCI_RESOURCE_DEBUG */  /*#define _SCI_DECOMPRESS_DEBUG*/ +#include "common/stream.h" +#include "common/str.h" +  #include "sci/include/resource.h"  #include "sci/include/versions.h" @@ -89,7 +92,6 @@  #define SCI_VERSION_1 SCI_VERSION_1_EARLY  #define RESSOURCE_TYPE_DIRECTORY 0 -#define RESSOURCE_TYPE_AUDIO_DIRECTORY 1  #define RESSOURCE_TYPE_VOLUME 2  #define RESSOURCE_TYPE_EXTERNAL_MAP 3  #define RESSOURCE_TYPE_INTERNAL_MAP 4 @@ -127,19 +129,10 @@ typedef struct resource_index_struct resource_index_t;  struct ResourceSource {  	int source_type; -	int scanned; -	union { -		struct { -			char *name; -			int volume_number; -		} file; -		struct { -			char *name; -		} dir; -		struct { -			struct _resource_struct *resource; -		} internal_map; -	} location; +	bool scanned; +	Common::String location_name;	// FIXME: Replace by FSNode ? +	Common::String location_dir_name;	// FIXME: Get rid of this again, only a temporary HACK! +	int volume_number;  	ResourceSource *associated_map;  	ResourceSource *next;  }; @@ -184,45 +177,38 @@ struct ResourceManager {  	int memory_locked; /* Amount of resource bytes in locked memory */  	int memory_lru; /* Amount of resource bytes under LRU control */ -	char *resource_path; /* Path to the resource and patch files */ -  	resource_t *lru_first, *lru_last; /* Pointers to the first and last LRU queue entries */  	/* LRU queue: lru_first points to the most recent entry */ + +public: +	/** +	 * Creates a new FreeSCI resource manager. +	 * @param version		The SCI version to look for; use SCI_VERSION_AUTODETECT +	 *						in the default case. +	 * @param maxMemory		Maximum number of bytes to allow allocated for resources +	 * +	 * @note maxMemory will not be interpreted as a hard limit, only as a restriction +	 *    for resources which are not explicitly locked. However, a warning will be +	 *    issued whenever this limit is exceeded. +	 */ +	ResourceManager(int version, int maxMemory); +	~ResourceManager();  };  /**** FUNCTION DECLARATIONS ****/  /**--- New Resource manager ---**/ -ResourceManager * -scir_new_resource_manager(char *dir, int version, int maxMemory); -/* Creates a new FreeSCI resource manager -** Parameters: (char *) dir: Path to the resource and patch files (not modified or freed -**                           by the resource manager) -**             (int) version: The SCI version to look for; use SCI_VERSION_AUTODETECT -**                            in the default case. -**             (int) maxMemory: Maximum number of bytes to allow allocated for resources -** Returns   : (ResourceManager *) A newly allocated resource manager -** maxMemory will not be interpreted as a hard limit, only as a restriction for resources -** which are not explicitly locked. However, a warning will be issued whenever this limit -** is exceeded. -*/ - -ResourceSource * -scir_add_patch_dir(ResourceManager *mgr, int type, char *path); +ResourceSource *scir_add_patch_dir(ResourceManager *mgr, const char *path);  /* Add a path to the resource manager's list of sources.  ** Parameters: (ResourceManager *) mgr: The resource manager to look up in -**             (int) dirtype: The type of patch directory to add, -**             either RESSOURCE_TYPE_DIRECTORY or RESSOURCE_TYPE_AUDIO_DIRECTORY -**             (char *) path: The path to add +**             (const char *) path: The path to add  ** Returns: A pointer to the added source structure, or NULL if an error occurred.  */ -ResourceSource * -scir_get_volume(ResourceManager *mgr, ResourceSource *map, int volume_nr); +ResourceSource *scir_get_volume(ResourceManager *mgr, ResourceSource *map, int volume_nr); -ResourceSource * -scir_add_volume(ResourceManager *mgr, ResourceSource *map, char *filename, +ResourceSource *scir_add_volume(ResourceManager *mgr, ResourceSource *map, const char *filename,                  int number, int extended_addressing);  /* Add a volume to the resource manager's list of sources.  ** Parameters: (ResourceManager *) mgr: The resource manager to look up in @@ -233,19 +219,10 @@ scir_add_volume(ResourceManager *mgr, ResourceSource *map, char *filename,  ** Returns: A pointer to the added source structure, or NULL if an error occurred.  */ -ResourceSource * -scir_add_external_map(ResourceManager *mgr, char *file_name); +ResourceSource *scir_add_external_map(ResourceManager *mgr, const char *file_name);  /* Add an external (i.e. separate file) map resource to the resource manager's list of sources.  ** Parameters: (ResourceManager *) mgr: The resource manager to look up in -**             (char *) file_name: The name of the volume to add -** Returns: A pointer to the added source structure, or NULL if an error occurred. -*/ - -ResourceSource * -scir_add_internal_map(ResourceManager *mgr, resource_t *map); -/* Add an internal (i.e. a resource) map resource to the resource manager's list of sources. -** Parameters: (ResourceManager *) mgr: The resource manager to look up in -**             (char *) file_name: The name of the volume to add +**             (const char *) file_name: The name of the volume to add  ** Returns: A pointer to the added source structure, or NULL if an error occurred.  */ @@ -294,17 +271,9 @@ scir_test_resource(ResourceManager *mgr, int type, int number);  ** Use scir_find_resource() if you want to use the data contained in the resource.  */ -void -scir_free_resource_manager(ResourceManager *mgr); -/* Frees a resource manager and all memory handled by it -** Parameters: (ResourceManager *) mgr: The Manager to free -** Returns   : (void) -*/ -  /**--- Resource map decoding functions ---*/ -int -sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **resources, int *resource_nr_p, int *sci_version); +int sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **resources, int *resource_nr_p, int *sci_version);  /* Reads the SCI0 resource.map file from a local directory  ** Parameters: (char *) path: (unused)  **             (resource_t **) resources: Pointer to a pointer @@ -317,8 +286,7 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  ** Returns   : (int) 0 on success, an SCI_ERROR_* code otherwise  */ -int -sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource *vol, +int sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource *vol,                         resource_t **resource_p, int *resource_nr_p, int *sci_version);  /* Reads the SCI1 resource.map file from a local directory  ** Parameters: (char *) path: (unused) @@ -352,8 +320,7 @@ sci1_sprintf_patch_file_name(char *string, resource_t *res);  ** Returns   : (void)  */ -int -sci0_read_resource_patches(ResourceSource *source, resource_t **resources, int *resource_nr_p); +int sci0_read_resource_patches(ResourceSource *source, resource_t **resources, int *resource_nr_p);  /* Reads SCI0 patch files from a local directory  ** Parameters: (char *) path: (unused)  **             (resource_t **) resources: Pointer to a pointer @@ -365,8 +332,7 @@ sci0_read_resource_patches(ResourceSource *source, resource_t **resources, int *  ** Returns   : (int) 0 on success, an SCI_ERROR_* code otherwise  */ -int -sci1_read_resource_patches(ResourceSource *source, resource_t **resources, int *resource_nr_p); +int sci1_read_resource_patches(ResourceSource *source, resource_t **resources, int *resource_nr_p);  /* Reads SCI1 patch files from a local directory  ** Parameters: (char *) path: (unused)  **             (resource_t **) resources: Pointer to a pointer @@ -382,39 +348,39 @@ sci1_read_resource_patches(ResourceSource *source, resource_t **resources, int *  /**--- Decompression functions ---**/ -int decompress0(resource_t *result, int resh, int sci_version); +int decompress0(resource_t *result, Common::ReadStream &stream, int sci_version);  /* Decrypts resource data and stores the result for SCI0-style compression.  ** Parameters : result: The resource_t the decompressed data is stored in. -**              resh  : File handle of the resource file +**              stream: Stream of the resource file  **              sci_version : Actual SCI resource version  ** Returns    : (int) 0 on success, one of SCI_ERROR_* if a problem was  **               encountered.  */ -int decompress01(resource_t *result, int resh, int sci_version); +int decompress01(resource_t *result, Common::ReadStream &stream, int sci_version);  /* Decrypts resource data and stores the result for SCI01-style compression.  ** Parameters : result: The resource_t the decompressed data is stored in. -**              resh  : File handle of the resource file +**              stream: Stream of the resource file  **              sci_version : Actual SCI resource version  ** Returns    : (int) 0 on success, one of SCI_ERROR_* if a problem was  **               encountered.  */ -int decompress1(resource_t *result, int resh, int sci_version); +int decompress1(resource_t *result, Common::ReadStream &stream, int sci_version);  /* Decrypts resource data and stores the result for SCI1.1-style compression.  ** Parameters : result: The resource_t the decompressed data is stored in.  **              sci_version : Actual SCI resource version -**              resh  : File handle of the resource file +**              stream: Stream of the resource file  ** Returns    : (int) 0 on success, one of SCI_ERROR_* if a problem was  **               encountered.  */ -int decompress11(resource_t *result, int resh, int sci_version); +int decompress11(resource_t *result, Common::ReadStream &stream, int sci_version);  /* Decrypts resource data and stores the result for SCI1.1-style compression.  ** Parameters : result: The resource_t the decompressed data is stored in.  **              sci_version : Actual SCI resource version -**              resh  : File handle of the resource file +**              stream: Stream of the resource file  ** Returns    : (int) 0 on success, one of SCI_ERROR_* if a problem was  **               encountered.  */ @@ -437,10 +403,10 @@ byte *pic_reorder(byte *inbuffer, int dsize);  /*--- Internal helper functions ---*/  void -_scir_free_resources(resource_t *resources, int resourcesNr); +_scir_free_resources(resource_t *resources, int _resourcesNr);  /* Frees a block of resources and associated data  ** Parameters: (resource_t *) resources: The resources to free -**             (int) resourcesNr: Number of resources in the block +**             (int) _resourcesNr: Number of resources in the block  ** Returns   : (void)  */ @@ -457,8 +423,7 @@ _scir_find_resource_unsorted(resource_t *res, int res_nr, int type, int number);  ** Returns   : (resource_t) The matching resource entry, or NULL if not found  */ -void -_scir_add_altsource(resource_t *res, ResourceSource *source, unsigned int file_offset); +void _scir_add_altsource(resource_t *res, ResourceSource *source, unsigned int file_offset);  /* Adds an alternative source to a resource  ** Parameters: (resource_t *) res: The resource to add to  **             (ResourceSource *) source: The source of the resource diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 9de4942bb8..50bf26d51c 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -199,7 +199,7 @@ Common::Error SciEngine::go() {  	char resource_dir[MAXPATHLEN+1] = "";  	getcwd(resource_dir, MAXPATHLEN); /* Store resource directory */ -	resmgr = scir_new_resource_manager(resource_dir, res_version, 256 * 1024); +	resmgr = new ResourceManager(res_version, 256 * 1024);  	if (!resmgr) {  		printf("No resources found in '%s'.\nAborting...\n", @@ -300,7 +300,7 @@ Common::Error SciEngine::go() {  	free(gamestate->work_dir);  	free(gamestate); -	scir_free_resource_manager(resmgr); +	delete resmgr;  	close_console_file(); diff --git a/engines/sci/scicore/decompress0.cpp b/engines/sci/scicore/decompress0.cpp index f65b7f9dd6..0c829ad3d8 100644 --- a/engines/sci/scicore/decompress0.cpp +++ b/engines/sci/scicore/decompress0.cpp @@ -225,18 +225,18 @@ int decrypt2(guint8* dest, guint8* src, int length, int complength)  /* Carl Muckenhoupt's decompression code ends here                         */  /***************************************************************************/ -int sci0_get_compression_method(int resh) { +int sci0_get_compression_method(Common::ReadStream &stream) {  	guint16 compressedLength;  	guint16 compressionMethod;  	guint16 result_size;  	/* Dummy variable */ -	if (read(resh, &result_size, 2) != 2) +	if (stream.read(&result_size, 2) != 2)  		return SCI_ERROR_IO_ERROR; -	if ((read(resh, &compressedLength, 2) != 2) || -	        (read(resh, &result_size, 2) != 2) || -	        (read(resh, &compressionMethod, 2) != 2)) +	if ((stream.read(&compressedLength, 2) != 2) || +	        (stream.read(&result_size, 2) != 2) || +	        (stream.read(&compressionMethod, 2) != 2))  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -247,13 +247,13 @@ int sci0_get_compression_method(int resh) {  } -int decompress0(resource_t *result, int resh, int sci_version) { +int decompress0(resource_t *result, Common::ReadStream &stream, int sci_version) {  	guint16 compressedLength;  	guint16 compressionMethod;  	guint16 result_size;  	guint8 *buffer; -	if (read(resh, &(result->id), 2) != 2) +	if (stream.read(&(result->id), 2) != 2)  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -265,9 +265,9 @@ int decompress0(resource_t *result, int resh, int sci_version) {  	if ((result->number > sci_max_resource_nr[sci_version]) || (result->type > sci_invalid_resource))  		return SCI_ERROR_DECOMPRESSION_INSANE; -	if ((read(resh, &compressedLength, 2) != 2) || -	        (read(resh, &result_size, 2) != 2) || -	        (read(resh, &compressionMethod, 2) != 2)) +	if ((stream.read(&compressedLength, 2) != 2) || +	        (stream.read(&result_size, 2) != 2) || +	        (stream.read(&compressionMethod, 2) != 2))  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -293,7 +293,7 @@ int decompress0(resource_t *result, int resh, int sci_version) {  	buffer = (guint8*)sci_malloc(compressedLength);  	result->data = (unsigned char*)sci_malloc(result->size); -	if (read(resh, buffer, compressedLength) != compressedLength) { +	if (stream.read(buffer, compressedLength) != compressedLength) {  		free(result->data);  		free(buffer);  		return SCI_ERROR_IO_ERROR; diff --git a/engines/sci/scicore/decompress01.cpp b/engines/sci/scicore/decompress01.cpp index 6f00bdfa73..e3219d3a5f 100644 --- a/engines/sci/scicore/decompress01.cpp +++ b/engines/sci/scicore/decompress01.cpp @@ -489,12 +489,12 @@ byte *view_reorder(byte *inbuffer, int dsize) { -int decompress01(resource_t *result, int resh, int sci_version) { +int decompress01(resource_t *result, Common::ReadStream &stream, int sci_version) {  	guint16 compressedLength, result_size;  	guint16 compressionMethod;  	guint8 *buffer; -	if (read(resh, &(result->id), 2) != 2) +	if (stream.read(&(result->id), 2) != 2)  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -507,9 +507,9 @@ int decompress01(resource_t *result, int resh, int sci_version) {  	if ((result->number > sci_max_resource_nr[sci_version] || (result->type > sci_invalid_resource)))  		return SCI_ERROR_DECOMPRESSION_INSANE; -	if ((read(resh, &compressedLength, 2) != 2) || -	        (read(resh, &result_size, 2) != 2) || -	        (read(resh, &compressionMethod, 2) != 2)) +	if ((stream.read(&compressedLength, 2) != 2) || +	        (stream.read(&result_size, 2) != 2) || +	        (stream.read(&compressionMethod, 2) != 2))  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -538,7 +538,7 @@ int decompress01(resource_t *result, int resh, int sci_version) {  	buffer = (guint8*)sci_malloc(compressedLength);  	result->data = (unsigned char*)sci_malloc(result->size); -	if (read(resh, buffer, compressedLength) != compressedLength) { +	if (stream.read(buffer, compressedLength) != compressedLength) {  		free(result->data);  		free(buffer);  		return SCI_ERROR_IO_ERROR; diff --git a/engines/sci/scicore/decompress1.cpp b/engines/sci/scicore/decompress1.cpp index 4f480fda1e..e231c24f9d 100644 --- a/engines/sci/scicore/decompress1.cpp +++ b/engines/sci/scicore/decompress1.cpp @@ -145,7 +145,6 @@ static int  decrypt4_hdyn(byte *dest, int length, struct bit_read_struct *reader) {  	int mode, length_param, value, val_length, val_distance;  	int write_pos = 0; -	int M[] = {0x07, 0x08, 0x0A, 0x0E, 0x16, 0x26, 0x46, 0x86, 0x106};  	CALLC(mode = getbits(reader, 8));  	CALLC(length_param = getbits(reader, 8)); @@ -185,7 +184,7 @@ decrypt4_hdyn(byte *dest, int length, struct bit_read_struct *reader) {  			else {  				int length_bonus; -				val_length = M[value - 7] + 2; +				val_length = 1<<(value - 7) + 8;  				CALLC(length_bonus = getbits(reader, value - 7));  				val_length += length_bonus;  			} @@ -272,16 +271,15 @@ decrypt4(guint8* dest, guint8* src, int length, int complength) {  void decryptinit3(void);  int decrypt3(guint8* dest, guint8* src, int length, int complength); -int decompress1(resource_t *result, int resh, int early); -int decompress1(resource_t *result, int resh, int sci_version) { +int decompress1(resource_t *result, Common::ReadStream &stream, int sci_version) {  	guint16 compressedLength;  	guint16 compressionMethod, result_size;  	guint8 *buffer;  	guint8 tempid;  	if (sci_version == SCI_VERSION_1_EARLY) { -		if (read(resh, &(result->id), 2) != 2) +		if (stream.read(&(result->id), 2) != 2)  			return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -294,13 +292,13 @@ int decompress1(resource_t *result, int resh, int sci_version) {  		if ((result->number >= sci_max_resource_nr[SCI_VERSION_1_LATE]) || (result->type > sci_invalid_resource))  			return SCI_ERROR_DECOMPRESSION_INSANE;  	} else { -		if (read(resh, &tempid, 1) != 1) +		if (stream.read(&tempid, 1) != 1)  			return SCI_ERROR_IO_ERROR;  		result->id = tempid;  		result->type = result->id & 0x7f; -		if (read(resh, &(result->number), 2) != 2) +		if (stream.read(&(result->number), 2) != 2)  			return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -310,9 +308,9 @@ int decompress1(resource_t *result, int resh, int sci_version) {  			return SCI_ERROR_DECOMPRESSION_INSANE;  	} -	if ((read(resh, &compressedLength, 2) != 2) || -	        (read(resh, &result_size, 2) != 2) || -	        (read(resh, &compressionMethod, 2) != 2)) +	if ((stream.read(&compressedLength, 2) != 2) || +	        (stream.read(&result_size, 2) != 2) || +	        (stream.read(&compressionMethod, 2) != 2))  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -337,7 +335,7 @@ int decompress1(resource_t *result, int resh, int sci_version) {  	buffer = (guint8*)sci_malloc(compressedLength);  	result->data = (unsigned char*)sci_malloc(result->size); -	if (read(resh, buffer, compressedLength) != compressedLength) { +	if (stream.read(buffer, compressedLength) != compressedLength) {  		free(result->data);  		free(buffer);  		return SCI_ERROR_IO_ERROR; diff --git a/engines/sci/scicore/decompress11.cpp b/engines/sci/scicore/decompress11.cpp index be4fa9794c..99b1b9e22e 100644 --- a/engines/sci/scicore/decompress11.cpp +++ b/engines/sci/scicore/decompress11.cpp @@ -34,7 +34,7 @@ void decryptinit3(void);  int decrypt3(guint8* dest, guint8* src, int length, int complength);  int decrypt4(guint8* dest, guint8* src, int length, int complength); -int decompress11(resource_t *result, int resh, int sci_version) { +int decompress11(resource_t *result, Common::ReadStream &stream, int sci_version) {  	guint16 compressedLength;  	guint16 compressionMethod, result_size;  	guint8 *buffer; @@ -42,13 +42,13 @@ int decompress11(resource_t *result, int resh, int sci_version) {  	DDEBUG("d1"); -	if (read(resh, &tempid, 1) != 1) +	if (stream.read(&tempid, 1) != 1)  		return SCI_ERROR_IO_ERROR;  	result->id = tempid;  	result->type = result->id & 0x7f; -	if (read(resh, &(result->number), 2) != 2) +	if (stream.read(&(result->number), 2) != 2)  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -57,9 +57,9 @@ int decompress11(resource_t *result, int resh, int sci_version) {  	if ((result->type > sci_invalid_resource))  		return SCI_ERROR_DECOMPRESSION_INSANE; -	if ((read(resh, &compressedLength, 2) != 2) || -	        (read(resh, &result_size, 2) != 2) || -	        (read(resh, &compressionMethod, 2) != 2)) +	if ((stream.read(&compressedLength, 2) != 2) || +	        (stream.read(&result_size, 2) != 2) || +	        (stream.read(&compressionMethod, 2) != 2))  		return SCI_ERROR_IO_ERROR;  #ifdef WORDS_BIGENDIAN @@ -88,15 +88,14 @@ int decompress11(resource_t *result, int resh, int sci_version) {  	buffer = (guint8*)sci_malloc(compressedLength);  	result->data = (unsigned char*)sci_malloc(result->size); -	if (read(resh, buffer, compressedLength) != compressedLength) { +	if (stream.read(buffer, compressedLength) != compressedLength) {  		free(result->data);  		free(buffer);  		return SCI_ERROR_IO_ERROR;  	};  	if (!(compressedLength & 1)) { /* Align */ -		int foo; -		read(resh, &foo, 1); +		stream.readByte();  	}  #ifdef _SCI_DECOMPRESS_DEBUG diff --git a/engines/sci/scicore/resource.cpp b/engines/sci/scicore/resource.cpp index d23713f556..d6064abf25 100644 --- a/engines/sci/scicore/resource.cpp +++ b/engines/sci/scicore/resource.cpp @@ -25,6 +25,8 @@  /* Resource library */ +#include "common/archive.h" +#include "common/file.h"  #include "common/util.h"  #include "sci/include/sci_memory.h" @@ -88,7 +90,7 @@ const char *sci_resource_type_suffixes[] = {"v56", "p56", "scr", "tex", "snd",  int resourcecmp(const void *first, const void *second); -typedef int decomp_funct(resource_t *result, int resh, int sci_version); +typedef int decomp_funct(resource_t *result, Common::ReadStream &stream, int sci_version);  typedef void patch_sprintf_funct(char *string, resource_t *res);  static decomp_funct *decompressors[] = { @@ -136,8 +138,7 @@ int resourcecmp(const void *first, const void *second) {  /*-- Resmgr helper functions --*/  /*-----------------------------*/ -void -_scir_add_altsource(resource_t *res, ResourceSource *source, unsigned int file_offset) { +void _scir_add_altsource(resource_t *res, ResourceSource *source, unsigned int file_offset) {  	resource_altsource_t *rsrc = (resource_altsource_t*)sci_malloc(sizeof(resource_altsource_t));  	rsrc->next = res->alt_sources; @@ -146,8 +147,7 @@ _scir_add_altsource(resource_t *res, ResourceSource *source, unsigned int file_o  	res->alt_sources = rsrc;  } -resource_t * -_scir_find_resource_unsorted(resource_t *res, int res_nr, int type, int number) { +resource_t *_scir_find_resource_unsorted(resource_t *res, int res_nr, int type, int number) {  	int i;  	for (i = 0; i < res_nr; i++)  		if (res[i].number == number && res[i].type == type) @@ -159,64 +159,57 @@ _scir_find_resource_unsorted(resource_t *res, int res_nr, int type, int number)  /** Resource source list management **/  /*-----------------------------------*/ -ResourceSource * -scir_add_external_map(ResourceManager *mgr, char *file_name) { -	ResourceSource *newsrc = (ResourceSource *) -	                            malloc(sizeof(ResourceSource)); +ResourceSource *scir_add_external_map(ResourceManager *mgr, const char *file_name) { +	ResourceSource *newsrc = new ResourceSource();  	/* Add the new source to the SLL of sources */  	newsrc->next = mgr->_sources;  	mgr->_sources = newsrc;  	newsrc->source_type = RESSOURCE_TYPE_EXTERNAL_MAP; -	newsrc->location.file.name = strdup(file_name); -	newsrc->scanned = 0; +	newsrc->location_name = file_name; +	newsrc->scanned = false;  	newsrc->associated_map = NULL;  	return newsrc;  } -ResourceSource * -scir_add_volume(ResourceManager *mgr, ResourceSource *map, char *filename, +ResourceSource *scir_add_volume(ResourceManager *mgr, ResourceSource *map, const char *filename,                  int number, int extended_addressing) { -	ResourceSource *newsrc = (ResourceSource *) -	                            malloc(sizeof(ResourceSource)); +	ResourceSource *newsrc = new ResourceSource();  	/* Add the new source to the SLL of sources */  	newsrc->next = mgr->_sources;  	mgr->_sources = newsrc;  	newsrc->source_type = RESSOURCE_TYPE_VOLUME; -	newsrc->scanned = 0; -	newsrc->location.file.name = strdup(filename); -	newsrc->location.file.volume_number = number; +	newsrc->scanned = false; +	newsrc->location_name = filename; +	newsrc->volume_number = number;  	newsrc->associated_map = map;  	return 0;  } -ResourceSource * -scir_add_patch_dir(ResourceManager *mgr, int type, char *dirname) { -	ResourceSource *newsrc = (ResourceSource *) -	                            malloc(sizeof(ResourceSource)); +ResourceSource *scir_add_patch_dir(ResourceManager *mgr, const char *dirname) { +	ResourceSource *newsrc = new ResourceSource();  	/* Add the new source to the SLL of sources */  	newsrc->next = mgr->_sources;  	mgr->_sources = newsrc;  	newsrc->source_type = RESSOURCE_TYPE_DIRECTORY; -	newsrc->scanned = 0; -	newsrc->location.dir.name = strdup(dirname); +	newsrc->scanned = false; +	newsrc->location_name = dirname;  	return 0;  } -ResourceSource * -scir_get_volume(ResourceManager *mgr, ResourceSource *map, int volume_nr) { +ResourceSource *scir_get_volume(ResourceManager *mgr, ResourceSource *map, int volume_nr) {  	ResourceSource *seeker = mgr->_sources;  	while (seeker) {  		if (seeker->source_type == RESSOURCE_TYPE_VOLUME &&  		        seeker->associated_map == map && -		        seeker->location.file.volume_number == volume_nr) +		        seeker->volume_number == volume_nr)  			return seeker;  		seeker = seeker->next;  	} @@ -229,34 +222,25 @@ scir_get_volume(ResourceManager *mgr, ResourceSource *map, int volume_nr) {  /*------------------------------------------------*/  static void -_scir_init_trivial(ResourceManager *mgr) { -	mgr->_resourcesNr = 0; -	mgr->_resources = (resource_t*)sci_malloc(1); -} - - -static void -_scir_load_from_patch_file(int fh, resource_t *res, char *filename) { +_scir_load_from_patch_file(Common::File &file, resource_t *res, char *filename) {  	unsigned int really_read;  	res->data = (unsigned char*)sci_malloc(res->size); -	really_read = read(fh, res->data, res->size); +	really_read = file.read(res->data, res->size);  	if (really_read < res->size) { -		sciprintf("Error: Read %d bytes from %s but expected %d!\n", +		error("Read %d bytes from %s but expected %d!",  		          really_read, filename, res->size); -		exit(1);  	}  	res->status = SCI_STATUS_ALLOCATED;  }  static void -_scir_load_resource(ResourceManager *mgr, resource_t *res, int protect) { +_scir_load_resource(ResourceManager *mgr, resource_t *res, bool protect) {  	char filename[MAXPATHLEN]; -	int fh; +	Common::File file;  	resource_t backup; -	char *save_cwd = sci_getcwd();  	memcpy(&backup, res, sizeof(resource_t)); @@ -264,53 +248,37 @@ _scir_load_resource(ResourceManager *mgr, resource_t *res, int protect) {  	if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY) {  		if (!patch_sprintfers[mgr->sci_version]) { -			sciprintf("Resource manager's SCI version (%d) has no patch file name printers -> internal error!\n", +			error("Resource manager's SCI version (%d) has no patch file name printers",  			          mgr->sci_version); -			exit(1);  		}  		/* Get patch file name */  		patch_sprintfers[mgr->sci_version](filename, res); -		chdir(res->source->location.dir.name); +		 +		// FIXME: Instead of using SearchMan, maybe we should only search +		// a single dir specified by this RESSOURCE_TYPE_DIRECTORY ResourceSource?  	} else -		strcpy(filename, res->source->location.file.name); +		strcpy(filename, res->source->location_name.c_str()); -	fh = open(filename, O_RDONLY | O_BINARY); - - -	if (!IS_VALID_FD(fh)) { -		char *raiser = filename; -		while (*raiser) { -			*raiser = toupper(*raiser); /* Uppercasify */ -			++raiser; -		} -		fh = sci_open(filename, O_RDONLY | O_BINARY); -	}    /* Try case-insensitively name */ - -	if (!IS_VALID_FD(fh)) { -		sciprintf("Failed to open %s!\n", filename); +	if (!file.open(filename)) { +		warning("Failed to open %s", filename);  		res->data = NULL;  		res->status = SCI_STATUS_NOMALLOC;  		res->size = 0; -		chdir(save_cwd); -		free(save_cwd);  		return;  	} -	lseek(fh, res->file_offset, SEEK_SET); +	file.seek(res->file_offset, SEEK_SET); -	if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY || -	        res->source->source_type == RESSOURCE_TYPE_AUDIO_DIRECTORY) -		_scir_load_from_patch_file(fh, res, filename); +	if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY) +		_scir_load_from_patch_file(file, res, filename);  	else if (!decompressors[mgr->sci_version]) {  		/* Check whether we support this at all */ -		sciprintf("Resource manager's SCI version (%d) is invalid!\n", -		          mgr->sci_version); -		exit(1); +		error("Resource manager's SCI version (%d) is invalid", mgr->sci_version);  	} else {  		int error = /* Decompress from regular resource file */ -		    decompressors[mgr->sci_version](res, fh, mgr->sci_version); +		    decompressors[mgr->sci_version](res, file, mgr->sci_version);  		if (error) {  			sciprintf("Error %d occured while reading %s.%03d" @@ -324,17 +292,12 @@ _scir_load_resource(ResourceManager *mgr, resource_t *res, int protect) {  			res->data = NULL;  			res->status = SCI_STATUS_NOMALLOC;  			res->size = 0; -			chdir(save_cwd); -			free(save_cwd); -			return;  		}  	} -	close(fh);  } -resource_t * -scir_test_resource(ResourceManager *mgr, int type, int number) { +resource_t *scir_test_resource(ResourceManager *mgr, int type, int number) {  	resource_t binseeker;  	binseeker.type = type;  	binseeker.number = number; @@ -343,11 +306,10 @@ scir_test_resource(ResourceManager *mgr, int type, int number) {  	               sizeof(resource_t), resourcecmp);  } -int sci0_get_compression_method(int resh); +int sci0_get_compression_method(Common::ReadStream &stream); -int -sci_test_view_type(ResourceManager *mgr) { -	int fh; +int sci_test_view_type(ResourceManager *mgr) { +	Common::File file;  	char filename[MAXPATHLEN];  	int compression;  	resource_t *res; @@ -355,65 +317,46 @@ sci_test_view_type(ResourceManager *mgr) {  	mgr->sci_version = SCI_VERSION_AUTODETECT; -	for (i = 0;i < 1000;i++) { +	for (i = 0; i < 1000; i++) {  		res = scir_test_resource(mgr, sci_view, i); -		if (!res) continue; - -		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY || -		        res->source->source_type == RESSOURCE_TYPE_AUDIO_DIRECTORY) +		if (!res)  			continue; -		strcpy(filename, res->source->location.file.name); -		fh = open(filename, O_RDONLY | O_BINARY); +		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY) +			continue; -		if (!IS_VALID_FD(fh)) { -			char *raiser = filename; -			while (*raiser) { -				*raiser = toupper(*raiser); /* Uppercasify */ -				++raiser; -			} -			fh = sci_open(filename, O_RDONLY | O_BINARY); -		}    /* Try case-insensitively name */ +		strcpy(filename, res->source->location_name.c_str()); -		if (!IS_VALID_FD(fh)) continue; -		lseek(fh, res->file_offset, SEEK_SET); +		if (!file.open(filename)) +			continue; +		file.seek(res->file_offset, SEEK_SET); -		compression = sci0_get_compression_method(fh); -		close(fh); +		compression = sci0_get_compression_method(file); +		file.close();  		if (compression == 3)  			return (mgr->sci_version = SCI_VERSION_01_VGA);  	}  	/* Try the same thing with pics */ -	for (i = 0;i < 1000;i++) { +	for (i = 0; i < 1000; i++) {  		res = scir_test_resource(mgr, sci_pic, i); -		if (!res) continue; - -		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY || -		        res->source->source_type == RESSOURCE_TYPE_AUDIO_DIRECTORY) +		if (!res)  			continue; -		strcpy(filename, res->source->location.file.name); -		fh = open(filename, O_RDONLY | O_BINARY); - +		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY) +			continue; -		if (!IS_VALID_FD(fh)) { -			char *raiser = filename; -			while (*raiser) { -				*raiser = toupper(*raiser); /* Uppercasify */ -				++raiser; -			} -			fh = sci_open(filename, O_RDONLY | O_BINARY); -		}    /* Try case-insensitively name */ +		strcpy(filename, res->source->location_name.c_str()); -		if (!IS_VALID_FD(fh)) continue; -		lseek(fh, res->file_offset, SEEK_SET); +		if (!file.open(filename)) +			continue; +		file.seek(res->file_offset, SEEK_SET); -		compression = sci0_get_compression_method(fh); -		close(fh); +		compression = sci0_get_compression_method(file); +		file.close();  		if (compression == 3)  			return (mgr->sci_version = SCI_VERSION_01_VGA); @@ -424,51 +367,30 @@ sci_test_view_type(ResourceManager *mgr) { -int -scir_add_appropriate_sources(ResourceManager *mgr, -                             char *dir) { -	const char *trailing_slash = ""; +int scir_add_appropriate_sources(ResourceManager *mgr) {  	//char path_separator; -	sci_dir_t dirent; -	char *name;  	ResourceSource *map; -	int fd; -	char fullname[MAXPATHLEN]; -	if (dir[strlen(dir)-1] != G_DIR_SEPARATOR) { -		trailing_slash = G_DIR_SEPARATOR_S; -	} +	if (!Common::File::exists("RESOURCE.MAP")) +		return 0; +	map = scir_add_external_map(mgr, "RESOURCE.MAP"); -	name = (char *)malloc(strlen(dir) + 1 + -	                      strlen("RESOURCE.MAP") + 1); - -	sprintf(fullname, "%s%s%s", dir, trailing_slash, "RESOURCE.MAP"); -	fd = sci_open("RESOURCE.MAP", O_RDONLY | O_BINARY); -	if (!IS_VALID_FD(fd)) return 0; -	close(fd); -	map = scir_add_external_map(mgr, fullname); -	free(name); -	sci_init_dir(&dirent); -	name = sci_find_first(&dirent, "RESOURCE.0??"); -	while (name != NULL) { -		char *dot = strrchr(name, '.'); +	Common::ArchiveMemberList files; +	SearchMan.listMatchingMembers(files, "RESOURCE.0??"); + +	for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { +		const Common::String name = (*x)->getName(); +		char *dot = strrchr(name.c_str(), '.');  		int number = atoi(dot + 1); -		sprintf(fullname, "%s%s%s", dir, G_DIR_SEPARATOR_S, name); -		scir_add_volume(mgr, map, fullname, number, 0); -		name = sci_find_next(&dirent); +		scir_add_volume(mgr, map, name.c_str(), number, 0);  	} -	sci_finish_find(&dirent); - -	sci_finish_find(&dirent); -	sprintf(fullname, "%s%s", dir, G_DIR_SEPARATOR_S); -	scir_add_patch_dir(mgr, RESSOURCE_TYPE_DIRECTORY, fullname); +	scir_add_patch_dir(mgr, "");	// FIXME: used to pass the 'current' instead of ""  	return 1;  } -static int -_scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSource *source) { +static int _scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSource *source) {  	int preset_version = mgr->sci_version;  	int resource_error = 0;  	int dummy = mgr->sci_version; @@ -482,7 +404,7 @@ _scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSour  		_scir_scan_new_sources(mgr, detected_version, source->next);  	if (!source->scanned) { -		source->scanned = 1; +		source->scanned = true;  		switch (source->source_type) {  		case RESSOURCE_TYPE_DIRECTORY:  			if (mgr->sci_version <= SCI_VERSION_01) @@ -511,8 +433,6 @@ _scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSour  					if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND)  						sciprintf("Running SCI games without a resource map is not supported ATM\n");  					sci_free(mgr); -					chdir(caller_cwd); -					free(caller_cwd);  					return NULL;  				}  				if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND) { @@ -522,7 +442,8 @@ _scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSour  				if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {  					/* Initialize empty resource manager */ -					_scir_init_trivial(mgr); +					mgr->_resourcesNr = 0; +					mgr->_resources = 0; // FIXME: Was = (resource_t*)sci_malloc(1);  					resource_error = 0;  				}  #endif @@ -547,7 +468,8 @@ _scir_scan_new_sources(ResourceManager *mgr, int *detected_version, ResourceSour  				if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {  					/* Initialize empty resource manager */ -					_scir_init_trivial(mgr); +					mgr->_resourcesNr = 0; +					mgr->_resources = 0; // FIXME: Was = (resource_t*)sci_malloc(1);  					resource_error = 0;  				}  			} @@ -567,59 +489,46 @@ scir_scan_new_sources(ResourceManager *mgr, int *detected_version) {  	return 0;  } -static void -_scir_free_resource_sources(ResourceSource *rss) { +static void _scir_free_resource_sources(ResourceSource *rss) {  	if (rss) {  		_scir_free_resource_sources(rss->next); -		free(rss); +		delete rss;  	}  } -ResourceManager * -scir_new_resource_manager(char *dir, int version, int maxMemory) { +ResourceManager::ResourceManager(int version, int maxMemory) {  	int resource_error = 0; -	ResourceManager *mgr = (ResourceManager*)sci_malloc(sizeof(ResourceManager)); -	char *caller_cwd = sci_getcwd(); +	ResourceManager *mgr = this;  	int resmap_version = version; -	if (chdir(dir)) { -		sciprintf("Resmgr: Directory '%s' is invalid!\n", dir); -		free(caller_cwd); -		return NULL; -	} - -	mgr->_maxMemory = maxMemory; +	_maxMemory = maxMemory;  	mgr->memory_locked = 0;  	mgr->memory_lru = 0; -	mgr->resource_path = dir; - -	mgr->_resources = NULL; -	mgr->_resourcesNr = 0; -	mgr->_sources = NULL; +	_resources = NULL; +	_resourcesNr = 0; +	_sources = NULL;  	mgr->sci_version = version; -	scir_add_appropriate_sources(mgr, dir); +	mgr->lru_first = NULL; +	mgr->lru_last = NULL; + +	scir_add_appropriate_sources(mgr);  	scir_scan_new_sources(mgr, &resmap_version); -	if (!mgr->_resources || !mgr->_resourcesNr) { -		if (mgr->_resources) { -			free(mgr->_resources); -			mgr->_resources = NULL; +	if (!_resources || !_resourcesNr) { +		if (_resources) { +			free(_resources); +			_resources = NULL;  		}  		sciprintf("Resmgr: Could not retrieve a resource list!\n");  		_scir_free_resource_sources(mgr->_sources); -		free(mgr); -		chdir(caller_cwd); -		free(caller_cwd); -		return NULL; +		error("FIXME: Move this code to an init() method so that we can perform error handling"); +//		return NULL;  	} -	mgr->lru_first = NULL; -	mgr->lru_last = NULL; - -	qsort(mgr->_resources, mgr->_resourcesNr, sizeof(resource_t), +	qsort(_resources, _resourcesNr, sizeof(resource_t),  	      resourcecmp); /* Sort resources */  	if (version == SCI_VERSION_AUTODETECT) @@ -666,7 +575,7 @@ scir_new_resource_manager(char *dir, int version, int maxMemory) {  			resource_t *res = scir_test_resource(mgr, sci_script, 0);  			mgr->sci_version = version = SCI_VERSION_1_EARLY; -			_scir_load_resource(mgr, res, 1); +			_scir_load_resource(mgr, res, true);  			if (res->status == SCI_STATUS_NOMALLOC)  				mgr->sci_version = version = SCI_VERSION_1_LATE; @@ -682,27 +591,11 @@ scir_new_resource_manager(char *dir, int version, int maxMemory) {  		}  	if (!resource_error) { -#if 0 -		if (version <= SCI_VERSION_01) -			sci0_read_resource_patches(dir, -			                           &mgr->_resources, -			                           &mgr->_resourcesNr); -		else -			sci1_read_resource_patches(dir, -			                           &mgr->_resources, -			                           &mgr->_resourcesNr); -#endif - -		qsort(mgr->_resources, mgr->_resourcesNr, sizeof(resource_t), +		qsort(_resources, _resourcesNr, sizeof(resource_t),  		      resourcecmp); /* Sort resources */  	}  	mgr->sci_version = version; - -	chdir(caller_cwd); -	free(caller_cwd); - -	return mgr;  }  static void @@ -730,13 +623,10 @@ _scir_free_resources(resource_t *resources, int _resourcesNr) {  	free(resources);  } -void -scir_free_resource_manager(ResourceManager *mgr) { -	_scir_free_resources(mgr->_resources, mgr->_resourcesNr); -	_scir_free_resource_sources(mgr->_sources); -	mgr->_resources = NULL; - -	free(mgr); +ResourceManager::~ResourceManager() { +	_scir_free_resources(_resources, _resourcesNr); +	_scir_free_resource_sources(_sources); +	_resources = NULL;  } @@ -856,7 +746,7 @@ scir_find_resource(ResourceManager *mgr, int type, int number, int lock) {  		return NULL;  	if (!retval->status) -		_scir_load_resource(mgr, retval, 0); +		_scir_load_resource(mgr, retval, false);  	else if (retval->status == SCI_STATUS_ENQUEUED)  		_scir_remove_from_lru(mgr, retval); diff --git a/engines/sci/scicore/resource_map.cpp b/engines/sci/scicore/resource_map.cpp index 70ea8fa447..c79027d0a5 100644 --- a/engines/sci/scicore/resource_map.cpp +++ b/engines/sci/scicore/resource_map.cpp @@ -26,9 +26,9 @@  #include "sci/include/sci_memory.h"  #include "sci/include/sciresource.h"  #include "sci/include/resource.h" -#ifdef HAVE_UNISTD_H -#  include <unistd.h> -#endif + +#include "common/file.h" +  #define RESOURCE_MAP_FILENAME "resource.map" @@ -86,39 +86,36 @@        | (((bytes)[3]) << 9) \        | (((bytes)[2]) << 1)) - -static int -detect_odd_sci01(int fh) { +static int detect_odd_sci01(Common::File &file) {  	byte buf[6];  	int files_ok = 1; -	int fsize, resources_nr, tempfh, read_ok; +	int fsize, resource_nr, read_ok;  	char filename[14]; -	fsize = sci_fd_size(fh); +	fsize = file.size();  	if (fsize < 0) {  		perror("Error occured while trying to get filesize of resource.map");  		return SCI_ERROR_RESMAP_NOT_FOUND;  	} -	resources_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE; +	resource_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE; -	while (resources_nr-- > 1) { -		read_ok = read(fh, &buf, SCI0_RESMAP_ENTRIES_SIZE); +	while (resource_nr-- > 1) { +		read_ok = file.read(&buf, SCI0_RESMAP_ENTRIES_SIZE);  		if (read_ok) {  			sprintf(filename, "resource.%03i", SCI0_RESFILE_GET_FILE(buf + 2)); -			tempfh = sci_open(filename, O_RDONLY | O_BINARY); - -			if (tempfh == SCI_INVALID_FD) { +			Common::File temp; +			 +			// FIXME: Maybe better to use File::exists here? +			if (!temp.open(filename)) {  				files_ok = 0;  				break;  			} - -			close(tempfh);  		}  	} -	lseek(fh, 0, SEEK_SET); +	file.seek(0, SEEK_SET);  	return files_ok;  } @@ -163,7 +160,7 @@ sci_res_read_entry(ResourceManager *mgr, ResourceSource *map,  inline int sci1_res_type(int ofs, int *types, int lastrt) {  	int i, last = -1; -	for (i = 0;i <= sci1_last_resource;i++) +	for (i = 0; i <= sci1_last_resource;i++)  		if (types[i]) {  			if (types[i] > ofs)  				return last; @@ -173,16 +170,17 @@ inline int sci1_res_type(int ofs, int *types, int lastrt) {  	return lastrt;  } -int sci1_parse_header(int fd, int *types, int *lastrt) { +int sci1_parse_header(Common::ReadStream &stream, int *types, int *lastrt) {  	unsigned char rtype;  	unsigned char offset[2];  	int read_ok;  	int size = 0;  	do { -		read_ok = read(fd, &rtype, 1); -		if (!read_ok) break; -		read_ok = read(fd, &offset, 2); +		read_ok = stream.read(&rtype, 1); +		if (!read_ok) +			break; +		read_ok = stream.read(&offset, 2);  		if (read_ok < 2)  			read_ok = 0;  		if (rtype != 0xff) { @@ -192,31 +190,30 @@ int sci1_parse_header(int fd, int *types, int *lastrt) {  		size += 3;  	} while (read_ok && (rtype != 0xFF)); -	if (!read_ok) return 0; +	if (!read_ok) +		return 0;  	return size;  } -int -sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **resource_p, int *resource_nr_p, int *sci_version) { +int sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **resource_p, int *resource_nr_p, int *sci_version) {  	int fsize; -	int fd; +	Common::File file;  	resource_t *resources; -	int resources_nr; +	int resource_nr;  	int resource_index = 0;  	int resources_total_read = 0;  	int next_entry;  	int max_resfile_nr = 0;  	byte buf[SCI0_RESMAP_ENTRIES_SIZE]; -	fd = sci_open(map->location.file.name, O_RDONLY | O_BINARY); -	if (!IS_VALID_FD(fd)) +	if (!file.open(map->location_name))  		return SCI_ERROR_RESMAP_NOT_FOUND; -	read(fd, &buf, 4); +	file.read(&buf, 4);  	/* Theory: An SCI1 map file begins with an index that allows us to seek quickly  	   to a particular resource type. The entries are three bytes long; one byte @@ -237,13 +234,12 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  	if ((buf[0] == 0x80) &&  	        (buf[1] % 3 == 0) &&  	        (buf[3] == 0x81)) { -		close(fd);  		return SCI_ERROR_INVALID_RESMAP_ENTRY;  	} -	lseek(fd, 0, SEEK_SET); +	file.seek(0, SEEK_SET); -	switch (detect_odd_sci01(fd)) { +	switch (detect_odd_sci01(file)) {  	case 0 : /* Odd SCI01 */  		if (*sci_version == SCI_VERSION_AUTODETECT)  			*sci_version = SCI_VERSION_01_VGA_ODD; @@ -256,22 +252,23 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  		return SCI_ERROR_RESMAP_NOT_FOUND;  	} -	if ((fsize = sci_fd_size(fd)) < 0) { +	fsize = file.size(); +	if (fsize < 0) {  		perror("Error occured while trying to get filesize of resource.map");  		return SCI_ERROR_RESMAP_NOT_FOUND;  	} -	resources_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE; +	resource_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE; -	resources = (resource_t*)sci_calloc(resources_nr, sizeof(resource_t)); +	resources = (resource_t*)sci_calloc(resource_nr, sizeof(resource_t));  	/* Sets valid default values for most entries */  	do { -		int read_ok = read(fd, &buf, SCI0_RESMAP_ENTRIES_SIZE); +		int read_ok = file.read(&buf, SCI0_RESMAP_ENTRIES_SIZE);  		next_entry = 1;  		if (read_ok < 0) { -			sciprintf("Error while reading %s: ", map->location.file.name); +			sciprintf("Error while reading %s: ", map->location_name.c_str());  			perror("");  			next_entry = 0;  		} else if (read_ok != SCI0_RESMAP_ENTRIES_SIZE) { @@ -286,7 +283,6 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  			if (sci_res_read_entry(mgr, map, buf, resources + resource_index, *sci_version)) {  				free(resources); -				close(fd);  				return SCI_ERROR_RESMAP_NOT_FOUND;  			} @@ -304,7 +300,7 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  			if (fresh)  				++resource_index; -			if (++resources_total_read >= resources_nr) { +			if (++resources_total_read >= resource_nr) {  				sciprintf("Warning: After %d entries, resource.map"  				          " is not terminated!\n", resource_index);  				next_entry = 0; @@ -314,16 +310,16 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  	} while (next_entry); -	close(fd); +	file.close();  	if (!resource_index) {  		sciprintf("resource.map was empty!\n"); -		_scir_free_resources(resources, resources_nr); +		_scir_free_resources(resources, resource_nr);  		return SCI_ERROR_RESMAP_NOT_FOUND;  	}  	if (max_resfile_nr > 999) { -		_scir_free_resources(resources, resources_nr); +		_scir_free_resources(resources, resource_nr);  		return SCI_ERROR_INVALID_RESMAP_ENTRY;  	} else {  #if 0 @@ -331,18 +327,16 @@ sci0_read_resource_map(ResourceManager *mgr, ResourceSource *map, resource_t **r  		/* Check whether the highest resfile used exists */  		char filename_buf[14];  		sprintf(filename_buf, "resource.%03d", max_resfile_nr); -		fd = sci_open(filename_buf, O_RDONLY); -		if (!IS_VALID_FD(fd)) { -			_scir_free_resources(resources, resources_nr); +		if (!file.open(filename_buf) { +			_scir_free_resources(resources, resource_nr);  			sciprintf("'%s' requested by resource.map, but not found\n", filename_buf);  			return SCI_ERROR_INVALID_RESMAP_ENTRY; -		} else -			close(fd); +		}  #endif  	} -	if (resource_index < resources_nr) +	if (resource_index < resource_nr)  		resources = (resource_t*)sci_realloc(resources, sizeof(resource_t) * resource_index);  	*resource_p = resources; @@ -388,9 +382,9 @@ int  sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource *vol,                         resource_t **resource_p, int *resource_nr_p, int *sci_version) {  	int fsize; -	int fd; +	Common::File file;  	resource_t *resources, *resource_start; -	int resources_nr; +	int resource_nr;  	int resource_index = 0;  	int ofs, header_size;  	int *types = (int*)sci_malloc(sizeof(int) * (sci1_last_resource + 1)); @@ -400,15 +394,12 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  	int entrysize;  	int entry_size_selector; -	fd = sci_open(map->location.file.name, O_RDONLY | O_BINARY); - -	if (!IS_VALID_FD(fd)) +	if (!file.open(map->location_name))  		return SCI_ERROR_RESMAP_NOT_FOUND;  	memset(types, 0, sizeof(int) * (sci1_last_resource + 1)); -	if (!(sci1_parse_header(fd, types, &lastrt))) { -		close(fd); +	if (!(sci1_parse_header(file, types, &lastrt))) {  		return SCI_ERROR_INVALID_RESMAP_ENTRY;  	} @@ -418,7 +409,6 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  	if (*sci_version == SCI_VERSION_AUTODETECT) { /* That didn't help */  		sciprintf("Unable to detect resource map version\n"); -		close(fd);  		return SCI_ERROR_NO_RESOURCE_FILES_FOUND;  	} @@ -426,24 +416,25 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  	            ? SCI11_RESMAP_ENTRIES_SIZE  	            : SCI1_RESMAP_ENTRIES_SIZE; -	if ((fsize = sci_fd_size(fd)) < 0) { +	fsize = file.size(); +	if (fsize < 0) {  		perror("Error occured while trying to get filesize of resource.map"); -		close(fd);  		return SCI_ERROR_RESMAP_NOT_FOUND;  	} -	resources_nr = (fsize - types[0]) / entrysize; -	resource_start = resources = (resource_t*)sci_realloc(mgr->_resources, (mgr->_resourcesNr + resources_nr) * sizeof(resource_t)); +	resource_nr = (fsize - types[0]) / entrysize; +	resource_start = resources = (resource_t*)sci_realloc(mgr->_resources, (mgr->_resourcesNr + resource_nr) * sizeof(resource_t));  	resources += mgr->_resourcesNr;  	i = 0; -	while (types[i] == 0) i++; +	while (types[i] == 0) +		i++;  	header_size = ofs = types[i]; -	lseek(fd, ofs, SEEK_SET); +	file.seek(ofs, SEEK_SET); -	for (i = 0; i < resources_nr; i++) { -		int read_ok = read(fd, &buf, entrysize); +	for (i = 0; i < resource_nr; i++) { +		int read_ok = file.read(&buf, entrysize);  		int j;  		resource_t *res;  		int addto = resource_index; @@ -451,10 +442,11 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  		if (read_ok < entrysize) {  #if 0 -			if (!eof(fd)) { -				sciprintf("Error while reading %s: ", map->location.file.name); +			if (!file.eof()) { +				sciprintf("Error while reading %s: ", map->location_name.c_str());  				perror(""); -			} else read_ok = 1; +			} else +				read_ok = 1;  			break;  #endif  		} @@ -498,7 +490,6 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  		ofs += entrysize;  	} -	close(fd);  	free(types);  	*resource_p = resource_start; @@ -510,9 +501,9 @@ sci1_read_resource_map(ResourceManager *mgr, ResourceSource *map, ResourceSource  #ifdef TEST_RESOURCE_MAP  int  main(int argc, char **argv) { -	int resources_nr; +	int resource_nr;  	resource_t *resources; -	int notok = sci0_read_resource_map(".", &resources, &resources_nr); +	int notok = sci0_read_resource_map(".", &resources, &resource_nr);  	if (notok) {  		fprintf(stderr, "Failed: Error code %d\n", notok); @@ -522,9 +513,9 @@ main(int argc, char **argv) {  	if (resources) {  		int i; -		printf("Found %d resources:\n", resources_nr); +		printf("Found %d resources:\n", resource_nr); -		for (i = 0; i < resources_nr; i++) { +		for (i = 0; i < resource_nr; i++) {  			resource_t *res = resources + i;  			printf("#%04d:\tRESOURCE.%03d:%8d\t%s.%03d\n", diff --git a/engines/sci/scicore/resource_patch.cpp b/engines/sci/scicore/resource_patch.cpp index a9e472468f..154eb73984 100644 --- a/engines/sci/scicore/resource_patch.cpp +++ b/engines/sci/scicore/resource_patch.cpp @@ -23,131 +23,118 @@   *   */ +#include "common/archive.h" +#include "common/file.h"  #include "sci/include/sciresource.h"  #include "sci/include/sci_memory.h" -void -sci0_sprintf_patch_file_name(char *string, resource_t *res) { +void sci0_sprintf_patch_file_name(char *string, resource_t *res) {  	sprintf(string, "%s.%03i", sci_resource_types[res->type], res->number);  } -void -sci1_sprintf_patch_file_name(char *string, resource_t *res) { +void sci1_sprintf_patch_file_name(char *string, resource_t *res) {  	sprintf(string, "%d.%s", res->number, sci_resource_type_suffixes[res->type]);  }  /* version-agnostic patch application */ -static void -process_patch(ResourceSource *source, -              char *entry, int restype, int resnumber, resource_t **resource_p, int *resource_nr_p) { -	int fsize; -	char filename[MAXPATHLEN]; +static void process_patch(ResourceSource *source, +              Common::ArchiveMember &member, int restype, int resnumber, resource_t **resource_p, int *resource_nr_p) { +	Common::File file;  	if (restype == sci_invalid_resource)  		return; -	printf("Patching \"%s\": ", entry); - -	sprintf(filename, "%s%s", source->location.dir.name, entry); -	fsize = sci_file_size(filename); -	if (fsize < 0) -		perror("""__FILE__"": (""__LINE__""): sci_file_size()"); +	printf("Patching \"%s\": ", member.getName().c_str()); +	if (!file.open(member.createReadStream(), member.getName())) +		perror("""__FILE__"": (""__LINE__""): failed to open");  	else { -		int file;  		guint8 filehdr[2];  		resource_t *newrsc = _scir_find_resource_unsorted(*resource_p,  		                     *resource_nr_p,  		                     restype,  		                     resnumber); - +		int fsize = file.size();  		if (fsize < 3) {  			printf("File too small\n");  			return;  		} -		file = open(entry, O_RDONLY); -		if (!IS_VALID_FD(file)) -			perror("""__FILE__"": (""__LINE__""): open()"); -		else { -			int patch_data_offset; - -			read(file, filehdr, 2); - -			patch_data_offset = filehdr[1]; - -			if ((filehdr[0] & 0x7f) != restype) { -				printf("Failed; resource type mismatch\n"); -				close(file); -			} else if (patch_data_offset + 2 >= fsize) { -				printf("Failed; patch starting at offset %d can't be in file of size %d\n", filehdr[1] + 2, fsize); -				close(file); -			} else { -				/* Adjust for file offset */ -				fsize -= patch_data_offset; - -				/* Prepare destination, if neccessary */ -				if (!newrsc) { -					/* Completely new resource! */ -					++(*resource_nr_p); -					*resource_p = (resource_t*)sci_realloc(*resource_p, -					                                       *resource_nr_p -					                                       * sizeof(resource_t)); -					newrsc = (*resource_p - 1) + *resource_nr_p; -					newrsc->alt_sources = NULL; -				} - -				/* Overwrite everything, because we're patching */ -				newrsc->size = fsize - 2; -				newrsc->id = restype << 11 | resnumber; -				newrsc->number = resnumber; -				newrsc->status = SCI_STATUS_NOMALLOC; -				newrsc->type = restype; -				newrsc->source = source; -				newrsc->file_offset = 2 + patch_data_offset; +		int patch_data_offset; + +		file.read(filehdr, 2); + +		patch_data_offset = filehdr[1]; + +		if ((filehdr[0] & 0x7f) != restype) { +			printf("Failed; resource type mismatch\n"); +		} else if (patch_data_offset + 2 >= fsize) { +			printf("Failed; patch starting at offset %d can't be in file of size %d\n", filehdr[1] + 2, fsize); +		} else { +			/* Adjust for file offset */ +			fsize -= patch_data_offset; + +			/* Prepare destination, if neccessary */ +			if (!newrsc) { +				/* Completely new resource! */ +				++(*resource_nr_p); +				*resource_p = (resource_t*)sci_realloc(*resource_p, +													   *resource_nr_p +													   * sizeof(resource_t)); +				newrsc = (*resource_p - 1) + *resource_nr_p; +				newrsc->alt_sources = NULL; +			} -				_scir_add_altsource(newrsc, source, 2); +			/* Overwrite everything, because we're patching */ +			newrsc->size = fsize - 2; +			newrsc->id = restype << 11 | resnumber; +			newrsc->number = resnumber; +			newrsc->status = SCI_STATUS_NOMALLOC; +			newrsc->type = restype; +			newrsc->source = source; +			newrsc->file_offset = 2 + patch_data_offset; -				close(file); +			_scir_add_altsource(newrsc, source, 2); -				printf("OK\n"); +			printf("OK\n"); -			}  		}  	}  } -int -sci0_read_resource_patches(ResourceSource *source, resource_t **resource_p, int *resource_nr_p) { -	sci_dir_t dir; -	char *entry; -	char *caller_cwd = sci_getcwd(); - -	chdir(source->location.dir.name); -	sci_init_dir(&dir); -	entry = sci_find_first(&dir, "*.???"); -	while (entry) { +int sci0_read_resource_patches(ResourceSource *source, resource_t **resource_p, int *resource_nr_p) { +	// FIXME: Use only one specific dir, instead of SearchMan? +	//chdir(source->location_dir_name.c_str()); +	//sci_init_dir(&dir); +	//entry = sci_find_first(&dir, "*.???"); + +	Common::ArchiveMemberList files; +	SearchMan.listMatchingMembers(files, "*.???"); + +	for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { +		const Common::String name = (*x)->getName();  		int restype = sci_invalid_resource;  		int resnumber = -1;  		int i;  		unsigned int resname_len;  		char *endptr; +printf("sci0_read_resource_patches: scanning '%s'\n", name.c_str());  		for (i = sci_view; i < sci_invalid_resource; i++) -			if (scumm_strnicmp(sci_resource_types[i], entry, +			if (scumm_strnicmp(sci_resource_types[i], name.c_str(),  			                strlen(sci_resource_types[i])) == 0)  				restype = i;  		if (restype != sci_invalid_resource) {  			resname_len = strlen(sci_resource_types[restype]); -			if (entry[resname_len] != '.') +			if (name[resname_len] != '.')  				restype = sci_invalid_resource;  			else { -				resnumber = strtol(entry + 1 + resname_len, +				resnumber = strtol(name.c_str() + 1 + resname_len,  				                   &endptr, 10); /* Get resource number */ -				if ((*endptr != '\0') || (resname_len + 1 == strlen(entry))) +				if ((*endptr != '\0') || (resname_len + 1 == name.size()))  					restype = sci_invalid_resource;  				if ((resnumber < 0) || (resnumber > 1000)) @@ -155,31 +142,29 @@ sci0_read_resource_patches(ResourceSource *source, resource_t **resource_p, int  			}  		} -		process_patch(source, entry, restype, resnumber, resource_p, resource_nr_p); - -		entry = sci_find_next(&dir); +		process_patch(source, **x, restype, resnumber, resource_p, resource_nr_p);  	} -	chdir(caller_cwd); -	free(caller_cwd);  	return 0;  }  int  sci1_read_resource_patches(ResourceSource *source, resource_t **resource_p, int *resource_nr_p) { -	sci_dir_t dir; -	char *entry; -	char *caller_cwd = sci_getcwd(); - -	chdir(source->location.dir.name); -	sci_init_dir(&dir); -	entry = sci_find_first(&dir, "*.*"); -	while (entry) { +	// FIXME: Use only one specific dir, instead of SearchMan? +	//chdir(source->location_dir_name.c_str()); +	//sci_init_dir(&dir); +	//entry = sci_find_first(&dir, "*.*"); + +	Common::ArchiveMemberList files; +	SearchMan.listMatchingMembers(files, "*.*"); + +	for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { +		const Common::String name = (*x)->getName();  		int restype = sci_invalid_resource;  		int resnumber = -1;  		int i;  		char *endptr; -		char *dot = strchr(entry, '.'); +		char *dot = strchr(name.c_str(), '.');  		for (i = sci_view; i < sci_invalid_resource; i++) {  			if (dot != NULL) { @@ -191,7 +176,7 @@ sci1_read_resource_patches(ResourceSource *source, resource_t **resource_p, int  		if (restype != sci_invalid_resource) { -			resnumber = strtol(entry, +			resnumber = strtol(name.c_str(),  			                   &endptr, 10); /* Get resource number */  			if (endptr != dot) @@ -204,13 +189,9 @@ sci1_read_resource_patches(ResourceSource *source, resource_t **resource_p, int  				restype = sci_invalid_resource;  		} -		process_patch(source, entry, restype, resnumber, resource_p, resource_nr_p); - -		entry = sci_find_next(&dir); +		process_patch(source, **x, restype, resnumber, resource_p, resource_nr_p);  	} -	chdir(caller_cwd); -	free(caller_cwd);  	return 0;  } diff --git a/engines/sci/scicore/tools.cpp b/engines/sci/scicore/tools.cpp index 9b192cbf24..417165af99 100644 --- a/engines/sci/scicore/tools.cpp +++ b/engines/sci/scicore/tools.cpp @@ -24,6 +24,11 @@   */ +#include "common/archive.h" +#include "common/file.h" +#include "common/util.h" + +  #ifdef _MSC_VER  #  include <sys/timeb.h>  #  include <windows.h> @@ -439,90 +444,45 @@ sci_sched_yield() {  **             (sci_dir_t *) dir: Directory to find file within.  ** Returns   : (char *) Case-sensitive filename of the file.  */ -char *_fcaseseek(const char *fname, sci_dir_t *dir) { +Common::String _fcaseseek(const char *fname) {  /* Expects *dir to be uninitialized and the caller to   ** free it afterwards  */ -	Common::String buf; -	char *retval = NULL, *name; - -#ifdef _MSC_VER -	return (char *)fname; -#endif -  	if (strchr(fname, G_DIR_SEPARATOR)) {  		fprintf(stderr, "_fcaseseek() does not support subdirs\n");  		BREAKPOINT();  	} -	sci_init_dir(dir); - -	/* Replace all letters with '?' chars */ -	buf = fname; -	 -	for (Common::String::iterator iterator = buf.begin(); iterator != buf.end(); ++iterator) { -		if (isalpha(*iterator)) -			*iterator = '?'; -	} - -	name = sci_find_first(dir, buf.c_str()); +	// Look up the file, ignoring case +	Common::ArchiveMemberList files; +	SearchMan.listMatchingMembers(files, fname); -	while (name && !retval) { -		if (!scumm_stricmp(fname, name)) -			retval = name; -		else -			name = sci_find_next(dir); +	for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { +		const Common::String name = (*x)->getName(); +		if (name.equalsIgnoreCase(fname)) +			return name;  	} - -	return retval; +	return Common::String();  } -FILE * -sci_fopen(const char *fname, const char *mode) { -	sci_dir_t dir; -	char *name = _fcaseseek(fname, &dir); +FILE *sci_fopen(const char *fname, const char *mode) { +	Common::String name = _fcaseseek(fname);  	FILE *file = NULL; -	if (name) -		file = fopen(name, mode); +	if (!name.empty()) +		file = fopen(name.c_str(), mode);  	else if (strchr(mode, 'w'))  		file = fopen(fname, mode); -	sci_finish_find(&dir); /* Free memory */ -  	return file;  } -int -sci_open(const char *fname, int flags) { -	sci_dir_t dir; -	char *name; +int sci_open(const char *fname, int flags) {  	int file = SCI_INVALID_FD; -	char *separator_position; -	char *path; -	char *caller_cwd; - -	sci_init_dir(&dir); - -	separator_position = (char *)strrchr(fname, G_DIR_SEPARATOR); -	if (separator_position) { -		path = (char *) malloc(separator_position - fname + 1); -		path[separator_position-fname] = 0; -		strncpy(path, fname, separator_position - fname); -		chdir(path); -		free(path); -	} - -	name = _fcaseseek(separator_position ? separator_position + 1 : fname, &dir); -	if (name) -		file = open(name, flags); - -	sci_finish_find(&dir); /* Free memory */ - -	caller_cwd = sci_getcwd(); -	chdir(caller_cwd); -	free(caller_cwd); +	Common::String name = _fcaseseek(fname); +	if (!name.empty()) +		file = open(name.c_str(), flags);  	return file;  }  | 
