enable gamecontroller GUID detection and GUID-based mapping

this makes prior workaround in SDL_gamecontroller.c obsolete that used
SDL_GAMECONTROLLERCONFIG environment variable and a fallback mapping;
so this is removed now.

tested with XBox 360/One, Logitech F310/Dual Action by me
testing with NEXT SNES controller and ok brynet@
This commit is contained in:
thfr 2021-01-23 17:47:43 +00:00
parent c465f9a263
commit 4f92a76afe
4 changed files with 147 additions and 55 deletions

View File

@ -1,11 +1,11 @@
# $OpenBSD: Makefile,v 1.33 2021/01/23 05:11:06 thfr Exp $
# $OpenBSD: Makefile,v 1.34 2021/01/23 17:47:43 thfr Exp $
COMMENT= cross-platform multimedia library
V= 2.0.14
DISTNAME= SDL2-${V}
PKGNAME= sdl2-${V}
REVISION= 0
REVISION= 1
CATEGORIES= devel
MASTER_SITES= https://www.libsdl.org/release/

View File

@ -1,50 +0,0 @@
$OpenBSD: patch-src_joystick_SDL_gamecontroller_c,v 1.7 2021/01/06 22:32:08 thfr Exp $
enable GameController API the Linux fallback way (by posing as Xbox360
controller)
also disable checking string "Xbox 360 Wireless Receiver", so for now
everything will be Xbox360 controller (works with generic joysticks)
map to SDL_GAMECONTROLLERCONFIG envvar if available
Use layout for XBox360 controller to maximize compatibility because
many controllers use this mapping
Index: src/joystick/SDL_gamecontroller.c
--- src/joystick/SDL_gamecontroller.c.orig
+++ src/joystick/SDL_gamecontroller.c
@@ -968,7 +968,7 @@ static char *SDL_PrivateGetControllerGUIDFromMappingSt
SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
SDL_memcpy(&pchGUID[0], "03000000", 8);
}
-#elif __MACOSX__
+#elif defined(__MACOSX__) || defined(__OpenBSD__)
if (SDL_strlen(pchGUID) == 32 &&
SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
@@ -1131,17 +1131,21 @@ static ControllerMapping_t *SDL_PrivateGetControllerMa
ControllerMapping_t *mapping;
mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE);
-#ifdef __LINUX__
+#if defined(__LINUX__) || defined(__OpenBSD__)
if (!mapping && name) {
- if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
- /* The Linux driver xpad.c maps the wireless dpad to buttons */
- SDL_bool existing;
+ /* The Linux driver xpad.c maps the wireless dpad to buttons */
+ SDL_bool existing;
+ char guid_str[1024];
+ SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
+ if (SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG) == NULL) {
mapping = SDL_PrivateAddMappingForGUID(guid,
-"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3",
+"none,XBox360 Controller,a:b7,b:b8,back:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b2,lefttrigger:a2,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b3,righttrigger:a5,rightx:a3,righty:a4~,start:b0,x:b9,y:b10",
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
+ } else {
+ mapping = SDL_PrivateAddMappingForGUID(guid, SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG), &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
}
-#endif /* __LINUX__ */
+#endif /* __LINUX__ || __OpenBSD__ */
if (!mapping && name && !SDL_IsJoystickWGI(guid)) {
if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {

View File

@ -0,0 +1,26 @@
$OpenBSD: patch-src_joystick_SDL_gamecontrollerdb_h,v 1.1 2021/01/23 17:47:43 thfr Exp $
enable controller detection by GUID on OpenBSD
use both LINUX and MACOSX guids to match both XInput and DInput devices
Index: src/joystick/SDL_gamecontrollerdb.h
--- src/joystick/SDL_gamecontrollerdb.h.orig
+++ src/joystick/SDL_gamecontrollerdb.h
@@ -338,7 +338,7 @@ static const char *s_ControllerMappings [] =
"030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
#endif
-#if defined(__MACOSX__)
+#if defined(__MACOSX__) || defined(__OpenBSD__)
"03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -479,7 +479,7 @@ static const char *s_ControllerMappings [] =
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,",
#endif
-#if defined(__LINUX__)
+#if defined(__LINUX__) || defined(__OpenBSD__)
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",

View File

@ -1,11 +1,42 @@
$OpenBSD: patch-src_joystick_bsd_SDL_bsdjoystick_c,v 1.1 2021/01/23 05:11:06 thfr Exp $
$OpenBSD: patch-src_joystick_bsd_SDL_bsdjoystick_c,v 1.2 2021/01/23 17:47:43 thfr Exp $
ujoy(4) device
assign buttons correctly
get GUID using USB_GET_DEVICEINFO
detect newer (XInput-style) gamecontroller if hitem.logical_maximum is
> 255; if so invert y axes
use ujoy(4) devices
Index: src/joystick/bsd/SDL_bsdjoystick.c
--- src/joystick/bsd/SDL_bsdjoystick.c.orig
+++ src/joystick/bsd/SDL_bsdjoystick.c
@@ -226,7 +226,7 @@ BSD_JoystickInit(void)
@@ -83,6 +83,9 @@
#ifdef __OpenBSD__
+#define DEV_USB 3 /* needed to get GUID from USB_GET_DEVICEINFO */
+#define GUID_LEN 32 /* GUID string has length 32 */
+
#define HUG_DPAD_UP 0x90
#define HUG_DPAD_DOWN 0x91
#define HUG_DPAD_RIGHT 0x92
@@ -192,6 +195,9 @@ struct joystick_hwdata
static char *joynames[MAX_JOYS];
static char *joydevnames[MAX_JOYS];
+#ifdef __OpenBSD__
+static char joyguids[MAX_JOYS][GUID_LEN];
+#endif
static int report_alloc(struct report *, struct report_desc *, int);
static void report_free(struct report *);
@@ -222,11 +228,14 @@ BSD_JoystickInit(void)
SDL_memset(joynames, 0, sizeof(joynames));
SDL_memset(joydevnames, 0, sizeof(joydevnames));
+#ifdef __OpenBSD__
+ SDL_memset(joyguids, 0, sizeof(char) * MAX_JOYS * GUID_LEN);
+#endif
for (i = 0; i < MAX_UHID_JOYS; i++) {
SDL_Joystick nj;
@ -14,3 +45,88 @@ Index: src/joystick/bsd/SDL_bsdjoystick.c
joynames[numjoysticks] = SDL_strdup(s);
@@ -356,6 +365,9 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index)
#endif
int fd;
int i;
+#ifdef __OpenBSD__
+ struct usb_device_info di;
+#endif
fd = open(path, O_RDONLY);
if (fd == -1) {
@@ -434,6 +446,17 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index)
}
desc_failed:
#endif
+#if defined(__OpenBSD__)
+ if (ioctl(fd, USB_GET_DEVICEINFO, &di) != -1) {
+ SDL_snprintf(joyguids[numjoysticks],
+ SDL_arraysize(joyguids[device_index]),
+ "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
+ DEV_USB & 0xFF, DEV_USB >> 8,
+ di.udi_vendorNo & 0xFF, di.udi_vendorNo >> 8,
+ di.udi_productNo & 0xFF, di.udi_productNo >> 8,
+ di.udi_releaseNo & 0xFF, di.udi_releaseNo >> 8);
+ }
+#endif
if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
goto usberr;
}
@@ -544,6 +567,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
Sint32 v;
#ifdef __OpenBSD__
Sint32 dpad[4] = {0, 0, 0, 0};
+ int actualbutton;
#endif
#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_)
@@ -618,6 +642,18 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
naxe = joy->hwdata->axis_map[joyaxe];
/* scaleaxe */
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
+#ifdef __OpenBSD__
+ /* XInput controllermapping relies on inverted Y axes.
+ * These devices have a 16bit signed space, as opposed
+ * to older DInput devices (8bit unsigned), so
+ * hitem.logical_maximum can be used to differentiate them.
+ */
+ if ((joyaxe == JOYAXE_Y || joyaxe == JOYAXE_RY)
+ && hitem.logical_maximum > 255) {
+ if (v != 0)
+ v = ~v;
+ }
+#endif
v -= (hitem.logical_maximum +
hitem.logical_minimum + 1) / 2;
v *= 32768 /
@@ -652,7 +688,12 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
}
case HUP_BUTTON:
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
+#ifdef __OpenBSD__
+ actualbutton = HID_USAGE(hitem.usage) - 1; /* sdl buttons are zero-based */
+ SDL_PrivateJoystickButton(joy, actualbutton, v);
+#else
SDL_PrivateJoystickButton(joy, nbutton, v);
+#endif
nbutton++;
break;
default:
@@ -697,11 +738,16 @@ static SDL_JoystickGUID
BSD_JoystickGetDeviceGUID( int device_index )
{
SDL_JoystickGUID guid;
+#ifdef __OpenBSD__
+ guid = SDL_JoystickGetGUIDFromString(joyguids[device_index]);
+ return guid;
+#else
/* the GUID is just the first 16 chars of the name for now */
const char *name = BSD_JoystickGetDeviceName( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
return guid;
+#endif
}
static int