From d44d8649e373202a714e50fd51b9bf2b2be5980b Mon Sep 17 00:00:00 2001 From: Rix Date: Sat, 10 Oct 2026 11:30:59 -0700 Subject: [PATCH] Play on Windows: run pcsx-redux.main, ignore stale tool paths pcsx-redux.exe relaunches pcsx-redux.main through the shell and exits, so the editor waited on a pid that never creates the display block and Play showed nothing. A saved tool path that no longer exists now falls through to the environment and the package instead of asking for the file again. --- src/editor/play.cpp | 21 +++++++++++++++++++++ src/editor/tests/editor_tests.cpp | 26 ++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/editor/play.cpp b/src/editor/play.cpp index 89bbcb6..75b7b04 100644 --- a/src/editor/play.cpp +++ b/src/editor/play.cpp @@ -91,7 +91,27 @@ static void fromBundle(fs::path& p, const fs::path& bundle, std::initializer_lis } } +// A saved path that no longer exists (an old build, a moved folder) must not +// hide the copy the package carries. +static void dropMissing(fs::path& p) { + std::error_code ec; + if (!p.empty() && !fs::is_regular_file(p, ec)) p.clear(); +} + +// On Windows pcsx-redux.exe only relaunches pcsx-redux.main through the shell and +// exits, so its pid never owns the display block and its output is lost. Run +// the real binary when it sits beside the launcher. +static void skipLauncher(fs::path& p) { + std::error_code ec; + if (p.filename() != "pcsx-redux.exe") return; + fs::path main = p.parent_path() / "pcsx-redux.main"; + if (fs::is_regular_file(main, ec)) p = main; +} + PlayTools withDefaults(PlayTools t, const fs::path& bundle) { + dropMissing(t.redux); + dropMissing(t.psxsplash); + dropMissing(t.disc); fromEnv(t.redux, "SPLASHEDIT_REDUX"); fromEnv(t.psxsplash, "SPLASHEDIT_PSXSPLASH"); fromEnv(t.bios, "SPLASHEDIT_BIOS"); @@ -103,6 +123,7 @@ PlayTools withDefaults(PlayTools t, const fs::path& bundle) { fromBundle(t.psxsplash, bundle, {"engine/psxsplash.ps-exe"}); fromBundle(t.disc, bundle, {"engine/psxsplash-cdrom.ps-exe"}); if (t.redux.empty()) t.redux = onPath("pcsx-redux"); + skipLauncher(t.redux); return t; } diff --git a/src/editor/tests/editor_tests.cpp b/src/editor/tests/editor_tests.cpp index fcbe212..ac11dac 100644 --- a/src/editor/tests/editor_tests.cpp +++ b/src/editor/tests/editor_tests.cpp @@ -723,8 +723,14 @@ void testPlay() { // Environment fills only what the settings left empty. setEnv("SPLASHEDIT_PSXSPLASH", "/env/psxsplash.ps-exe"); setEnv("SPLASHEDIT_REDUX", "/env/pcsx-redux"); - editor::PlayTools e = editor::withDefaults(l); - CHECK(e.redux == t.redux && e.psxsplash == t.psxsplash); + editor::PlayTools onDisk = l; + onDisk.redux = cfg; // an existing file stands in for the programs + onDisk.psxsplash = cfg; + editor::PlayTools e = editor::withDefaults(onDisk); + CHECK(e.redux == cfg && e.psxsplash == cfg); + // A saved path that is gone falls through to what is there now. + editor::PlayTools gone = editor::withDefaults(l); + CHECK(gone.redux == fs::path("/env/pcsx-redux") && gone.psxsplash == fs::path("/env/psxsplash.ps-exe")); editor::PlayTools e2 = editor::withDefaults({}); CHECK(e2.redux == fs::path("/env/pcsx-redux") && e2.psxsplash == fs::path("/env/psxsplash.ps-exe")); @@ -752,6 +758,22 @@ void testPlay() { CHECK(editor::missingDiscTools(fromBundle).empty()); editor::PlayTools empty = editor::withDefaults({}, dir / "nothing-here"); CHECK(empty.psxsplash.empty()); + // A stale saved build loses to the packaged one. + editor::PlayTools stale; + stale.psxsplash = dir / "old-build" / "psxsplash.ps-exe"; + CHECK(editor::withDefaults(stale, bundle).psxsplash == bundle / "engine" / "psxsplash.ps-exe"); + + // Windows: the pcsx-redux.exe launcher hands off to pcsx-redux.main, so + // Play runs .main directly when it is there. + fs::path win = dir / "winbundle"; + fs::create_directories(win / "redux"); + std::ofstream(win / "redux" / "pcsx-redux.exe") << "x"; + CHECK(editor::withDefaults({}, win).redux == win / "redux" / "pcsx-redux.exe"); + std::ofstream(win / "redux" / "pcsx-redux.main") << "x"; + CHECK(editor::withDefaults({}, win).redux == win / "redux" / "pcsx-redux.main"); + editor::PlayTools picked; + picked.redux = win / "redux" / "pcsx-redux.exe"; + CHECK(editor::withDefaults(picked).redux == win / "redux" / "pcsx-redux.main"); // What is missing, and the command once nothing is. CHECK(editor::missingTools({}).size() == 2);