diff options
author | Max Horn | 2011-05-13 11:45:42 +0200 |
---|---|---|
committer | Max Horn | 2011-05-13 11:47:13 +0200 |
commit | c02420df43bec4ec523c18d8e6fdb381af29c1b5 (patch) | |
tree | f595cd9d72f0b5ba5b98e80caf3544a0f0401830 /engines/scumm | |
parent | abaaf0cad9a63c1a6f1946a8a90facd1535e762d (diff) | |
download | scummvm-rg350-c02420df43bec4ec523c18d8e6fdb381af29c1b5.tar.gz scummvm-rg350-c02420df43bec4ec523c18d8e6fdb381af29c1b5.tar.bz2 scummvm-rg350-c02420df43bec4ec523c18d8e6fdb381af29c1b5.zip |
SCUMM: Add a Resource class, refactor res code around it
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/detection.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/he/resource_he.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/he/script_v72he.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse.cpp | 29 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse.h | 1 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse_internal.h | 2 | ||||
-rw-r--r-- | engines/scumm/object.cpp | 10 | ||||
-rw-r--r-- | engines/scumm/resource.cpp | 175 | ||||
-rw-r--r-- | engines/scumm/resource.h | 112 | ||||
-rw-r--r-- | engines/scumm/resource_v2.cpp | 32 | ||||
-rw-r--r-- | engines/scumm/resource_v3.cpp | 10 | ||||
-rw-r--r-- | engines/scumm/resource_v4.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/saveload.cpp | 8 | ||||
-rw-r--r-- | engines/scumm/script.cpp | 10 | ||||
-rw-r--r-- | engines/scumm/script_v6.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 8 | ||||
-rw-r--r-- | engines/scumm/sound.cpp | 6 |
17 files changed, 222 insertions, 199 deletions
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 6440228d78..38c65b3049 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -68,7 +68,7 @@ static const MD5Table *findInMD5Table(const char *md5) { } Common::String ScummEngine::generateFilename(const int room) const { - const int diskNumber = (room > 0) ? _res->_types[rtRoom].roomno[room] : 0; + const int diskNumber = (room > 0) ? _res->_types[rtRoom]._resources[room]._roomno : 0; char buf[128]; if (_game.version == 4) { @@ -110,7 +110,7 @@ Common::String ScummEngine_v60he::generateFilename(const int room) const { if (room < 0) { id = '0' - room; } else { - const int diskNumber = (room > 0) ? _res->_types[rtRoom].roomno[room] : 0; + const int diskNumber = (room > 0) ? _res->_types[rtRoom]._resources[room]._roomno : 0; id = diskNumber + '0'; } diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index 435e0e547b..70b5543add 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -226,7 +226,7 @@ void ScummEngine_v70he::readRoomsOffsets() { num = READ_LE_UINT16(_heV7RoomOffsets); ptr = _heV7RoomOffsets + 2; for (i = 0; i < num; i++) { - _res->_types[rtRoom].roomoffs[i] = READ_LE_UINT32(ptr); + _res->_types[rtRoom]._resources[i]._roomoffs = READ_LE_UINT32(ptr); ptr += 4; } } diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 96ffa2af3b..dfcfa32df4 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -621,11 +621,11 @@ void ScummEngine_v72he::o72_getArrayDimSize() { } void ScummEngine_v72he::o72_getNumFreeArrays() { - byte **addr = _res->_types[rtString]._address; + const ResourceManager::ResTypeData &rtd = _res->_types[rtString]; int i, num = 0; for (i = 1; i < _numArray; i++) { - if (!addr[i]) + if (!rtd._resources[i]._address) num++; } diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index 4a7ddd05fc..75cdb2028a 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -30,6 +30,7 @@ #include "scumm/imuse/imuse.h" #include "scumm/imuse/imuse_internal.h" #include "scumm/imuse/instrument.h" +#include "scumm/resource.h" #include "scumm/saveload.h" #include "scumm/scumm.h" @@ -47,7 +48,6 @@ _enable_gs(false), _sc55(false), _midi_adlib(NULL), _midi_native(NULL), -_base_sounds(NULL), _sysex(NULL), _paused(false), _initialized(false), @@ -100,11 +100,9 @@ IMuseInternal::~IMuseInternal() { } byte *IMuseInternal::findStartOfSound(int sound) { - byte *ptr = NULL; int32 size, pos; - if (_base_sounds) - ptr = _base_sounds[sound]; + byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address; if (ptr == NULL) { debug(1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist", sound); @@ -136,16 +134,11 @@ byte *IMuseInternal::findStartOfSound(int sound) { } bool IMuseInternal::isMT32(int sound) { - byte *ptr = NULL; - uint32 tag; - - if (_base_sounds) - ptr = _base_sounds[sound]; - + byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address; if (ptr == NULL) return false; - tag = READ_BE_UINT32(ptr); + uint32 tag = READ_BE_UINT32(ptr); switch (tag) { case MKTAG('A','D','L',' '): case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects @@ -183,16 +176,11 @@ bool IMuseInternal::isMT32(int sound) { } bool IMuseInternal::isMIDI(int sound) { - byte *ptr = NULL; - uint32 tag; - - if (_base_sounds) - ptr = _base_sounds[sound]; - + byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address; if (ptr == NULL) return false; - tag = READ_BE_UINT32(ptr); + uint32 tag = READ_BE_UINT32(ptr); switch (tag) { case MKTAG('A','D','L',' '): case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects @@ -423,11 +411,6 @@ int32 IMuseInternal::doCommand(int numargs, int a[]) { return doCommand_internal(numargs, a); } -void IMuseInternal::setBase(byte **base) { - Common::StackLock lock(_mutex, "IMuseInternal::setBase()"); - _base_sounds = base; -} - uint32 IMuseInternal::property(int prop, uint32 value) { Common::StackLock lock(_mutex, "IMuseInternal::property()"); switch (prop) { diff --git a/engines/scumm/imuse/imuse.h b/engines/scumm/imuse/imuse.h index c5e7f0a561..8014b13409 100644 --- a/engines/scumm/imuse/imuse.h +++ b/engines/scumm/imuse/imuse.h @@ -65,7 +65,6 @@ public: virtual bool get_sound_active(int sound) const = 0; virtual int32 doCommand(int numargs, int args[]) = 0; virtual int clear_queue() = 0; - virtual void setBase(byte **base) = 0; virtual uint32 property(int prop, uint32 value) = 0; virtual void addSysexHandler (byte mfgID, sysexfunc handler) = 0; diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index 56617ff820..ec60b22509 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -394,7 +394,6 @@ protected: TimerCallbackInfo _timer_info_native; uint32 _game_id; - byte **_base_sounds; // Plug-in SysEx handling. Right now this only supports one // custom SysEx handler for the hardcoded IMUSE_SYSEX_ID @@ -510,7 +509,6 @@ public: int save_or_load(Serializer *ser, ScummEngine *scumm); bool get_sound_active(int sound) const; int32 doCommand(int numargs, int args[]); - void setBase(byte **base); uint32 property(int prop, uint32 value); virtual void addSysexHandler(byte mfgID, sysexfunc handler); diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 8b0e22d33e..edcf54dac0 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -193,10 +193,10 @@ void ScummEngine::clearOwnerOf(int obj) { _inventory[i] = _inventory[i+1]; _inventory[i+1] = 0; // FIXME FIXME FIXME: This is incomplete, as we do not touch flags, status... BUG - _res->_types[rtInventory]._address[i] = _res->_types[rtInventory]._address[i + 1]; - _res->_types[rtInventory]._size[i] = _res->_types[rtInventory]._size[i + 1]; - _res->_types[rtInventory]._address[i + 1] = NULL; - _res->_types[rtInventory]._size[i + 1] = 0; + _res->_types[rtInventory]._resources[i]._address = _res->_types[rtInventory]._resources[i + 1]._address; + _res->_types[rtInventory]._resources[i]._size = _res->_types[rtInventory]._resources[i + 1]._size; + _res->_types[rtInventory]._resources[i + 1]._address = NULL; + _res->_types[rtInventory]._resources[i + 1]._size = 0; } } break; @@ -1799,7 +1799,7 @@ int ScummEngine::findLocalObjectSlot() { int ScummEngine::findFlObjectSlot() { int i; for (i = 1; i < _numFlObject; i++) { - if (_res->_types[rtFlObject]._address[i] == NULL) + if (_res->_types[rtFlObject]._resources[i]._address == NULL) return i; } error("findFlObjectSlot: Out of FLObject slots"); diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index 3b278a6b80..8767e1b315 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -83,8 +83,8 @@ void ScummEngine::openRoom(const int room) { // Load the disk numer / room offs (special case for room 0 exists because // room 0 contains the data which is used to create the roomno / roomoffs // tables -- hence obviously we mustn't use those when loading room 0. - const uint32 diskNumber = room ? _res->_types[rtRoom].roomno[room] : 0; - const uint32 room_offs = room ? _res->_types[rtRoom].roomoffs[room] : 0; + const uint32 diskNumber = room ? _res->_types[rtRoom]._resources[room]._roomno : 0; + const uint32 room_offs = room ? _res->_types[rtRoom]._resources[room]._roomoffs : 0; // FIXME: Since room_offs is const, clearly the following loop either // is never entered, or loops forever (if it wasn't for the return/error @@ -94,7 +94,7 @@ void ScummEngine::openRoom(const int room) { while (room_offs != RES_INVALID_OFFSET) { if (room_offs != 0 && room != 0 && _game.heversion < 98) { - _fileOffset = _res->_types[rtRoom].roomoffs[room]; + _fileOffset = _res->_types[rtRoom]._resources[room]._roomoffs; return; } @@ -122,7 +122,7 @@ void ScummEngine::openRoom(const int room) { return; deleteRoomOffsets(); readRoomsOffsets(); - _fileOffset = _res->_types[rtRoom].roomoffs[room]; + _fileOffset = _res->_types[rtRoom]._resources[room]._roomoffs; if (_fileOffset != 8) return; @@ -157,8 +157,8 @@ void ScummEngine::closeRoom() { /** Delete the currently loaded room offsets. */ void ScummEngine::deleteRoomOffsets() { for (int i = 0; i < _numRooms; i++) { - if (_res->_types[rtRoom].roomoffs[i] != RES_INVALID_OFFSET) - _res->_types[rtRoom].roomoffs[i] = 0; + if (_res->_types[rtRoom]._resources[i]._roomoffs != RES_INVALID_OFFSET) + _res->_types[rtRoom]._resources[i]._roomoffs = 0; } } @@ -174,8 +174,8 @@ void ScummEngine::readRoomsOffsets() { while (num--) { int room = _fileHandle->readByte(); int offset = _fileHandle->readUint32LE(); - if (_res->_types[rtRoom].roomoffs[room] != RES_INVALID_OFFSET) { - _res->_types[rtRoom].roomoffs[room] = offset; + if (_res->_types[rtRoom]._resources[room]._roomoffs != RES_INVALID_OFFSET) { + _res->_types[rtRoom]._resources[room]._roomoffs = offset; } } } @@ -499,10 +499,10 @@ int ScummEngine::readResTypeList(int id) { for (i = 0; i < num; i++) { - _res->_types[id].roomno[i] = _fileHandle->readByte(); + _res->_types[id]._resources[i]._roomno = _fileHandle->readByte(); } for (i = 0; i < num; i++) { - _res->_types[id].roomoffs[i] = _fileHandle->readUint32LE(); + _res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint32LE(); } return num; @@ -516,11 +516,11 @@ int ScummEngine_v70he::readResTypeList(int id) { if (id == rtRoom) for (i = 0; i < num; i++) { - _heV7RoomIntOffsets[i] = _res->_types[rtRoom].roomoffs[i]; + _heV7RoomIntOffsets[i] = _res->_types[rtRoom]._resources[i]._roomoffs; } for (i = 0; i < num; i++) { - _res->_types[id].globsize[i] = _fileHandle->readUint32LE(); + _res->_types[id]._resources[i]._globsize = _fileHandle->readUint32LE(); } return num; @@ -536,11 +536,11 @@ void ResourceManager::allocResTypeData(int id, uint32 tag, int num, ResTypeMode _types[id]._mode = mode; _types[id]._num = num; _types[id]._tag = tag; - _types[id]._address = (byte **)calloc(num, sizeof(byte *)); - _types[id]._size = (uint32 *)calloc(num, sizeof(uint32)); - _types[id].flags = (byte *)calloc(num, sizeof(byte)); - _types[id]._status = (byte *)calloc(num, sizeof(byte)); + _types[id]._resources.resize(num); +/* + TODO: Use multiple Resource subclasses, one for each res mode; then, + given them serializability. if (mode) { _types[id].roomno = (byte *)calloc(num, sizeof(byte)); _types[id].roomoffs = (uint32 *)calloc(num, sizeof(uint32)); @@ -549,7 +549,7 @@ void ResourceManager::allocResTypeData(int id, uint32 tag, int num, ResTypeMode if (_vm->_game.heversion >= 70) { _types[id].globsize = (uint32 *)calloc(num, sizeof(uint32)); } - +*/ } void ScummEngine::loadCharset(int no) { @@ -604,7 +604,7 @@ void ScummEngine::ensureResourceLoaded(int type, int i) { if (type != rtCharset && i == 0) return; - if (i <= _res->_types[type]._num && _res->_types[type]._address[i]) + if (i <= _res->_types[type]._num && _res->_types[type]._resources[i]._address) return; loadResource(type, i); @@ -690,27 +690,27 @@ int ScummEngine::loadResource(int type, int idx) { int ScummEngine::getResourceRoomNr(int type, int idx) { if (type == rtRoom && _game.heversion < 70) return idx; - return _res->_types[type].roomno[idx]; + return _res->_types[type]._resources[idx]._roomno; } uint32 ScummEngine::getResourceRoomOffset(int type, int idx) { if (type == rtRoom) { return (_game.version == 8) ? 8 : 0; } - return _res->_types[type].roomoffs[idx]; + return _res->_types[type]._resources[idx]._roomoffs; } uint32 ScummEngine_v70he::getResourceRoomOffset(int type, int idx) { if (type == rtRoom) { return _heV7RoomIntOffsets[idx]; } - return _res->_types[type].roomoffs[idx]; + return _res->_types[type]._resources[idx]._roomoffs; } int ScummEngine::getResourceSize(int type, int idx) { byte *ptr = getResourceAddress(type, idx); assert(ptr); - return _res->_types[type]._size[idx]; + return _res->_types[type]._resources[idx]._size; } byte *ScummEngine::getResourceAddress(int type, int idx) { @@ -722,17 +722,12 @@ byte *ScummEngine::getResourceAddress(int type, int idx) { if (!_res->validateResource("getResourceAddress", type, idx)) return NULL; - if (!_res->_types[type]._address) { - debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d), _res->_types[type]._address == NULL", resTypeFromId(type), idx); - return NULL; - } - // 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) { + if (!_res->_types[type]._resources[idx]._address && _res->_types[type]._mode != kDynamicResTypeMode) { ensureResourceLoaded(type, idx); } - ptr = (byte *)_res->_types[type]._address[idx]; + ptr = (byte *)_res->_types[type]._resources[idx]._address; if (!ptr) { debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); return NULL; @@ -774,7 +769,7 @@ void ResourceManager::increaseResourceCounters() { for (i = rtFirst; i <= rtLast; i++) { for (j = _types[i]._num; --j >= 0;) { - counter = _types[i].flags[j] & RF_USAGE; + counter = _types[i]._resources[j].getResourceCounter(); if (counter && counter < RF_USAGE_MAX) { setResourceCounter(i, j, counter + 1); } @@ -783,8 +778,16 @@ void ResourceManager::increaseResourceCounters() { } void ResourceManager::setResourceCounter(int type, int idx, byte counter) { - _types[type].flags[idx] &= RF_LOCK; // Clear lower 7 bits, preserve the lock bit. - _types[type].flags[idx] |= counter; // Update the usage counter + _types[type]._resources[idx].setResourceCounter(counter); +} + +void ResourceManager::Resource::setResourceCounter(byte counter) { + _flags &= RF_LOCK; // Clear lower 7 bits, preserve the lock bit. + _flags |= counter; // Update the usage counter +} + +byte ResourceManager::Resource::getResourceCounter() const { + return _flags & RF_USAGE; } /* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */ @@ -801,8 +804,8 @@ byte *ResourceManager::createResource(int type, int idx, uint32 size) { // cases. For instance, Zak tries to reload the intro music // while it's playing. See bug #1253171. - if (_types[type]._address[idx] && (type == rtSound || type == rtScript || type == rtCostume)) - return _types[type]._address[idx]; + if (_types[type]._resources[idx]._address && (type == rtSound || type == rtScript || type == rtCostume)) + return _types[type]._resources[idx]._address; } nukeResource(type, idx); @@ -816,14 +819,39 @@ byte *ResourceManager::createResource(int type, int idx, uint32 size) { _allocatedSize += size; - _types[type]._address[idx] = ptr; - _types[type]._size[idx] = size; + _types[type]._resources[idx]._address = ptr; + _types[type]._resources[idx]._size = size; setResourceCounter(type, idx, 1); return ptr; } +ResourceManager::Resource::Resource() { + _address = 0; + _size = 0; + _flags = 0; + _status = 0; + _roomno = 0; + _roomoffs = 0; + _globsize = 0; +} + +ResourceManager::Resource::~Resource() { + delete _address; + _address = 0; +} + +void ResourceManager::Resource::nuke() { + delete _address; + _address = 0; + _size = 0; + _flags = 0; + _status &= ~RS_MODIFIED; +} + ResourceManager::ResTypeData::ResTypeData() { - memset(this, 0, sizeof(*this)); + _mode = kDynamicResTypeMode; + _num = 0; + _tag = 0; } ResourceManager::ResTypeData::~ResTypeData() { @@ -856,22 +884,11 @@ bool ResourceManager::validateResource(const char *str, int type, int idx) const } void ResourceManager::nukeResource(int type, int idx) { - byte *ptr; - - if (!_types[type]._address) - return; - - assert(idx >= 0 && idx < _types[type]._num); - - ptr = _types[type]._address[idx]; + byte *ptr = _types[type]._resources[idx]._address; if (ptr != NULL) { debugC(DEBUG_RESOURCE, "nukeResource(%s,%d)", resTypeFromId(type), idx); - _types[type]._address[idx] = 0; - _types[type]._size[idx] = 0; - _types[type].flags[idx] = 0; - _types[type]._status[idx] &= ~RS_MODIFIED; - _allocatedSize -= _types[type]._size[idx]; - free(ptr); + _allocatedSize -= _types[type]._resources[idx]._size; + _types[type]._resources[idx].nuke(); } } @@ -903,19 +920,31 @@ int ScummEngine::getResourceDataSize(const byte *ptr) const { void ResourceManager::lock(int type, int i) { if (!validateResource("Locking", type, i)) return; - _types[type].flags[i] |= RF_LOCK; + _types[type]._resources[i].lock(); } void ResourceManager::unlock(int type, int i) { if (!validateResource("Unlocking", type, i)) return; - _types[type].flags[i] &= ~RF_LOCK; + _types[type]._resources[i].unlock(); } bool ResourceManager::isLocked(int type, int i) const { if (!validateResource("isLocked", type, i)) return false; - return (_types[type].flags[i] & RF_LOCK) != 0; + return _types[type]._resources[i].isLocked(); +} + +void ResourceManager::Resource::lock() { + _flags |= RF_LOCK; +} + +void ResourceManager::Resource::unlock() { + _flags &= ~RF_LOCK; +} + +bool ResourceManager::Resource::isLocked() const { + return (_flags & RF_LOCK) != 0; } bool ScummEngine::isResourceInUse(int type, int i) const { @@ -952,18 +981,25 @@ bool ScummEngine::isResourceInUse(int type, int i) const { void ResourceManager::setModified(int type, int i) { if (!validateResource("Modified", type, i)) return; - _types[type]._status[i] |= RS_MODIFIED; + _types[type]._resources[i].setModified(); } bool ResourceManager::isModified(int type, int i) const { if (!validateResource("isModified", type, i)) return false; - return (_types[type]._status[i] & RS_MODIFIED) != 0; + return _types[type]._resources[i].isModified(); +} + +void ResourceManager::Resource::setModified() { + _status |= RS_MODIFIED; +} + +bool ResourceManager::Resource::isModified() const { + return (_status & RS_MODIFIED) != 0; } void ResourceManager::expireResources(uint32 size) { int i, j; - byte flag; byte best_counter; int best_type, best_res = 0; uint32 oldAllocatedSize; @@ -987,9 +1023,10 @@ void ResourceManager::expireResources(uint32 size) { // 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)) { - best_counter = flag; + Resource &tmp = _types[i]._resources[j]; + byte counter = tmp.getResourceCounter(); + if (!tmp.isLocked() && counter >= best_counter && tmp._address && !_vm->isResourceInUse(i, j)) { + best_counter = counter; best_type = i; best_res = j; } @@ -1013,14 +1050,7 @@ void ResourceManager::freeResources() { if (isResourceLoaded(i, j)) nukeResource(i, j); } - free(_types[i]._address); - free(_types[i]._size); - free(_types[i].flags); - free(_types[i]._status); - free(_types[i].roomno); - free(_types[i].roomoffs); - - free(_types[i].globsize); + _types[i]._resources.clear(); } } @@ -1051,19 +1081,18 @@ void ScummEngine::loadPtrToResource(int type, int resindex, const byte *source) bool ResourceManager::isResourceLoaded(int type, int idx) const { if (!validateResource("isResourceLoaded", type, idx)) return false; - return _types[type]._address[idx] != NULL; + return _types[type]._resources[idx]._address != NULL; } void ResourceManager::resourceStats() { int i, j; uint32 lockedSize = 0, lockedNum = 0; - byte flag; for (i = rtFirst; i <= rtLast; i++) for (j = _types[i]._num; --j >= 0;) { - flag = _types[i].flags[j]; - if (flag & RF_LOCK && _types[i]._address[j]) { - lockedSize += _types[i]._size[j]; + Resource &tmp = _types[i]._resources[j]; + if (tmp.isLocked() && tmp._address) { + lockedSize += tmp._size; lockedNum++; } } diff --git a/engines/scumm/resource.h b/engines/scumm/resource.h index 9685830c81..5aae49b7ad 100644 --- a/engines/scumm/resource.h +++ b/engines/scumm/resource.h @@ -22,6 +22,7 @@ #ifndef SCUMM_RESOURCE_H #define SCUMM_RESOURCE_H +#include "common/array.h" #include "scumm/scumm.h" // for rtNumTypes namespace Scumm { @@ -78,79 +79,97 @@ protected: ScummEngine *_vm; public: - /** - * This struct represents a resource type and all resource of that type. - */ - class ResTypeData { - friend class ResourceManager; + class Resource { public: - ResTypeMode _mode; /** - * The maximal number of resource of this type. Determines the size - * of various arrays. + * Pointer to the data contained in this resource */ - uint16 _num; + byte *_address; /** - * The 4-byte tag or chunk type associated to this resource type, if any. - * Only applies to resources that are loaded from the game data files. + * Size of this resource, i.e. of the data contained in it. */ - uint32 _tag; + uint32 _size; + protected: /** - * Array of size _num containing pointers to each resource of this type. + * The uppermost bit indicates whether the resources is locked. + * The lower 7 bits contain a counter. This counter measures roughly + * how old the resource is; it starts out with a count of 1 and can go + * as high as 127. When memory falls low resp. when the engine decides + * that it should throw out some unused stuff, then it begins by + * removing the resources with the highest counter (excluding locked + * resources and resources that are known to be in use). */ - byte **_address; + byte _flags; /** - * Array of size _num containing the sizes of each resource of this type. + * The status of the resource. Currently only one bit is used, which + * indicates whether the resource is modified. */ - uint32 *_size; + byte _status; - protected: + public: /** - * Array of size _num containing some information on each resource of - * this type. - * First off, the uppermost bit indicates whether the resources is - * locked into memory. - * Secondly, the lower 7 bits contain a counter. This counter measures - * roughly how old it is; a resource starts out with a count of 1 and - * can go as high as 127. When memory falls low resp. when the engine - * decides that it should throw out some unused stuff, then it begins - * by removing the resources with the highest counter (excluding locked - * resources and resources that are known to be in use). + * The id of the room (resp. the disk) the resource is contained in. + */ + byte _roomno; + + /** + * The offset (in bytes) where the data for this resources can be found + * in the game data file(s), relative to the start of the room the + * resource is contained in. + * + * A value of RES_INVALID_OFFSET indicates a resources that is not contained + * in the game data files. */ - byte *flags; + uint32 _roomoffs; /** - * Array of size _num containing the status of each resource of this type. - * This is a bitfield of which currently only one bit is used, which indicates - * whether the resource is modified. + * Occurs in HE 70+, but we don't use it for anything. */ - byte *_status; + uint32 _globsize; public: + Resource(); + ~Resource(); + + void nuke(); + + inline void setResourceCounter(byte counter); + inline byte getResourceCounter() const; + + void lock(); + void unlock(); + bool isLocked() const; + + void setModified(); + bool isModified() const; + }; + + /** + * This struct represents a resource type and all resource of that type. + */ + class ResTypeData { + friend class ResourceManager; + public: + ResTypeMode _mode; /** - * Array of size _num containing for each resource of this type the - * id of the room (resp. the disk) the resource is contained in. + * The maximal number of resource of this type. Determines the size + * of various arrays. */ - byte *roomno; + uint16 _num; /** - * Array of size _num containing room offsets of each resource of this type. - * That is the offset (in bytes) where the data for this resources - * can be found in the game data file(s), relative to the start - * of the room the resource is contained in. - * - * A value of RES_INVALID_OFFSET indicates a resources that is not contained - * in the game data files. + * The 4-byte tag or chunk type associated to this resource type, if any. + * Only applies to resources that are loaded from the game data files. */ - uint32 *roomoffs; + uint32 _tag; /** - * Array of size _num. Occurs in HE 70+, but we don't use it for anything. + * Array of size _num containing pointers to each resource of this type. */ - uint32 *globsize; + Common::Array<Resource> _resources; public: ResTypeData(); @@ -175,6 +194,9 @@ public: byte *createResource(int type, int idx, uint32 size); void nukeResource(int type, int idx); + inline Resource &getRes(int type, int idx) { return _types[type]._resources[idx]; } + inline const Resource &getRes(int type, int idx) const { return _types[type]._resources[idx]; } + bool isResourceLoaded(int type, int idx) const; void lock(int type, int idx); diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp index f86924821d..38dfa7c0ca 100644 --- a/engines/scumm/resource_v2.cpp +++ b/engines/scumm/resource_v2.cpp @@ -84,40 +84,40 @@ void ScummEngine_v2::readClassicIndexFile() { } for (i = 0; i < _numRooms; i++) { - _res->_types[rtRoom].roomno[i] = i; + _res->_types[rtRoom]._resources[i]._roomno = i; } _fileHandle->seek(_numRooms, SEEK_CUR); for (i = 0; i < _numRooms; i++) { - _res->_types[rtRoom].roomoffs[i] = _fileHandle->readUint16LE(); - if (_res->_types[rtRoom].roomoffs[i] == 0xFFFF) - _res->_types[rtRoom].roomoffs[i] = (uint32)RES_INVALID_OFFSET; + _res->_types[rtRoom]._resources[i]._roomoffs = _fileHandle->readUint16LE(); + if (_res->_types[rtRoom]._resources[i]._roomoffs == 0xFFFF) + _res->_types[rtRoom]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numCostumes; i++) { - _res->_types[rtCostume].roomno[i] = _fileHandle->readByte(); + _res->_types[rtCostume]._resources[i]._roomno = _fileHandle->readByte(); } for (i = 0; i < _numCostumes; i++) { - _res->_types[rtCostume].roomoffs[i] = _fileHandle->readUint16LE(); - if (_res->_types[rtCostume].roomoffs[i] == 0xFFFF) - _res->_types[rtCostume].roomoffs[i] = (uint32)RES_INVALID_OFFSET; + _res->_types[rtCostume]._resources[i]._roomoffs = _fileHandle->readUint16LE(); + if (_res->_types[rtCostume]._resources[i]._roomoffs == 0xFFFF) + _res->_types[rtCostume]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numScripts; i++) { - _res->_types[rtScript].roomno[i] = _fileHandle->readByte(); + _res->_types[rtScript]._resources[i]._roomno = _fileHandle->readByte(); } for (i = 0; i < _numScripts; i++) { - _res->_types[rtScript].roomoffs[i] = _fileHandle->readUint16LE(); - if (_res->_types[rtScript].roomoffs[i] == 0xFFFF) - _res->_types[rtScript].roomoffs[i] = (uint32)RES_INVALID_OFFSET; + _res->_types[rtScript]._resources[i]._roomoffs = _fileHandle->readUint16LE(); + if (_res->_types[rtScript]._resources[i]._roomoffs == 0xFFFF) + _res->_types[rtScript]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numSounds; i++) { - _res->_types[rtSound].roomno[i] = _fileHandle->readByte(); + _res->_types[rtSound]._resources[i]._roomno = _fileHandle->readByte(); } for (i = 0; i < _numSounds; i++) { - _res->_types[rtSound].roomoffs[i] = _fileHandle->readUint16LE(); - if (_res->_types[rtSound].roomoffs[i] == 0xFFFF) - _res->_types[rtSound].roomoffs[i] = (uint32)RES_INVALID_OFFSET; + _res->_types[rtSound]._resources[i]._roomoffs = _fileHandle->readUint16LE(); + if (_res->_types[rtSound]._resources[i]._roomoffs == 0xFFFF) + _res->_types[rtSound]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET; } } diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp index 3a8b1dd017..0f9f97ad16 100644 --- a/engines/scumm/resource_v3.cpp +++ b/engines/scumm/resource_v3.cpp @@ -44,16 +44,16 @@ int ScummEngine_v3old::readResTypeList(int id) { if (id == rtRoom) { for (i = 0; i < num; i++) - _res->_types[id].roomno[i] = i; + _res->_types[id]._resources[i]._roomno = i; _fileHandle->seek(num, SEEK_CUR); } else { for (i = 0; i < num; i++) - _res->_types[id].roomno[i] = _fileHandle->readByte(); + _res->_types[id]._resources[i]._roomno = _fileHandle->readByte(); } for (i = 0; i < num; i++) { - _res->_types[id].roomoffs[i] = _fileHandle->readUint16LE(); - if (_res->_types[id].roomoffs[i] == 0xFFFF) - _res->_types[id].roomoffs[i] = (uint32)RES_INVALID_OFFSET; + _res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint16LE(); + if (_res->_types[id]._resources[i]._roomoffs == 0xFFFF) + _res->_types[id]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET; } return num; diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp index 95eb8d4292..e7e6d30352 100644 --- a/engines/scumm/resource_v4.cpp +++ b/engines/scumm/resource_v4.cpp @@ -43,8 +43,8 @@ int ScummEngine_v4::readResTypeList(int id) { } for (i = 0; i < num; i++) { - _res->_types[id].roomno[i] = _fileHandle->readByte(); - _res->_types[id].roomoffs[i] = _fileHandle->readUint32LE(); + _res->_types[id]._resources[i]._roomno = _fileHandle->readByte(); + _res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint32LE(); } return num; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index d81095a37b..996e8685bb 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1247,7 +1247,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { s->saveUint16(type); // Save the res type... for (idx = 0; idx < _res->_types[type]._num; idx++) { // Only save resources which actually exist... - if (_res->_types[type]._address[idx]) { + if (_res->_types[type]._resources[idx]._address) { s->saveUint16(idx); // Save the index of the resource saveResource(s, type, idx); } @@ -1663,11 +1663,11 @@ void ScummEngine::loadResourceOLD(Serializer *ser, int type, int idx) { } void ScummEngine::saveResource(Serializer *ser, int type, int idx) { - assert(_res->_types[type]._address[idx]); + assert(_res->_types[type]._resources[idx]._address); if (_res->_types[type]._mode == kDynamicResTypeMode) { - byte *ptr = _res->_types[type]._address[idx]; - uint32 size = _res->_types[type]._size[idx]; + byte *ptr = _res->_types[type]._resources[idx]._address; + uint32 size = _res->_types[type]._resources[idx]._size; ser->saveUint32(size); ser->saveBytes(ptr, size); diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index e418fcd290..47cf8e024e 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -390,7 +390,7 @@ void ScummEngine::getScriptBaseAddress() { break; _scriptOrgPointer = getResourceAddress(rtInventory, idx); assert(idx < _numInventory); - _lastCodePtr = &_res->_types[rtInventory]._address[idx]; + _lastCodePtr = &_res->_types[rtInventory]._resources[idx]._address; break; case WIO_LOCAL: @@ -398,18 +398,18 @@ void ScummEngine::getScriptBaseAddress() { if (_game.version == 8) { _scriptOrgPointer = getResourceAddress(rtRoomScripts, _roomResource); assert(_roomResource < _res->_types[rtRoomScripts]._num); - _lastCodePtr = &_res->_types[rtRoomScripts]._address[_roomResource]; + _lastCodePtr = &_res->_types[rtRoomScripts]._resources[_roomResource]._address; } else { _scriptOrgPointer = getResourceAddress(rtRoom, _roomResource); assert(_roomResource < _numRooms); - _lastCodePtr = &_res->_types[rtRoom]._address[_roomResource]; + _lastCodePtr = &_res->_types[rtRoom]._resources[_roomResource]._address; } break; case WIO_GLOBAL: /* global script */ _scriptOrgPointer = getResourceAddress(rtScript, ss->number); assert(ss->number < _numScripts); - _lastCodePtr = &_res->_types[rtScript]._address[ss->number]; + _lastCodePtr = &_res->_types[rtScript]._resources[ss->number]._address; break; case WIO_FLOBJECT: /* flobject script */ @@ -418,7 +418,7 @@ void ScummEngine::getScriptBaseAddress() { idx = _objs[idx].fl_object_index; _scriptOrgPointer = getResourceAddress(rtFlObject, idx); assert(idx < _numFlObject); - _lastCodePtr = &_res->_types[rtFlObject]._address[idx]; + _lastCodePtr = &_res->_types[rtFlObject]._resources[idx]._address; break; default: error("Bad type while getting base address"); diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp index 138da3f921..341f6ecf5c 100644 --- a/engines/scumm/script_v6.cpp +++ b/engines/scumm/script_v6.cpp @@ -357,11 +357,11 @@ void ScummEngine_v6::nukeArray(int a) { } int ScummEngine_v6::findFreeArrayId() { - byte **addr = _res->_types[rtString]._address; + const ResourceManager::ResTypeData &rtd = _res->_types[rtString]; int i; for (i = 1; i < _numArray; i++) { - if (!addr[i]) + if (!rtd._resources[i]._address) return i; } error("Out of array pointers, %d max", _numArray); diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 21521d0fe6..f0b646157a 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1184,10 +1184,6 @@ Common::Error ScummEngine::init() { resetScumm(); resetScummVars(); - if (_imuse) { - _imuse->setBase(_res->_types[rtSound]._address); - } - if (_game.version >= 5 && _game.version <= 7) _sound->setupSound(); @@ -2461,10 +2457,6 @@ void ScummEngine::restart() { resetScumm(); resetScummVars(); - if (_imuse) { - _imuse->setBase(_res->_types[rtSound]._address); - } - // Reinit sound engine if (_game.version >= 5 && _game.version <= 7) _sound->setupSound(); diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index f5068e75d0..4a136f65d5 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -1224,7 +1224,7 @@ int ScummEngine::readSoundResource(int idx) { if (!dmuFile.open(buffer)) { error("Can't open music file %s", buffer); - _res->_types[rtSound].roomoffs[idx] = RES_INVALID_OFFSET; + _res->_types[rtSound]._resources[idx]._roomoffs = RES_INVALID_OFFSET; return 0; } dmuFile.seek(4, SEEK_SET); @@ -1248,7 +1248,7 @@ int ScummEngine::readSoundResource(int idx) { } error("Unrecognized base tag 0x%08x in sound %d", basetag, idx); } - _res->_types[rtSound].roomoffs[idx] = RES_INVALID_OFFSET; + _res->_types[rtSound]._resources[idx]._roomoffs = RES_INVALID_OFFSET; return 0; } @@ -2123,7 +2123,7 @@ int ScummEngine::readSoundResourceSmallHeader(int idx) { _fileHandle->read(_res->createResource(rtSound, idx, ro_size - 4), ro_size - 4); return 1; } - _res->_types[rtSound].roomoffs[idx] = RES_INVALID_OFFSET; + _res->_types[rtSound]._resources[idx]._roomoffs = RES_INVALID_OFFSET; return 0; } |