@ -18,6 +18,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
@ -465,40 +466,45 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
static void ImGui_ImplSDL2_UpdateGamepads ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
memset ( io . NavInputs , 0 , sizeof ( io . NavInputs ) ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
return ;
// Get gamepad
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
SDL_GameController * game_controller = SDL_GameControllerOpen ( 0 ) ;
if ( ! game_controller )
{
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
return ;
}
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
// Update gamepad inputs
# define MAP_BUTTON(NAV_NO, BUTTON_NO) { io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; }
# define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
# 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_GameControllerGetButton(game_controller, BUTTON_NO) != 0, ImGuiInputSource_Gamepad); }
# define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn, ImGuiInputSource_Gamepad); }
const int thumb_dead_zone = 8000 ; // SDL_gamecontroller.h suggests using this value.
MAP_BUTTON ( ImGuiNavInput_Activate , SDL_CONTROLLER_BUTTON_A ) ; // Cross / A
MAP_BUTTON ( ImGuiNavInput_Cancel , SDL_CONTROLLER_BUTTON_B ) ; // Circle / B
MAP_BUTTON ( ImGuiNavInput_Menu , SDL_CONTROLLER_BUTTON_X ) ; // Square / X
MAP_BUTTON ( ImGuiNavInput_Input , SDL_CONTROLLER_BUTTON_Y ) ; // Triangle / Y
MAP_BUTTON ( ImGuiNavInput_DpadLeft , SDL_CONTROLLER_BUTTON_DPAD_LEFT ) ; // D-Pad Left
MAP_BUTTON ( ImGuiNavInput_DpadRight , SDL_CONTROLLER_BUTTON_DPAD_RIGHT ) ; // D-Pad Right
MAP_BUTTON ( ImGuiNavInput_DpadUp , SDL_CONTROLLER_BUTTON_DPAD_UP ) ; // D-Pad Up
MAP_BUTTON ( ImGuiNavInput_DpadDown , SDL_CONTROLLER_BUTTON_DPAD_DOWN ) ; // D-Pad Down
MAP_BUTTON ( ImGuiNavInput_FocusPrev , SDL_CONTROLLER_BUTTON_LEFTSHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_FocusNext , SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ) ; // R1 / RB
MAP_BUTTON ( ImGuiNavInput_TweakSlow , SDL_CONTROLLER_BUTTON_LEFTSHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_TweakFast , SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ) ; // R1 / RB
MAP_ANALOG ( ImGuiNavInput_LStickLeft , SDL_CONTROLLER_AXIS_LEFTX , - thumb_dead_zone , - 32768 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickRight , SDL_CONTROLLER_AXIS_LEFTX , + thumb_dead_zone , + 32767 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickUp , SDL_CONTROLLER_AXIS_LEFTY , - thumb_dead_zone , - 32767 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickDown , SDL_CONTROLLER_AXIS_LEFTY , + thumb_dead_zone , + 32767 ) ;
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
MAP_BUTTON ( ImGuiKey_GamepadStart , SDL_CONTROLLER_BUTTON_START ) ;
MAP_BUTTON ( ImGuiKey_GamepadBack , SDL_CONTROLLER_BUTTON_BACK ) ;
MAP_BUTTON ( ImGuiKey_GamepadFaceDown , SDL_CONTROLLER_BUTTON_A ) ; // Xbox A, PS Cross
MAP_BUTTON ( ImGuiKey_GamepadFaceRight , SDL_CONTROLLER_BUTTON_B ) ; // Xbox B, PS Circle
MAP_BUTTON ( ImGuiKey_GamepadFaceLeft , SDL_CONTROLLER_BUTTON_X ) ; // Xbox X, PS Square
MAP_BUTTON ( ImGuiKey_GamepadFaceUp , SDL_CONTROLLER_BUTTON_Y ) ; // Xbox Y, PS Triangle
MAP_BUTTON ( ImGuiKey_GamepadDpadLeft , SDL_CONTROLLER_BUTTON_DPAD_LEFT ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadRight , SDL_CONTROLLER_BUTTON_DPAD_RIGHT ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadUp , SDL_CONTROLLER_BUTTON_DPAD_UP ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadDown , SDL_CONTROLLER_BUTTON_DPAD_DOWN ) ;
MAP_BUTTON ( ImGuiKey_GamepadL1 , SDL_CONTROLLER_BUTTON_LEFTSHOULDER ) ;
MAP_BUTTON ( ImGuiKey_GamepadR1 , SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ) ;
MAP_ANALOG ( ImGuiKey_GamepadL2 , SDL_CONTROLLER_AXIS_TRIGGERLEFT , 0.0f , 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadR2 , SDL_CONTROLLER_AXIS_TRIGGERRIGHT , 0.0f , 32767 ) ;
MAP_BUTTON ( ImGuiKey_GamepadL3 , SDL_CONTROLLER_BUTTON_LEFTSTICK ) ;
MAP_BUTTON ( ImGuiKey_GamepadR3 , SDL_CONTROLLER_BUTTON_RIGHTSTICK ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickLeft , SDL_CONTROLLER_AXIS_LEFTX , - thumb_dead_zone , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickRight , SDL_CONTROLLER_AXIS_LEFTX , + thumb_dead_zone , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickUp , SDL_CONTROLLER_AXIS_LEFTY , - thumb_dead_zone , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickDown , SDL_CONTROLLER_AXIS_LEFTY , + thumb_dead_zone , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickLeft , SDL_CONTROLLER_AXIS_RIGHTX , - thumb_dead_zone , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickRight , SDL_CONTROLLER_AXIS_RIGHTX , + thumb_dead_zone , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickUp , SDL_CONTROLLER_AXIS_RIGHTY , - thumb_dead_zone , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickDown , SDL_CONTROLLER_AXIS_RIGHTY , + thumb_dead_zone , + 32767 ) ;
# undef MAP_BUTTON
# undef MAP_ANALOG
}