From 80d45cdfd7d17fd45a3bf323fb02604e71e3ea21 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 (cherry picked from commit 52405a9d599412545efd3bc3ace8342ae571ccd0) --- 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 ee473382..d6f0bec8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -100,6 +100,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 080ab1e2..462c7d63 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ information on what to include when reporting a bug. - Bugfix: Failure to make a newly created context current could cause segfault (#2327) - [Win32] Fix pkg-config for dynamic library on Windows (#2386, #2420) - [Win32] Bugfix: `glfwWaitEventsTimeout` did not return for some sent messages (#2408) + - [Win32] Bugfix: XInput could reportedly provide invalid DPad bit masks (#2291) - [Wayland] Added improved fallback window decorations via libdecor (#1639,#1693) - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Wayland] Disabled alpha channel for opaque windows on systems lacking diff --git a/src/win32_joystick.c b/src/win32_joystick.c index f471f0a9..2eb25da4 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -736,6 +736,13 @@ int _glfwPlatformPollJoystick(_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); }