Replace XInput with SDL 3 Input

This commit is contained in:
2026-08-07 06:45:41 +03:00
parent ae9abf45a2
commit 75f8389c1e
98 changed files with 82676 additions and 52 deletions
+115 -50
View File
@@ -23,18 +23,24 @@ SOFTWARE.
*/
#include "INP_Main.h"
#include "vendor\SDL\include\SDL3\SDL.h"
CInput InternalInputManager;
SDL_Event event;
CInput::CInput()
{
m_ForceFeedback = CForceFeedback();
m_Keyboard = CKeyboard();
m_uiSigninJoypadMask = 0;
for (int i = 0; i < 4; ++i)
m_bIsMenuDisplayed[i] = 0;
if (!SDL_Init(SDL_INIT_GAMEPAD)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
assert(0);
}
InitTime();
m_fRepeatDelaySecs = 0.5f;
@@ -63,7 +69,7 @@ void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char uc
for (int i = 0; i < MAX_JOYPADS; i++)
{
m_Joypads[i].m_pInputStates = new XINPUT_STATE[m_ucInputStateC];
m_Joypads[i].m_pGamepad = nullptr;
m_Joypads[i].m_ucInputStateIndex = -1;
m_Joypads[i].m_pfLeftThumbXAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbX;
m_Joypads[i].m_pfLeftThumbYAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbY;
@@ -84,173 +90,191 @@ void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char uc
m_ucJoypadMapActionC = ucActionC;
m_ucMenuActionC = ucMenuActionC;
m_bJoypadMapArrayIsSetup = false;
m_ForceFeedback.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC);
}
void CInput::Tick(void)
{
HandleGamepadEvents();
UpdateJoypads();
m_ForceFeedback.Tick();
m_Keyboard.Tick();
}
void CInput::SetJoypadValues(JOYPAD *pThisPad)
{
XINPUT_GAMEPAD *pGamePad = &pThisPad->m_pInputStates[pThisPad->m_ucInputStateIndex].Gamepad;
SDL_Gamepad *pGamePad = pThisPad->m_pGamepad;
if (pGamePad->bLeftTrigger > 0x7Fu)
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) > (SDL_MAX_SINT16 / 2))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LT;
}
if (pGamePad->bRightTrigger > 0x7Fu)
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) > (SDL_MAX_SINT16 / 2))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RT;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RB;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LB;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_A) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_SOUTH))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_A;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_B) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_EAST))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_B;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_X) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_WEST))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_X;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_Y) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_NORTH))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_Y;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_START) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_START))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_START;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_BACK) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_BACK))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_BACK;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_LEFT_STICK))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LTHUMB;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_RIGHT_STICK))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RTHUMB;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_UP))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_UP;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_DOWN))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_DOWN;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_LEFT))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_LEFT;
}
if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0)
if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT))
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_RIGHT;
}
if (pGamePad->sThumbLX > m_iHalfRange + m_iDeadzone)
// RY and LY are inverted, so we have to negate them.
// This does not apply to RX and LX.
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX) > m_iHalfRange + m_iDeadzone)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_RIGHT;
}
if (pGamePad->sThumbLX < -m_iDeadzone - m_iHalfRange)
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX) < -m_iDeadzone - m_iHalfRange)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_LEFT;
}
if (pGamePad->sThumbRY < -m_iDeadzone - m_iHalfRange)
if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY) < -m_iDeadzone - m_iHalfRange)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_DOWN;
}
if (pGamePad->sThumbRY > m_iHalfRange + m_iDeadzone)
if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY) > m_iHalfRange + m_iDeadzone)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_UP;
}
if (pGamePad->sThumbRX > m_iHalfRange + m_iDeadzone)
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX) > m_iHalfRange + m_iDeadzone)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_RIGHT;
}
if (pGamePad->sThumbRX < -m_iDeadzone - m_iHalfRange)
if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX) < -m_iDeadzone - m_iHalfRange)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_LEFT;
}
if (pGamePad->sThumbLY < -m_iDeadzone - m_iHalfRange)
if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY) < -m_iDeadzone - m_iHalfRange)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_DOWN;
}
if (pGamePad->sThumbLY > m_iHalfRange + m_iDeadzone)
if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY) > m_iHalfRange + m_iDeadzone)
{
pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_UP;
}
pThisPad->m_ucLeftTriggerState = pGamePad->bLeftTrigger;
pThisPad->m_ucRightTriggerState = pGamePad->bRightTrigger;
pThisPad->m_ucLeftTriggerState = (unsigned char)(SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) >> 7);
pThisPad->m_ucRightTriggerState = (unsigned char)(SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) >> 7);
if (pGamePad->sThumbRX <= m_iDeadzone)
Sint16 sThumbRX = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX);
if (sThumbRX <= m_iDeadzone)
{
if (pGamePad->sThumbRX >= -m_iDeadzone)
if (sThumbRX >= -m_iDeadzone)
pThisPad->m_iRightThumbX = 0;
else
pThisPad->m_iRightThumbX = m_iDeadzone + pGamePad->sThumbRX;
pThisPad->m_iRightThumbX = m_iDeadzone + sThumbRX;
}
else
{
pThisPad->m_iRightThumbX = pGamePad->sThumbRX - m_iDeadzone;
pThisPad->m_iRightThumbX = sThumbRX - m_iDeadzone;
}
if (pGamePad->sThumbRY <= m_iDeadzone)
// RY and LY are inverted, so we have to negate them.
// We have to also keep in mind that the thumbstick shouldn't go over the integer limit
// then flip (Talking from experience :3)
// This does not apply to RX and LX.
Sint16 rawRY = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY);
if (rawRY < -SDL_MAX_SINT16) rawRY = -SDL_MAX_SINT16;
Sint16 sThumbRY = -rawRY;
if (sThumbRY <= m_iDeadzone)
{
if (pGamePad->sThumbRY >= -m_iDeadzone)
if (sThumbRY >= -m_iDeadzone)
pThisPad->m_iRightThumbY = 0;
else
pThisPad->m_iRightThumbY = m_iDeadzone + pGamePad->sThumbRY;
pThisPad->m_iRightThumbY = m_iDeadzone + sThumbRY;
}
else
{
pThisPad->m_iRightThumbY = pGamePad->sThumbRY - m_iDeadzone;
pThisPad->m_iRightThumbY = sThumbRY - m_iDeadzone;
}
if (pGamePad->sThumbLX <= m_iDeadzone)
Sint16 sThumbLX = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX);
if (sThumbLX <= m_iDeadzone)
{
if (pGamePad->sThumbLX >= -m_iDeadzone)
if (sThumbLX >= -m_iDeadzone)
pThisPad->m_iLeftThumbX = 0;
else
pThisPad->m_iLeftThumbX = m_iDeadzone + pGamePad->sThumbLX;
pThisPad->m_iLeftThumbX = m_iDeadzone + sThumbLX;
}
else
{
pThisPad->m_iLeftThumbX = pGamePad->sThumbLX - m_iDeadzone;
pThisPad->m_iLeftThumbX = sThumbLX - m_iDeadzone;
}
if (pGamePad->sThumbLY <= m_iDeadzone)
Sint16 rawLY = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY);
if (rawLY < -SDL_MAX_SINT16) rawLY = -SDL_MAX_SINT16;
Sint16 sThumbLY = -rawLY;
if (sThumbLY <= m_iDeadzone)
{
if (pGamePad->sThumbLY >= -m_iDeadzone)
if (sThumbLY >= -m_iDeadzone)
pThisPad->m_iLeftThumbY = 0;
else
pThisPad->m_iLeftThumbY = m_iDeadzone + pGamePad->sThumbLY;
pThisPad->m_iLeftThumbY = m_iDeadzone + sThumbLY;
}
else
{
pThisPad->m_iLeftThumbY = pGamePad->sThumbLY - m_iDeadzone;
pThisPad->m_iLeftThumbY = sThumbLY - m_iDeadzone;
}
pThisPad->m_iNormalizedLeftThumbX = pThisPad->m_iLeftThumbX / m_iEffectiveRange;
@@ -589,6 +613,47 @@ FLOAT CInput::GetIdleSeconds(int iPad)
return this->m_fTickToSeconds * (qwDeltaTime.LowPart - fElapsedTime.LowPart);
}
void CInput::HandleGamepadEvents()
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_EVENT_GAMEPAD_ADDED:
for (int i = 0; i < MAX_JOYPADS; i++)
{
if (!m_Joypads[i].m_pGamepad)
{
SDL_Gamepad *pad = SDL_OpenGamepad(event.gdevice.which);
if (pad)
{
SDL_SetGamepadPlayerIndex(pad, i);
m_Joypads[i].m_pGamepad = pad;
}
break;
}
}
break;
case SDL_EVENT_GAMEPAD_REMOVED:
for (int i = 0; i < MAX_JOYPADS; i++)
{
if (m_Joypads[i].m_pGamepad &&
SDL_GetGamepadID(m_Joypads[i].m_pGamepad) == event.gdevice.which)
{
SDL_CloseGamepad(m_Joypads[i].m_pGamepad);
m_Joypads[i].m_pGamepad = nullptr;
m_Joypads[i].m_bIsConnected = false;
break;
}
}
break;
}
}
}
bool CInput::UpdateJoypads()
{
assert(m_bJoypadMapArrayIsSetup);
@@ -621,7 +686,7 @@ bool CInput::UpdateJoypads()
pThisPad->m_ucInputStateIndex = 0;
}
pThisPad->m_bIsConnected = XInputGetState(i, &pThisPad->m_pInputStates[pThisPad->m_ucInputStateIndex]) == 0;
pThisPad->m_bIsConnected = (pThisPad->m_pGamepad != nullptr);
bool bWasConnected = bOldIsConnected && !pThisPad->m_bIsConnected;
pThisPad->m_bWasConnected = bWasConnected;