diff options
Diffstat (limited to 'engines/sci/graphics/frameout.cpp')
-rw-r--r-- | engines/sci/graphics/frameout.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 71ea4c536b..9d8a806e56 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -21,6 +21,7 @@ */ #include "common/algorithm.h" +#include "common/config-manager.h" #include "common/events.h" #include "common/keyboard.h" #include "common/list.h" @@ -149,12 +150,92 @@ void GfxFrameout::run() { _planes.add(initPlane); } +// SCI32 actually did not clear anything at all it seems on restore. The scripts actually cleared up +// planes + screen items right before restoring. And after restoring they sync'd its internal planes list +// as well. void GfxFrameout::clear() { _planes.clear(); _visiblePlanes.clear(); _showList.clear(); } +// This is what Game::restore does, only needed when our ScummVM dialogs are patched in +// It actually does one pass before actual restore deleting screen items + planes +// And after restore it does another pass adding screen items + planes. +void GfxFrameout::syncWithScripts(bool addElements) { + EngineState *engineState = g_sci->getEngineState(); + SegManager *segMan = engineState->_segMan; + + // In case original save/restore dialogs are active, don't do anything + if (ConfMan.getBool("originalsaveload")) + return; + + // Get planes list object + reg_t planesListObject = engineState->variables[VAR_GLOBAL][10]; + reg_t planesListElements = readSelector(segMan, planesListObject, SELECTOR(elements)); + + List *planesList = segMan->lookupList(planesListElements); + reg_t planesNodeObject = planesList->first; + + // Go through all elements of planes::elements + while (!planesNodeObject.isNull()) { + Node *planesNode = segMan->lookupNode(planesNodeObject); + reg_t planeObject = planesNode->value; + + if (addElements) { + // Add this plane object + kernelAddPlane(planeObject); + } + + reg_t planeCastsObject = readSelector(segMan, planeObject, SELECTOR(casts)); + reg_t setListElements = readSelector(segMan, planeCastsObject, SELECTOR(elements)); + + // Now go through all elements of plane::casts::elements + List *planeCastsList = segMan->lookupList(setListElements); + reg_t planeCastsNodeObject = planeCastsList->first; + + while (!planeCastsNodeObject.isNull()) { + Node *castsNode = segMan->lookupNode(planeCastsNodeObject); + reg_t castObject = castsNode->value; + + reg_t castListElements = readSelector(segMan, castObject, SELECTOR(elements)); + + List *castList = segMan->lookupList(castListElements); + reg_t castNodeObject = castList->first; + + while (!castNodeObject.isNull()) { + Node *castNode = segMan->lookupNode(castNodeObject); + reg_t castObject = castNode->value; + + // read selector "-info-" of this object + // TODO: Seems to have been changed for SCI3 + uint16 castInfoSelector = readSelectorValue(segMan, castObject, SELECTOR(_info_)); + + if (castInfoSelector & kInfoFlagViewInserted) { + if (addElements) { + // Flag set, so add this screen item + kernelAddScreenItem(castObject); + } else { + // Flag set, so delete this screen item + kernelDeleteScreenItem(castObject); + } + } + + castNodeObject = castNode->succ; + } + + planeCastsNodeObject = castsNode->succ; + } + + if (!addElements) { + // Delete this plane object + kernelDeletePlane(planeObject); + } + + planesNodeObject = planesNode->succ; + } +} + #pragma mark - #pragma mark Screen items |