Fix for Bug [805593] MI2: Music stops in LeChuck's fortress

Implemented _cmd_queue save/load. In addition to requiring
_cmd_queue information, this bug arises from a rare assumption
that sound resources are loaded in memory even though they
aren't currently playing. Therefore, a list of sound resources
loaded in memory is included in the savegame, so that all
relevant sound resources are reloaded when the savegame is
loaded. This also fixes an unreported music bug in S&M when
saving a game while outside the Bumpusville mansion.

As a result of savegame format modifications, we are now at
savegame version 23.

svn-id: r10254
This commit is contained in:
Jamieson Christian 2003-09-14 20:34:48 +00:00
parent 6512592d0f
commit d91278198b
4 changed files with 44 additions and 27 deletions

View File

@ -1287,7 +1287,11 @@ int IMuseInternal::save_or_load(Serializer *ser, Scumm *scumm) {
MKLINE(IMuseInternal, _trigger_count, sleUint16, VER(8)),
MKARRAY(IMuseInternal, _channel_volume[0], sleUint16, 8, VER(8)),
MKARRAY(IMuseInternal, _volchan_table[0], sleUint16, 8, VER(8)),
// TODO: Add _cmd_queue in here
MKEND()
};
const SaveLoadEntry cmdQueueEntries[] = {
MKARRAY(CommandQueue, array[0], sleUint16, 8, VER(23)),
MKEND()
};
@ -1335,6 +1339,9 @@ int IMuseInternal::save_or_load(Serializer *ser, Scumm *scumm) {
ser->_load_ref = loadReference;
ser->saveLoadEntries(this, mainEntries);
ser->saveLoadArrayOf (_cmd_queue, ARRAYSIZE(_cmd_queue), sizeof(_cmd_queue[0]), cmdQueueEntries);
// The players
for (i = 0; i < ARRAYSIZE(_players); ++i)
_players[i].save_or_load(ser);
ser->saveLoadArrayOf(_parts, ARRAYSIZE(_parts), sizeof(_parts[0]), partEntries);

View File

@ -2131,7 +2131,7 @@ void Scumm::allocateArrays() {
_numCostumes, "costume", 1);
allocResTypeData(rtRoom, MKID('ROOM'), _numRooms, "room", 1);
allocResTypeData(rtRoomScripts, MKID('RMSC'), _numRooms, "room script", 1);
allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 1);
allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 2);
allocResTypeData(rtScript, MKID('SCRP'), _numScripts, "script", 1);
allocResTypeData(rtCharset, MKID('CHAR'), _numCharsets, "charset", 1);
allocResTypeData(rtObjectName, MKID('NONE'), _numNewNames, "new name", 0);

View File

@ -600,7 +600,7 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion) {
// We should at least store for each save resource it's type and ID. Then at least
// we can perform some integrety checks when loading.
for (i = rtFirst; i <= rtLast; i++)
if (res.mode[i] == 0)
if (res.mode[i] != 1)
for (j = 1; j < res.num[i]; j++)
saveLoadResource(s, i, j);
@ -684,32 +684,42 @@ void Scumm::saveLoadResource(Serializer *ser, int type, int idx) {
uint32 size;
/* don't save/load these resource types */
if (type == rtTemp || type == rtBuffer || res.mode[type])
if (type == rtTemp || type == rtBuffer)
return;
if (ser->isSaving()) {
ptr = res.address[type][idx];
if (ptr == NULL) {
ser->saveUint32(0);
return;
}
size = ((MemBlkHeader *)ptr)->size;
ser->saveUint32(size);
ser->saveBytes(ptr + sizeof(MemBlkHeader), size);
if (type == rtInventory) {
ser->saveWord(_inventory[idx]);
}
} else {
size = ser->loadUint32();
if (size) {
createResource(type, idx, size);
ser->loadBytes(getResourceAddress(type, idx), size);
if (type == rtInventory) {
_inventory[idx] = ser->loadWord();
if (!res.mode[type]) {
if (ser->isSaving()) {
ptr = res.address[type][idx];
if (ptr == NULL) {
ser->saveUint32(0);
return;
}
size = ((MemBlkHeader *)ptr)->size;
ser->saveUint32(size);
ser->saveBytes(ptr + sizeof(MemBlkHeader), size);
if (type == rtInventory) {
ser->saveWord(_inventory[idx]);
}
} else {
size = ser->loadUint32();
if (size) {
createResource(type, idx, size);
ser->loadBytes(getResourceAddress(type, idx), size);
if (type == rtInventory) {
_inventory[idx] = ser->loadWord();
}
}
}
} else if (res.mode[type] == 2 && ser->getVersion() >= VER(23)) {
// Save/load only a list of resource numbers that need reloaded.
if (ser->isSaving()) {
ser->saveWord (res.address[type][idx] ? 1 : 0);
} else {
if (ser->loadWord())
ensureResourceLoaded (type, idx);
}
}
}

View File

@ -28,7 +28,7 @@
// Can be useful for other ports too :)
#define VER(x) x
#define CURRENT_VER 22
#define CURRENT_VER 23
// To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types,
// we use a small trick: instead of 0 we use 42. Why? Well, it seems newer GCC