From 8b3bae4cf3045c53c5fae89bc5dd9235b5b2997a Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 12 Jan 2026 01:30:08 -0500 Subject: [PATCH] Track latest started gamemode --- librecomp/include/librecomp/mods.hpp | 11 +++++++++- librecomp/src/mods.cpp | 32 ++++++++++++++++++++++++---- librecomp/src/recomp.cpp | 11 ++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/librecomp/include/librecomp/mods.hpp b/librecomp/include/librecomp/mods.hpp index c404109..d0bda55 100644 --- a/librecomp/include/librecomp/mods.hpp +++ b/librecomp/include/librecomp/mods.hpp @@ -307,7 +307,11 @@ namespace recomp { uint32_t pad; }; - typedef std::variant ModConfigQueueVariant; + struct ModConfigSetLatestGamemode { + uint32_t pad; + }; + + typedef std::variant ModConfigQueueVariant; class LiveRecompilerCodeHandle; class ModContext { @@ -345,6 +349,8 @@ namespace recomp { config::ConfigValueVariant get_mod_config_value(const std::string &mod_id, const std::string &option_id) const; void set_mods_config_path(const std::filesystem::path &path); void set_mod_config_directory(const std::filesystem::path &path); + std::string get_latest_game_mode_id() const; + void set_latest_game_mode_id(const std::string& game_mode_id); ModContentTypeId register_content_type(const ModContentType& type); bool register_container_type(const std::string& extension, const std::vector& content_types, bool requires_manifest); ModContentTypeId get_code_content_type() const { return code_content_type_id; } @@ -412,6 +418,7 @@ namespace recomp { ModContentTypeId code_content_type_id; ModContentTypeId rom_patch_content_type_id; size_t active_game = (size_t)-1; + std::string latest_game_mode; }; class ModCodeHandle { @@ -609,6 +616,8 @@ namespace recomp { void set_mod_config_value(const std::string &mod_id, const std::string &option_id, const config::ConfigValueVariant &value); config::ConfigValueVariant get_mod_config_value(size_t mod_index, const std::string &option_id); config::ConfigValueVariant get_mod_config_value(const std::string &mod_id, const std::string &option_id); + std::string get_latest_game_mode_id(); + void set_latest_game_mode_id(const std::string& game_mode_id); std::string get_mod_id_from_filename(const std::filesystem::path& mod_filename); std::filesystem::path get_mod_filename(const std::string& mod_id); size_t get_mod_order_index(const std::string& mod_id); diff --git a/librecomp/src/mods.cpp b/librecomp/src/mods.cpp index c26da02..2883661 100644 --- a/librecomp/src/mods.cpp +++ b/librecomp/src/mods.cpp @@ -658,7 +658,7 @@ bool save_mod_config_storage(const std::string &mod_id, const recomp::Version &m return config->save_config_json(config_json); } -bool parse_mods_config(const std::filesystem::path &path, std::unordered_set &enabled_mods, std::vector &mod_order) { +bool parse_mods_config(const std::filesystem::path &path, std::string& latest_game_mode, std::unordered_set &enabled_mods, std::vector &mod_order) { using json = nlohmann::json; json config_json; if (!read_json_with_backups(path, config_json)) { @@ -680,13 +680,25 @@ bool parse_mods_config(const std::filesystem::path &path, std::unordered_set(*mod_order_json, mod_order); } + auto latest_game_mode_json = config_json.find("latest_game_mode"); + if (latest_game_mode_json != config_json.end()) { + const std::string* temp_ptr = latest_game_mode_json->get_ptr(); + if (temp_ptr == nullptr) { + latest_game_mode = {}; + } + else { + latest_game_mode = *temp_ptr; + } + } + return true; } -bool save_mods_config(const std::filesystem::path &path, const std::unordered_set &enabled_mods, const std::vector &mod_order) { +bool save_mods_config(const std::filesystem::path &path, const std::string& latest_game_mode, const std::unordered_set &enabled_mods, const std::vector &mod_order) { nlohmann::json config_json; config_json["enabled_mods"] = enabled_mods; config_json["mod_order"] = mod_order; + config_json["latest_game_mode"] = latest_game_mode; std::ofstream output_file = recomp::open_output_file_with_backup(path); if (!output_file.good()) { @@ -723,6 +735,9 @@ void recomp::mods::ModContext::dirty_mod_configuration_thread_process() { else if (const ModConfigQueueSaveMod* queue_save_mod = std::get_if(&variant)) { pending_mods.emplace(queue_save_mod->mod_id); } + else if (const ModConfigSetLatestGamemode* set_latest_game_mode = std::get_if(&variant)) { + pending_config_save = true; + } }; while (active) { @@ -768,7 +783,7 @@ void recomp::mods::ModContext::dirty_mod_configuration_thread_process() { } } - save_mods_config(mods_config_path, config_enabled_mods, config_mod_order); + save_mods_config(mods_config_path, latest_game_mode, config_enabled_mods, config_mod_order); pending_config_save = false; } } @@ -828,7 +843,7 @@ void recomp::mods::ModContext::load_mods_config() { std::unordered_set config_enabled_mods; std::vector config_mod_order; std::vector opened_mod_is_known; - parse_mods_config(mods_config_path, config_enabled_mods, config_mod_order); + parse_mods_config(mods_config_path, latest_game_mode, config_enabled_mods, config_mod_order); // Fill a vector with the relative order of the mods. Existing mods will get ordered below new mods. std::vector sort_order; @@ -1507,6 +1522,15 @@ void recomp::mods::ModContext::set_mod_config_directory(const std::filesystem::p mod_config_directory = path; } +std::string recomp::mods::ModContext::get_latest_game_mode_id() const { + return latest_game_mode; +} + +void recomp::mods::ModContext::set_latest_game_mode_id(const std::string& game_mode_id) { + latest_game_mode = game_mode_id; + mod_configuration_thread_queue.enqueue(ModConfigSetLatestGamemode()); +} + std::vector recomp::mods::ModContext::load_mods(const GameEntry& game_entry, const std::string& game_mode_id, uint8_t* rdram, int32_t load_address, uint32_t& ram_used) { std::vector ret{}; ram_used = 0; diff --git a/librecomp/src/recomp.cpp b/librecomp/src/recomp.cpp index 985751f..e94a048 100644 --- a/librecomp/src/recomp.cpp +++ b/librecomp/src/recomp.cpp @@ -533,6 +533,7 @@ void recomp::start_game(const std::u8string& game_id, const std::string& game_mo current_game = game_id; game_status.store(GameStatus::Running); game_status.notify_all(); + mods::set_latest_game_mode_id(game_mode_id); } bool ultramodern::is_game_started() { @@ -601,6 +602,16 @@ recomp::config::ConfigValueVariant recomp::mods::get_mod_config_value(const std: return mod_context->get_mod_config_value(mod_id, option_id); } +std::string recomp::mods::get_latest_game_mode_id() { + std::lock_guard lock{ mod_context_mutex }; + return mod_context->get_latest_game_mode_id(); +} + +void recomp::mods::set_latest_game_mode_id(const std::string& game_mode_id) { + std::lock_guard lock{ mod_context_mutex }; + mod_context->set_latest_game_mode_id(game_mode_id); +} + std::string recomp::mods::get_mod_id_from_filename(const std::filesystem::path& mod_filename) { std::lock_guard lock { mod_context_mutex }; return mod_context->get_mod_id_from_filename(mod_filename);