SCUMM: Add a Resource class, refactor res code around it
This commit is contained in:
parent
abaaf0cad9
commit
c02420df43
17 changed files with 228 additions and 205 deletions
|
@ -68,7 +68,7 @@ static const MD5Table *findInMD5Table(const char *md5) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String ScummEngine::generateFilename(const int room) const {
|
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];
|
char buf[128];
|
||||||
|
|
||||||
if (_game.version == 4) {
|
if (_game.version == 4) {
|
||||||
|
@ -110,7 +110,7 @@ Common::String ScummEngine_v60he::generateFilename(const int room) const {
|
||||||
if (room < 0) {
|
if (room < 0) {
|
||||||
id = '0' - room;
|
id = '0' - room;
|
||||||
} else {
|
} 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';
|
id = diskNumber + '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ void ScummEngine_v70he::readRoomsOffsets() {
|
||||||
num = READ_LE_UINT16(_heV7RoomOffsets);
|
num = READ_LE_UINT16(_heV7RoomOffsets);
|
||||||
ptr = _heV7RoomOffsets + 2;
|
ptr = _heV7RoomOffsets + 2;
|
||||||
for (i = 0; i < num; i++) {
|
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;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,11 +621,11 @@ void ScummEngine_v72he::o72_getArrayDimSize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScummEngine_v72he::o72_getNumFreeArrays() {
|
void ScummEngine_v72he::o72_getNumFreeArrays() {
|
||||||
byte **addr = _res->_types[rtString]._address;
|
const ResourceManager::ResTypeData &rtd = _res->_types[rtString];
|
||||||
int i, num = 0;
|
int i, num = 0;
|
||||||
|
|
||||||
for (i = 1; i < _numArray; i++) {
|
for (i = 1; i < _numArray; i++) {
|
||||||
if (!addr[i])
|
if (!rtd._resources[i]._address)
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "scumm/imuse/imuse.h"
|
#include "scumm/imuse/imuse.h"
|
||||||
#include "scumm/imuse/imuse_internal.h"
|
#include "scumm/imuse/imuse_internal.h"
|
||||||
#include "scumm/imuse/instrument.h"
|
#include "scumm/imuse/instrument.h"
|
||||||
|
#include "scumm/resource.h"
|
||||||
#include "scumm/saveload.h"
|
#include "scumm/saveload.h"
|
||||||
#include "scumm/scumm.h"
|
#include "scumm/scumm.h"
|
||||||
|
|
||||||
|
@ -47,7 +48,6 @@ _enable_gs(false),
|
||||||
_sc55(false),
|
_sc55(false),
|
||||||
_midi_adlib(NULL),
|
_midi_adlib(NULL),
|
||||||
_midi_native(NULL),
|
_midi_native(NULL),
|
||||||
_base_sounds(NULL),
|
|
||||||
_sysex(NULL),
|
_sysex(NULL),
|
||||||
_paused(false),
|
_paused(false),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
|
@ -100,11 +100,9 @@ IMuseInternal::~IMuseInternal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *IMuseInternal::findStartOfSound(int sound) {
|
byte *IMuseInternal::findStartOfSound(int sound) {
|
||||||
byte *ptr = NULL;
|
|
||||||
int32 size, pos;
|
int32 size, pos;
|
||||||
|
|
||||||
if (_base_sounds)
|
byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address;
|
||||||
ptr = _base_sounds[sound];
|
|
||||||
|
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
debug(1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist", sound);
|
debug(1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist", sound);
|
||||||
|
@ -136,16 +134,11 @@ byte *IMuseInternal::findStartOfSound(int sound) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IMuseInternal::isMT32(int sound) {
|
bool IMuseInternal::isMT32(int sound) {
|
||||||
byte *ptr = NULL;
|
byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address;
|
||||||
uint32 tag;
|
|
||||||
|
|
||||||
if (_base_sounds)
|
|
||||||
ptr = _base_sounds[sound];
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tag = READ_BE_UINT32(ptr);
|
uint32 tag = READ_BE_UINT32(ptr);
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case MKTAG('A','D','L',' '):
|
case MKTAG('A','D','L',' '):
|
||||||
case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects
|
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) {
|
bool IMuseInternal::isMIDI(int sound) {
|
||||||
byte *ptr = NULL;
|
byte *ptr = g_scumm->_res->_types[rtSound]._resources[sound]._address;
|
||||||
uint32 tag;
|
|
||||||
|
|
||||||
if (_base_sounds)
|
|
||||||
ptr = _base_sounds[sound];
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tag = READ_BE_UINT32(ptr);
|
uint32 tag = READ_BE_UINT32(ptr);
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case MKTAG('A','D','L',' '):
|
case MKTAG('A','D','L',' '):
|
||||||
case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects
|
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);
|
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) {
|
uint32 IMuseInternal::property(int prop, uint32 value) {
|
||||||
Common::StackLock lock(_mutex, "IMuseInternal::property()");
|
Common::StackLock lock(_mutex, "IMuseInternal::property()");
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
|
|
|
@ -65,7 +65,6 @@ public:
|
||||||
virtual bool get_sound_active(int sound) const = 0;
|
virtual bool get_sound_active(int sound) const = 0;
|
||||||
virtual int32 doCommand(int numargs, int args[]) = 0;
|
virtual int32 doCommand(int numargs, int args[]) = 0;
|
||||||
virtual int clear_queue() = 0;
|
virtual int clear_queue() = 0;
|
||||||
virtual void setBase(byte **base) = 0;
|
|
||||||
virtual uint32 property(int prop, uint32 value) = 0;
|
virtual uint32 property(int prop, uint32 value) = 0;
|
||||||
virtual void addSysexHandler (byte mfgID, sysexfunc handler) = 0;
|
virtual void addSysexHandler (byte mfgID, sysexfunc handler) = 0;
|
||||||
|
|
||||||
|
|
|
@ -394,7 +394,6 @@ protected:
|
||||||
TimerCallbackInfo _timer_info_native;
|
TimerCallbackInfo _timer_info_native;
|
||||||
|
|
||||||
uint32 _game_id;
|
uint32 _game_id;
|
||||||
byte **_base_sounds;
|
|
||||||
|
|
||||||
// Plug-in SysEx handling. Right now this only supports one
|
// Plug-in SysEx handling. Right now this only supports one
|
||||||
// custom SysEx handler for the hardcoded IMUSE_SYSEX_ID
|
// custom SysEx handler for the hardcoded IMUSE_SYSEX_ID
|
||||||
|
@ -510,7 +509,6 @@ public:
|
||||||
int save_or_load(Serializer *ser, ScummEngine *scumm);
|
int save_or_load(Serializer *ser, ScummEngine *scumm);
|
||||||
bool get_sound_active(int sound) const;
|
bool get_sound_active(int sound) const;
|
||||||
int32 doCommand(int numargs, int args[]);
|
int32 doCommand(int numargs, int args[]);
|
||||||
void setBase(byte **base);
|
|
||||||
uint32 property(int prop, uint32 value);
|
uint32 property(int prop, uint32 value);
|
||||||
virtual void addSysexHandler(byte mfgID, sysexfunc handler);
|
virtual void addSysexHandler(byte mfgID, sysexfunc handler);
|
||||||
|
|
||||||
|
|
|
@ -193,10 +193,10 @@ void ScummEngine::clearOwnerOf(int obj) {
|
||||||
_inventory[i] = _inventory[i+1];
|
_inventory[i] = _inventory[i+1];
|
||||||
_inventory[i+1] = 0;
|
_inventory[i+1] = 0;
|
||||||
// FIXME FIXME FIXME: This is incomplete, as we do not touch flags, status... BUG
|
// 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]._resources[i]._address = _res->_types[rtInventory]._resources[i + 1]._address;
|
||||||
_res->_types[rtInventory]._size[i] = _res->_types[rtInventory]._size[i + 1];
|
_res->_types[rtInventory]._resources[i]._size = _res->_types[rtInventory]._resources[i + 1]._size;
|
||||||
_res->_types[rtInventory]._address[i + 1] = NULL;
|
_res->_types[rtInventory]._resources[i + 1]._address = NULL;
|
||||||
_res->_types[rtInventory]._size[i + 1] = 0;
|
_res->_types[rtInventory]._resources[i + 1]._size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1799,7 +1799,7 @@ int ScummEngine::findLocalObjectSlot() {
|
||||||
int ScummEngine::findFlObjectSlot() {
|
int ScummEngine::findFlObjectSlot() {
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < _numFlObject; i++) {
|
for (i = 1; i < _numFlObject; i++) {
|
||||||
if (_res->_types[rtFlObject]._address[i] == NULL)
|
if (_res->_types[rtFlObject]._resources[i]._address == NULL)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
error("findFlObjectSlot: Out of FLObject slots");
|
error("findFlObjectSlot: Out of FLObject slots");
|
||||||
|
|
|
@ -83,8 +83,8 @@ void ScummEngine::openRoom(const int room) {
|
||||||
// Load the disk numer / room offs (special case for room 0 exists because
|
// 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
|
// 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.
|
// tables -- hence obviously we mustn't use those when loading room 0.
|
||||||
const uint32 diskNumber = room ? _res->_types[rtRoom].roomno[room] : 0;
|
const uint32 diskNumber = room ? _res->_types[rtRoom]._resources[room]._roomno : 0;
|
||||||
const uint32 room_offs = room ? _res->_types[rtRoom].roomoffs[room] : 0;
|
const uint32 room_offs = room ? _res->_types[rtRoom]._resources[room]._roomoffs : 0;
|
||||||
|
|
||||||
// FIXME: Since room_offs is const, clearly the following loop either
|
// 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
|
// 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) {
|
while (room_offs != RES_INVALID_OFFSET) {
|
||||||
|
|
||||||
if (room_offs != 0 && room != 0 && _game.heversion < 98) {
|
if (room_offs != 0 && room != 0 && _game.heversion < 98) {
|
||||||
_fileOffset = _res->_types[rtRoom].roomoffs[room];
|
_fileOffset = _res->_types[rtRoom]._resources[room]._roomoffs;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ void ScummEngine::openRoom(const int room) {
|
||||||
return;
|
return;
|
||||||
deleteRoomOffsets();
|
deleteRoomOffsets();
|
||||||
readRoomsOffsets();
|
readRoomsOffsets();
|
||||||
_fileOffset = _res->_types[rtRoom].roomoffs[room];
|
_fileOffset = _res->_types[rtRoom]._resources[room]._roomoffs;
|
||||||
|
|
||||||
if (_fileOffset != 8)
|
if (_fileOffset != 8)
|
||||||
return;
|
return;
|
||||||
|
@ -157,8 +157,8 @@ void ScummEngine::closeRoom() {
|
||||||
/** Delete the currently loaded room offsets. */
|
/** Delete the currently loaded room offsets. */
|
||||||
void ScummEngine::deleteRoomOffsets() {
|
void ScummEngine::deleteRoomOffsets() {
|
||||||
for (int i = 0; i < _numRooms; i++) {
|
for (int i = 0; i < _numRooms; i++) {
|
||||||
if (_res->_types[rtRoom].roomoffs[i] != RES_INVALID_OFFSET)
|
if (_res->_types[rtRoom]._resources[i]._roomoffs != RES_INVALID_OFFSET)
|
||||||
_res->_types[rtRoom].roomoffs[i] = 0;
|
_res->_types[rtRoom]._resources[i]._roomoffs = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +174,8 @@ void ScummEngine::readRoomsOffsets() {
|
||||||
while (num--) {
|
while (num--) {
|
||||||
int room = _fileHandle->readByte();
|
int room = _fileHandle->readByte();
|
||||||
int offset = _fileHandle->readUint32LE();
|
int offset = _fileHandle->readUint32LE();
|
||||||
if (_res->_types[rtRoom].roomoffs[room] != RES_INVALID_OFFSET) {
|
if (_res->_types[rtRoom]._resources[room]._roomoffs != RES_INVALID_OFFSET) {
|
||||||
_res->_types[rtRoom].roomoffs[room] = offset;
|
_res->_types[rtRoom]._resources[room]._roomoffs = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,10 +499,10 @@ int ScummEngine::readResTypeList(int id) {
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
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++) {
|
for (i = 0; i < num; i++) {
|
||||||
_res->_types[id].roomoffs[i] = _fileHandle->readUint32LE();
|
_res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint32LE();
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
@ -516,11 +516,11 @@ int ScummEngine_v70he::readResTypeList(int id) {
|
||||||
|
|
||||||
if (id == rtRoom)
|
if (id == rtRoom)
|
||||||
for (i = 0; i < num; i++) {
|
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++) {
|
for (i = 0; i < num; i++) {
|
||||||
_res->_types[id].globsize[i] = _fileHandle->readUint32LE();
|
_res->_types[id]._resources[i]._globsize = _fileHandle->readUint32LE();
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
@ -536,11 +536,11 @@ void ResourceManager::allocResTypeData(int id, uint32 tag, int num, ResTypeMode
|
||||||
_types[id]._mode = mode;
|
_types[id]._mode = mode;
|
||||||
_types[id]._num = num;
|
_types[id]._num = num;
|
||||||
_types[id]._tag = tag;
|
_types[id]._tag = tag;
|
||||||
_types[id]._address = (byte **)calloc(num, sizeof(byte *));
|
_types[id]._resources.resize(num);
|
||||||
_types[id]._size = (uint32 *)calloc(num, sizeof(uint32));
|
|
||||||
_types[id].flags = (byte *)calloc(num, sizeof(byte));
|
|
||||||
_types[id]._status = (byte *)calloc(num, sizeof(byte));
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Use multiple Resource subclasses, one for each res mode; then,
|
||||||
|
given them serializability.
|
||||||
if (mode) {
|
if (mode) {
|
||||||
_types[id].roomno = (byte *)calloc(num, sizeof(byte));
|
_types[id].roomno = (byte *)calloc(num, sizeof(byte));
|
||||||
_types[id].roomoffs = (uint32 *)calloc(num, sizeof(uint32));
|
_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) {
|
if (_vm->_game.heversion >= 70) {
|
||||||
_types[id].globsize = (uint32 *)calloc(num, sizeof(uint32));
|
_types[id].globsize = (uint32 *)calloc(num, sizeof(uint32));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScummEngine::loadCharset(int no) {
|
void ScummEngine::loadCharset(int no) {
|
||||||
|
@ -604,7 +604,7 @@ void ScummEngine::ensureResourceLoaded(int type, int i) {
|
||||||
if (type != rtCharset && i == 0)
|
if (type != rtCharset && i == 0)
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
loadResource(type, i);
|
loadResource(type, i);
|
||||||
|
@ -690,27 +690,27 @@ int ScummEngine::loadResource(int type, int idx) {
|
||||||
int ScummEngine::getResourceRoomNr(int type, int idx) {
|
int ScummEngine::getResourceRoomNr(int type, int idx) {
|
||||||
if (type == rtRoom && _game.heversion < 70)
|
if (type == rtRoom && _game.heversion < 70)
|
||||||
return idx;
|
return idx;
|
||||||
return _res->_types[type].roomno[idx];
|
return _res->_types[type]._resources[idx]._roomno;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ScummEngine::getResourceRoomOffset(int type, int idx) {
|
uint32 ScummEngine::getResourceRoomOffset(int type, int idx) {
|
||||||
if (type == rtRoom) {
|
if (type == rtRoom) {
|
||||||
return (_game.version == 8) ? 8 : 0;
|
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) {
|
uint32 ScummEngine_v70he::getResourceRoomOffset(int type, int idx) {
|
||||||
if (type == rtRoom) {
|
if (type == rtRoom) {
|
||||||
return _heV7RoomIntOffsets[idx];
|
return _heV7RoomIntOffsets[idx];
|
||||||
}
|
}
|
||||||
return _res->_types[type].roomoffs[idx];
|
return _res->_types[type]._resources[idx]._roomoffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScummEngine::getResourceSize(int type, int idx) {
|
int ScummEngine::getResourceSize(int type, int idx) {
|
||||||
byte *ptr = getResourceAddress(type, idx);
|
byte *ptr = getResourceAddress(type, idx);
|
||||||
assert(ptr);
|
assert(ptr);
|
||||||
return _res->_types[type]._size[idx];
|
return _res->_types[type]._resources[idx]._size;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *ScummEngine::getResourceAddress(int type, int idx) {
|
byte *ScummEngine::getResourceAddress(int type, int idx) {
|
||||||
|
@ -722,17 +722,12 @@ byte *ScummEngine::getResourceAddress(int type, int idx) {
|
||||||
if (!_res->validateResource("getResourceAddress", type, idx))
|
if (!_res->validateResource("getResourceAddress", type, idx))
|
||||||
return NULL;
|
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 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);
|
ensureResourceLoaded(type, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = (byte *)_res->_types[type]._address[idx];
|
ptr = (byte *)_res->_types[type]._resources[idx]._address;
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx);
|
debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -774,7 +769,7 @@ void ResourceManager::increaseResourceCounters() {
|
||||||
|
|
||||||
for (i = rtFirst; i <= rtLast; i++) {
|
for (i = rtFirst; i <= rtLast; i++) {
|
||||||
for (j = _types[i]._num; --j >= 0;) {
|
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) {
|
if (counter && counter < RF_USAGE_MAX) {
|
||||||
setResourceCounter(i, j, counter + 1);
|
setResourceCounter(i, j, counter + 1);
|
||||||
}
|
}
|
||||||
|
@ -783,8 +778,16 @@ void ResourceManager::increaseResourceCounters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::setResourceCounter(int type, int idx, byte counter) {
|
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]._resources[idx].setResourceCounter(counter);
|
||||||
_types[type].flags[idx] |= counter; // Update the usage 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 */
|
/* 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
|
// cases. For instance, Zak tries to reload the intro music
|
||||||
// while it's playing. See bug #1253171.
|
// while it's playing. See bug #1253171.
|
||||||
|
|
||||||
if (_types[type]._address[idx] && (type == rtSound || type == rtScript || type == rtCostume))
|
if (_types[type]._resources[idx]._address && (type == rtSound || type == rtScript || type == rtCostume))
|
||||||
return _types[type]._address[idx];
|
return _types[type]._resources[idx]._address;
|
||||||
}
|
}
|
||||||
|
|
||||||
nukeResource(type, idx);
|
nukeResource(type, idx);
|
||||||
|
@ -816,14 +819,39 @@ byte *ResourceManager::createResource(int type, int idx, uint32 size) {
|
||||||
|
|
||||||
_allocatedSize += size;
|
_allocatedSize += size;
|
||||||
|
|
||||||
_types[type]._address[idx] = ptr;
|
_types[type]._resources[idx]._address = ptr;
|
||||||
_types[type]._size[idx] = size;
|
_types[type]._resources[idx]._size = size;
|
||||||
setResourceCounter(type, idx, 1);
|
setResourceCounter(type, idx, 1);
|
||||||
return ptr;
|
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() {
|
ResourceManager::ResTypeData::ResTypeData() {
|
||||||
memset(this, 0, sizeof(*this));
|
_mode = kDynamicResTypeMode;
|
||||||
|
_num = 0;
|
||||||
|
_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager::ResTypeData::~ResTypeData() {
|
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) {
|
void ResourceManager::nukeResource(int type, int idx) {
|
||||||
byte *ptr;
|
byte *ptr = _types[type]._resources[idx]._address;
|
||||||
|
|
||||||
if (!_types[type]._address)
|
|
||||||
return;
|
|
||||||
|
|
||||||
assert(idx >= 0 && idx < _types[type]._num);
|
|
||||||
|
|
||||||
ptr = _types[type]._address[idx];
|
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
debugC(DEBUG_RESOURCE, "nukeResource(%s,%d)", resTypeFromId(type), idx);
|
debugC(DEBUG_RESOURCE, "nukeResource(%s,%d)", resTypeFromId(type), idx);
|
||||||
_types[type]._address[idx] = 0;
|
_allocatedSize -= _types[type]._resources[idx]._size;
|
||||||
_types[type]._size[idx] = 0;
|
_types[type]._resources[idx].nuke();
|
||||||
_types[type].flags[idx] = 0;
|
|
||||||
_types[type]._status[idx] &= ~RS_MODIFIED;
|
|
||||||
_allocatedSize -= _types[type]._size[idx];
|
|
||||||
free(ptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,19 +920,31 @@ int ScummEngine::getResourceDataSize(const byte *ptr) const {
|
||||||
void ResourceManager::lock(int type, int i) {
|
void ResourceManager::lock(int type, int i) {
|
||||||
if (!validateResource("Locking", type, i))
|
if (!validateResource("Locking", type, i))
|
||||||
return;
|
return;
|
||||||
_types[type].flags[i] |= RF_LOCK;
|
_types[type]._resources[i].lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::unlock(int type, int i) {
|
void ResourceManager::unlock(int type, int i) {
|
||||||
if (!validateResource("Unlocking", type, i))
|
if (!validateResource("Unlocking", type, i))
|
||||||
return;
|
return;
|
||||||
_types[type].flags[i] &= ~RF_LOCK;
|
_types[type]._resources[i].unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::isLocked(int type, int i) const {
|
bool ResourceManager::isLocked(int type, int i) const {
|
||||||
if (!validateResource("isLocked", type, i))
|
if (!validateResource("isLocked", type, i))
|
||||||
return false;
|
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 {
|
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) {
|
void ResourceManager::setModified(int type, int i) {
|
||||||
if (!validateResource("Modified", type, i))
|
if (!validateResource("Modified", type, i))
|
||||||
return;
|
return;
|
||||||
_types[type]._status[i] |= RS_MODIFIED;
|
_types[type]._resources[i].setModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::isModified(int type, int i) const {
|
bool ResourceManager::isModified(int type, int i) const {
|
||||||
if (!validateResource("isModified", type, i))
|
if (!validateResource("isModified", type, i))
|
||||||
return false;
|
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) {
|
void ResourceManager::expireResources(uint32 size) {
|
||||||
int i, j;
|
int i, j;
|
||||||
byte flag;
|
|
||||||
byte best_counter;
|
byte best_counter;
|
||||||
int best_type, best_res = 0;
|
int best_type, best_res = 0;
|
||||||
uint32 oldAllocatedSize;
|
uint32 oldAllocatedSize;
|
||||||
|
@ -987,9 +1023,10 @@ void ResourceManager::expireResources(uint32 size) {
|
||||||
// Resources of this type can be reloaded from the data files,
|
// Resources of this type can be reloaded from the data files,
|
||||||
// so we can potentially unload them to free memory.
|
// so we can potentially unload them to free memory.
|
||||||
for (j = _types[i]._num; --j >= 0;) {
|
for (j = _types[i]._num; --j >= 0;) {
|
||||||
flag = _types[i].flags[j];
|
Resource &tmp = _types[i]._resources[j];
|
||||||
if (!(flag & RF_LOCK) && flag >= best_counter && _types[i]._address[j] && !_vm->isResourceInUse(i, j)) {
|
byte counter = tmp.getResourceCounter();
|
||||||
best_counter = flag;
|
if (!tmp.isLocked() && counter >= best_counter && tmp._address && !_vm->isResourceInUse(i, j)) {
|
||||||
|
best_counter = counter;
|
||||||
best_type = i;
|
best_type = i;
|
||||||
best_res = j;
|
best_res = j;
|
||||||
}
|
}
|
||||||
|
@ -1013,14 +1050,7 @@ void ResourceManager::freeResources() {
|
||||||
if (isResourceLoaded(i, j))
|
if (isResourceLoaded(i, j))
|
||||||
nukeResource(i, j);
|
nukeResource(i, j);
|
||||||
}
|
}
|
||||||
free(_types[i]._address);
|
_types[i]._resources.clear();
|
||||||
free(_types[i]._size);
|
|
||||||
free(_types[i].flags);
|
|
||||||
free(_types[i]._status);
|
|
||||||
free(_types[i].roomno);
|
|
||||||
free(_types[i].roomoffs);
|
|
||||||
|
|
||||||
free(_types[i].globsize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,19 +1081,18 @@ void ScummEngine::loadPtrToResource(int type, int resindex, const byte *source)
|
||||||
bool ResourceManager::isResourceLoaded(int type, int idx) const {
|
bool ResourceManager::isResourceLoaded(int type, int idx) const {
|
||||||
if (!validateResource("isResourceLoaded", type, idx))
|
if (!validateResource("isResourceLoaded", type, idx))
|
||||||
return false;
|
return false;
|
||||||
return _types[type]._address[idx] != NULL;
|
return _types[type]._resources[idx]._address != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::resourceStats() {
|
void ResourceManager::resourceStats() {
|
||||||
int i, j;
|
int i, j;
|
||||||
uint32 lockedSize = 0, lockedNum = 0;
|
uint32 lockedSize = 0, lockedNum = 0;
|
||||||
byte flag;
|
|
||||||
|
|
||||||
for (i = rtFirst; i <= rtLast; i++)
|
for (i = rtFirst; i <= rtLast; i++)
|
||||||
for (j = _types[i]._num; --j >= 0;) {
|
for (j = _types[i]._num; --j >= 0;) {
|
||||||
flag = _types[i].flags[j];
|
Resource &tmp = _types[i]._resources[j];
|
||||||
if (flag & RF_LOCK && _types[i]._address[j]) {
|
if (tmp.isLocked() && tmp._address) {
|
||||||
lockedSize += _types[i]._size[j];
|
lockedSize += tmp._size;
|
||||||
lockedNum++;
|
lockedNum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ifndef SCUMM_RESOURCE_H
|
#ifndef SCUMM_RESOURCE_H
|
||||||
#define SCUMM_RESOURCE_H
|
#define SCUMM_RESOURCE_H
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
#include "scumm/scumm.h" // for rtNumTypes
|
#include "scumm/scumm.h" // for rtNumTypes
|
||||||
|
|
||||||
namespace Scumm {
|
namespace Scumm {
|
||||||
|
@ -78,6 +79,74 @@ protected:
|
||||||
ScummEngine *_vm;
|
ScummEngine *_vm;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
class Resource {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Pointer to the data contained in this resource
|
||||||
|
*/
|
||||||
|
byte *_address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of this resource, i.e. of the data contained in it.
|
||||||
|
*/
|
||||||
|
uint32 _size;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* 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 _flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of the resource. Currently only one bit is used, which
|
||||||
|
* indicates whether the resource is modified.
|
||||||
|
*/
|
||||||
|
byte _status;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
uint32 _roomoffs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occurs in HE 70+, but we don't use it for anything.
|
||||||
|
*/
|
||||||
|
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.
|
* This struct represents a resource type and all resource of that type.
|
||||||
*/
|
*/
|
||||||
|
@ -100,57 +169,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Array of size _num containing pointers to each resource of this type.
|
* Array of size _num containing pointers to each resource of this type.
|
||||||
*/
|
*/
|
||||||
byte **_address;
|
Common::Array<Resource> _resources;
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of size _num containing the sizes of each resource of this type.
|
|
||||||
*/
|
|
||||||
uint32 *_size;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* 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).
|
|
||||||
*/
|
|
||||||
byte *flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
byte *_status;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Array of size _num containing for each resource of this type the
|
|
||||||
* id of the room (resp. the disk) the resource is contained in.
|
|
||||||
*/
|
|
||||||
byte *roomno;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
uint32 *roomoffs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of size _num. Occurs in HE 70+, but we don't use it for anything.
|
|
||||||
*/
|
|
||||||
uint32 *globsize;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResTypeData();
|
ResTypeData();
|
||||||
|
@ -175,6 +194,9 @@ public:
|
||||||
byte *createResource(int type, int idx, uint32 size);
|
byte *createResource(int type, int idx, uint32 size);
|
||||||
void nukeResource(int type, int idx);
|
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;
|
bool isResourceLoaded(int type, int idx) const;
|
||||||
|
|
||||||
void lock(int type, int idx);
|
void lock(int type, int idx);
|
||||||
|
|
|
@ -84,40 +84,40 @@ void ScummEngine_v2::readClassicIndexFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _numRooms; i++) {
|
for (i = 0; i < _numRooms; i++) {
|
||||||
_res->_types[rtRoom].roomno[i] = i;
|
_res->_types[rtRoom]._resources[i]._roomno = i;
|
||||||
}
|
}
|
||||||
_fileHandle->seek(_numRooms, SEEK_CUR);
|
_fileHandle->seek(_numRooms, SEEK_CUR);
|
||||||
for (i = 0; i < _numRooms; i++) {
|
for (i = 0; i < _numRooms; i++) {
|
||||||
_res->_types[rtRoom].roomoffs[i] = _fileHandle->readUint16LE();
|
_res->_types[rtRoom]._resources[i]._roomoffs = _fileHandle->readUint16LE();
|
||||||
if (_res->_types[rtRoom].roomoffs[i] == 0xFFFF)
|
if (_res->_types[rtRoom]._resources[i]._roomoffs == 0xFFFF)
|
||||||
_res->_types[rtRoom].roomoffs[i] = (uint32)RES_INVALID_OFFSET;
|
_res->_types[rtRoom]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _numCostumes; i++) {
|
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++) {
|
for (i = 0; i < _numCostumes; i++) {
|
||||||
_res->_types[rtCostume].roomoffs[i] = _fileHandle->readUint16LE();
|
_res->_types[rtCostume]._resources[i]._roomoffs = _fileHandle->readUint16LE();
|
||||||
if (_res->_types[rtCostume].roomoffs[i] == 0xFFFF)
|
if (_res->_types[rtCostume]._resources[i]._roomoffs == 0xFFFF)
|
||||||
_res->_types[rtCostume].roomoffs[i] = (uint32)RES_INVALID_OFFSET;
|
_res->_types[rtCostume]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _numScripts; i++) {
|
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++) {
|
for (i = 0; i < _numScripts; i++) {
|
||||||
_res->_types[rtScript].roomoffs[i] = _fileHandle->readUint16LE();
|
_res->_types[rtScript]._resources[i]._roomoffs = _fileHandle->readUint16LE();
|
||||||
if (_res->_types[rtScript].roomoffs[i] == 0xFFFF)
|
if (_res->_types[rtScript]._resources[i]._roomoffs == 0xFFFF)
|
||||||
_res->_types[rtScript].roomoffs[i] = (uint32)RES_INVALID_OFFSET;
|
_res->_types[rtScript]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _numSounds; i++) {
|
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++) {
|
for (i = 0; i < _numSounds; i++) {
|
||||||
_res->_types[rtSound].roomoffs[i] = _fileHandle->readUint16LE();
|
_res->_types[rtSound]._resources[i]._roomoffs = _fileHandle->readUint16LE();
|
||||||
if (_res->_types[rtSound].roomoffs[i] == 0xFFFF)
|
if (_res->_types[rtSound]._resources[i]._roomoffs == 0xFFFF)
|
||||||
_res->_types[rtSound].roomoffs[i] = (uint32)RES_INVALID_OFFSET;
|
_res->_types[rtSound]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,16 +44,16 @@ int ScummEngine_v3old::readResTypeList(int id) {
|
||||||
|
|
||||||
if (id == rtRoom) {
|
if (id == rtRoom) {
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
_res->_types[id].roomno[i] = i;
|
_res->_types[id]._resources[i]._roomno = i;
|
||||||
_fileHandle->seek(num, SEEK_CUR);
|
_fileHandle->seek(num, SEEK_CUR);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < num; i++)
|
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++) {
|
for (i = 0; i < num; i++) {
|
||||||
_res->_types[id].roomoffs[i] = _fileHandle->readUint16LE();
|
_res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint16LE();
|
||||||
if (_res->_types[id].roomoffs[i] == 0xFFFF)
|
if (_res->_types[id]._resources[i]._roomoffs == 0xFFFF)
|
||||||
_res->_types[id].roomoffs[i] = (uint32)RES_INVALID_OFFSET;
|
_res->_types[id]._resources[i]._roomoffs = (uint32)RES_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
|
|
@ -43,8 +43,8 @@ int ScummEngine_v4::readResTypeList(int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
_res->_types[id].roomno[i] = _fileHandle->readByte();
|
_res->_types[id]._resources[i]._roomno = _fileHandle->readByte();
|
||||||
_res->_types[id].roomoffs[i] = _fileHandle->readUint32LE();
|
_res->_types[id]._resources[i]._roomoffs = _fileHandle->readUint32LE();
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
|
|
@ -1247,7 +1247,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
|
||||||
s->saveUint16(type); // Save the res type...
|
s->saveUint16(type); // Save the res type...
|
||||||
for (idx = 0; idx < _res->_types[type]._num; idx++) {
|
for (idx = 0; idx < _res->_types[type]._num; idx++) {
|
||||||
// Only save resources which actually exist...
|
// 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
|
s->saveUint16(idx); // Save the index of the resource
|
||||||
saveResource(s, type, idx);
|
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) {
|
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) {
|
if (_res->_types[type]._mode == kDynamicResTypeMode) {
|
||||||
byte *ptr = _res->_types[type]._address[idx];
|
byte *ptr = _res->_types[type]._resources[idx]._address;
|
||||||
uint32 size = _res->_types[type]._size[idx];
|
uint32 size = _res->_types[type]._resources[idx]._size;
|
||||||
|
|
||||||
ser->saveUint32(size);
|
ser->saveUint32(size);
|
||||||
ser->saveBytes(ptr, size);
|
ser->saveBytes(ptr, size);
|
||||||
|
|
|
@ -390,7 +390,7 @@ void ScummEngine::getScriptBaseAddress() {
|
||||||
break;
|
break;
|
||||||
_scriptOrgPointer = getResourceAddress(rtInventory, idx);
|
_scriptOrgPointer = getResourceAddress(rtInventory, idx);
|
||||||
assert(idx < _numInventory);
|
assert(idx < _numInventory);
|
||||||
_lastCodePtr = &_res->_types[rtInventory]._address[idx];
|
_lastCodePtr = &_res->_types[rtInventory]._resources[idx]._address;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WIO_LOCAL:
|
case WIO_LOCAL:
|
||||||
|
@ -398,18 +398,18 @@ void ScummEngine::getScriptBaseAddress() {
|
||||||
if (_game.version == 8) {
|
if (_game.version == 8) {
|
||||||
_scriptOrgPointer = getResourceAddress(rtRoomScripts, _roomResource);
|
_scriptOrgPointer = getResourceAddress(rtRoomScripts, _roomResource);
|
||||||
assert(_roomResource < _res->_types[rtRoomScripts]._num);
|
assert(_roomResource < _res->_types[rtRoomScripts]._num);
|
||||||
_lastCodePtr = &_res->_types[rtRoomScripts]._address[_roomResource];
|
_lastCodePtr = &_res->_types[rtRoomScripts]._resources[_roomResource]._address;
|
||||||
} else {
|
} else {
|
||||||
_scriptOrgPointer = getResourceAddress(rtRoom, _roomResource);
|
_scriptOrgPointer = getResourceAddress(rtRoom, _roomResource);
|
||||||
assert(_roomResource < _numRooms);
|
assert(_roomResource < _numRooms);
|
||||||
_lastCodePtr = &_res->_types[rtRoom]._address[_roomResource];
|
_lastCodePtr = &_res->_types[rtRoom]._resources[_roomResource]._address;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WIO_GLOBAL: /* global script */
|
case WIO_GLOBAL: /* global script */
|
||||||
_scriptOrgPointer = getResourceAddress(rtScript, ss->number);
|
_scriptOrgPointer = getResourceAddress(rtScript, ss->number);
|
||||||
assert(ss->number < _numScripts);
|
assert(ss->number < _numScripts);
|
||||||
_lastCodePtr = &_res->_types[rtScript]._address[ss->number];
|
_lastCodePtr = &_res->_types[rtScript]._resources[ss->number]._address;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WIO_FLOBJECT: /* flobject script */
|
case WIO_FLOBJECT: /* flobject script */
|
||||||
|
@ -418,7 +418,7 @@ void ScummEngine::getScriptBaseAddress() {
|
||||||
idx = _objs[idx].fl_object_index;
|
idx = _objs[idx].fl_object_index;
|
||||||
_scriptOrgPointer = getResourceAddress(rtFlObject, idx);
|
_scriptOrgPointer = getResourceAddress(rtFlObject, idx);
|
||||||
assert(idx < _numFlObject);
|
assert(idx < _numFlObject);
|
||||||
_lastCodePtr = &_res->_types[rtFlObject]._address[idx];
|
_lastCodePtr = &_res->_types[rtFlObject]._resources[idx]._address;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Bad type while getting base address");
|
error("Bad type while getting base address");
|
||||||
|
|
|
@ -357,11 +357,11 @@ void ScummEngine_v6::nukeArray(int a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScummEngine_v6::findFreeArrayId() {
|
int ScummEngine_v6::findFreeArrayId() {
|
||||||
byte **addr = _res->_types[rtString]._address;
|
const ResourceManager::ResTypeData &rtd = _res->_types[rtString];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < _numArray; i++) {
|
for (i = 1; i < _numArray; i++) {
|
||||||
if (!addr[i])
|
if (!rtd._resources[i]._address)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
error("Out of array pointers, %d max", _numArray);
|
error("Out of array pointers, %d max", _numArray);
|
||||||
|
|
|
@ -1184,10 +1184,6 @@ Common::Error ScummEngine::init() {
|
||||||
resetScumm();
|
resetScumm();
|
||||||
resetScummVars();
|
resetScummVars();
|
||||||
|
|
||||||
if (_imuse) {
|
|
||||||
_imuse->setBase(_res->_types[rtSound]._address);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_game.version >= 5 && _game.version <= 7)
|
if (_game.version >= 5 && _game.version <= 7)
|
||||||
_sound->setupSound();
|
_sound->setupSound();
|
||||||
|
|
||||||
|
@ -2461,10 +2457,6 @@ void ScummEngine::restart() {
|
||||||
resetScumm();
|
resetScumm();
|
||||||
resetScummVars();
|
resetScummVars();
|
||||||
|
|
||||||
if (_imuse) {
|
|
||||||
_imuse->setBase(_res->_types[rtSound]._address);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinit sound engine
|
// Reinit sound engine
|
||||||
if (_game.version >= 5 && _game.version <= 7)
|
if (_game.version >= 5 && _game.version <= 7)
|
||||||
_sound->setupSound();
|
_sound->setupSound();
|
||||||
|
|
|
@ -1224,7 +1224,7 @@ int ScummEngine::readSoundResource(int idx) {
|
||||||
|
|
||||||
if (!dmuFile.open(buffer)) {
|
if (!dmuFile.open(buffer)) {
|
||||||
error("Can't open music file %s", 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;
|
return 0;
|
||||||
}
|
}
|
||||||
dmuFile.seek(4, SEEK_SET);
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2123,7 +2123,7 @@ int ScummEngine::readSoundResourceSmallHeader(int idx) {
|
||||||
_fileHandle->read(_res->createResource(rtSound, idx, ro_size - 4), ro_size - 4);
|
_fileHandle->read(_res->createResource(rtSound, idx, ro_size - 4), ro_size - 4);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
_res->_types[rtSound].roomoffs[idx] = RES_INVALID_OFFSET;
|
_res->_types[rtSound]._resources[idx]._roomoffs = RES_INVALID_OFFSET;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue