diff --git a/mods/randomizer/CMakeLists.txt b/mods/randomizer/CMakeLists.txt index e91e45a3f1..d040aa7a9f 100644 --- a/mods/randomizer/CMakeLists.txt +++ b/mods/randomizer/CMakeLists.txt @@ -85,6 +85,8 @@ set(RANDOMIZER_SOURCES src/verify_item_functions.cpp src/paths.cpp src/session.cpp + src/ui/config_store.cpp + src/ui/rando_seed_generation.cpp ) # Embed the generator's YAML data into the mod library. Paths are relative to this diff --git a/mods/randomizer/src/ui/config_store.cpp b/mods/randomizer/src/ui/config_store.cpp new file mode 100644 index 0000000000..f14867efc9 --- /dev/null +++ b/mods/randomizer/src/ui/config_store.cpp @@ -0,0 +1,45 @@ +#include "config_store.hpp" + +#include + +#include "../../generator/seedgen/seed.hpp" +#include "../paths.hpp" + +namespace randomizer::ui { + +seedgen::config::Config& GetRandomizerConfig() { + static seedgen::config::Config s_config{paths::GetRandomizerSettingsPath(), + paths::GetRandomizerPreferencesPath()}; + return s_config; +} + +void SaveRandomizerConfig() { + GetRandomizerConfig().WriteToFile(paths::GetRandomizerSettingsPath(), + paths::GetRandomizerPreferencesPath()); +} + +seedgen::settings::Setting* FindSetting(const std::string& key) { + if (key.empty()) { + return nullptr; + } + auto& settings = GetRandomizerConfig().GetSettings(); + auto& map = settings.GetMap(); + auto it = map.find(key); + if (it == map.end()) { + mods::log::error("randomizer: failed to get settings key: {}", key); + return nullptr; + } + return &it->second; +} + +bool TryCreateRandomSeed() { + auto& config = GetRandomizerConfig(); + if (config.GetSeed().empty()) { + config.SetSeed(seedgen::seed::GenerateSeed()); + SaveRandomizerConfig(); + return true; + } + return false; +} + +} // namespace randomizer::ui diff --git a/mods/randomizer/src/ui/config_store.hpp b/mods/randomizer/src/ui/config_store.hpp new file mode 100644 index 0000000000..c0cd805a71 --- /dev/null +++ b/mods/randomizer/src/ui/config_store.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include "../../generator/seedgen/config.hpp" +#include "../../generator/seedgen/settings.hpp" + +namespace randomizer::ui { + +seedgen::config::Config& GetRandomizerConfig(); +void SaveRandomizerConfig(); +seedgen::settings::Setting* FindSetting(const std::string& key); +bool TryCreateRandomSeed(); + +} // namespace randomizer::ui diff --git a/mods/randomizer/src/ui/rando_seed_generation.cpp b/mods/randomizer/src/ui/rando_seed_generation.cpp new file mode 100644 index 0000000000..5daf9735d7 --- /dev/null +++ b/mods/randomizer/src/ui/rando_seed_generation.cpp @@ -0,0 +1,104 @@ +#include "rando_seed_generation.hpp" + +#include + +#include "../session.hpp" +#include "../randomizer_context.hpp" + +#include "m_Do/m_Do_audio.h" + +#include +#include +#include + +namespace randomizer::ui { +enum class SeedGenerateStatus { + Ready, + Generating, + Success, + Error, +}; + +UiDialogHandle seedGenDialog{0}; +static std::atomic seedGenStatus = SeedGenerateStatus::Ready; +static std::string generationStatusMsg{}; + +void OnDialogActionOK(ModContext* ctx, UiDialogHandle dialogHandle, void*) { + mDoAud_seStartMenu(Z2SE_SY_MENU_BACK); + session::svc_mng.ui->dialog_close(ctx, dialogHandle); +} + +static void StartSeedGeneration() { + if (GenerateAndWriteSeed(generationStatusMsg)) { + seedGenStatus.store(SeedGenerateStatus::Success); + } else { + seedGenStatus.store(SeedGenerateStatus::Error); + } + + mods::log::debug("{}", generationStatusMsg); +} + +static ModResult buildDialog() { + UiDialogDesc desc = UI_DIALOG_DESC_INIT; + desc.title = "Randomizer"; + desc.body_rml = "Generating Seed..."; + desc.icon = "verifying"; + desc.variant = UI_DIALOG_NORMAL; + + UiDialogAction action = { + .label = "OK", + .on_pressed = OnDialogActionOK, + .user_data = nullptr, + .keep_open = false, + }; + desc.actions = &action; + desc.action_count = 1; + + if (session::svc_mng.ui->dialog_push(session::svc_mng.mod_ctx, &desc, &seedGenDialog) != MOD_OK) { + mods::log::error("Failed to push dialog"); + return MOD_ERROR; + } + + return MOD_OK; +} + +void GenerateRandomizerSeed() { + if (buildDialog() != MOD_OK) { + return; + } + + // Start generation thread + seedGenStatus.store(SeedGenerateStatus::Generating); + std::thread rando_gen_thread(StartSeedGeneration); + rando_gen_thread.detach(); +} + +ModResult UpdateSeedGenerationDialog() { + if (seedGenDialog == 0) { + return MOD_OK; + } + + auto curSeedGenStatus = seedGenStatus.load(); + + // Change the modal text if we've finished attempting to generate + if (curSeedGenStatus == SeedGenerateStatus::Success || + curSeedGenStatus == SeedGenerateStatus::Error) + { + auto* ctx = session::svc_mng.mod_ctx; + auto* ui_svc = session::svc_mng.ui; + + if (curSeedGenStatus == SeedGenerateStatus::Success) { + mDoAud_seStartMenu(Z2SE_SY_FILE_SAVE_OK); + ui_svc->dialog_set_icon(ctx, seedGenDialog, "celebration"); + } else { + mDoAud_seStartMenu(Z2SE_SYS_RESULT_WRONG); + ui_svc->dialog_set_icon(ctx, seedGenDialog, "error"); + } + + ui_svc->dialog_set_body(ctx, seedGenDialog, generationStatusMsg.c_str()); + seedGenStatus.store(SeedGenerateStatus::Ready); + } + + return MOD_OK; +} +} \ No newline at end of file diff --git a/mods/randomizer/src/ui/rando_seed_generation.hpp b/mods/randomizer/src/ui/rando_seed_generation.hpp new file mode 100644 index 0000000000..92df6e6937 --- /dev/null +++ b/mods/randomizer/src/ui/rando_seed_generation.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace randomizer::ui { + +void GenerateRandomizerSeed(); +ModResult UpdateSeedGenerationDialog(); + +}