diff options
author | Martin Kiewitz | 2010-08-03 19:43:16 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-08-03 19:43:16 +0000 |
commit | 2e11c1cf9642de2db81ea0a25541872c20f28b8e (patch) | |
tree | 4f36bcedc25fadfec20056b9da21d35415cb7479 /engines/sci | |
parent | fcede4680a03e4f7a389a43f71d1484794e8dead (diff) | |
download | scummvm-rg350-2e11c1cf9642de2db81ea0a25541872c20f28b8e.tar.gz scummvm-rg350-2e11c1cf9642de2db81ea0a25541872c20f28b8e.tar.bz2 scummvm-rg350-2e11c1cf9642de2db81ea0a25541872c20f28b8e.zip |
SCI: reset ports when restoring
fixes qfg3/fairy tales restoring (bug #3035626)
also fixes ScummVM menu restoring while a window is shown (e.g. sq5)
svn-id: r51712
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/ports.cpp | 52 | ||||
-rw-r--r-- | engines/sci/graphics/ports.h | 6 |
3 files changed, 49 insertions, 11 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index f434e5326b..fb23b79c34 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -760,6 +760,8 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { s->gameStartTime = g_system->getMillis(); s->_screenUpdateTime = g_system->getMillis(); + g_sci->_gfxPorts->reset(); + g_sci->_soundCmd->reconstructPlayList(meta.savegame_version); // Message state: diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp index 2137de39de..afbe0e676c 100644 --- a/engines/sci/graphics/ports.cpp +++ b/engines/sci/graphics/ports.cpp @@ -50,7 +50,10 @@ GfxPorts::GfxPorts(SegManager *segMan, GfxScreen *screen) } GfxPorts::~GfxPorts() { - // TODO: Clear _windowList and delete all stuff in it? + // reset frees all windows but _picWind + reset(); + freeWindow(_picWind); + delete _wmgrPort; delete _menuPort; } @@ -135,7 +138,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te _wmgrPort->curLeft = 0; _windowList.push_front(_wmgrPort); - _picWind = newWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); + _picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); // For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead // Because of the menu/status bar if (g_sci->_features->usesOldGfxFunctions()) @@ -144,6 +147,30 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te kernelInitPriorityBands(); } +// Removes any windows from windowList +// is used when restoring/restarting the game +// Sierra SCI actually saved the whole windowList, it seems we don't need to do this at all +// but in some games there are still windows active when restoring. Leaving those windows open +// would create all sorts of issues, that's why we remove them +void GfxPorts::reset() { + PortList::iterator it = _windowList.begin(); + const PortList::iterator end = _windowList.end(); + + setPort(_picWind); + + while (it != end) { + Port *pPort = *it; + if (pPort->id > 2) { + // found a window beyond _picWind + freeWindow((Window *)pPort); + } + it++; + } + _windowList.clear(); + _windowList.push_front(_wmgrPort); + _windowList.push_back(_picWind); +} + void GfxPorts::kernelSetActive(uint16 portId) { switch (portId) { case 0: @@ -179,9 +206,9 @@ reg_t GfxPorts::kernelNewWindow(Common::Rect dims, Common::Rect restoreRect, uin Window *wnd = NULL; if (restoreRect.bottom != 0 && restoreRect.right != 0) - wnd = newWindow(dims, &restoreRect, title, style, priority, false); + wnd = addWindow(dims, &restoreRect, title, style, priority, false); else - wnd = newWindow(dims, NULL, title, style, priority, false); + wnd = addWindow(dims, NULL, title, style, priority, false); wnd->penClr = colorPen; wnd->backClr = colorBack; drawWindow(wnd); @@ -191,7 +218,7 @@ reg_t GfxPorts::kernelNewWindow(Common::Rect dims, Common::Rect restoreRect, uin void GfxPorts::kernelDisposeWindow(uint16 windowId, bool reanimate) { Window *wnd = (Window *)getPortById(windowId); - disposeWindow(wnd, reanimate); + removeWindow(wnd, reanimate); } int16 GfxPorts::isFrontWindow(Window *pWnd) { @@ -228,7 +255,7 @@ void GfxPorts::endUpdate(Window *wnd) { setPort(oldPort); } -Window *GfxPorts::newWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) { +Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) { // Find an unused window/port id uint id = 1; while (id < _windowsById.size() && _windowsById[id]) { @@ -378,7 +405,7 @@ void GfxPorts::drawWindow(Window *pWnd) { setPort(oldport); } -void GfxPorts::disposeWindow(Window *pWnd, bool reanimate) { +void GfxPorts::removeWindow(Window *pWnd, bool reanimate) { setPort(_wmgrPort); _paint16->bitsRestore(pWnd->hSaved1); _paint16->bitsRestore(pWnd->hSaved2); @@ -392,6 +419,15 @@ void GfxPorts::disposeWindow(Window *pWnd, bool reanimate) { delete pWnd; } +void GfxPorts::freeWindow(Window *pWnd) { + if (!pWnd->hSaved1.isNull()) + _segMan->freeHunkEntry(pWnd->hSaved1); + if (!pWnd->hSaved2.isNull()) + _segMan->freeHunkEntry(pWnd->hSaved1); + _windowsById[pWnd->id] = 0; + delete pWnd; +} + void GfxPorts::updateWindow(Window *wnd) { reg_t handle; @@ -413,8 +449,6 @@ Port *GfxPorts::getPortById(uint16 id) { return _windowsById[id]; } - - Port *GfxPorts::setPort(Port *newPort) { Port *oldPort = _curPort; _curPort = newPort; diff --git a/engines/sci/graphics/ports.h b/engines/sci/graphics/ports.h index d10bc6772f..f7f0721eb7 100644 --- a/engines/sci/graphics/ports.h +++ b/engines/sci/graphics/ports.h @@ -46,6 +46,7 @@ public: ~GfxPorts(); void init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *text16); + void reset(); void kernelSetActive(uint16 portId); Common::Rect kernelGetPicWindow(int16 &picTop, int16 &picLeft); @@ -57,9 +58,10 @@ public: int16 isFrontWindow(Window *wnd); void beginUpdate(Window *wnd); void endUpdate(Window *wnd); - Window *newWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw); + Window *addWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw); void drawWindow(Window *wnd); - void disposeWindow(Window *pWnd, bool reanimate); + void removeWindow(Window *pWnd, bool reanimate); + void freeWindow(Window *pWnd); void updateWindow(Window *wnd); Port *getPortById(uint16 id); |