aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorGreg Frieger2009-03-11 20:15:42 +0000
committerGreg Frieger2009-03-11 20:15:42 +0000
commiteca41c0d11fd0ff1d0e11a2099bf63bcaa921f29 (patch)
treeecfd3926a08c2445dc5686b488bac0ca9a630574 /engines/sci
parent6ccf0161276bc21852889a5ce149af56392a380b (diff)
downloadscummvm-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.cpp64
-rw-r--r--engines/sci/scicore/resource.h72
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);