Bladeren bron

Fixing gamepad buttons not working in drm backend (#3888)

* Fixing gamepad buttons in drm backend

* Remove trailing spaces

* Axis enumeration now works properly
MrMugame 1 jaar geleden
bovenliggende
commit
eda239cc97
2 gewijzigde bestanden met toevoegingen van 120 en 50 verwijderingen
  1. 118 48
      src/platforms/rcore_drm.c
  2. 2 2
      src/raylib.h

+ 118 - 48
src/platforms/rcore_drm.c

@@ -82,6 +82,10 @@
 
 #define DEFAULT_EVDEV_PATH       "/dev/input/"      // Path to the linux input events
 
+// So actually the biggest key is KEY_CNT but we only really map the keys up to
+// KEY_ALS_TOGGLE
+#define KEYMAP_SIZE KEY_ALS_TOGGLE
+
 //----------------------------------------------------------------------------------
 // Types and Structures Definition
 //----------------------------------------------------------------------------------
@@ -135,31 +139,13 @@ static PlatformData platform = { 0 };   // Platform specific data
 //----------------------------------------------------------------------------------
 // Local Variables Definition
 //----------------------------------------------------------------------------------
-// Scancode to keycode mapping for US keyboards
+
+// NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h
+// TODO: Complete the LUT with all unicode decimal values
 // TODO: Replace this with a keymap from the X11 to get the correct regional map for the keyboard:
 // Currently non US keyboards will have the wrong mapping for some keys
 // NOTE: Replacing this with the keymap from X11 would probably be useless, as people use the drm
 // backend to *avoid* X11
-static const int keymapUS[] = {
-    0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84,
-    89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96,
-    340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291,
-    292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325,
-    326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95,
-    335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261,
-    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127,
-    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
-    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
-    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
-    192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
-    211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
-    227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
-    243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0
-};
-
-// NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h
-// TODO: Complete the LUT with all unicode decimal values
 static const int evkeyToUnicodeLUT[] = {
     0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8, 0, 113, 119, 101, 114,
     116, 121, 117, 105, 111, 112, 0, 0, 13, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59,
@@ -167,6 +153,67 @@ static const int evkeyToUnicodeLUT[] = {
     // LUT currently incomplete, just mapped the most essential keys
 };
 
+// This is the map used to map any keycode returned from linux to a raylib code from 'raylib.h'
+// NOTE: Use short here to save a little memory
+static const short linuxToRaylibMap[KEYMAP_SIZE] = {
+    // We don't map those with designated initialization, because we would getting
+    // into loads of naming conflicts
+    0,   256, 49,  50,  51,  52,  53,  54,
+    55,  56,  57,  48,  45,  61,  259, 258,
+    81,  87,  69,  82,  84,  89,  85,  73,
+    79,  80,  91,  93,  257, 341, 65,  83,
+    68,  70,  71,  72,  74,  75,  76,  59,
+    39,  96,  340, 92,  90,  88,  67,  86,
+    66,  78,  77,  44,  46,  47,  344, 332,
+    342, 32,  280, 290, 291, 292, 293, 294,
+    295, 296, 297, 298, 299, 282, 281, 327,
+    328, 329, 333, 324, 325, 326, 334, 321,
+    322, 323, 320, 330, 0,   85,  86,  300,
+    301, 89,  90,  91,  92,  93,  94,  95,
+    335, 345, 331, 283, 346, 101, 268, 265,
+    266, 263, 262, 269, 264, 267, 260, 261,
+    112, 113, 114, 115, 116, 117, 118, 119,
+    120, 121, 122, 123, 124, 125, 347, 127,
+    128, 129, 130, 131, 132, 133, 134, 135,
+    136, 137, 138, 139, 140, 141, 142, 143,
+    144, 145, 146, 147, 148, 149, 150, 151,
+    152, 153, 154, 155, 156, 157, 158, 159,
+    160, 161, 162, 163, 164, 165, 166, 167,
+    168, 169, 170, 171, 172, 173, 174, 175,
+    176, 177, 178, 179, 180, 181, 182, 183,
+    184, 185, 186, 187, 188, 189, 190, 191,
+    192, 193, 194, 0,   0,   0,   0,   0,
+    200, 201, 202, 203, 204, 205, 206, 207,
+    208, 209, 210, 211, 212, 213, 214, 215,
+    216, 217, 218, 219, 220, 221, 222, 223,
+    224, 225, 226, 227, 228, 229, 230, 231,
+    232, 233, 234, 235, 236, 237, 238, 239,
+    240, 241, 242, 243, 244, 245, 246, 247,
+    248, 0,   0,   0,   0,   0,   0,   0,
+
+    // Gamepads are mapped according to:
+    // https://www.kernel.org/doc/html/next/input/gamepad.html
+    // Those mappings are standardized, but that doesn't mean people follow
+    // the standards, so this is more of an approximation
+    [BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP,
+    [BTN_DPAD_RIGHT] = GAMEPAD_BUTTON_LEFT_FACE_RIGHT,
+    [BTN_DPAD_DOWN] = GAMEPAD_BUTTON_LEFT_FACE_DOWN,
+    [BTN_DPAD_LEFT] = GAMEPAD_BUTTON_LEFT_FACE_LEFT,
+    [BTN_Y] = GAMEPAD_BUTTON_RIGHT_FACE_UP,
+    [BTN_B] = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT,
+    [BTN_A] = GAMEPAD_BUTTON_RIGHT_FACE_DOWN,
+    [BTN_X] = GAMEPAD_BUTTON_RIGHT_FACE_LEFT,
+    [BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,
+    [BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,
+    [BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
+    [BTN_TR2] GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
+    [BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,
+    [BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,
+    [BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,
+    [BTN_THUMBL] = GAMEPAD_BUTTON_LEFT_THUMB,
+    [BTN_THUMBR] = GAMEPAD_BUTTON_RIGHT_THUMB,
+};
+
 //----------------------------------------------------------------------------------
 // Module Internal Functions Declaration
 //----------------------------------------------------------------------------------
@@ -574,7 +621,7 @@ void PollInputEvents(void)
     CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
     CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove;
     platform.eventWheelMove = (Vector2){ 0.0f, 0.0f };
-    
+
     for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
     {
         CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
@@ -1293,7 +1340,10 @@ static void ConfigureEvdevDevice(char *device)
 
     // Identify the device
     //-------------------------------------------------------------------------------------------------------
-    struct input_absinfo absinfo[ABS_CNT] = { 0 };
+    struct {
+        bool exist;
+        struct input_absinfo info;
+    } absinfo[ABS_CNT] = { 0 };
 
     // These flags aren't really a one of
     // Some devices could have properties we assosciate with keyboards as well as properties
@@ -1318,8 +1368,12 @@ static void ConfigureEvdevDevice(char *device)
         if (hasAbsXY)
         {
             absAxisCount += 2;
-            ioctl(fd, EVIOCGABS(ABS_X), &absinfo[ABS_X]);
-            ioctl(fd, EVIOCGABS(ABS_Y), &absinfo[ABS_Y]);
+
+            absinfo[ABS_X].exist = true;
+            absinfo[ABS_Y].exist = true;
+
+            ioctl(fd, EVIOCGABS(ABS_X), &absinfo[ABS_X].info);
+            ioctl(fd, EVIOCGABS(ABS_Y), &absinfo[ABS_Y].info);
         }
 
         // If it has any of these buttons it's a touch device
@@ -1340,10 +1394,11 @@ static void ConfigureEvdevDevice(char *device)
             {
                 if (TEST_BIT(absBits, axis))
                 {
+                    absinfo[axis].exist = true;
                     isGamepad = true;
                     absAxisCount++;
 
-                    ioctl(fd, EVIOCGABS(axis), &absinfo[axis]);
+                    ioctl(fd, EVIOCGABS(axis), &absinfo[axis].info);
                 }
             }
         }
@@ -1398,11 +1453,11 @@ static void ConfigureEvdevDevice(char *device)
 
         if (absAxisCount > 0)
         {
-            platform.absRange.x = absinfo[ABS_X].minimum;
-            platform.absRange.width = absinfo[ABS_X].maximum - absinfo[ABS_X].minimum;
+            platform.absRange.x = absinfo[ABS_X].info.minimum;
+            platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum;
 
-            platform.absRange.y = absinfo[ABS_Y].minimum;
-            platform.absRange.height = absinfo[ABS_Y].maximum - absinfo[ABS_Y].minimum;
+            platform.absRange.y = absinfo[ABS_Y].info.minimum;
+            platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum;
         }
     }
     else if (isGamepad && !isMouse && !isKeyboard && platform.gamepadCount < MAX_GAMEPADS)
@@ -1429,10 +1484,14 @@ static void ConfigureEvdevDevice(char *device)
             int axisIndex = 0;
             for (int axis = ABS_X; axis < ABS_PRESSURE; axis++)
             {
-                platform.gamepadAbsAxisRange[index][axisIndex][0] = absinfo[axisIndex].minimum;
-                platform.gamepadAbsAxisRange[index][axisIndex][1] = absinfo[axisIndex].maximum - absinfo[axisIndex].minimum;
+                if (absinfo[axis].exist)
+                {
+                    platform.gamepadAbsAxisRange[index][axisIndex][0] = absinfo[axisIndex].info.minimum;
+                    platform.gamepadAbsAxisRange[index][axisIndex][1] = absinfo[axisIndex].info.maximum - absinfo[axisIndex].info.minimum;
 
-                platform.gamepadAbsAxisMap[index][axis] = axisIndex++;
+                    platform.gamepadAbsAxisMap[index][axis] = axisIndex;
+                    axisIndex++;
+                }
             }
         }
     }
@@ -1475,7 +1534,7 @@ static void PollKeyboardEvents(void)
         {
 
             // Lookup the scancode in the keymap to get a keycode
-            keycode = keymapUS[event.code];
+            keycode = linuxToRaylibMap[event.code];
 
             // Make sure we got a valid keycode
             if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS))
@@ -1527,27 +1586,38 @@ static void PollGamepadEvents(void)
         {
             if (event.type == EV_KEY)
             {
-                if (event.code >= MAX_GAMEPAD_BUTTONS) continue;
+                if (event.code < KEYMAP_SIZE)
+                {
+                    short keycodeRaylib = linuxToRaylibMap[event.code];
 
-                TRACELOG(LOG_DEBUG, "INPUT: Gamepad %i button: %i, value: %i", i, event.code, event.value);
+                    TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0) ? "UP  " : "DOWN", event.code, keycodeRaylib);
 
-                // 1 - button pressed, 0 - button released
-                CORE.Input.Gamepad.currentButtonState[i][event.code] = event.value;
+                    if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS))
+                    {
+                        // 1 - button pressed, 0 - button released
+                        CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value;
 
-                if (event.value == 1) CORE.Input.Gamepad.lastButtonPressed = event.code;
-                else CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
+                        CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN;
+                    }
+                }
             }
             else if (event.type == EV_ABS)
             {
-                if (event.code >= MAX_GAMEPAD_AXIS) continue;
+                if (event.code < ABS_CNT)
+                {
+                    int axisRaylib = platform.gamepadAbsAxisMap[i][event.code];
 
-                TRACELOG(LOG_DEBUG, "INPUT: Gamepad %i axis: %i, value: %i", i, platform.gamepadAbsAxisMap[i][event.code], event.value);
+                    TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: Axis: %2i Value: %i", i, axisRaylib, event.value);
 
-                int min = platform.gamepadAbsAxisRange[i][event.code][0];
-                int range = platform.gamepadAbsAxisRange[i][event.code][1];
+                    if (axisRaylib < MAX_GAMEPAD_AXIS)
+                    {
+                        int min = platform.gamepadAbsAxisRange[i][event.code][0];
+                        int range = platform.gamepadAbsAxisRange[i][event.code][1];
 
-                // NOTE: Scaling of event.value to get values between -1..1
-                CORE.Input.Gamepad.axisState[i][platform.gamepadAbsAxisMap[i][event.code]] = (2 * (float)(event.value - min) / range) - 1;
+                        // NOTE: Scaling of event.value to get values between -1..1
+                        CORE.Input.Gamepad.axisState[i][axisRaylib] = (2 * (float)(event.value - min) / range) - 1;
+                    }
+                }
             }
         }
     }
