From 52405a9d599412545efd3bc3ace8342ae571ccd0 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Tue, 7 Mar 2023 23:03:06 -0800 Subject: [PATCH] Win32: Fix invalid hat bit mask being accepted It is reportedly possible to get opposing directions of an XInput DPad bit mask set simultaneously with some controllers. This commit ensures that those values are not passed on to other parts of GLFW. This commit is based on the PR #2291 by @ PeterJohnson but with the following changes: - moved XInput-specific special case to XInput implementation - attempt to preserve data by only masking out the invalid axis - admin (credit, changelog, commit message) Closes #2291 --- CONTRIBUTORS.md | 1 + README.md | 1 + src/win32_joystick.c | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1b9a277a..afd91a01 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -102,6 +102,7 @@ video tutorials. - JannikGM - Erik S. V. Jansson - jjYBdx4IL + - Peter Johnson - Toni Jovanoski - Arseny Kapoulkine - Cem Karan diff --git a/README.md b/README.md index 797ffd17..7045e75c 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: Right shift emitted `GLFW_KEY_UNKNOWN` when using a CJK IME (#2050) - [Win32] Bugfix: `glfwWaitEventsTimeout` did not return for some sent messages (#2408) - [Win32] Bugfix: Fix pkg-config for dynamic library on Windows (#2386, #2420) + - [Win32] Bugfix: XInput could reportedly provide invalid DPad bit masks (#2291) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Moved main menu creation to GLFW initialization time (#1649) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 4e83577a..eae44edf 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -736,6 +736,13 @@ GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode) if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) dpad |= GLFW_HAT_LEFT; + // Treat invalid combinations as neither being pressed + // while preserving what data can be preserved + if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT)) + dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT); + if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN)) + dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN); + _glfwInputJoystickHat(js, 0, dpad); }