aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/savegame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/savegame.cpp')
-rw-r--r--engines/sci/engine/savegame.cpp65
1 files changed, 60 insertions, 5 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 0b6caa515b..ffe91534b8 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -40,6 +40,7 @@
#include "sci/engine/selector.h"
#include "sci/engine/vm_types.h"
#include "sci/engine/script.h" // for SCI_OBJ_EXPORTS and SCI_OBJ_SYNONYMS
+#include "sci/graphics/helpers.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/ports.h"
#include "sci/sound/audio.h"
@@ -175,9 +176,6 @@ void syncWithSerializer(Common::Serializer &s, Class &obj) {
}
static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj) {
- // TODO: It would be a good idea to store a magic number & a header size here,
- // so that we can implement backward compatibility if the savegame format changes.
-
s.syncString(obj.name);
s.syncVersion(CURRENT_SAVEGAME_VERSION);
obj.version = s.getVersion();
@@ -605,6 +603,61 @@ void GfxPalette::saveLoadWithSerializer(Common::Serializer &s) {
}
}
+void GfxPorts::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.isLoading())
+ reset(); // remove all script generated windows
+
+ if (s.getVersion() >= 27) {
+ uint windowCount = 0;
+ uint id = PORTS_FIRSTSCRIPTWINDOWID;
+ if (s.isSaving()) {
+ while (id < _windowsById.size()) {
+ if (_windowsById[id])
+ windowCount++;
+ id++;
+ }
+ }
+ // Save/Restore window count
+ s.syncAsUint32LE(windowCount);
+
+ if (s.isSaving()) {
+ id = PORTS_FIRSTSCRIPTWINDOWID;
+ while (id < _windowsById.size()) {
+ if (_windowsById[id]) {
+ Window *window = (Window *)_windowsById[id];
+ window->saveLoadWithSerializer(s);
+ }
+ id++;
+ }
+ } else {
+ id = PORTS_FIRSTSCRIPTWINDOWID;
+ while (windowCount) {
+ Window *window = new Window(0);
+ window->saveLoadWithSerializer(s);
+
+ // add enough entries inside _windowsById as needed
+ while (id <= window->id) {
+ _windowsById.push_back(0);
+ id++;
+ }
+ _windowsById[window->id] = window;
+ // _windowList may not be 100% correct using that way of restoring
+ // saving/restoring ports won't work perfectly anyway, because the contents
+ // of the window can only get repainted by the scripts and they dont do that
+ // so we will get empty, transparent windows instead. So perfect window order
+ // shouldn't really matter
+ if (window->wndStyle & SCI_WINDOWMGR_STYLE_TOPMOST)
+ _windowList.push_front(window);
+ else
+ _windowList.push_back(window);
+
+ windowCount--;
+ id++;
+ }
+ }
+ }
+}
+
void SegManager::reconstructStack(EngineState *s) {
DataStack *stack = (DataStack *)(_heap[findSegmentByType(SEG_TYPE_STACK)]);
s->stack_base = stack->_entries;
@@ -711,6 +764,8 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savenam
sync_SavegameMetadata(ser, meta);
Graphics::saveThumbnail(*fh);
s->saveLoadWithSerializer(ser); // FIXME: Error handling?
+ if (g_sci->_gfxPorts)
+ g_sci->_gfxPorts->saveLoadWithSerializer(ser);
return true;
}
@@ -761,6 +816,7 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
s->reset(true);
s->saveLoadWithSerializer(ser); // FIXME: Error handling?
+
// Now copy all current state information
s->_segMan->reconstructStack(s);
@@ -775,8 +831,7 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
g_engine->setTotalPlayTime(meta.playTime * 1000);
if (g_sci->_gfxPorts)
- g_sci->_gfxPorts->reset();
-
+ g_sci->_gfxPorts->saveLoadWithSerializer(ser);
g_sci->_soundCmd->reconstructPlayList();
// Message state: