[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