Difference between Joysticks and Game Controllers?

Sorry if this is a stupid question. To me a joystick and a game controller is basically the same thing, and both appear to have button and axis events in SDL2… can someone help me understand the difference? Which is used for what?


In general “Gamecontroller” often refers to gamepads (i.e. not joysticks or steering wheels or whatever)

In SDL2, it refers to Gamepads that are like the one of the xbox360 or PS3 - with two analog sticks, one dpad, two shoulder buttons on each side (one of them possibly a trigger axis and not just a button), 4 buttons on the right and some buttons in the middle of the pad.
SDL2 maps the axis and buttons of devices it knows (and XInput Devices on Windows) to standardized button/axis names based on xbox360/xinput controllers.
So you know that SDL_CONTROLLER_BUTTON_A is the lower one of the 4 buttons on the right and so on. This allows you to provide usable default bindings for such devices and to visualize the controller with its buttons and axes in your configuration dialog - or in game, like “press A button to jump” showing a picture of a gamepad with that button highlighted etc.

Each SDL Gamecontroller device can also be used as a Joystick device.
But with generic joystick devices there is no reliable way to know if it’s a joystick, steering wheel or gamepad, and which button or axis is which, or what kind of axis something is, like an trigger or pedal axis that only goes one way and is at minimum/maximum by default until pressed, or the axis of an analog stick that can be pushed both ways and is at position 0 by default… DirectInput or whatever the API your platform uses just doesn’t provide all that information in a reliable manner.

So if you only want to support gamepads, the Gamecontroller API is probably better suited/easier to use, as long as SDL “knows” about the device.
Otherwise you should use the generic Joystick API.

In one game (that needs to support all kinds of devices) I did the following: I use the generic Joystick API for events etc and let users configure per axis what kind of axis it is (trigger/pedal, analog stick axis, steering wheel) and what its default position and deadzone is etc.
However, I check if the SDL_Joystick is a known SDL_GameController (https://wiki.libsdl.org/SDL_IsGameController) and if it is, I use https://wiki.libsdl.org/SDL_GameControllerGetBindForButton and https://wiki.libsdl.org/SDL_GameControllerGetBindForAxis to get information about the buttons+axes and set the names and default settings for the SDL_Joystick’s buttons/axes accordingly.