[Scummvm-cvs-logs] SF.net SVN: scummvm:[39098] scummvm/trunk/engines/sci/scicore

gregfrieger at users.sourceforge.net gregfrieger at users.sourceforge.net
Wed Mar 4 00:07:06 CET 2009


Revision: 39098
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39098&view=rev
Author:   gregfrieger
Date:     2009-03-03 23:07:06 +0000 (Tue, 03 Mar 2009)

Log Message:
-----------
- ResourceManager uses HashMap to store and access resource info.
- Changes and clean-ups in resource loading code.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/scicore/resource.cpp
    scummvm/trunk/engines/sci/scicore/resource.h
    scummvm/trunk/engines/sci/scicore/resource_map.cpp
    scummvm/trunk/engines/sci/scicore/resource_patch.cpp

Modified: scummvm/trunk/engines/sci/scicore/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/scicore/resource.cpp	2009-03-03 22:32:39 UTC (rev 39097)
+++ scummvm/trunk/engines/sci/scicore/resource.cpp	2009-03-03 23:07:06 UTC (rev 39098)
@@ -26,6 +26,7 @@
 // Resource library
 
 #include "common/util.h"
+#include "common/debug.h"
 
 #include "sci/tools.h"
 #include "sci/sci_memory.h"
@@ -88,8 +89,6 @@
 	return resourceTypeSuffixes[restype];
 }
 
-int resourcecmp(const void *first, const void *second);
-
 typedef int decomp_funct(Resource *result, Common::ReadStream &stream, int sci_version);
 typedef void patch_sprintf_funct(char *string, Resource *res);
 
@@ -117,39 +116,32 @@
 	&sci1_sprintf_patch_file_name
 };
 
