aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2002-12-08 16:14:29 +0000
committerMax Horn2002-12-08 16:14:29 +0000
commit4ddecdad589e9df3db4a5a12fb9cdb874ae1d00b (patch)
tree165ba65531919c0a158136d496b225a3f30a969a /scumm
parent2986adb53dea09928f5051674e4d53d39d83cf27 (diff)
downloadscummvm-rg350-4ddecdad589e9df3db4a5a12fb9cdb874ae1d00b.tar.gz
scummvm-rg350-4ddecdad589e9df3db4a5a12fb9cdb874ae1d00b.tar.bz2
scummvm-rg350-4ddecdad589e9df3db4a5a12fb9cdb874ae1d00b.zip
Patch #650085: Make saveload system extensible
svn-id: r5885
Diffstat (limited to 'scumm')
-rw-r--r--scumm/actor.h1
-rw-r--r--scumm/imuse.cpp153
-rw-r--r--scumm/saveload.cpp929
-rw-r--r--scumm/saveload.h79
-rw-r--r--scumm/scumm.h6
5 files changed, 586 insertions, 582 deletions
diff --git a/scumm/actor.h b/scumm/actor.h
index 3bb5188a8d..2ebfaf02c7 100644
--- a/scumm/actor.h
+++ b/scumm/actor.h
@@ -101,7 +101,6 @@ public:
byte frame;
byte walkbox;
- byte mask; // FIXME: This field is *NOT* used - remove next time save game format changes
byte animProgress, animSpeed;
int16 new_1, new_2;
uint16 talk_script, walk_script;
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 30af7deee7..d46cfe336d 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -455,8 +455,8 @@ private:
void fix_parts_after_load();
void fix_players_after_load(Scumm *scumm);
- static int saveReference(IMuseInternal *me, byte type, void *ref);
- static void *loadReference(IMuseInternal *me, byte type, int ref);
+ static int saveReference(void *me_ref, byte type, void *ref);
+ static void *loadReference(void *me_ref, byte type, int ref);
void lock();
void unlock();
@@ -3143,8 +3143,9 @@ enum {
TYPE_PLAYER = 2,
};
-int IMuseInternal::saveReference(IMuseInternal *me, byte type, void *ref)
+int IMuseInternal::saveReference(void *me_ref, byte type, void *ref)
{
+ IMuseInternal *me = (IMuseInternal *)me_ref;
switch (type) {
case TYPE_PART:
return (Part *)ref - me->_parts;
@@ -3155,8 +3156,9 @@ int IMuseInternal::saveReference(IMuseInternal *me, byte type, void *ref)
}
}
-void *IMuseInternal::loadReference(IMuseInternal *me, byte type, int ref)
+void *IMuseInternal::loadReference(void *me_ref, byte type, int ref)
{
+ IMuseInternal *me = (IMuseInternal *)me_ref;
switch (type) {
case TYPE_PART:
return &me->_parts[ref];
@@ -3170,88 +3172,88 @@ void *IMuseInternal::loadReference(IMuseInternal *me, byte type, int ref)
int IMuseInternal::save_or_load(Serializer *ser, Scumm *scumm)
{
const SaveLoadEntry mainEntries[] = {
- MKLINE(IMuseInternal, _queue_end, sleUint8),
- MKLINE(IMuseInternal, _queue_pos, sleUint8),
- MKLINE(IMuseInternal, _queue_sound, sleUint16),
- MKLINE(IMuseInternal, _queue_adding, sleByte),
- MKLINE(IMuseInternal, _queue_marker, sleByte),
- MKLINE(IMuseInternal, _queue_cleared, sleByte),
- MKLINE(IMuseInternal, _master_volume, sleByte),
- MKLINE(IMuseInternal, _trigger_count, sleUint16),
- MKARRAY(IMuseInternal, _channel_volume[0], sleUint16, 8),
- MKARRAY(IMuseInternal, _volchan_table[0], sleUint16, 8),
+ MKLINE(IMuseInternal, _queue_end, sleUint8, VER_V8),
+ MKLINE(IMuseInternal, _queue_pos, sleUint8, VER_V8),
+ MKLINE(IMuseInternal, _queue_sound, sleUint16, VER_V8),
+ MKLINE(IMuseInternal, _queue_adding, sleByte, VER_V8),
+ MKLINE(IMuseInternal, _queue_marker, sleByte, VER_V8),
+ MKLINE(IMuseInternal, _queue_cleared, sleByte, VER_V8),
+ MKLINE(IMuseInternal, _master_volume, sleByte, VER_V8),
+ MKLINE(IMuseInternal, _trigger_count, sleUint16, VER_V8),
+ MKARRAY(IMuseInternal, _channel_volume[0], sleUint16, 8, VER_V8),
+ MKARRAY(IMuseInternal, _volchan_table[0], sleUint16, 8, VER_V8),
MKEND()
};
const SaveLoadEntry playerEntries[] = {
- MKREF(Player, _parts, TYPE_PART),
- MKLINE(Player, _active, sleByte),
- MKLINE(Player, _id, sleUint16),
- MKLINE(Player, _priority, sleByte),
- MKLINE(Player, _volume, sleByte),
- MKLINE(Player, _pan, sleInt8),
- MKLINE(Player, _transpose, sleByte),
- MKLINE(Player, _detune, sleInt8),
- MKLINE(Player, _vol_chan, sleUint16),
- MKLINE(Player, _vol_eff, sleByte),
- MKLINE(Player, _speed, sleByte),
- MKLINE(Player, _song_index, sleUint16),
- MKLINE(Player, _track_index, sleUint16),
- MKLINE(Player, _timer_counter, sleUint16),
- MKLINE(Player, _loop_to_beat, sleUint16),
- MKLINE(Player, _loop_from_beat, sleUint16),
- MKLINE(Player, _loop_counter, sleUint16),
- MKLINE(Player, _loop_to_tick, sleUint16),
- MKLINE(Player, _loop_from_tick, sleUint16),
- MKLINE(Player, _tempo, sleUint32),
- MKLINE(Player, _cur_pos, sleUint32),
- MKLINE(Player, _next_pos, sleUint32),
- MKLINE(Player, _song_offset, sleUint32),
- MKLINE(Player, _tick_index, sleUint16),
- MKLINE(Player, _beat_index, sleUint16),
- MKLINE(Player, _ticks_per_beat, sleUint16),
- MKLINE(Player, _hook._jump, sleByte),
- MKLINE(Player, _hook._transpose, sleByte),
- MKARRAY(Player, _hook._part_onoff[0], sleByte, 16),
- MKARRAY(Player, _hook._part_volume[0], sleByte, 16),
- MKARRAY(Player, _hook._part_program[0], sleByte, 16),
- MKARRAY(Player, _hook._part_transpose[0], sleByte, 16),
+ MKREF(Player, _parts, TYPE_PART, VER_V8),
+ MKLINE(Player, _active, sleByte, VER_V8),
+ MKLINE(Player, _id, sleUint16, VER_V8),
+ MKLINE(Player, _priority, sleByte, VER_V8),
+ MKLINE(Player, _volume, sleByte, VER_V8),
+ MKLINE(Player, _pan, sleInt8, VER_V8),
+ MKLINE(Player, _transpose, sleByte, VER_V8),
+ MKLINE(Player, _detune, sleInt8, VER_V8),
+ MKLINE(Player, _vol_chan, sleUint16, VER_V8),
+ MKLINE(Player, _vol_eff, sleByte, VER_V8),
+ MKLINE(Player, _speed, sleByte, VER_V8),
+ MKLINE(Player, _song_index, sleUint16, VER_V8),
+ MKLINE(Player, _track_index, sleUint16, VER_V8),
+ MKLINE(Player, _timer_counter, sleUint16, VER_V8),
+ MKLINE(Player, _loop_to_beat, sleUint16, VER_V8),
+ MKLINE(Player, _loop_from_beat, sleUint16, VER_V8),
+ MKLINE(Player, _loop_counter, sleUint16, VER_V8),
+ MKLINE(Player, _loop_to_tick, sleUint16, VER_V8),
+ MKLINE(Player, _loop_from_tick, sleUint16, VER_V8),
+ MKLINE(Player, _tempo, sleUint32, VER_V8),
+ MKLINE(Player, _cur_pos, sleUint32, VER_V8),
+ MKLINE(Player, _next_pos, sleUint32, VER_V8),
+ MKLINE(Player, _song_offset, sleUint32, VER_V8),
+ MKLINE(Player, _tick_index, sleUint16, VER_V8),
+ MKLINE(Player, _beat_index, sleUint16, VER_V8),
+ MKLINE(Player, _ticks_per_beat, sleUint16, VER_V8),
+ MKLINE(Player, _hook._jump, sleByte, VER_V8),
+ MKLINE(Player, _hook._transpose, sleByte, VER_V8),
+ MKARRAY(Player, _hook._part_onoff[0], sleByte, 16, VER_V8),
+ MKARRAY(Player, _hook._part_volume[0], sleByte, 16, VER_V8),
+ MKARRAY(Player, _hook._part_program[0], sleByte, 16, VER_V8),
+ MKARRAY(Player, _hook._part_transpose[0], sleByte, 16, VER_V8),
MKEND()
};
const SaveLoadEntry volumeFaderEntries[] = {
- MKREF(VolumeFader, player, TYPE_PLAYER),
- MKLINE(VolumeFader, active, sleUint8),
- MKLINE(VolumeFader, curvol, sleUint8),
- MKLINE(VolumeFader, speed_lo_max, sleUint16),
- MKLINE(VolumeFader, num_steps, sleUint16),
- MKLINE(VolumeFader, speed_hi, sleInt8),
- MKLINE(VolumeFader, direction, sleInt8),
- MKLINE(VolumeFader, speed_lo, sleInt8),
- MKLINE(VolumeFader, speed_lo_counter, sleUint16),
+ MKREF(VolumeFader, player, TYPE_PLAYER, VER_V8),
+ MKLINE(VolumeFader, active, sleUint8, VER_V8),
+ MKLINE(VolumeFader, curvol, sleUint8, VER_V8),
+ MKLINE(VolumeFader, speed_lo_max, sleUint16, VER_V8),
+ MKLINE(VolumeFader, num_steps, sleUint16, VER_V8),
+ MKLINE(VolumeFader, speed_hi, sleInt8, VER_V8),
+ MKLINE(VolumeFader, direction, sleInt8, VER_V8),
+ MKLINE(VolumeFader, speed_lo, sleInt8, VER_V8),
+ MKLINE(VolumeFader, speed_lo_counter, sleUint16, VER_V8),
MKEND()
};
const SaveLoadEntry partEntries[] = {
- MKREF(Part, _next, TYPE_PART),
- MKREF(Part, _prev, TYPE_PART),
- MKREF(Part, _player, TYPE_PLAYER),
- MKLINE(Part, _pitchbend, sleInt16),
- MKLINE(Part, _pitchbend_factor, sleUint8),
- MKLINE(Part, _transpose, sleInt8),
- MKLINE(Part, _vol, sleUint8),
- MKLINE(Part, _detune, sleInt8),
- MKLINE(Part, _pan, sleInt8),
- MKLINE(Part, _on, sleUint8),
- MKLINE(Part, _modwheel, sleUint8),
- MKLINE(Part, _pedal, sleUint8),
- MKLINE(Part, _program, sleUint8),
- MKLINE(Part, _pri, sleUint8),
- MKLINE(Part, _chan, sleUint8),
- MKLINE(Part, _effect_level, sleUint8),
- MKLINE(Part, _chorus, sleUint8),
- MKLINE(Part, _percussion, sleUint8),
- MKLINE(Part, _bank, sleUint8),
+ MKREF(Part, _next, TYPE_PART, VER_V8),
+ MKREF(Part, _prev, TYPE_PART, VER_V8),
+ MKREF(Part, _player, TYPE_PLAYER, VER_V8),
+ MKLINE(Part, _pitchbend, sleInt16, VER_V8),
+ MKLINE(Part, _pitchbend_factor, sleUint8, VER_V8),
+ MKLINE(Part, _transpose, sleInt8, VER_V8),
+ MKLINE(Part, _vol, sleUint8, VER_V8),
+ MKLINE(Part, _detune, sleInt8, VER_V8),
+ MKLINE(Part, _pan, sleInt8, VER_V8),
+ MKLINE(Part, _on, sleUint8, VER_V8),
+ MKLINE(Part, _modwheel, sleUint8, VER_V8),
+ MKLINE(Part, _pedal, sleUint8, VER_V8),
+ MKLINE(Part, _program, sleUint8, VER_V8),
+ MKLINE(Part, _pri, sleUint8, VER_V8),
+ MKLINE(Part, _chan, sleUint8, VER_V8),
+ MKLINE(Part, _effect_level, sleUint8, VER_V8),
+ MKLINE(Part, _chorus, sleUint8, VER_V8),
+ MKLINE(Part, _percussion, sleUint8, VER_V8),
+ MKLINE(Part, _bank, sleUint8, VER_V8),
MKEND()
};
@@ -3261,7 +3263,8 @@ int IMuseInternal::save_or_load(Serializer *ser, Scumm *scumm)
#endif
ser->_ref_me = this;
- ser->_saveload_ref = ser->isSaving()? ((void *)&saveReference) : ((void *)&loadReference);
+ ser->_save_ref = saveReference;
+ ser->_load_ref = loadReference;
ser->saveLoadEntries(this, mainEntries);
ser->saveLoadArrayOf(_players, ARRAYSIZE(_players), sizeof(_players[0]), playerEntries);
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
index a562925587..e55188fde7 100644
--- a/scumm/saveload.cpp
+++ b/scumm/saveload.cpp
@@ -38,23 +38,12 @@ struct SaveGameHeader {
char name[32];
};
-// Support for "old" savegames (made with 2501 CVS build)
-// Can be useful for other ports too :)
-
-#define VER_V9 9
-#define VER_V8 8
-#define VER_V7 7
-
-#define CURRENT_VER VER_V9
-
-static uint32 _current_version = CURRENT_VER;
bool Scumm::saveState(int slot, bool compat)
{
char filename[256];
SerializerStream out;
SaveGameHeader hdr;
- Serializer ser;
makeSavegameName(filename, slot, compat);
@@ -65,12 +54,13 @@ bool Scumm::saveState(int slot, bool compat)
hdr.type = MKID('SCVM');
hdr.size = 0;
- hdr.ver = TO_LE_32(_current_version);
+ hdr.ver = TO_LE_32(CURRENT_VER);
out.fwrite(&hdr, sizeof(hdr), 1);
- ser._saveLoadStream = out;
- ser._saveOrLoad = true;
+ Serializer ser(out, true, CURRENT_VER);
+
+ _savegameVersion = CURRENT_VER;
saveOrLoad(&ser);
out.fclose();
@@ -84,7 +74,6 @@ bool Scumm::loadState(int slot, bool compat)
SerializerStream out;
int i, j;
SaveGameHeader hdr;
- Serializer ser;
int sb, sh;
makeSavegameName(filename, slot, compat);
@@ -100,16 +89,23 @@ bool Scumm::loadState(int slot, bool compat)
// In older versions of ScummVM, the header version was not endian safe.
// We account for that by retrying once with swapped byte order.
- if (hdr.ver < VER_V7 || hdr.ver > _current_version)
+ if (hdr.ver > CURRENT_VER)
hdr.ver = SWAP_BYTES(hdr.ver);
- if (hdr.ver < VER_V7 || hdr.ver > _current_version)
+ if (hdr.ver < VER_V7 || hdr.ver > CURRENT_VER)
{
warning("Invalid version of '%s'", filename);
out.fclose();
return false;
}
-
- _current_version = hdr.ver;
+
+ // Due to a bug in scummvm up to and including 0.3.0, save games could be saved
+ // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
+ if (hdr.ver == VER_V7)
+ hdr.ver = VER_V8;
+
+ // _savegameVersion is set so that the load code can know which data format to expect
+ _savegameVersion = hdr.ver;
+
memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
if (_imuseDigital) {
@@ -133,8 +129,7 @@ bool Scumm::loadState(int slot, bool compat)
initScummVars();
- ser._saveLoadStream = out;
- ser._saveOrLoad = false;
+ Serializer ser(out, false, _savegameVersion);
saveOrLoad(&ser);
out.fclose();
@@ -181,7 +176,6 @@ void Scumm::makeSavegameName(char *out, int slot, bool compatible)
{
const char *dir = getSavePath();
- // snprintf should be used here, but it's not portable enough
sprintf(out, "%s%s.%c%.2d", dir, _game_name, compatible ? 'c' : 's', slot);
}
@@ -205,9 +199,9 @@ bool Scumm::getSavegameName(int slot, char *desc)
return false;
}
- if (hdr.ver < VER_V7 || hdr.ver > _current_version)
+ if (hdr.ver > CURRENT_VER)
hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER_V7 || hdr.ver > _current_version) {
+ if (hdr.ver < VER_V7 || hdr.ver > CURRENT_VER) {
strcpy(desc, "Invalid version");
return false;
}
@@ -220,410 +214,314 @@ bool Scumm::getSavegameName(int slot, char *desc)
void Scumm::saveOrLoad(Serializer *s)
{
const SaveLoadEntry objectEntries[] = {
- MKLINE(ObjectData, offs_obim_to_room, sleUint32),
- MKLINE(ObjectData, offs_obcd_to_room, sleUint32),
- MKLINE(ObjectData, walk_x, sleUint16),
- MKLINE(ObjectData, walk_y, sleUint16),
- MKLINE(ObjectData, obj_nr, sleUint16),
- MKLINE(ObjectData, x_pos, sleInt16),
- MKLINE(ObjectData, y_pos, sleInt16),
- MKLINE(ObjectData, width, sleUint16),
- MKLINE(ObjectData, height, sleUint16),
- MKLINE(ObjectData, actordir, sleByte),
- MKLINE(ObjectData, parentstate, sleByte),
- MKLINE(ObjectData, parent, sleByte),
- MKLINE(ObjectData, state, sleByte),
- MKLINE(ObjectData, fl_object_index, sleByte),
+ MKLINE(ObjectData, offs_obim_to_room, sleUint32, VER_V8),
+ MKLINE(ObjectData, offs_obcd_to_room, sleUint32, VER_V8),
+ MKLINE(ObjectData, walk_x, sleUint16, VER_V8),
+ MKLINE(ObjectData, walk_y, sleUint16, VER_V8),
+ MKLINE(ObjectData, obj_nr, sleUint16, VER_V8),
+ MKLINE(ObjectData, x_pos, sleInt16, VER_V8),
+ MKLINE(ObjectData, y_pos, sleInt16, VER_V8),
+ MKLINE(ObjectData, width, sleUint16, VER_V8),
+ MKLINE(ObjectData, height, sleUint16, VER_V8),
+ MKLINE(ObjectData, actordir, sleByte, VER_V8),
+ MKLINE(ObjectData, parentstate, sleByte, VER_V8),
+ MKLINE(ObjectData, parent, sleByte, VER_V8),
+ MKLINE(ObjectData, state, sleByte, VER_V8),
+ MKLINE(ObjectData, fl_object_index, sleByte, VER_V8),
MKEND()
};
const SaveLoadEntry actorEntries[] = {
- MKLINE(Actor, x, sleInt16),
- MKLINE(Actor, y, sleInt16),
- MKLINE(Actor, top, sleInt16),
- MKLINE(Actor, bottom, sleInt16),
- MKLINE(Actor, elevation, sleInt16),
- MKLINE(Actor, width, sleUint16),
- MKLINE(Actor, facing, sleUint16),
- MKLINE(Actor, costume, sleUint16),
- MKLINE(Actor, room, sleByte),
- MKLINE(Actor, talkColor, sleByte),
- MKLINE(Actor, scalex, sleByte),
- MKLINE(Actor, scaley, sleByte),
- MKLINE(Actor, charset, sleByte),
- MKARRAY(Actor, sound[0], sleByte, 8),
- MKARRAY(Actor, animVariable[0], sleUint16, 8),
- MKLINE(Actor, newDirection, sleUint16),
- MKLINE(Actor, moving, sleByte),
- MKLINE(Actor, ignoreBoxes, sleByte),
- MKLINE(Actor, forceClip, sleByte),
- MKLINE(Actor, initFrame, sleByte),
- MKLINE(Actor, walkFrame, sleByte),
- MKLINE(Actor, standFrame, sleByte),
- MKLINE(Actor, talkFrame1, sleByte),
- MKLINE(Actor, talkFrame2, sleByte),
- MKLINE(Actor, speedx, sleUint16),
- MKLINE(Actor, speedy, sleUint16),
- MKLINE(Actor, cost.animCounter1, sleUint16),
- MKLINE(Actor, cost.animCounter2, sleByte),
- // TODO: increase actor palette to 256
- MKARRAY(Actor, palette[0], sleByte, 64),
- MKLINE(Actor, mask, sleByte), // FIXME: see actor.h comment
- MKLINE(Actor, shadow_mode, sleByte),
- MKLINE(Actor, visible, sleByte),
+ MKLINE(Actor, x, sleInt16, VER_V8),
+ MKLINE(Actor, y, sleInt16, VER_V8),
+ MKLINE(Actor, top, sleInt16, VER_V8),
+ MKLINE(Actor, bottom, sleInt16, VER_V8),
+ MKLINE(Actor, elevation, sleInt16, VER_V8),
+ MKLINE(Actor, width, sleUint16, VER_V8),
+ MKLINE(Actor, facing, sleUint16, VER_V8),
+ MKLINE(Actor, costume, sleUint16, VER_V8),
+ MKLINE(Actor, room, sleByte, VER_V8),
+ MKLINE(Actor, talkColor, sleByte, VER_V8),
+ MKLINE(Actor, scalex, sleByte, VER_V8),
+ MKLINE(Actor, scaley, sleByte, VER_V8),
+ MKLINE(Actor, charset, sleByte, VER_V8),
+ MKARRAY(Actor, sound[0], sleByte, 8, VER_V8),
+ MKARRAY(Actor, animVariable[0], sleUint16, 8, VER_V8),
+ MKLINE(Actor, newDirection, sleUint16, VER_V8),
+ MKLINE(Actor, moving, sleByte, VER_V8),
+ MKLINE(Actor, ignoreBoxes, sleByte, VER_V8),
+ MKLINE(Actor, forceClip, sleByte, VER_V8),
+ MKLINE(Actor, initFrame, sleByte, VER_V8),
+ MKLINE(Actor, walkFrame, sleByte, VER_V8),
+ MKLINE(Actor, standFrame, sleByte, VER_V8),
+ MKLINE(Actor, talkFrame1, sleByte, VER_V8),
+ MKLINE(Actor, talkFrame2, sleByte, VER_V8),
+ MKLINE(Actor, speedx, sleUint16, VER_V8),
+ MKLINE(Actor, speedy, sleUint16, VER_V8),
+ MKLINE(Actor, cost.animCounter1, sleUint16, VER_V8),
+ MKLINE(Actor, cost.animCounter2, sleByte, VER_V8),
+
+ // Actor palette grew from 64 to 256 bytes
+ MKARRAY_OLD(Actor, palette[0], sleByte, 64, VER_V8, VER_V9),
+ MKARRAY(Actor, palette[0], sleByte, 256, VER_V10),
+
+ MK_OBSOLETE(Actor, mask, sleByte, VER_V8, VER_V9),
+ MKLINE(Actor, shadow_mode, sleByte, VER_V8),
+ MKLINE(Actor, visible, sleByte, VER_V8),
// FIXME - frame is never set and thus always 0! See actor.h comment
- MKLINE(Actor, frame, sleByte),
- MKLINE(Actor, animSpeed, sleByte),
- MKLINE(Actor, animProgress, sleByte),
- MKLINE(Actor, walkbox, sleByte),
- MKLINE(Actor, needRedraw, sleByte),
- MKLINE(Actor, needBgReset, sleByte),
- MKLINE(Actor, costumeNeedsInit, sleByte),
-
- MKLINE(Actor, new_1, sleInt16),
- MKLINE(Actor, new_2, sleInt16),
- MKLINE(Actor, new_3, sleByte),
-
- MKLINE(Actor, layer, sleByte),
-
- MKLINE(Actor, talk_script, sleUint16),
- MKLINE(Actor, walk_script, sleUint16),
-
- MKLINE(Actor, walkdata.destx, sleInt16),
- MKLINE(Actor, walkdata.desty, sleInt16),
- MKLINE(Actor, walkdata.destbox, sleByte),
- MKLINE(Actor, walkdata.destdir, sleUint16),
- MKLINE(Actor, walkdata.curbox, sleByte),
- MKLINE(Actor, walkdata.x, sleInt16),
- MKLINE(Actor, walkdata.y, sleInt16),
- MKLINE(Actor, walkdata.newx, sleInt16),
- MKLINE(Actor, walkdata.newy, sleInt16),
- MKLINE(Actor, walkdata.XYFactor, sleInt32),
- MKLINE(Actor, walkdata.YXFactor, sleInt32),
- MKLINE(Actor, walkdata.xfrac, sleUint16),
- MKLINE(Actor, walkdata.yfrac, sleUint16),
-
- MKARRAY(Actor, cost.active[0], sleByte, 16),
- MKLINE(Actor, cost.stopped, sleUint16),
- MKARRAY(Actor, cost.curpos[0], sleUint16, 16),
- MKARRAY(Actor, cost.start[0], sleUint16, 16),
- MKARRAY(Actor, cost.end[0], sleUint16, 16),
- MKARRAY(Actor, cost.frame[0], sleUint16, 16),
+ MKLINE(Actor, frame, sleByte, VER_V8),
+ MKLINE(Actor, animSpeed, sleByte, VER_V8),
+ MKLINE(Actor, animProgress, sleByte, VER_V8),
+ MKLINE(Actor, walkbox, sleByte, VER_V8),
+ MKLINE(Actor, needRedraw, sleByte, VER_V8),
+ MKLINE(Actor, needBgReset, sleByte, VER_V8),
+ MKLINE(Actor, costumeNeedsInit, sleByte, VER_V8),
+
+ MKLINE(Actor, new_1, sleInt16, VER_V8),
+ MKLINE(Actor, new_2, sleInt16, VER_V8),
+ MKLINE(Actor, new_3, sleByte, VER_V8),
+
+ MKLINE(Actor, layer, sleByte, VER_V8),
+
+ MKLINE(Actor, talk_script, sleUint16, VER_V8),
+ MKLINE(Actor, walk_script, sleUint16, VER_V8),
+
+ MKLINE(Actor, walkdata.destx, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.desty, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.destbox, sleByte, VER_V8),
+ MKLINE(Actor, walkdata.destdir, sleUint16, VER_V8),
+ MKLINE(Actor, walkdata.curbox, sleByte, VER_V8),
+ MKLINE(Actor, walkdata.x, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.y, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.newx, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.newy, sleInt16, VER_V8),
+ MKLINE(Actor, walkdata.XYFactor, sleInt32, VER_V8),
+ MKLINE(Actor, walkdata.YXFactor, sleInt32, VER_V8),
+ MKLINE(Actor, walkdata.xfrac, sleUint16, VER_V8),
+ MKLINE(Actor, walkdata.yfrac, sleUint16, VER_V8),
+
+ MKARRAY(Actor, cost.active[0], sleByte, 16, VER_V8),
+ MKLINE(Actor, cost.stopped, sleUint16, VER_V8),
+ MKARRAY(Actor, cost.curpos[0], sleUint16, 16, VER_V8),
+ MKARRAY(Actor, cost.start[0], sleUint16, 16, VER_V8),
+ MKARRAY(Actor, cost.end[0], sleUint16, 16, VER_V8),
+ MKARRAY(Actor, cost.frame[0], sleUint16, 16, VER_V8),
MKEND()
};
const SaveLoadEntry verbEntries[] = {
- MKLINE(VerbSlot, x, sleInt16),
- MKLINE(VerbSlot, y, sleInt16),
- MKLINE(VerbSlot, right, sleInt16),
- MKLINE(VerbSlot, bottom, sleInt16),
- MKLINE(VerbSlot, oldleft, sleInt16),
- MKLINE(VerbSlot, oldtop, sleInt16),
- MKLINE(VerbSlot, oldright, sleInt16),
- MKLINE(VerbSlot, oldbottom, sleInt16),
- MKLINE(VerbSlot, verbid, sleByte),
- MKLINE(VerbSlot, color, sleByte),
- MKLINE(VerbSlot, hicolor, sleByte),
- MKLINE(VerbSlot, dimcolor, sleByte),
- MKLINE(VerbSlot, bkcolor, sleByte),
- MKLINE(VerbSlot, type, sleByte),
- MKLINE(VerbSlot, charset_nr, sleByte),
- MKLINE(VerbSlot, curmode, sleByte),
- MKLINE(VerbSlot, saveid, sleByte),
- MKLINE(VerbSlot, key, sleByte),
- MKLINE(VerbSlot, center, sleByte),
- MKLINE(VerbSlot, field_1B, sleByte),
- MKLINE(VerbSlot, imgindex, sleUint16),
- MKEND()
- };
-
- const SaveLoadEntry mainEntriesV9[] = {
- MKLINE(Scumm, _scrWidth, sleUint16),
- MKLINE(Scumm, _scrHeight, sleUint16),
- MKLINE(Scumm, _ENCD_offs, sleUint32),
- MKLINE(Scumm, _EXCD_offs, sleUint32),
- MKLINE(Scumm, _IM00_offs, sleUint32),
- MKLINE(Scumm, _CLUT_offs, sleUint32),
- /* XXX Remove _EPAL_offs next time format changes */
- MKLINE(Scumm, _EPAL_offs, sleUint32),
- MKLINE(Scumm, _PALS_offs, sleUint32),
- MKLINE(Scumm, _curPalIndex, sleByte),
- MKLINE(Scumm, _currentRoom, sleByte),
- MKLINE(Scumm, _roomResource, sleByte),
- MKLINE(Scumm, _numObjectsInRoom, sleByte),
- MKLINE(Scumm, _currentScript, sleByte),
- MKARRAY(Scumm, _localScriptList[0], sleUint32, NUM_LOCALSCRIPT),
- MKARRAY(Scumm, vm.localvar[0][0], sleUint16, NUM_SCRIPT_SLOT * 17),
- MKARRAY(Scumm, _resourceMapper[0], sleByte, 128),
- MKARRAY(Scumm, charset._colorMap[0], sleByte, 16),
- MKARRAY(Scumm, _charsetData[0][0], sleByte, 10 * 16), // FIXME - _charsetData is 15*16 these days
- MKLINE(Scumm, _curExecScript, sleUint16),
-
- MKLINE(Scumm, camera._dest.x, sleInt16),
- MKLINE(Scumm, camera._dest.y, sleInt16),
- MKLINE(Scumm, camera._cur.x, sleInt16),
- MKLINE(Scumm, camera._cur.y, sleInt16),
- MKLINE(Scumm, camera._last.x, sleInt16),
- MKLINE(Scumm, camera._last.y, sleInt16),
- MKLINE(Scumm, camera._accel.x, sleInt16),
- MKLINE(Scumm, camera._accel.y, sleInt16),
- MKLINE(Scumm, _screenStartStrip, sleInt16),
- MKLINE(Scumm, _screenEndStrip, sleInt16),
- MKLINE(Scumm, camera._mode, sleByte),
- MKLINE(Scumm, camera._follows, sleByte),
- MKLINE(Scumm, camera._leftTrigger, sleInt16),
- MKLINE(Scumm, camera._rightTrigger, sleInt16),
- MKLINE(Scumm, camera._movingToActor, sleUint16),
-
- MKLINE(Scumm, _actorToPrintStrFor, sleByte),
- MKLINE(Scumm, _charsetColor, sleByte),
- /* XXX Convert into word next time format changes */
- MKLINE(Scumm, charset._bufPos, sleByte),
- MKLINE(Scumm, _haveMsg, sleByte),
- MKLINE(Scumm, _useTalkAnims, sleByte),
-
- MKLINE(Scumm, _talkDelay, sleInt16),
- MKLINE(Scumm, _defaultTalkDelay, sleInt16),
- MKLINE(Scumm, _numInMsgStack, sleInt16),
- MKLINE(Scumm, _sentenceNum, sleByte),
-
- MKLINE(Scumm, vm.cutSceneStackPointer, sleByte),
- MKARRAY(Scumm, vm.cutScenePtr[0], sleUint32, 5),
- MKARRAY(Scumm, vm.cutSceneScript[0], sleByte, 5),
- MKARRAY(Scumm, vm.cutSceneData[0], sleInt16, 5),
- MKLINE(Scumm, vm.cutSceneScriptIndex, sleInt16),
-
- /* nest */
- MKLINE(Scumm, _numNestedScripts, sleByte),
- MKLINE(Scumm, _userPut, sleByte),
- MKLINE(Scumm, _cursor.state, sleByte),
- MKLINE(Scumm, gdi._cursorActive, sleByte),
- MKLINE(Scumm, _currentCursor, sleByte),
-
- MKLINE(Scumm, _doEffect, sleByte),
- MKLINE(Scumm, _switchRoomEffect, sleByte),
- MKLINE(Scumm, _newEffect, sleByte),
- MKLINE(Scumm, _switchRoomEffect2, sleByte),
- MKLINE(Scumm, _BgNeedsRedraw, sleByte),
-
- // Jamieson630: variables for palManipulate
- // TODO: Add these next time save game format changes.
- // MKLINE(Scumm, _palManipStart, sleByte),
- // MKLINE(Scumm, _palManipEnd, sleByte),
- // MKLINE(Scumm, _palManipCounter, sleUint16),
-
- // MKARRAY(Scumm, gfxUsageBits[0], sleUint32, 410),
- // replace below:
- MKARRAY(Scumm, gfxUsageBits[0], sleUint32, 200),
- MKLINE(Scumm, gdi._transparency, sleByte),
- MKARRAY(Scumm, _currentPalette[0], sleByte, 768),
-
- MKARRAY(Scumm, _proc_special_palette[0], sleByte, 256),
- /* virtscr */
-
- MKARRAY(Scumm, charset._buffer[0], sleByte, 256),
-
- MKLINE(Scumm, _egoPositioned, sleByte),
-
- // FIXME: Should be 5, not 4 :
- MKARRAY(Scumm, gdi._imgBufOffs[0], sleUint16, 4),
- MKLINE(Scumm, gdi._numZBuffer, sleByte),
-
- MKLINE(Scumm, _screenEffectFlag, sleByte),
-
- // FIXME: remove when new savegame system is implemented
- MKLINE(Scumm, _randSeed1, sleUint32),
- MKLINE(Scumm, _randSeed2, sleUint32),
-
- /* XXX: next time the save game format changes,
- * convert _shakeEnabled to boolean and add a _shakeFrame field */
- MKLINE(Scumm, _shakeEnabled, sleInt16),
-
- MKLINE(Scumm, _keepText, sleByte),
-
- MKLINE(Scumm, _screenB, sleUint16),
- MKLINE(Scumm, _screenH, sleUint16),
-
- MKLINE(Scumm, _cd_track, sleInt16), // FIXME - remove next time save format changes
- MKLINE(Scumm, _cd_loops, sleInt16), // FIXME - remove next time save format changes
- MKLINE(Scumm, _cd_frame, sleInt16), // FIXME - remove next time save format changes
- MKLINE(Scumm, _cd_end, sleInt16), // FIXME - remove next time save format changes
-
+ MKLINE(VerbSlot, x, sleInt16, VER_V8),
+ MKLINE(VerbSlot, y, sleInt16, VER_V8),
+ MKLINE(VerbSlot, right, sleInt16, VER_V8),
+ MKLINE(VerbSlot, bottom, sleInt16, VER_V8),
+ MKLINE(VerbSlot, oldleft, sleInt16, VER_V8),
+ MKLINE(VerbSlot, oldtop, sleInt16, VER_V8),
+ MKLINE(VerbSlot, oldright, sleInt16, VER_V8),
+ MKLINE(VerbSlot, oldbottom, sleInt16, VER_V8),
+ MKLINE(VerbSlot, verbid, sleByte, VER_V8),
+ MKLINE(VerbSlot, color, sleByte, VER_V8),
+ MKLINE(VerbSlot, hicolor, sleByte, VER_V8),
+ MKLINE(VerbSlot, dimcolor, sleByte, VER_V8),
+ MKLINE(VerbSlot, bkcolor, sleByte, VER_V8),
+ MKLINE(VerbSlot, type, sleByte, VER_V8),
+ MKLINE(VerbSlot, charset_nr, sleByte, VER_V8),
+ MKLINE(VerbSlot, curmode, sleByte, VER_V8),
+ MKLINE(VerbSlot, saveid, sleByte, VER_V8),
+ MKLINE(VerbSlot, key, sleByte, VER_V8),
+ MKLINE(VerbSlot, center, sleByte, VER_V8),
+ MKLINE(VerbSlot, field_1B, sleByte, VER_V8),
+ MKLINE(VerbSlot, imgindex, sleUint16, VER_V8),
MKEND()
};
- const SaveLoadEntry mainEntriesV8[] = {
- MKLINE(Scumm, _scrWidth, sleUint16),
- MKLINE(Scumm, _scrHeight, sleUint16),
- MKLINE(Scumm, _ENCD_offs, sleUint32),
- MKLINE(Scumm, _EXCD_offs, sleUint32),
- MKLINE(Scumm, _IM00_offs, sleUint32),
- MKLINE(Scumm, _CLUT_offs, sleUint32),
- /* XXX Remove _EPAL_offs next time format changes */
- MKLINE(Scumm, _EPAL_offs, sleUint32),
- MKLINE(Scumm, _PALS_offs, sleUint32),
- MKLINE(Scumm, _curPalIndex, sleByte),
- MKLINE(Scumm, _currentRoom, sleByte),
- MKLINE(Scumm, _roomResource, sleByte),
- MKLINE(Scumm, _numObjectsInRoom, sleByte),
- MKLINE(Scumm, _currentScript, sleByte),
- MKARRAY(Scumm, _localScriptList[0], sleUint32, NUM_LOCALSCRIPT),
- MKARRAY(Scumm, vm.localvar[0][0], sleUint16, 25 * 17),
- MKARRAY(Scumm, _resourceMapper[0], sleByte, 128),
- MKARRAY(Scumm, charset._colorMap[0], sleByte, 16),
- MKARRAY(Scumm, _charsetData[0][0], sleByte, 10 * 16), // FIXME - _charsetData is 15*16 these days
- MKLINE(Scumm, _curExecScript, sleUint16),
-
- MKLINE(Scumm, camera._dest.x, sleInt16),
- MKLINE(Scumm, camera._dest.y, sleInt16),
- MKLINE(Scumm, camera._cur.x, sleInt16),
- MKLINE(Scumm, camera._cur.y, sleInt16),
- MKLINE(Scumm, camera._last.x, sleInt16),
- MKLINE(Scumm, camera._last.y, sleInt16),
- MKLINE(Scumm, camera._accel.x, sleInt16),
- MKLINE(Scumm, camera._accel.y, sleInt16),
- MKLINE(Scumm, _screenStartStrip, sleInt16),
- MKLINE(Scumm, _screenEndStrip, sleInt16),
- MKLINE(Scumm, camera._mode, sleByte),
- MKLINE(Scumm, camera._follows, sleByte),
- MKLINE(Scumm, camera._leftTrigger, sleInt16),
- MKLINE(Scumm, camera._rightTrigger, sleInt16),
- MKLINE(Scumm, camera._movingToActor, sleUint16),
-
- MKLINE(Scumm, _actorToPrintStrFor, sleByte),
- MKLINE(Scumm, _charsetColor, sleByte),
- /* XXX Convert into word next time format changes */
- MKLINE(Scumm, charset._bufPos, sleByte),
- MKLINE(Scumm, _haveMsg, sleByte),
- MKLINE(Scumm, _useTalkAnims, sleByte),
-
- MKLINE(Scumm, _talkDelay, sleInt16),
- MKLINE(Scumm, _defaultTalkDelay, sleInt16),
- MKLINE(Scumm, _numInMsgStack, sleInt16),
- MKLINE(Scumm, _sentenceNum, sleByte),
-
- MKLINE(Scumm, vm.cutSceneStackPointer, sleByte),
- MKARRAY(Scumm, vm.cutScenePtr[0], sleUint32, 5),
- MKARRAY(Scumm, vm.cutSceneScript[0], sleByte, 5),
- MKARRAY(Scumm, vm.cutSceneData[0], sleInt16, 5),
- MKLINE(Scumm, vm.cutSceneScriptIndex, sleInt16),
-
- /* nest */
- MKLINE(Scumm, _numNestedScripts, sleByte),
- MKLINE(Scumm, _userPut, sleByte),
- MKLINE(Scumm, _cursor.state, sleByte),
- MKLINE(Scumm, gdi._cursorActive, sleByte),
- MKLINE(Scumm, _currentCursor, sleByte),
-
- MKLINE(Scumm, _doEffect, sleByte),
- MKLINE(Scumm, _switchRoomEffect, sleByte),
- MKLINE(Scumm, _newEffect, sleByte),
- MKLINE(Scumm, _switchRoomEffect2, sleByte),
- MKLINE(Scumm, _BgNeedsRedraw, sleByte),
-
- // Jamieson630: variables for palManipulate
- // TODO: Add these next time save game format changes.
- // MKLINE(Scumm, _palManipStart, sleByte),
- // MKLINE(Scumm, _palManipEnd, sleByte),
- // MKLINE(Scumm, _palManipCounter, sleUint16),
-
- // MKARRAY(Scumm, gfxUsageBits[0], sleUint32, 410),
- // replace below:
- MKARRAY(Scumm, gfxUsageBits[0], sleUint32, 200),
- MKLINE(Scumm, gdi._transparency, sleByte),
- MKARRAY(Scumm, _currentPalette[0], sleByte, 768),
-
- MKARRAY(Scumm, _proc_special_palette[0], sleByte, 256),
- /* virtscr */
-
- MKARRAY(Scumm, charset._buffer[0], sleByte, 256),
-
- MKLINE(Scumm, _egoPositioned, sleByte),
-
- // FIXME: Should be 5, not 4 :
- MKARRAY(Scumm, gdi._imgBufOffs[0], sleUint16, 4),
- MKLINE(Scumm, gdi._numZBuffer, sleByte),
-
- MKLINE(Scumm, _screenEffectFlag, sleByte),
-
- // FIXME: remove when new savegame system is implemented
- MKLINE(Scumm, _randSeed1, sleUint32),
- MKLINE(Scumm, _randSeed2, sleUint32),
-
- /* XXX: next time the save game format changes,
- * convert _shakeEnabled to boolean and add a _shakeFrame field */
- MKLINE(Scumm, _shakeEnabled, sleInt16),
-
- MKLINE(Scumm, _keepText, sleByte),
-
- MKLINE(Scumm, _screenB, sleUint16),
- MKLINE(Scumm, _screenH, sleUint16),
-
+ const SaveLoadEntry mainEntries[] = {
+ MKLINE(Scumm, _scrWidth, sleUint16, VER_V8),
+ MKLINE(Scumm, _scrHeight, sleUint16, VER_V8),
+ MKLINE(Scumm, _ENCD_offs, sleUint32, VER_V8),
+ MKLINE(Scumm, _EXCD_offs, sleUint32, VER_V8),
+ MKLINE(Scumm, _IM00_offs, sleUint32, VER_V8),
+ MKLINE(Scumm, _CLUT_offs, sleUint32, VER_V8),
+ MK_OBSOLETE(Scumm, _EPAL_offs, sleUint32, VER_V8, VER_V9),
+ MKLINE(Scumm, _PALS_offs, sleUint32, VER_V8),
+ MKLINE(Scumm, _curPalIndex, sleByte, VER_V8),
+ MKLINE(Scumm, _currentRoom, sleByte, VER_V8),
+ MKLINE(Scumm, _roomResource, sleByte, VER_V8),
+ MKLINE(Scumm, _numObjectsInRoom, sleByte, VER_V8),
+ MKLINE(Scumm, _currentScript, sleByte, VER_V8),
+ MKARRAY(Scumm, _localScriptList[0], sleUint32, NUM_LOCALSCRIPT, VER_V8),
+
+ // vm.localvar grew from 25 to 40 entries
+ MKARRAY_OLD(Scumm, vm.localvar[0][0], sleUint16, 25 * 17, VER_V8, VER_V8),
+ MKARRAY(Scumm, vm.localvar[0][0], sleUint16, NUM_SCRIPT_SLOT * 17, VER_V9),
+
+ MKARRAY(Scumm, _resourceMapper[0], sleByte, 128, VER_V8),
+ MKARRAY(Scumm, charset._colorMap[0], sleByte, 16, VER_V8),
+
+ // _charsetData grew from 10*16 to 15*16 bytes
+ MKARRAY_OLD(Scumm, _charsetData[0][0], sleByte, 10 * 16, VER_V8, VER_V9),
+ MKARRAY(Scumm, _charsetData[0][0], sleByte, 15 * 16, VER_V10),
+
+ MKLINE(Scumm, _curExecScript, sleUint16, VER_V8),
+
+ MKLINE(Scumm, camera._dest.x, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._dest.y, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._cur.x, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._cur.y, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._last.x, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._last.y, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._accel.x, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._accel.y, sleInt16, VER_V8),
+ MKLINE(Scumm, _screenStartStrip, sleInt16, VER_V8),
+ MKLINE(Scumm, _screenEndStrip, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._mode, sleByte, VER_V8),
+ MKLINE(Scumm, camera._follows, sleByte, VER_V8),
+ MKLINE(Scumm, camera._leftTrigger, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._rightTrigger, sleInt16, VER_V8),
+ MKLINE(Scumm, camera._movingToActor, sleUint16, VER_V8),
+
+ MKLINE(Scumm, _actorToPrintStrFor, sleByte, VER_V8),
+ MKLINE(Scumm, _charsetColor, sleByte, VER_V8),
+
+ // charset._bufPos was changed from byte to int
+ MKLINE_OLD(Scumm, charset._bufPos, sleByte, VER_V8, VER_V9),
+ MKLINE(Scumm, charset._bufPos, sleInt16, VER_V10),
+
+ MKLINE(Scumm, _haveMsg, sleByte, VER_V8),
+ MKLINE(Scumm, _useTalkAnims, sleByte, VER_V8),
+
+ MKLINE(Scumm, _talkDelay, sleInt16, VER_V8),
+ MKLINE(Scumm, _defaultTalkDelay, sleInt16, VER_V8),
+ MKLINE(Scumm, _numInMsgStack, sleInt16, VER_V8),
+ MKLINE(Scumm, _sentenceNum, sleByte, VER_V8),
+
+ MKLINE(Scumm, vm.cutSceneStackPointer, sleByte, VER_V8),
+ MKARRAY(Scumm, vm.cutScenePtr[0], sleUint32, 5, VER_V8),
+ MKARRAY(Scumm, vm.cutSceneScript[0], sleByte, 5, VER_V8),
+ MKARRAY(Scumm, vm.cutSceneData[0], sleInt16, 5, VER_V8),
+ MKLINE(Scumm, vm.cutSceneScriptIndex, sleInt16, VER_V8),
+
+ MKLINE(Scumm, _numNestedScripts, sleByte, VER_V8),
+ MKLINE(Scumm, _userPut, sleByte, VER_V8),
+ MKLINE(Scumm, _cursor.state, sleByte, VER_V8),
+ MKLINE(Scumm, gdi._cursorActive, sleByte, VER_V8),
+ MKLINE(Scumm, _currentCursor, sleByte, VER_V8),
+
+ MKLINE(Scumm, _doEffect, sleByte, VER_V8),
+ MKLINE(Scumm, _switchRoomEffect, sleByte, VER_V8),
+ MKLINE(Scumm, _newEffect, sleByte, VER_V8),
+ MKLINE(Scumm, _switchRoomEffect2, sleByte, VER_V8),
+ MKLINE(Scumm, _BgNeedsRedraw, sleByte, VER_V8),
+
+ // The state of palManipulate is stored only since V10
+ MKLINE(Scumm, _palManipStart, sleByte, VER_V10),
+ MKLINE(Scumm, _palManipEnd, sleByte, VER_V10),
+ MKLINE(Scumm, _palManipCounter, sleUint16, VER_V10),
+
+ // gfxUsageBits grew from 200 to 410 entries:
+ MKARRAY_OLD(Scumm, gfxUsageBits[0], sleUint32, 200, VER_V8, VER_V9),
+ MKARRAY(Scumm, gfxUsageBits[0], sleUint32, 410, VER_V10),
+
+ MKLINE(Scumm, gdi._transparency, sleByte, VER_V8),
+ MKARRAY(Scumm, _currentPalette[0], sleByte, 768, VER_V8),
+
+ MKARRAY(Scumm, _proc_special_palette[0], sleByte, 256, VER_V8),
+
+ MKARRAY(Scumm, charset._buffer[0], sleByte, 256, VER_V8),
+
+ MKLINE(Scumm, _egoPositioned, sleByte, VER_V8),
+
+ // gdi._imgBufOffs grew from 4 to 5 entries :
+ MKARRAY_OLD(Scumm, gdi._imgBufOffs[0], sleUint16, 4, VER_V8, VER_V9),
+ MKARRAY(Scumm, gdi._imgBufOffs[0], sleUint16, 5, VER_V10),
+
+ MKLINE(Scumm, gdi._numZBuffer, sleByte, VER_V8),
+
+ MKLINE(Scumm, _screenEffectFlag, sleByte, VER_V8),
+
+ MK_OBSOLETE(Scumm, _randSeed1, sleUint32, VER_V8, VER_V9),
+ MK_OBSOLETE(Scumm, _randSeed2, sleUint32, VER_V8, VER_V9),
+
+ // Converted _shakeEnabled to boolean and added a _shakeFrame field.
+ MKLINE_OLD(Scumm, _shakeEnabled, sleInt16, VER_V8, VER_V9),
+ MKLINE(Scumm, _shakeEnabled, sleByte, VER_V10),
+ MKLINE(Scumm, _shakeFrame, sleUint32, VER_V10),
+
+ MKLINE(Scumm, _keepText, sleByte, VER_V8),
+
+ MKLINE(Scumm, _screenB, sleUint16, VER_V8),
+ MKLINE(Scumm, _screenH, sleUint16, VER_V8),
+
+ MK_OBSOLETE(Scumm, _cd_track, sleInt16, VER_V9, VER_V9),
+ MK_OBSOLETE(Scumm, _cd_loops, sleInt16, VER_V9, VER_V9),
+ MK_OBSOLETE(Scumm, _cd_frame, sleInt16, VER_V9, VER_V9),
+ MK_OBSOLETE(Scumm, _cd_end, sleInt16, VER_V9, VER_V9),
+
MKEND()
};
const SaveLoadEntry scriptSlotEntries[] = {
- MKLINE(ScriptSlot, offs, sleUint32),
- MKLINE(ScriptSlot, delay, sleInt32),
- MKLINE(ScriptSlot, number, sleUint16),
- MKLINE(ScriptSlot, delayFrameCount, sleUint16),
- MKLINE(ScriptSlot, status, sleByte),
- MKLINE(ScriptSlot, where, sleByte),
- MKLINE(ScriptSlot, unk1, sleByte),
- MKLINE(ScriptSlot, unk2, sleByte),
- MKLINE(ScriptSlot, freezeCount, sleByte),
- MKLINE(ScriptSlot, didexec, sleByte),
- MKLINE(ScriptSlot, cutsceneOverride, sleByte),
- MKLINE(ScriptSlot, unk5, sleByte),
+ MKLINE(ScriptSlot, offs, sleUint32, VER_V8),
+ MKLINE(ScriptSlot, delay, sleInt32, VER_V8),
+ MKLINE(ScriptSlot, number, sleUint16, VER_V8),
+ MKLINE(ScriptSlot, delayFrameCount, sleUint16, VER_V8),
+ MKLINE(ScriptSlot, status, sleByte, VER_V8),
+ MKLINE(ScriptSlot, where, sleByte, VER_V8),
+ MKLINE(ScriptSlot, unk1, sleByte, VER_V8),
+ MKLINE(ScriptSlot, unk2, sleByte, VER_V8),
+ MKLINE(ScriptSlot, freezeCount, sleByte, VER_V8),
+ MKLINE(ScriptSlot, didexec, sleByte, VER_V8),
+ MKLINE(ScriptSlot, cutsceneOverride, sleByte, VER_V8),
+ MKLINE(ScriptSlot, unk5, sleByte, VER_V8),
MKEND()
};
const SaveLoadEntry nestedScriptEntries[] = {
- MKLINE(NestedScript, number, sleUint16),
- MKLINE(NestedScript, where, sleByte),
- MKLINE(NestedScript, slot, sleByte),
+ MKLINE(NestedScript, number, sleUint16, VER_V8),
+ MKLINE(NestedScript, where, sleByte, VER_V8),
+ MKLINE(NestedScript, slot, sleByte, VER_V8),
MKEND()
};
const SaveLoadEntry sentenceTabEntries[] = {
- MKLINE(SentenceTab, unk5, sleUint8),
- MKLINE(SentenceTab, unk2, sleUint8),
- MKLINE(SentenceTab, unk4, sleUint16),
- MKLINE(SentenceTab, unk3, sleUint16),
- MKLINE(SentenceTab, unk, sleUint8),
+ MKLINE(SentenceTab, unk5, sleUint8, VER_V8),
+ MKLINE(SentenceTab, unk2, sleUint8, VER_V8),
+ MKLINE(SentenceTab, unk4, sleUint16, VER_V8),
+ MKLINE(SentenceTab, unk3, sleUint16, VER_V8),
+ MKLINE(SentenceTab, unk, sleUint8, VER_V8),
MKEND()
};
const SaveLoadEntry stringTabEntries[] = {
// TODO - It makes no sense to have all these t_* fields in StringTab
// Rather let's dump them all when the save game format changes, and
- // keep two StringTab objects: one normal, and a "t_" one.
- // Then copying them can be done in one line etc.
- MKLINE(StringTab, xpos, sleInt16),
- MKLINE(StringTab, t_xpos, sleInt16),
- MKLINE(StringTab, ypos, sleInt16),
- MKLINE(StringTab, t_ypos, sleInt16),
- MKLINE(StringTab, right, sleInt16),
- MKLINE(StringTab, t_right, sleInt16),
- MKLINE(StringTab, color, sleInt8),
- MKLINE(StringTab, t_color, sleInt8),
- MKLINE(StringTab, charset, sleInt8),
- MKLINE(StringTab, t_charset, sleInt8),
- MKLINE(StringTab, center, sleByte),
- MKLINE(StringTab, t_center, sleByte),
- MKLINE(StringTab, overhead, sleByte),
- MKLINE(StringTab, t_overhead, sleByte),
- MKLINE(StringTab, no_talk_anim, sleByte),
- MKLINE(StringTab, t_no_talk_anim, sleByte),
+ // keep two StringTab objects where we have one now: a "normal" one,
+ // and a temporar y"t_" one.
+ // Then backup/restore of a StringTab entry becomes a one liner.
+ MKLINE(StringTab, xpos, sleInt16, VER_V8),
+ MKLINE(StringTab, t_xpos, sleInt16, VER_V8),
+ MKLINE(StringTab, ypos, sleInt16, VER_V8),
+ MKLINE(StringTab, t_ypos, sleInt16, VER_V8),
+ MKLINE(StringTab, right, sleInt16, VER_V8),
+ MKLINE(StringTab, t_right, sleInt16, VER_V8),
+ MKLINE(StringTab, color, sleInt8, VER_V8),
+ MKLINE(StringTab, t_color, sleInt8, VER_V8),
+ MKLINE(StringTab, charset, sleInt8, VER_V8),
+ MKLINE(StringTab, t_charset, sleInt8, VER_V8),
+ MKLINE(StringTab, center, sleByte, VER_V8),
+ MKLINE(StringTab, t_center, sleByte, VER_V8),
+ MKLINE(StringTab, overhead, sleByte, VER_V8),
+ MKLINE(StringTab, t_overhead, sleByte, VER_V8),
+ MKLINE(StringTab, no_talk_anim, sleByte, VER_V8),
+ MKLINE(StringTab, t_no_talk_anim, sleByte, VER_V8),
MKEND()
};
const SaveLoadEntry colorCycleEntries[] = {
- MKLINE(ColorCycle, delay, sleUint16),
- MKLINE(ColorCycle, counter, sleUint16),
- MKLINE(ColorCycle, flags, sleUint16),
- MKLINE(ColorCycle, start, sleByte),
- MKLINE(ColorCycle, end, sleByte),
+ MKLINE(ColorCycle, delay, sleUint16, VER_V8),
+ MKLINE(ColorCycle, counter, sleUint16, VER_V8),
+ MKLINE(ColorCycle, flags, sleUint16, VER_V8),
+ MKLINE(ColorCycle, start, sleByte, VER_V8),
+ MKLINE(ColorCycle, end, sleByte, VER_V8),
MKEND()
};
@@ -642,17 +540,15 @@ void Scumm::saveOrLoad(Serializer *s)
}
}
- if (_current_version == VER_V9)
- s->saveLoadEntries(this, mainEntriesV9);
- else
- s->saveLoadEntries(this, mainEntriesV8);
+ s->saveLoadEntries(this, mainEntries);
s->saveLoadArrayOf(_actors, NUM_ACTORS, sizeof(_actors[0]), actorEntries);
- if (_current_version < VER_V9)
+ if (_savegameVersion < VER_V9)
s->saveLoadArrayOf(vm.slot, 25, sizeof(vm.slot[0]), scriptSlotEntries);
else
s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries);
+
s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries);
s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries);
s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries);
@@ -674,7 +570,9 @@ void Scumm::saveOrLoad(Serializer *s)
if (_shadowPaletteSize)
s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte);
- _palManipCounter = 0; // TODO: Remove this once it's being loaded from disk
+ // PalManip data was not saved before V10 save games
+ if (_savegameVersion < VER_V10)
+ _palManipCounter = 0;
if (_palManipCounter) {
if (!_palManipPalette)
_palManipPalette = (byte *)calloc(0x300, 1);
@@ -823,83 +721,92 @@ byte Serializer::loadByte()
return e;
}
-void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype)
+void Serializer::saveArrayOf(void *b, int len, int datasize, byte filetype)
{
byte *at = (byte *)b;
uint32 data;
- /* speed up byte arrays */
+ // speed up byte arrays
if (datasize == 1 && filetype == sleByte) {
- if (isSaving())
- saveBytes(b, len);
- else
- loadBytes(b, len);
+ saveBytes(b, len);
return;
}
while (--len >= 0) {
- if (isSaving()) {
- /* saving */
- 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("saveLoadArrayOf: invalid size %d", datasize);
- }
- switch (filetype) {
- case sleByte:
- saveByte((byte)data);
- break;
- case sleUint16:
- case sleInt16:
- saveWord((int16)data);
- break;
- case sleInt32:
- case sleUint32:
- saveUint32(data);
- break;
- default:
- error("saveLoadArrayOf: invalid filetype %d", filetype);
- }
+ 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 {
- /* loading */
- switch (filetype) {
- case sleByte:
- data = loadByte();
- break;
- case sleUint16:
- data = loadWord();
- break;
- case sleInt16:
- data = (int16)loadWord();
- break;
- case sleUint32:
- data = loadUint32();
- break;
- case sleInt32:
- data = (int32)loadUint32();
- break;
- default:
- error("saveLoadArrayOf: invalid filetype %d", filetype);
- }
- 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("saveLoadArrayOf: invalid size %d", datasize);
- }
+ error("saveLoadArrayOf: invalid size %d", datasize);
+ }
+ switch (filetype) {
+ case sleByte:
+ saveByte((byte)data);
+ break;
+ case sleUint16:
+ case sleInt16:
+ saveWord((int16)data);
+ break;
+ case sleInt32:
+ case sleUint32:
+ saveUint32(data);
+ break;
+ default:
+ error("saveLoadArrayOf: 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 = loadWord();
+ break;
+ case sleInt16:
+ data = (int16)loadWord();
+ break;
+ case sleUint32:
+ data = loadUint32();
+ break;
+ case sleInt32:
+ data = (int32)loadUint32();
+ break;
+ default:
+ error("saveLoadArrayOf: 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("saveLoadArrayOf: invalid size %d", datasize);
}
}
}
@@ -908,45 +815,99 @@ void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadE
{
byte *data = (byte *)b;
- while (--num >= 0) {
- saveLoadEntries(data, sle);
- data += datasize;
+ 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)
{
- int replen;
+ if (isSaving())
+ saveEntries(d, sle);
+ else
+ loadEntries(d, sle);
+}
+
+void Serializer::saveEntries(void *d, const SaveLoadEntry *sle)
+{
byte type;
byte *at;
int size;
- int num;
- void *ptr;
while (sle->offs != 0xFFFF) {
at = (byte *)d + sle->offs;
size = sle->size;
type = sle->type;
- if (size == 0xFF) {
- if (isSaving()) {
- /* save reference */
- ptr = *((void **)at);
- saveWord(ptr ? ((*_save_ref) (_ref_me, type, ptr) + 1) : 0);
- } else {
- /* load reference */
- num = loadWord();
- *((void **)at) = num ? (*_load_ref) (_ref_me, type, num - 1) : NULL;
+ if (sle->maxVersion != CURRENT_VER) {
+ // Skip obsolete entries
+ if (type & 128)
+ sle++;
+ } else if (size == 0xFF) {
+ // save reference
+ void *ptr = *((void **)at);
+ saveWord(ptr ? ((*_save_ref) (_ref_me, type, ptr) + 1) : 0);
+ } else {
+ // save entry
+ int replen = 1;
+ if (type & 128) {
+ sle++;
+ replen = sle->offs;
+ type &= ~128;
}
+ saveArrayOf(at, replen, size, type);
+ }
+ 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 = 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 if (size == 0xFF) {
+ // load reference...
+ int num = loadWord();
+ // ...but only use it if it's still there in CURRENT_VER
+ if (sle->maxVersion == CURRENT_VER)
+ *((void **)at) = num ? (*_load_ref) (_ref_me, type, num - 1) : NULL;
} else {
- replen = 1;
+ // load entry
+ int replen = 1;
+
if (type & 128) {
sle++;
replen = sle->offs;
type &= ~128;
}
- saveLoadArrayOf(at, replen, size, type);
+ loadArrayOf(at, replen, size, type);
}
sle++;
}
diff --git a/scumm/saveload.h b/scumm/saveload.h
index 914d6b9346..1667aeb045 100644
--- a/scumm/saveload.h
+++ b/scumm/saveload.h
@@ -22,6 +22,17 @@
#ifndef SAVELOAD_H
#define SAVELOAD_H
+// Support for "old" savegames (made with 2501 CVS build)
+// Can be useful for other ports too :)
+
+#define VER_V10 10
+#define VER_V9 9
+#define VER_V8 8
+#define VER_V7 7
+
+#define CURRENT_VER VER_V10
+
+
// 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 hae a heuristic built in to detect "offset-of" patterns - which is exactly
@@ -32,11 +43,29 @@
#define OFFS(type,item) (((int)(&((type*)42)->type::item))-42)
#define SIZE(type,item) sizeof(((type*)42)->type::item)
-#define MKLINE(type,item,saveas) {OFFS(type,item),saveas,SIZE(type,item)}
-#define MKARRAY(type,item,saveas,num) {OFFS(type,item),128|saveas,SIZE(type,item)}, {num,0,0}
-#define MKEND() {0xFFFF,0xFF,0xFF}
-#define MKREF(type,item,refid) {OFFS(type,item),refid,0xFF}
+// 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,num,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {num,0,0,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,num,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {num,0,0,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,num,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {num,0,0,0,0}
+
+// End marker
+#define MKEND() {0xFFFF,0xFF,0xFF,0,0}
+
+// A reference
+#define MKREF(type,item,refid,minVer) {OFFS(type,item),refid,0xFF,minVer,CURRENT_VER}
+
+// An obsolete reference.
+#define MK_OBSOLETE_REF(type,item,refid,minVer,maxVer) {0,sleUint16,0,minVer,maxVer}
+
enum {
sleByte = 1,
@@ -52,6 +81,8 @@ struct SaveLoadEntry {
uint32 offs;
uint8 type;
uint8 size;
+ uint8 minVersion;
+ uint8 maxVersion;
};
struct SerializerStream {
@@ -83,24 +114,25 @@ struct SerializerStream {
typedef int SerializerSaveReference(void *me, byte type, void *ref);
typedef void *SerializerLoadReference(void *me, byte type, int ref);
-struct Serializer {
- SerializerStream _saveLoadStream;
+class Serializer {
+public:
+ Serializer(SerializerStream stream, bool saveOrLoad, uint32 savegameVersion)
+ : _save_ref(0), _load_ref(0), _ref_me(0),
+ _saveLoadStream(stream), _saveOrLoad(saveOrLoad),
+ _savegameVersion(savegameVersion)
+ { }
- union {
- SerializerSaveReference *_save_ref;
- SerializerLoadReference *_load_ref;
- void *_saveload_ref;
- };
+ SerializerSaveReference *_save_ref;
+ SerializerLoadReference *_load_ref;
void *_ref_me;
- bool _saveOrLoad;
-
- void saveBytes(void *b, int len);
- void loadBytes(void *b, int len);
-
void saveLoadArrayOf(void *b, int len, int datasize, byte filetype);
- void saveLoadEntries(void *d, const SaveLoadEntry *sle);
void saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle);
+ void saveLoadEntries(void *d, const SaveLoadEntry *sle);
+
+ bool isSaving() { return _saveOrLoad; }
+
+ bool checkEOFLoadStream();
void saveUint32(uint32 d);
void saveWord(uint16 d);
@@ -110,10 +142,19 @@ struct Serializer {
uint16 loadWord();
uint32 loadUint32();
- bool isSaving() { return _saveOrLoad; }
+ void saveBytes(void *b, int len);
+ void loadBytes(void *b, int len);
+
+protected:
+ SerializerStream _saveLoadStream;
+ bool _saveOrLoad;
+ uint32 _savegameVersion;
- bool checkEOFLoadStream();
+ 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);
};
#endif
diff --git a/scumm/scumm.h b/scumm/scumm.h
index d4341959f0..0a1ca45f14 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -359,7 +359,6 @@ public:
void convertKeysToClicks();
/* Random number generation */
- uint32 _randSeed1, _randSeed2; // FIXME: can be removed when new savegame system is implemented
RandomSource _rnd;
/* Core variable definitions */
@@ -427,6 +426,8 @@ public:
bool _saveLoadCompatible;
char _saveLoadName[32];
+ uint32 _savegameVersion;
+
bool saveState(int slot, bool compat);
bool loadState(int slot, bool compat);
void saveOrLoad(Serializer *s);
@@ -692,7 +693,7 @@ public:
ColorCycle _colorCycle[16]; // Palette cycles
uint32 _ENCD_offs, _EXCD_offs;
- uint32 _CLUT_offs, _EPAL_offs;
+ uint32 _CLUT_offs;
uint32 _IM00_offs, _PALS_offs;
//ender: fullscreen
@@ -856,7 +857,6 @@ public:
bool _silentDigitalImuse;
int _saveSound;
int current_cd_sound;
- int _cd_loops, _cd_frame, _cd_track, _cd_end; // FIXME - these are not used anymore
/* Walkbox / Navigation class */
int _maxBoxVertexHeap, _boxPathVertexHeapIndex, _boxMatrixItem;