[Scummvm-git-logs] scummvm master -> b4083476d5a8645e781052e68918a32a2e821dbf

bgK bastien.bouclet at gmail.com
Sat May 30 17:41:32 UTC 2020


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:
b4083476d5 KEYMAPPER: Allow mapped actions without modifier keys when no mapped actions exist for current modifier keys


Commit: b4083476d5a8645e781052e68918a32a2e821dbf
    https://github.com/scummvm/scummvm/commit/b4083476d5a8645e781052e68918a32a2e821dbf
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2020-05-30T19:37:20+02:00

Commit Message:
KEYMAPPER: Allow mapped actions without modifier keys when no mapped actions exist for current modifier keys

Changed paths:
    backends/keymapper/keymap.cpp
    backends/keymapper/keymap.h
    backends/keymapper/keymapper.cpp
    backends/keymapper/keymapper.h


diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp
index 64b8c3ddaa..5e45e0a786 100644
--- a/backends/keymapper/keymap.cpp
+++ b/backends/keymapper/keymap.cpp
@@ -124,74 +124,108 @@ const Action *Keymap::findAction(const char *id) const {
 	return nullptr;
 }
 
-Keymap::ActionArray Keymap::getMappedActions(const Event &event) const {
+Keymap::KeymapMatch Keymap::getMappedActions(const Event &event, ActionArray &actions) const {
 	switch (event.type) {
 	case EVENT_KEYDOWN:
 	case EVENT_KEYUP: {
 		KeyState normalizedKeystate = KeyboardHardwareInputSet::normalizeKeyState(event.kbd);
 		HardwareInput hardwareInput = HardwareInput::createKeyboard("", normalizedKeystate, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		if (!actions.empty()) {
+			return kKeymapMatchExact;
+		}
+
+		if (normalizedKeystate.flags & KBD_NON_STICKY) {
+			// If no matching actions and non-sticky keyboard modifiers are down,
+			// check again for matches without the exact keyboard modifiers
+			for (HardwareActionMap::const_iterator itInput = _hwActionMap.begin(); itInput != _hwActionMap.end(); ++itInput) {
+				if (itInput->_key.type == kHardwareInputTypeKeyboard && itInput->_key.key.keycode == normalizedKeystate.keycode) {
+					int flags = itInput->_key.key.flags;
+					if (flags & KBD_NON_STICKY && (flags & normalizedKeystate.flags) == flags) {
+						actions.push_back(itInput->_value);
+						return kKeymapMatchPartial;
+					}
+				}
+			}
+
+			// Lastly check again for matches no non-sticky keyboard modifiers
+			normalizedKeystate.flags &= ~KBD_NON_STICKY;
+			hardwareInput = HardwareInput::createKeyboard("", normalizedKeystate, "");
+			actions.push_back(_hwActionMap[hardwareInput]);
+			return actions.empty() ? kKeymapMatchNone : kKeymapMatchPartial;
+		}
+		break;
 	}
 	case EVENT_LBUTTONDOWN:
 	case EVENT_LBUTTONUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_LEFT, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_RBUTTONDOWN:
 	case EVENT_RBUTTONUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_RIGHT, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_MBUTTONDOWN:
 	case EVENT_MBUTTONUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_MIDDLE, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case Common::EVENT_WHEELUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_WHEEL_UP, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case Common::EVENT_WHEELDOWN: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_WHEEL_DOWN, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_X1BUTTONDOWN:
 	case EVENT_X1BUTTONUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_X1, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_X2BUTTONDOWN:
 	case EVENT_X2BUTTONUP: {
 		HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_X2, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_JOYBUTTON_DOWN:
 	case EVENT_JOYBUTTON_UP: {
 		HardwareInput hardwareInput = HardwareInput::createJoystickButton("", event.joystick.button, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	case EVENT_JOYAXIS_MOTION: {
 		if (event.joystick.position != 0) {
 			bool positiveHalf = event.joystick.position >= 0;
 			HardwareInput hardwareInput = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, positiveHalf, "");
-			return _hwActionMap[hardwareInput];
+			actions.push_back(_hwActionMap[hardwareInput]);
 		} else {
 			// Axis position zero is part of both half axes, and triggers actions bound to both
-			Keymap::ActionArray actions;
 			HardwareInput hardwareInputPos = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, true, "");
 			HardwareInput hardwareInputNeg = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, false, "");
 			actions.push_back(_hwActionMap[hardwareInputPos]);
 			actions.push_back(_hwActionMap[hardwareInputNeg]);
-			return actions;
 		}
+		break;
 	}
 	case EVENT_CUSTOM_BACKEND_HARDWARE: {
 		HardwareInput hardwareInput = HardwareInput::createCustom("", event.customType, "");
-		return _hwActionMap[hardwareInput];
+		actions.push_back(_hwActionMap[hardwareInput]);
+		break;
 	}
 	default:
-		return ActionArray();
+		break;
 	}
+
+	return actions.empty() ? kKeymapMatchNone : kKeymapMatchExact;
 }
 
 void Keymap::setConfigDomain(ConfigManager::Domain *configDomain) {
diff --git a/backends/keymapper/keymap.h b/backends/keymapper/keymap.h
index 2f4d5680a2..2db3653147 100644
--- a/backends/keymapper/keymap.h
+++ b/backends/keymapper/keymap.h
@@ -72,6 +72,12 @@ public:
 		kKeymapTypeGame
 	};
 
+	enum KeymapMatch {
+		kKeymapMatchNone,
+		kKeymapMatchPartial,
+		kKeymapMatchExact
+	};
+
 	typedef Array<Action *> ActionArray;
 
 	Keymap(KeymapType type, const String &id, const String &description);
@@ -109,9 +115,10 @@ public:
 	/**
 	 * Find the Actions that a hardware input is mapped to
 	 * @param hardwareInput	the input that is mapped to the required Action
-	 * @return		an array containing pointers to the actions
+	 * @param actions an array containing pointers to the actions
+	 * @return	the matching status for the retieved actions
 	 */
-	ActionArray getMappedActions(const Event &event) const;
+	KeymapMatch getMappedActions(const Event &event, ActionArray &actions) const;
 
 	/**
 	 * Adds a new Action to this Map
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index 277a383b3c..1be29220d8 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -170,13 +170,40 @@ List<Event> Keymapper::mapEvent(const Event &ev) {
 
 	hardcodedEventMapping(ev);
 
-	List<Event> mappedEvents;
-	bool matchedAction = mapEvent(ev, _enabledKeymapType, mappedEvents);
-	if (!matchedAction) {
-		// If we found actions matching this input in the game / gui keymaps,
+	Keymap::ActionArray actions;
+	Keymap::KeymapMatch match = getMappedActions(ev, actions, _enabledKeymapType);
+	if (match != Keymap::kKeymapMatchExact) {
+		// If we found exact matching actions this input in the game / gui keymaps,
 		// no need to look at the global keymaps. An input resulting in actions
 		// from system and game keymaps would lead to unexpected user experience.
-		matchedAction = mapEvent(ev, Keymap::kKeymapTypeGlobal, mappedEvents);
+		Keymap::ActionArray globalActions;
+		match = getMappedActions(ev, globalActions, Keymap::kKeymapTypeGlobal);
+		if (match == Keymap::kKeymapMatchExact || actions.empty()) {
+			actions = globalActions;
+		}
+	}
+
+	bool matchedAction = !actions.empty();
+	List<Event> mappedEvents;
+	for (Keymap::ActionArray::const_iterator it = actions.begin(); it != actions.end(); it++) {
+		Event mappedEvent = executeAction(*it, ev);
+		if (mappedEvent.type == EVENT_INVALID) {
+			continue;
+		}
+
+		// In case we mapped a mouse event to something else, we need to generate an artificial
+		// mouse move event so event observers can keep track of the mouse position.
+		// Makes it possible to reliably use the mouse position from EventManager when consuming
+		// custom action events.
+		if (isMouseEvent(ev) && !isMouseEvent(mappedEvent)) {
+			Event fakeMouseEvent;
+			fakeMouseEvent.type  = EVENT_MOUSEMOVE;
+			fakeMouseEvent.mouse = ev.mouse;
+
+			mappedEvents.push_back(fakeMouseEvent);
+		}
+
+		mappedEvents.push_back(mappedEvent);
 	}
 
 	if (ev.type == EVENT_JOYAXIS_MOTION && ev.joystick.axis < ARRAYSIZE(_joystickAxisPreviouslyPressed)) {
@@ -195,42 +222,25 @@ List<Event> Keymapper::mapEvent(const Event &ev) {
 	return mappedEvents;
 }
 
-bool Keymapper::mapEvent(const Event &ev, Keymap::KeymapType keymapType, List<Event> &mappedEvents) {
-	bool matchedAction = false;
+Keymap::KeymapMatch Keymapper::getMappedActions(const Event &event, Keymap::ActionArray &actions, Keymap::KeymapType keymapType) const {
+	Keymap::KeymapMatch match = Keymap::kKeymapMatchNone;
 
 	for (uint i = 0; i < _keymaps.size(); i++) {
 		if (!_keymaps[i]->isEnabled() || _keymaps[i]->getType() != keymapType) {
 			continue;
 		}
 
-		Keymap::ActionArray actions = _keymaps[i]->getMappedActions(ev);
-		if (!actions.empty()) {
-			matchedAction = true;
-		}
-
-		for (Keymap::ActionArray::const_iterator it = actions.begin(); it != actions.end(); it++) {
-			Event mappedEvent = executeAction(*it, ev);
-			if (mappedEvent.type == EVENT_INVALID) {
-				continue;
-			}
-
-			// In case we mapped a mouse event to something else, we need to generate an artificial
-			// mouse move event so event observers can keep track of the mouse position.
-			// Makes it possible to reliably use the mouse position from EventManager when consuming
-			// custom action events.
-			if (isMouseEvent(ev) && !isMouseEvent(mappedEvent)) {
-				Event fakeMouseEvent;
-				fakeMouseEvent.type  = EVENT_MOUSEMOVE;
-				fakeMouseEvent.mouse = ev.mouse;
-
-				mappedEvents.push_back(fakeMouseEvent);
-			}
-
-			mappedEvents.push_back(mappedEvent);
+		Keymap::ActionArray array;
+		Keymap::KeymapMatch match2 = _keymaps[i]->getMappedActions(event, array);
+		if (match2 == match) {
+			actions.push_back(array);
+		} else if (match2 > match) {
+			match = match2;
+			actions.clear();
+			actions.push_back(array);
 		}
 	}
-
-	return matchedAction;
+	return match;
 }
 
 Keymapper::IncomingEventType Keymapper::convertToIncomingEventType(const Event &ev) const {
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index 26bc90d769..60ca0912a2 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -150,7 +150,7 @@ private:
 
 	bool _joystickAxisPreviouslyPressed[6];
 
-	bool mapEvent(const Event &ev, Keymap::KeymapType keymapType, List<Event> &mappedEvents);
+	Keymap::KeymapMatch getMappedActions(const Event &event, Keymap::ActionArray &actions, Keymap::KeymapType keymapType) const;
 	Event executeAction(const Action *act, const Event &incomingEvent);
 	EventType convertStartToEnd(EventType eventType);
 	IncomingEventType convertToIncomingEventType(const Event &ev) const;




More information about the Scummvm-git-logs mailing list