From 00fd812028c6aaa9b2ec05963a66a23dabbd33ba Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 11:23:31 -1000 Subject: SHERLOCK: Properly restrict scene drawing to scene area --- engines/sherlock/graphics.cpp | 8 ------- engines/sherlock/graphics.h | 2 -- engines/sherlock/map.cpp | 1 - engines/sherlock/scene.cpp | 53 ++++++++++++++++++++++--------------------- engines/sherlock/screen.cpp | 26 ++++++++++++++++++--- engines/sherlock/screen.h | 1 + 6 files changed, 51 insertions(+), 40 deletions(-) (limited to 'engines/sherlock') diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 6e986c839b..6fd046e458 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -164,14 +164,6 @@ void Surface::fillRect(const Common::Rect &r, byte color) { addDirtyRect(r); } -/** - * Return a sub-area of the surface as a new surface object. The surfaces - * are shared in common, so changes in the sub-surface affects the original. - */ -Surface Surface::getSubArea(const Common::Rect &r) { - return Surface(*this, r); -} - /** * Clips the given source bounds so the passed destBounds will be entirely on-screen */ diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 85f3ba8c40..80b692130c 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -55,8 +55,6 @@ public: void fillRect(int x1, int y1, int x2, int y2, byte color); void fillRect(const Common::Rect &r, byte color); - - Surface getSubArea(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 5ff27a9709..f572e3771a 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -442,7 +442,6 @@ void Map::updateMap(bool flushScreen) { */ void Map::walkTheStreets() { People &people = *_vm->_people; - Scene &scene = *_vm->_scene; bool reversePath = false; Common::Array tempPath; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 1d00e9d23d..50e62b7ba5 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -716,10 +716,11 @@ int Scene::toggleObject(const Common::String &name) { void Scene::updateBackground() { People &people = *_vm->_people; Screen &screen = *_vm->_screen; - Surface surface = screen._backBuffer1.getSubArea( - Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); Sprite &player = people[AL]; + // Restrict drawing window + screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + // Update Holmes if he's turned on if (people._holmesOn) player.adjustSprite(); @@ -731,26 +732,26 @@ void Scene::updateBackground() { // Draw all active shapes which are behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } // Draw all active shapes which are normal and behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -760,7 +761,7 @@ void Scene::updateBackground() { player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT || player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; - surface.transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, + screen._backBuffer->transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, player._position.y / 100 - player.frameHeight()), flipped); } @@ -768,14 +769,14 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the player for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -787,14 +788,14 @@ void Scene::updateBackground() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are forward for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == FORWARD) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } } @@ -1079,8 +1080,8 @@ void Scene::doBgAnim() { Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; - Surface surface = screen._backBuffer1.getSubArea(Common::Rect(0, 0, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + + screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); int cursorId = events.getCursor(); Common::Point mousePos = events.mousePos(); @@ -1150,7 +1151,7 @@ void Scene::doBgAnim() { if (people[AL]._type == CHARACTER) screen.restoreBackground(bounds); else if (people[AL]._type == REMOVE) - screen._backBuffer1.blitFrom(screen._backBuffer2, pt, bounds); + screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds); for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; @@ -1169,7 +1170,7 @@ void Scene::doBgAnim() { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && ((o._flags & 1) == 0)) { // Restore screen area - screen._backBuffer1.blitFrom(screen._backBuffer2, o._position, + screen._backBuffer->blitFrom(screen._backBuffer2, o._position, Common::Rect(o._position.x, o._position.y, o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y)); @@ -1218,14 +1219,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1233,14 +1234,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1253,7 +1254,7 @@ void Scene::doBgAnim() { bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT || people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT || people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT; - screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, + screen._backBuffer->transBlitFrom(*people[AL]._imageFrame, Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); } @@ -1261,14 +1262,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1276,19 +1277,19 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - screen._backBuffer1.transBlitFrom(*people._portrait._imageFrame, + screen._backBuffer->transBlitFrom(*people._portrait._imageFrame, people._portrait._position, people._portrait._flags & 2); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1296,7 +1297,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & 1) == 0) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Bring the newly built picture to the screen diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 3c9a10e4a1..66590c3ada 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -39,6 +39,10 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); + + // Set dummy surface used for restricted scene drawing + _sceneSurface.format = Graphics::PixelFormat::createFormatCLUT8(); + _sceneSurface.pitch = SHERLOCK_SCREEN_WIDTH; } Screen::~Screen() { @@ -469,15 +473,31 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); } +/** + * Sets the active back buffer pointer to a restricted sub-area of the first back buffer + */ void Screen::setDisplayBounds(const Common::Rect &r) { - // TODO: See if needed + assert(r.left == 0 && r.top == 0); + _sceneSurface.setPixels(_backBuffer1.getPixels()); + _sceneSurface.w = r.width(); + _sceneSurface.h = r.height(); + + _backBuffer = &_sceneSurface; } + +/** + * Resets the active buffer pointer to point back to the full first back buffer + */ void Screen::resetDisplayBounds() { - setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + _backBuffer = &_backBuffer1; } +/** + * Return the size of the current display window + */ Common::Rect Screen::getDisplayBounds() { - return Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) : + Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } /** diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index a8bdc53b5a..bbfba1c575 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -65,6 +65,7 @@ private: uint32 _transitionSeed; ImageFile *_font; int _fontHeight; + Surface _sceneSurface; void mergeDirtyRects(); -- cgit v1.2.3