[Scummvm-git-logs] scummvm master -> 957e4a0cd76bc59edf917834ca2b5c2e9c03c38a

mduggan noreply at scummvm.org
Sun Mar 9 03:55:41 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
957e4a0cd7 DGDS: Multiple mouse fixes to match original


Commit: 957e4a0cd76bc59edf917834ca2b5c2e9c03c38a
    https://github.com/scummvm/scummvm/commit/957e4a0cd76bc59edf917834ca2b5c2e9c03c38a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2025-03-09T14:45:31+11:00

Commit Message:
DGDS: Multiple mouse fixes to match original

This changes the mouse behavior to better match the original games.

* Left-click "use" should only happen on a short click (mouse button goes down
  and up within a few frames) - longer clicks should always do "pick up"
  operation.
* Right-click "look" should only happen on short clicks, longer right button
  should start targetting mode
* Both-click should operate on all areas under the mouse, ignoring their
  conditions

This fixes #15774 and #15782, and also fixes eg Rise of the Dragon trying to
fire the gun in Blade's apartment.

Changed paths:
    engines/dgds/dgds.cpp
    engines/dgds/globals.cpp
    engines/dgds/globals.h
    engines/dgds/inventory.cpp
    engines/dgds/inventory.h
    engines/dgds/scene.cpp
    engines/dgds/scene.h


diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index bb4bccedf06..dbb3fe4ba66 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -718,9 +718,6 @@ Common::Error DgdsEngine::run() {
 
 			if (_inventory->isOpen()) {
 				switch (_lastMouseEvent) {
-				case Common::EVENT_MOUSEMOVE:
-					_inventory->mouseMoved(_lastMouse);
-					break;
 				case Common::EVENT_LBUTTONDOWN:
 					_inventory->mouseLDown(_lastMouse);
 					break;
@@ -730,14 +727,13 @@ Common::Error DgdsEngine::run() {
 				case Common::EVENT_RBUTTONUP:
 					_inventory->mouseRUp(_lastMouse);
 					break;
+				case Common::EVENT_MOUSEMOVE:
 				default:
+					_inventory->mouseUpdate(_lastMouse);
 					break;
 				}
 			} else {
 				switch (_lastMouseEvent) {
-				case Common::EVENT_MOUSEMOVE:
-					_scene->mouseMoved(_lastMouse);
-					break;
 				case Common::EVENT_LBUTTONDOWN:
 					_scene->mouseLDown(_lastMouse);
 					break;
@@ -750,7 +746,9 @@ Common::Error DgdsEngine::run() {
 				case Common::EVENT_RBUTTONUP:
 					_scene->mouseRUp(_lastMouse);
 					break;
+				case Common::EVENT_MOUSEMOVE:
 				default:
+					_scene->mouseUpdate(_lastMouse);
 					break;
 				}
 			}
diff --git a/engines/dgds/globals.cpp b/engines/dgds/globals.cpp
index a2b495db0a3..22c564bece3 100644
--- a/engines/dgds/globals.cpp
+++ b/engines/dgds/globals.cpp
@@ -61,7 +61,7 @@ private:
 
 Globals::Globals(Clock &clock) :
 _lastOpcode1SceneChangeNum(0), _sceneOp12SceneNum(0), _currentSelectedItem(0),
-_gameMinsToAddOnLClick(0), _gameMinsToAddOnStartDrag(0), _gameMinsToAddOnRClick(0), _gameMinsToAddOnDragFinished(0),
+_gameMinsToAddOnUse(0), _gameMinsToAddOnPickUp(0), _gameMinsToAddOnLook(0), _gameMinsToAddOnDrop(0),
 _gameMinsToAddOnObjInteraction(0), _gameIsInteractiveGlobal(0), _sceneOpcode15FromScene(0),
 _sceneOpcode15ToScene(0) {
 	_globals.push_back(clock.getGameMinsAddedGlobal(1));
@@ -73,10 +73,10 @@ _sceneOpcode15ToScene(0) {
 	_globals.push_back(clock.getDaysGlobal(0x5F));
 	_globals.push_back(clock.getHoursGlobal(0x5E));
 	_globals.push_back(clock.getMinsGlobal(0x5D));
-	_globals.push_back(new RWI16Global(0x5C, &_gameMinsToAddOnLClick));
-	_globals.push_back(new RWI16Global(0x5B, &_gameMinsToAddOnStartDrag));
-	_globals.push_back(new RWI16Global(0x5A, &_gameMinsToAddOnRClick));
-	_globals.push_back(new RWI16Global(0x59, &_gameMinsToAddOnDragFinished));
+	_globals.push_back(new RWI16Global(0x5C, &_gameMinsToAddOnUse));
+	_globals.push_back(new RWI16Global(0x5B, &_gameMinsToAddOnPickUp));
+	_globals.push_back(new RWI16Global(0x5A, &_gameMinsToAddOnLook));
+	_globals.push_back(new RWI16Global(0x59, &_gameMinsToAddOnDrop));
 	_globals.push_back(new RWI16Global(0x58, &_gameMinsToAddOnObjInteraction));
 	_globals.push_back(new GameIsInteractiveGlobal(0x57, &_gameIsInteractiveGlobal));
 	_globals.push_back(clock.getDays2Global(0x56));
@@ -126,10 +126,10 @@ Common::Error Globals::syncState(Common::Serializer &s) {
 	s.syncAsSint16LE(_lastOpcode1SceneChangeNum);
 	s.syncAsSint16LE(_sceneOp12SceneNum);
 	s.syncAsSint16LE(_currentSelectedItem);
-	s.syncAsSint16LE(_gameMinsToAddOnLClick);
-	s.syncAsSint16LE(_gameMinsToAddOnStartDrag);
-	s.syncAsSint16LE(_gameMinsToAddOnRClick);
-	s.syncAsSint16LE(_gameMinsToAddOnDragFinished);
+	s.syncAsSint16LE(_gameMinsToAddOnUse);
+	s.syncAsSint16LE(_gameMinsToAddOnPickUp);
+	s.syncAsSint16LE(_gameMinsToAddOnLook);
+	s.syncAsSint16LE(_gameMinsToAddOnDrop);
 	s.syncAsSint16LE(_gameMinsToAddOnObjInteraction);
 	s.syncAsSint16LE(_gameIsInteractiveGlobal);
 	s.syncAsSint16LE(_sceneOpcode15FromScene);
diff --git a/engines/dgds/globals.h b/engines/dgds/globals.h
index f1e48dc8a2c..d8bcd23d4b9 100644
--- a/engines/dgds/globals.h
+++ b/engines/dgds/globals.h
@@ -89,10 +89,10 @@ public:
 	virtual Common::Error syncState(Common::Serializer &s); // note: children should call parent first
 	Common::Array<Global *> &getAllGlobals() { return _globals; }
 
-	int16 getGameMinsToAddOnLClick() const { return _gameMinsToAddOnLClick; }
-	int16 getGameMinsToAddOnStartDrag() const { return _gameMinsToAddOnStartDrag; }
-	int16 getGameMinsToAddOnRClick() const { return _gameMinsToAddOnRClick; }
-	int16 getGameMinsToAddOnDragFinished() const { return _gameMinsToAddOnDragFinished; }
+	int16 getGameMinsToAddOnUse() const { return _gameMinsToAddOnUse; }
+	int16 getGameMinsToAddOnPickUp() const { return _gameMinsToAddOnPickUp; }
+	int16 getGameMinsToAddOnLook() const { return _gameMinsToAddOnLook; }
+	int16 getGameMinsToAddOnDrop() const { return _gameMinsToAddOnDrop; }
 	int16 getGameMinsToAddOnObjInteraction() const { return _gameMinsToAddOnObjInteraction; }
 	int16 getGameIsInteractiveGlobal() { return _gameIsInteractiveGlobal; }
 
@@ -105,10 +105,10 @@ protected:
 	int16 _lastOpcode1SceneChangeNum;
 	int16 _sceneOp12SceneNum;
 	int16 _currentSelectedItem;
-	int16 _gameMinsToAddOnLClick;
-	int16 _gameMinsToAddOnStartDrag;
-	int16 _gameMinsToAddOnRClick;
-	int16 _gameMinsToAddOnDragFinished;
+	int16 _gameMinsToAddOnUse;
+	int16 _gameMinsToAddOnPickUp;
+	int16 _gameMinsToAddOnLook;
+	int16 _gameMinsToAddOnDrop;
 	int16 _gameMinsToAddOnObjInteraction;
 	int16 _gameIsInteractiveGlobal; // used to decide if the game can start a "meanwhile" sequence
 	int16 _sceneOpcode15FromScene;
diff --git a/engines/dgds/inventory.cpp b/engines/dgds/inventory.cpp
index d6507f2f1b5..072e3877723 100644
--- a/engines/dgds/inventory.cpp
+++ b/engines/dgds/inventory.cpp
@@ -322,7 +322,7 @@ void Inventory::drawItems(Graphics::ManagedSurface &surf) {
 	}
 }
 
-void Inventory::mouseMoved(const Common::Point &pt) {
+void Inventory::mouseUpdate(const Common::Point &pt) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 	GameItem *dragItem = engine->getScene()->getDragItem();
 	if (dragItem) {
@@ -398,7 +398,7 @@ void Inventory::mouseLDown(const Common::Point &pt) {
 		GameItem *underMouse = itemUnderMouse(pt);
 		if (underMouse) {
 			_highlightItemNo = underMouse->_num;
-			engine->getScene()->runOps(underMouse->onLDownOps);
+			engine->getScene()->runOps(underMouse->onPickUpOps);
 			engine->getScene()->setDragItem(underMouse);
 			underMouse->_flags |= kItemStateWasInInv;
 			if (underMouse->_iconNum)
@@ -477,7 +477,7 @@ void Inventory::mouseRUp(const Common::Point &pt) {
 				// here for zooming within the box.
 				engine->getBackgroundBuffer().fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
 			}
-			engine->getScene()->runOps(underMouse->onRClickOps);
+			engine->getScene()->runOps(underMouse->onLookOps);
 		}
 	} else {
 		engine->getScene()->mouseRUp(pt);
diff --git a/engines/dgds/inventory.h b/engines/dgds/inventory.h
index d871b476033..c785de7dfbc 100644
--- a/engines/dgds/inventory.h
+++ b/engines/dgds/inventory.h
@@ -46,7 +46,7 @@ public:
 	void drawTime(Graphics::ManagedSurface &surf);
 	void drawHeader(Graphics::ManagedSurface &surf);
 
-	void mouseMoved(const Common::Point &pt);
+	void mouseUpdate(const Common::Point &pt);
 	void mouseLDown(const Common::Point &pt);
 	void mouseLUp(const Common::Point &pt);
 	void mouseRUp(const Common::Point &pt);
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 92930da987e..bb4c8f61d2c 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -42,13 +42,21 @@
 namespace Dgds {
 
 
+//
+// The number of frames between mouse down and the action changing:
+//           short     long
+// L button: use   ->  pick up
+// R button: look  ->  target
+//
+static const int MOUSE_DOWN_TIMEOUT = 3;
+
 Common::String HotArea::dump(const Common::String &indent) const {
 	Common::String str = Common::String::format("%sHotArea<%s num %d cursor %d cursor2 %d interactionRectNum %d",
 			indent.c_str(), _rect.dump("").c_str(), _num, _cursorNum, _cursorNum2, _objInteractionRectNum);
 	str += DebugUtil::dumpStructList(indent, "enableConditions", enableConditions);
-	str += DebugUtil::dumpStructList(indent, "onRClickOps", onRClickOps);
-	str += DebugUtil::dumpStructList(indent, "onLDownOps", onLDownOps);
-	str += DebugUtil::dumpStructList(indent, "onLClickOps", onLClickOps);
+	str += DebugUtil::dumpStructList(indent, "onLookOps", onLookOps);
+	str += DebugUtil::dumpStructList(indent, "onPickUpOps", onPickUpOps);
+	str += DebugUtil::dumpStructList(indent, "onUseOps", onUseOps);
 	str += "\n";
 	str += indent + ">";
 	return str;
@@ -159,9 +167,9 @@ bool Scene::readHotArea(Common::SeekableReadStream *s, HotArea &dst) const {
 		dst._objInteractionRectNum = 0;
 	}
 	readConditionList(s, dst.enableConditions);
-	readOpList(s, dst.onRClickOps);
-	readOpList(s, dst.onLDownOps);
-	readOpList(s, dst.onLClickOps);
+	readOpList(s, dst.onLookOps);
+	readOpList(s, dst.onPickUpOps);
+	readOpList(s, dst.onUseOps);
 	return !s->err();
 }
 
@@ -511,7 +519,8 @@ bool SDSScene::_dlgWithFlagLo8IsClosing = false;
 DialogFlags SDSScene::_sceneDialogFlags = kDlgFlagNone;
 
 SDSScene::SDSScene() : _num(-1), _dragItem(nullptr), _shouldClearDlg(false), _ignoreMouseUp(false),
-_field6_0x14(0), _rbuttonDown(false), _lbuttonDown(false), _lookMode(0), _lbuttonDownWithDrag(false) {
+_field6_0x14(0), _rbuttonDown(false), _lbuttonDown(false), _lookMode(0), _lbuttonDownWithDrag(false),
+_mouseDownArea(nullptr), _mouseDownCounter(0) {
 }
 
 bool SDSScene::load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor) {
@@ -596,6 +605,10 @@ void SDSScene::unload() {
 	_conversation.unloadData();
 	_conditionalOps.clear();
 	_sceneDialogFlags = kDlgFlagNone;
+	_mouseDownArea = nullptr;
+	_mouseDownCounter = 0;
+	_rbuttonDown = false;
+	_lbuttonDown = false;
 }
 
 
@@ -1193,7 +1206,7 @@ bool SDSScene::drawAndUpdateDialogs(Graphics::ManagedSurface *dst) {
 	return retval;
 }
 
-void SDSScene::mouseMoved(const Common::Point &pt) {
+void SDSScene::mouseUpdate(const Common::Point &pt) {
 	Dialog *dlg = getVisibleDialog();
 	const HotArea *area = findAreaUnderMouse(pt);
 	DgdsEngine *engine = DgdsEngine::getInstance();
@@ -1210,6 +1223,21 @@ void SDSScene::mouseMoved(const Common::Point &pt) {
 
 	GameItem *activeItem = engine->getGDSScene()->getActiveItem();
 
+	if (_lbuttonDown || _rbuttonDown) {
+		_mouseDownCounter++;
+		if (_mouseDownCounter > MOUSE_DOWN_TIMEOUT) {
+			if (_lbuttonDown && !_rbuttonDown)
+				doPickUp(_mouseDownArea);
+			if (activeItem && _rbuttonDown) {
+				// Start target mode
+				cursorNum = activeItem->_altCursor;
+			}
+		}
+	} else {
+		_mouseDownArea = nullptr;
+		_mouseDownCounter = 0;
+	}
+
 	if (_dragItem) {
 		if (area && area->_objInteractionRectNum == 1 && !(_dragItem->_flags & kItemStateWasInInv)) {
 			// drag over Willy Beamish
@@ -1218,11 +1246,10 @@ void SDSScene::mouseMoved(const Common::Point &pt) {
 		}
 
 		cursorNum = _dragItem->_iconNum;
-	} else if (activeItem) {
-		// In HOC or Dragon you need to hold down right button to get the
-		// target cursor.  In Willy Beamish it is look mode 2 (target)
-		if (_rbuttonDown || _lookMode == 2)
-			cursorNum = activeItem->_altCursor;
+	} else if (activeItem && _lookMode == 2) {
+		// For Willy Beamish, target mode is sticky (look mode 2), in
+		// other games it's only while mouse is down
+		cursorNum = activeItem->_altCursor;
 	}
 
 	engine->setMouseCursor(cursorNum);
@@ -1248,17 +1275,19 @@ void SDSScene::mouseLDown(const Common::Point &pt) {
 	if (_lookMode)
 		return;
 
-	HotArea *area = findAreaUnderMouse(pt);
+	_mouseDownArea = findAreaUnderMouse(pt);
+}
+
+void SDSScene::doPickUp(HotArea *area) {
 	if (!area)
 		return;
-
-	debug(9, "Mouse LDown on area %d (%d,%d,%d,%d) cursor %d cursor2 %d. Run %d ops", area->_num,
+	debug(9, "doPickUp on area %d (%d,%d,%d,%d) cursor %d cursor2 %d. Run %d ops", area->_num,
 			area->_rect.x, area->_rect.y, area->_rect.width, area->_rect.height,
-			area->_cursorNum, area->_cursorNum2, area->onLDownOps.size());
+			area->_cursorNum, area->_cursorNum2, area->onPickUpOps.size());
 
 	DgdsEngine *engine = DgdsEngine::getInstance();
-	int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnStartDrag();
-	runOps(area->onLDownOps, addmins);
+	int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnPickUp();
+	runOps(area->onPickUpOps, addmins);
 	GameItem *item = dynamic_cast<GameItem *>(area);
 	if (item) {
 		_dragItem = item;
@@ -1267,6 +1296,9 @@ void SDSScene::mouseLDown(const Common::Point &pt) {
 		if (item->_iconNum)
 			engine->setMouseCursor(item->_iconNum);
 	}
+
+	_mouseDownArea = nullptr;
+	_mouseDownCounter = 0;
 }
 
 static bool _isInRect(const Common::Point &pt, const DgdsRect rect) {
@@ -1307,27 +1339,84 @@ void SDSScene::mouseLUp(const Common::Point &pt) {
 	}
 
 	if (_lookMode == 1) {
+		// Sticky look mode is on
 		rightButtonAction(pt);
 		return;
 	}
 
-	const HotArea *area = findAreaUnderMouse(pt);
-	if (!area)
+	const HotArea *area = _mouseDownArea;
+	_mouseDownArea = nullptr;
+	_mouseDownCounter = 0;
+
+	if (area) {
+		debug(9, "Mouse LUp on area %d (%d,%d,%d,%d) cursor %d cursor2 %d", area->_num, area->_rect.x, area->_rect.y,
+			  area->_rect.width, area->_rect.height, area->_cursorNum, area->_cursorNum2);
+	} else {
+		debug(9, "Mouse LUp at %d,%d with no active area", pt.x, pt.y);
+	}
+
+	const GameItem *activeItem = engine->getGDSScene()->getActiveItem();
+
+	if (activeItem && (_rbuttonDown || _lookMode == 2)) {
+		bothButtonAction(pt);
+	} else {
+		leftButtonAction(area);
+	}
+}
+
+void SDSScene::bothButtonAction(const Common::Point &pt) {
+	DgdsEngine *engine = DgdsEngine::getInstance();
+	GDSScene *gds = engine->getGDSScene();
+	const GameItem *activeItem = gds->getActiveItem();
+
+	debug(1, " --> exec both-button click ops with active item %d", activeItem->_num);
+	if (!runOps(activeItem->onBothButtonsOps))
 		return;
 
-	debug(9, "Mouse LUp on area %d (%d,%d,%d,%d) cursor %d cursor2 %d", area->_num, area->_rect.x, area->_rect.y,
-		  area->_rect.width, area->_rect.height, area->_cursorNum, area->_cursorNum2);
+	//
+	// Both-button click interactions are run on *all* things the mouse
+	// ignoring their "active" status.
+	//
 
-	if (!_rbuttonDown)
-		engine->setMouseCursor(area->_cursorNum);
+	for (const auto &hotArea : _hotAreaList) {
+		if (!hotArea._rect.contains(pt))
+			continue;
 
+		const ObjectInteraction *i = _findInteraction(_objInteractions2, activeItem->_num, hotArea._num);
+		if (!i)
+			continue;
+
+		debug(1, " --> exec %d both-click ops for item-area combo %d", i->opList.size(), activeItem->_num);
+		if (!runOps(i->opList, engine->getGameGlobals()->getGameMinsToAddOnObjInteraction()))
+			return;
+	}
+
+	for (const auto &item : gds->getGameItems()) {
+		if (item._inSceneNum != _num || !item._rect.contains(pt))
+			continue;
+
+		const ObjectInteraction *i = _findInteraction(gds->getObjInteractions2(), activeItem->_num, item._num);
+		if (!i)
+			continue;
+
+		debug(1, " --> exec %d both-click ops for item-item combo %d", i->opList.size(), activeItem->_num);
+		if (!runOps(i->opList, engine->getGameGlobals()->getGameMinsToAddOnObjInteraction()))
+			return;
+	}
+}
+
+void SDSScene::leftButtonAction(const HotArea *area) {
+	if (!area)
+		return;
+
+	DgdsEngine *engine = DgdsEngine::getInstance();
 	GDSScene *gds = engine->getGDSScene();
 
 	if (area->_num == 0 || area->_objInteractionRectNum == 1) {
-		debug(1, "Mouseup on inventory.");
+		debug(1, "Mouse LUp on inventory.");
 		engine->getInventory()->open();
-	} else if (area->_num == 0xffff) {
-		debug(1, "Mouseup on swap characters.");
+	} else if (area && area->_num == 0xffff) {
+		debug(1, "Mouse LUp on swap characters.");
 		bool haveInvBtn = _hotAreaList.size() && _hotAreaList.front()._num == 0;
 		if (haveInvBtn)
 			removeInvButtonFromHotAreaList();
@@ -1337,30 +1426,9 @@ void SDSScene::mouseLUp(const Common::Point &pt) {
 		if (haveInvBtn)
 			addInvButtonToHotAreaList();
 	} else {
-		const GameItem *activeItem = engine->getGDSScene()->getActiveItem();
-		if (activeItem && (_rbuttonDown || _lookMode == 2)) {
-			debug(1, " --> exec both-button click ops for area %d", area->_num);
-			// A both-button-click event, find the interaction list.
-			if (!runOps(activeItem->onBothButtonsOps))
-				return;
-
-			const GameItem *destItem = dynamic_cast<const GameItem *>(area);
-			const ObjectInteraction *i;
-			if (destItem) {
-				i =_findInteraction(gds->getObjInteractions2(), activeItem->_num, area->_num);
-			} else {
-				i = _findInteraction(_objInteractions2, activeItem->_num, area->_num);
-			}
-			if (i) {
-				debug(1, " --> exec %d both-click ops for item combo %d", i->opList.size(), activeItem->_num);
-				if (!runOps(i->opList, engine->getGameGlobals()->getGameMinsToAddOnObjInteraction()))
-					return;
-			}
-		} else {
-			debug(1, " --> exec %d L click ops for area %d", area->onLClickOps.size(), area->_num);
-			int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
-			runOps(area->onLClickOps, addmins);
-		}
+		debug(1, " --> exec %d use ops for area %d", area->onUseOps.size(), area->_num);
+		int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnUse();
+		runOps(area->onUseOps, addmins);
 	}
 }
 
@@ -1384,7 +1452,7 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
 			dropSceneNum = 2;
 	}
 
-	runOps(dragItem->onDragFinishedOps, globals->getGameMinsToAddOnDragFinished());
+	runOps(dragItem->onDragFinishedOps, globals->getGameMinsToAddOnDrop());
 
 	// Check for dropping on an object
 	for (const auto &item : gdsScene->getGameItems()) {
@@ -1452,8 +1520,8 @@ void SDSScene::mouseRDown(const Common::Point &pt) {
 		return;
 	}
 	_rbuttonDown = true;
-	// Ensure mouse cursor is updated
-	mouseMoved(pt);
+	_mouseDownArea = findAreaUnderMouse(pt);
+	mouseUpdate(pt);
 }
 
 void SDSScene::mouseRUp(const Common::Point &pt) {
@@ -1472,11 +1540,13 @@ void SDSScene::mouseRUp(const Common::Point &pt) {
 		} else {
 			_lookMode = !_lookMode;
 		}
-		mouseMoved(pt);
+		mouseUpdate(pt);
 	} else {
 		// Other games do right-button action straight away.
-		mouseMoved(pt);
-		rightButtonAction(pt);
+		bool doAction = _mouseDownCounter <= MOUSE_DOWN_TIMEOUT;
+		mouseUpdate(pt);
+		if (doAction)
+			rightButtonAction(pt);
 	}
 }
 
@@ -1498,12 +1568,19 @@ void SDSScene::rightButtonAction(const Common::Point &pt) {
 		if (swapDlgFile && swapDlgNum)
 			showDialog(swapDlgFile, swapDlgNum);
 	} else {
-		int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
-		debug(1, "Mouse RUp on area %d, run %d ops (+%d mins)", area->_num, area->onRClickOps.size(), addmins);
-		runOps(area->onRClickOps, addmins);
+		doLook(area);
 	}
 }
 
+void SDSScene::doLook(const HotArea *area) {
+	if (!area)
+		return;
+	DgdsEngine *engine = DgdsEngine::getInstance();
+	int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnUse();
+	debug(1, "doLook on area %d, run %d ops (+%d mins)", area->_num, area->onLookOps.size(), addmins);
+	runOps(area->onLookOps, addmins);
+}
+
 Dialog *SDSScene::getVisibleDialog() {
 	for (auto &dlg : _dialogs) {
 		if (dlg.hasFlag(kDlgFlagVisible) && !dlg.hasFlag(kDlgFlagOpening)) {
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 3e11f5db8f7..07279706bc9 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -54,9 +54,9 @@ public:
 	uint16 _objInteractionRectNum;
 
 	Common::Array<SceneConditions> enableConditions;
-	Common::Array<SceneOp> onRClickOps;
-	Common::Array<SceneOp> onLDownOps;
-	Common::Array<SceneOp> onLClickOps;
+	Common::Array<SceneOp> onLookOps;
+	Common::Array<SceneOp> onPickUpOps;
+	Common::Array<SceneOp> onUseOps;
 
 	virtual ~HotArea() {}
 
@@ -289,7 +289,7 @@ public:
 	bool drawAndUpdateDialogs(Graphics::ManagedSurface *dst);
 	bool checkForClearedDialogs();
 
-	void mouseMoved(const Common::Point &pt);
+	void mouseUpdate(const Common::Point &pt);
 	void mouseLDown(const Common::Point &pt);
 	void mouseLUp(const Common::Point &pt);
 	void mouseRDown(const Common::Point &pt);
@@ -348,8 +348,13 @@ protected:
 private:
 	Dialog *getVisibleDialog();
 	bool readTalkData(Common::SeekableReadStream *s, TalkData &dst);
+	void leftButtonAction(const HotArea *area);
+	void bothButtonAction(const Common::Point &pt);
 	void rightButtonAction(const Common::Point &pt);
 
+	void doPickUp(HotArea *area);
+	void doLook(const HotArea *area);
+
 	int _num;
 	Common::Array<SceneOp> _enterSceneOps;
 	Common::Array<SceneOp> _leaveSceneOps;
@@ -378,6 +383,9 @@ private:
 	bool _rbuttonDown;
 	bool _lbuttonDownWithDrag;
 
+	HotArea *_mouseDownArea;
+	int _mouseDownCounter;
+
 	/// Only changes in beamish - toggle between use (0), look (1) and target (2)
 	int16 _lookMode;
 




More information about the Scummvm-git-logs mailing list