[PATCH 1/1] winebus.sys: Implement SOCD neutral cleaning for hatswitches.

Rémi Bernon wine at gitlab.winehq.org
Mon Jun 13 11:03:15 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52841
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_sdl.c      | 27 +++++++++++++++------------
 dlls/winebus.sys/hid.c          | 11 +++++++++++
 dlls/winebus.sys/unix_private.h |  1 +
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 7dc47cdd518..5d810d25205 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -382,6 +382,8 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
     static const USAGE trigger_axis_usages[] = {HID_USAGE_GENERIC_Z, HID_USAGE_GENERIC_RZ};
     struct sdl_device *impl = impl_from_unix_device(iface);
     ULONG i, button_count = SDL_CONTROLLER_BUTTON_MAX - 1;
+    BOOL state;
+
     C_ASSERT(SDL_CONTROLLER_AXIS_MAX == 6);
 
     if (!hid_device_begin_report_descriptor(iface, &device_usage))
@@ -420,14 +422,15 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
     /* Initialize axis in the report */
     for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++)
         hid_device_set_abs_axis(iface, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i));
-    if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_UP))
-        hid_device_set_hatswitch_y(iface, 0, -1);
-    if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN))
-        hid_device_set_hatswitch_y(iface, 0, +1);
-    if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
-        hid_device_set_hatswitch_x(iface, 0, -1);
-    if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
-        hid_device_set_hatswitch_x(iface, 0, +1);
+
+    state = pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_UP);
+    hid_device_move_hatswitch(iface, 0, 0, state ? -1 : +1);
+    state = pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
+    hid_device_move_hatswitch(iface, 0, 0, state ? +1 : -1);
+    state = pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
+    hid_device_move_hatswitch(iface, 0, state ? -1 : +1, 0);
+    state = pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
+    hid_device_move_hatswitch(iface, 0, state ? +1 : -1, 0);
 
     return STATUS_SUCCESS;
 }
@@ -873,16 +876,16 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
             switch ((button = ie->button))
             {
             case SDL_CONTROLLER_BUTTON_DPAD_UP:
-                hid_device_set_hatswitch_y(iface, 0, ie->state ? -1 : 0);
+                hid_device_move_hatswitch(iface, 0, 0, ie->state ? -1 : +1);
                 break;
             case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
-                hid_device_set_hatswitch_y(iface, 0, ie->state ? +1 : 0);
+                hid_device_move_hatswitch(iface, 0, 0, ie->state ? +1 : -1);
                 break;
             case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
-                hid_device_set_hatswitch_x(iface, 0, ie->state ? -1 : 0);
+                hid_device_move_hatswitch(iface, 0, ie->state ? -1 : +1, 0);
                 break;
             case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
-                hid_device_set_hatswitch_x(iface, 0, ie->state ? +1 : 0);
+                hid_device_move_hatswitch(iface, 0, ie->state ? +1 : -1, 0);
                 break;
             case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 4; break;
             case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 5; break;
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 8ed8c752893..c5543e081ae 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -1453,6 +1453,17 @@ BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new
     return TRUE;
 }
 
+BOOL hid_device_move_hatswitch(struct unix_device *iface, ULONG index, LONG x, LONG y)
+{
+    struct hid_device_state *state = &iface->hid_device_state;
+    ULONG offset = state->hatswitch_start + index;
+    LONG old_x, old_y;
+    if (index > state->hatswitch_count) return FALSE;
+    hatswitch_decompose(state->report_buf[offset], &old_x, &old_y);
+    hatswitch_compose(old_x + x, old_y + y, &state->report_buf[offset]);
+    return TRUE;
+}
+
 BOOL hid_device_sync_report(struct unix_device *iface)
 {
     BOOL dropped;
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index f94a243d887..85eab6ccf5d 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -257,6 +257,7 @@ extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG
 extern BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set) DECLSPEC_HIDDEN;
 extern BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x) DECLSPEC_HIDDEN;
 extern BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y) DECLSPEC_HIDDEN;
+extern BOOL hid_device_move_hatswitch(struct unix_device *iface, ULONG index, LONG x, LONG y) DECLSPEC_HIDDEN;
 
 extern BOOL hid_device_sync_report(struct unix_device *iface) DECLSPEC_HIDDEN;
 extern void hid_device_drop_report(struct unix_device *iface) DECLSPEC_HIDDEN;
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/236



More information about the wine-devel mailing list