Updated dinput-joy-directX3 patchset

This commit is contained in:
Alistair Leslie-Hughes 2019-05-07 09:44:57 +10:00
parent b105021410
commit 29db3393bc
3 changed files with 210 additions and 3 deletions

View File

@ -0,0 +1,203 @@
From ad66457e277817f93fdc4b26b72919ea85147d8e Mon Sep 17 00:00:00 2001
From: Andrew Eikum <aeikum@codeweavers.com>
Date: Mon, 6 May 2019 10:14:24 -0500
Subject: [PATCH] dinput: Use heuristics to guess if a device is a gamepad or a
joystick
Fixes: https://bugs.winehq.org/show_bug.cgi?id=47123
---
dlls/dinput/dinput_private.h | 2 +-
dlls/dinput/joystick.c | 6 +++++-
dlls/dinput/joystick_linux.c | 38 +++++++++++++++++++++++++++++++++++++-
dlls/dinput/joystick_linuxinput.c | 27 ++++++++++++++++++++++++---
dlls/dinput/joystick_osx.c | 6 ++++--
5 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index c97a493..289b2f1 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -81,7 +81,7 @@ extern void _copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLS
extern HRESULT _configure_devices(IDirectInput8W *iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) DECLSPEC_HIDDEN;
extern WCHAR* get_mapping_path(const WCHAR *device, const WCHAR *username) DECLSPEC_HIDDEN;
-extern DWORD get_device_type(DWORD version) DECLSPEC_HIDDEN;
+extern DWORD get_device_type(DWORD version, BOOL is_joystick) DECLSPEC_HIDDEN;
#define IS_DIPROP(x) (((ULONG_PTR)(x) >> 16) == 0)
diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
index 9240ba3..6bd0dc9 100644
--- a/dlls/dinput/joystick.c
+++ b/dlls/dinput/joystick.c
@@ -76,8 +76,12 @@ DWORD typeFromGUID(REFGUID guid)
}
}
-DWORD get_device_type(DWORD version)
+DWORD get_device_type(DWORD version, BOOL is_joystick)
{
+ if (is_joystick)
+ return version >= 0x0800 ? DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
+ DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+
return version >= 0x0800 ? DI8DEVTYPE_GAMEPAD | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_GAMEPAD << 8);
}
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index fb1b878..6e22e14 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -84,6 +84,8 @@ struct JoyDev
int *dev_axes_map;
WORD vendor_id, product_id, bus_type;
+
+ BOOL is_joystick;
};
typedef struct JoystickImpl JoystickImpl;
@@ -177,6 +179,7 @@ static INT find_joystick_devices(void)
int fd;
struct JoyDev joydev, *new_joydevs;
BYTE axes_map[ABS_MAX + 1];
+ SHORT btn_map[KEY_MAX - BTN_MISC + 1];
snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
if ((fd = open(joydev.device, O_RDONLY)) == -1)
@@ -220,6 +223,39 @@ static INT find_joystick_devices(void)
joydev.button_count = 2;
#endif
+ joydev.is_joystick = FALSE;
+ if (ioctl(fd, JSIOCGBTNMAP, btn_map) < 0)
+ {
+ WARN("ioctl(%s,JSIOCGBTNMAP) failed: %s\n", joydev.device, strerror(errno));
+ }
+ else
+ {
+ INT j;
+ for (j = 0; !joydev.is_joystick && j < joydev.button_count; j++)
+ {
+ switch(btn_map[j])
+ {
+ case BTN_TRIGGER:
+ case BTN_THUMB:
+ case BTN_THUMB2:
+ case BTN_TOP:
+ case BTN_TOP2:
+ case BTN_PINKIE:
+ case BTN_BASE:
+ case BTN_BASE2:
+ case BTN_BASE3:
+ case BTN_BASE4:
+ case BTN_BASE5:
+ case BTN_BASE6:
+ case BTN_DEAD:
+ joydev.is_joystick = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
if (ioctl(fd, JSIOCGAXMAP, axes_map) < 0)
{
WARN("ioctl(%s,JSIOCGAXMAP) failed: %s\n", joydev.device, strerror(errno));
@@ -322,7 +358,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
lpddi->guidInstance = DInput_Wine_Joystick_GUID;
lpddi->guidInstance.Data3 = id;
lpddi->guidProduct = joystick_devices[id].guid_product;
- lpddi->dwDevType = get_device_type(version);
+ lpddi->dwDevType = get_device_type(version, joystick_devices[id].is_joystick);
/* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
if (joystick_devices[id].bus_type == BUS_USB &&
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index bc3c4de..d386403 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -100,7 +100,7 @@ struct JoyDev {
GUID guid;
GUID guid_product;
- BOOL has_ff;
+ BOOL has_ff, is_joystick;
int num_effects;
/* data returned by EVIOCGBIT for caps, EV_ABS, EV_KEY, and EV_FF */
@@ -243,6 +243,24 @@ static void find_joydevs(void)
continue;
}
+ /* in lieu of properly reporting HID usage, detect presence of
+ * "joystick buttons" and report those devices as joysticks instead of
+ * gamepads */
+ joydev.is_joystick =
+ test_bit(joydev.keybits, BTN_TRIGGER) ||
+ test_bit(joydev.keybits, BTN_THUMB) ||
+ test_bit(joydev.keybits, BTN_THUMB2) ||
+ test_bit(joydev.keybits, BTN_TOP) ||
+ test_bit(joydev.keybits, BTN_TOP2) ||
+ test_bit(joydev.keybits, BTN_PINKIE) ||
+ test_bit(joydev.keybits, BTN_BASE) ||
+ test_bit(joydev.keybits, BTN_BASE2) ||
+ test_bit(joydev.keybits, BTN_BASE3) ||
+ test_bit(joydev.keybits, BTN_BASE4) ||
+ test_bit(joydev.keybits, BTN_BASE5) ||
+ test_bit(joydev.keybits, BTN_BASE6) ||
+ test_bit(joydev.keybits, BTN_DEAD);
+
if (!(joydev.device = HeapAlloc(GetProcessHeap(), 0, strlen(buf) + 1)))
{
close(fd);
@@ -350,7 +368,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
lpddi->guidInstance = joydevs[id].guid;
lpddi->guidProduct = joydevs[id].guid_product;
lpddi->guidFFDriver = GUID_NULL;
- lpddi->dwDevType = get_device_type(version);
+ lpddi->dwDevType = get_device_type(version, joydevs[id].is_joystick);
/* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
if (joydevs[id].bus_type == BUS_USB &&
@@ -358,7 +376,10 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
{
lpddi->dwDevType |= DIDEVTYPE_HID;
lpddi->wUsagePage = 0x01; /* Desktop */
- lpddi->wUsage = 0x05; /* Game Pad */
+ if (joydevs[id].is_joystick)
+ lpddi->wUsage = 0x04; /* Joystick */
+ else
+ lpddi->wUsage = 0x05; /* Game Pad */
}
MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszInstanceName, MAX_PATH);
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index cb88b2f..1955cb7 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -967,7 +967,8 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
lpddi->guidInstance.Data3 = id;
lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
lpddi->guidProduct.Data1 = make_vid_pid(device);
- lpddi->dwDevType = get_device_type(version);
+ lpddi->dwDevType = get_device_type(version,
+ get_device_property_long(device, kIOHIDDeviceUsageKey) == kHIDUsage_GD_Joystick);
lpddi->dwDevType |= DIDEVTYPE_HID;
lpddi->wUsagePage = 0x01; /* Desktop */
lpddi->wUsage = 0x05; /* Game Pad */
@@ -1010,7 +1011,8 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
lpddi->guidInstance.Data3 = id;
lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
lpddi->guidProduct.Data1 = make_vid_pid(device);
- lpddi->dwDevType = get_device_type(version);
+ lpddi->dwDevType = get_device_type(version,
+ get_device_property_long(device, kIOHIDDeviceUsageKey) == kHIDUsage_GD_Joystick);
sprintf(friendly, "Joystick %d", id);
MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
/* get the device name */
--
1.9.1

View File

@ -1,2 +1,3 @@
Fixes: [36764] dinput: Allow DirectX version 3 to enumerate joysticks.
# Other cleanups for dinput.
Fixes: [47123] dinput: Use heuristics to guess if a device is a gamepad or a joystick.

View File

@ -3074,15 +3074,18 @@ fi
# |
# | This patchset fixes the following Wine bugs:
# | * [#36764] dinput: Allow DirectX version 3 to enumerate joysticks.
# | * [#47123] dinput: Use heuristics to guess if a device is a gamepad or a joystick.
# |
# | Modified files:
# | * dlls/dinput/joystick_linux.c, dlls/dinput/joystick_linuxinput.c, dlls/dinput/joystick_osx.c,
# | dlls/dinput/tests/joystick.c
# | * dlls/dinput/dinput_private.h, dlls/dinput/joystick.c, dlls/dinput/joystick_linux.c, dlls/dinput/joystick_linuxinput.c,
# | dlls/dinput/joystick_osx.c, dlls/dinput/tests/joystick.c
# |
if test "$enable_dinput_joy_directX3" -eq 1; then
patch_apply dinput-joy-directX3/0001-dinput-Allow-Enumeration-of-joysticks-with-DirectX-3.patch
patch_apply dinput-joy-directX3/0002--dinput-Use-heuristics-to-guess-if-a-device-is-a-game.patch
(
printf '%s\n' '+ { "Alistair Leslie-Hughes", "dinput: Allow Enumeration of joysticks with DirectX 3.", 1 },';
printf '%s\n' '+ { "Andrew Eikum", "dinput: Use heuristics to guess if a device is a gamepad or a joystick.", 1 },';
) >> "$patchlist"
fi