diff options
author | Paul Gilbert | 2017-08-08 22:24:22 -0400 |
---|---|---|
committer | Paul Gilbert | 2017-08-08 22:24:22 -0400 |
commit | 660f7bf11479222689cf77060077fe47d65a465e (patch) | |
tree | 48798a2d991a3d9bb533efeb42ca41d9b485d5f1 /engines/titanic/core | |
parent | 6fac0ace2c844aa68c2482362021981ed1db931b (diff) | |
download | scummvm-rg350-660f7bf11479222689cf77060077fe47d65a465e.tar.gz scummvm-rg350-660f7bf11479222689cf77060077fe47d65a465e.tar.bz2 scummvm-rg350-660f7bf11479222689cf77060077fe47d65a465e.zip |
TITANIC: Further improvements to arrow key movement
The movement code, when deciding on an item or link that matches the
desired direction, will check five points on the object/links area..
center, left edge, right edge, top edge, and bottom edge. For each
of these, it makes sure that at that point, clicking will actually
get passed to it. Otherwise, it moves onto one of the other edges.
This helps avoid issues where links weren't working because standard
scene objects were partially obscuring them.
Diffstat (limited to 'engines/titanic/core')
-rw-r--r-- | engines/titanic/core/game_object.cpp | 9 | ||||
-rw-r--r-- | engines/titanic/core/game_object.h | 7 | ||||
-rw-r--r-- | engines/titanic/core/link_item.cpp | 11 | ||||
-rw-r--r-- | engines/titanic/core/link_item.h | 9 | ||||
-rw-r--r-- | engines/titanic/core/view_item.cpp | 43 | ||||
-rw-r--r-- | engines/titanic/core/view_item.h | 6 |
6 files changed, 73 insertions, 12 deletions
diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp index ab91a6decc..1519a2de66 100644 --- a/engines/titanic/core/game_object.cpp +++ b/engines/titanic/core/game_object.cpp @@ -289,18 +289,17 @@ bool CGameObject::checkPoint(const Point &pt, bool ignoreSurface, bool visibleOn return pixel != transColor; } -bool CGameObject::findPoint(Point &pt) { +bool CGameObject::findPoint(Quadrant quadrant, Point &pt) { // Start by checking a centroid point in the bounds if (!_bounds.isEmpty()) { - pt = Point((_bounds.left + _bounds.right) / 2, - (_bounds.top + _bounds.bottom) / 2); + pt = _bounds.getPoint(quadrant); if (checkPoint(pt, false, true)) return true; } // Scan through all the area of the bounds to find a valid point - for (pt.y = _bounds.top; pt.y < _bounds.bottom; ++pt.y) { - for (pt.x = _bounds.left; pt.x < _bounds.right; ++pt.x) { + for (; pt.y < _bounds.bottom; ++pt.y, pt.x = _bounds.left) { + for (; pt.x < _bounds.right; ++pt.x) { if (checkPoint(pt, false, true)) return true; } diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h index 9a7d426d0a..619c56bc50 100644 --- a/engines/titanic/core/game_object.h +++ b/engines/titanic/core/game_object.h @@ -611,10 +611,11 @@ public: /** * Returns a point that falls within the object. Used for simulating * mouse clicks for movement when arrow keys are pressed - * @param pt Return point - * @returns True if a point was found + * @param quadrant Quadrant (edge) to return point for + * @param pt Return point + * @returns True if a point was found */ - virtual bool findPoint(Point &pt); + bool findPoint(Quadrant quadrant, Point &pt); /** * Set the position of the object diff --git a/engines/titanic/core/link_item.cpp b/engines/titanic/core/link_item.cpp index c46e44aa8b..23be00596b 100644 --- a/engines/titanic/core/link_item.cpp +++ b/engines/titanic/core/link_item.cpp @@ -35,7 +35,8 @@ Movement CLinkItem::getMovementFromCursor(CursorId cursorId) { else if (cursorId == CURSOR_MOVE_RIGHT) return TURN_RIGHT; else if (cursorId == CURSOR_MOVE_FORWARD || cursorId == CURSOR_MOVE_THROUGH || - cursorId == CURSOR_DOWN) + cursorId == CURSOR_DOWN || cursorId == CURSOR_LOOK_UP || + cursorId == CURSOR_LOOK_DOWN || cursorId == CURSOR_MAGNIFIER) return MOVE_FORWARDS; else if (cursorId == CURSOR_BACKWARDS) return MOVE_BACKWARDS; @@ -194,4 +195,12 @@ Movement CLinkItem::getMovement() const { return getMovementFromCursor(_cursorId); } +bool CLinkItem::findPoint(Quadrant quadrant, Point &pt) { + if (_bounds.isEmpty()) + return false; + + pt = _bounds.getPoint(quadrant); + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/core/link_item.h b/engines/titanic/core/link_item.h index 609310a7c3..05435e8c6d 100644 --- a/engines/titanic/core/link_item.h +++ b/engines/titanic/core/link_item.h @@ -101,6 +101,15 @@ public: * Get the movement, if any, the cursor represents */ Movement getMovement() const; + + /** + * Returns a point that falls within the link. Used for simulating + * mouse clicks for movement when arrow keys are pressed + * @param quadrant Quadrant (edge) to return point for + * @param pt Return point + * @returns True if a point was found + */ + bool findPoint(Quadrant quadrant, Point &pt); }; } // End of namespace Titanic diff --git a/engines/titanic/core/view_item.cpp b/engines/titanic/core/view_item.cpp index f98b015feb..60e08a5582 100644 --- a/engines/titanic/core/view_item.cpp +++ b/engines/titanic/core/view_item.cpp @@ -341,6 +341,7 @@ CString CViewItem::getNodeViewName() const { bool CViewItem::MovementMsg(CMovementMsg *msg) { Point pt; bool foundPt = false; + int quadrant; // First allow any child objects to handle it for (CTreeItem *treeItem = getFirstChild(); treeItem; @@ -365,13 +366,23 @@ bool CViewItem::MovementMsg(CMovementMsg *msg) { if (link->getMovement() != msg->_movement) continue; - pt = Point((link->_bounds.left + link->_bounds.right) / 2, - (link->_bounds.top + link->_bounds.bottom) / 2); + for (quadrant = Q_CENTER; quadrant <= Q_BOTTOM; ++quadrant) { + if (link->findPoint((Quadrant)quadrant, pt)) + if (link == getItemAtPoint(pt)) + break; + } + if (quadrant > Q_BOTTOM) + continue; } else if (gameObj) { if (!gameObj->_visible || gameObj->getMovement() != msg->_movement) continue; - if (!gameObj->findPoint(pt)) + for (quadrant = Q_CENTER; quadrant <= Q_BOTTOM; ++quadrant) { + if (gameObj->findPoint((Quadrant)quadrant, pt)) + if (gameObj == getItemAtPoint(pt)) + break; + } + if (quadrant > Q_BOTTOM) continue; } else { // Not a link or object, so ignore @@ -397,4 +408,30 @@ bool CViewItem::MovementMsg(CMovementMsg *msg) { return false; } +CTreeItem *CViewItem::getItemAtPoint(const Point &pt) { + CTreeItem *result = nullptr; + + // First scan for objects + for (CTreeItem *treeItem = scan(this); treeItem; treeItem = treeItem->scan(this)) { + CGameObject *gameObject = dynamic_cast<CGameObject *>(treeItem); + + if (gameObject && gameObject->checkPoint(pt, false, true)) + result = treeItem; + } + + if (result == nullptr) { + // Scan for links coverign that position + for (CTreeItem *treeItem = scan(this); treeItem; treeItem = treeItem->scan(this)) { + CLinkItem *link = dynamic_cast<CLinkItem *>(treeItem); + + if (link && link->_bounds.contains(pt)) { + result = treeItem; + break; + } + } + } + + return result; +} + } // End of namespace Titanic diff --git a/engines/titanic/core/view_item.h b/engines/titanic/core/view_item.h index 253294d9a1..ab6a4373b7 100644 --- a/engines/titanic/core/view_item.h +++ b/engines/titanic/core/view_item.h @@ -54,6 +54,12 @@ private: * Handles mouse button up messages */ void handleButtonUpMsg(CMouseButtonUpMsg *msg); + + /** + * Returns the item in the view at a given point that will + * receive any mouse click + */ + CTreeItem *getItemAtPoint(const Point &pt); protected: int _field24; CResourceKey _resourceKey; |