mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
SCUMM: Replace UB-triggering serialization code with Common::Serializer
Fixes Trac#10342.
This commit is contained in:
parent
157ee95f64
commit
9916b26383
@ -3437,43 +3437,38 @@ void Actor_v0::actorSetWalkTo() {
|
||||
}
|
||||
}
|
||||
|
||||
void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
|
||||
Actor::saveLoadWithSerializer(ser);
|
||||
void Actor_v0::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
Actor::saveLoadWithSerializer(s);
|
||||
|
||||
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)),
|
||||
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));
|
||||
|
||||
MKARRAY(Actor_v0, _walkboxQueue[0], sleByte, 16, VER(98)),
|
||||
MKLINE(Actor_v0, _walkboxQueueIndex, sleByte, VER(98)),
|
||||
MKEND()
|
||||
};
|
||||
|
||||
ser->saveLoadEntries(this, actorEntries);
|
||||
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);
|
||||
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));
|
||||
|
||||
if (ser->isLoading() && _vm->_game.version <= 2 && ser->getVersion() < VER(70)) {
|
||||
// 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;
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 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 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()
|
||||
};
|
||||
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));
|
||||
}
|
||||
|
||||
if (s->getVersion() >= VER(64)) {
|
||||
s->saveLoadArrayOf(_spriteTable, _varNumSprites + 1, sizeof(_spriteTable[0]), spriteEntries);
|
||||
s->saveLoadArrayOf(_spriteGroups, _varNumSpriteGroups + 1, sizeof(_spriteGroups[0]), spriteGroupEntries);
|
||||
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
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
};
|
||||
static void syncWithSerializer(Common::Serializer &s, CommandQueue &cq) {
|
||||
s.syncArray(cq.array, 8, Common::Serializer::Uint16LE, VER(23));
|
||||
}
|
||||
|
||||
const SaveLoadEntry cmdQueueEntries[] = {
|
||||
MKARRAY(CommandQueue, array[0], sleUint16, 8, VER(23)),
|
||||
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));
|
||||
}
|
||||
|
||||
// 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()
|
||||
};
|
||||
|
||||
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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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()
|
||||
};
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -103,61 +103,55 @@ void IMuseDigital::resetState() {
|
||||
_triggerUsed = false;
|
||||
}
|
||||
|
||||
void IMuseDigital::saveOrLoad(Serializer *ser) {
|
||||
Common::StackLock lock(_mutex, "IMuseDigital::saveOrLoad()");
|
||||
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));
|
||||
}
|
||||
|
||||
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()
|
||||
};
|
||||
void IMuseDigital::saveLoadEarly(Common::Serializer &s) {
|
||||
Common::StackLock lock(_mutex, "IMuseDigital::saveLoadEarly()");
|
||||
|
||||
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);
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
};
|
||||
s.syncAsByte(_eupCurrentSound, VER(81));
|
||||
s.syncAsByte(_eupLooping, VER(81));
|
||||
s.syncAsByte(_eupVolLeft, VER(81));
|
||||
s.syncAsByte(_eupVolRight, VER(81));
|
||||
|
||||
ser->saveLoadEntries(this, eupEntries);
|
||||
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user