@@ -1576,7 +1646,7 @@ static void PollMouseEvents(void)
                     CORE.Input.Mouse.previousPosition.x = 0.0f;
                 }
                 else CORE.Input.Mouse.currentPosition.x += event.value;
-                
+
                 CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;
                 touchAction = 2;    // TOUCH_ACTION_MOVE
             }
@@ -1589,7 +1659,7 @@ static void PollMouseEvents(void)
                     CORE.Input.Mouse.previousPosition.y = 0.0f;
                 }
                 else CORE.Input.Mouse.currentPosition.y += event.value;
-                
+
                 CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;
                 touchAction = 2;    // TOUCH_ACTION_MOVE
             }

+ 2 - 2
src/raylib.h

@@ -721,9 +721,9 @@ typedef enum {
     GAMEPAD_BUTTON_LEFT_FACE_DOWN,      // Gamepad left DPAD down button
     GAMEPAD_BUTTON_LEFT_FACE_LEFT,      // Gamepad left DPAD left button
     GAMEPAD_BUTTON_RIGHT_FACE_UP,       // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y)
-    GAMEPAD_BUTTON_RIGHT_FACE_RIGHT,    // Gamepad right button right (i.e. PS3: Square, Xbox: X)
+    GAMEPAD_BUTTON_RIGHT_FACE_RIGHT,    // Gamepad right button right (i.e. PS3: Circle, Xbox: B)
     GAMEPAD_BUTTON_RIGHT_FACE_DOWN,     // Gamepad right button down (i.e. PS3: Cross, Xbox: A)
-    GAMEPAD_BUTTON_RIGHT_FACE_LEFT,     // Gamepad right button left (i.e. PS3: Circle, Xbox: B)
+    GAMEPAD_BUTTON_RIGHT_FACE_LEFT,     // Gamepad right button left (i.e. PS3: Square, Xbox: X)
     GAMEPAD_BUTTON_LEFT_TRIGGER_1,      // Gamepad top/back trigger left (first), it could be a trailing button
     GAMEPAD_BUTTON_LEFT_TRIGGER_2,      // Gamepad top/back trigger left (second), it could be a trailing button
     GAMEPAD_BUTTON_RIGHT_TRIGGER_1,     // Gamepad top/back trigger right (one), it could be a trailing button