Rémi Bernon : winebus.sys: Implement SOCD neutral cleaning for hatswitches.
Alexandre Julliard
julliard at winehq.org
Mon Jun 13 16:02:16 CDT 2022
Module: wine
Branch: master
Commit: e2936702a47247f806478f16d4631516ca2c3e9f
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e2936702a47247f806478f16d4631516ca2c3e9f
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Fri May 20 21:05:36 2022 +0200
winebus.sys: Implement SOCD neutral cleaning for hatswitches.
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;
More information about the wine-cvs
mailing list