diff options
author | Max Horn | 2011-05-11 17:07:31 +0200 |
---|---|---|
committer | Max Horn | 2011-05-13 11:47:09 +0200 |
commit | 26efa39d2caa0b6bb7da8414382eb5643c108261 (patch) | |
tree | 6cd58f9ec1c908d26e983a68c815c21d520bd9b6 | |
parent | 45e65d7ea04b10cf7bb5282bd66b8df609700a63 (diff) | |
download | scummvm-rg350-26efa39d2caa0b6bb7da8414382eb5643c108261.tar.gz scummvm-rg350-26efa39d2caa0b6bb7da8414382eb5643c108261.tar.bz2 scummvm-rg350-26efa39d2caa0b6bb7da8414382eb5643c108261.zip |
SCUMM: Document and cleanup resource type mode
-rw-r--r-- | engines/scumm/resource.cpp | 80 | ||||
-rw-r--r-- | engines/scumm/resource.h | 27 | ||||
-rw-r--r-- | engines/scumm/saveload.cpp | 14 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 2 |
4 files changed, 74 insertions, 49 deletions
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index 76b6830137..7f88def0ad 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -526,28 +526,28 @@ int ScummEngine_v70he::readResTypeList(int id) { return num; } -void ResourceManager::allocResTypeData(int id, uint32 tag, int num_, const char *name_, int mode_) { - debug(9, "allocResTypeData(%s/%s,%s,%d,%d)", resTypeFromId(id), name_, tag2str(TO_BE_32(tag)), num_, mode_); +void ResourceManager::allocResTypeData(int id, uint32 tag, int num, const char *name, ResTypeMode mode) { + debug(9, "allocResTypeData(%s/%s,%s,%d,%d)", resTypeFromId(id), name, tag2str(TO_BE_32(tag)), num, mode); assert(id >= 0 && id < (int)(ARRAYSIZE(_types))); - if (num_ >= 8000) - error("Too many %ss (%d) in directory", name_, num_); + if (num >= 8000) + error("Too many %ss (%d) in directory", name, num); - _types[id].mode = mode_; - _types[id].num = num_; - _types[id].tags = tag; - _types[id].name = name_; - _types[id].address = (byte **)calloc(num_, sizeof(void *)); - _types[id].flags = (byte *)calloc(num_, sizeof(byte)); - _types[id].status = (byte *)calloc(num_, sizeof(byte)); + _types[id]._mode = mode; + _types[id].num = num; + _types[id].tag = tag; + _types[id].name = name; + _types[id].address = (byte **)calloc(num, sizeof(void *)); + _types[id].flags = (byte *)calloc(num, sizeof(byte)); + _types[id].status = (byte *)calloc(num, sizeof(byte)); - if (mode_) { - _types[id].roomno = (byte *)calloc(num_, sizeof(byte)); - _types[id].roomoffs = (uint32 *)calloc(num_, sizeof(uint32)); + if (mode) { + _types[id].roomno = (byte *)calloc(num, sizeof(byte)); + _types[id].roomoffs = (uint32 *)calloc(num, sizeof(uint32)); } if (_vm->_game.heversion >= 70) { - _types[id].globsize = (uint32 *)calloc(num_, sizeof(uint32)); + _types[id].globsize = (uint32 *)calloc(num, sizeof(uint32)); } } @@ -669,7 +669,7 @@ int ScummEngine::loadResource(int type, int idx) { tag = _fileHandle->readUint32BE(); - if (tag != _res->_types[type].tags && _game.heversion < 70) { + if (tag != _res->_types[type].tag && _game.heversion < 70) { error("%s %d not in room %d at %d+%d in file %s", _res->_types[type].name, idx, roomNr, _fileOffset, fileOffs, _fileHandle->getName()); @@ -734,11 +734,13 @@ byte *ScummEngine::getResourceAddress(int type, int idx) { return NULL; } - if (_res->_types[type].mode && !_res->_types[type].address[idx]) { + // If the resource is missing, but loadable from the game data files, try to do so. + if (!_res->_types[type].address[idx] && _res->_types[type]._mode != kDynamicResTypeMode) { ensureResourceLoaded(type, idx); } - if (!(ptr = (byte *)_res->_types[type].address[idx])) { + ptr = (byte *)_res->_types[type].address[idx]; + if (!ptr) { debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); return NULL; } @@ -978,7 +980,9 @@ void ResourceManager::expireResources(uint32 size) { best_counter = 2; for (i = rtFirst; i <= rtLast; i++) - if (_types[i].mode) { + if (_types[i]._mode != kDynamicResTypeMode) { + // Resources of this type can be reloaded from the data files, + // so we can potentially unload them to free memory. for (j = _types[i].num; --j >= 0;) { flag = _types[i].flags[j]; if (!(flag & RF_LOCK) && flag >= best_counter && _types[i].address[j] && !_vm->isResourceInUse(i, j)) { @@ -1275,30 +1279,30 @@ void ScummEngine::allocateArrays() { } _res->allocResTypeData(rtCostume, (_game.features & GF_NEW_COSTUMES) ? MKTAG('A','K','O','S') : MKTAG('C','O','S','T'), - _numCostumes, "costume", 1); - _res->allocResTypeData(rtRoom, MKTAG('R','O','O','M'), _numRooms, "room", 1); - _res->allocResTypeData(rtRoomImage, MKTAG('R','M','I','M'), _numRooms, "room image", 1); - _res->allocResTypeData(rtRoomScripts, MKTAG('R','M','S','C'), _numRooms, "room script", 1); - _res->allocResTypeData(rtSound, MKTAG('S','O','U','N'), _numSounds, "sound", 2); - _res->allocResTypeData(rtScript, MKTAG('S','C','R','P'), _numScripts, "script", 1); - _res->allocResTypeData(rtCharset, MKTAG('C','H','A','R'), _numCharsets, "charset", 1); - _res->allocResTypeData(rtObjectName, 0, _numNewNames, "new name", 0); - _res->allocResTypeData(rtInventory, 0, _numInventory, "inventory", 0); - _res->allocResTypeData(rtTemp, 0, 10, "temp", 0); - _res->allocResTypeData(rtScaleTable, 0, 5, "scale table", 0); - _res->allocResTypeData(rtActorName, 0, _numActors, "actor name", 0); - _res->allocResTypeData(rtVerb, 0, _numVerbs, "verb", 0); - _res->allocResTypeData(rtString, 0, _numArray, "array", 0); - _res->allocResTypeData(rtFlObject, 0, _numFlObject, "flobject", 0); - _res->allocResTypeData(rtMatrix, 0, 10, "boxes", 0); - _res->allocResTypeData(rtImage, MKTAG('A','W','I','Z'), _numImages, "images", 1); - _res->allocResTypeData(rtTalkie, MKTAG('T','L','K','E'), _numTalkies, "talkie", 1); + _numCostumes, "costume", kStaticResTypeMode); + _res->allocResTypeData(rtRoom, MKTAG('R','O','O','M'), _numRooms, "room", kStaticResTypeMode); + _res->allocResTypeData(rtRoomImage, MKTAG('R','M','I','M'), _numRooms, "room image", kStaticResTypeMode); + _res->allocResTypeData(rtRoomScripts, MKTAG('R','M','S','C'), _numRooms, "room script", kStaticResTypeMode); + _res->allocResTypeData(rtSound, MKTAG('S','O','U','N'), _numSounds, "sound", kSoundResTypeMode); + _res->allocResTypeData(rtScript, MKTAG('S','C','R','P'), _numScripts, "script", kStaticResTypeMode); + _res->allocResTypeData(rtCharset, MKTAG('C','H','A','R'), _numCharsets, "charset", kStaticResTypeMode); + _res->allocResTypeData(rtObjectName, 0, _numNewNames, "new name", kDynamicResTypeMode); + _res->allocResTypeData(rtInventory, 0, _numInventory, "inventory", kDynamicResTypeMode); + _res->allocResTypeData(rtTemp, 0, 10, "temp", kDynamicResTypeMode); + _res->allocResTypeData(rtScaleTable, 0, 5, "scale table", kDynamicResTypeMode); + _res->allocResTypeData(rtActorName, 0, _numActors, "actor name", kDynamicResTypeMode); + _res->allocResTypeData(rtVerb, 0, _numVerbs, "verb", kDynamicResTypeMode); + _res->allocResTypeData(rtString, 0, _numArray, "array", kDynamicResTypeMode); + _res->allocResTypeData(rtFlObject, 0, _numFlObject, "flobject", kDynamicResTypeMode); + _res->allocResTypeData(rtMatrix, 0, 10, "boxes", kDynamicResTypeMode); + _res->allocResTypeData(rtImage, MKTAG('A','W','I','Z'), _numImages, "images", kStaticResTypeMode); + _res->allocResTypeData(rtTalkie, MKTAG('T','L','K','E'), _numTalkies, "talkie", kStaticResTypeMode); } void ScummEngine_v70he::allocateArrays() { ScummEngine::allocateArrays(); - _res->allocResTypeData(rtSpoolBuffer, 0, 9, "spool buffer", 1); + _res->allocResTypeData(rtSpoolBuffer, 0, 9, "spool buffer", kStaticResTypeMode); _heV7RoomIntOffsets = (uint32 *)calloc(_numRooms, sizeof(uint32)); } diff --git a/engines/scumm/resource.h b/engines/scumm/resource.h index b3cb424d4f..8540ef3138 100644 --- a/engines/scumm/resource.h +++ b/engines/scumm/resource.h @@ -50,6 +50,24 @@ enum { class ScummEngine; /** + * The mode of a resource type indicates whether the resource can be restored + * from the game data files or not. + * This affects for example whether the resource is stored in savestates. + * + * Note that we treat sound resources somewhat differently: On the one hand, + * these behave mostly like a kStaticResTypeMode res type. However, when we + * create a savestate, we do save *some* information about them: Namely, which + * sound resources are loaded in memory at the time the save is made. And when + * loading, we invoke ensureResourceLoaded() for each sound resource that was + * marked in this way. + */ +enum ResTypeMode { + kDynamicResTypeMode = 0, ///!< Resource is generated during runtime and may change + kStaticResTypeMode = 1, ///!< Resource comes from data files, does not change + kSoundResTypeMode = 2 ///!< Resource comes from data files, but may change +}; + +/** * The 'resource manager' class. Currently doesn't really deserve to be called * a 'class', at least until somebody gets around to OOfying this more. */ @@ -60,12 +78,15 @@ protected: ScummEngine *_vm; public: + /** + * This struct represents a resource type and all resource of that type. + */ class ResTypeData { friend class ResourceManager; public: - byte mode; + ResTypeMode _mode; uint16 num; - uint32 tags; + uint32 tag; const char *name; byte **address; protected: @@ -89,7 +110,7 @@ public: void setHeapThreshold(int min, int max); - void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode); + void allocResTypeData(int id, uint32 tag, int num, const char *name, ResTypeMode mode); void freeResources(); byte *createResource(int type, int index, uint32 size); diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 424e0005f4..40dc70af4b 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1243,7 +1243,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { // number of script resources, savegames won't break. if (s->isSaving()) { for (type = rtFirst; type <= rtLast; type++) { - if (_res->_types[type].mode != 1 && type != rtTemp && type != rtBuffer) { + if (_res->_types[type]._mode != kStaticResTypeMode && type != rtTemp && type != rtBuffer) { s->saveUint16(type); // Save the res type... for (idx = 0; idx < _res->_types[type].num; idx++) { // Only save resources which actually exist... @@ -1269,7 +1269,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { // with index 0, and breaks whenever we change the limit on a given // resource type. for (type = rtFirst; type <= rtLast; type++) - if (_res->_types[type].mode != 1 && type != rtTemp && type != rtBuffer) { + if (_res->_types[type]._mode != kStaticResTypeMode && type != rtTemp && type != rtBuffer) { // For V1-V5 games, there used to be no object name resources. // At some point this changed. But since old savegames rely on // unchanged resource counts, we have to hard code the following check @@ -1637,7 +1637,7 @@ void ScummEngine::saveLoadResource(Serializer *ser, int type, int idx) { byte *ptr; uint32 size; - if (!_res->_types[type].mode) { + if (_res->_types[type]._mode == kDynamicResTypeMode) { if (ser->isSaving()) { ptr = _res->_types[type].address[idx]; if (ptr == NULL) { @@ -1676,7 +1676,7 @@ void ScummEngine::saveLoadResource(Serializer *ser, int type, int idx) { } } } - } else if (_res->_types[type].mode == 2 && ser->getVersion() >= VER(23)) { + } else if (_res->_types[type]._mode == kSoundResTypeMode && ser->getVersion() >= VER(23)) { // Save/load only a list of resource numbers that need to be reloaded. if (ser->isSaving()) { ser->saveUint16(_res->_types[type].address[idx] ? 1 : 0); @@ -1690,7 +1690,7 @@ void ScummEngine::saveLoadResource(Serializer *ser, int type, int idx) { void ScummEngine::saveResource(Serializer *ser, int type, int idx) { assert(_res->_types[type].address[idx]); - if (_res->_types[type].mode == 0) { + if (_res->_types[type]._mode == kDynamicResTypeMode) { byte *ptr = _res->_types[type].address[idx]; uint32 size = ((MemBlkHeader *)ptr)->size; @@ -1713,7 +1713,7 @@ void ScummEngine::loadResource(Serializer *ser, int type, int idx) { assert(size); _res->createResource(type, idx, size); ser->loadBytes(getResourceAddress(type, idx), size); - } else if (_res->_types[type].mode == 0) { + } else if (_res->_types[type]._mode == kDynamicResTypeMode) { uint32 size = ser->loadUint32(); assert(size); _res->createResource(type, idx, size); @@ -1725,7 +1725,7 @@ void ScummEngine::loadResource(Serializer *ser, int type, int idx) { if (type == rtObjectName) { _newNames[idx] = ser->loadUint16(); } - } else if (_res->_types[type].mode == 2) { + } else if (_res->_types[type]._mode == kSoundResTypeMode) { // HE Games use sound resource 1 for speech if (_game.heversion >= 60 && idx == 1) return; diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index d5c2b2eeb9..e89100688a 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1233,7 +1233,7 @@ void ScummEngine::setupScumm() { requestLoad(ConfMan.getInt("save_slot")); } - _res->allocResTypeData(rtBuffer, 0, 10, "buffer", 0); + _res->allocResTypeData(rtBuffer, 0, 10, "buffer", kDynamicResTypeMode); setupScummVars(); |