aboutsummaryrefslogtreecommitdiff
path: root/src/yuzu_cmd/yuzu.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-27 12:00:22 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-27 12:00:22 -0400
commitad38a7d9f0a370fde7bc616ca191ca7894ede4f5 (patch)
tree014a25827fbf3e7cb4ad2812132a22fb27981b3e /src/yuzu_cmd/yuzu.cpp
parentfcec744e1a0de179738712cc36c830704fb4e46e (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/yuzu_cmd/yuzu.cpp')
-rw-r--r--src/yuzu_cmd/yuzu.cpp19
1 files changed, 11 insertions, 8 deletions
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;