Quick answer: SDL ships a mapping DB snapshot. For newer pads, bundle an updated gamecontrollerdb.txt and load it via SDL_AddGamepadMappingsFromFile at startup.

A player’s recent third-party controller is detected as a generic joystick, not a gamepad — SDL3’s built-in mapping table predates the device.

Load an Updated Database

// at startup, before opening gamepads
int added = SDL_AddGamepadMappingsFromFile("gamecontrollerdb.txt");
if (added < 0) {
    SDL_Log("Failed to load mappings: %s", SDL_GetError());
}

Bundle the latest gamecontrollerdb.txt (community-maintained, updated frequently) with your game. It adds/overrides mappings for thousands of controllers.

Add a Single Mapping

SDL_AddGamepadMapping(
  "03000000xxxx...,My Controller,a:b0,b:b1,x:b2,y:b3,...");

For one specific controller, add its mapping string directly. Get the GUID from SDL_GetJoystickGUIDString.

Let Players Remap

No database covers everything. Ship an in-game remapping screen. Save the user’s custom mapping string and load it on next launch.

Check Recognition

if (SDL_IsGamepad(joystick_id)) {
    SDL_Gamepad* pad = SDL_OpenGamepad(joystick_id);
}

SDL_IsGamepad returns true only if a mapping exists. Otherwise treat it as a raw joystick or prompt for remap.

Verifying

Plug in a recent controller. It’s recognized as a gamepad with correct button layout. Test a few obscure pads — remapping UI covers the gaps.

“SDL’s built-in DB is a snapshot. Ship the live community DB and offer remapping.”

Re-download gamecontrollerdb.txt as part of your release process — it’s updated weekly with new hardware.