diff --git a/runtime/src/mod_runtime.cpp b/runtime/src/mod_runtime.cpp index ad35da1f..cd93d301 100644 --- a/runtime/src/mod_runtime.cpp +++ b/runtime/src/mod_runtime.cpp @@ -1462,6 +1462,12 @@ bool mod_runtime_netplay_content_negotiation() { return netplay_content_negotiation_enabled; } +/* Live option overrides (psx_mod_set_option_live) belong to one session's + * plan: initialising the runtime, committing a plan or switching to the + * netplay plan drops them, so a new plan's committed values are what the + * API answers (defined with the overrides below). */ +void reset_live_option_overrides(); + bool mod_runtime_initialize(const std::filesystem::path& root, const std::string& game_id, uint32_t game_entry_pc, @@ -1480,6 +1486,7 @@ bool mod_runtime_initialize(const std::filesystem::path& root, s.audio_tracks.clear(); s.extent_start = 0; s.plan = {}; + reset_live_option_overrides(); /* a new plan ends the last session's live values */ s.validation = {}; s.raw_disc_index.clear(); s.user_disc_index.clear(); @@ -1586,6 +1593,7 @@ bool mod_runtime_clear_for_netplay(std::string* error) { s.audio_tracks.clear(); s.extent_start = 0; s.plan = {}; + reset_live_option_overrides(); /* a new plan ends the last session's live values */ s.validation = {}; s.raw_disc_index.clear(); s.user_disc_index.clear(); @@ -1740,6 +1748,7 @@ bool mod_runtime_commit_netplay(const std::filesystem::path& disc_path, if (renderer) plan.plugins.push_back({renderer, "", ""}); s.disc_path = disc_path; s.plan = std::move(plan); + reset_live_option_overrides(); /* a new plan ends the last session's live values */ mod_runtime_set_session_plan_fp({}); psx_mod_netplay_set_active(1); std::fprintf(stdout, "psxrecomp: title netplay profile %s (%s)\n", @@ -2067,6 +2076,7 @@ static bool install_plan(RuntimeMods& s, ModResolution plan, s.audio_tracks.clear(); s.extent_start = 0; s.plan = std::move(plan); + reset_live_option_overrides(); /* a new plan ends the last session's live values */ { HostLaunchTimingScope index_timing(HOST_LAUNCH_BUILD_DISC_INDEX); build_disc_index(s); @@ -2870,6 +2880,10 @@ extern "C" int psx_mod_save_selection(void) { return 1; } +namespace PSXRecompV4 { +void reset_live_option_overrides() { live_option_values().clear(); } +} // namespace PSXRecompV4 + extern "C" int psx_mod_set_option_live(const char* package_id, const char* feature_id, const char* option_id, const char* value) { using namespace PSXRecompV4; diff --git a/runtime/tests/test_mod_runtime.cpp b/runtime/tests/test_mod_runtime.cpp index ad8ff7d8..08ee4d9f 100644 --- a/runtime/tests/test_mod_runtime.cpp +++ b/runtime/tests/test_mod_runtime.cpp @@ -1124,6 +1124,17 @@ int main(int argc, char** argv) { std::string(value) == "four", "a refused live set must not change the value later reads see"); option_changed_refuse = 0; + /* A new session (initialise + commit) answers its own committed + * plan, not the previous session's live override. */ + check(PSXRecompV4::mod_runtime_initialize( + req_root, "SLUS-REQ", 0x80002000, {}, &error), + error.c_str()); + check(PSXRecompV4::mod_runtime_commit(stock_path, &error), + "the second session must commit"); + mod_runtime_activate_plugins(); + check(psx_mod_option_value("runtime.ram", "big-ram", "size", value, sizeof(value)) == 1 && + std::string(value) == "eight", + "a live override must not outlive its session's plan"); check(psx_mod_set_option_live("runtime.ram", "no-such-feature", "size", "x") == 0, "features outside the plan are not live-settable"); check(psx_mod_save_selection() == 1, "saving the selection mid-session must succeed");