Fixed bug 4436 - [OpenBSD] fix D-pad
authorSam Lantinga <slouken@libsdl.org>
Sun, 19 May 2019 11:56:26 -0700
changeset 1273864dabb27041d
parent 12737 b7320ef610b5
child 12739 ae1dd7bee797
Fixed bug 4436 - [OpenBSD] fix D-pad

Thomas Frohwein

Hi,

If a gamepad lists the Dpad as 4 buttons (Dpad Up,Down, Left, Right) like with the Xbox 360 gamepad / XInput report descriptor used by OpenBSD (https://github.com/openbsd/src/blob/master/sys/dev/usb/uhid_rdesc.h#L184), this is not recognized by the SDL BSD backend and no hat or any other listing for the D-pad exists, e.g. in sdl2-jstest (https://gitlab.com/sdl-jstest/sdl-jstest).

The attached diff fixes this and makes the D-pad on my Xbox 360 and Logitech F310 controllers usable. It adds a hat to nhats when usage HUG_DPAD_UP is found, reads the state of the D-pad buttons into array dpad[], and turns the value of dpad[] into an SDL hat direction (dpad_to_sdl()).

Tested and works with Xbox 360 controller and Logitech F310 in XInput mode. Software-side tested with sdl2-jstest and Owlboy where this worked without problems or regressions.

I don't know if this would be applicable to other *BSDs and don't have an install to test it with, therefore wrapped it in __OpenBSD__ ifdefs.

Thanks,

thfr
src/joystick/bsd/SDL_sysjoystick.c
     1.1 --- a/src/joystick/bsd/SDL_sysjoystick.c	Mon Dec 03 20:14:35 2018 +0200
     1.2 +++ b/src/joystick/bsd/SDL_sysjoystick.c	Sun May 19 11:56:26 2019 -0700
     1.3 @@ -80,6 +80,49 @@
     1.4  #define MAX_JOY_JOYS    2
     1.5  #define MAX_JOYS    (MAX_UHID_JOYS + MAX_JOY_JOYS)
     1.6  
     1.7 +#ifdef __OpenBSD__
     1.8 +
     1.9 +#define HUG_DPAD_UP         0x90
    1.10 +#define HUG_DPAD_DOWN       0x91
    1.11 +#define HUG_DPAD_RIGHT      0x92
    1.12 +#define HUG_DPAD_LEFT       0x93
    1.13 +
    1.14 +#define HAT_CENTERED        0x00
    1.15 +#define HAT_UP              0x01
    1.16 +#define HAT_RIGHT           0x02
    1.17 +#define HAT_DOWN            0x04
    1.18 +#define HAT_LEFT            0x08
    1.19 +#define HAT_RIGHTUP         (HAT_RIGHT|HAT_UP)
    1.20 +#define HAT_RIGHTDOWN       (HAT_RIGHT|HAT_DOWN)
    1.21 +#define HAT_LEFTUP          (HAT_LEFT|HAT_UP)
    1.22 +#define HAT_LEFTDOWN        (HAT_LEFT|HAT_DOWN)
    1.23 +
    1.24 +/* calculate the value from the state of the dpad */
    1.25 +int
    1.26 +dpad_to_sdl(Sint32 *dpad)
    1.27 +{
    1.28 +    if (dpad[2]) {
    1.29 +        if (dpad[0])
    1.30 +            return HAT_RIGHTUP;
    1.31 +        else if (dpad[1])
    1.32 +            return HAT_RIGHTDOWN;
    1.33 +        else
    1.34 +            return HAT_RIGHT;
    1.35 +    } else if (dpad[3]) {
    1.36 +        if (dpad[0])
    1.37 +            return HAT_LEFTUP;
    1.38 +        else if (dpad[1])
    1.39 +            return HAT_LEFTDOWN;
    1.40 +        else
    1.41 +            return HAT_LEFT;
    1.42 +    } else if (dpad[0]) {
    1.43 +        return HAT_UP;
    1.44 +    } else if (dpad[1]) {
    1.45 +        return HAT_DOWN;
    1.46 +    }
    1.47 +    return HAT_CENTERED;
    1.48 +}
    1.49 +#endif
    1.50  
    1.51  struct report
    1.52  {
    1.53 @@ -434,7 +477,11 @@
    1.54                      int joyaxe = usage_to_joyaxe(usage);
    1.55                      if (joyaxe >= 0) {
    1.56                          hw->axis_map[joyaxe] = 1;
    1.57 -                    } else if (usage == HUG_HAT_SWITCH) {
    1.58 +                    } else if (usage == HUG_HAT_SWITCH
    1.59 +#ifdef __OpenBSD__
    1.60 +                               || usage == HUG_DPAD_UP
    1.61 +#endif
    1.62 +                               ) {
    1.63                          joy->nhats++;
    1.64                      }
    1.65                      break;
    1.66 @@ -487,6 +534,9 @@
    1.67      struct report *rep;
    1.68      int nbutton, naxe = -1;
    1.69      Sint32 v;
    1.70 +#ifdef __OpenBSD__
    1.71 +    Sint32 dpad[4] = {0, 0, 0, 0};
    1.72 +#endif
    1.73  
    1.74  #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
    1.75      struct joystick gameport;
    1.76 @@ -572,6 +622,16 @@
    1.77                                                     hatval_to_sdl(v) -
    1.78                                                     hitem.logical_minimum);
    1.79                          }
    1.80 +#ifdef __OpenBSD__
    1.81 +                        else if (usage == HUG_DPAD_UP)
    1.82 +                            dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
    1.83 +                        else if (usage == HUG_DPAD_DOWN)
    1.84 +                            dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
    1.85 +                        else if (usage == HUG_DPAD_RIGHT)
    1.86 +                            dpad[2] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
    1.87 +                        else if (usage == HUG_DPAD_LEFT)
    1.88 +                            dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
    1.89 +#endif
    1.90                          break;
    1.91                      }
    1.92                  case HUP_BUTTON:
    1.93 @@ -587,6 +647,9 @@
    1.94                  break;
    1.95              }
    1.96          }
    1.97 +#ifdef __OpenBSD__
    1.98 +        SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
    1.99 +#endif
   1.100          hid_end_parse(hdata);
   1.101      }
   1.102  }