Browse Source

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

* Fixing gamepad buttons in drm backend

* Remove trailing spaces

* Axis enumeration now works properly
pull/3891/head
MrMugame 9 months ago
committed by GitHub
parent
commit
eda239cc97
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
2 changed files with 120 additions and 50 deletions
  1. +118
    -48
      src/platforms/rcore_drm.c
  2. +2
    -2
      src/raylib.h

+ 118
- 48
src/platforms/rcore_drm.c View File

@ -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, p">(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 View File

@ -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

Loading…
Cancel
Save