The standard W3C Gamepad API mapping for an Xbox controller
I recently set out on a project to make a web game with controller support.
The Gamepad API enables you to connect to controllers from the browser, which gives you an array of buttons.
The specification defines a standard
mapping for controllers, from this array to the relevant buttons. The specification helpfully provides an image that explains the mapping for something looking like a DualShock controller, but it's not immediately clear how this maps to an Xbox controller.
Here's a table mapping the W3C Standard Gamepad buttons/axes to their corresponding Xbox controller inputs:
W3C Standard Gamepad | Xbox Controller |
---|---|
Buttons | |
button[0] | A |
button[1] | B |
button[2] | X |
button[3] | Y |
button[4] | Left Bumper (LB) |
button[5] | Right Bumper (RB) |
button[6] | Left Trigger (LT) |
button[7] | Right Trigger (RT) |
button[8] | View (Back) |
button[9] | Menu (Start) |
button[10] | Left Stick Press |
button[11] | Right Stick Press |
button[12] | D-pad Up |
button[13] | D-pad Down |
button[14] | D-pad Left |
button[15] | D-pad Right |
button[16] | Xbox Button |
Axes | |
axes[0] | Left Stick X (negative = left) |
axes[1] | Left Stick Y (negative = up) |
axes[2] | Right Stick X (negative = left) |
axes[3] | Right Stick Y (negative = up) |
If you're looking for a JavaScript or TypeScript snippet to map this into something easier to use, try this:
const mapGamepadToGamepadState = (gamepad: Gamepad, deadzone = 0.5) => {
const { axes, buttons } = gamepad;
return {
buttons: {
A: buttons[0].pressed,
B: buttons[1].pressed,
X: buttons[2].pressed,
Y: buttons[3].pressed,
LB: buttons[4].pressed,
RB: buttons[5].pressed,
LT: buttons[6].pressed,
RT: buttons[7].pressed,
View: buttons[8].pressed,
Menu: buttons[9].pressed,
LS: buttons[10].pressed,
RS: buttons[11].pressed,
DUp: buttons[12].pressed,
DDown: buttons[13].pressed,
DLeft: buttons[14].pressed,
DRight: buttons[15].pressed,
Xbox: buttons[16].pressed,
LUp: axes[1] < -deadzone,
LDown: axes[1] > deadzone,
LLeft: axes[0] < -deadzone,
LRight: axes[0] > deadzone,
RUp: axes[3] < -deadzone,
RDown: axes[3] > deadzone,
RLeft: axes[2] < -deadzone,
RRight: axes[2] > deadzone,
},
axes: {
L: {
x: axes[0],
y: axes[1],
},
R: {
x: axes[2],
y: axes[3],
},
},
};
};
CC0: This code has been marked as dedicated to the public domain.
And finally, if you're looking to do some troubleshooting with your controller you can use Human Benchmark's gamepad tester. I have no relation to this service other than as a user, but I found it really helpful.