-
-int resourcecmp(const void *first, const void *second) {
-	if (((Resource *)first)->type ==
-	        ((Resource *)second)->type)
-		return (((Resource *)first)->number <
-		        ((Resource *)second)->number) ? -1 :
-		       !(((Resource *)first)->number ==
-		         ((Resource *)second)->number);
-	else
-		return (((Resource *)first)->type <
-		        ((Resource *)second)->type) ? -1 : 1;
+//-- Resource main functions --
+Resource::Resource() {
+	data = NULL;
+	number = 0;
+	type = kResourceTypeInvalid;
+	id = 0;
+	size = 0;
+	file_offset = 0;
+	status = SCI_STATUS_NOMALLOC;
+	lockers = 0;
+	next = prev = NULL;
+	source = NULL;
 }
 
-
-//-- Resmgr helper functions --
-
-void ResourceManager::addAltSource(Resource *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;
-	rsrc->source = source;
-	rsrc->file_offset = file_offset;
-	res->alt_sources = rsrc;
+Resource::~Resource() {
+	delete[] data;
 }
 
-Resource *ResourceManager::findResourceUnsorted(Resource *res, int res_nr, ResourceType type, int number) {
-	int i;
-	for (i = 0; i < res_nr; i++)
-		if (res[i].number == number && res[i].type == type)
-			return res + i;
-	return NULL;
+void Resource::unalloc() {
+	delete[] data;
+	data = NULL;
+	status = SCI_STATUS_NOMALLOC;
 }
 
+//-- Resmgr helper functions --
+
 // Resource source list management
 
 ResourceSource *ResourceManager::addExternalMap(const char *file_name) {
@@ -159,7 +151,7 @@
 	newsrc->next = _sources;
 	_sources = newsrc;
 
-	newsrc->source_type = RESSOURCE_TYPE_EXTERNAL_MAP;
+	newsrc->source_type = kSourceExtMap;
 	newsrc->location_name = file_name;
 	newsrc->scanned = false;
 	newsrc->associated_map = NULL;
@@ -174,7 +166,7 @@
 	newsrc->next = _sources;
 	_sources = newsrc;
 
-	newsrc->source_type = RESSOURCE_TYPE_VOLUME;
+	newsrc->source_type = kSourceVolume;
 	newsrc->scanned = false;
 	newsrc->location_name = filename;
 	newsrc->volume_number = number;
@@ -190,7 +182,7 @@
 	newsrc->next = _sources;
 	_sources = newsrc;
 
-	newsrc->source_type = RESSOURCE_TYPE_DIRECTORY;
+	newsrc->source_type = kSourceDirectory;
 	newsrc->scanned = false;
 	newsrc->location_name = dirname;
 
@@ -201,7 +193,7 @@
 	ResourceSource *seeker = _sources;
 
 	while (seeker) {
-		if (seeker->source_type == RESSOURCE_TYPE_VOLUME && seeker->associated_map == map &&
+		if (seeker->source_type == kSourceVolume && seeker->associated_map == map &&
 		        seeker->volume_number == volume_nr)
 			return seeker;
 		seeker = seeker->next;
@@ -212,79 +204,77 @@
 
 // Resource manager constructors and operations
 
-void ResourceManager::loadFromPatchFile(Common::File &file, Resource *res, char *filename) {
-	unsigned int really_read;
+bool ResourceManager::loadFromPatchFile(Resource *res) {
+	Common::File file;
+	char filename[MAXPATHLEN];
+	if (!patch_sprintfers[_sciVersion]) {
+		error("Resource manager's SCI version (%d) has no patch file name printers", _sciVersion);
+	}
+	// TODO: use only dir specified by res->source->location_dir_name
+	patch_sprintfers[_sciVersion](filename, res);
+	if (file.open(filename) == false) {
+		warning("Failed to open patch file %s", filename);
+		res->unalloc();
+		return false;
+	}
+	res->data = new byte[res->size];
 
-	res->data = (unsigned char *)sci_malloc(res->size);
-	really_read = file.read(res->data, res->size);
+	if (res->data == NULL) {
+		error("Can't allocate %d bytes needed for loading %s!", res->size, filename);
+	}
 
-	if (really_read < res->size) {
+	file.seek(res->file_offset, SEEK_SET);
+	unsigned int really_read = file.read(res->data, res->size);
+	if (really_read != res->size) {
 		error("Read %d bytes from %s but expected %d!", really_read, filename, res->size);
 	}
-
 	res->status = SCI_STATUS_ALLOCATED;
+	return true;
 }
 
 void ResourceManager::loadResource(Resource *res, bool protect) {
+	// TODO: check if protect is needed at all
 	char filename[MAXPATHLEN];
 	Common::File file;
 	Resource backup;
 
 	memcpy(&backup, res, sizeof(Resource));
 
-	// First try lower-case name
-	if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY) {
-		if (!patch_sprintfers[_sciVersion]) {
-			error("Resource manager's SCI version (%d) has no patch file name printers", _sciVersion);
-		}
+	if (res->source->source_type == kSourceDirectory && loadFromPatchFile(res))
+		return;
+	// Either loading from volume or patch loading failed
+	strcpy(filename, res->source->location_name.c_str());
 
-		// Get patch file name
-		patch_sprintfers[_sciVersion](filename, res);
-
-		// 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_name.c_str());
-
 	if (!file.open(filename)) {
 		warning("Failed to open %s", filename);
-		res->data = NULL;
-		res->status = SCI_STATUS_NOMALLOC;
-		res->size = 0;
+		res->unalloc();
 		return;
 	}
-
 	file.seek(res->file_offset, SEEK_SET);
 
-	if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY)
-		loadFromPatchFile(file, res, filename);
-	else if (!decompressors[_sciVersion]) {
-		// Check whether we support this at all
+	// Check whether we support this at all
+	if (decompressors[_sciVersion] == NULL)
 		error("Resource manager's SCI version (%d) is invalid", _sciVersion);
-	} else {
-		int error = // Decompress from regular resource file
-		    decompressors[_sciVersion](res, file, _sciVersion);
+	// Decompress from regular resource file
+	int error = decompressors[_sciVersion](res, file, _sciVersion);
 
-		if (error) {
-			sciprintf("Error %d occured while reading %s.%03d from resource file: %s\n",
-			          error, getResourceTypeName(res->type), res->number, sci_error_types[error]);
+	if (error) {
+		warning("Error %d occured while reading %s.%03d from resource file: %s\n",
+			error, getResourceTypeName(res->type), res->number, sci_error_types[error]);
 
-			if (protect)
-				memcpy(res, &backup, sizeof(Resource));
-
-			res->data = NULL;
-			res->status = SCI_STATUS_NOMALLOC;
-			res->size = 0;
-		}
+		if (protect)
+			memcpy(res, &backup, sizeof(Resource));
+		res->unalloc();
 	}
-
 }
 
 Resource *ResourceManager::testResource(ResourceType type, int number) {
 	Resource binseeker;
 	binseeker.type = type;
 	binseeker.number = number;
-	return (Resource *)bsearch(&binseeker, _resources, _resourcesNr, sizeof(Resource), resourcecmp);
+	if (_resMap.contains(RESOURCE_HASH(type, number)))
+		return _resMap.getVal(RESOURCE_HASH(type, number));
+	return NULL;
 }
 
 int sci0_get_compression_method(Common::ReadStream &stream);
@@ -304,7 +294,7 @@
 		if (!res)
 			continue;
 
-		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY)
+		if (res->source->source_type == kSourceDirectory)
 			continue;
 
 		strcpy(filename, res->source->location_name.c_str());
@@ -329,7 +319,7 @@
 		if (!res)
 			continue;
 
-		if (res->source->source_type == RESSOURCE_TYPE_DIRECTORY)
+		if (res->source->source_type == kSourceDirectory)
 			continue;
 
 		strcpy(filename, res->source->location_name.c_str());
@@ -373,10 +363,12 @@
 }
 
 int ResourceManager::scanNewSources(int *detected_version, ResourceSource *source) {
+	if (!source)
+		return SCI_ERROR_NO_RESOURCE_FILES_FOUND;
+
 	int preset_version = _sciVersion;
 	int resource_error = 0;
 	int dummy = _sciVersion;
-	//Resource **concat_ptr = &(mgr->_resources[mgr->_resourcesNr - 1].next);
 
 	if (detected_version == NULL)
 		detected_version = &dummy;
@@ -388,13 +380,13 @@
 	if (!source->scanned) {
 		source->scanned = true;
 		switch (source->source_type) {
-		case RESSOURCE_TYPE_DIRECTORY:
+		case kSourceDirectory:
 			if (_sciVersion <= SCI_VERSION_01)
 				readResourcePatchesSCI0(source);
 			else
 				readResourcePatchesSCI1(source);
 			break;
-		case RESSOURCE_TYPE_EXTERNAL_MAP:
+		case kSourceExtMap:
 			if (preset_version <= SCI_VERSION_01_VGA_ODD /* || preset_version == SCI_VERSION_AUTODETECT -- subsumed by the above line */) {
 				resource_error = readResourceMapSCI0(source, detected_version);
 #if 0
@@ -429,8 +421,7 @@
 
 				if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {
 					// Initialize empty resource manager
-					_resourcesNr = 0;
-					_resources = 0; // FIXME: Was = (Resource*)sci_malloc(1);
+					_resMap.clear();
 					resource_error = 0;
 				}
 			}
@@ -440,7 +431,6 @@
 		default:
 			break;
 		}
-		qsort(_resources, _resourcesNr, sizeof(Resource), resourcecmp); // Sort resources
 	}
 	return resource_error;
 }
@@ -461,8 +451,7 @@
 	_memoryLocked = 0;
 	_memoryLRU = 0;
 
-	_resources = NULL;
-	_resourcesNr = 0;
+	_resMap.clear();
 	_sources = NULL;
 	_sciVersion = version;
 
@@ -472,56 +461,43 @@
 	addAppropriateSources();
 	scanNewSources(&resmap_version, _sources);
 
-	if (!_resources || !_resourcesNr) {
-		if (_resources) {
-			free(_resources);
-			_resources = NULL;
-		}
-		sciprintf("Resmgr: Could not retrieve a resource list!\n");
-		freeResourceSources(_sources);
-		error("FIXME: Move this code to an init() method so that we can perform error handling");
-//		return NULL;
-	}
-
-	qsort(_resources, _resourcesNr, sizeof(Resource), resourcecmp); // Sort resources
-
 	if (version == SCI_VERSION_AUTODETECT)
 		switch (resmap_version) {
 		case SCI_VERSION_0:
 			if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB)) {
 				version = sci_test_view_type(this);
 				if (version == SCI_VERSION_01_VGA) {
-					sciprintf("Resmgr: Detected KQ5 or similar\n");
+					debug("Resmgr: Detected KQ5 or similar\n");
 				} else {
-					sciprintf("Resmgr: Detected SCI0\n");
+					debug("Resmgr: Detected SCI0\n");
 					version = SCI_VERSION_0;
 				}
 			} else if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB)) {
 				version = sci_test_view_type(this);
 				if (version == SCI_VERSION_01_VGA) {
-					sciprintf("Resmgr: Detected KQ5 or similar\n");
+					debug("Resmgr: Detected KQ5 or similar\n");
 				} else {
 					if (testResource(kResourceTypeVocab, 912)) {
-						sciprintf("Resmgr: Running KQ1 or similar, using SCI0 resource encoding\n");
+						debug("Resmgr: Running KQ1 or similar, using SCI0 resource encoding\n");
 						version = SCI_VERSION_0;
 					} else {
 						version = SCI_VERSION_01;
-						sciprintf("Resmgr: Detected SCI01\n");
+						debug("Resmgr: Detected SCI01\n");
 					}
 				}
 			} else {
 				version = sci_test_view_type(this);
 				if (version == SCI_VERSION_01_VGA) {
-					sciprintf("Resmgr: Detected KQ5 or similar\n");
+					debug("Resmgr: Detected KQ5 or similar\n");
 				} else {
-					sciprintf("Resmgr: Warning: Could not find vocabulary; assuming SCI0 w/o parser\n");
+					debug("Resmgr: Warning: Could not find vocabulary; assuming SCI0 w/o parser\n");
 					version = SCI_VERSION_0;
 				}
 			}
 			break;
 		case SCI_VERSION_01_VGA_ODD:
 			version = resmap_version;
-			sciprintf("Resmgr: Detected Jones/CD or similar\n");
+			debug("Resmgr: Detected Jones/CD or similar\n");
 			break;
 		case SCI_VERSION_1: {
 			Resource *res = testResource(kResourceTypeScript, 0);
@@ -529,60 +505,36 @@
 			_sciVersion = version = SCI_VERSION_1_EARLY;
 			loadResource(res, true);
 
-			if (res->status == SCI_STATUS_NOMALLOC)
+			if (res->status == SCI_STATUS_NOMALLOC) {
 				_sciVersion = version = SCI_VERSION_1_LATE;
+				debug("Resmgr: Detected SCI1 Late"); 
+			} else
+				debug("Resmgr: Detected SCI1 Early"); 
 			break;
 		}
 		case SCI_VERSION_1_1:
 			// No need to handle SCI 1.1 here - it was done in resource_map.cpp
 			version = SCI_VERSION_1_1;
+			debug("Resmgr: Detected SCI1.1"); 
 			break;
 		default:
-			sciprintf("Resmgr: Warning: While autodetecting: Couldn't determine SCI version");
+			debug("Resmgr: Warning: While autodetecting: Couldn't determine SCI version");
 		}
 
-	if (!resource_error) {
-		qsort(_resources, _resourcesNr, sizeof(Resource), resourcecmp); // Sort resources
-	}
-
 	_sciVersion = version;
 }
 
-void ResourceManager::freeAltSources(resource_altsource_t *dynressrc) {
-	if (dynressrc) {
-		freeAltSources(dynressrc->next);
-		free(dynressrc);
-	}
-}
-
-void ResourceManager::freeResources(Resource *resources, int resourcesNr) {
-	int i;
-
-	for (i = 0; i < resourcesNr; i++) {
-		Resource *res = resources + i;
-
-		// FIXME: alt_sources->next may point to an invalid memory location
-		freeAltSources(res->alt_sources);
-
-		if (res->status != SCI_STATUS_NOMALLOC)
-			free(res->data);
-	}
-
-	free(resources);
-}
-
 ResourceManager::~ResourceManager() {
-	freeResources(_resources, _resourcesNr);
+	// freeing resources
+	Common::HashMap<uint32, Resource *>::iterator itr = _resMap.begin();
+	while (itr != _resMap.end()) {
+		delete itr->_value;
+		itr ++;
+	}
 	freeResourceSources(_sources);
-	_resources = NULL;
+	_resMap.empty();
 }
 
-void ResourceManager::unalloc(Resource *res) {
-	free(res->data);
-	res->data = NULL;
-	res->status = SCI_STATUS_NOMALLOC;
-}
-
 void ResourceManager::removeFromLRU(Resource *res) {
 	if (res->status != SCI_STATUS_ENQUEUED) {
 		sciprintf("Resmgr: Oops: trying to remove resource that isn't enqueued\n");
@@ -657,7 +609,7 @@
 		}
 
 		removeFromLRU(goner);
-		unalloc(goner);
+		goner->unalloc();
 #ifdef SCI_VERBOSE_RESMGR
 		sciprintf("Resmgr-debug: LRU: Freeing %s.%03d (%d bytes)\n", getResourceTypeName(goner->type), goner->number, goner->size);
 #endif

Modified: scummvm/trunk/engines/sci/scicore/resource.h
===================================================================
--- scummvm/trunk/engines/sci/scicore/resource.h	2009-03-03 22:32:39 UTC (rev 39097)
+++ scummvm/trunk/engines/sci/scicore/resource.h	2009-03-03 23:07:06 UTC (rev 39098)
@@ -84,17 +84,19 @@
 #define SCI_VERSION_1 SCI_VERSION_1_EARLY
 
 enum ResSourceType {
-	RESSOURCE_TYPE_DIRECTORY = 0,
-	RESSOURCE_TYPE_VOLUME = 2,
-	RESSOURCE_TYPE_EXTERNAL_MAP = 3,
-	RESSOURCE_TYPE_INTERNAL_MAP = 4,
-	RESSOURCE_TYPE_MASK = 127
+	kSourceDirectory = 0,
+	kSourceVolume = 2,
+	kSourceExtMap = 3,
+	kSourceIntMap = 4,
+	kSourceMask = 127
 };
 
 #define RESSOURCE_ADDRESSING_BASIC 0
 #define RESSOURCE_ADDRESSING_EXTENDED 128
 #define RESSOURCE_ADDRESSING_MASK 128
 
+#define RESOURCE_HASH(type, number) (uint32)((type<<16) | number) 
+
 extern const char *sci_error_types[];
 extern const char *sci_version_types[];
 extern const int sci_max_resource_nr[]; /* Highest possible resource numbers */
@@ -150,31 +152,28 @@
 	ResourceSource *next;
 };
 
-struct resource_altsource_t {
-	ResourceSource *source;
-	unsigned int file_offset;
-	resource_altsource_t *next;
-};
-
-
-/** Struct for storing resources in memory */
+/** Class for storing resources in memory */
 class Resource {
 
 public:
+	Resource::Resource();
+	Resource::~Resource();
+	void unalloc();
+
 // NOTE : Currently all member data has the same name and public visibility
 // to let the rest of the engine compile without changes
-	unsigned char *data;
-	unsigned short number;
+public:
+	byte *data;
+	uint16 number;
 	ResourceType type;
 	uint16 id; /* contains number and type */
 	unsigned int size;
 	unsigned int file_offset; /* Offset in file */
-	unsigned char status;
+	byte status;
 	unsigned short lockers; /* Number of places where this resource was locked */
 	Resource *next; /* Position marker for the LRU queue */
 	Resource *prev;
 	ResourceSource *source;
-	resource_altsource_t *alt_sources; /* SLL of alternative resource data sources */
 };
 
 
@@ -257,50 +256,21 @@
 
 protected:
 	int _maxMemory; /* Config option: Maximum total byte number allocated */
-	int _resourcesNr;
+	//int _resourcesNr;
 	ResourceSource *_sources;
-	Resource *_resources;
+	//Resource *_resources;
 	int _memoryLocked;	// Amount of resource bytes in locked memory
 	int _memoryLRU;		// Amount of resource bytes under LRU control
 	Resource *lru_first, *lru_last;	// Pointers to the first and last LRU queue entries
 										// LRU queue: lru_first points to the most recent entry
+	Common::HashMap<uint32, Resource *> _resMap;
 
-	/* Frees a block of resources and associated data
-	** Parameters: (Resource *) resources: The resources to free
-	**             (int) _resourcesNr: Number of resources in the block
-	** Returns   : (void)
-	*/
-	void freeResources(Resource *resources, int _resourcesNr);
-
-	/* Finds a resource matching type.number in an unsorted Resource block
-	** To be used during initial resource loading, when the resource list
-	** may not have been sorted yet.
-	** Parameters: (Resource *) res: Pointer to the block to search in
-	**             (int) res_nr: Number of Resource structs allocated and defined
-	**                           in the block pointed to by res
-	**             (ResourceType) type: Type of the resource to look for
-	**             (int) number: Number of the resource to look for
-	** Returns   : (Resource) The matching resource entry, or NULL if not found
-	*/
-	Resource *findResourceUnsorted(Resource *res, int res_nr, ResourceType type, int number);
-
-	/* Adds an alternative source to a resource
-	** Parameters: (Resource *) res: The resource to add to
-	**             (ResourceSource *) source: The source of the resource
-	**             (unsigned int) file_offset: Offset in the file the resource
-	**                            is stored at
-	** Returns   : (void)
-	*/
-	void addAltSource(Resource *res, ResourceSource *source, unsigned int file_offset);
-
 	int addAppropriateSources();
 	void freeResourceSources(ResourceSource *rss);
-	void freeAltSources(resource_altsource_t *dynressrc);
 
 	void loadResource(Resource *res, bool protect);
-	void loadFromPatchFile(Common::File &file, Resource *res, char *filename);
+	bool loadFromPatchFile(Resource *res);
 	void freeOldResources(int last_invulnerable);
-	void unalloc(Resource *res);
 
 	/**--- Resource map decoding functions ---*/
 
@@ -326,28 +296,16 @@
 
 	/**--- Patch management functions ---*/
 
-	/* Reads SCI0 patch files from a local directory
-	** Parameters: (char *) path: (unused)
-	**             (Resource **) resources: Pointer to a pointer
-	**                                        that will be set to the
-	**                                        location of the resources
-	**                                        (in one large chunk)
-	**             (int *) resource_nr_p: Pointer to an int the number of resources
-	**                                    read is stored in
-	** Returns   : (int) 0 on success, an SCI_ERROR_* code otherwise
-	*/
+	//! Reads SCI0 patch files from a local directory
+	/** @paramParameters: ResourceSource *source
+	  * @return   : (int) 0 on success, an SCI_ERROR_* code otherwise
+	  */
 	int readResourcePatchesSCI0(ResourceSource *source);
 
-	/* Reads SCI1 patch files from a local directory
-	** Parameters: (char *) path: (unused)
-	**             (Resource **) resources: Pointer to a pointer
-	**                                        that will be set to the
-	**                                        location of the resources
-	**                                        (in one large chunk)
-	**             (int *) resource_nr_p: Pointer to an int the number of resources
-	**                                    read is stored in
-	** Returns   : (int) 0 on success, an SCI_ERROR_* code otherwise
-	*/
+	//! Reads SCI1 patch files from a local directory
+	/** @paramParameters: ResourceSource *source
+	  * @return   : (int) 0 on success, an SCI_ERROR_* code otherwise
+	  */
 	int readResourcePatchesSCI1(ResourceSource *source);
 
 	void process_patch(ResourceSource *source, Common::ArchiveMember &member,

Modified: scummvm/trunk/engines/sci/scicore/resource_map.cpp
===================================================================
--- scummvm/trunk/engines/sci/scicore/resource_map.cpp	2009-03-03 22:32:39 UTC (rev 39097)
+++ scummvm/trunk/engines/sci/scicore/resource_map.cpp	2009-03-03 23:07:06 UTC (rev 39098)
@@ -200,13 +200,9 @@
 int ResourceManager::readResourceMapSCI0(ResourceSource *map, int *sci_version) {
 	int fsize;
 	Common::File file;
-	Resource *resources;
-	int resource_nr;
-	int resource_index = 0;
+	Resource *res, res1;
 	int resources_total_read = 0;
-	int next_entry;
-	int max_resfile_nr = 0;
-
+	bool bAdded = false;
 	byte buf[SCI0_RESMAP_ENTRIES_SIZE];
 
 	if (!file.open(map->location_name))
@@ -255,86 +251,43 @@
 		return SCI_ERROR_RESMAP_NOT_FOUND;
 	}
 
-	resource_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE;
+	int resource_nr = fsize / SCI0_RESMAP_ENTRIES_SIZE;
 
-	resources = (Resource *)sci_calloc(resource_nr, sizeof(Resource));
-	// Sets valid default values for most entries
-
 	do {
 		int read_ok = file.read(&buf, SCI0_RESMAP_ENTRIES_SIZE);
-		next_entry = 1;
 
-		if (read_ok < 0) {
+		if (read_ok != SCI0_RESMAP_ENTRIES_SIZE) {
 			sciprintf("Error while reading %s: ", map->location_name.c_str());
 			perror("");
-			next_entry = 0;
-		} else if (read_ok != SCI0_RESMAP_ENTRIES_SIZE) {
-			next_entry = 0;
-		} else if (buf[5] == 0xff) // Most significant offset byte
-			next_entry = 0;
+			break;
+		}
+		if(buf[5] == 0xff)
+			break;
 
-		if (next_entry) {
-			int fresh = 1;
-			int addto = resource_index;
-			int i;
-
-			if (resReadEntry(map, buf, resources + resource_index, *sci_version)) {
-				free(resources);
-				return SCI_ERROR_RESMAP_NOT_FOUND;
-			}
-
-			for (i = 0; i < resource_index; i++)
-				if (resources[resource_index].id == resources[i].id) {
-					addto = i;
-					fresh = 0;
-				}
-
-			addAltSource(resources + addto, resources[resource_index].source, resources[resource_index].file_offset);
-
-			if (fresh)
-				++resource_index;
-
-			if (++resources_total_read >= resource_nr) {
-				warning("After %d entries, resource.map is not terminated", resource_index);
-				next_entry = 0;
-			}
-
+		if (resReadEntry(map, buf, &res1, *sci_version))
+			return SCI_ERROR_RESMAP_NOT_FOUND;
+		uint32 resId = RESOURCE_HASH(res1.type, res1.number);
+		// adding a new resource
+		if (_resMap.contains(resId) == false) {
+			res = new Resource;
+			res->id = res1.id;
+			res->file_offset = res1.file_offset;
+			res->number = res1.number;
+			res->type = res1.type;
+			res->source = res1.source;
+			_resMap.setVal(resId, res);
+			bAdded = true;
 		}
 
-	} while (next_entry);
-
-	file.close();
-
-	if (!resource_index) {
-		sciprintf("resource.map was empty!\n");
-		freeResources(resources, resource_nr);
+		if (++resources_total_read >= resource_nr) {
+			warning("After %d entries, resource.map is not terminated", resources_total_read);
+			break;
+		}
+	} while (!file.eos());
+	if (!bAdded)
 		return SCI_ERROR_RESMAP_NOT_FOUND;
-	}
 
-	if (max_resfile_nr > 999) {
-		freeResources(resources, resource_nr);
-		return SCI_ERROR_INVALID_RESMAP_ENTRY;
-	} else {
-#if 0
-		// Check disabled, Mac SQ3 thinks it has resource.004 but doesn't need it -- CR
-		// Check whether the highest resfile used exists
-		char filename_buf[14];
-		sprintf(filename_buf, "resource.%03d", max_resfile_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;
-		}
-#endif
-	}
-
-	if (resource_index < resource_nr)
-		resources = (Resource *)sci_realloc(resources, sizeof(Resource) * resource_index);
-
-	_resources = resources;
-	_resourcesNr = resource_index;
-
+	file.close();
 	return 0;
 }
 
@@ -374,7 +327,6 @@
 int ResourceManager::readResourceMapSCI1(ResourceSource *map, ResourceSource *vol, int *sci_version) {
 	int fsize;
 	Common::File file;
-	Resource *resources, *resource_start;
 	int resource_nr;
 	int resource_index = 0;
 	int ofs, header_size;
@@ -412,10 +364,6 @@
 	}
 
 	resource_nr = (fsize - types[0]) / entrysize;
-	resource_start = resources = (Resource*)sci_realloc(_resources, (_resourcesNr + resource_nr) * sizeof(Resource));
-	memset(resource_start + sizeof(Resource) * _resourcesNr, 0, resource_nr * sizeof(Resource));
-	resources += _resourcesNr;
-
 	i = 0;
 	while (types[i] == 0)
 		i++;
@@ -424,94 +372,38 @@
 	file.seek(ofs, SEEK_SET);
 
 	for (i = 0; i < resource_nr; i++) {
-		int read_ok = file.read(&buf, entrysize);
-		int j;
 		Resource *res;
-		int addto = resource_index;
-		int fresh = 1;
+		int number;
+		ResourceType type;
+		uint32 resId;
 
-		if (read_ok < entrysize) {
-#if 0
-			if (!file.eof()) {
-				sciprintf("Error while reading %s: ", map->location_name.c_str());
-				perror("");
-			} else
-				read_ok = 1;
-			break;
-#endif
+		file.read(&buf, entrysize);
+		type = resTypeSCI1(ofs, types, lastrt);
+		number = SCI1_RESFILE_GET_NUMBER(buf);
+		resId = RESOURCE_HASH(type, number);
+		// adding new resource only if it does not exist
+		if (_resMap.contains(resId) == false) {
+			res = new Resource;
+			_resMap.setVal(resId, res);
+			res->type = type;
+			res->number = number;
+			res->id = res->number | (res->type << 16);
+		// only 1st source would be used when loading resource
+			if (entry_size_selector < SCI_VERSION_1_1) {
+				res->source = getVolume(map, SCI1_RESFILE_GET_FILE(buf));
+				res->file_offset = SCI1_RESFILE_GET_OFFSET(buf);
+			} else {
+				res->source = vol;
+				res->file_offset = SCI11_RESFILE_GET_OFFSET(buf);
+			};
 		}
 
-		res = &(resources[resource_index]);
-		res->type = resTypeSCI1(ofs, types, lastrt);
-		res->number = SCI1_RESFILE_GET_NUMBER(buf);
-		res->status = SCI_STATUS_NOMALLOC;
-
-		if (entry_size_selector < SCI_VERSION_1_1) {
-			res->source = getVolume(map, SCI1_RESFILE_GET_FILE(buf));
-			res->file_offset = SCI1_RESFILE_GET_OFFSET(buf);
-		} else {
-			res->source = vol;
-			res->file_offset = SCI11_RESFILE_GET_OFFSET(buf);
-		};
-
-		res->id = res->number | (res->type << 16);
-
-		for (j = 0; i < resource_index; i++)
-			if (resources[resource_index].id == resources[i].id) {
-				addto = i;
-				fresh = 0;
-			}
-
-#if 0
-		fprintf(stderr, "Read [%04x] %6d.%s\tresource.%03d, %08x ==> %d\n",
-		        res->id, res->number,
-		        sci_resource_type_suffixes[res->type],
-		        res->file, res->file_offset, addto);
-#endif
-
-		addAltSource(resources + addto, resources[resource_index].source, resources[resource_index].file_offset);
-
-		if (fresh)
-			++resource_index;
-
 		ofs += entrysize;
 	}
 
 	free(types);
 
-	_resources = resource_start;
-	_resourcesNr += resource_index;
 	return 0;
-
 }
 
-#ifdef TEST_RESOURCE_MAP
-int main(int argc, char **argv) {
-	int resource_nr;
-	Resource *resources;
-	int notok = sci0_read_resource_map(".", &resources, &resource_nr);
-
-	if (notok) {
-		fprintf(stderr, "Failed: Error code %d\n", notok);
-		return 1;
-	}
-
-	if (resources) {
-		int i;
-
-		printf("Found %d resources:\n", resource_nr);
-
-		for (i = 0; i < resource_nr; i++) {
-			Resource *res = resources + i;
-
-			printf("#%04d:\tRESOURCE.%03d:%8d\t%s.%03d\n", i, res->file, res->file_offset,
-					sci_resource_types[res->type], res->number);
-		}
-	} else
-		fprintf(stderr, "Found no resources.\n");
-
-	return 0;
-}
-#endif
-
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/scicore/resource_patch.cpp
===================================================================
--- scummvm/trunk/engines/sci/scicore/resource_patch.cpp	2009-03-03 22:32:39 UTC (rev 39097)
+++ scummvm/trunk/engines/sci/scicore/resource_patch.cpp	2009-03-03 23:07:06 UTC (rev 39098)
@@ -51,14 +51,15 @@
 	if (!file.open(member.createReadStream(), member.getName()))
 		perror("""__FILE__"": (""__LINE__""): failed to open");
 	else {
-		uint8 filehdr[2];
-		Resource *newrsc = findResourceUnsorted(_resources, _resourcesNr, restype, resnumber);
+		byte filehdr[2];
 		int fsize = file.size();
 		if (fsize < 3) {
 			printf("File too small\n");
 			return;
 		}
-
+		
+		uint32 resId = RESOURCE_HASH(restype, resnumber);
+		Resource *newrsc;
 		int patch_data_offset;
 
 		file.read(filehdr, 2);
@@ -74,23 +75,20 @@
 			fsize -= patch_data_offset;
 
 			// Prepare destination, if neccessary
-			if (!newrsc) {
-				// Completely new resource!
-				_resourcesNr++;
-				_resources = (Resource *)sci_realloc(_resources, _resourcesNr * sizeof(Resource));
-				newrsc = (_resources - 1) + _resourcesNr;
-				newrsc->alt_sources = NULL;
-			}
+			if (_resMap.contains(resId) == false) {
+				newrsc = new Resource;
+				_resMap.setVal(resId, newrsc);
+			} else 
+				newrsc = _resMap.getVal(resId);
 
 			// Overwrite everything, because we're patching
 			newrsc->size = fsize - 2;
-			newrsc->id = restype << 11 | resnumber;
+			newrsc->id = resId;
 			newrsc->number = resnumber;
 			newrsc->status = SCI_STATUS_NOMALLOC;
 			newrsc->type = restype;
 			newrsc->source = source;
 			newrsc->file_offset = 2 + patch_data_offset;
-			addAltSource(newrsc, source, 2);
 			printf("OK\n");
 		}
 	}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list