From be64c6ba8b5f4a81e6703b5a6325b7a7112c14d4 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Sat, 5 Aug 2017 22:28:03 -0500 Subject: SCI32: Fix closing a Robot when its Plane has been destroyed already This can happen during game restores in at least Lighthouse, which has a Robot on the menu screen whose plane is deleted prior to a call to kRestoreGame32 (which closes the Robot). --- engines/sci/video/robot_decoder.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp index 948f437fdb..c0b5ee5e5c 100644 --- a/engines/sci/video/robot_decoder.cpp +++ b/engines/sci/video/robot_decoder.cpp @@ -579,16 +579,6 @@ void RobotDecoder::close() { debugC(kDebugLevelVideo, "Closing robot"); - _robotId = -1; - _planeId = NULL_REG; - _status = kRobotStatusUninitialized; - _videoSizes.clear(); - _recordPositions.clear(); - _celDecompressionBuffer.clear(); - _doVersion5Scratch.clear(); - delete _stream; - _stream = nullptr; - for (CelHandleList::size_type i = 0; i < _celHandles.size(); ++i) { if (_celHandles[i].status == CelHandleInfo::kFrameLifetime) { _segMan->freeBitmap(_celHandles[i].bitmapId); @@ -601,7 +591,7 @@ void RobotDecoder::close() { } _fixedCels.clear(); - if (g_sci->_gfxFrameout->getPlanes().findByObject(_plane->_object) != nullptr) { + if (g_sci->_gfxFrameout->getPlanes().findByObject(_planeId) != nullptr) { for (RobotScreenItemList::size_type i = 0; i < _screenItemList.size(); ++i) { if (_screenItemList[i] != nullptr) { g_sci->_gfxFrameout->deleteScreenItem(*_screenItemList[i]); @@ -613,6 +603,17 @@ void RobotDecoder::close() { if (_hasAudio) { _audioList.reset(); } + + _robotId = -1; + _planeId = NULL_REG; + _plane = nullptr; + _status = kRobotStatusUninitialized; + _videoSizes.clear(); + _recordPositions.clear(); + _celDecompressionBuffer.clear(); + _doVersion5Scratch.clear(); + delete _stream; + _stream = nullptr; } void RobotDecoder::pause() { @@ -717,7 +718,7 @@ void RobotDecoder::showFrame(const uint16 frameNo, const uint16 newX, const uint CelInfo32 celInfo; celInfo.type = kCelTypeMem; celInfo.bitmap = _celHandles[i].bitmapId; - ScreenItem *screenItem = new ScreenItem(_plane->_object, celInfo); + ScreenItem *screenItem = new ScreenItem(_planeId, celInfo); _screenItemList[i] = screenItem; screenItem->_position = Common::Point(_screenItemX[i], _screenItemY[i]); if (_priority == -1) { @@ -1167,6 +1168,7 @@ bool RobotDecoder::readPartialAudioRecordAndSubmit(const int startFrame, const i #pragma mark RobotDecoder - Rendering uint16 RobotDecoder::getFrameSize(Common::Rect &outRect) const { + assert(_plane != nullptr); outRect.clip(0, 0); for (RobotScreenItemList::size_type i = 0; i < _screenItemList.size(); ++i) { ScreenItem &screenItem = *_screenItemList[i]; @@ -1396,7 +1398,7 @@ void RobotDecoder::doVersion5(const bool shouldSubmitAudio) { if (_screenItemList[i] == nullptr) { CelInfo32 celInfo; celInfo.bitmap = _celHandles[i].bitmapId; - ScreenItem *screenItem = new ScreenItem(_plane->_object, celInfo, position, _scaleInfo); + ScreenItem *screenItem = new ScreenItem(_planeId, celInfo, position, _scaleInfo); _screenItemList[i] = screenItem; // TODO: Version 6 robot? // screenItem->_field_30 = scaleXRemainder; -- cgit v1.2.3