Skip to content

Commit

Permalink
Fixing gamepad buttons not working in drm backend (#3888)
Browse files Browse the repository at this point in the history
* Fixing gamepad buttons in drm backend

* Remove trailing spaces

* Axis enumeration now works properly
  • Loading branch information
MrMugame committed Mar 29, 2024
1 parent 0712889 commit eda239c
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 50 deletions.
166 changes: 118 additions & 48 deletions src/platforms/rcore_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
//----------------------------------------------------------------------------------
Expand Down Expand Up @@ -135,38 +139,81 @@ 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,
39, 96, 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 32
// 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
//----------------------------------------------------------------------------------
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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)
Expand All @@ -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++;
}
}
}
}
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
}
}
}
}
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions src/raylib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit eda239c

Please sign in to comment.