When implementing controller support in a game, it’s desirable for gamepads to
just work without a lot of user configuration. Platform APIs are pretty useless
for this, the solution is an API like SDL_GameController that allows you to
target a large number of gamepads without much effort.
Each operating system has its own API for gamepad input. Windows has XInput, and
Linux has the joystick and evdev APIs. When a gamepad button is pressed,
applications will receive a button id. This is a number, there’s no OS way to
know which button id corresponds with which button. The ids for a button are not
the same on different gamepads and platforms, making it super hard to support
more than a couple of devices.
if (SDL_JoystickGetButton(joystick, 8)) {
std::cerr << "no idea what button 8 is" << std::endl;
}
One thing platforms do give you is the name, model, and manufacturer
of the game controller. If you test with a large number of gamepads, you can
create a database from gamepad name to layout. Luckily, SDL_GameController
has already done this for you. Instead of a random number, you can use a named
button that will work no matter the gamepad and platform:
if (SDL_GameControllerGetButton(controller, SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X)) {
std::cerr << "X was pressed!" << std::endl;
}