Skip to content

Commit

Permalink
Fix SDL Gamepad handling
Browse files Browse the repository at this point in the history
SDL_OpenGamepad(0) doesn't work with latest SDL3.
Now we need to get all the gamepags, then we need to open it:
    int pads = 0;
    auto ids = SDL_GetGamepads(&pads);
    auto joyId = SDL_OpenGamepad(ids[0]);
    ...
    SDL_CloseGamepad(joyId);

A new function ImGui_ImplSDL3_SetGamepad is needed to allow the user to
set which gamepad will be used for Ui Navigation, as we shouldn't open/
close the gamepad for each frame.
  • Loading branch information
bog-dan-ro committed Dec 29, 2023
1 parent 240ab58 commit 00799ed
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
17 changes: 13 additions & 4 deletions backends/imgui_impl_sdl3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct ImGui_ImplSDL3_Data
int PendingMouseLeaveFrame;
char* ClipboardTextData;
bool MouseCanUseGlobalState;
SDL_Gamepad* Gamepad;

ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
};
Expand Down Expand Up @@ -531,15 +532,15 @@ static void ImGui_ImplSDL3_UpdateGamepads()

// Get gamepad
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
SDL_Gamepad* gamepad = SDL_OpenGamepad(0);
if (!gamepad)
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
if (!bd->Gamepad)
return;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;

// Update gamepad inputs
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GetGamepadButton(gamepad, BUTTON_NO) != 0); }
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GetGamepadAxis(gamepad, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GetGamepadButton(bd->Gamepad, BUTTON_NO) != 0); }
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GetGamepadAxis(bd->Gamepad, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
MAP_BUTTON(ImGuiKey_GamepadStart, SDL_GAMEPAD_BUTTON_START);
MAP_BUTTON(ImGuiKey_GamepadBack, SDL_GAMEPAD_BUTTON_BACK);
Expand Down Expand Up @@ -609,10 +610,18 @@ void ImGui_ImplSDL3_NewFrame()
ImGui_ImplSDL3_UpdateGamepads();
}


void ImGui_ImplSDL3_SetGamepad(SDL_Gamepad *gamepad)
{
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
bd->Gamepad = gamepad;
}

//-----------------------------------------------------------------------------

#if defined(__clang__)
#pragma clang diagnostic pop
#endif

#endif // #ifndef IMGUI_DISABLE

3 changes: 2 additions & 1 deletion backends/imgui_impl_sdl3.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

struct SDL_Window;
struct SDL_Renderer;
struct SDL_Gamepad;
typedef union SDL_Event SDL_Event;

IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
Expand All @@ -37,5 +38,5 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);

IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepad(SDL_Gamepad* gamepad);
#endif // #ifndef IMGUI_DISABLE

0 comments on commit 00799ed

Please sign in to comment.