From 0c0be43a3e1e4d012eb6742a88aaa2e398360f2c Mon Sep 17 00:00:00 2001 From: Borja Lorente Date: Fri, 5 Aug 2016 10:46:58 +0200 Subject: MACVENTURE: Fix corner case drawing overflow --- engines/macventure/gui.cpp | 48 +++++++++++++++++++++----------------------- engines/macventure/image.cpp | 14 +++++++------ engines/macventure/image.h | 2 +- 3 files changed, 32 insertions(+), 32 deletions(-) (limited to 'engines/macventure') diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp index b449855fc0..6833de7dfc 100644 --- a/engines/macventure/gui.cpp +++ b/engines/macventure/gui.cpp @@ -696,22 +696,34 @@ void Gui::drawWindowTitle(WindowReference target, Graphics::ManagedSurface * sur void Gui::drawDraggedObject() { if (_draggedObj.id != 0 && - _engine->isObjVisible(_draggedObj.id)) { + _engine->isObjVisible(_draggedObj.id)) { ensureAssetLoaded(_draggedObj.id); ImageAsset *asset = _assets[_draggedObj.id]; - _draggedSurface.create(asset->getWidth(), asset->getHeight(), _screen.format); + // In case of overflow from the right/top + uint w = asset->getWidth() + MIN((int16)0, _draggedObj.pos.x); + uint h = asset->getHeight() + MIN((int16)0, _draggedObj.pos.y); - asset->blitInto(&_draggedSurface, 0, 0, kBlitBIC); + // In case of overflow from the bottom/left + if (_draggedObj.pos.x > 0 && _draggedObj.pos.x + w > kScreenWidth) { w = kScreenWidth - _draggedObj.pos.x; } + if (_draggedObj.pos.y > 0 && _draggedObj.pos.y + h > kScreenHeight) { h = kScreenHeight - _draggedObj.pos.y; } + + _draggedSurface.create(w, h, _screen.format); + + asset->blitInto(&_draggedSurface, MIN((int16)0, _draggedObj.pos.x), MIN((int16)0, _draggedObj.pos.y), kBlitBIC); + + Common::Point target = _draggedObj.pos; + if (target.x < 0) { target.x = 0; } + if (target.y < 0) { target.y = 0; } g_system->copyRectToScreen( - _draggedSurface.getPixels(), + _draggedSurface.getBasePtr(0, 0), _draggedSurface.pitch, - _draggedObj.pos.x, - _draggedObj.pos.y, + target.x, + target.y, _draggedSurface.w, - _draggedSurface.h); - + _draggedSurface.h + ); } } @@ -846,25 +858,11 @@ void Gui::saveInto(int slot) { } void Gui::moveDraggedObject(Common::Point target) { - Common::Point newPos = target + _draggedObj.mouseOffset; - bool movement = false; - // If we overflow, move the mouseOffset, not the position. - if (newPos.x < 0 || newPos.x + _assets[_draggedObj.id]->getWidth() >= kScreenWidth) { - _draggedObj.mouseOffset.x = _draggedObj.pos.x - target.x; - } else { - _draggedObj.pos.x = newPos.x; - movement = true; - } - - if (newPos.y < 0 || newPos.y + _assets[_draggedObj.id]->getHeight() >= kScreenHeight) { - _draggedObj.mouseOffset.y = _draggedObj.pos.y - target.y; - } else { - _draggedObj.pos.y = newPos.y; - movement = true; - } + ensureAssetLoaded(_draggedObj.id); + _draggedObj.pos = target + _draggedObj.mouseOffset; // TODO FInd more elegant way of making pow2 - _draggedObj.hasMoved = movement && (_draggedObj.startPos.sqrDist(_draggedObj.pos) >= (kDragThreshold * kDragThreshold)); + _draggedObj.hasMoved = (_draggedObj.startPos.sqrDist(_draggedObj.pos) >= (kDragThreshold * kDragThreshold)); debug(4, "Dragged obj position: (%d, %d), mouse offset: (%d, %d), hasMoved: %d, dist: %d, threshold: %d", _draggedObj.pos.x, _draggedObj.pos.y, diff --git a/engines/macventure/image.cpp b/engines/macventure/image.cpp index 05ec68c2a0..a89eae94be 100644 --- a/engines/macventure/image.cpp +++ b/engines/macventure/image.cpp @@ -412,7 +412,7 @@ int ImageAsset::getHeight() { void ImageAsset::blitDirect(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array& data, uint bitHeight, uint bitWidth, uint rowBytes) { uint sx, sy, w, h; - calculateSubsection(ox, oy, bitWidth, bitHeight, sx, sy, w, h); + calculateSubsection(target, ox, oy, bitWidth, bitHeight, sx, sy, w, h); for (uint y = 0; y < h; y++) { uint bmpofs = (y + sy) * rowBytes; @@ -427,12 +427,12 @@ void ImageAsset::blitDirect(Graphics::ManagedSurface * target, int ox, int oy, c void ImageAsset::blitBIC(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array &data, uint bitHeight, uint bitWidth, uint rowBytes) { uint sx, sy, w, h; - calculateSubsection(ox, oy, bitWidth, bitHeight, sx, sy, w, h); + calculateSubsection(target, ox, oy, bitWidth, bitHeight, sx, sy, w, h); for (uint y = 0; y < h; y++) { uint bmpofs = (y + sy) * rowBytes; byte pix = 0; - for (uint x = sx; x < w; x++) { + for (uint x = 0; x < w; x++) { pix = data[bmpofs + ((x + sx) >> 3)] & (1 << (7 - ((x + sx) & 7))); if (pix) *((byte *)target->getBasePtr(ox + x, oy + y)) = kColorWhite; } @@ -441,7 +441,7 @@ void ImageAsset::blitBIC(Graphics::ManagedSurface * target, int ox, int oy, cons void ImageAsset::blitOR(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array &data, uint bitHeight, uint bitWidth, uint rowBytes) { uint sx, sy, w, h; - calculateSubsection(ox, oy, bitWidth, bitHeight, sx, sy, w, h); + calculateSubsection(target, ox, oy, bitWidth, bitHeight, sx, sy, w, h); for (uint y = 0; y < h; y++) { uint bmpofs = (y + sy) * rowBytes; @@ -455,7 +455,7 @@ void ImageAsset::blitOR(Graphics::ManagedSurface * target, int ox, int oy, const void ImageAsset::blitXOR(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array &data, uint bitHeight, uint bitWidth, uint rowBytes) { uint sx, sy, w, h; - calculateSubsection(ox, oy, bitWidth, bitHeight, sx, sy, w, h); + calculateSubsection(target, ox, oy, bitWidth, bitHeight, sx, sy, w, h); for (uint y = 0; y < h; y++) { uint bmpofs = (y + sy) * rowBytes; @@ -471,13 +471,15 @@ void ImageAsset::blitXOR(Graphics::ManagedSurface * target, int ox, int oy, cons } } -void ImageAsset::calculateSubsection(int &ox, int &oy, uint bitWidth, uint bitHeight, uint &sx, uint &sy, uint &w, uint &h) { +void ImageAsset::calculateSubsection(Graphics::ManagedSurface *target, int &ox, int &oy, uint bitWidth, uint bitHeight, uint &sx, uint &sy, uint &w, uint &h) { sx = (ox < 0) ? -ox : 0; sy = (oy < 0) ? -oy : 0; ox = (ox < 0) ? 0 : ox; oy = (oy < 0) ? 0 : oy; w = MAX((int)(bitWidth - sx), 0); h = MAX((int)(bitHeight - sy), 0); + w = w > target->w ? target->w : w; + h = h > target->h ? target->h : h; } } // End of namespace MacVenture diff --git a/engines/macventure/image.h b/engines/macventure/image.h index 3520f8182e..3910f83fa8 100644 --- a/engines/macventure/image.h +++ b/engines/macventure/image.h @@ -82,7 +82,7 @@ private: void blitOR(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array &data, uint bitHeight, uint bitWidth, uint rowBytes); void blitXOR(Graphics::ManagedSurface * target, int ox, int oy, const Common::Array &data, uint bitHeight, uint bitWidth, uint rowBytes); - void calculateSubsection(int &ox, int &oy, uint bitWidth, uint bitHeight, uint &sx, uint &sy, uint &w, uint &h); + void calculateSubsection(Graphics::ManagedSurface *target, int &ox, int &oy, uint bitWidth, uint bitHeight, uint &sx, uint &sy, uint &w, uint &h); private: ObjID _id; -- cgit v1.2.3