Applied OpenBSD patch http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/devel/sdl2/patches/patch-src_joystick_bsd_SDL_bsdjoystick_c?rev=1.5&content-type=text/plain&hideattic=1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
diff --git a/src/joystick/bsd/SDL_bsdjoystick.c b/src/joystick/bsd/SDL_bsdjoystick.c
index 1f4e122..b4f0bd2 100644
--- a/src/joystick/bsd/SDL_bsdjoystick.c
+++ b/src/joystick/bsd/SDL_bsdjoystick.c
@@ -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,6 +228,9 @@ 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;
@@ -366,6 +375,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 | O_CLOEXEC);
if (fd == -1) {
@@ -444,6 +456,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;
}
@@ -554,6 +577,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
Sint32 v;
#ifdef __OpenBSD__
Sint32 dpad[4] = {0, 0, 0, 0};
+ int actualbutton;
#endif
#if defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_)
@@ -628,6 +652,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 /
@@ -662,7 +698,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:
@@ -706,9 +747,15 @@ BSD_JoystickQuit(void)
static SDL_JoystickGUID
BSD_JoystickGetDeviceGUID(int device_index)
{
+#ifdef __OpenBSD__
+ SDL_JoystickGUID guid;
+ guid = SDL_JoystickGetGUIDFromString(joyguids[device_index]);
+ return guid;
+#else
/* the GUID is just the name for now */
const char *name = BSD_JoystickGetDeviceName(device_index);
return SDL_CreateJoystickGUIDForName(name);
+#endif
}
static int