diff options
author | Greg Frieger | 2009-03-11 20:15:42 +0000 |
---|---|---|
committer | Greg Frieger | 2009-03-11 20:15:42 +0000 |
commit | eca41c0d11fd0ff1d0e11a2099bf63bcaa921f29 (patch) | |
tree | ecfd3926a08c2445dc5686b488bac0ca9a630574 /engines/sci | |
parent | 6ccf0161276bc21852889a5ce149af56392a380b (diff) | |
download | scummvm-rg350-eca41c0d11fd0ff1d0e11a2099bf63bcaa921f29.tar.gz scummvm-rg350-eca41c0d11fd0ff1d0e11a2099bf63bcaa921f29.tar.bz2 scummvm-rg350-eca41c0d11fd0ff1d0e11a2099bf63bcaa921f29.zip |
ResourceManager:
- Keep a list of opened volumes to avoid redundant file opens
- Internal functions moved from public to protected
svn-id: r39334
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/scicore/resource.cpp | 64 | ||||
-rw-r--r-- | engines/sci/scicore/resource.h | 72 |
2 files changed, 84 insertions, 52 deletions
diff --git a/engines/sci/scicore/resource.cpp b/engines/sci/scicore/resource.cpp index dba8ad1a7e..f48c795074 100644 --- a/engines/sci/scicore/resource.cpp +++ b/engines/sci/scicore/resource.cpp @@ -206,23 +206,53 @@ bool ResourceManager::loadFromPatchFile(Resource *res) { return true; } +Common::File *ResourceManager::getVolumeFile(const char *filename) { + Common::List<Common::File *>::iterator it = _volumeFiles.begin(); + Common::File *file; + + // check if file is already opened + while (it != _volumeFiles.end()) { + file = *it; + if (scumm_stricmp(file->getName(), filename) == 0) { + // move file to top + if (it != _volumeFiles.begin()) { + _volumeFiles.erase(it); + _volumeFiles.push_front(file); + } + return file; + } + it ++; + } + // adding a new file + file = new Common::File; + if (file->open(filename)) { + if (_volumeFiles.size() == MAX_OPENED_VOLUMES) { + it = --_volumeFiles.end(); + delete *it; + _volumeFiles.erase(it); + } + _volumeFiles.push_front(file); + return file; + } + // failed + delete file; + return NULL; +} + void ResourceManager::loadResource(Resource *res) { - char filename[MAXPATHLEN]; - Common::File file; + Common::File *file; if (res->source->source_type == kSourcePatch && loadFromPatchFile(res)) return; // Either loading from volume or patch loading failed - strcpy(filename, res->source->location_name.c_str()); - - if (!file.open(filename)) { - warning("Failed to open %s", filename); + file = getVolumeFile(res->source->location_name.c_str()); + if (!file) { + warning("Failed to open %s", res->source->location_name.c_str()); res->unalloc(); return; } - file.seek(res->file_offset, SEEK_SET); - - int error = decompress(res, &file); + file->seek(res->file_offset, SEEK_SET); + int error = decompress(res, file); 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]); @@ -324,7 +354,8 @@ int ResourceManager::addAppropriateSources() { addVolume(map, name.c_str(), number, 0); } - addPatchDir(""); // FIXME: used to pass the 'current' instead of "" + addPatchDir(""); + // TODO: add RESOURCE.AUD and RESOURCE.SFX for SCI1.1 games return 1; } @@ -471,6 +502,12 @@ ResourceManager::~ResourceManager() { } freeResourceSources(_sources); _resMap.empty(); + + Common::List<Common::File *>::iterator it = _volumeFiles.begin(); + while (it != _volumeFiles.end()) { + delete *it; + it ++; + } } void ResourceManager::removeFromLRU(Resource *res) { @@ -549,9 +586,8 @@ Resource *ResourceManager::findResource(ResourceType type, int number, int lock) if (!retval) return NULL; - if (!retval->status) + if (retval->status == kResStatusNoMalloc) loadResource(retval); - else if (retval->status == kResStatusEnqueued) removeFromLRU(retval); // Unless an error occured, the resource is now either @@ -563,9 +599,7 @@ Resource *ResourceManager::findResource(ResourceType type, int number, int lock) retval->lockers = 0; _memoryLocked += retval->size; } - - ++retval->lockers; - + retval->lockers++; } else if (retval->status != kResStatusLocked) { // Don't lock it if (retval->status == kResStatusAllocated) addToLRU(retval); diff --git a/engines/sci/scicore/resource.h b/engines/sci/scicore/resource.h index a88b7358a8..70d2fe4279 100644 --- a/engines/sci/scicore/resource.h +++ b/engines/sci/scicore/resource.h @@ -84,6 +84,8 @@ enum ResourceStatus { #define SCI_VERSION_1 SCI_VERSION_1_EARLY +#define MAX_OPENED_VOLUMES 5 // Max number of simultaneously opened volumes + enum ResSourceType { kSourceDirectory = 0, kSourcePatch = 1, @@ -138,11 +140,11 @@ const char *getResourceTypeSuffix(ResourceType restype); /* Used for autodetection */ - +// resource type for SCI1 resource.map file struct resource_index_t { uint16 wOffset; uint16 wSize; -}; /* resource type as stored in the resource.map file */ +}; struct ResourceSource { ResSourceType source_type; @@ -155,7 +157,6 @@ struct ResourceSource { /** Class for storing resources in memory */ class Resource { - public: Resource(); ~Resource(); @@ -168,8 +169,6 @@ public: uint16 number; ResourceType type; uint32 id; // contains number and type. - // TODO: maybe use uint32 and set id = RESOURCE_HASH() - // for all SCI versions unsigned int size; unsigned int file_offset; /* Offset in file */ ResourceStatus status; @@ -197,36 +196,6 @@ public: ResourceManager(int version, int maxMemory); ~ResourceManager(); - /* Add a path to the resource manager's list of sources. - ** Returns: A pointer to the added source structure, or NULL if an error occurred. - */ - ResourceSource *addPatchDir(const char *path); - - ResourceSource *getVolume(ResourceSource *map, int volume_nr); - - //! Add a volume to the resource manager's list of sources. - /** @param map The map associated with this volume - * @param filename The name of the volume to add - * @param extended_addressing 1 if this volume uses extended addressing, - * 0 otherwise. - * @return A pointer to the added source structure, or NULL if an error occurred. - */ - ResourceSource *addVolume(ResourceSource *map, const char *filename, - int number, int extended_addressing); - - //! Add an external (i.e. separate file) map resource to the resource manager's list of sources. - /** @param file_name The name of the volume to add - * @return A pointer to the added source structure, or NULL if an error occurred. - */ - ResourceSource *addExternalMap(const char *file_name); - - //! Scans newly registered resource sources for resources, earliest addition first. - /** @param detected_version: Pointer to the detected version number, - * used during startup. May be NULL. - * @return One of SCI_ERROR_*. - */ - int scanNewSources(ResourceSource *source); - //! Looks up a resource's data /** @param type: The resource type to look for * @param number: The resource number to search @@ -258,16 +227,45 @@ public: Resource *testResource(ResourceType type, int number); protected: - int _maxMemory; /* Config option: Maximum total byte number allocated */ + int _maxMemory; // Config option: Maximum total byte number allocated ResourceSource *_sources; int _memoryLocked; // Amount of resource bytes in locked memory int _memoryLRU; // Amount of resource bytes under LRU control Common::List<Resource *> _LRU; // Last Resource Used list Common::HashMap<uint32, Resource *> _resMap; + Common::List<Common::File *> _volumeFiles; // list of opened volume files + + /* Add a path to the resource manager's list of sources. + ** Returns: A pointer to the added source structure, or NULL if an error occurred. + */ + ResourceSource *addPatchDir(const char *path); + ResourceSource *getVolume(ResourceSource *map, int volume_nr); + + //! Add a volume to the resource manager's list of sources. + /** @param map The map associated with this volume + * @param filename The name of the volume to add + * @param extended_addressing 1 if this volume uses extended addressing, + * 0 otherwise. + * @return A pointer to the added source structure, or NULL if an error occurred. + */ + ResourceSource *addVolume(ResourceSource *map, const char *filename, + int number, int extended_addressing); + //! Add an external (i.e. separate file) map resource to the resource manager's list of sources. + /** @param file_name The name of the volume to add + * @return A pointer to the added source structure, or NULL if an error occurred. + */ + ResourceSource *addExternalMap(const char *file_name); + //! Scans newly registered resource sources for resources, earliest addition first. + /** @param detected_version: Pointer to the detected version number, + * used during startup. May be NULL. + * @return One of SCI_ERROR_*. + */ + int scanNewSources(ResourceSource *source); int addAppropriateSources(); void freeResourceSources(ResourceSource *rss); + Common::File *getVolumeFile(const char *filename); void loadResource(Resource *res); bool loadFromPatchFile(Resource *res); void freeOldResources(int last_invulnerable); @@ -290,7 +288,7 @@ protected: /**--- Patch management functions ---*/ - //! Reads SCI1 patch files from a local directory + //! Reads patch files from a local directory /** @paramParameters: ResourceSource *source */ void readResourcePatches(ResourceSource *source); |