diff options
Diffstat (limited to 'engines/titanic')
-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 | ||||
-rw-r--r-- | engines/titanic/support/rect.cpp | 18 | ||||
-rw-r--r-- | engines/titanic/support/rect.h | 9 |
8 files changed, 100 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; diff --git a/engines/titanic/support/rect.cpp b/engines/titanic/support/rect.cpp index b39ffc1c45..f7f8f14d2f 100644 --- a/engines/titanic/support/rect.cpp +++ b/engines/titanic/support/rect.cpp @@ -42,4 +42,22 @@ void Rect::constrain(const Rect &r) { } } +Point Rect::getPoint(Quadrant quadrant) { + if (isEmpty()) + return Point(left, top); + + switch (quadrant) { + case Q_LEFT: + return Point(MIN(left + 10, (int)right), (top + bottom) / 2); + case Q_RIGHT: + return Point(MAX(right - 10, (int)left), (top + bottom) / 2); + case Q_TOP: + return Point((left + right) / 2, MIN(top + 10, (int)bottom)); + case Q_BOTTOM: + return Point((left + right) / 2, MAX(bottom - 10, (int)top)); + default: + return Point((left + right) / 2, (top + bottom) / 2); + } +} + } // End of namespace Titanic diff --git a/engines/titanic/support/rect.h b/engines/titanic/support/rect.h index 1661711870..eca256df56 100644 --- a/engines/titanic/support/rect.h +++ b/engines/titanic/support/rect.h @@ -27,6 +27,10 @@ namespace Titanic { +enum Quadrant { + Q_CENTER = 0, Q_LEFT, Q_RIGHT, Q_TOP, Q_BOTTOM +}; + typedef Common::Point Point; class Rect : public Common::Rect { @@ -54,6 +58,11 @@ public: * Constrains/clips to the intersection area of the given rect */ void constrain(const Rect &r); + + /** + * Returns a center point for a given edge or center of the rect + */ + Point getPoint(Quadrant quadrant); }; } // End of namespace Titanic |