Skip to content

Commit ade29fc

Browse files
githubawnbobtista
andcommitted
fix(sdl3): backport SDL3 input, focus, and windowing fixes from review
Co-authored-by: Bobby Battista <bobtista@gmail.com>
1 parent f1c78e9 commit ade29fc

7 files changed

Lines changed: 84 additions & 27 deletions

File tree

Core/GameEngine/Include/GameClient/Mouse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ class Mouse : public SubsystemInterface
283283

284284
virtual void draw() override; ///< draw the mouse
285285
virtual void setPosition( Int x, Int y ); ///< set the mouse position
286+
virtual void syncPositionToSystemCursor() { setPosition( 0, 0 ); }
286287
virtual void setCursor( MouseCursor cursor ) = 0; ///< set mouse cursor
287288

288289
void initCapture(); ///< called once to unlock the mouse capture functionality

Core/GameEngineDevice/Include/SDL3Device/GameClient/SDL3Input.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class SDL3Mouse : public Mouse
5555
virtual void setVisibility(Bool visible) override;
5656
virtual void loseFocus() override;
5757
virtual void regainFocus() override;
58+
virtual void syncPositionToSystemCursor() override;
5859

5960
// SDL3-specific methods
6061
void addSDLEvent(SDL_Event* event);
@@ -74,7 +75,6 @@ class SDL3Mouse : public Mouse
7475
SDL_Window* m_Window;
7576
Bool m_IsCaptured;
7677
Bool m_IsVisible;
77-
Bool m_LostFocus;
7878

7979
Int m_directionFrame;
8080

Core/GameEngineDevice/Source/SDL3Device/Common/SDL3GameEngine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void SDL3GameEngine::updateTextInputState()
255255

256256
GameWindow* focusedWindow = TheWindowManager->winGetFocus();
257257
const Bool wantsTextInput =
258-
focusedWindow != nullptr && BitIsSet(focusedWindow->winGetStyle(), GWS_ENTRY_FIELD);
258+
focusedWindow != nullptr && (BitIsSet(focusedWindow->winGetStyle(), GWS_ENTRY_FIELD) || BitIsSet(focusedWindow->winGetStyle(), GWS_COMBO_BOX));
259259

