Adam Jones|HomeBlog

The standard W3C Gamepad API mapping for an Xbox controller

Headshot of Adam Jones

Adam Jones

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 GamepadXbox 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.