Skip to content

Evdev Code Mapping

NanoMindExplores edited this page Jul 14, 2026 · 1 revision

Evdev Code Mapping

This page documents how GameMapperMind maps Linux evdev button/axis codes to logical gamepad buttons.

Button Mapping Table

Logical Button evdev Codes Notes
A BTN_GAMEPAD, BTN_A, BTN_SOUTH BTN_GAMEPAD = BTN_A = BTN_SOUTH (same code 0x130). Many generic Bluetooth gamepads report A as BTN_GAMEPAD.
B BTN_B, BTN_EAST
X BTN_X, BTN_NORTH
Y BTN_Y, BTN_WEST
LT (digital) BTN_TL2, BTN_LT Digital trigger button. MUST be checked before BTN_TL.
RT (digital) BTN_TR2, BTN_RT Digital trigger button. Same precedence rule as LT.
LB BTN_TL, BTN_L1 Bumper (not trigger)
RB BTN_TR, BTN_R1 Bumper (not trigger)
L3 BTN_THUMBL, BTN_THUMB Left stick click
R3 BTN_THUMBR, BTN_THUMB2 Right stick click
START BTN_START
SELECT BTN_SELECT
HOME BTN_MODE Xbox logo / PS button
DPAD_UP BTN_DPAD_UP Discrete D-pad (rare). Most controllers use ABS_HAT0Y.
DPAD_DOWN BTN_DPAD_DOWN
DPAD_LEFT BTN_DPAD_LEFT
DPAD_RIGHT BTN_DPAD_RIGHT

Axis Mapping Table

Logical Axis evdev Codes Notes
Left Stick X ABS_X Always present on gamepads
Left Stick Y ABS_Y Always present on gamepads
Right Stick X ABS_RX (Xbox) OR ABS_Z (generic) Auto-detected per controller
Right Stick Y ABS_RY (Xbox) OR ABS_RZ (generic) Auto-detected per controller
LT (analog) ABS_Z (Xbox), ABS_BRAKE, ABS_LTRIGGER Fallback heuristic: 255/1023/4095/32767
RT (analog) ABS_RZ (Xbox), ABS_GAS, ABS_RTRIGGER Same fallback heuristic
D-Pad ABS_HAT0X, ABS_HAT0Y Value: -1, 0, 1 (not continuous)

Right Stick Auto-Detection

Some controllers (especially generic Bluetooth gamepads) report the right stick on ABS_Z/ABS_RZ instead of ABS_RX/ABS_RY. The app detects this at connection time:

rightStickUsesZRZ = no ABS_RX AND no ABS_RY AND has ABS_Z AND has ABS_RZ

When rightStickUsesZRZ = true:

  • ABS_Z to right stick X
  • ABS_RZ to right stick Y
  • Triggers are expected to be digital (BTN_TL2/BTN_TR2)

Trigger Normalization

Triggers come in many ranges depending on controller:

  • Xbox Bluetooth: 0..1023 (10-bit)
  • Generic HID: 0..255 (8-bit)
  • Some PS4 clones: 0..4095 (12-bit)
  • xpad kernel driver: 0..32767 (15-bit)

The app reads the actual min/max from getevent -lp and normalizes accordingly. If range not detected, uses heuristic based on raw value magnitude.

BTN_GAMEPAD = BTN_A (Important!)

In Linux input.h:

  • BTN_GAMEPAD = 0x130
  • BTN_SOUTH = 0x130
  • BTN_A = 0x130

These are all the same code. Many generic Bluetooth gamepads report their A button as BTN_GAMEPAD in getevent output. Before v3, the app only checked for BTN_A and BTN_SOUTH substrings, which do not match BTN_GAMEPAD — so the A button was silently dropped during gameplay.

v3 fix: mapEvdevToButton(BTN_GAMEPAD) now returns A.

Diagnostic Log

When a controller connects, the app emits: GAMEPAD-DETECT axes: ... buttons: ... R-stick uses Z/RZ: true

If you press a button and see: GAMEPAD-KEY Unmapped button BTN_XXX DOWN

...then your controller uses a code not yet mapped. Please open an Issue with the button name so we can add it.

See Also

  • Gamepad-Detection — How the app auto-detects controller layout
  • Trigger-Normalization — How analog triggers are normalized

Clone this wiki locally