260260
if (wantsTextInput)
261261
{

Core/GameEngineDevice/Source/SDL3Device/GameClient/SDL3Input.cpp

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "GameClient/Display.h"
3838
#include "GameClient/InGameUI.h"
3939
#include "GameClient/LookAtXlat.h"
40+
#include "GameClient/GameWindowManager.h"
4041
#include "GameLogic/GameLogic.h"
4142
#include "SDL3Device/Common/SDL3GameEngine.h"
4243
#include "SDL3Device/GameClient/SDL3Cursor.h"
@@ -50,7 +51,6 @@ SDL3Mouse::SDL3Mouse(SDL_Window* window)
5051
, m_Window(window)
5152
, m_IsCaptured(false)
5253
, m_IsVisible(true)
53-
, m_LostFocus(false)
5454
, m_directionFrame(0)
5555
, m_accumulatedDeltaX(0.0f)
5656
, m_accumulatedDeltaY(0.0f)
@@ -85,11 +85,6 @@ void SDL3Mouse::update()
8585
{
8686
Mouse::update();
8787

88-
if (m_LostFocus)
89-
{
90-
return;
91-
}
92-
9388
MouseCursor cursor = m_currentCursor;
9489

9590
if (cursor != NONE && cursor != INVALID_MOUSE_CURSOR && m_cursorInfo[cursor].numDirections > 1)
@@ -214,6 +209,25 @@ void SDL3Mouse::regainFocus()
214209
Mouse::regainFocus();
215210
}
216211

212+
void SDL3Mouse::syncPositionToSystemCursor()
213+
{
214+
if (!m_Window)
215+
return;
216+
217+
float mx = 0.0f;
218+
float my = 0.0f;
219+
SDL_GetMouseState(&mx, &my);
220+
221+
Uint32 windowID = SDL_GetWindowID(m_Window);
222+
int scaledX = (int)mx;
223+
int scaledY = (int)my;
224+
scaleMouseCoordinates((int)mx, (int)my, windowID, scaledX, scaledY);
225+
226+
m_currMouse.pos.x = scaledX;
227+
m_currMouse.pos.y = scaledY;
228+
m_prevMouse.pos = m_currMouse.pos;
229+
}
230+
217231
void SDL3Mouse::capture()
218232
{
219233
if (!m_Window || m_isCursorCaptured)
@@ -711,7 +725,14 @@ void SDL3InputManager::update()
711725
{
712726
case SDL_EVENT_QUIT:
713727
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
714-
m_isQuitting = true;
728+
if (TheMessageStream && TheMessageStream->isReadyForMessages())
729+
{
730+
TheMessageStream->appendMessage(GameMessage::MSG_META_DEMO_INSTANT_QUIT);
731+
}
732+
else
733+
{
734+
m_isQuitting = true;
735+
}
715736
break;
716737

717738
case SDL_EVENT_GAMEPAD_ADDED:
@@ -725,14 +746,23 @@ void SDL3InputManager::update()
725746
break;
726747

727748
case SDL_EVENT_WINDOW_FOCUS_GAINED:
749+
if (TheGameEngine)
750+
TheGameEngine->setIsActive(true);
751+
if (TheKeyboard)
752+
TheKeyboard->reset();
728753
if (TheMouse)
729754
{
730755
TheMouse->regainFocus();
731756
TheMouse->refreshCursorCapture();
757+
TheMouse->syncPositionToSystemCursor();
732758
}
733759
break;
734760

735761
case SDL_EVENT_WINDOW_FOCUS_LOST:
762+
if (TheGameEngine)
763+
TheGameEngine->setIsActive(false);
764+
if (TheKeyboard)
765+
TheKeyboard->reset();
736766
if (TheMouse)
737767
TheMouse->loseFocus();
738768
break;
@@ -757,7 +787,24 @@ void SDL3InputManager::update()
757787
case SDL_EVENT_KEY_DOWN:
758788
case SDL_EVENT_KEY_UP:
759789
if (!event.key.repeat)
790+
{
760791
addKeyboardSDLEvent(event);
792+
if (event.key.down && (event.key.scancode == SDL_SCANCODE_RETURN || event.key.scancode == SDL_SCANCODE_KP_ENTER))
793+
{
794+
if (TheWindowManager)
795+
{
796+
GameWindow* focus = TheWindowManager->winGetFocus();
797+
if (focus)
798+
{
799+
const UnsignedInt style = focus->winGetStyle();
800+
if (BitIsSet(style, GWS_ENTRY_FIELD) || BitIsSet(style, GWS_COMBO_BOX))
801+
{
802+
TheWindowManager->winSendInputMsg(focus, GWM_IME_CHAR, VK_RETURN, 0);
803+
}
804+
}
805+
}
806+
}
807+
}
761808
break;
762809

763810
case SDL_EVENT_TEXT_INPUT:
@@ -852,16 +899,17 @@ void SDL3InputManager::closeGamepad()
852899
if (m_state.stickUp) virtualPulseKey(SDL_SCANCODE_UP, false);
853900
if (m_state.stickDown) virtualPulseKey(SDL_SCANCODE_DOWN, false);
854901

855-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_SOUTH]) virtualPulseKey(SDL_SCANCODE_RETURN, false);
856-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_EAST]) virtualPulseKey(SDL_SCANCODE_ESCAPE, false);
857-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_WEST]) virtualPulseKey(SDL_SCANCODE_X, false);
858-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_NORTH]) virtualPulseKey(SDL_SCANCODE_E, false);
902+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_SOUTH]) virtualPulseMouse(SDL_BUTTON_LEFT, false);
903+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_EAST]) virtualPulseMouse(SDL_BUTTON_RIGHT, false);
904+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_WEST]) virtualPulseKey(SDL_SCANCODE_A, false);
859905
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_LEFT_SHOULDER]) virtualPulseKey(SDL_SCANCODE_Q, false);
860-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER]) virtualPulseKey(SDL_SCANCODE_E, false);
861-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_UP]) virtualPulseKey(SDL_SCANCODE_1, false);
862-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_DOWN]) virtualPulseKey(SDL_SCANCODE_2, false);
863-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_LEFT]) virtualPulseKey(SDL_SCANCODE_3, false);
864-
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_RIGHT]) virtualPulseKey(SDL_SCANCODE_4, false);
906+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER]) virtualPulseKey(SDL_SCANCODE_LSHIFT, false);
907+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_START]) virtualPulseKey(SDL_SCANCODE_ESCAPE, false);
908+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_BACK]) virtualPulseKey(SDL_SCANCODE_SPACE, false);
909+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_UP]) virtualPulseKey(SDL_SCANCODE_2, false);
910+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_DOWN]) virtualPulseKey(SDL_SCANCODE_4, false);
911+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_LEFT]) virtualPulseKey(SDL_SCANCODE_1, false);
912+
if (m_state.buttonState[SDL_GAMEPAD_BUTTON_DPAD_RIGHT]) virtualPulseKey(SDL_SCANCODE_3, false);
865913

