SCI: Started rewriting file handling. Warning: This will likely introduce
regressions, but we just have to start somewhere. - factored out some common code in engine/kfile.cpp into a separate func - replaced many uses of chdir, getcwd, sci_init_dir etc. by equivalent or better functionality from SearchMan etc. - replaced many uses of sci_open and sci_fopen by using Common::File and Common::Stream - C++ified some stuff - simplified ResourceSource a bit (loosing some unused functionality) svn-id: r38597
This commit is contained in:
parent
e736b7fa62
commit
bc360ee525
11 changed files with 399 additions and 617 deletions
|
@ -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];
|
||||
}
|
||||
|
||||
fclose(s->file_handles[handle]);
|
||||
void file_close(state_t *s, int handle) {
|
||||
SCIkdebug(SCIkFILE, "Closing file %d\n", 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");
|
||||
FILE *f = getFileFromHandle(s, handle);
|
||||
if (!f)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((handle >= s->file_handles_nr) || (s->file_handles[handle] == NULL)) {
|
||||
SCIkwarn(SCIkERROR, "Attempt seek on invalid/unused file handle %d\n", handle);
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
strcpy(filename, res->source->location_name.c_str());
|
||||
|
||||
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 (!file.open(filename))
|
||||
continue;
|
||||
file.seek(res->file_offset, SEEK_SET);
|
||||
|
||||
if (!IS_VALID_FD(fh)) continue;
|
||||
lseek(fh, 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);
|
||||
Common::ArchiveMemberList files;
|
||||
SearchMan.listMatchingMembers(files, "RESOURCE.0??");
|
||||
|
||||
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, '.');
|
||||
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);
|
||||
scir_scan_new_sources(mgr, &resmap_version);
|
||||
|
||||
if (!mgr->_resources || !mgr->_resourcesNr) {
|
||||
if (mgr->_resources) {
|
||||
free(mgr->_resources);
|
||||
mgr->_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;
|
||||
}
|
||||
|
||||
mgr->lru_first = NULL;
|
||||
mgr->lru_last = NULL;
|
||||
|
||||
qsort(mgr->_resources, mgr->_resourcesNr, sizeof(resource_t),
|
||||
scir_add_appropriate_sources(mgr);
|
||||
scir_scan_new_sources(mgr, &resmap_version);
|
||||
|
||||
if (!_resources || !_resourcesNr) {
|
||||
if (_resources) {
|
||||
free(_resources);
|
||||
_resources = NULL;
|
||||
}
|
||||
sciprintf("Resmgr: Could not retrieve a resource list!\n");
|
||||
_scir_free_resource_sources(mgr->_sources);
|
||||
error("FIXME: Move this code to an init() method so that we can perform error handling");
|
||||
// return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
int patch_data_offset;
|
||||
|
||||
read(file, filehdr, 2);
|
||||
file.read(filehdr, 2);
|
||||
|
||||
patch_data_offset = filehdr[1];
|
||||
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;
|
||||
|
||||
_scir_add_altsource(newrsc, source, 2);
|
||||
|
||||
close(file);
|
||||
|
||||
printf("OK\n");
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
_scir_add_altsource(newrsc, source, 2);
|
||||
|
||||
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();
|
||||
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, "*.???");
|
||||
|
||||
chdir(source->location.dir.name);
|
||||
sci_init_dir(&dir);
|
||||
entry = sci_find_first(&dir, "*.???");
|
||||
while (entry) {
|
||||
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();
|
||||
// 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, "*.*");
|
||||
|
||||
chdir(source->location.dir.name);
|
||||
sci_init_dir(&dir);
|
||||
entry = sci_find_first(&dir, "*.*");
|
||||
while (entry) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
// Look up the file, ignoring case
|
||||
Common::ArchiveMemberList files;
|
||||
SearchMan.listMatchingMembers(files, fname);
|
||||
|
||||
/* Replace all letters with '?' chars */
|
||||
buf = fname;
|
||||
|
||||
for (Common::String::iterator iterator = buf.begin(); iterator != buf.end(); ++iterator) {
|
||||
if (isalpha(*iterator))
|
||||
*iterator = '?';
|
||||
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
|
||||
const Common::String name = (*x)->getName();
|
||||
if (name.equalsIgnoreCase(fname))
|
||||
return name;
|
||||
}
|
||||
|
||||
name = sci_find_first(dir, buf.c_str());
|
||||
|
||||
while (name && !retval) {
|
||||
if (!scumm_stricmp(fname, name))
|
||||
retval = name;
|
||||
else
|
||||
name = sci_find_next(dir);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue