aboutsummaryrefslogtreecommitdiff
path: root/engines/dreamweb/saveload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/dreamweb/saveload.cpp')
-rw-r--r--engines/dreamweb/saveload.cpp63
1 files changed, 62 insertions, 1 deletions
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp
index ea9cdc0249..8a0791d19b 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -156,8 +156,16 @@ void DreamWebEngine::doLoad(int savegameId) {
} else {
if (savegameId == -1) {
- // Open dialog to get savegameId
+ // Wait till both mouse buttons are up. We should wait till the user
+ // releases the mouse button, otherwise the follow-up mouseup event
+ // will trigger a load of the save slot under the mouse cursor. Fixes
+ // bug #3582582.
+ while (_oldMouseState > 0) {
+ readMouse();
+ g_system->delayMillis(10);
+ }
+ // Open dialog to get savegameId
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
savegameId = dialog->runModalWithCurrentTarget();
delete dialog;
@@ -241,6 +249,15 @@ void DreamWebEngine::saveGame() {
}
return;
} else {
+ // Wait till both mouse buttons are up. We should wait till the user
+ // releases the mouse button, otherwise the follow-up mouseup event
+ // will trigger a save into the save slot under the mouse cursor. Fixes
+ // bug #3582582.
+ while (_oldMouseState > 0) {
+ readMouse();
+ g_system->delayMillis(10);
+ }
+
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
int savegameId = dialog->runModalWithCurrentTarget();
Common::String game_description = dialog->getResultString();
@@ -557,6 +574,14 @@ void DreamWebEngine::savePosition(unsigned int slot, const char *descbuf) {
delete outSaveFile;
}
+
+// Utility struct for a savegame sanity check in loadPosition
+struct FrameExtent {
+ uint16 start;
+ uint16 length;
+ bool operator<(const struct FrameExtent& other) const { return start<other.start; }
+};
+
void DreamWebEngine::loadPosition(unsigned int slot) {
_timeCount = 0;
clearChanges();
@@ -636,6 +661,42 @@ void DreamWebEngine::loadPosition(unsigned int slot) {
}
delete inSaveFile;
+
+
+ // Do a sanity check on exFrames data to detect exFrames corruption
+ // caused by a (now fixed) bug in emergencyPurge. See bug #3591088.
+ // Gather the location of frame data of all used ex object frames.
+ Common::List<FrameExtent> flist;
+ for (unsigned int i = 0; i < kNumexobjects; ++i) {
+ if (_exData[i].mapad[0] != 0xff) {
+ FrameExtent fe;
+ Frame *frame = &_exFrames._frames[3*i+0];
+ fe.start = frame->ptr();
+ fe.length = frame->width * frame->height;
+ flist.push_back(fe);
+
+ frame = &_exFrames._frames[3*i+1];
+ fe.start = frame->ptr();
+ fe.length = frame->width * frame->height;
+ flist.push_back(fe);
+ }
+ }
+ // ...and check if the frames overlap.
+ Common::sort(flist.begin(), flist.end(), Common::Less<FrameExtent>());
+ Common::List<FrameExtent>::const_iterator iter;
+ uint16 curEnd = 0;
+ for (iter = flist.begin(); iter != flist.end(); ++iter) {
+ if (iter->start < curEnd)
+ error("exFrames data corruption in savegame");
+ curEnd = iter->start + iter->length;
+ }
+ if (curEnd > _vars._exFramePos) {
+ if (curEnd > kExframeslen)
+ error("exFrames data corruption in savegame");
+ warning("Fixing up exFramePos");
+ _vars._exFramePos = curEnd;
+ }
+ // (end of sanity check)
}
// Count number of save files, and load their descriptions into _saveNames