restore Y/RY axis inversion for XInput controllers for now, pending
a more permanent upstream solution to this
https://github.com/libsdl-org/SDL/issues/7609#issuecomment-1522831640

backport D-pad calculation by bitwise operation
https://github.com/libsdl-org/SDL/pull/7996

break from axis/hat assignments to not override hat with 0 after HUG_DPAD_*

Index: src/joystick/bsd/SDL_bsdjoystick.c
--- src/joystick/bsd/SDL_bsdjoystick.c.orig
+++ src/joystick/bsd/SDL_bsdjoystick.c
@@ -93,40 +93,11 @@
 #define HUG_DPAD_RIGHT 0x92
 #define HUG_DPAD_LEFT  0x93
 
-#define HAT_CENTERED  0x00
 #define HAT_UP        0x01
 #define HAT_RIGHT     0x02
 #define HAT_DOWN      0x04
 #define HAT_LEFT      0x08
-#define HAT_RIGHTUP   (HAT_RIGHT | HAT_UP)
-#define HAT_RIGHTDOWN (HAT_RIGHT | HAT_DOWN)
-#define HAT_LEFTUP    (HAT_LEFT | HAT_UP)
-#define HAT_LEFTDOWN  (HAT_LEFT | HAT_DOWN)
 
-/* calculate the value from the state of the dpad */
-int dpad_to_sdl(Sint32 *dpad)
-{
-    if (dpad[2]) {
-        if (dpad[0])
-            return HAT_RIGHTUP;
-        else if (dpad[1])
-            return HAT_RIGHTDOWN;
-        else
-            return HAT_RIGHT;
-    } else if (dpad[3]) {
-        if (dpad[0])
-            return HAT_LEFTUP;
-        else if (dpad[1])
-            return HAT_LEFTDOWN;
-        else
-            return HAT_LEFT;
-    } else if (dpad[0]) {
-        return HAT_UP;
-    } else if (dpad[1]) {
-        return HAT_DOWN;
-    }
-    return HAT_CENTERED;
-}
 #endif
 
 struct report
@@ -716,27 +687,55 @@ static void BSD_JoystickUpdate(SDL_Joystick *joy)
                         /* scaleaxe */
                         v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
                         v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * (v - hitem.logical_minimum)) / (hitem.logical_maximum - hitem.logical_minimum)) + SDL_JOYSTICK_AXIS_MIN;
+#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
                         SDL_PrivateJoystickAxis(joy, naxe, v);
+#ifdef __OpenBSD__
+                        break;
+#endif
                     } else if (usage == HUG_HAT_SWITCH) {
                         v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
                         SDL_PrivateJoystickHat(joy, 0,
                                                hatval_to_sdl(v) -
                                                    hitem.logical_minimum);
+#ifdef __OpenBSD__
+                        break;
+#endif
                     }
 #ifdef __OpenBSD__
-                    else if (usage == HUG_DPAD_UP) {
+                    /* here D-pad directions are reported like separate buttons.
+                     * calculate the SDL hat value from the 4 separate values.
+                     */
+                    switch (usage) {
+                    case HUG_DPAD_UP:
                         dpad[0] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
-                        SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
-                    } else if (usage == HUG_DPAD_DOWN) {
+                        break;
+                    case HUG_DPAD_DOWN:
                         dpad[1] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
-                        SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
-                    } else if (usage == HUG_DPAD_RIGHT) {
+                        break;
+                    case HUG_DPAD_RIGHT:
                         dpad[2] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
-                        SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
-                    } else if (usage == HUG_DPAD_LEFT) {
+                        break;
+                    case HUG_DPAD_LEFT:
                         dpad[3] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem);
-                        SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
+                        break;
+                    //default:
+                        // no-op
                     }
+                    SDL_PrivateJoystickHat(joy, 0, (dpad[0] * HAT_UP) |
+                                                   (dpad[1] * HAT_DOWN) |
+                                                   (dpad[2] * HAT_RIGHT) |
+                                                   (dpad[3] * HAT_LEFT) );
 #endif
                     break;
                 }
