From 58773ad5cf6a79a6ec4fc2856aeb5fdf3f877368 Mon Sep 17 00:00:00 2001 From: Andrew Church Date: Mon, 25 Feb 2019 11:21:03 +1100 Subject: [PATCH] dinput: Allow remapping of joystick buttons Changed - Change the array to store the origial button. - Remove lookup loops. - Changed max Buttons to 128 to match DIJOYSTATE2 structure. Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=35815 --- dlls/dinput/joystick.c | 29 +++++++++++++++++++++++++++++ dlls/dinput/joystick_linux.c | 7 +++++-- dlls/dinput/joystick_linuxinput.c | 2 ++ dlls/dinput/joystick_osx.c | 2 ++ dlls/dinput/joystick_private.h | 4 ++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c index c85fda5cddb..21c81b0b683 100644 --- a/dlls/dinput/joystick.c +++ b/dlls/dinput/joystick.c @@ -921,6 +921,7 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ int tokens = 0; int axis = 0; int pov = 0; + int button; get_app_key(&hkey, &appkey); @@ -932,6 +933,34 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ TRACE("setting default deadzone to: \"%s\" %d\n", buffer, This->deadzone); } + for (button = 0; button < MAX_MAP_BUTTONS; button++) + This->button_map[button] = button; + + if (!get_config_key(hkey, appkey, "ButtonMap", buffer, sizeof(buffer))) + { + static const char *delim = ","; + int button = 0; + char *token; + + TRACE("ButtonMap = \"%s\"\n", buffer); + for (token = strtok(buffer, delim); + token != NULL && button < MAX_MAP_BUTTONS; + token = strtok(NULL, delim), button++) + { + char *s; + int value = strtol(token, &s, 10); + if (value < 0 || *s != '\0') + { + ERR("invalid button number: \"%s\"", token); + } + else + { + TRACE("mapping physical button %d to DInput button %d", value, button); + This->button_map[value] = button; + } + } + } + This->axis_map = HeapAlloc(GetProcessHeap(), 0, This->device_axis_count * sizeof(int)); if (!This->axis_map) return DIERR_OUTOFMEMORY; diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c index 5b54e352c20..7a7a59bcb58 100644 --- a/dlls/dinput/joystick_linux.c +++ b/dlls/dinput/joystick_linux.c @@ -735,10 +735,13 @@ static void joy_polldev( IDirectInputDevice8W *iface ) jse.type,jse.number,jse.value); if (jse.type & JS_EVENT_BUTTON) { + int button; if (jse.number >= This->generic.devcaps.dwButtons) return; - inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON; - This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00; + button = This->generic.button_map[jse.number]; + + inst_id = DIDFT_MAKEINSTANCE(button) | DIDFT_PSHBUTTON; + This->generic.js.rgbButtons[button] = value = jse.value ? 0x80 : 0x00; } else if (jse.type & JS_EVENT_AXIS) { diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index e3876a97b7f..aa56aa28d08 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -820,6 +820,8 @@ static void joy_polldev( IDirectInputDevice8W *iface ) if (btn & 0x80) { btn &= 0x7F; + btn = This->generic.button_map[btn]; + inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON; This->generic.js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00; } diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c index 9ee45e8a445..f88ee566781 100644 --- a/dlls/dinput/joystick_osx.c +++ b/dlls/dinput/joystick_osx.c @@ -891,6 +891,8 @@ static void poll_osx_device_state( IDirectInputDevice8W *iface ) TRACE("val %d oldVal %d newVal %d\n", val, oldVal, newVal); if (oldVal != newVal) { + button_idx = device->generic.button_map[button_idx]; + inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); if (device->generic.base.hEvent) diff --git a/dlls/dinput/joystick_private.h b/dlls/dinput/joystick_private.h index 32265edef03..fb0edfa7878 100644 --- a/dlls/dinput/joystick_private.h +++ b/dlls/dinput/joystick_private.h @@ -33,6 +33,9 @@ #define MAX_PROPS 164 struct JoystickGenericImpl; +/* Number of buttons for which to allow remapping */ +#define MAX_MAP_BUTTONS 128 + typedef void joy_polldev_handler( IDirectInputDevice8W *iface ); typedef struct JoystickGenericImpl @@ -47,6 +50,7 @@ typedef struct JoystickGenericImpl char *name; int device_axis_count; /* Total number of axes in the device */ int *axis_map; /* User axes remapping */ + int button_map[MAX_MAP_BUTTONS]; /* User button remapping */ LONG deadzone; /* Default dead-zone */ joy_polldev_handler *joy_polldev; -- 2.33.0