aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamieson Christian2003-09-14 20:34:48 +0000
committerJamieson Christian2003-09-14 20:34:48 +0000
commitd91278198b40cb86d9816971904fbad1e9bcfbf3 (patch)
tree24a38d4046079245ea2cd592a6044b4e86040a11
parent6512592d0f0be9afcc0f3aa30b1b505490ebea54 (diff)
downloadscummvm-rg350-d91278198b40cb86d9816971904fbad1e9bcfbf3.tar.gz
scummvm-rg350-d91278198b40cb86d9816971904fbad1e9bcfbf3.tar.bz2
scummvm-rg350-d91278198b40cb86d9816971904fbad1e9bcfbf3.zip
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
-rw-r--r--scumm/imuse.cpp9
-rw-r--r--scumm/resource.cpp2
-rw-r--r--scumm/saveload.cpp50
-rw-r--r--scumm/saveload.h2
4 files changed, 40 insertions, 23 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 515a6be117..29a5232921 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -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);
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index 12968a90f5..b9c1d209c6 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -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);
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
index 7d7b4775a3..49f08f1e18 100644
--- a/scumm/saveload.cpp
+++ b/scumm/saveload.cpp
@@ -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;
- }
+ if (!res.mode[type]) {
+ if (ser->isSaving()) {
+ ptr = res.address[type][idx];
+ if (ptr == NULL) {
+ ser->saveUint32(0);
+ return;
+ }
- size = ((MemBlkHeader *)ptr)->size;
+ size = ((MemBlkHeader *)ptr)->size;
- ser->saveUint32(size);
- ser->saveBytes(ptr + sizeof(MemBlkHeader), 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();
+ 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);
}
}
}
diff --git a/scumm/saveload.h b/scumm/saveload.h
index 225d295c24..5042befa06 100644
--- a/scumm/saveload.h
+++ b/scumm/saveload.h
@@ -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