866914
m_state = GamepadState();
867915
m_lastUpdateTime = 0;
@@ -950,21 +998,29 @@ void SDL3InputManager::processGamepadInput()
950998
if (!m_gamepad)
951999
return;
9521000

1001+
const float DEADZONE = DEFAULT_DEADZONE;
1002+
float rx = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTX) / AXIS_MAX;
1003+
float ry = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTY) / AXIS_MAX;
1004+
1005+
float lx_axis = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_LEFTX) / AXIS_MAX;
1006+
float ly_axis = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_LEFTY) / AXIS_MAX;
1007+
float stickMag_check = sqrtf(lx_axis * lx_axis + ly_axis * ly_axis);
1008+
1009+
bool hasStickInput = (stickMag_check > DEADZONE) || (SDL_fabsf(rx) > DEADZONE) || (SDL_fabsf(ry) > DEADZONE);
9531010
if (TheLookAtTranslator)
954-
TheLookAtTranslator->setControllerInputActive(true);
1011+
TheLookAtTranslator->setControllerInputActive(hasStickInput);
9551012

9561013
Uint64 now = SDL_GetTicks();
9571014
float deltaTime = (now - m_lastUpdateTime) / 1000.0f;
9581015
m_lastUpdateTime = now;
9591016
if (deltaTime > 0.1f)
9601017
deltaTime = 0.1f;
9611018

962-
const float DEADZONE = DEFAULT_DEADZONE;
9631019
float resolutionScale = 1.0f;
9641020
int windowWidth = 0;
9651021
int windowHeight = 0;
966-
if (m_window && SDL_GetWindowSizeInPixels(m_window, &windowWidth, &windowHeight) && windowHeight > 0)
967-
resolutionScale = windowHeight / DESIGNED_WINDOW_HEIGHT;
1022+
if (m_window && SDL_GetWindowSize(m_window, &windowWidth, &windowHeight) && windowHeight > 0)
1023+
resolutionScale = (float)windowHeight / DESIGNED_WINDOW_HEIGHT;
9681024

9691025
const float CURSOR_SPEED = DEFAULT_CURSOR_SPEED * resolutionScale;
9701026
const float CURSOR_ACCELERATION = DEFAULT_CURSOR_ACCELERATION * resolutionScale;
@@ -1081,8 +1137,8 @@ void SDL3InputManager::processGamepadInput()
10811137
m_cursorRemainderY = 0.0f;
10821138
}
10831139

1084-
float rx = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTX) / AXIS_MAX;
1085-
float ry = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTY) / AXIS_MAX;
1140+
rx = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTX) / AXIS_MAX;
1141+
ry = SDL_GetGamepadAxis(m_gamepad, SDL_GAMEPAD_AXIS_RIGHTY) / AXIS_MAX;
10861142

10871143
handleGamepadButton(
10881144
SDL_GAMEPAD_BUTTON_INVALID,

Core/Main/SDL3Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int main(int argc, char* argv[])
7474
return exitcode;
7575
}
7676

77-
Uint32 flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
77+
Uint32 flags = SDL_WINDOW_HIDDEN;
7878
if (!TheGlobalData->m_windowed)
7979
{
8080
flags |= SDL_WINDOW_FULLSCREEN;

Generals/Code/GameEngine/Source/GameClient/GameClient.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ void GameClient::init()
389389
// finish initializing the mouse.
390390
TheMouse->init();
391391
TheMouse->initCapture();
392-
TheMouse->setPosition( 0, 0 );
392+
TheMouse->syncPositionToSystemCursor();
393393
TheMouse->setMouseLimits();
394394
TheMouse->setName("TheMouse");
395395
}

GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ void GameClient::init()
402402
// finish initializing the mouse.
403403
TheMouse->init();
404404
TheMouse->initCapture();
405-
TheMouse->setPosition( 0, 0 );
405+
TheMouse->syncPositionToSystemCursor();
406406
TheMouse->setMouseLimits();
407407
TheMouse->setName("TheMouse");
408408
}

0 commit comments

Comments
 (0)