@ -34,6 +34,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
// CHANGELOG
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// (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: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before a key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before a key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
@ -277,7 +278,6 @@ static void ImGui_ImplWin32_UpdateGamepads()
# ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
# ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
ImGuiIO & io = ImGui : : GetIO ( ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
ImGui_ImplWin32_Data * bd = ImGui_ImplWin32_GetBackendData ( ) ;
ImGui_ImplWin32_Data * bd = ImGui_ImplWin32_GetBackendData ( ) ;
memset ( io . NavInputs , 0 , sizeof ( io . NavInputs ) ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
return ;
return ;
@ -285,39 +285,47 @@ static void ImGui_ImplWin32_UpdateGamepads()
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
if ( bd - > WantUpdateHasGamepad )
if ( bd - > WantUpdateHasGamepad )
{
{
XINPUT_CAPABILITIES caps ;
XINPUT_CAPABILITIES caps = { } ;
bd - > HasGamepad = bd - > XInputGetCapabilities ? ( bd - > XInputGetCapabilities ( 0 , XINPUT_FLAG_GAMEPAD , & caps ) = = ERROR_SUCCESS ) : false ;
bd - > HasGamepad = bd - > XInputGetCapabilities ? ( bd - > XInputGetCapabilities ( 0 , XINPUT_FLAG_GAMEPAD , & caps ) = = ERROR_SUCCESS ) : false ;
bd - > WantUpdateHasGamepad = false ;
bd - > WantUpdateHasGamepad = false ;
}
}
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
XINPUT_STATE xinput_state ;
XINPUT_STATE xinput_state ;
if ( bd - > HasGamepad & & bd - > XInputGetState & & bd - > XInputGetState ( 0 , & xinput_state ) = = ERROR_SUCCESS )
XINPUT_GAMEPAD & gamepad = xinput_state . Gamepad ;
{
if ( ! bd - > HasGamepad | | bd - > XInputGetState = = NULL | | bd - > XInputGetState ( 0 , & xinput_state ) ! = ERROR_SUCCESS )
const XINPUT_GAMEPAD & gamepad = xinput_state . Gamepad ;
return ;
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
# define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
# define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
# define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - 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 MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0, ImGuiInputSource_Gamepad); }
MAP_BUTTON ( ImGuiNavInput_Activate , XINPUT_GAMEPAD_A ) ; // Cross / A
# define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn), ImGuiInputSource_Gamepad); }
MAP_BUTTON ( ImGuiNavInput_Cancel , XINPUT_GAMEPAD_B ) ; // Circle / B
MAP_BUTTON ( ImGuiKey_GamepadStart , XINPUT_GAMEPAD_START ) ;
MAP_BUTTON ( ImGuiNavInput_Menu , XINPUT_GAMEPAD_X ) ; // Square / X
MAP_BUTTON ( ImGuiKey_GamepadBack , XINPUT_GAMEPAD_BACK ) ;
MAP_BUTTON ( ImGuiNavInput_Input , XINPUT_GAMEPAD_Y ) ; // Triangle / Y
MAP_BUTTON ( ImGuiKey_GamepadFaceDown , XINPUT_GAMEPAD_A ) ;
MAP_BUTTON ( ImGuiNavInput_DpadLeft , XINPUT_GAMEPAD_DPAD_LEFT ) ; // D-Pad Left
MAP_BUTTON ( ImGuiKey_GamepadFaceRight , XINPUT_GAMEPAD_B ) ;
MAP_BUTTON ( ImGuiNavInput_DpadRight , XINPUT_GAMEPAD_DPAD_RIGHT ) ; // D-Pad Right
MAP_BUTTON ( ImGuiKey_GamepadFaceLeft , XINPUT_GAMEPAD_X ) ;
MAP_BUTTON ( ImGuiNavInput_DpadUp , XINPUT_GAMEPAD_DPAD_UP ) ; // D-Pad Up
MAP_BUTTON ( ImGuiKey_GamepadFaceUp , XINPUT_GAMEPAD_Y ) ;
MAP_BUTTON ( ImGuiNavInput_DpadDown , XINPUT_GAMEPAD_DPAD_DOWN ) ; // D-Pad Down
MAP_BUTTON ( ImGuiKey_GamepadDpadLeft , XINPUT_GAMEPAD_DPAD_LEFT ) ;
MAP_BUTTON ( ImGuiNavInput_FocusPrev , XINPUT_GAMEPAD_LEFT_SHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiKey_GamepadDpadRight , XINPUT_GAMEPAD_DPAD_RIGHT ) ;
MAP_BUTTON ( ImGuiNavInput_FocusNext , XINPUT_GAMEPAD_RIGHT_SHOULDER ) ; // R1 / RB
MAP_BUTTON ( ImGuiKey_GamepadDpadUp , XINPUT_GAMEPAD_DPAD_UP ) ;
MAP_BUTTON ( ImGuiNavInput_TweakSlow , XINPUT_GAMEPAD_LEFT_SHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiKey_GamepadDpadDown , XINPUT_GAMEPAD_DPAD_DOWN ) ;
MAP_BUTTON ( ImGuiNavInput_TweakFast , XINPUT_GAMEPAD_RIGHT_SHOULDER ) ; // R1 / RB
MAP_BUTTON ( ImGuiKey_GamepadL1 , XINPUT_GAMEPAD_LEFT_SHOULDER ) ;
MAP_ANALOG ( ImGuiNavInput_LStickLeft , gamepad . sThumbLX , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
MAP_BUTTON ( ImGuiKey_GamepadR1 , XINPUT_GAMEPAD_RIGHT_SHOULDER ) ;
MAP_ANALOG ( ImGuiNavInput_LStickRight , gamepad . sThumbLX , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadL2 , gamepad . bLeftTrigger , XINPUT_GAMEPAD_TRIGGER_THRESHOLD , 255 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickUp , gamepad . sThumbLY , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadR2 , gamepad . bRightTrigger , XINPUT_GAMEPAD_TRIGGER_THRESHOLD , 255 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickDown , gamepad . sThumbLY , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32767 ) ;
MAP_BUTTON ( ImGuiKey_GamepadL3 , XINPUT_GAMEPAD_LEFT_THUMB ) ;
MAP_BUTTON ( ImGuiKey_GamepadR3 , XINPUT_GAMEPAD_RIGHT_THUMB ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickLeft , gamepad . sThumbLX , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickRight , gamepad . sThumbLX , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickUp , gamepad . sThumbLY , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickDown , gamepad . sThumbLY , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickLeft , gamepad . sThumbRX , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickRight , gamepad . sThumbRX , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickUp , gamepad . sThumbRY , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickDown , gamepad . sThumbRY , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
# undef MAP_BUTTON
# undef MAP_BUTTON
# undef MAP_ANALOG
# undef MAP_ANALOG
}
# endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
# endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
}
}