feat(input): Implement SDL3 input and window management - #2639
feat(input): Implement SDL3 input and window management#2639githubawn wants to merge 47 commits into
Conversation
a785545 to
7cc0861
Compare
|
| Filename | Overview |
|---|---|
| Core/GameEngineDevice/Source/SDL3Device/GameClient/SDL3Input.cpp | Core of the SDL3 input backend — implements SDL3Mouse, SDL3Keyboard, and SDL3InputManager with a ring-buffer event queue, gamepad support, and virtual event injection; has minor style issues in closeGamepad() (if-bodies on same line) and a redundant left-stick axis read, but all previously flagged functional bugs appear fixed. |
| Core/GameEngineDevice/Include/SDL3Device/GameClient/SDL3Input.h | Header for SDL3 input classes; previously flagged scancode truncation and missing m_SDLWindow member are now fixed; dead-code field m_IsCaptured is the only remaining issue. |
| Core/GameEngineDevice/Source/SDL3Device/GameClient/SDL3Cursor.cpp | ANI cursor loader using SDL3_image; previous direction-count bounds issue is fixed with the loop guard; now uses SDL3's native SDL_CreateAnimatedCursor instead of a hand-rolled frame array. |
| Core/GameEngineDevice/Source/SDL3Device/Common/SDL3GameEngine.cpp | SDL3 game-engine lifecycle: window/input-manager setup, minimized-loop with throttle and LAN keep-alive, and UTF-8 text input forwarding; headless path now correctly falls through to GameEngine::init(). |
| Core/Main/SDL3Main.cpp | SDL3 entry point: SDL_Init, window creation, splash-screen blit, and game main loop; SDL_Init failure correctly returns early; headless path skips SDL entirely. |
| Core/Main/AppMain.cpp | New shared application lifecycle helper (initBeforeWindow, initAfterWindow, run, shutdown) refactored out of both WinMain files; centralises critical-section setup, version management, and instance-mutex logic. |
| Core/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | Extended with controller-aware scrolling: setControllerInputActive() stops screen-edge scroll when the stick is active, getControllerScrollScale() slows key-scroll relative to zoom; setScrolling/stopScrolling null-guards for all global pointers now added; previously flagged side-effect regressions are resolved. |
| Generals/Code/Main/WinMain.cpp | Refactored to delegate lifecycle calls to AppMain; removes duplicate startup code; no functional regressions visible. |
| GeneralsMD/Code/Main/WinMain.cpp | Same AppMain refactor as the Generals WinMain; stub SDL3 surface variable added under RTS_SDL3_ENABLE guard for future splash support. |
Sequence Diagram
sequenceDiagram
participant OS as OS / Hardware
participant SDL3 as SDL3 Event Pump
participant IM as SDL3InputManager
participant KB as SDL3Keyboard
participant MS as SDL3Mouse
participant GP as Gamepad subsystem
participant GE as SDL3GameEngine
participant LX as LookAtTranslator
participant GC as GameClient
OS->>SDL3: Raw input (keyboard/mouse/gamepad)
GE->>IM: update() [each frame via pollSDL3Events]
IM->>SDL3: SDL_PollEvent loop
SDL3-->>IM: SDL_Event
IM->>IM: Route: key → addKeyboardSDLEvent mouse → addMouseSDLEvent
IM->>GP: processGamepadInput()
GP->>GP: Read axes and buttons
GP->>IM: virtualPulseKey() / virtualPulseMouse()
GP->>LX: setControllerInputActive(bool)
LX->>LX: Suppress edge-scroll, scale key-scroll
GC->>KB: getKey() [keyboard poll]
KB->>IM: getNextKeyboardEvent()
IM-->>KB: SDL_KeyboardEvent
KB-->>GC: KeyboardIO
GC->>MS: getMouseEvent() [mouse poll]
MS->>IM: getNextMouseEvent()
IM-->>MS: SDL_MouseEvent
MS->>MS: translateEvent then scaleMouseCoordinates
MS-->>GC: MouseIO (scaled coords)
Reviews (37): Last reviewed commit: "greptile feedback" | Re-trigger Greptile
e365605 to
627ef23
Compare
eb9908a to
534e694
Compare
xezon
left a comment
There was a problem hiding this comment.
This needs polishing. Not yet reviewed extensively until the obvious style issues are fixed.
|
Perhaps also check Fighter19's fork for SDL related implementations. As far as I am aware he has it all done. |
|
I have looked at all existing forks and attributed where possible. |
|
How about changing display-mode? eg getDisplayModeCount() / getDisplayModeDescription() using SDL_GetFullscreenDisplayModes + desktop mode + resolution filtering. EDIT: Also account for mouse position which can sometimes not match clicks to cursor position. |
|
Is it better to use SDL3InputManager (+ SDL3CursorManager) or to split out SDL3Keyboard + SDL3Mouse that subclass the engine's existing Keyboard/Mouse base classes? |
|
I've started cleaning up the style and structural issues in the latest commits. Regarding SDL3Main: The main benefit of the current approach is that we keep the game's native Win32 WinMain entry point and startup sequence intact. To get rid of the #ifdef blocks in WinMain while minimizing duplication, I can move the window initialization out into SDL3Window. Regarding splitting out subclasses: I don't think splitting the input handling into isolated SDL3Keyboard and SDL3Mouse subclasses is the right way. It runs contrary to how SDL3 tries to be a unified way; it relies on a single event pump where all keyboard, mouse, and gamepad signals flow together. |
But this is how you currently have set this up. What is the plan here? |
|
It's improved a lot. I left more comments - also, there are thousands of lines changed in MainMenuUtils.cpp, CHATAPI.cpp, and both OptionsMenu.cpp that are just line ending stuff, could remove that and let a formatting pass deal with it later. My stack has working implementations of several of the inline items (close → MSG_META_DEMO_INSTANT_QUIT routing, focus → setIsActive + keyboard reset, Return → GWM_IME_CHAR commit, cursor position sync, deferred resize) if you want to lift from them. |
0acb86c to
3bd8573
Compare
Co-authored-by: Bobby Battista <bobtista@gmail.com>
…backport # Conflicts: # GeneralsMD/Code/Main/CMakeLists.txt
|
I think you pinged the wrong greptile |
|
/agentic_review |
SDL3 loads .ani cursors via TheFileSystem rather than Win32's LoadCursorFromFile, enabling cursor loading from .BIG archives and virtual filesystems. Add a non-positive size check before allocating memory buffers to handle empty or invalid files safely.
- Use event.wheel.mouse_x/y directly instead of calling SDL_GetMouseState, ensuring accurate cursor position at the exact moment of the wheel event. - Replace Win32 timeGetTime() with SDL keyEvent.timestamp in SDL3Keyboard::getKey for portable millisecond key-down timing. - Replace Win32 VK_RETURN macro with character code 13 in IME Return key dispatch.
…ameEngine::getTicksMsec()
combo box text dropping fixed
SDL3 Input Backend
This PR updates the windowing and input pipeline to use SDL3 by default on modern toolchains (non-VC6 builds) to DirectInput and Win32 window creation. By utilizing SDL3, we bypass DirectInput emulation layers on modern systems, providing a lower-latency pipeline for Windows 11 and Wine/Linux users.
Input handling
Unified event manager that centralizes keyboard, mouse, and gamepad events into a thread-safe buffer
Gamepad Support (v0.1)
This is an initial baseline implementation focused on providing functional out-of-the-box playability. Feedback is encouraged regarding the ergonomics and logic of these default mappings.
Scope Note: This implementation provides a hardcoded default layout to establish core functionality. Advanced features, such as input remapping, radial menus, adjustable deadzones, are currently out of scope for this PR and may be addressed in future iterations.
This SDL3 input/windowing backend builds on prior work from the community: