aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2017-11-29 00:06:12 -0600
committerEugene Sandulenko2018-01-31 17:58:01 +0100
commit9916b263831f20e5841275051a8ed014de1f24eb (patch)
treebcd69585fa26cfa3c93ab60c7c480433fe9746f9 /engines
parent157ee95f64380215c3e6b1fed53be99607479582 (diff)
downloadscummvm-rg350-9916b263831f20e5841275051a8ed014de1f24eb.tar.gz
scummvm-rg350-9916b263831f20e5841275051a8ed014de1f24eb.tar.bz2
scummvm-rg350-9916b263831f20e5841275051a8ed014de1f24eb.zip
SCUMM: Replace UB-triggering serialization code with Common::Serializer
Fixes Trac#10342.
Diffstat (limited to 'engines')
-rw-r--r--engines/scumm/actor.cpp284
-rw-r--r--engines/scumm/actor.h9
-rw-r--r--engines/scumm/charset.cpp15
-rw-r--r--engines/scumm/charset.h2
-rw-r--r--engines/scumm/he/intern_he.h12
-rw-r--r--engines/scumm/he/sprite_he.cpp137
-rw-r--r--engines/scumm/he/sprite_he.h6
-rw-r--r--engines/scumm/imuse/imuse.cpp85
-rw-r--r--engines/scumm/imuse/imuse.h4
-rw-r--r--engines/scumm/imuse/imuse_internal.h11
-rw-r--r--engines/scumm/imuse/imuse_part.cpp54
-rw-r--r--engines/scumm/imuse/imuse_player.cpp101
-rw-r--r--engines/scumm/imuse/instrument.cpp106
-rw-r--r--engines/scumm/imuse/instrument.h9
-rw-r--r--engines/scumm/imuse_digi/dimuse.cpp94
-rw-r--r--engines/scumm/imuse_digi/dimuse.h4
-rw-r--r--engines/scumm/music.h7
-rw-r--r--engines/scumm/players/player_ad.cpp31
-rw-r--r--engines/scumm/players/player_ad.h4
-rw-r--r--engines/scumm/players/player_mac.cpp53
-rw-r--r--engines/scumm/players/player_mac.h4
-rw-r--r--engines/scumm/players/player_towns.cpp63
-rw-r--r--engines/scumm/players/player_towns.h7
-rw-r--r--engines/scumm/saveload.cpp1333
-rw-r--r--engines/scumm/saveload.h120
-rw-r--r--engines/scumm/scumm.h13
-rw-r--r--engines/scumm/scumm_v0.h2
-rw-r--r--engines/scumm/scumm_v2.h2
-rw-r--r--engines/scumm/scumm_v5.h2
-rw-r--r--engines/scumm/scumm_v7.h3
-rw-r--r--engines/scumm/sound.cpp11
-rw-r--r--engines/scumm/sound.h6
32 files changed, 1061 insertions, 1533 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 66a7d90b42..c00e38e91d 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -3437,43 +3437,38 @@ void Actor_v0::actorSetWalkTo() {
}
}
-void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
- Actor::saveLoadWithSerializer(ser);
-
- static const SaveLoadEntry actorEntries[] = {
- MKLINE(Actor_v0, _costCommand, sleByte, VER(84)),
- MK_OBSOLETE(Actor_v0, _costFrame, sleByte, VER(84), VER(89)),
- MKLINE(Actor_v0, _miscflags, sleByte, VER(84)),
- MKLINE(Actor_v0, _speaking, sleByte, VER(84)),
- MK_OBSOLETE(Actor_v0, _speakingPrev, sleByte, VER(84), VER(89)),
- MK_OBSOLETE(Actor_v0, _limbTemp, sleByte, VER(89), VER(89)),
- MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)),
- MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)),
- MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)),
- MKLINE(Actor_v0, _CurrentWalkTo.x, sleInt16, VER(97)),
- MKLINE(Actor_v0, _CurrentWalkTo.y, sleInt16, VER(97)),
- MKLINE(Actor_v0, _NewWalkTo.x, sleInt16, VER(97)),
- MKLINE(Actor_v0, _NewWalkTo.y, sleInt16, VER(97)),
- MKLINE(Actor_v0, _walkCountModulo, sleInt8, VER(97)),
- MKLINE(Actor_v0, _newWalkBoxEntered, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkDirX, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkDirY, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkYCountGreaterThanXCount, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkXCount, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkXCountInc, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkYCount, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkYCountInc, sleByte, VER(97)),
- MKLINE(Actor_v0, _walkMaxXYCountInc, sleByte, VER(97)),
-
- MKARRAY(Actor_v0, _walkboxQueue[0], sleByte, 16, VER(98)),
- MKLINE(Actor_v0, _walkboxQueueIndex, sleByte, VER(98)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, actorEntries);
+void Actor_v0::saveLoadWithSerializer(Common::Serializer &s) {
+ Actor::saveLoadWithSerializer(s);
+
+ s.syncAsByte(_costCommand, VER(84));
+ s.skip(1, VER(84), VER(89)); // _costFrame
+ s.syncAsByte(_miscflags, VER(84));
+ s.syncAsByte(_speaking, VER(84));
+ s.skip(1, VER(84), VER(89)); // _speakingPrev
+ s.skip(1, VER(89), VER(89)); // _limbTemp
+ s.syncAsByte(_animFrameRepeat, VER(89));
+ s.syncArray(_limbFrameRepeatNew, 8, Common::Serializer::SByte, VER(89));
+ s.syncArray(_limbFrameRepeat, 8, Common::Serializer::SByte, VER(90));
+ s.syncAsSint16LE(_CurrentWalkTo.x, VER(97));
+ s.syncAsSint16LE(_CurrentWalkTo.y, VER(97));
+ s.syncAsSint16LE(_NewWalkTo.x, VER(97));
+ s.syncAsSint16LE(_NewWalkTo.y, VER(97));
+ s.syncAsSByte(_walkCountModulo, VER(97));
+ s.syncAsByte(_newWalkBoxEntered, VER(97));
+ s.syncAsByte(_walkDirX, VER(97));
+ s.syncAsByte(_walkDirY, VER(97));
+ s.syncAsByte(_walkYCountGreaterThanXCount, VER(97));
+ s.syncAsByte(_walkXCount, VER(97));
+ s.syncAsByte(_walkXCountInc, VER(97));
+ s.syncAsByte(_walkYCount, VER(97));
+ s.syncAsByte(_walkYCountInc, VER(97));
+ s.syncAsByte(_walkMaxXYCountInc, VER(97));
+
+ s.syncBytes(_walkboxQueue, 16, VER(98));
+ s.syncAsByte(_walkboxQueueIndex, VER(98));
// When loading, we need to ensure the limbs are restarted
- if (ser->isLoading()) {
+ if (s.isLoading()) {
// valid costume command?
if (_costCommand != 0xFF) {
@@ -3498,124 +3493,119 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
}
}
-void Actor::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry actorEntries[] = {
- MKLINE(Actor, _pos.x, sleInt16, VER(8)),
- MKLINE(Actor, _pos.y, sleInt16, VER(8)),
- MKLINE(Actor, _heOffsX, sleInt16, VER(32)),
- MKLINE(Actor, _heOffsY, sleInt16, VER(32)),
- MKLINE(Actor, _top, sleInt16, VER(8)),
- MKLINE(Actor, _bottom, sleInt16, VER(8)),
- MKLINE(Actor, _elevation, sleInt16, VER(8)),
- MKLINE(Actor, _width, sleUint16, VER(8)),
- MKLINE(Actor, _facing, sleUint16, VER(8)),
- MKLINE(Actor, _costume, sleUint16, VER(8)),
- MKLINE(Actor, _room, sleByte, VER(8)),
- MKLINE(Actor, _talkColor, sleByte, VER(8)),
- MKLINE(Actor, _talkFrequency, sleInt16, VER(16)),
- MKLINE(Actor, _talkPan, sleInt16, VER(24)),
- MKLINE(Actor, _talkVolume, sleInt16, VER(29)),
- MKLINE(Actor, _boxscale, sleUint16, VER(34)),
- MKLINE(Actor, _scalex, sleByte, VER(8)),
- MKLINE(Actor, _scaley, sleByte, VER(8)),
- MKLINE(Actor, _charset, sleByte, VER(8)),
-
- // Actor sound grew from 8 to 32 bytes and switched to uint16 in HE games
- MKARRAY_OLD(Actor, _sound[0], sleByte, 8, VER(8), VER(36)),
- MKARRAY_OLD(Actor, _sound[0], sleByte, 32, VER(37), VER(61)),
- MKARRAY(Actor, _sound[0], sleUint16, 32, VER(62)),
-
- // Actor animVariable grew from 8 to 27
- MKARRAY_OLD(Actor, _animVariable[0], sleUint16, 8, VER(8), VER(40)),
- MKARRAY(Actor, _animVariable[0], sleUint16, 27, VER(41)),
-
- MKLINE(Actor, _targetFacing, sleUint16, VER(8)),
- MKLINE(Actor, _moving, sleByte, VER(8)),
- MKLINE(Actor, _ignoreBoxes, sleByte, VER(8)),
- MKLINE(Actor, _forceClip, sleByte, VER(8)),
- MKLINE(Actor, _initFrame, sleByte, VER(8)),
- MKLINE(Actor, _walkFrame, sleByte, VER(8)),
- MKLINE(Actor, _standFrame, sleByte, VER(8)),
- MKLINE(Actor, _talkStartFrame, sleByte, VER(8)),
- MKLINE(Actor, _talkStopFrame, sleByte, VER(8)),
- MKLINE(Actor, _speedx, sleUint16, VER(8)),
- MKLINE(Actor, _speedy, sleUint16, VER(8)),
- MKLINE(Actor, _cost.animCounter, sleUint16, VER(8)),
- MKLINE(Actor, _cost.soundCounter, sleByte, VER(8)),
- MKLINE(Actor, _drawToBackBuf, sleByte, VER(32)),
- MKLINE(Actor, _flip, sleByte, VER(32)),
- MKLINE(Actor, _heSkipLimbs, sleByte, VER(32)),
-
- // Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
- MKARRAY_OLD(Actor, _palette[0], sleByte, 64, VER(8), VER(9)),
- MKARRAY_OLD(Actor, _palette[0], sleByte, 256, VER(10), VER(79)),
- MKARRAY(Actor, _palette[0], sleUint16, 256, VER(80)),
-
- MK_OBSOLETE(Actor, _mask, sleByte, VER(8), VER(9)),
- MKLINE(Actor, _shadowMode, sleByte, VER(8)),
- MKLINE(Actor, _visible, sleByte, VER(8)),
- MKLINE(Actor, _frame, sleByte, VER(8)),
- MKLINE(Actor, _animSpeed, sleByte, VER(8)),
- MKLINE(Actor, _animProgress, sleByte, VER(8)),
- MKLINE(Actor, _walkbox, sleByte, VER(8)),
- MKLINE(Actor, _needRedraw, sleByte, VER(8)),
- MKLINE(Actor, _needBgReset, sleByte, VER(8)),
- MKLINE(Actor, _costumeNeedsInit, sleByte, VER(8)),
- MKLINE(Actor, _heCondMask, sleUint32, VER(38)),
- MKLINE(Actor, _hePaletteNum, sleUint32, VER(59)),
- MKLINE(Actor, _heXmapNum, sleUint32, VER(59)),
-
- MKLINE(Actor, _talkPosY, sleInt16, VER(8)),
- MKLINE(Actor, _talkPosX, sleInt16, VER(8)),
- MKLINE(Actor, _ignoreTurns, sleByte, VER(8)),
-
- // Actor layer switched to int32 in HE games
- MKLINE_OLD(Actor, _layer, sleByte, VER(8), VER(57)),
- MKLINE(Actor, _layer, sleInt32, VER(58)),
-
- MKLINE(Actor, _talkScript, sleUint16, VER(8)),
- MKLINE(Actor, _walkScript, sleUint16, VER(8)),
-
- MKLINE(Actor, _walkdata.dest.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.dest.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.destbox, sleByte, VER(8)),
- MKLINE(Actor, _walkdata.destdir, sleUint16, VER(8)),
- MKLINE(Actor, _walkdata.curbox, sleByte, VER(8)),
- MKLINE(Actor, _walkdata.cur.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.cur.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.next.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.next.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.deltaXFactor, sleInt32, VER(8)),
- MKLINE(Actor, _walkdata.deltaYFactor, sleInt32, VER(8)),
- MKLINE(Actor, _walkdata.xfrac, sleUint16, VER(8)),
- MKLINE(Actor, _walkdata.yfrac, sleUint16, VER(8)),
-
- MKLINE(Actor, _walkdata.point3.x, sleUint16, VER(42)),
- MKLINE(Actor, _walkdata.point3.y, sleUint16, VER(42)),
-
- MKARRAY(Actor, _cost.active[0], sleByte, 16, VER(8)),
- MKLINE(Actor, _cost.stopped, sleUint16, VER(8)),
- MKARRAY(Actor, _cost.curpos[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.start[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.end[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.frame[0], sleUint16, 16, VER(8)),
-
- MKARRAY(Actor, _cost.heJumpOffsetTable[0], sleUint16, 16, VER(65)),
- MKARRAY(Actor, _cost.heJumpCountTable[0], sleUint16, 16, VER(65)),
- MKARRAY(Actor, _cost.heCondMaskTable[0], sleUint32, 16, VER(65)),
- MKEND()
- };
-
- if (ser->isLoading()) {
+void Actor::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.isLoading()) {
// Not all actor data is saved; so when loading, we first reset
// the actor, to ensure completely reproducible behavior (else,
// some not saved value in the actor class can cause odd things)
initActor(-1);
}
- ser->saveLoadEntries(this, actorEntries);
-
- if (ser->isLoading() && _vm->_game.version <= 2 && ser->getVersion() < VER(70)) {
+ s.syncAsSint16LE(_pos.x, VER(8));
+ s.syncAsSint16LE(_pos.y, VER(8));
+ s.syncAsSint16LE(_heOffsX, VER(32));
+ s.syncAsSint16LE(_heOffsY, VER(32));
+ s.syncAsSint16LE(_top, VER(8));
+ s.syncAsSint16LE(_bottom, VER(8));
+ s.syncAsSint16LE(_elevation, VER(8));
+ s.syncAsUint16LE(_width, VER(8));
+ s.syncAsUint16LE(_facing, VER(8));
+ s.syncAsUint16LE(_costume, VER(8));
+ s.syncAsByte(_room, VER(8));
+ s.syncAsByte(_talkColor, VER(8));
+ s.syncAsSint16LE(_talkFrequency, VER(16));
+ s.syncAsSint16LE(_talkPan, VER(24));
+ s.syncAsSint16LE(_talkVolume, VER(29));
+ s.syncAsUint16LE(_boxscale, VER(34));
+ s.syncAsByte(_scalex, VER(8));
+ s.syncAsByte(_scaley, VER(8));
+ s.syncAsByte(_charset, VER(8));
+
+ // Actor sound grew from 8 to 32 bytes and switched to uint16 in HE games
+ s.syncArray(_sound, 8, Common::Serializer::Byte, VER(8), VER(36));
+ s.syncArray(_sound, 32, Common::Serializer::Byte, VER(37), VER(61));
+ s.syncArray(_sound, 32, Common::Serializer::Uint16LE, VER(62));
+
+ // Actor animVariable grew from 8 to 27
+ s.syncArray(_animVariable, 8, Common::Serializer::Uint16LE, VER(8), VER(40));
+ s.syncArray(_animVariable, 27, Common::Serializer::Uint16LE, VER(41));
+
+ s.syncAsUint16LE(_targetFacing, VER(8));
+ s.syncAsByte(_moving, VER(8));
+ s.syncAsByte(_ignoreBoxes, VER(8));
+ s.syncAsByte(_forceClip, VER(8));
+ s.syncAsByte(_initFrame, VER(8));
+ s.syncAsByte(_walkFrame, VER(8));
+ s.syncAsByte(_standFrame, VER(8));
+ s.syncAsByte(_talkStartFrame, VER(8));
+ s.syncAsByte(_talkStopFrame, VER(8));
+ s.syncAsUint16LE(_speedx, VER(8));
+ s.syncAsUint16LE(_speedy, VER(8));
+ s.syncAsUint16LE(_cost.animCounter, VER(8));
+ s.syncAsByte(_cost.soundCounter, VER(8));
+ s.syncAsByte(_drawToBackBuf, VER(32));
+ s.syncAsByte(_flip, VER(32));
+ s.syncAsByte(_heSkipLimbs, VER(32));
+
+ // Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
+ s.syncArray(_palette, 64, Common::Serializer::Byte, VER(8), VER(9));
+ s.syncArray(_palette, 256, Common::Serializer::Byte, VER(10), VER(79));
+ s.syncArray(_palette, 256, Common::Serializer::Uint16LE, VER(80));
+
+ s.skip(1, VER(8), VER(9)); // _mask
+ s.syncAsByte(_shadowMode, VER(8));
+ s.syncAsByte(_visible, VER(8));
+ s.syncAsByte(_frame, VER(8));
+ s.syncAsByte(_animSpeed, VER(8));
+ s.syncAsByte(_animProgress, VER(8));
+ s.syncAsByte(_walkbox, VER(8));
+ s.syncAsByte(_needRedraw, VER(8));
+ s.syncAsByte(_needBgReset, VER(8));
+ s.syncAsByte(_costumeNeedsInit, VER(8));
+ s.syncAsUint32LE(_heCondMask, VER(38));
+ s.syncAsUint32LE(_hePaletteNum, VER(59));
+ s.syncAsUint32LE(_heXmapNum, VER(59));
+
+ s.syncAsSint16LE(_talkPosY, VER(8));
+ s.syncAsSint16LE(_talkPosX, VER(8));
+ s.syncAsByte(_ignoreTurns, VER(8));
+
+ // Actor layer switched to int32 in HE games
+ s.syncAsByte(_layer, VER(8), VER(57));
+ s.syncAsSint32LE(_layer, VER(58));
+
+ s.syncAsUint16LE(_talkScript, VER(8));
+ s.syncAsUint16LE(_walkScript, VER(8));
+
+ s.syncAsSint16LE(_walkdata.dest.x, VER(8));
+ s.syncAsSint16LE(_walkdata.dest.y, VER(8));
+ s.syncAsByte(_walkdata.destbox, VER(8));
+ s.syncAsUint16LE(_walkdata.destdir, VER(8));
+ s.syncAsByte(_walkdata.curbox, VER(8));
+ s.syncAsSint16LE(_walkdata.cur.x, VER(8));
+ s.syncAsSint16LE(_walkdata.cur.y, VER(8));
+ s.syncAsSint16LE(_walkdata.next.x, VER(8));
+ s.syncAsSint16LE(_walkdata.next.y, VER(8));
+ s.syncAsSint32LE(_walkdata.deltaXFactor, VER(8));
+ s.syncAsSint32LE(_walkdata.deltaYFactor, VER(8));
+ s.syncAsUint16LE(_walkdata.xfrac, VER(8));
+ s.syncAsUint16LE(_walkdata.yfrac, VER(8));
+
+ s.syncAsUint16LE(_walkdata.point3.x, VER(42));
+ s.syncAsUint16LE(_walkdata.point3.y, VER(42));
+
+ s.syncBytes(_cost.active, 16, VER(8));
+ s.syncAsUint16LE(_cost.stopped, VER(8));
+ s.syncArray(_cost.curpos, 16, Common::Serializer::Uint16LE, VER(8));
+ s.syncArray(_cost.start, 16, Common::Serializer::Uint16LE, VER(8));
+ s.syncArray(_cost.end, 16, Common::Serializer::Uint16LE, VER(8));
+ s.syncArray(_cost.frame, 16, Common::Serializer::Uint16LE, VER(8));
+
+ s.syncArray(_cost.heJumpOffsetTable, 16, Common::Serializer::Uint16LE, VER(65));
+ s.syncArray(_cost.heJumpCountTable, 16, Common::Serializer::Uint16LE, VER(65));
+ s.syncArray(_cost.heCondMaskTable, 16, Common::Serializer::Uint32LE, VER(65));
+
+ if (s.isLoading() && _vm->_game.version <= 2 && s.getVersion() < VER(70)) {
_pos.x >>= V12_X_SHIFT;
_pos.y >>= V12_Y_SHIFT;
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 62ba161f4e..c059d08397 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -25,6 +25,7 @@
#define SCUMM_ACTOR_H
#include "common/scummsys.h"
+#include "common/serializer.h"
#include "scumm/saveload.h"
#include "scumm/scumm.h"
@@ -82,7 +83,7 @@ enum {
kNewInavlidBox = 0
};
-class Actor : public Serializable {
+class Actor : public Common::Serializable {
public:
static byte kInvalidBox;
@@ -300,8 +301,7 @@ public:
void classChanged(int cls, bool value);
- // Used by the save/load system:
- virtual void saveLoadWithSerializer(Serializer *ser);
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
protected:
bool isInClass(int cls);
@@ -421,8 +421,7 @@ public:
void setTmpFromActor();
void setActorFromTmp();
- // Used by the save/load system:
- virtual void saveLoadWithSerializer(Serializer *ser);
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index e546c805b5..214eeb7d5c 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -708,17 +708,12 @@ void CharsetRenderer::translateColor() {
}
}
-void CharsetRenderer::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry charsetRendererEntries[] = {
- MKLINE_OLD(CharsetRenderer, _curId, sleByte, VER(73), VER(73)),
- MKLINE(CharsetRenderer, _curId, sleInt32, VER(74)),
- MKLINE(CharsetRenderer, _color, sleByte, VER(73)),
- MKEND()
- };
+void CharsetRenderer::saveLoadWithSerializer(Common::Serializer &ser) {
+ ser.syncAsByte(_curId, VER(73), VER(73));
+ ser.syncAsSint32LE(_curId, VER(74));
+ ser.syncAsByte(_color, VER(73));
- ser->saveLoadEntries(this, charsetRendererEntries);
-
- if (ser->isLoading()) {
+ if (ser.isLoading()) {
setCurID(_curId);
setColor(_color);
}
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index b4b3d88ccd..7f3a8baf88 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -89,7 +89,7 @@ public:
virtual void setColor(byte color) { _color = color; translateColor(); }
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
};
class CharsetRendererCommon : public CharsetRenderer {
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index bd3cdb2c57..25dd31f007 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -73,7 +73,7 @@ public:
protected:
virtual void setupOpcodes();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
void localizeArray(int slot, byte scriptSlot);
void redimArray(int arrayId, int newX, int newY, int d);
@@ -163,7 +163,7 @@ protected:
virtual void setupScummVars();
virtual void resetScummVars();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void readRoomsOffsets();
virtual void readGlobalObjects();
@@ -222,7 +222,7 @@ public:
protected:
virtual void setupOpcodes();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void redrawBGAreas();
@@ -490,7 +490,7 @@ protected:
virtual void processInput();
virtual void clearClickedStatus();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void readMAXS(int blockSize);
void setResourceOffHeap(int typeId, int resId, int val);
@@ -581,7 +581,7 @@ protected:
virtual void readMAXS(int blockSize);
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void copyPalColor(int dst, int src);
virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
@@ -613,7 +613,7 @@ public:
protected:
virtual void setupOpcodes();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void decodeParseString(int a, int b);
diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp
index bef1c0b5eb..16c3b50365 100644
--- a/engines/scumm/he/sprite_he.cpp
+++ b/engines/scumm/he/sprite_he.cpp
@@ -1389,80 +1389,79 @@ void Sprite::processImages(bool arg) {
}
}
-void Sprite::saveOrLoadSpriteData(Serializer *s) {
- static const SaveLoadEntry spriteEntries[] = {
- MKLINE(SpriteInfo, id, sleInt32, VER(48)),
- MKLINE(SpriteInfo, zorder, sleInt32, VER(48)),
- MKLINE(SpriteInfo, flags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, image, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imageState, sleInt32, VER(48)),
- MKLINE(SpriteInfo, group, sleInt32, VER(48)),
- MKLINE(SpriteInfo, palette, sleInt32, VER(48)),
- MKLINE(SpriteInfo, priority, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.left, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.top, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.right, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.bottom, sleInt32, VER(48)),
- MKLINE(SpriteInfo, dx, sleInt32, VER(48)),
- MKLINE(SpriteInfo, dy, sleInt32, VER(48)),
- MKLINE(SpriteInfo, pos.x, sleInt32, VER(48)),
- MKLINE(SpriteInfo, pos.y, sleInt32, VER(48)),
- MKLINE(SpriteInfo, tx, sleInt32, VER(48)),
- MKLINE(SpriteInfo, ty, sleInt32, VER(48)),
- MKLINE(SpriteInfo, userValue, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImageState, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imglistNum, sleInt32, VER(48)),
- MKLINE(SpriteInfo, shadow, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imageStateCount, sleInt32, VER(48)),
- MKLINE(SpriteInfo, angle, sleInt32, VER(48)),
- MKLINE(SpriteInfo, scale, sleInt32, VER(48)),
- MKLINE(SpriteInfo, animProgress, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curAngle, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curScale, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, animIndex, sleInt32, VER(48)),
- MKLINE(SpriteInfo, animSpeed, sleInt32, VER(48)),
- MKLINE(SpriteInfo, sourceImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, maskImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, zbufferImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, classFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, conditionBits, sleInt32, VER(48)),
- MKEND()
- };
-
- static const SaveLoadEntry spriteGroupEntries[] = {
- MKLINE(SpriteGroup, bbox.left, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.top, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.right, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.bottom, sleInt32, VER(48)),
- MKLINE(SpriteGroup, priority, sleInt32, VER(48)),
- MKLINE(SpriteGroup, flags, sleInt32, VER(48)),
- MKLINE(SpriteGroup, tx, sleInt32, VER(48)),
- MKLINE(SpriteGroup, ty, sleInt32, VER(48)),
- MKLINE(SpriteGroup, image, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scaling, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_x_ratio_mul, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_x_ratio_div, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_y_ratio_mul, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_y_ratio_div, sleInt32, VER(48)),
- MKEND()
- };
-
- if (s->getVersion() >= VER(64)) {
- s->saveLoadArrayOf(_spriteTable, _varNumSprites + 1, sizeof(_spriteTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteGroups, _varNumSpriteGroups + 1, sizeof(_spriteGroups[0]), spriteGroupEntries);
+static void syncWithSerializer(Common::Serializer &s, SpriteInfo &si) {
+ s.syncAsSint32LE(si.id, VER(48));
+ s.syncAsSint32LE(si.zorder, VER(48));
+ s.syncAsSint32LE(si.flags, VER(48));
+ s.syncAsSint32LE(si.image, VER(48));
+ s.syncAsSint32LE(si.imageState, VER(48));
+ s.syncAsSint32LE(si.group, VER(48));
+ s.syncAsSint32LE(si.palette, VER(48));
+ s.syncAsSint32LE(si.priority, VER(48));
+ s.syncAsSint32LE(si.bbox.left, VER(48));
+ s.syncAsSint32LE(si.bbox.top, VER(48));
+ s.syncAsSint32LE(si.bbox.right, VER(48));
+ s.syncAsSint32LE(si.bbox.bottom, VER(48));
+ s.syncAsSint32LE(si.dx, VER(48));
+ s.syncAsSint32LE(si.dy, VER(48));
+ s.syncAsSint32LE(si.pos.x, VER(48));
+ s.syncAsSint32LE(si.pos.y, VER(48));
+ s.syncAsSint32LE(si.tx, VER(48));
+ s.syncAsSint32LE(si.ty, VER(48));
+ s.syncAsSint32LE(si.userValue, VER(48));
+ s.syncAsSint32LE(si.curImageState, VER(48));
+ s.syncAsSint32LE(si.curImage, VER(48));
+ s.syncAsSint32LE(si.imglistNum, VER(48));
+ s.syncAsSint32LE(si.shadow, VER(48));
+ s.syncAsSint32LE(si.imageStateCount, VER(48));
+ s.syncAsSint32LE(si.angle, VER(48));
+ s.syncAsSint32LE(si.scale, VER(48));
+ s.syncAsSint32LE(si.animProgress, VER(48));
+ s.syncAsSint32LE(si.curAngle, VER(48));
+ s.syncAsSint32LE(si.curScale, VER(48));
+ s.syncAsSint32LE(si.curImgFlags, VER(48));
+ s.syncAsSint32LE(si.animIndex, VER(48));
+ s.syncAsSint32LE(si.animSpeed, VER(48));
+ s.syncAsSint32LE(si.sourceImage, VER(48));
+ s.syncAsSint32LE(si.maskImage, VER(48));
+ s.syncAsSint32LE(si.zbufferImage, VER(48));
+ s.syncAsSint32LE(si.classFlags, VER(48));
+ s.syncAsSint32LE(si.imgFlags, VER(48));
+ s.syncAsSint32LE(si.conditionBits, VER(48));
+}
+
+static void syncWithSerializer(Common::Serializer &s, SpriteGroup &sg) {
+ s.syncAsSint32LE(sg.bbox.left, VER(48));
+ s.syncAsSint32LE(sg.bbox.top, VER(48));
+ s.syncAsSint32LE(sg.bbox.right, VER(48));
+ s.syncAsSint32LE(sg.bbox.bottom, VER(48));
+ s.syncAsSint32LE(sg.priority, VER(48));
+ s.syncAsSint32LE(sg.flags, VER(48));
+ s.syncAsSint32LE(sg.tx, VER(48));
+ s.syncAsSint32LE(sg.ty, VER(48));
+ s.syncAsSint32LE(sg.image, VER(48));
+ s.syncAsSint32LE(sg.scaling, VER(48));
+ s.syncAsSint32LE(sg.scale_x_ratio_mul, VER(48));
+ s.syncAsSint32LE(sg.scale_x_ratio_div, VER(48));
+ s.syncAsSint32LE(sg.scale_y_ratio_mul, VER(48));
+ s.syncAsSint32LE(sg.scale_y_ratio_div, VER(48));
+}
+
+void Sprite::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.getVersion() >= VER(64)) {
+ s.syncArray(_spriteTable, _varNumSprites + 1, syncWithSerializer);
+ s.syncArray(_spriteGroups, _varNumSpriteGroups + 1, syncWithSerializer);
} else {
- s->saveLoadArrayOf(_activeSpritesTable, _varNumSprites, sizeof(_activeSpritesTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteTable, _varNumSprites, sizeof(_spriteTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteGroups, _varNumSpriteGroups, sizeof(_spriteGroups[0]), spriteGroupEntries);
+ // TODO: This had been bogus, what is it really supposed to do?
+// s->saveLoadArrayOf(_activeSpritesTable, _varNumSprites, sizeof(_activeSpritesTable[0]), spriteEntries);
+ s.syncArray(*_activeSpritesTable, _varNumSprites, syncWithSerializer);
+ s.syncArray(_spriteTable, _varNumSprites, syncWithSerializer);
+ s.syncArray(_spriteGroups, _varNumSpriteGroups, syncWithSerializer);
}
// Reset active sprite table
- if (s->isLoading())
+ if (s.isLoading())
_numSpritesToProcess = 0;
-
}
} // End of namespace Scumm
diff --git a/engines/scumm/he/sprite_he.h b/engines/scumm/he/sprite_he.h
index 3ea6bb9f84..77e527b3ce 100644
--- a/engines/scumm/he/sprite_he.h
+++ b/engines/scumm/he/sprite_he.h
@@ -23,6 +23,8 @@
#if !defined(SCUMM_HE_SPRITE_HE_H) && defined(ENABLE_HE)
#define SCUMM_HE_SPRITE_HE_H
+#include "common/serializer.h"
+
namespace Scumm {
enum SpriteFlags {
@@ -98,7 +100,7 @@ struct SpriteGroup {
class ScummEngine_v90he;
-class Sprite {
+class Sprite : public Common::Serializable {
public:
Sprite(ScummEngine_v90he *vm);
virtual ~Sprite();
@@ -112,7 +114,7 @@ public:
int32 _varNumSprites;
int32 _varMaxSprites;
- void saveOrLoadSpriteData(Serializer *s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void resetBackground();
void setRedrawFlags(bool checkZOrder);
void sortActiveSprites();
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index b7b72ba181..d083dc8dfd 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -362,70 +362,50 @@ void IMuseInternal::pause(bool paused) {
_paused = paused;
}
-int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad) {
- Common::StackLock lock(_mutex, "IMuseInternal::save_or_load()");
- const SaveLoadEntry mainEntries[] = {
- MKLINE(IMuseInternal, _queue_end, sleUint8, VER(8)),
- MKLINE(IMuseInternal, _queue_pos, sleUint8, VER(8)),
- MKLINE(IMuseInternal, _queue_sound, sleUint16, VER(8)),
- MKLINE(IMuseInternal, _queue_adding, sleByte, VER(8)),
- MKLINE(IMuseInternal, _queue_marker, sleByte, VER(8)),
- MKLINE(IMuseInternal, _queue_cleared, sleByte, VER(8)),
- MKLINE(IMuseInternal, _master_volume, sleByte, VER(8)),
- MKLINE(IMuseInternal, _trigger_count, sleUint16, VER(8)),
- MKLINE(IMuseInternal, _snm_trigger_index, sleUint16, VER(54)),
- MKARRAY(IMuseInternal, _channel_volume[0], sleUint16, 8, VER(8)),
- MKARRAY(IMuseInternal, _volchan_table[0], sleUint16, 8, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry cmdQueueEntries[] = {
- MKARRAY(CommandQueue, array[0], sleUint16, 8, VER(23)),
- MKEND()
- };
+static void syncWithSerializer(Common::Serializer &s, CommandQueue &cq) {
+ s.syncArray(cq.array, 8, Common::Serializer::Uint16LE, VER(23));
+}
- // VolumeFader is obsolete.
- const SaveLoadEntry volumeFaderEntries[] = {
- MK_OBSOLETE(VolumeFader, player, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, active, sleUint8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, curvol, sleUint8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo_max, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, num_steps, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_hi, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, direction, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo_counter, sleUint16, VER(8), VER(16)),
- MKEND()
- };
+static void syncWithSerializer(Common::Serializer &s, ImTrigger &it) {
+ s.syncAsSint16LE(it.sound, VER(54));
+ s.syncAsByte(it.id, VER(54));
+ s.syncAsUint16LE(it.expire, VER(54));
+ s.syncArray(it.command, 8, Common::Serializer::Uint16LE, VER(54));
+}
- const SaveLoadEntry snmTriggerEntries[] = {
- MKLINE(ImTrigger, sound, sleInt16, VER(54)),
- MKLINE(ImTrigger, id, sleByte, VER(54)),
- MKLINE(ImTrigger, expire, sleUint16, VER(54)),
- MKARRAY(ImTrigger, command[0], sleUint16, 8, VER(54)),
- MKEND()
- };
+void IMuseInternal::saveLoadWithSerializer(Common::Serializer &s, ScummEngine *scumm, bool fixAfterLoad) {
+ Common::StackLock lock(_mutex, "IMuseInternal::saveLoadWithSerializer()");
int i;
- ser->saveLoadEntries(this, mainEntries);
- ser->saveLoadArrayOf(_cmd_queue, ARRAYSIZE(_cmd_queue), sizeof(_cmd_queue[0]), cmdQueueEntries);
- ser->saveLoadArrayOf(_snm_triggers, ARRAYSIZE(_snm_triggers), sizeof(_snm_triggers[0]), snmTriggerEntries);
+ s.syncAsByte(_queue_end, VER(8));
+ s.syncAsByte(_queue_pos, VER(8));
+ s.syncAsUint16LE(_queue_sound, VER(8));
+ s.syncAsByte(_queue_adding, VER(8));
+ s.syncAsByte(_queue_marker, VER(8));
+ s.syncAsByte(_queue_cleared, VER(8));
+ s.syncAsByte(_master_volume, VER(8));
+ s.syncAsUint16LE(_trigger_count, VER(8));
+ s.syncAsUint16LE(_snm_trigger_index, VER(54));
+ s.syncArray(_channel_volume, 8, Common::Serializer::Uint16LE, VER(8));
+ s.syncArray(_volchan_table, 8, Common::Serializer::Uint16LE, VER(8));
+ s.syncArray(_cmd_queue, ARRAYSIZE(_cmd_queue), syncWithSerializer);
+ s.syncArray(_snm_triggers, ARRAYSIZE(_snm_triggers), syncWithSerializer);
// The players
for (i = 0; i < ARRAYSIZE(_players); ++i)
- _players[i].saveLoadWithSerializer(ser);
+ _players[i].saveLoadWithSerializer(s);
// The parts
for (i = 0; i < ARRAYSIZE(_parts); ++i)
- _parts[i].saveLoadWithSerializer(ser);
+ _parts[i].saveLoadWithSerializer(s);
{
// Load/save the instrument definitions, which were revamped with V11.
Part *part = &_parts[0];
- if (ser->getVersion() >= VER(11)) {
+ if (s.getVersion() >= VER(11)) {
for (i = ARRAYSIZE(_parts); i; --i, ++part) {
- part->_instrument.saveOrLoad(ser);
+ part->_instrument.saveLoadWithSerializer(s);
}
} else {
for (i = ARRAYSIZE(_parts); i; --i, ++part)
@@ -434,10 +414,7 @@ int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAft
}
// VolumeFader has been replaced with the more generic ParameterFader.
- // FIXME: replace this loop by something like
- // if (loading && version <= 16) ser->skip(XXX bytes);
- for (i = 0; i < 8; ++i)
- ser->saveLoadEntries(0, volumeFaderEntries);
+ s.skip(13 * 8, VER(8), VER(16));
// Normally, we have to fix up the data structures after loading a
// saved game. But there are cases where we don't. For instance, The
@@ -448,7 +425,7 @@ int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAft
// dummy iMUSE object, but since the resource is no longer recognizable
// to iMUSE, the fixup fails hard. So yes, this is a bit of a hack.
- if (ser->isLoading() && fixAfterLoad) {
+ if (s.isLoading() && fixAfterLoad) {
// Load all sounds that we need
fix_players_after_load(scumm);
fix_parts_after_load();
@@ -459,8 +436,6 @@ int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAft
if (_midi_adlib)
reallocateMidiChannels(_midi_adlib);
}
-
- return 0;
}
bool IMuseInternal::get_sound_active(int sound) const {
diff --git a/engines/scumm/imuse/imuse.h b/engines/scumm/imuse/imuse.h
index 35ccc931b5..513d27e8e9 100644
--- a/engines/scumm/imuse/imuse.h
+++ b/engines/scumm/imuse/imuse.h
@@ -24,6 +24,7 @@
#define SCUMM_IMUSE_H
#include "common/scummsys.h"
+#include "common/serializer.h"
#include "common/mutex.h"
#include "scumm/music.h"
@@ -35,7 +36,6 @@ namespace Scumm {
class IMuseInternal;
class Player;
class ScummEngine;
-class Serializer;
typedef void (*sysexfunc)(Player *, const byte *, uint16);
@@ -62,7 +62,7 @@ public:
public:
virtual void on_timer(MidiDriver *midi) = 0;
virtual void pause(bool paused) = 0;
- virtual int save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad = true) = 0;
+ virtual void saveLoadWithSerializer(Common::Serializer &ser, ScummEngine *scumm, bool fixAfterLoad = true) = 0;
virtual bool get_sound_active(int sound) const = 0;
virtual int32 doCommand(int numargs, int args[]) = 0;
virtual int clear_queue() = 0;
diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h
index fed716e300..7b1d2f65fa 100644
--- a/engines/scumm/imuse/imuse_internal.h
+++ b/engines/scumm/imuse/imuse_internal.h
@@ -24,6 +24,7 @@
#define SCUMM_IMUSE_INTERNAL
#include "common/scummsys.h"
+#include "common/serializer.h"
#include "scumm/imuse/imuse.h"
#include "scumm/imuse/instrument.h"
#include "scumm/saveload.h"
@@ -153,7 +154,7 @@ struct CommandQueue {
//
//////////////////////////////////////////////////
-class Player : public MidiDriver_BASE {
+class Player : public MidiDriver_BASE, public Common::Serializable {
/*
* External SysEx handler functions shall each be defined in
* a separate file. This header file shall be included at the
@@ -267,7 +268,7 @@ public:
void onTimer();
void removePart(Part *part);
int scan(uint totrack, uint tobeat, uint totick);
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
int setHook(byte cls, byte value, byte chan) { return _hook.set(cls, value, chan); }
void setDetune(int detune);
void setOffsetNote(int offset);
@@ -295,7 +296,7 @@ public:
//
//////////////////////////////////////////////////
-struct Part : public Serializable {
+struct Part : public Common::Serializable {
IMuseInternal *_se;
int _slot;
Part *_next, *_prev;
@@ -360,7 +361,7 @@ struct Part : public Serializable {
Part();
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
private:
void sendPitchBend();
@@ -518,7 +519,7 @@ protected:
public:
// IMuse interface
void pause(bool paused);
- int save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad = true);
+ void saveLoadWithSerializer(Common::Serializer &ser, ScummEngine *scumm, bool fixAfterLoad = true);
bool get_sound_active(int sound) const;
int32 doCommand(int numargs, int args[]);
uint32 property(int prop, uint32 value);
diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp
index 937523d275..ca0eaa4630 100644
--- a/engines/scumm/imuse/imuse_part.cpp
+++ b/engines/scumm/imuse/imuse_part.cpp
@@ -66,48 +66,44 @@ Part::Part() {
_unassigned_instrument = false;
}
-void Part::saveLoadWithSerializer(Serializer *ser) {
- const SaveLoadEntry partEntries[] = {
- MKLINE(Part, _pitchbend, sleInt16, VER(8)),
- MKLINE(Part, _pitchbend_factor, sleUint8, VER(8)),
- MKLINE(Part, _transpose, sleInt8, VER(8)),
- MKLINE(Part, _vol, sleUint8, VER(8)),
- MKLINE(Part, _detune, sleInt8, VER(8)),
- MKLINE(Part, _pan, sleInt8, VER(8)),
- MKLINE(Part, _on, sleUint8, VER(8)),
- MKLINE(Part, _modwheel, sleUint8, VER(8)),
- MKLINE(Part, _pedal, sleUint8, VER(8)),
- MK_OBSOLETE(Part, _program, sleUint8, VER(8), VER(16)),
- MKLINE(Part, _pri, sleUint8, VER(8)),
- MKLINE(Part, _chan, sleUint8, VER(8)),
- MKLINE(Part, _effect_level, sleUint8, VER(8)),
- MKLINE(Part, _chorus, sleUint8, VER(8)),
- MKLINE(Part, _percussion, sleUint8, VER(8)),
- MKLINE(Part, _bank, sleUint8, VER(8)),
- MKEND()
- };
-
+void Part::saveLoadWithSerializer(Common::Serializer &ser) {
int num;
- if (ser->isSaving()) {
+ if (ser.isSaving()) {
num = (_next ? (_next - _se->_parts + 1) : 0);
- ser->saveUint16(num);
+ ser.syncAsUint16LE(num);
num = (_prev ? (_prev - _se->_parts + 1) : 0);
- ser->saveUint16(num);
+ ser.syncAsUint16LE(num);
num = (_player ? (_player - _se->_players + 1) : 0);
- ser->saveUint16(num);
+ ser.syncAsUint16LE(num);
} else {
- num = ser->loadUint16();
+ ser.syncAsUint16LE(num);
_next = (num ? &_se->_parts[num - 1] : 0);
- num = ser->loadUint16();
+ ser.syncAsUint16LE(num);
_prev = (num ? &_se->_parts[num - 1] : 0);
- num = ser->loadUint16();
+ ser.syncAsUint16LE(num);
_player = (num ? &_se->_players[num - 1] : 0);
}
- ser->saveLoadEntries(this, partEntries);
+
+ ser.syncAsSint16LE(_pitchbend, VER(8));
+ ser.syncAsByte(_pitchbend_factor, VER(8));
+ ser.syncAsSByte(_transpose, VER(8));
+ ser.syncAsByte(_vol, VER(8));
+ ser.syncAsSByte(_detune, VER(8));
+ ser.syncAsSByte(_pan, VER(8));
+ ser.syncAsByte(_on, VER(8));
+ ser.syncAsByte(_modwheel, VER(8));
+ ser.syncAsByte(_pedal, VER(8));
+ ser.skip(1, VER(8), VER(16)); // _program
+ ser.syncAsByte(_pri, VER(8));
+ ser.syncAsByte(_chan, VER(8));
+ ser.syncAsByte(_effect_level, VER(8));
+ ser.syncAsByte(_chorus, VER(8));
+ ser.syncAsByte(_percussion, VER(8));
+ ser.syncAsByte(_bank, VER(8));
}
void Part::set_detune(int8 detune) {
diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp
index 33b38eec72..a4b79f75d3 100644
--- a/engines/scumm/imuse/imuse_player.cpp
+++ b/engines/scumm/imuse/imuse_player.cpp
@@ -1033,70 +1033,63 @@ void Player::metaEvent(byte type, byte *msg, uint16 len) {
//
////////////////////////////////////////
-void Player::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry playerEntries[] = {
- MKLINE(Player, _active, sleByte, VER(8)),
- MKLINE(Player, _id, sleUint16, VER(8)),
- MKLINE(Player, _priority, sleByte, VER(8)),
- MKLINE(Player, _volume, sleByte, VER(8)),
- MKLINE(Player, _pan, sleInt8, VER(8)),
- MKLINE(Player, _transpose, sleByte, VER(8)),
- MKLINE(Player, _detune, sleInt8, VER(8)),
- MKLINE(Player, _vol_chan, sleUint16, VER(8)),
- MKLINE(Player, _vol_eff, sleByte, VER(8)),
- MKLINE(Player, _speed, sleByte, VER(8)),
- MK_OBSOLETE(Player, _song_index, sleUint16, VER(8), VER(19)),
- MKLINE(Player, _track_index, sleUint16, VER(8)),
- MK_OBSOLETE(Player, _timer_counter, sleUint16, VER(8), VER(17)),
- MKLINE(Player, _loop_to_beat, sleUint16, VER(8)),
- MKLINE(Player, _loop_from_beat, sleUint16, VER(8)),
- MKLINE(Player, _loop_counter, sleUint16, VER(8)),
- MKLINE(Player, _loop_to_tick, sleUint16, VER(8)),
- MKLINE(Player, _loop_from_tick, sleUint16, VER(8)),
- MK_OBSOLETE(Player, _tempo, sleUint32, VER(8), VER(19)),
- MK_OBSOLETE(Player, _cur_pos, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _next_pos, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _song_offset, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _tick_index, sleUint16, VER(8), VER(17)),
- MK_OBSOLETE(Player, _beat_index, sleUint16, VER(8), VER(17)),
- MK_OBSOLETE(Player, _ticks_per_beat, sleUint16, VER(8), VER(17)),
- MKLINE(Player, _music_tick, sleUint32, VER(19)),
- MKLINE(Player, _hook._jump[0], sleByte, VER(8)),
- MKLINE(Player, _hook._transpose, sleByte, VER(8)),
- MKARRAY(Player, _hook._part_onoff[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_volume[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_program[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_transpose[0], sleByte, 16, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry parameterFaderEntries[] = {
- MKLINE(ParameterFader, param, sleInt16, VER(17)),
- MKLINE(ParameterFader, start, sleInt16, VER(17)),
- MKLINE(ParameterFader, end, sleInt16, VER(17)),
- MKLINE(ParameterFader, total_time, sleUint32, VER(17)),
- MKLINE(ParameterFader, current_time, sleUint32, VER(17)),
- MKEND()
- };
-
- if (!ser->isSaving() && _parser) {
+static void syncWithSerializer(Common::Serializer &s, ParameterFader &pf) {
+ s.syncAsSint16LE(pf.param, VER(17));
+ s.syncAsSint16LE(pf.start, VER(17));
+ s.syncAsSint16LE(pf.end, VER(17));
+ s.syncAsUint32LE(pf.total_time, VER(17));
+ s.syncAsUint32LE(pf.current_time, VER(17));
+}
+
+void Player::saveLoadWithSerializer(Common::Serializer &s) {
+ if (!s.isSaving() && _parser) {
delete _parser;
_parser = 0;
}
_music_tick = _parser ? _parser->getTick() : 0;
int num;
- if (ser->isSaving()) {
+ if (s.isSaving()) {
num = (_parts ? (_parts - _se->_parts + 1) : 0);
- ser->saveUint16(num);
+ s.syncAsUint16LE(num);
} else {
- num = ser->loadUint16();
+ s.syncAsUint16LE(num);
_parts = (num ? &_se->_parts[num - 1] : 0);
}
- ser->saveLoadEntries(this, playerEntries);
- ser->saveLoadArrayOf(_parameterFaders, ARRAYSIZE(_parameterFaders),
- sizeof(ParameterFader), parameterFaderEntries);
- return;
+
+ s.syncAsByte(_active, VER(8));
+ s.syncAsUint16LE(_id, VER(8));
+ s.syncAsByte(_priority, VER(8));
+ s.syncAsByte(_volume, VER(8));
+ s.syncAsSByte(_pan, VER(8));
+ s.syncAsByte(_transpose, VER(8));
+ s.syncAsSByte(_detune, VER(8));
+ s.syncAsUint16LE(_vol_chan, VER(8));
+ s.syncAsByte(_vol_eff, VER(8));
+ s.syncAsByte(_speed, VER(8));
+ s.skip(2, VER(8), VER(19)); // _song_index
+ s.syncAsUint16LE(_track_index, VER(8));
+ s.skip(2, VER(8), VER(17)); // _timer_counter
+ s.syncAsUint16LE(_loop_to_beat, VER(8));
+ s.syncAsUint16LE(_loop_from_beat, VER(8));
+ s.syncAsUint16LE(_loop_counter, VER(8));
+ s.syncAsUint16LE(_loop_to_tick, VER(8));
+ s.syncAsUint16LE(_loop_from_tick, VER(8));
+ s.skip(4, VER(8), VER(19)); // _tempo
+ s.skip(4, VER(8), VER(17)); // _cur_pos
+ s.skip(4, VER(8), VER(17)); // _next_pos
+ s.skip(4, VER(8), VER(17)); // _song_offset
+ s.skip(2, VER(8), VER(17)); // _tick_index
+ s.skip(2, VER(8), VER(17)); // _beat_index
+ s.skip(2, VER(8), VER(17)); // _ticks_per_beat
+ s.syncAsUint32LE(_music_tick, VER(19));
+ s.syncAsByte(_hook._jump[0], VER(8));
+ s.syncAsByte(_hook._transpose, VER(8));
+ s.syncBytes(_hook._part_onoff, 16, VER(8));
+ s.syncBytes(_hook._part_volume, 16, VER(8));
+ s.syncBytes(_hook._part_program, 16, VER(8));
+ s.syncBytes(_hook._part_transpose, 16, VER(8));
+ s.syncArray(_parameterFaders, ARRAYSIZE(_parameterFaders), syncWithSerializer);
}
} // End of namespace Scumm
diff --git a/engines/scumm/imuse/instrument.cpp b/engines/scumm/imuse/instrument.cpp
index 670b3647eb..708a98046b 100644
--- a/engines/scumm/imuse/instrument.cpp
+++ b/engines/scumm/imuse/instrument.cpp
@@ -20,7 +20,6 @@
*
*/
-
#include "scumm/scumm.h"
#include "scumm/saveload.h"
#include "scumm/imuse/instrument.h"
@@ -132,8 +131,8 @@ private:
public:
Instrument_Program(byte program, bool mt32);
- Instrument_Program(Serializer *s);
- void saveOrLoad(Serializer *s);
+ Instrument_Program(Common::Serializer &s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc);
void copy_to(Instrument *dest) { dest->program(_program, _mt32); }
bool is_valid() {
@@ -178,8 +177,8 @@ private:
public:
Instrument_AdLib(const byte *data);
- Instrument_AdLib(Serializer *s);
- void saveOrLoad(Serializer *s);
+ Instrument_AdLib(Common::Serializer &s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc);
void copy_to(Instrument *dest) { dest->adlib((byte *)&_instrument); }
bool is_valid() { return true; }
@@ -259,8 +258,8 @@ private:
public:
Instrument_Roland(const byte *data);
- Instrument_Roland(Serializer *s);
- void saveOrLoad(Serializer *s);
+ Instrument_Roland(Common::Serializer &s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc);
void copy_to(Instrument *dest) { dest->roland((byte *)&_instrument); }
bool is_valid() { return (_native_mt32 ? true : (_instrument_name[0] != '\0')); }
@@ -269,8 +268,8 @@ public:
class Instrument_PcSpk : public InstrumentInternal {
public:
Instrument_PcSpk(const byte *data);
- Instrument_PcSpk(Serializer *s);
- void saveOrLoad(Serializer *s);
+ Instrument_PcSpk(Common::Serializer &s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc);
void copy_to(Instrument *dest) { dest->pcspk((byte *)&_instrument); }
bool is_valid() { return true; }
@@ -285,8 +284,8 @@ private:
public:
Instrument_MacSfx(byte program);
- Instrument_MacSfx(Serializer *s);
- void saveOrLoad(Serializer *s);
+ Instrument_MacSfx(Common::Serializer &s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc);
void copy_to(Instrument *dest) { dest->macSfx(_program); }
bool is_valid() {
@@ -350,14 +349,14 @@ void Instrument::macSfx(byte prog) {
_instrument = new Instrument_MacSfx(prog);
}
-void Instrument::saveOrLoad(Serializer *s) {
- if (s->isSaving()) {
- s->saveByte(_type);
+void Instrument::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.isSaving()) {
+ s.syncAsByte(_type);
if (_instrument)
- _instrument->saveOrLoad(s);
+ _instrument->saveLoadWithSerializer(s);
} else {
clear();
- _type = s->loadByte();
+ s.syncAsByte(_type);
switch (_type) {
case itNone:
break;
@@ -396,20 +395,21 @@ Instrument_Program::Instrument_Program(byte program, bool mt32) :
_program = 255;
}
-Instrument_Program::Instrument_Program(Serializer *s) {
+Instrument_Program::Instrument_Program(Common::Serializer &s) {
_program = 255;
_mt32 = false;
- if (!s->isSaving())
- saveOrLoad(s);
+ if (!s.isSaving())
+ saveLoadWithSerializer(s);
}
-void Instrument_Program::saveOrLoad(Serializer *s) {
- if (s->isSaving()) {
- s->saveByte(_program);
- s->saveByte(_mt32 ? 1 : 0);
+void Instrument_Program::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsByte(_program);
+ if (s.isSaving()) {
+ s.syncAsByte(_mt32);
} else {
- _program = s->loadByte();
- _mt32 = (s->loadByte() > 0);
+ byte tmp;
+ s.syncAsByte(tmp);
+ _mt32 = (tmp > 0);
}
}
@@ -434,18 +434,15 @@ Instrument_AdLib::Instrument_AdLib(const byte *data) {
memcpy(&_instrument, data, sizeof(_instrument));
}
-Instrument_AdLib::Instrument_AdLib(Serializer *s) {
- if (!s->isSaving())
- saveOrLoad(s);
+Instrument_AdLib::Instrument_AdLib(Common::Serializer &s) {
+ if (!s.isSaving())
+ saveLoadWithSerializer(s);
else
memset(&_instrument, 0, sizeof(_instrument));
}
-void Instrument_AdLib::saveOrLoad(Serializer *s) {
- if (s->isSaving())
- s->saveBytes(&_instrument, sizeof(_instrument));
- else
- s->loadBytes(&_instrument, sizeof(_instrument));
+void Instrument_AdLib::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncBytes((byte *)(&_instrument), sizeof(_instrument));
}
void Instrument_AdLib::send(MidiChannel *mc) {
@@ -468,26 +465,24 @@ Instrument_Roland::Instrument_Roland(const byte *data) {
}
}
-Instrument_Roland::Instrument_Roland(Serializer *s) {
+Instrument_Roland::Instrument_Roland(Common::Serializer &s) {
_instrument_name[0] = '\0';
- if (!s->isSaving())
- saveOrLoad(s);
+ if (!s.isSaving())
+ saveLoadWithSerializer(s);
else
memset(&_instrument, 0, sizeof(_instrument));
}
-void Instrument_Roland::saveOrLoad(Serializer *s) {
- if (s->isSaving()) {
- s->saveBytes(&_instrument, sizeof(_instrument));
- } else {
- s->loadBytes(&_instrument, sizeof(_instrument));
+void Instrument_Roland::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncBytes((byte *)(&_instrument), sizeof(_instrument));
+ if (!s.isSaving()) {
memcpy(&_instrument_name, &_instrument.common.name, sizeof(_instrument.common.name));
_instrument_name[10] = '\0';
if (!_native_mt32 && getEquivalentGM() >= 128) {
debug(2, "MT-32 custom instrument \"%s\" not supported", _instrument_name);
_instrument_name[0] = '\0';
}
- } // end if
+ }
}
void Instrument_Roland::send(MidiChannel *mc) {
@@ -538,18 +533,15 @@ Instrument_PcSpk::Instrument_PcSpk(const byte *data) {
memcpy(_instrument, data, sizeof(_instrument));
}
-Instrument_PcSpk::Instrument_PcSpk(Serializer *s) {
- if (!s->isSaving())
- saveOrLoad(s);
+Instrument_PcSpk::Instrument_PcSpk(Common::Serializer &s) {
+ if (!s.isSaving())
+ saveLoadWithSerializer(s);
else
memset(_instrument, 0, sizeof(_instrument));
}
-void Instrument_PcSpk::saveOrLoad(Serializer *s) {
- if (s->isSaving())
- s->saveBytes(_instrument, sizeof(_instrument));
- else
- s->loadBytes(_instrument, sizeof(_instrument));
+void Instrument_PcSpk::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncBytes(_instrument, sizeof(_instrument));
}
void Instrument_PcSpk::send(MidiChannel *mc) {
@@ -569,19 +561,15 @@ Instrument_MacSfx::Instrument_MacSfx(byte program) :
}
}
-Instrument_MacSfx::Instrument_MacSfx(Serializer *s) {
+Instrument_MacSfx::Instrument_MacSfx(Common::Serializer &s) {
_program = 255;
- if (!s->isSaving()) {
- saveOrLoad(s);
+ if (!s.isSaving()) {
+ saveLoadWithSerializer(s);
}
}
-void Instrument_MacSfx::saveOrLoad(Serializer *s) {
- if (s->isSaving()) {
- s->saveByte(_program);
- } else {
- _program = s->loadByte();
- }
+void Instrument_MacSfx::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsByte(_program);
}
void Instrument_MacSfx::send(MidiChannel *mc) {
diff --git a/engines/scumm/imuse/instrument.h b/engines/scumm/imuse/instrument.h
index 47f556b40b..374b6352f1 100644
--- a/engines/scumm/imuse/instrument.h
+++ b/engines/scumm/imuse/instrument.h
@@ -25,24 +25,23 @@
#include "common/scummsys.h"
+#include "common/serializer.h"
class MidiChannel;
namespace Scumm {
-class Serializer;
class Instrument;
-class InstrumentInternal {
+class InstrumentInternal : public Common::Serializable {
public:
virtual ~InstrumentInternal() {}
- virtual void saveOrLoad(Serializer *s) = 0;
virtual void send(MidiChannel *mc) = 0;
virtual void copy_to(Instrument *dest) = 0;
virtual bool is_valid() = 0;
};
-class Instrument {
+class Instrument : public Common::Serializable {
private:
byte _type;
InstrumentInternal *_instrument;
@@ -78,7 +77,7 @@ public:
byte getType() { return _type; }
bool isValid() { return (_instrument ? _instrument->is_valid() : false); }
- void saveOrLoad(Serializer *s);
+ void saveLoadWithSerializer(Common::Serializer &s);
void send(MidiChannel *mc) {
if (_instrument)
_instrument->send(mc);
diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp
index 3f61946bf2..9dac8b7662 100644
--- a/engines/scumm/imuse_digi/dimuse.cpp
+++ b/engines/scumm/imuse_digi/dimuse.cpp
@@ -103,61 +103,55 @@ void IMuseDigital::resetState() {
_triggerUsed = false;
}
-void IMuseDigital::saveOrLoad(Serializer *ser) {
- Common::StackLock lock(_mutex, "IMuseDigital::saveOrLoad()");
-
- const SaveLoadEntry mainEntries[] = {
- MK_OBSOLETE(IMuseDigital, _volVoice, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(IMuseDigital, _volSfx, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(IMuseDigital, _volMusic, sleInt32, VER(31), VER(42)),
- MKLINE(IMuseDigital, _curMusicState, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _curMusicSeq, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _curMusicCue, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _nextSeqToPlay, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _radioChatterSFX, sleByte, VER(76)),
- MKARRAY(IMuseDigital, _attributes[0], sleInt32, 188, VER(31)),
- MKEND()
- };
-
- const SaveLoadEntry trackEntries[] = {
- MKLINE(Track, pan, sleInt8, VER(31)),
- MKLINE(Track, vol, sleInt32, VER(31)),
- MKLINE(Track, volFadeDest, sleInt32, VER(31)),
- MKLINE(Track, volFadeStep, sleInt32, VER(31)),
- MKLINE(Track, volFadeDelay, sleInt32, VER(31)),
- MKLINE(Track, volFadeUsed, sleByte, VER(31)),
- MKLINE(Track, soundId, sleInt32, VER(31)),
- MKARRAY(Track, soundName[0], sleByte, 15, VER(31)),
- MKLINE(Track, used, sleByte, VER(31)),
- MKLINE(Track, toBeRemoved, sleByte, VER(31)),
- MKLINE(Track, souStreamUsed, sleByte, VER(31)),
- MK_OBSOLETE(Track, mixerStreamRunning, sleByte, VER(31), VER(76)),
- MKLINE(Track, soundPriority, sleInt32, VER(31)),
- MKLINE(Track, regionOffset, sleInt32, VER(31)),
- MK_OBSOLETE(Track, trackOffset, sleInt32, VER(31), VER(31)),
- MKLINE(Track, dataOffset, sleInt32, VER(31)),
- MKLINE(Track, curRegion, sleInt32, VER(31)),
- MKLINE(Track, curHookId, sleInt32, VER(31)),
- MKLINE(Track, volGroupId, sleInt32, VER(31)),
- MKLINE(Track, soundType, sleInt32, VER(31)),
- MKLINE(Track, feedSize, sleInt32, VER(31)),
- MKLINE(Track, dataMod12Bit, sleInt32, VER(31)),
- MKLINE(Track, mixerFlags, sleInt32, VER(31)),
- MK_OBSOLETE(Track, mixerVol, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(Track, mixerPan, sleInt32, VER(31), VER(42)),
- MKLINE(Track, sndDataExtComp, sleByte, VER(45)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, mainEntries);
+static void syncWithSerializer(Common::Serializer &s, Track &t) {
+ s.syncAsSByte(t.pan, VER(31));
+ s.syncAsSint32LE(t.vol, VER(31));
+ s.syncAsSint32LE(t.volFadeDest, VER(31));
+ s.syncAsSint32LE(t.volFadeStep, VER(31));
+ s.syncAsSint32LE(t.volFadeDelay, VER(31));
+ s.syncAsByte(t.volFadeUsed, VER(31));
+ s.syncAsSint32LE(t.soundId, VER(31));
+ s.syncArray(t.soundName, 15, Common::Serializer::SByte, VER(31));
+ s.syncAsByte(t.used, VER(31));
+ s.syncAsByte(t.toBeRemoved, VER(31));
+ s.syncAsByte(t.souStreamUsed, VER(31));
+ s.skip(1, VER(31), VER(76)); // mixerStreamRunning
+ s.syncAsSint32LE(t.soundPriority, VER(31));
+ s.syncAsSint32LE(t.regionOffset, VER(31));
+ s.skip(4, VER(31), VER(31)); // trackOffset
+ s.syncAsSint32LE(t.dataOffset, VER(31));
+ s.syncAsSint32LE(t.curRegion, VER(31));
+ s.syncAsSint32LE(t.curHookId, VER(31));
+ s.syncAsSint32LE(t.volGroupId, VER(31));
+ s.syncAsSint32LE(t.soundType, VER(31));
+ s.syncAsSint32LE(t.feedSize, VER(31));
+ s.syncAsSint32LE(t.dataMod12Bit, VER(31));
+ s.syncAsSint32LE(t.mixerFlags, VER(31));
+ s.skip(4, VER(31), VER(42)); // mixerVol
+ s.skip(4, VER(31), VER(42)); // mixerPan
+ s.syncAsByte(t.sndDataExtComp, VER(45));
+}
+
+void IMuseDigital::saveLoadEarly(Common::Serializer &s) {
+ Common::StackLock lock(_mutex, "IMuseDigital::saveLoadEarly()");
+
+ s.skip(4, VER(31), VER(42)); // _volVoice
+ s.skip(4, VER(31), VER(42)); // _volSfx
+ s.skip(4, VER(31), VER(42)); // _volMusic
+ s.syncAsSint32LE(_curMusicState, VER(31));
+ s.syncAsSint32LE(_curMusicSeq, VER(31));
+ s.syncAsSint32LE(_curMusicCue, VER(31));
+ s.syncAsSint32LE(_nextSeqToPlay, VER(31));
+ s.syncAsByte(_radioChatterSFX, VER(76));
+ s.syncArray(_attributes, 188, Common::Serializer::Sint32LE, VER(31));
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
Track *track = _track[l];
- if (ser->isLoading()) {
+ if (s.isLoading()) {
memset(track, 0, sizeof(Track));
}
- ser->saveLoadEntries(track, trackEntries);
- if (ser->isLoading()) {
+ syncWithSerializer(s, *track);
+ if (s.isLoading()) {
_track[l]->trackId = l;
if (!track->used)
continue;
diff --git a/engines/scumm/imuse_digi/dimuse.h b/engines/scumm/imuse_digi/dimuse.h
index 02f899df85..86c8d21bcc 100644
--- a/engines/scumm/imuse_digi/dimuse.h
+++ b/engines/scumm/imuse_digi/dimuse.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/mutex.h"
+#include "common/serializer.h"
#include "common/textconsole.h"
#include "common/util.h"
@@ -48,7 +49,6 @@ enum {
struct imuseDigTable;
struct imuseComiTable;
-class Serializer;
class ScummEngine_v7;
struct Track;
@@ -136,7 +136,7 @@ public:
void startSound(int sound)
{ error("IMuseDigital::startSound(int) should be never called"); }
- void saveOrLoad(Serializer *ser);
+ void saveLoadEarly(Common::Serializer &ser);
void resetState();
void setRadioChatterSFX(bool state) {
_radioChatterSFX = state;
diff --git a/engines/scumm/music.h b/engines/scumm/music.h
index e170647560..9404ce7af3 100644
--- a/engines/scumm/music.h
+++ b/engines/scumm/music.h
@@ -23,12 +23,11 @@
#ifndef SCUMM_MUSIC_H
#define SCUMM_MUSIC_H
+#include "common/serializer.h"
#include "common/scummsys.h"
namespace Scumm {
-class Serializer;
-
/**
* Pure virtual base class for the various music/sound engines used in Scumm
* games. In particular, the iMuse code provides a subclass of this. There are
@@ -39,7 +38,7 @@ class Serializer;
*
* Instantiated by class Scumm.
*/
-class MusicEngine {
+class MusicEngine : public Common::Serializable {
public:
virtual ~MusicEngine() {}
@@ -84,7 +83,7 @@ public:
/**
* Save or load the music state.
*/
- virtual void saveLoadWithSerializer(Serializer *ser) {}
+ virtual void saveLoadWithSerializer(Common::Serializer &ser) {}
};
} // End of namespace Scumm
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 55bbeeef98..2de8ac96e4 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -191,27 +191,27 @@ int Player_AD::getSoundStatus(int sound) const {
return false;
}
-void Player_AD::saveLoadWithSerializer(Serializer *ser) {
+void Player_AD::saveLoadWithSerializer(Common::Serializer &s) {
Common::StackLock lock(_mutex);
- if (ser->getVersion() < VER(95)) {
+ if (s.getVersion() < VER(95)) {
IMuse *dummyImuse = IMuse::create(_vm->_system, NULL, NULL);
- dummyImuse->save_or_load(ser, _vm, false);
+ dummyImuse->saveLoadWithSerializer(s, _vm, false);
delete dummyImuse;
return;
}
- if (ser->getVersion() >= VER(96)) {
+ if (s.getVersion() >= VER(96)) {
int32 res[4] = {
_musicResource, _sfx[0].resource, _sfx[1].resource, _sfx[2].resource
};
// The first thing we save is a list of sound resources being played
// at the moment.
- ser->saveLoadArrayOf(res, 4, sizeof(res[0]), sleInt32);
+ s.syncArray(res, 4, Common::Serializer::Sint32LE);
// If we are loading start the music again at this point.
- if (ser->isLoading()) {
+ if (s.isLoading()) {
if (res[0] != -1) {
startSound(res[0]);
}
@@ -219,26 +219,21 @@ void Player_AD::saveLoadWithSerializer(Serializer *ser) {
uint32 musicOffset = _curOffset;
- static const SaveLoadEntry musicData[] = {
- MKLINE(Player_AD, _engineMusicTimer, sleInt32, VER(96)),
- MKLINE(Player_AD, _musicTimer, sleUint32, VER(96)),
- MKLINE(Player_AD, _internalMusicTimer, sleUint32, VER(96)),
- MKLINE(Player_AD, _curOffset, sleUint32, VER(96)),
- MKLINE(Player_AD, _nextEventTimer, sleUint32, VER(96)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, musicData);
+ s.syncAsSint32LE(_engineMusicTimer, VER(96));
+ s.syncAsUint32LE(_musicTimer, VER(96));
+ s.syncAsUint32LE(_internalMusicTimer, VER(96));
+ s.syncAsUint32LE(_curOffset, VER(96));
+ s.syncAsUint32LE(_nextEventTimer, VER(96));
// We seek back to the old music position.
- if (ser->isLoading()) {
+ if (s.isLoading()) {
SWAP(musicOffset, _curOffset);
musicSeekTo(musicOffset);
}
// Finally start up the SFX. This makes sure that they are not
// accidently stopped while seeking to the old music position.
- if (ser->isLoading()) {
+ if (s.isLoading()) {
for (int i = 1; i < ARRAYSIZE(res); ++i) {
if (res[i] != -1) {
startSound(res[i]);
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index 1e665e82d5..20c8b3d475 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -26,6 +26,7 @@
#include "scumm/music.h"
#include "common/mutex.h"
+#include "common/serializer.h"
namespace OPL {
class OPL;
@@ -34,7 +35,6 @@ class OPL;
namespace Scumm {
class ScummEngine;
-class Serializer;
/**
* Sound output for v3/v4 AdLib data.
@@ -52,7 +52,7 @@ public:
virtual int getMusicTimer();
virtual int getSoundStatus(int sound) const;
- virtual void saveLoadWithSerializer(Serializer *ser);
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
// Timer callback
void onTimer();
diff --git a/engines/scumm/players/player_mac.cpp b/engines/scumm/players/player_mac.cpp
index 87406f4e34..cc65adceab 100644
--- a/engines/scumm/players/player_mac.cpp
+++ b/engines/scumm/players/player_mac.cpp
@@ -97,53 +97,46 @@ Player_Mac::~Player_Mac() {
delete[] _channel;
}
-void Player_Mac::saveLoadWithSerializer(Serializer *ser) {
+void syncWithSerializer(Common::Serializer &s, Player_Mac::Channel &c) {
+ s.syncAsUint16LE(c._pos, VER(94));
+ s.syncAsSint32LE(c._pitchModifier, VER(94));
+ s.syncAsByte(c._velocity, VER(94));
+ s.syncAsUint32LE(c._remaining, VER(94));
+ s.syncAsByte(c._notesLeft, VER(94));
+}
+
+void syncWithSerializer(Common::Serializer &s, Player_Mac::Instrument &i) {
+ s.syncAsUint32LE(i._pos, VER(94));
+ s.syncAsUint32LE(i._subPos, VER(94));
+}
+
+void Player_Mac::saveLoadWithSerializer(Common::Serializer &s) {
Common::StackLock lock(_mutex);
- if (ser->getVersion() < VER(94)) {
- if (_vm->_game.id == GID_MONKEY && ser->isLoading()) {
+ if (s.getVersion() < VER(94)) {
+ if (_vm->_game.id == GID_MONKEY && s.isLoading()) {
IMuse *dummyImuse = IMuse::create(_vm->_system, NULL, NULL);
- dummyImuse->save_or_load(ser, _vm, false);
+ dummyImuse->saveLoadWithSerializer(s, _vm, false);
delete dummyImuse;
}
} else {
- static const SaveLoadEntry musicEntries[] = {
- MKLINE(Player_Mac, _sampleRate, sleUint32, VER(94)),
- MKLINE(Player_Mac, _soundPlaying, sleInt16, VER(94)),
- MKEND()
- };
-
- static const SaveLoadEntry channelEntries[] = {
- MKLINE(Channel, _pos, sleUint16, VER(94)),
- MKLINE(Channel, _pitchModifier, sleInt32, VER(94)),
- MKLINE(Channel, _velocity, sleUint8, VER(94)),
- MKLINE(Channel, _remaining, sleUint32, VER(94)),
- MKLINE(Channel, _notesLeft, sleUint8, VER(94)),
- MKEND()
- };
-
- static const SaveLoadEntry instrumentEntries[] = {
- MKLINE(Instrument, _pos, sleUint32, VER(94)),
- MKLINE(Instrument, _subPos, sleUint32, VER(94)),
- MKEND()
- };
-
uint32 mixerSampleRate = _sampleRate;
int i;
- ser->saveLoadEntries(this, musicEntries);
+ s.syncAsUint32LE(_sampleRate, VER(94));
+ s.syncAsSint16LE(_soundPlaying, VER(94));
- if (ser->isLoading() && _soundPlaying != -1) {
+ if (s.isLoading() && _soundPlaying != -1) {
const byte *ptr = _vm->getResourceAddress(rtSound, _soundPlaying);
assert(ptr);
loadMusic(ptr);
}
- ser->saveLoadArrayOf(_channel, _numberOfChannels, sizeof(Channel), channelEntries);
+ s.syncArray(_channel, _numberOfChannels, syncWithSerializer);
for (i = 0; i < _numberOfChannels; i++) {
- ser->saveLoadEntries(&_channel[i], instrumentEntries);
+ syncWithSerializer(s, _channel[i]);
}
- if (ser->isLoading()) {
+ if (s.isLoading()) {
// If necessary, adjust the channel data to fit the
// current sample rate.
if (_soundPlaying != -1 && _sampleRate != mixerSampleRate) {
diff --git a/engines/scumm/players/player_mac.h b/engines/scumm/players/player_mac.h
index d247ce9883..897960d775 100644
--- a/engines/scumm/players/player_mac.h
+++ b/engines/scumm/players/player_mac.h
@@ -63,7 +63,7 @@ public:
virtual bool endOfData() const { return false; }
virtual int getRate() const { return _sampleRate; }
- virtual void saveLoadWithSerializer(Serializer *ser);
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
private:
Common::Mutex _mutex;
@@ -92,6 +92,7 @@ private:
void generateSamples(int16 *data, int pitchModifier, int volume, int numSamples, int remainingSamplesOnNote, bool fadeNoteEnds);
};
+ friend void syncWithSerializer(Common::Serializer &, Instrument &);
int _pitchTable[128];
int _numberOfChannels;
@@ -120,6 +121,7 @@ protected:
bool loadInstrument(Common::SeekableReadStream *stream);
};
+ friend void syncWithSerializer(Common::Serializer &, Channel &);
ScummEngine *const _vm;
Channel *_channel;
diff --git a/engines/scumm/players/player_towns.cpp b/engines/scumm/players/player_towns.cpp
index d540fc4f6b..16080205c0 100644
--- a/engines/scumm/players/player_towns.cpp
+++ b/engines/scumm/players/player_towns.cpp
@@ -46,19 +46,18 @@ int Player_Towns::getSoundStatus(int sound) const {
return 0;
}
-void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry pcmEntries[] = {
- MKLINE(PcmCurrentSound, index, sleInt16, VER(81)),
- MKLINE(PcmCurrentSound, chan, sleInt16, VER(81)),
- MKLINE(PcmCurrentSound, note, sleUint8, VER(81)),
- MKLINE(PcmCurrentSound, velo, sleUint8, VER(81)),
- MKLINE(PcmCurrentSound, pan, sleUint8, VER(81)),
- MKLINE(PcmCurrentSound, paused, sleUint8, VER(81)),
- MKLINE(PcmCurrentSound, looping, sleUint8, VER(81)),
- MKLINE(PcmCurrentSound, priority, sleUint32, VER(81)),
- MKEND()
- };
-
+void syncWithSerializer(Common::Serializer &s, Player_Towns::PcmCurrentSound &pcs) {
+ s.syncAsSint16LE(pcs.index, VER(81));
+ s.syncAsSint16LE(pcs.chan, VER(81));
+ s.syncAsByte(pcs.note, VER(81));
+ s.syncAsByte(pcs.velo, VER(81));
+ s.syncAsByte(pcs.pan, VER(81));
+ s.syncAsByte(pcs.paused, VER(81));
+ s.syncAsByte(pcs.looping, VER(81));
+ s.syncAsUint32LE(pcs.priority, VER(81));
+}
+
+void Player_Towns::saveLoadWithSerializer(Common::Serializer &s) {
for (int i = 1; i < 9; i++) {
if (!_pcmCurrentSound[i].index)
continue;
@@ -71,7 +70,7 @@ void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
_pcmCurrentSound[i].index = 0;
}
- ser->saveLoadArrayOf(_pcmCurrentSound, 9, sizeof(PcmCurrentSound), pcmEntries);
+ s.syncArray(_pcmCurrentSound, 9, syncWithSerializer);
}
void Player_Towns::restoreAfterLoad() {
@@ -362,34 +361,24 @@ void Player_Towns_v1::setSoundNote(int sound, int note) {
_soundOverride[sound].note = note;
}
-void Player_Towns_v1::saveLoadWithSerializer(Serializer *ser) {
+void Player_Towns_v1::saveLoadWithSerializer(Common::Serializer &s) {
_cdaCurrentSoundTemp = (_vm->_sound->pollCD() && _cdaNumLoops > 1) ? _cdaCurrentSound & 0xff : 0;
_cdaNumLoopsTemp = _cdaNumLoops & 0xff;
- static const SaveLoadEntry cdEntries[] = {
- MKLINE(Player_Towns_v1, _cdaCurrentSoundTemp, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _cdaNumLoopsTemp, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _cdaVolLeft, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _cdaVolRight, sleUint8, VER(81)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, cdEntries);
+ s.syncAsByte(_cdaCurrentSoundTemp, VER(81));
+ s.syncAsByte(_cdaNumLoopsTemp, VER(81));
+ s.syncAsByte(_cdaVolLeft, VER(81));
+ s.syncAsByte(_cdaVolRight, VER(81));
if (!_eupLooping && !_player->isPlaying())
_eupCurrentSound = 0;
- static const SaveLoadEntry eupEntries[] = {
- MKLINE(Player_Towns_v1, _eupCurrentSound, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _eupLooping, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _eupVolLeft, sleUint8, VER(81)),
- MKLINE(Player_Towns_v1, _eupVolRight, sleUint8, VER(81)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, eupEntries);
+ s.syncAsByte(_eupCurrentSound, VER(81));
+ s.syncAsByte(_eupLooping, VER(81));
+ s.syncAsByte(_eupVolLeft, VER(81));
+ s.syncAsByte(_eupVolRight, VER(81));
- Player_Towns::saveLoadWithSerializer(ser);
+ Player_Towns::saveLoadWithSerializer(s);
}
void Player_Towns_v1::restoreAfterLoad() {
@@ -721,9 +710,9 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
return res;
}
-void Player_Towns_v2::saveLoadWithSerializer(Serializer *ser) {
- if (ser->getVersion() >= 83)
- Player_Towns::saveLoadWithSerializer(ser);
+void Player_Towns_v2::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.getVersion() >= VER(83))
+ Player_Towns::saveLoadWithSerializer(s);
}
void Player_Towns_v2::playVocTrack(const uint8 *data) {
diff --git a/engines/scumm/players/player_towns.h b/engines/scumm/players/player_towns.h
index 576d17e392..ad51c3e561 100644
--- a/engines/scumm/players/player_towns.h
+++ b/engines/scumm/players/player_towns.h
@@ -43,7 +43,7 @@ public:
virtual int32 doCommand(int numargs, int args[]) = 0;
- virtual void saveLoadWithSerializer(Serializer *ser);
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
virtual void restoreAfterLoad();
// version 1 specific
@@ -69,6 +69,7 @@ protected:
uint8 looping;
uint32 priority;
} _pcmCurrentSound[9];
+ friend void syncWithSerializer(Common::Serializer &, PcmCurrentSound &);
uint8 _unkFlags;
@@ -101,7 +102,7 @@ public:
void setSoundVolume(int sound, int left, int right);
void setSoundNote(int sound, int note);
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
void restoreAfterLoad();
private:
@@ -154,7 +155,7 @@ public:
int32 doCommand(int numargs, int args[]);
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
private:
void playVocTrack(const uint8 *data);
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 06d564648b..3e0a7f1ef8 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -23,6 +23,7 @@
#include "common/config-manager.h"
#include "common/memstream.h"
#include "common/savefile.h"
+#include "common/serializer.h"
#include "common/system.h"
#include "common/zlib.h"
@@ -185,8 +186,9 @@ bool ScummEngine::saveState(Common::WriteStream *out, bool writeHeader) {
#endif
saveInfos(out);
- Serializer ser(0, out, CURRENT_VER);
- saveOrLoad(&ser);
+ Common::Serializer ser(0, out);
+ ser.setVersion(CURRENT_VER);
+ saveLoadWithSerializer(ser);
return true;
}
@@ -442,8 +444,9 @@ bool ScummEngine::loadState(int slot, bool compat, Common::String &filename) {
//
// Now do the actual loading
//
- Serializer ser(in, 0, hdr.ver);
- saveOrLoad(&ser);
+ Common::Serializer ser(in, 0);
+ ser.setVersion(hdr.ver);
+ saveLoadWithSerializer(ser);
delete in;
// Update volume settings
@@ -793,334 +796,337 @@ void ScummEngine::saveInfos(Common::WriteStream *file) {
file->writeUint16BE(section.time);
}
-void ScummEngine::saveOrLoad(Serializer *s) {
- const SaveLoadEntry objectEntries[] = {
- MKLINE(ObjectData, OBIMoffset, sleUint32, VER(8)),
- MKLINE(ObjectData, OBCDoffset, sleUint32, VER(8)),
- MKLINE(ObjectData, walk_x, sleUint16, VER(8)),
- MKLINE(ObjectData, walk_y, sleUint16, VER(8)),
- MKLINE(ObjectData, obj_nr, sleUint16, VER(8)),
- MKLINE(ObjectData, x_pos, sleInt16, VER(8)),
- MKLINE(ObjectData, y_pos, sleInt16, VER(8)),
- MKLINE(ObjectData, width, sleUint16, VER(8)),
- MKLINE(ObjectData, height, sleUint16, VER(8)),
- MKLINE(ObjectData, actordir, sleByte, VER(8)),
- MKLINE(ObjectData, parentstate, sleByte, VER(8)),
- MKLINE(ObjectData, parent, sleByte, VER(8)),
- MKLINE(ObjectData, state, sleByte, VER(8)),
- MKLINE(ObjectData, fl_object_index, sleByte, VER(8)),
- MKLINE(ObjectData, flags, sleByte, VER(46)),
- MKEND()
- };
-
- const SaveLoadEntry verbEntries[] = {
- MKLINE(VerbSlot, curRect.left, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.top, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.right, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.bottom, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.left, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.top, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.right, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.bottom, sleInt16, VER(8)),
-
- MKLINE_OLD(VerbSlot, verbid, sleByte, VER(8), VER(11)),
- MKLINE(VerbSlot, verbid, sleInt16, VER(12)),
-
- MKLINE(VerbSlot, color, sleByte, VER(8)),
- MKLINE(VerbSlot, hicolor, sleByte, VER(8)),
- MKLINE(VerbSlot, dimcolor, sleByte, VER(8)),
- MKLINE(VerbSlot, bkcolor, sleByte, VER(8)),
- MKLINE(VerbSlot, type, sleByte, VER(8)),
- MKLINE(VerbSlot, charset_nr, sleByte, VER(8)),
- MKLINE(VerbSlot, curmode, sleByte, VER(8)),
- MKLINE(VerbSlot, saveid, sleByte, VER(8)),
- MKLINE(VerbSlot, key, sleByte, VER(8)),
- MKLINE(VerbSlot, center, sleByte, VER(8)),
- MKLINE(VerbSlot, prep, sleByte, VER(8)),
- MKLINE(VerbSlot, imgindex, sleUint16, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry mainEntries[] = {
- MKARRAY(ScummEngine, _gameMD5[0], sleUint8, 16, VER(39)),
- MK_OBSOLETE(ScummEngine, _roomWidth, sleUint16, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _roomHeight, sleUint16, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _ENCD_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _EXCD_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _IM00_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _CLUT_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _EPAL_offs, sleUint32, VER(8), VER(9)),
- MK_OBSOLETE(ScummEngine, _PALS_offs, sleUint32, VER(8), VER(50)),
- MKLINE(ScummEngine, _curPalIndex, sleByte, VER(8)),
- MKLINE(ScummEngine, _currentRoom, sleByte, VER(8)),
- MKLINE(ScummEngine, _roomResource, sleByte, VER(8)),
- MKLINE(ScummEngine, _numObjectsInRoom, sleByte, VER(8)),
- MKLINE(ScummEngine, _currentScript, sleByte, VER(8)),
- MK_OBSOLETE_ARRAY(ScummEngine, _localScriptOffsets[0], sleUint32, _numLocalScripts, VER(8), VER(50)),
-
-
- // vm.localvar grew from 25 to 40 script entries and then from
- // 16 to 32 bit variables (but that wasn't reflect here)... and
- // THEN from 16 to 25 variables.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 25, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(8), VER(8)),
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 40, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(9), VER(14)),
-
- // We used to save 25 * 40 = 1000 blocks; but actually, each 'row consisted of 26 entry,
- // i.e. 26 * 40 = 1040. Thus the last 40 blocks of localvar where not saved at all. To be
- // able to load this screwed format, we use a trick: We load 26 * 38 = 988 blocks.
- // Then, we mark the followin 12 blocks (24 bytes) as obsolete.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 26, 38, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(15), VER(17)),
- MK_OBSOLETE_ARRAY(ScummEngine, vm.localvar[39][0], sleUint16, 12, VER(15), VER(17)),
-
- // This was the first proper multi dimensional version of the localvars, with 32 bit values
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint32, 26, 40, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(18), VER(19)),
-
- // Then we doubled the script slots again, from 40 to 80
- MKARRAY2(ScummEngine, vm.localvar[0][0], sleUint32, 26, NUM_SCRIPT_SLOT, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(20)),
-
-
- MKARRAY(ScummEngine, _resourceMapper[0], sleByte, 128, VER(8)),
- MKARRAY(ScummEngine, _charsetColorMap[0], sleByte, 16, VER(8)),
-
- // _charsetData grew from 10*16, to 15*16, to 23*16 bytes
- MKARRAY_OLD(ScummEngine, _charsetData[0][0], sleByte, 10 * 16, VER(8), VER(9)),
- MKARRAY_OLD(ScummEngine, _charsetData[0][0], sleByte, 15 * 16, VER(10), VER(66)),
- MKARRAY(ScummEngine, _charsetData[0][0], sleByte, 23 * 16, VER(67)),
-
- MK_OBSOLETE(ScummEngine, _curExecScript, sleUint16, VER(8), VER(62)),
-
- MKLINE(ScummEngine, camera._dest.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._dest.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._cur.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._cur.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._last.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._last.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._accel.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._accel.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, _screenStartStrip, sleInt16, VER(8)),
- MKLINE(ScummEngine, _screenEndStrip, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._mode, sleByte, VER(8)),
- MKLINE(ScummEngine, camera._follows, sleByte, VER(8)),
- MKLINE(ScummEngine, camera._leftTrigger, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._rightTrigger, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._movingToActor, sleUint16, VER(8)),
-
- MKLINE(ScummEngine, _actorToPrintStrFor, sleByte, VER(8)),
- MKLINE(ScummEngine, _charsetColor, sleByte, VER(8)),
-
- // _charsetBufPos was changed from byte to int
- MKLINE_OLD(ScummEngine, _charsetBufPos, sleByte, VER(8), VER(9)),
- MKLINE(ScummEngine, _charsetBufPos, sleInt16, VER(10)),
-
- MKLINE(ScummEngine, _haveMsg, sleByte, VER(8)),
- MKLINE(ScummEngine, _haveActorSpeechMsg, sleByte, VER(61)),
- MKLINE(ScummEngine, _useTalkAnims, sleByte, VER(8)),
-
- MKLINE(ScummEngine, _talkDelay, sleInt16, VER(8)),
- MKLINE(ScummEngine, _defaultTalkDelay, sleInt16, VER(8)),
- MK_OBSOLETE(ScummEngine, _numInMsgStack, sleInt16, VER(8), VER(27)),
- MKLINE(ScummEngine, _sentenceNum, sleByte, VER(8)),
-
- MKLINE(ScummEngine, vm.cutSceneStackPointer, sleByte, VER(8)),
- MKARRAY(ScummEngine, vm.cutScenePtr[0], sleUint32, 5, VER(8)),
- MKARRAY(ScummEngine, vm.cutSceneScript[0], sleByte, 5, VER(8)),
- MKARRAY(ScummEngine, vm.cutSceneData[0], sleInt16, 5, VER(8)),
- MKLINE(ScummEngine, vm.cutSceneScriptIndex, sleInt16, VER(8)),
-
- MKLINE(ScummEngine, vm.numNestedScripts, sleByte, VER(8)),
- MKLINE(ScummEngine, _userPut, sleByte, VER(8)),
- MKLINE(ScummEngine, _userState, sleUint16, VER(17)),
- MKLINE(ScummEngine, _cursor.state, sleByte, VER(8)),
- MK_OBSOLETE(ScummEngine, _gdi->_cursorActive, sleByte, VER(8), VER(20)),
- MKLINE(ScummEngine, _currentCursor, sleByte, VER(8)),
- MKARRAY(ScummEngine, _grabbedCursor[0], sleByte, 8192, VER(20)),
- MKLINE(ScummEngine, _cursor.width, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.height, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.hotspotX, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.hotspotY, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.animate, sleByte, VER(20)),
- MKLINE(ScummEngine, _cursor.animateIndex, sleByte, VER(20)),
- MKLINE(ScummEngine, _mouse.x, sleInt16, VER(20)),
- MKLINE(ScummEngine, _mouse.y, sleInt16, VER(20)),
-
- MKARRAY(ScummEngine, _colorUsedByCycle[0], sleByte, 256, VER(60)),
- MKLINE(ScummEngine, _doEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _switchRoomEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _newEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _switchRoomEffect2, sleByte, VER(8)),
- MKLINE(ScummEngine, _bgNeedsRedraw, sleByte, VER(8)),
-
- // The state of palManipulate is stored only since V10
- MKLINE(ScummEngine, _palManipStart, sleByte, VER(10)),
- MKLINE(ScummEngine, _palManipEnd, sleByte, VER(10)),
- MKLINE(ScummEngine, _palManipCounter, sleUint16, VER(10)),
-
- // gfxUsageBits grew from 200 to 410 entries. Then 3 * 410 entries:
- MKARRAY_OLD(ScummEngine, gfxUsageBits[0], sleUint32, 200, VER(8), VER(9)),
- MKARRAY_OLD(ScummEngine, gfxUsageBits[0], sleUint32, 410, VER(10), VER(13)),
- MKARRAY(ScummEngine, gfxUsageBits[0], sleUint32, 3 * 410, VER(14)),
-
- MK_OBSOLETE(ScummEngine, _gdi->_transparentColor, sleByte, VER(8), VER(50)),
- MKARRAY(ScummEngine, _currentPalette[0], sleByte, 768, VER(8)),
- MKARRAY(ScummEngine, _darkenPalette[0], sleByte, 768, VER(53)),
-
- // Sam & Max specific palette replaced by _shadowPalette now.
- MK_OBSOLETE_ARRAY(ScummEngine, _proc_special_palette[0], sleByte, 256, VER(8), VER(33)),
-
- MKARRAY(ScummEngine, _charsetBuffer[0], sleByte, 256, VER(8)),
-
- MKLINE(ScummEngine, _egoPositioned, sleByte, VER(8)),
-
- // _gdi->_imgBufOffs grew from 4 to 5 entries. Then one day we realized
- // that we don't have to store it since initBGBuffers() recomputes it.
- MK_OBSOLETE_ARRAY(ScummEngine, _gdi->_imgBufOffs[0], sleUint16, 4, VER(8), VER(9)),
- MK_OBSOLETE_ARRAY(ScummEngine, _gdi->_imgBufOffs[0], sleUint16, 5, VER(10), VER(26)),
-
- // See _imgBufOffs: _numZBuffer is recomputed by initBGBuffers().
- MK_OBSOLETE(ScummEngine, _gdi->_numZBuffer, sleByte, VER(8), VER(26)),
-
- MKLINE(ScummEngine, _screenEffectFlag, sleByte, VER(8)),
-
- MK_OBSOLETE(ScummEngine, _randSeed1, sleUint32, VER(8), VER(9)),
- MK_OBSOLETE(ScummEngine, _randSeed2, sleUint32, VER(8), VER(9)),
-
- // Converted _shakeEnabled to boolean and added a _shakeFrame field.
- MKLINE_OLD(ScummEngine, _shakeEnabled, sleInt16, VER(8), VER(9)),
- MKLINE(ScummEngine, _shakeEnabled, sleByte, VER(10)),
- MKLINE(ScummEngine, _shakeFrame, sleUint32, VER(10)),
-
- MKLINE(ScummEngine, _keepText, sleByte, VER(8)),
-
- MKLINE(ScummEngine, _screenB, sleUint16, VER(8)),
- MKLINE(ScummEngine, _screenH, sleUint16, VER(8)),
-
- MKLINE(ScummEngine, _NESCostumeSet, sleUint16, VER(47)),
-
- MK_OBSOLETE(ScummEngine, _cd_track, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_loops, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_frame, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_end, sleInt16, VER(9), VER(9)),
-
- MKEND()
- };
-
- const SaveLoadEntry scriptSlotEntries[] = {
- MKLINE(ScriptSlot, offs, sleUint32, VER(8)),
- MKLINE(ScriptSlot, delay, sleInt32, VER(8)),
- MKLINE(ScriptSlot, number, sleUint16, VER(8)),
- MKLINE(ScriptSlot, delayFrameCount, sleUint16, VER(8)),
- MKLINE(ScriptSlot, status, sleByte, VER(8)),
- MKLINE(ScriptSlot, where, sleByte, VER(8)),
- MKLINE(ScriptSlot, freezeResistant, sleByte, VER(8)),
- MKLINE(ScriptSlot, recursive, sleByte, VER(8)),
- MKLINE(ScriptSlot, freezeCount, sleByte, VER(8)),
- MKLINE(ScriptSlot, didexec, sleByte, VER(8)),
- MKLINE(ScriptSlot, cutsceneOverride, sleByte, VER(8)),
- MKLINE(ScriptSlot, cycle, sleByte, VER(46)),
- MK_OBSOLETE(ScriptSlot, unk5, sleByte, VER(8), VER(10)),
- MKEND()
- };
-
- const SaveLoadEntry nestedScriptEntries[] = {
- MKLINE(NestedScript, number, sleUint16, VER(8)),
- MKLINE(NestedScript, where, sleByte, VER(8)),
- MKLINE(NestedScript, slot, sleByte, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry sentenceTabEntries[] = {
- MKLINE(SentenceTab, verb, sleUint8, VER(8)),
- MKLINE(SentenceTab, preposition, sleUint8, VER(8)),
- MKLINE(SentenceTab, objectA, sleUint16, VER(8)),
- MKLINE(SentenceTab, objectB, sleUint16, VER(8)),
- MKLINE(SentenceTab, freezeCount, sleUint8, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry stringTabEntries[] = {
- // Then _default/restore of a StringTab entry becomes a one liner.
- MKLINE(StringTab, xpos, sleInt16, VER(8)),
- MKLINE(StringTab, _default.xpos, sleInt16, VER(8)),
- MKLINE(StringTab, ypos, sleInt16, VER(8)),
- MKLINE(StringTab, _default.ypos, sleInt16, VER(8)),
- MKLINE(StringTab, right, sleInt16, VER(8)),
- MKLINE(StringTab, _default.right, sleInt16, VER(8)),
- MKLINE(StringTab, color, sleInt8, VER(8)),
- MKLINE(StringTab, _default.color, sleInt8, VER(8)),
- MKLINE(StringTab, charset, sleInt8, VER(8)),
- MKLINE(StringTab, _default.charset, sleInt8, VER(8)),
- MKLINE(StringTab, center, sleByte, VER(8)),
- MKLINE(StringTab, _default.center, sleByte, VER(8)),
- MKLINE(StringTab, overhead, sleByte, VER(8)),
- MKLINE(StringTab, _default.overhead, sleByte, VER(8)),
- MKLINE(StringTab, no_talk_anim, sleByte, VER(8)),
- MKLINE(StringTab, _default.no_talk_anim, sleByte, VER(8)),
- MKLINE(StringTab, wrapping, sleByte, VER(71)),
- MKLINE(StringTab, _default.wrapping, sleByte, VER(71)),
- MKEND()
- };
-
- const SaveLoadEntry colorCycleEntries[] = {
- MKLINE(ColorCycle, delay, sleUint16, VER(8)),
- MKLINE(ColorCycle, counter, sleUint16, VER(8)),
- MKLINE(ColorCycle, flags, sleUint16, VER(8)),
- MKLINE(ColorCycle, start, sleByte, VER(8)),
- MKLINE(ColorCycle, end, sleByte, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry scaleSlotsEntries[] = {
- MKLINE(ScaleSlot, x1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, y1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, scale1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, x2, sleUint16, VER(13)),
- MKLINE(ScaleSlot, y2, sleUint16, VER(13)),
- MKLINE(ScaleSlot, scale2, sleUint16, VER(13)),
- MKEND()
- };
-
- // MSVC6 FIX (Jamieson630):
- // MSVC6 has a problem with any notation that involves
- // more than one set of double colons ::
- // The following MKLINE macros expand to such things
- // as AudioCDManager::Status::playing, and MSVC6 has
- // a fit with that. This typedef simplifies the notation
- // to something MSVC6 can grasp.
- typedef AudioCDManager::Status AudioCDManager_Status;
- const SaveLoadEntry audioCDEntries[] = {
- MKLINE(AudioCDManager_Status, playing, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, track, sleInt32, VER(24)),
- MKLINE(AudioCDManager_Status, start, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, duration, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, numLoops, sleInt32, VER(24)),
- MKEND()
- };
+static void syncWithSerializer(Common::Serializer &s, ObjectData &od) {
+ s.syncAsUint32LE(od.OBIMoffset, VER(8));
+ s.syncAsUint32LE(od.OBCDoffset, VER(8));
+ s.syncAsUint16LE(od.walk_x, VER(8));
+ s.syncAsUint16LE(od.walk_y, VER(8));
+ s.syncAsUint16LE(od.obj_nr, VER(8));
+ s.syncAsSint16LE(od.x_pos, VER(8));
+ s.syncAsSint16LE(od.y_pos, VER(8));
+ s.syncAsUint16LE(od.width, VER(8));
+ s.syncAsUint16LE(od.height, VER(8));
+ s.syncAsByte(od.actordir, VER(8));
+ s.syncAsByte(od.parentstate, VER(8));
+ s.syncAsByte(od.parent, VER(8));
+ s.syncAsByte(od.state, VER(8));
+ s.syncAsByte(od.fl_object_index, VER(8));
+ s.syncAsByte(od.flags, VER(46));
+}
+
+static void syncWithSerializer(Common::Serializer &s, VerbSlot &vs) {
+ s.syncAsSint16LE(vs.curRect.left, VER(8));
+ s.syncAsSint16LE(vs.curRect.top, VER(8));
+ s.syncAsSint16LE(vs.curRect.right, VER(8));
+ s.syncAsSint16LE(vs.curRect.bottom, VER(8));
+ s.syncAsSint16LE(vs.oldRect.left, VER(8));
+ s.syncAsSint16LE(vs.oldRect.top, VER(8));
+ s.syncAsSint16LE(vs.oldRect.right, VER(8));
+ s.syncAsSint16LE(vs.oldRect.bottom, VER(8));
+ s.syncAsByte(vs.verbid, VER(8), VER(11));
+ s.syncAsSint16LE(vs.verbid, VER(12));
+ s.syncAsByte(vs.color, VER(8));
+ s.syncAsByte(vs.hicolor, VER(8));
+ s.syncAsByte(vs.dimcolor, VER(8));
+ s.syncAsByte(vs.bkcolor, VER(8));
+ s.syncAsByte(vs.type, VER(8));
+ s.syncAsByte(vs.charset_nr, VER(8));
+ s.syncAsByte(vs.curmode, VER(8));
+ s.syncAsByte(vs.saveid, VER(8));
+ s.syncAsByte(vs.key, VER(8));
+ s.syncAsByte(vs.center, VER(8));
+ s.syncAsByte(vs.prep, VER(8));
+ s.syncAsUint16LE(vs.imgindex, VER(8));
+}
+
+static void syncWithSerializer(Common::Serializer &s, ScriptSlot &ss) {
+ s.syncAsUint32LE(ss.offs, VER(8));
+ s.syncAsSint32LE(ss.delay, VER(8));
+ s.syncAsUint16LE(ss.number, VER(8));
+ s.syncAsUint16LE(ss.delayFrameCount, VER(8));
+ s.syncAsByte(ss.status, VER(8));
+ s.syncAsByte(ss.where, VER(8));
+ s.syncAsByte(ss.freezeResistant, VER(8));
+ s.syncAsByte(ss.recursive, VER(8));
+ s.syncAsByte(ss.freezeCount, VER(8));
+ s.syncAsByte(ss.didexec, VER(8));
+ s.syncAsByte(ss.cutsceneOverride, VER(8));
+ s.syncAsByte(ss.cycle, VER(46));
+ s.skip(1, VER(8), VER(10)); // unk5
+}
+
+static void syncWithSerializer(Common::Serializer &s, NestedScript &ns) {
+ s.syncAsUint16LE(ns.number, VER(8));
+ s.syncAsByte(ns.where, VER(8));
+ s.syncAsByte(ns.slot, VER(8));
+}
+
+static void syncWithSerializer(Common::Serializer &s, SentenceTab &st) {
+ s.syncAsByte(st.verb, VER(8));
+ s.syncAsByte(st.preposition, VER(8));
+ s.syncAsUint16LE(st.objectA, VER(8));
+ s.syncAsUint16LE(st.objectB, VER(8));
+ s.syncAsByte(st.freezeCount, VER(8));
+}
+
+static void syncWithSerializer(Common::Serializer &s, StringTab &st) {
+ s.syncAsSint16LE(st.xpos, VER(8));
+ s.syncAsSint16LE(st._default.xpos, VER(8));
+ s.syncAsSint16LE(st.ypos, VER(8));
+ s.syncAsSint16LE(st._default.ypos, VER(8));
+ s.syncAsSint16LE(st.right, VER(8));
+ s.syncAsSint16LE(st._default.right, VER(8));
+ s.syncAsSByte(st.color, VER(8));
+ s.syncAsSByte(st._default.color, VER(8));
+ s.syncAsSByte(st.charset, VER(8));
+ s.syncAsSByte(st._default.charset, VER(8));
+ s.syncAsByte(st.center, VER(8));
+ s.syncAsByte(st._default.center, VER(8));
+ s.syncAsByte(st.overhead, VER(8));
+ s.syncAsByte(st._default.overhead, VER(8));
+ s.syncAsByte(st.no_talk_anim, VER(8));
+ s.syncAsByte(st._default.no_talk_anim, VER(8));
+ s.syncAsByte(st.wrapping, VER(71));
+ s.syncAsByte(st._default.wrapping, VER(71));
+}
+
+static void syncWithSerializer(Common::Serializer &s, ColorCycle &cc) {
+ s.syncAsUint16LE(cc.delay, VER(8));
+ s.syncAsUint16LE(cc.counter, VER(8));
+ s.syncAsUint16LE(cc.flags, VER(8));
+ s.syncAsByte(cc.start, VER(8));
+ s.syncAsByte(cc.end, VER(8));
+}
+
+void syncWithSerializer(Common::Serializer &s, ScummEngine::ScaleSlot &ss) {
+ s.syncAsUint16LE(ss.x1, VER(13));
+ s.syncAsUint16LE(ss.y1, VER(13));
+ s.syncAsUint16LE(ss.scale1, VER(13));
+ s.syncAsUint16LE(ss.x2, VER(13));
+ s.syncAsUint16LE(ss.y2, VER(13));
+ s.syncAsUint16LE(ss.scale2, VER(13));
+}
+
+static void syncWithSerializer(Common::Serializer &s, AudioCDManager::Status &as) {
+ s.syncAsUint32LE(as.playing, VER(24));
+ s.syncAsSint32LE(as.track, VER(24));
+ s.syncAsUint32LE(as.start, VER(24));
+ s.syncAsUint32LE(as.duration, VER(24));
+ s.syncAsSint32LE(as.numLoops, VER(24));
+}
+
+static void syncWithSerializer(Common::Serializer &s, Common::Rect &rect) {
+ s.syncAsSint16LE(rect.left);
+ s.syncAsSint16LE(rect.top);
+ s.syncAsSint16LE(rect.right);
+ s.syncAsSint16LE(rect.bottom);
+}
+
+template <typename T, size_t N, size_t M>
+static void sync2DArray(Common::Serializer &s, T (&array)[N][M], const size_t dim1, const size_t dim2, void (*serializer)(Common::Serializer &, T &), Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+
+ if (s.getVersion() < minVersion || s.getVersion() > maxVersion) {
+ return;
+ }
+ assert(dim1 <= N);
+ assert(dim2 <= M);
+ for (size_t i = 0; i < dim1; ++i) {
+ for (size_t j = 0; j < dim2; ++j) {
+ serializer(s, array[i][j]);
+ }
+ }
+}
+
+void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
int i;
int var120Backup;
int var98Backup;
uint8 md5Backup[16];
// MD5 Operations: Backup on load, compare, and reset.
- if (s->isLoading())
+ if (s.isLoading())
memcpy(md5Backup, _gameMD5, 16);
//
// Save/load main state (many members of class ScummEngine get saved here)
//
- s->saveLoadEntries(this, mainEntries);
+ s.syncBytes(_gameMD5, sizeof(_gameMD5), VER(39));
+ s.skip(2, VER(8), VER(50)); // _roomWidth
+ s.skip(2, VER(8), VER(50)); // _roomHeight
+ s.skip(4, VER(8), VER(50)); // _ENCD_offs
+ s.skip(4, VER(8), VER(50)); // _EXCD_offs
+ s.skip(4, VER(8), VER(50)); // _IM00_offs
+ s.skip(4, VER(8), VER(50)); // _CLUT_offs
+ s.skip(4, VER(8), VER(9)); // _EPAL_offs
+ s.skip(4, VER(8), VER(50)); // _PALS_offs
+ s.syncAsByte(_curPalIndex, VER(8));
+ s.syncAsByte(_currentRoom, VER(8));
+ s.syncAsByte(_roomResource, VER(8));
+ s.syncAsByte(_numObjectsInRoom, VER(8));
+ s.syncAsByte(_currentScript, VER(8));
+ s.skip(4 * _numLocalScripts, VER(8), VER(50)); // _localScriptOffsets
+
+ // vm.localvar grew from 25 to 40 script entries and then from
+ // 16 to 32 bit variables (but that wasn't reflect here)... and
+ // THEN from 16 to 25 variables.
+ sync2DArray(s, vm.localvar, 25, 17, Common::Serializer::Uint16LE, VER(8), VER(8));
+ sync2DArray(s, vm.localvar, 40, 17, Common::Serializer::Uint16LE, VER(9), VER(14));
+
+ // We used to save 25 * 40 = 1000 blocks; but actually, each 'row consisted of 26 entry,
+ // i. 26 * 40 = 1040. Thus the last 40 blocks of localvar where not saved at all. To be
+ // able to load this screwed format, we use a trick: We load 26 * 38 = 988 blocks.
+ // Then, we mark the followin 12 blocks (24 bytes) as obsolete.
+ sync2DArray(s, vm.localvar, 38, 26, Common::Serializer::Uint16LE, VER(15), VER(17));
+ s.skip(2 * 12, VER(15), VER(17));
+
+ // This was the first proper multi dimensional version of the localvars, with 32 bit values
+ sync2DArray(s, vm.localvar, 40, 26, Common::Serializer::Uint32LE, VER(18), VER(19));
+
+ // Then we doubled the script slots again, from 40 to 80
+ sync2DArray(s, vm.localvar, NUM_SCRIPT_SLOT, 26, Common::Serializer::Uint32LE, VER(20));
+
+ s.syncBytes(_resourceMapper, 128, VER(8));
+ s.syncBytes(_charsetColorMap, 16, VER(8));
+
+ // _charsetData grew from 10*16, to 15*16, to 23*16 bytes
+ for (int i = 0; i < 10; ++i) {
+ s.syncBytes(_charsetData[i], 16, VER(8));
+ }
+ for (int i = 10; i < 15; ++i) {
+ s.syncBytes(_charsetData[i], 16, VER(10));
+ }
+ for (int i = 15; i < 23; ++i) {
+ s.syncBytes(_charsetData[i], 16, VER(67));
+ }
+
+ s.skip(2, VER(8), VER(62)); // _curExecScript
+
+ s.syncAsSint16LE(camera._dest.x, VER(8));
+ s.syncAsSint16LE(camera._dest.y, VER(8));
+ s.syncAsSint16LE(camera._cur.x, VER(8));
+ s.syncAsSint16LE(camera._cur.y, VER(8));
+ s.syncAsSint16LE(camera._last.x, VER(8));
+ s.syncAsSint16LE(camera._last.y, VER(8));
+ s.syncAsSint16LE(camera._accel.x, VER(8));
+ s.syncAsSint16LE(camera._accel.y, VER(8));
+ s.syncAsSint16LE(_screenStartStrip, VER(8));
+ s.syncAsSint16LE(_screenEndStrip, VER(8));
+ s.syncAsByte(camera._mode, VER(8));
+ s.syncAsByte(camera._follows, VER(8));
+ s.syncAsSint16LE(camera._leftTrigger, VER(8));
+ s.syncAsSint16LE(camera._rightTrigger, VER(8));
+ s.syncAsUint16LE(camera._movingToActor, VER(8));
+
+ s.syncAsByte(_actorToPrintStrFor, VER(8));
+ s.syncAsByte(_charsetColor, VER(8));
+
+ // _charsetBufPos was changed from byte to int
+ s.syncAsByte(_charsetBufPos, VER(8), VER(9));
+ s.syncAsSint16LE(_charsetBufPos, VER(10));
+
+ s.syncAsByte(_haveMsg, VER(8));
+ s.syncAsByte(_haveActorSpeechMsg, VER(61));
+ s.syncAsByte(_useTalkAnims, VER(8));
+
+ s.syncAsSint16LE(_talkDelay, VER(8));
+ s.syncAsSint16LE(_defaultTalkDelay, VER(8));
+ s.skip(2, VER(8), VER(27)); // _numInMsgStack
+ s.syncAsByte(_sentenceNum, VER(8));
+
+ s.syncAsByte(vm.cutSceneStackPointer, VER(8));
+ s.syncArray(vm.cutScenePtr, 5, Common::Serializer::Uint32LE, VER(8));
+ s.syncBytes(vm.cutSceneScript, 5, VER(8));
+ s.syncArray(vm.cutSceneData, 5, Common::Serializer::Sint16LE, VER(8));
+ s.syncAsSint16LE(vm.cutSceneScriptIndex, VER(8));
+
+ s.syncAsByte(vm.numNestedScripts, VER(8));
+ s.syncAsByte(_userPut, VER(8));
+ s.syncAsUint16LE(_userState, VER(17));
+ s.syncAsByte(_cursor.state, VER(8));
+ s.skip(1, VER(8), VER(20)); // _gdi->_cursorActive
+ s.syncAsByte(_currentCursor, VER(8));
+ // TODO: This seems wrong, _grabbedCursor is >8192 bytes and sometimes holds
+ // 16-bit values
+ s.syncBytes(_grabbedCursor, 8192, VER(20));
+ s.syncAsSint16LE(_cursor.width, VER(20));
+ s.syncAsSint16LE(_cursor.height, VER(20));
+ s.syncAsSint16LE(_cursor.hotspotX, VER(20));
+ s.syncAsSint16LE(_cursor.hotspotY, VER(20));
+ s.syncAsByte(_cursor.animate, VER(20));
+ s.syncAsByte(_cursor.animateIndex, VER(20));
+ s.syncAsSint16LE(_mouse.x, VER(20));
+ s.syncAsSint16LE(_mouse.y, VER(20));
+
+ s.syncBytes(_colorUsedByCycle, 256, VER(60));
+ s.syncAsByte(_doEffect, VER(8));
+ s.syncAsByte(_switchRoomEffect, VER(8));
+ s.syncAsByte(_newEffect, VER(8));
+ s.syncAsByte(_switchRoomEffect2, VER(8));
+ s.syncAsByte(_bgNeedsRedraw, VER(8));
+
+ // The state of palManipulate is stored only since V10
+ s.syncAsByte(_palManipStart, VER(10));
+ s.syncAsByte(_palManipEnd, VER(10));
+ s.syncAsUint16LE(_palManipCounter, VER(10));
+
+ // gfxUsageBits grew from 200 to 410 entries. Then 3 * 410 entries:
+ s.syncArray(gfxUsageBits, 200, Common::Serializer::Uint32LE, VER(8), VER(9));
+ s.syncArray(gfxUsageBits, 410, Common::Serializer::Uint32LE, VER(10), VER(13));
+ s.syncArray(gfxUsageBits, 3 * 410, Common::Serializer::Uint32LE, VER(14));
+
+ s.skip(1, VER(8), VER(50)); // _gdi->_transparentColor
+ s.syncBytes(_currentPalette, 768, VER(8));
+ s.syncBytes(_darkenPalette, 768, VER(53));
+
+ // Sam & Max specific palette replaced by _shadowPalette now.
+ s.skip(256, VER(8), VER(33)); // _proc_special_palette
+
+ s.syncBytes(_charsetBuffer, 256, VER(8));
+
+ s.syncAsByte(_egoPositioned, VER(8));
+
+ // _gdi->_imgBufOffs grew from 4 to 5 entries. Then one day we realized
+ // that we don't have to store it since initBGBuffers() recomputes it.
+ s.skip(2 * 4, VER(8), VER(9)); // _gdi->_imgBufOffs
+ s.skip(2 * 5, VER(10), VER(26)); // _gdi->_imgBufOffs
+
+ // See _imgBufOffs: _numZBuffer is recomputed by initBGBuffers().
+ s.skip(1, VER(8), VER(26)); // _gdi->_numZBuffer
+
+ s.syncAsByte(_screenEffectFlag, VER(8));
+
+ s.skip(4, VER(8), VER(9)); // _randSeed1
+ s.skip(4, VER(8), VER(9)); // _randSeed2
+
+ // Converted _shakeEnabled to boolean and added a _shakeFrame field.
+ s.syncAsSint16LE(_shakeEnabled, VER(8), VER(9));
+ s.syncAsByte(_shakeEnabled, VER(10));
+ s.syncAsUint32LE(_shakeFrame, VER(10));
+
+ s.syncAsByte(_keepText, VER(8));
+
+ s.syncAsUint16LE(_screenB, VER(8));
+ s.syncAsUint16LE(_screenH, VER(8));
+
+ s.syncAsUint16LE(_NESCostumeSet, VER(47));
+
+ s.skip(2, VER(9), VER(9)); // _cd_track
+ s.skip(2, VER(9), VER(9)); // _cd_loops
+ s.skip(2, VER(9), VER(9)); // _cd_frame
+ s.skip(2, VER(9), VER(9)); // _cd_end
// MD5 Operations: Backup on load, compare, and reset.
- if (s->isLoading()) {
+ if (s.isLoading()) {
char md5str1[32+1], md5str2[32+1];
for (i = 0; i < 16; i++) {
sprintf(md5str1 + i*2, "%02x", (int)_gameMD5[i]);
sprintf(md5str2 + i*2, "%02x", (int)md5Backup[i]);
}
- debug(2, "Save version: %d", s->getVersion());
- debug(2, "Saved game MD5: %s", (s->getVersion() >= 39) ? md5str1 : "unknown");
+ debug(2, "Save version: %d", s.getVersion());
+ debug(2, "Saved game MD5: %s", (s.getVersion() >= 39) ? md5str1 : "unknown");
if (memcmp(md5Backup, _gameMD5, 16) != 0) {
warning("Game was saved with different gamedata - you may encounter problems");
@@ -1134,22 +1140,22 @@ void ScummEngine::saveOrLoad(Serializer *s) {
// that have more than 30 actors (up to 94 are supported now, in theory).
// Since the format of the usage bits was changed by this, we have to
// convert them when loading an older savegame.
- if (s->isLoading() && s->getVersion() < VER(14))
+ if (s.isLoading() && s.getVersion() < VER(14))
upgradeGfxUsageBits();
// When loading, reset the ShakePos. Fixes one part of bug #7141
- if (s->isLoading() && s->getVersion() >= VER(10))
+ if (s.isLoading() && s.getVersion() >= VER(10))
_system->setShakePos(0);
// When loading, move the mouse to the saved mouse position.
- if (s->isLoading() && s->getVersion() >= VER(20)) {
+ if (s.isLoading() && s.getVersion() >= VER(20)) {
updateCursor();
_system->warpMouse(_mouse.x, _mouse.y);
}
// Before V61, we re-used the _haveMsg flag to handle "alternative" speech
// sound files (see charset code 10).
- if (s->isLoading() && s->getVersion() < VER(61)) {
+ if (s.isLoading() && s.getVersion() < VER(61)) {
if (_haveMsg == 0xFE) {
_haveActorSpeechMsg = false;
_haveMsg = 0xFF;
@@ -1174,14 +1180,11 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load script data
//
- if (s->getVersion() < VER(9))
- s->saveLoadArrayOf(vm.slot, 25, sizeof(vm.slot[0]), scriptSlotEntries);
- else if (s->getVersion() < VER(20))
- s->saveLoadArrayOf(vm.slot, 40, sizeof(vm.slot[0]), scriptSlotEntries);
- else
- s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries);
+ s.syncArray(vm.slot, 25, syncWithSerializer, VER(0), VER(8));
+ s.syncArray(vm.slot, 40, syncWithSerializer, VER(9), VER(19));
+ s.syncArray(vm.slot, NUM_SCRIPT_SLOT, syncWithSerializer, VER(20));
- if (s->getVersion() < VER(46)) {
+ if (s.getVersion() < VER(46)) {
// When loading an old savegame, make sure that the 'cycle'
// field is set to something sensible, otherwise the scripts
// that were running probably won't be.
@@ -1195,13 +1198,13 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load local objects
//
- s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries);
- if (s->isLoading()) {
- if (s->getVersion() < VER(13)) {
+ s.syncArray(_objs, _numLocalObjects, syncWithSerializer);
+ if (s.isLoading()) {
+ if (s.getVersion() < VER(13)) {
// Since roughly v13 of the save games, the objs storage has changed a bit
for (i = _numObjectsInRoom; i < _numLocalObjects; i++)
_objs[i].obj_nr = 0;
- } else if (_game.version == 0 && s->getVersion() < VER(91)) {
+ } else if (_game.version == 0 && s.getVersion() < VER(91)) {
for (i = 0; i < _numLocalObjects; i++) {
// Merge object id and type (previously stored in flags)
if (_objs[i].obj_nr != 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == 0 && _objs[i].flags != 0)
@@ -1215,13 +1218,12 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load misc stuff
//
- s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries);
- s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries);
- s->saveLoadArrayOf(_sentence, 6, sizeof(_sentence[0]), sentenceTabEntries);
- s->saveLoadArrayOf(_string, 6, sizeof(_string[0]), stringTabEntries);
- s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries);
- if (s->getVersion() >= VER(13))
- s->saveLoadArrayOf(_scaleSlots, 20, sizeof(_scaleSlots[0]), scaleSlotsEntries);
+ s.syncArray(_verbs, _numVerbs, syncWithSerializer);
+ s.syncArray(vm.nest, 16, syncWithSerializer);
+ s.syncArray(_sentence, 6, syncWithSerializer);
+ s.syncArray(_string, 6, syncWithSerializer);
+ s.syncArray(_colorCycle, 16, syncWithSerializer);
+ s.syncArray(_scaleSlots, 20, syncWithSerializer, VER(13));
//
@@ -1229,30 +1231,31 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
ResType type;
ResId idx;
- if (s->getVersion() >= VER(26)) {
+ if (s.getVersion() >= VER(26)) {
// New, more robust resource save/load system. This stores the type
// and index of each resource. Thus if we increase e.g. the maximum
// number of script resources, savegames won't break.
- if (s->isSaving()) {
+ if (s.isSaving()) {
+ uint16 endMarker = 0xFFFF;
for (type = rtFirst; type <= rtLast; type = ResType(type + 1)) {
if (_res->_types[type]._mode != kStaticResTypeMode && type != rtTemp && type != rtBuffer) {
- s->saveUint16(type); // Save the res type...
+ s.syncAsUint16LE(type); // Save the res type...
for (idx = 0; idx < _res->_types[type].size(); idx++) {
// Only save resources which actually exist...
if (_res->_types[type][idx]._address) {
- s->saveUint16(idx); // Save the index of the resource
+ s.syncAsUint16LE(idx); // Save the index of the resource
saveResource(s, type, idx);
}
}
- s->saveUint16(0xFFFF); // End marker
+ s.syncAsUint16LE(endMarker);
}
}
- s->saveUint16(0xFFFF); // End marker
+ s.syncAsUint16LE(endMarker);
} else {
uint16 tmp;
- while ((tmp = s->loadUint16()) != 0xFFFF) {
+ while (s.syncAsUint16LE(tmp), tmp != 0xFFFF) {
type = (ResType)tmp;
- while ((idx = s->loadUint16()) != 0xFFFF) {
+ while (s.syncAsUint16LE(idx), idx != 0xFFFF) {
assert(idx < _res->_types[type].size());
loadResource(s, type, idx);
}
@@ -1278,17 +1281,17 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load global object state
//
- s->saveLoadArrayOf(_objectOwnerTable, _numGlobalObjects, sizeof(_objectOwnerTable[0]), sleByte);
- s->saveLoadArrayOf(_objectStateTable, _numGlobalObjects, sizeof(_objectStateTable[0]), sleByte);
+ s.syncBytes(_objectOwnerTable, _numGlobalObjects);
+ s.syncBytes(_objectStateTable, _numGlobalObjects);
if (_objectRoomTable)
- s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects, sizeof(_objectRoomTable[0]), sleByte);
+ s.syncBytes(_objectRoomTable, _numGlobalObjects);
//
// Save/load palette data
// Don't save 16 bit palette in FM-Towns and PCE games, since it gets regenerated afterwards anyway.
- if (_16BitPalette && !(_game.platform == Common::kPlatformFMTowns && s->getVersion() < VER(82)) && !((_game.platform == Common::kPlatformFMTowns || _game.platform == Common::kPlatformPCEngine) && s->getVersion() > VER(87))) {
- s->saveLoadArrayOf(_16BitPalette, 512, sizeof(_16BitPalette[0]), sleUint16);
+ if (_16BitPalette && !(_game.platform == Common::kPlatformFMTowns && s.getVersion() < VER(82)) && !((_game.platform == Common::kPlatformFMTowns || _game.platform == Common::kPlatformPCEngine) && s.getVersion() > VER(87))) {
+ s.syncArray(_16BitPalette, 512, Common::Serializer::Uint16LE);
}
@@ -1310,82 +1313,71 @@ void ScummEngine::saveOrLoad(Serializer *s) {
}
#else
- byte hasTownsData = ((_game.platform == Common::kPlatformFMTowns && s->getVersion() >= VER(87)) || (s->getVersion() >= VER(82) && s->getVersion() < VER(87))) ? 1 : 0;
- if (_game.platform == Common::kPlatformFMTowns && s->getVersion() > VER(87))
- s->saveLoadArrayOf(&hasTownsData, 1, sizeof(byte), sleByte);
+ byte hasTownsData = ((_game.platform == Common::kPlatformFMTowns && s.getVersion() >= VER(87)) || (s.getVersion() >= VER(82) && s.getVersion() < VER(87))) ? 1 : 0;
+ if (_game.platform == Common::kPlatformFMTowns && s.getVersion() > VER(87))
+ s.syncAsByte(hasTownsData);
if (hasTownsData) {
- const SaveLoadEntry townsFields[] = {
- MKLINE(Common::Rect, left, sleInt16, VER(82)),
- MKLINE(Common::Rect, top, sleInt16, VER(82)),
- MKLINE(Common::Rect, right, sleInt16, VER(82)),
- MKLINE(Common::Rect, bottom, sleInt16, VER(82)),
- MKEND()
- };
-
- const SaveLoadEntry townsExtraEntries[] = {
- MKLINE(ScummEngine, _townsOverrideShadowColor, sleUint8, VER(82)),
- MKLINE(ScummEngine, _numCyclRects, sleUint8, VER(82)),
- MKLINE(ScummEngine, _townsPaletteFlags, sleUint8, VER(82)),
- MKLINE(ScummEngine, _townsClearLayerFlag, sleUint8, VER(82)),
- MKLINE(ScummEngine, _townsActiveLayerFlags, sleUint8, VER(82)),
- MKEND()
- };
-
- s->saveLoadArrayOf(_textPalette, 48, sizeof(_textPalette[0]), sleUint8);
- s->saveLoadArrayOf(_cyclRects, 10, sizeof(_cyclRects[0]), townsFields);
- s->saveLoadArrayOf(&_curStringRect, 1, sizeof(_curStringRect), townsFields);
- s->saveLoadArrayOf(_townsCharsetColorMap, 16, sizeof(_townsCharsetColorMap[0]), sleUint8);
- s->saveLoadEntries(this, townsExtraEntries);
- } else if (_game.platform == Common::kPlatformFMTowns && s->getVersion() >= VER(82)) {
+ s.syncBytes(_textPalette, 48);
+ // TODO: This seems wrong, there are 16 _cyclRects
+ s.syncArray(_cyclRects, 10, syncWithSerializer, VER(82));
+ if (s.getVersion() >= VER(82))
+ syncWithSerializer(s, _curStringRect);
+ s.syncBytes(_townsCharsetColorMap, 16);
+ s.syncAsByte(_townsOverrideShadowColor, VER(82));
+ s.syncAsByte(_numCyclRects, VER(82));
+ s.syncAsByte(_townsPaletteFlags, VER(82));
+ s.syncAsByte(_townsClearLayerFlag, VER(82));
+ s.syncAsByte(_townsActiveLayerFlags, VER(82));
+ } else if (_game.platform == Common::kPlatformFMTowns && s.getVersion() >= VER(82)) {
warning("Save file is missing FM-Towns specific graphic data (game was apparently saved on another platform)");
}
#endif
if (_shadowPaletteSize) {
- s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte);
+ s.syncBytes(_shadowPalette, _shadowPaletteSize);
// _roomPalette didn't show up until V21 save games
// Note that we also save the room palette for Indy4 Amiga, since it
// is used as palette map there too, but we do so slightly a bit
// further down to group it with the other special palettes needed.
- if (s->getVersion() >= VER(21) && _game.version < 5)
- s->saveLoadArrayOf(_roomPalette, sizeof(_roomPalette), 1, sleByte);
+ if (s.getVersion() >= VER(21) && _game.version < 5)
+ s.syncBytes(_roomPalette, sizeof(_roomPalette));
}
// PalManip data was not saved before V10 save games
- if (s->getVersion() < VER(10))
+ if (s.getVersion() < VER(10))
_palManipCounter = 0;
if (_palManipCounter) {
if (!_palManipPalette)
_palManipPalette = (byte *)calloc(0x300, 1);
if (!_palManipIntermediatePal)
_palManipIntermediatePal = (byte *)calloc(0x600, 1);
- s->saveLoadArrayOf(_palManipPalette, 0x300, 1, sleByte);
- s->saveLoadArrayOf(_palManipIntermediatePal, 0x600, 1, sleByte);
+ s.syncBytes(_palManipPalette, 0x300);
+ s.syncBytes(_palManipIntermediatePal, 0x600);
}
// darkenPalette was not saved before V53
- if (s->isLoading() && s->getVersion() < VER(53)) {
+ if (s.isLoading() && s.getVersion() < VER(53)) {
memcpy(_darkenPalette, _currentPalette, 768);
}
// _colorUsedByCycle was not saved before V60
- if (s->isLoading() && s->getVersion() < VER(60)) {
+ if (s.isLoading() && s.getVersion() < VER(60)) {
memset(_colorUsedByCycle, 0, sizeof(_colorUsedByCycle));
}
// Indy4 Amiga specific palette tables were not saved before V85
if (_game.platform == Common::kPlatformAmiga && _game.id == GID_INDY4) {
- if (s->getVersion() >= 85) {
- s->saveLoadArrayOf(_roomPalette, 256, 1, sleByte);
- s->saveLoadArrayOf(_verbPalette, 256, 1, sleByte);
- s->saveLoadArrayOf(_amigaPalette, 3 * 64, 1, sleByte);
+ if (s.getVersion() >= 85) {
+ s.syncBytes(_roomPalette, 256);
+ s.syncBytes(_verbPalette, 256);
+ s.syncBytes(_amigaPalette, 3 * 64);
// Starting from version 86 we also save the first used color in
// the palette beyond the verb palette. For old versions we just
// look for it again, which hopefully won't cause any troubles.
- if (s->getVersion() >= 86) {
- s->saveLoadArrayOf(&_amigaFirstUsedColor, 1, 2, sleUint16);
+ if (s.getVersion() >= VER(86)) {
+ s.syncAsUint16LE(_amigaFirstUsedColor);
} else {
amigaPaletteFindFirstUsedColor();
}
@@ -1400,7 +1392,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load more global object state
//
- s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32);
+ s.syncArray(_classData, _numGlobalObjects, Common::Serializer::Uint32LE);
//
@@ -1409,40 +1401,40 @@ void ScummEngine::saveOrLoad(Serializer *s) {
var120Backup = _scummVars[120];
var98Backup = _scummVars[98];
- if (s->getVersion() > VER(37))
- s->saveLoadArrayOf(_roomVars, _numRoomVariables, sizeof(_roomVars[0]), sleInt32);
+ s.syncArray(_roomVars, _numRoomVariables, Common::Serializer::Sint32LE, VER(38));
// The variables grew from 16 to 32 bit.
- if (s->getVersion() < VER(15))
- s->saveLoadArrayOf(_scummVars, _numVariables, sizeof(_scummVars[0]), sleInt16);
+ if (s.getVersion() < VER(15))
+ s.syncArray(_scummVars, _numVariables, Common::Serializer::Sint16LE);
else
- s->saveLoadArrayOf(_scummVars, _numVariables, sizeof(_scummVars[0]), sleInt32);
+ s.syncArray(_scummVars, _numVariables, Common::Serializer::Sint32LE);
if (_game.id == GID_TENTACLE) // Maybe misplaced, but that's the main idea
_scummVars[120] = var120Backup;
if (_game.id == GID_INDY4)
_scummVars[98] = var98Backup;
- s->saveLoadArrayOf(_bitVars, _numBitVariables >> 3, 1, sleByte);
+ s.syncBytes(_bitVars, _numBitVariables / 8);
//
// Save/load a list of the locked objects
//
- if (s->isSaving()) {
+ if (s.isSaving()) {
+ byte endMarker = 0xFF;
for (type = rtFirst; type <= rtLast; type = ResType(type + 1))
for (idx = 1; idx < _res->_types[type].size(); idx++) {
if (_res->isLocked(type, idx)) {
- s->saveByte(type);
- s->saveUint16(idx);
+ s.syncAsByte(type);
+ s.syncAsUint16LE(idx);
}
}
- s->saveByte(0xFF);
+ s.syncAsByte(endMarker);
} else {
uint8 tmp;
- while ((tmp = s->loadByte()) != 0xFF) {
+ while (s.syncAsByte(tmp), tmp != 0xFF) {
type = (ResType)tmp;
- idx = s->loadUint16();
+ s.syncAsUint16LE(idx);
_res->lock(type, idx);
}
}
@@ -1451,15 +1443,15 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load the Audio CD status
//
- if (s->getVersion() >= VER(24)) {
+ if (s.getVersion() >= VER(24)) {
AudioCDManager::Status info;
- if (s->isSaving())
+ if (s.isSaving())
info = _system->getAudioCDManager()->getStatus();
- s->saveLoadArrayOf(&info, 1, sizeof(info), audioCDEntries);
+ syncWithSerializer(s, info);
// If we are loading, and the music being loaded was supposed to loop
// forever, then resume playing it. This helps a lot when the audio CD
// is used to provide ambient music (see bug #788195).
- if (s->isLoading() && info.playing && info.numLoops < 0)
+ if (s.isLoading() && info.playing && info.numLoops < 0)
_sound->playCDTrackInternal(info.track, info.numLoops, info.start, info.duration);
}
@@ -1468,7 +1460,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
// Save/load the iMuse status
//
if (_imuse && (_saveSound || !_saveTemporaryState)) {
- _imuse->save_or_load(s, this);
+ _imuse->saveLoadWithSerializer(s, this);
}
@@ -1483,11 +1475,13 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load the charset renderer state
//
- if (s->getVersion() >= VER(73)) {
+ if (s.getVersion() >= VER(73)) {
_charset->saveLoadWithSerializer(s);
- } else if (s->isLoading()) {
- if (s->getVersion() == VER(72)) {
- _charset->setCurID(s->loadByte());
+ } else if (s.isLoading()) {
+ if (s.getVersion() == VER(72)) {
+ byte curId;
+ s.syncAsByte(curId);
+ _charset->setCurID(curId);
} else {
// Before V72, the charset id wasn't saved. This used to cause issues such
// as the one described in the bug report #1722153. For these savegames,
@@ -1497,57 +1491,45 @@ void ScummEngine::saveOrLoad(Serializer *s) {
}
}
-void ScummEngine_v0::saveOrLoad(Serializer *s) {
- ScummEngine_v2::saveOrLoad(s);
-
- const SaveLoadEntry v0Entrys[] = {
- MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)),
- MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)),
- MKLINE(ScummEngine_v0, _activeVerb, sleByte, VER(92)),
- MKLINE(ScummEngine_v0, _activeObject, sleUint16, VER(92)),
- MKLINE(ScummEngine_v0, _activeObject2, sleUint16, VER(92)),
- MKLINE(ScummEngine_v0, _cmdVerb, sleByte, VER(92)),
- MKLINE(ScummEngine_v0, _cmdObject, sleUint16, VER(92)),
- MKLINE(ScummEngine_v0, _cmdObject2, sleUint16, VER(92)),
- MKLINE(ScummEngine_v0, _walkToObject, sleUint16, VER(92)),
- MKLINE(ScummEngine_v0, _walkToObjectState, sleByte, VER(92)),
- MKEND()
- };
- s->saveLoadEntries(this, v0Entrys);
+void ScummEngine_v0::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v2::saveLoadWithSerializer(s);
+
+ s.syncAsByte(_currentMode, VER(78));
+ s.syncAsByte(_currentLights, VER(78));
+ s.syncAsByte(_activeVerb, VER(92));
+ s.syncAsUint16LE(_activeObject, VER(92));
+ s.syncAsUint16LE(_activeObject2, VER(92));
+ s.syncAsByte(_cmdVerb, VER(92));
+ s.syncAsUint16LE(_cmdObject, VER(92));
+ s.syncAsUint16LE(_cmdObject2, VER(92));
+ s.syncAsUint16LE(_walkToObject, VER(92));
+ s.syncAsByte(_walkToObjectState, VER(92));
}
-void ScummEngine_v2::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
+void ScummEngine_v2::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine::saveLoadWithSerializer(s);
- const SaveLoadEntry v2Entrys[] = {
- MKLINE(ScummEngine_v2, _inventoryOffset, sleUint16, VER(79)),
- MKEND()
- };
- s->saveLoadEntries(this, v2Entrys);
+ s.syncAsUint16LE(_inventoryOffset, VER(79));
// In old saves we didn't store _inventoryOffset -> reset it to
// a sane default when loading one of those.
- if (s->getVersion() < 79 && s->isLoading()) {
+ if (s.getVersion() < VER(79) && s.isLoading()) {
_inventoryOffset = 0;
}
}
-void ScummEngine_v5::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
-
- const SaveLoadEntry cursorEntries[] = {
- MKARRAY2(ScummEngine_v5, _cursorImages[0][0], sleUint16, 16, 4, (byte *)_cursorImages[1] - (byte *)_cursorImages[0], VER(44)),
- MKARRAY(ScummEngine_v5, _cursorHotspots[0], sleByte, 8, VER(44)),
- MKEND()
- };
+void ScummEngine_v5::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine::saveLoadWithSerializer(s);
// This is probably only needed for Loom.
- s->saveLoadEntries(this, cursorEntries);
+ // TODO: This looks wrong, _cursorImages is [4][17]
+ sync2DArray(s, _cursorImages, 4, 16, Common::Serializer::Uint16LE, VER(44));
+ s.syncBytes(_cursorHotspots, 8, VER(44));
// Reset cursors for old FM-Towns savegames saved with 256 color setting.
// Otherwise the cursor will be messed up when displayed in the new hi color setting.
- if (_game.platform == Common::kPlatformFMTowns && _outputPixelFormat.bytesPerPixel == 2 && s->isLoading() && s->getVersion() < VER(82)) {
+ if (_game.platform == Common::kPlatformFMTowns && _outputPixelFormat.bytesPerPixel == 2 && s.isLoading() && s.getVersion() < VER(82)) {
if (_game.id == GID_LOOM) {
redefineBuiltinCursorFromChar(1, 1);
redefineBuiltinCursorHotspot(1, 0, 0);
@@ -1560,7 +1542,7 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
// This avoids color issues when loading savegames that have been saved with a different ScummVM port
// that uses a different 16bit color mode than the ScummVM port which is currently used.
#ifdef USE_RGB_COLOR
- if (_game.platform == Common::kPlatformPCEngine && s->isLoading()) {
+ if (_game.platform == Common::kPlatformPCEngine && s.isLoading()) {
for (int i = 0; i < 256; ++i)
_16BitPalette[i] = get16BitColor(_currentPalette[i * 3 + 0], _currentPalette[i * 3 + 1], _currentPalette[i * 3 + 2]);
}
@@ -1568,154 +1550,133 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
}
#ifdef ENABLE_SCUMM_7_8
-void ScummEngine_v7::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
-
- const SaveLoadEntry subtitleQueueEntries[] = {
- MKARRAY(SubtitleText, text[0], sleByte, 256, VER(61)),
- MKLINE(SubtitleText, charset, sleByte, VER(61)),
- MKLINE(SubtitleText, color, sleByte, VER(61)),
- MKLINE(SubtitleText, xpos, sleInt16, VER(61)),
- MKLINE(SubtitleText, ypos, sleInt16, VER(61)),
- MKLINE(SubtitleText, actorSpeechMsg, sleByte, VER(61)),
- MKEND()
- };
-
- const SaveLoadEntry V7Entries[] = {
- MKLINE(ScummEngine_v7, _subtitleQueuePos, sleInt32, VER(61)),
- MK_OBSOLETE(ScummEngine_v7, _verbCharset, sleInt32, VER(68), VER(68)),
- MKLINE(ScummEngine_v7, _verbLineSpacing, sleInt32, VER(68)),
- MKEND()
- };
-
- _imuseDigital->saveOrLoad(s);
-
- s->saveLoadArrayOf(_subtitleQueue, ARRAYSIZE(_subtitleQueue), sizeof(_subtitleQueue[0]), subtitleQueueEntries);
- s->saveLoadEntries(this, V7Entries);
-
- if (s->getVersion() <= VER(68) && s->isLoading()) {
+void syncWithSerializer(Common::Serializer &s, ScummEngine_v7::SubtitleText &st) {
+ s.syncBytes(st.text, 256, VER(61));
+ s.syncAsByte(st.charset, VER(61));
+ s.syncAsByte(st.color, VER(61));
+ s.syncAsSint16LE(st.xpos, VER(61));
+ s.syncAsSint16LE(st.ypos, VER(61));
+ s.syncAsByte(st.actorSpeechMsg, VER(61));
+}
+
+void ScummEngine_v7::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine::saveLoadWithSerializer(s);
+
+ _imuseDigital->saveLoadEarly(s);
+
+ s.syncArray(_subtitleQueue, ARRAYSIZE(_subtitleQueue), syncWithSerializer);
+ s.syncAsSint32LE(_subtitleQueuePos, VER(61));
+ s.skip(4, VER(68), VER(68)); // _verbCharset
+ s.syncAsSint32LE(_verbLineSpacing, VER(68));
+
+ if (s.getVersion() <= VER(68) && s.isLoading()) {
// WORKAROUND bug #1846049: Reset the default charset color to a sane value.
_string[0]._default.charset = 1;
}
}
#endif
-void ScummEngine_v60he::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
+void ScummEngine_v60he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine::saveLoadWithSerializer(s);
- s->saveLoadArrayOf(_arraySlot, _numArray, sizeof(_arraySlot[0]), sleByte);
+ s.syncBytes(_arraySlot, _numArray);
}
-void ScummEngine_v70he::saveOrLoad(Serializer *s) {
- ScummEngine_v60he::saveOrLoad(s);
-
- const SaveLoadEntry HE70Entries[] = {
- MKLINE(ScummEngine_v70he, _heSndSoundId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndOffset, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndChannel, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndFlags, sleInt32, VER(51)),
- MKEND()
- };
+void ScummEngine_v70he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v60he::saveLoadWithSerializer(s);
- s->saveLoadEntries(this, HE70Entries);
+ s.syncAsSint32LE(_heSndSoundId, VER(51));
+ s.syncAsSint32LE(_heSndOffset, VER(51));
+ s.syncAsSint32LE(_heSndChannel, VER(51));
+ s.syncAsSint32LE(_heSndFlags, VER(51));
}
#ifdef ENABLE_HE
-void ScummEngine_v71he::saveOrLoad(Serializer *s) {
- ScummEngine_v70he::saveOrLoad(s);
-
- const SaveLoadEntry polygonEntries[] = {
- MKLINE(WizPolygon, vert[0].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[0].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[1].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[1].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[2].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[2].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[3].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[3].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[4].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[4].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.left, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.top, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.right, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.bottom, sleInt16, VER(40)),
- MKLINE(WizPolygon, id, sleInt16, VER(40)),
- MKLINE(WizPolygon, numVerts, sleInt16, VER(40)),
- MKLINE(WizPolygon, flag, sleByte, VER(40)),
- MKEND()
- };
-
- s->saveLoadArrayOf(_wiz->_polygons, ARRAYSIZE(_wiz->_polygons), sizeof(_wiz->_polygons[0]), polygonEntries);
+static void syncWithSerializer(Common::Serializer &s, WizPolygon &wp) {
+ s.syncAsSint16LE(wp.vert[0].x, VER(40));
+ s.syncAsSint16LE(wp.vert[0].y, VER(40));
+ s.syncAsSint16LE(wp.vert[1].x, VER(40));
+ s.syncAsSint16LE(wp.vert[1].y, VER(40));
+ s.syncAsSint16LE(wp.vert[2].x, VER(40));
+ s.syncAsSint16LE(wp.vert[2].y, VER(40));
+ s.syncAsSint16LE(wp.vert[3].x, VER(40));
+ s.syncAsSint16LE(wp.vert[3].y, VER(40));
+ s.syncAsSint16LE(wp.vert[4].x, VER(40));
+ s.syncAsSint16LE(wp.vert[4].y, VER(40));
+ s.syncAsSint16LE(wp.bound.left, VER(40));
+ s.syncAsSint16LE(wp.bound.top, VER(40));
+ s.syncAsSint16LE(wp.bound.right, VER(40));
+ s.syncAsSint16LE(wp.bound.bottom, VER(40));
+ s.syncAsSint16LE(wp.id, VER(40));
+ s.syncAsSint16LE(wp.numVerts, VER(40));
+ s.syncAsByte(wp.flag, VER(40));
}
-void ScummEngine_v90he::saveOrLoad(Serializer *s) {
- ScummEngine_v71he::saveOrLoad(s);
-
- const SaveLoadEntry floodFillEntries[] = {
- MKLINE(FloodFillParameters, box.left, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.top, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.right, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.bottom, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, x, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, y, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, flags, sleInt32, VER(51)),
- MK_OBSOLETE(FloodFillParameters, unk1C, sleInt32, VER(51), VER(62)),
- MKEND()
- };
-
- const SaveLoadEntry HE90Entries[] = {
- MKLINE(ScummEngine_v90he, _curMaxSpriteId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _curSpriteId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _curSpriteGroupId, sleInt32, VER(51)),
- MK_OBSOLETE(ScummEngine_v90he, _numSpritesToProcess, sleInt32, VER(51), VER(63)),
- MKLINE(ScummEngine_v90he, _heObject, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _heObjectNum, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _hePaletteNum, sleInt32, VER(51)),
- MKEND()
- };
-
- _sprite->saveOrLoadSpriteData(s);
-
- s->saveLoadArrayOf(&_floodFillParams, 1, sizeof(_floodFillParams), floodFillEntries);
-
- s->saveLoadEntries(this, HE90Entries);
+void ScummEngine_v71he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v70he::saveLoadWithSerializer(s);
+
+ s.syncArray(_wiz->_polygons, ARRAYSIZE(_wiz->_polygons), syncWithSerializer);
}
-void ScummEngine_v99he::saveOrLoad(Serializer *s) {
- ScummEngine_v90he::saveOrLoad(s);
+void syncWithSerializer(Common::Serializer &s, FloodFillParameters &ffp) {
+ s.syncAsSint32LE(ffp.box.left, VER(51));
+ s.syncAsSint32LE(ffp.box.top, VER(51));
+ s.syncAsSint32LE(ffp.box.right, VER(51));
+ s.syncAsSint32LE(ffp.box.bottom, VER(51));
+ s.syncAsSint32LE(ffp.x, VER(51));
+ s.syncAsSint32LE(ffp.y, VER(51));
+ s.syncAsSint32LE(ffp.flags, VER(51));
+ s.skip(4, VER(51), VER(62)); // unk1C
+}
+
+void ScummEngine_v90he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v71he::saveLoadWithSerializer(s);
+
+ _sprite->saveLoadWithSerializer(s);
+
+ syncWithSerializer(s, _floodFillParams);
- s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * _hePaletteSlot, sizeof(_hePalettes[0]), sleUint8);
+ s.syncAsSint32LE(_curMaxSpriteId, VER(51));
+ s.syncAsSint32LE(_curSpriteId, VER(51));
+ s.syncAsSint32LE(_curSpriteGroupId, VER(51));
+ s.skip(4, VER(51), VER(63)); // _numSpritesToProcess
+ s.syncAsSint32LE(_heObject, VER(51));
+ s.syncAsSint32LE(_heObjectNum, VER(51));
+ s.syncAsSint32LE(_hePaletteNum, VER(51));
}
-void ScummEngine_v100he::saveOrLoad(Serializer *s) {
- ScummEngine_v99he::saveOrLoad(s);
+void ScummEngine_v99he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v90he::saveLoadWithSerializer(s);
- const SaveLoadEntry HE100Entries[] = {
- MKLINE(ScummEngine_v100he, _heResId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v100he, _heResType, sleInt32, VER(51)),
- MKEND()
- };
+ s.syncBytes(_hePalettes, (_numPalettes + 1) * _hePaletteSlot);
+}
+
+void ScummEngine_v100he::saveLoadWithSerializer(Common::Serializer &s) {
+ ScummEngine_v99he::saveLoadWithSerializer(s);
- s->saveLoadEntries(this, HE100Entries);
+ s.syncAsSint32LE(_heResId, VER(51));
+ s.syncAsSint32LE(_heResType, VER(51));
}
#endif
-void ScummEngine::loadResourceOLD(Serializer *ser, ResType type, ResId idx) {
+void ScummEngine::loadResourceOLD(Common::Serializer &ser, ResType type, ResId idx) {
uint32 size;
- if (type == rtSound && ser->getVersion() >= VER(23)) {
+ if (type == rtSound && ser.getVersion() >= VER(23)) {
// Save/load only a list of resource numbers that need to be reloaded.
- if (ser->loadUint16())
+ uint16 tmp;
+ ser.syncAsUint16LE(tmp);
+ if (tmp)
ensureResourceLoaded(rtSound, idx);
} else if (_res->_types[type]._mode == kDynamicResTypeMode) {
- size = ser->loadUint32();
+ ser.syncAsUint32LE(size);
if (size) {
_res->createResource(type, idx, size);
- ser->loadBytes(getResourceAddress(type, idx), size);
+ ser.syncBytes(getResourceAddress(type, idx), size);
if (type == rtInventory) {
- _inventory[idx] = ser->loadUint16();
+ ser.syncAsUint16LE(_inventory[idx]);
}
- if (type == rtObjectName && ser->getVersion() >= VER(25)) {
+ if (type == rtObjectName && ser.getVersion() >= VER(25)) {
// Paranoia: We increased the possible number of new names
// to fix bugs #933610 and #936323. The savegame format
// didn't change, but at least during the transition
@@ -1723,38 +1684,39 @@ void ScummEngine::loadResourceOLD(Serializer *ser, ResType type, ResId idx) {
// more names than we have allocated space for. If so,
// discard them.
if (idx < _numNewNames)
- _newNames[idx] = ser->loadUint16();
+ ser.syncAsUint16LE(_newNames[idx]);
}
}
}
}
-void ScummEngine::saveResource(Serializer *ser, ResType type, ResId idx) {
+void ScummEngine::saveResource(Common::Serializer &ser, ResType type, ResId idx) {
assert(_res->_types[type][idx]._address);
if (_res->_types[type]._mode == kDynamicResTypeMode) {
byte *ptr = _res->_types[type][idx]._address;
uint32 size = _res->_types[type][idx]._size;
- ser->saveUint32(size);
- ser->saveBytes(ptr, size);
+ ser.syncAsUint32LE(size);
+ ser.syncBytes(ptr, size);
if (type == rtInventory) {
- ser->saveUint16(_inventory[idx]);
+ ser.syncAsUint16LE(_inventory[idx]);
}
if (type == rtObjectName) {
- ser->saveUint16(_newNames[idx]);
+ ser.syncAsUint16LE(_newNames[idx]);
}
}
}
-void ScummEngine::loadResource(Serializer *ser, ResType type, ResId idx) {
- if (_game.heversion >= 60 && ser->getVersion() <= VER(65) &&
+void ScummEngine::loadResource(Common::Serializer &ser, ResType type, ResId idx) {
+ if (_game.heversion >= 60 && ser.getVersion() <= VER(65) &&
((type == rtSound && idx == 1) || (type == rtSpoolBuffer))) {
- uint32 size = ser->loadUint32();
+ uint32 size;
+ ser.syncAsUint32LE(size);
assert(size);
_res->createResource(type, idx, size);
- ser->loadBytes(getResourceAddress(type, idx), size);
+ ser.syncBytes(getResourceAddress(type, idx), size);
} else if (type == rtSound) {
// HE Games use sound resource 1 for speech
if (_game.heversion >= 60 && idx == 1)
@@ -1762,243 +1724,18 @@ void ScummEngine::loadResource(Serializer *ser, ResType type, ResId idx) {
ensureResourceLoaded(rtSound, idx);
} else if (_res->_types[type]._mode == kDynamicResTypeMode) {
- uint32 size = ser->loadUint32();
+ uint32 size;
+ ser.syncAsUint32LE(size);
assert(size);
byte *ptr = _res->createResource(type, idx, size);
- ser->loadBytes(ptr, size);
+ ser.syncBytes(ptr, size);
if (type == rtInventory) {
- _inventory[idx] = ser->loadUint16();
+ ser.syncAsUint16LE(_inventory[idx]);
}
if (type == rtObjectName) {
- _newNames[idx] = ser->loadUint16();
- }
- }
-}
-
-void Serializer::saveBytes(void *b, int len) {
- _saveStream->write(b, len);
-}
-
-void Serializer::loadBytes(void *b, int len) {
- _loadStream->read(b, len);
-}
-
-void Serializer::saveUint32(uint32 d) {
- _saveStream->writeUint32LE(d);
-}
-
-void Serializer::saveUint16(uint16 d) {
- _saveStream->writeUint16LE(d);
-}
-
-void Serializer::saveByte(byte b) {
- _saveStream->writeByte(b);
-}
-
-uint32 Serializer::loadUint32() {
- return _loadStream->readUint32LE();
-}
-
-uint16 Serializer::loadUint16() {
- return _loadStream->readUint16LE();
-}
-
-byte Serializer::loadByte() {
- return _loadStream->readByte();
-}
-
-void Serializer::saveArrayOf(void *b, int len, int datasize, byte filetype) {
- byte *at = (byte *)b;
- uint32 data;
-
- // speed up byte arrays
- if (datasize == 1 && filetype == sleByte) {
- if (len > 0) {
- saveBytes(b, len);
- }
- return;
- }
-
- while (--len >= 0) {
- if (datasize == 0) {
- // Do nothing for obsolete data
- data = 0;
- } else if (datasize == 1) {
- data = *(byte *)at;
- at += 1;
- } else if (datasize == 2) {
- data = *(uint16 *)at;
- at += 2;
- } else if (datasize == 4) {
- data = *(uint32 *)at;
- at += 4;
- } else {
- error("saveArrayOf: invalid size %d", datasize);
- }
- switch (filetype) {
- case sleByte:
- saveByte((byte)data);
- break;
- case sleUint16:
- case sleInt16:
- saveUint16((int16)data);
- break;
- case sleInt32:
- case sleUint32:
- saveUint32(data);
- break;
- default:
- error("saveArrayOf: invalid filetype %d", filetype);
- }
- }
-}
-
-void Serializer::loadArrayOf(void *b, int len, int datasize, byte filetype) {
- byte *at = (byte *)b;
- uint32 data;
-
- // speed up byte arrays
- if (datasize == 1 && filetype == sleByte) {
- loadBytes(b, len);
- return;
- }
-
- while (--len >= 0) {
- switch (filetype) {
- case sleByte:
- data = loadByte();
- break;
- case sleUint16:
- data = loadUint16();
- break;
- case sleInt16:
- data = (int16)loadUint16();
- break;
- case sleUint32:
- data = loadUint32();
- break;
- case sleInt32:
- data = (int32)loadUint32();
- break;
- default:
- error("loadArrayOf: invalid filetype %d", filetype);
- }
- if (datasize == 0) {
- // Do nothing for obsolete data
- } else if (datasize == 1) {
- *(byte *)at = (byte)data;
- at += 1;
- } else if (datasize == 2) {
- *(uint16 *)at = (uint16)data;
- at += 2;
- } else if (datasize == 4) {
- *(uint32 *)at = data;
- at += 4;
- } else {
- error("loadArrayOf: invalid size %d", datasize);
- }
- }
-}
-
-void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle) {
- byte *data = (byte *)b;
-
- if (isSaving()) {
- while (--num >= 0) {
- saveEntries(data, sle);
- data += datasize;
- }
- } else {
- while (--num >= 0) {
- loadEntries(data, sle);
- data += datasize;
- }
- }
-}
-
-void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) {
- if (isSaving())
- saveArrayOf(b, len, datasize, filetype);
- else
- loadArrayOf(b, len, datasize, filetype);
-}
-
-void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
- if (isSaving())
- saveEntries(d, sle);
- else
- loadEntries(d, sle);
-}
-
-void Serializer::saveEntries(void *d, const SaveLoadEntry *sle) {
- byte type;
- byte *at;
- int size;
-
- while (sle->offs != 0xFFFF) {
- at = (byte *)d + sle->offs;
- size = sle->size;
- type = (byte) sle->type;
-
- if (sle->maxVersion != CURRENT_VER) {
- // Skip obsolete entries
- if (type & 128)
- sle++;
- } else {
- // save entry
- int columns = 1;
- int rows = 1;
- int rowlen = 0;
- if (type & 128) {
- sle++;
- columns = sle->offs;
- rows = sle->type;
- rowlen = sle->size;
- type &= ~128;
- }
- while (rows--) {
- saveArrayOf(at, columns, size, type);
- at += rowlen;
- }
- }
- sle++;
- }
-}
-
-void Serializer::loadEntries(void *d, const SaveLoadEntry *sle) {
- byte type;
- byte *at;
- int size;
-
- while (sle->offs != 0xFFFF) {
- at = (byte *)d + sle->offs;
- size = sle->size;
- type = (byte) sle->type;
-
- if (_savegameVersion < sle->minVersion || _savegameVersion > sle->maxVersion) {
- // Skip entries which are not present in this save game version
- if (type & 128)
- sle++;
- } else {
- // load entry
- int columns = 1;
- int rows = 1;
- int rowlen = 0;
-
- if (type & 128) {
- sle++;
- columns = sle->offs;
- rows = sle->type;
- rowlen = sle->size;
- type &= ~128;
- }
- while (rows--) {
- loadArrayOf(at, columns, size, type);
- at += rowlen;
- }
+ ser.syncAsUint16LE(_newNames[idx]);
}
- sle++;
}
}
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index fb2d45df8c..a0f45a32fc 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -24,16 +24,10 @@
#define SCUMM_SAVELOAD_H
#include "common/scummsys.h"
-#include <stddef.h> // for ptrdiff_t
-
-namespace Common {
-class SeekableReadStream;
-class WriteStream;
-}
+#include "common/serializer.h"
namespace Scumm {
-
/**
* The current savegame format version.
* Our save/load system uses an elaborate scheme to allow us to modify the
@@ -54,117 +48,7 @@ namespace Scumm {
* of just writing the raw version, because this way they stand out more to
* the reading eye, making it a bit easier to navigate through the code.
*/
-#define VER(x) x
-
-
-/**
- * The OFFS macro essentially provides the functionality of offsetof(), that
- * is, it determines the offset of a struct/class member within instances of
- * that class.
- *
- * This is a place where we cheat a bit and sacrifice some potential portability
- * (although so far we haven't encountered any platform where this matters).
- *
- * 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
- * versions have a heuristic built in to detect "offset-of" patterns - which is exactly
- * what our OFFS macro does. Now, for non-POD types this is not really legal, because
- * member need not be at a fixed offset relative to the variable, even if they are in
- * current reality (many of our complex structs are non-POD; for an explanation of
- * what POD means refer to <http://en.wikipedia.org/wiki/Plain_Old_Data_Structures> or
- * to <http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=32&rl=1>)
- */
-#define OFFS(type,item) ((uint32)(((ptrdiff_t)(&((type *)42)->type::item))-42))
-
-/**
- * Similar to the OFFS macro, this macro computes the size (in bytes) of a
- * member of a given struct/class type.
- */
-#define SIZE(type,item) sizeof(((type *)42)->type::item)
-
-// Any item that is still in use automatically gets a maxVersion equal to CURRENT_VER
-#define MKLINE(type,item,saveas,minVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,CURRENT_VER}
-#define MKARRAY(type,item,saveas,dim,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {(uint32)(dim),1,0,0,0}
-#define MKARRAY2(type,item,saveas,dim,dim2,rowlen,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0}
-
-// Use this if you have an entry that used to be smaller:
-#define MKLINE_OLD(type,item,saveas,minVer,maxVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,maxVer}
-#define MKARRAY_OLD(type,item,saveas,dim,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {(uint32)(dim),1,0,0,0}
-#define MKARRAY2_OLD(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0}
-
-// An obsolete item/array, to be ignored upon load. We retain the type/item params to make it easier to debug.
-// Obsolete items have size == 0.
-#define MK_OBSOLETE(type,item,saveas,minVer,maxVer) {0,saveas,0,minVer,maxVer}
-#define MK_OBSOLETE_ARRAY(type,item,saveas,dim,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {(uint32)(dim),1,0,0,0}
-#define MK_OBSOLETE_ARRAY2(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0}
-
-// End marker
-#define MKEND() {0xFFFF,0xFF,0xFF,0,0}
-
-
-enum {
- sleByte = 1,
- sleUint8 = 1,
- sleInt8 = 1,
- sleInt16 = 2,
- sleUint16 = 3,
- sleInt32 = 4,
- sleUint32 = 5
-};
-
-struct SaveLoadEntry {
- uint32 offs; // or: array dimension
- uint16 type; // or: array dimension 2
- uint16 size; // or: array row length
- uint8 minVersion;
- uint8 maxVersion;
-};
-
-class Serializer {
-public:
- Serializer(Common::SeekableReadStream *in, Common::WriteStream *out, uint32 savegameVersion)
- : _loadStream(in), _saveStream(out),
- _savegameVersion(savegameVersion)
- { }
-
- void saveLoadArrayOf(void *b, int len, int datasize, byte filetype);
- void saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle);
- void saveLoadEntries(void *d, const SaveLoadEntry *sle);
-
- bool isSaving() { return (_saveStream != 0); }
- bool isLoading() { return (_loadStream != 0); }
- uint32 getVersion() { return _savegameVersion; }
-
- void saveUint32(uint32 d);
- void saveUint16(uint16 d);
- void saveByte(byte b);
-
- byte loadByte();
- uint16 loadUint16();
- uint32 loadUint32();
-
- void saveBytes(void *b, int len);
- void loadBytes(void *b, int len);
-
-protected:
- Common::SeekableReadStream *_loadStream;
- Common::WriteStream *_saveStream;
- uint32 _savegameVersion;
-
- void saveArrayOf(void *b, int len, int datasize, byte filetype);
- void loadArrayOf(void *b, int len, int datasize, byte filetype);
-
- void saveEntries(void *d, const SaveLoadEntry *sle);
- void loadEntries(void *d, const SaveLoadEntry *sle);
-};
-
-
-// Mixin class / interface. Maybe call it ISerializable or SerializableMixin ?
-class Serializable {
-public:
- virtual ~Serializable() {}
- virtual void saveLoadWithSerializer(Serializer *ser) = 0;
-};
+#define VER(x) Common::Serializer::Version(x)
} // End of namespace Scumm
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index caa1f84704..ad3a3c161a 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -33,6 +33,7 @@
#include "common/random.h"
#include "common/rect.h"
#include "common/rendermode.h"
+#include "common/serializer.h"
#include "common/str.h"
#include "common/textconsole.h"
#include "graphics/surface.h"
@@ -88,7 +89,6 @@ class MusicEngine;
class Player_Towns;
class ScummEngine;
class ScummDebugger;
-class Serializer;
class Sound;
struct Box;
@@ -375,7 +375,7 @@ class ResourceManager;
/**
* Base class for all SCUMM engines.
*/
-class ScummEngine : public Engine {
+class ScummEngine : public Engine, public Common::Serializable {
friend class ScummDebugger;
friend class CharsetRenderer;
friend class CharsetRendererTownsClassic;
@@ -608,10 +608,10 @@ protected:
bool saveState(int slot, bool compat, Common::String &fileName);
bool loadState(int slot, bool compat);
bool loadState(int slot, bool compat, Common::String &fileName);
- virtual void saveOrLoad(Serializer *s);
- void saveResource(Serializer *ser, ResType type, ResId idx);
- void loadResource(Serializer *ser, ResType type, ResId idx);
- void loadResourceOLD(Serializer *ser, ResType type, ResId idx); // "Obsolete"
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
+ void saveResource(Common::Serializer &ser, ResType type, ResId idx);
+ void loadResource(Common::Serializer &ser, ResType type, ResId idx);
+ void loadResourceOLD(Common::Serializer &ser, ResType type, ResId idx); // "Obsolete"
virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName);
virtual Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName);
@@ -1166,6 +1166,7 @@ protected:
int x1, y1, scale1;
int x2, y2, scale2;
};
+ friend void syncWithSerializer(Common::Serializer &, ScaleSlot &);
ScaleSlot _scaleSlots[20];
void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
void setBoxScaleSlot(int box, int slot);
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 5f40940166..dd2142dac5 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -86,7 +86,7 @@ protected:
virtual void processInput();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual bool objIsActor(int obj);
virtual int objToActor(int obj);
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 2a9e7a96e6..43226b8386 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -60,7 +60,7 @@ protected:
virtual void resetScummVars();
virtual void decodeParseString();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void processKeyboard(Common::KeyState lastKeyHit);
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index 1bd38d68f2..76b6c12e36 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -66,7 +66,7 @@ protected:
virtual void resetScummVars();
virtual void decodeParseString();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void readMAXS(int blockSize);
diff --git a/engines/scumm/scumm_v7.h b/engines/scumm/scumm_v7.h
index b8830be810..822ef7ca76 100644
--- a/engines/scumm/scumm_v7.h
+++ b/engines/scumm/scumm_v7.h
@@ -84,6 +84,7 @@ protected:
struct SubtitleText : TextObject {
bool actorSpeechMsg;
};
+ friend void syncWithSerializer(Common::Serializer &, SubtitleText &);
#endif
int _subtitleQueuePos;
@@ -111,7 +112,7 @@ protected:
virtual void akos_processQueue();
- virtual void saveOrLoad(Serializer *s);
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
virtual void readMAXS(int blockSize);
virtual void readGlobalObjects();
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 599871b0e7..8099dd250a 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -1116,14 +1116,9 @@ AudioCDManager::Status Sound::getCDStatus() {
}
}
-void Sound::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry soundEntries[] = {
- MKLINE(Sound, _currentCDSound, sleInt16, VER(35)),
- MKLINE(Sound, _currentMusic, sleInt16, VER(35)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, soundEntries);
+void Sound::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsSint16LE(_currentCDSound, VER(35));
+ s.syncAsSint16LE(_currentMusic, VER(35));
}
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index bc1e88f76b..440570307d 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -24,6 +24,7 @@
#define SCUMM_SOUND_H
#include "common/scummsys.h"
+#include "common/serializer.h"
#include "common/str.h"
#include "audio/mididrv.h"
#include "backends/audiocd/audiocd.h"
@@ -46,7 +47,7 @@ enum {
// TODO: Consider splitting Sound into even more subclasses.
// E.g. for v1-v4, v5, v6+, ...
-class Sound : public Serializable {
+class Sound : public Common::Serializable {
public:
enum SoundMode {
kVOCMode,
@@ -132,8 +133,7 @@ public:
AudioCDManager::Status getCDStatus();
int getCurrentCDSound() const { return _currentCDSound; }
- // Used by the save/load system:
- void saveLoadWithSerializer(Serializer *ser);
+ void saveLoadWithSerializer(Common::Serializer &ser);
protected:
void setupSfxFile();