aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/titanic/core/game_object.cpp9
-rw-r--r--engines/titanic/core/game_object.h7
-rw-r--r--engines/titanic/core/link_item.cpp11
-rw-r--r--engines/titanic/core/link_item.h9
-rw-r--r--engines/titanic/core/view_item.cpp43
-rw-r--r--engines/titanic/core/view_item.h6
-rw-r--r--engines/titanic/support/rect.cpp18
-rw-r--r--engines/titanic/support/rect.h9
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