diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 12:00:22 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 12:00:22 -0400 |
| commit | ad38a7d9f0a370fde7bc616ca191ca7894ede4f5 (patch) | |
| tree | 014a25827fbf3e7cb4ad2812132a22fb27981b3e /src | |
| parent | fcec744e1a0de179738712cc36c830704fb4e46e (diff) | |
eden-cli: fix SDL3 main-callback lifetime bugs
- SDL_AppInit never stored *appstate, so every later callback got null.
- SDL_AppInit/SDL_AppEvent returned SDL_APP_SUCCESS, which tells SDL3 to
quit; they must return SDL_APP_CONTINUE.
- InputSubsystem was a local in SDL_AppInit but the window and its timers
keep a pointer to it; keep it in SdlState, ahead of the window.
- Guard the mouse timer against firing before the mouse driver exists.
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl3.cpp | 5 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 19 |
2 files changed, 15 insertions, 9 deletions
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp index 950e001f81..f2026e9722 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp @@ -39,7 +39,10 @@ EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Co }, this); mouse_timer = SDL_AddTimer(100, [](void *userdata, SDL_TimerID, Uint32) -> Uint32 { auto* this_ = (EmuWindow_SDL3*)userdata; - this_->input_subsystem->GetMouse()->NotifyChanged(); + // The timer can fire before the input subsystem has created its mouse driver. + if (auto* const mouse = this_->input_subsystem->GetMouse()) { + mouse->NotifyChanged(); + } return 100; }, this); } diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 473a5b1014..088141a251 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -159,11 +159,14 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) { struct SdlState { Core::System system{}; + // Must outlive emu_window, which keeps a pointer to it. + InputCommon::InputSubsystem input_subsystem{}; std::unique_ptr<EmuWindow_SDL3> emu_window; }; extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { SdlState* state = new SdlState(); + *appstate = state; #ifdef _WIN32 if (AttachConsole(ATTACH_PARENT_PROCESS)) { @@ -202,7 +205,6 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { state->system.Initialize(); - InputCommon::InputSubsystem input_subsystem{}; // Apply the command line arguments state->system.ApplySettings(); @@ -212,14 +214,14 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { case Settings::RendererBackend::OpenGL_GLSL: case Settings::RendererBackend::OpenGL_GLASM: case Settings::RendererBackend::OpenGL_SPIRV: - state->emu_window = std::make_unique<EmuWindow_SDL3_GL>(&input_subsystem, state->system, lp.fullscreen); + state->emu_window = std::make_unique<EmuWindow_SDL3_GL>(&state->input_subsystem, state->system, lp.fullscreen); break; #endif case Settings::RendererBackend::Vulkan: - state->emu_window = std::make_unique<EmuWindow_SDL3_VK>(&input_subsystem, state->system, lp.fullscreen); + state->emu_window = std::make_unique<EmuWindow_SDL3_VK>(&state->input_subsystem, state->system, lp.fullscreen); break; case Settings::RendererBackend::Null: - state->emu_window = std::make_unique<EmuWindow_SDL3_Null>(&input_subsystem, state->system, lp.fullscreen); + state->emu_window = std::make_unique<EmuWindow_SDL3_Null>(&state->input_subsystem, state->system, lp.fullscreen); break; default: LOG_CRITICAL(Frontend, "Invalid renderer backend"); @@ -319,16 +321,17 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { void(state->system.Run()); if (state->system.DebuggerEnabled()) state->system.InitializeDebugger(); - return SDL_APP_SUCCESS; + return SDL_APP_CONTINUE; } extern "C" SDL_AppResult SDL_AppIterate(void *appstate) { SdlState *state = (SdlState *)appstate; - return state->emu_window->IsOpen() ? SDL_APP_CONTINUE : SDL_APP_SUCCESS; + return state->emu_window && state->emu_window->IsOpen() ? SDL_APP_CONTINUE : SDL_APP_SUCCESS; } extern "C" SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { SdlState *state = (SdlState *)appstate; - state->emu_window->OnEvent(*event); - return SDL_APP_SUCCESS; + if (state->emu_window) + state->emu_window->OnEvent(*event); + return SDL_APP_CONTINUE; } extern "C" void SDL_AppQuit(void *appstate, SDL_AppResult result) { SdlState *state = (SdlState *)appstate; |
