From a76fdeee93cf1115b45cf2cdbdb2038ed41f4a4a Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 16 Oct 2021 03:23:27 +0200 Subject: [PATCH] DolphinQt: Act like Riivolution and pre-select the last selected patch options when launching via the RiivolutionBootWidget. --- .../Core/DolphinQt/RiivolutionBootWidget.cpp | 61 +++++++++++++++++-- Source/Core/DolphinQt/RiivolutionBootWidget.h | 5 +- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/Source/Core/DolphinQt/RiivolutionBootWidget.cpp b/Source/Core/DolphinQt/RiivolutionBootWidget.cpp index 8ad3e7745c..ecb4ac078a 100644 --- a/Source/Core/DolphinQt/RiivolutionBootWidget.cpp +++ b/Source/Core/DolphinQt/RiivolutionBootWidget.cpp @@ -3,6 +3,10 @@ #include "DolphinQt/RiivolutionBootWidget.h" +#include + +#include + #include #include #include @@ -81,12 +85,15 @@ void RiivolutionBootWidget::CreateWidgets() void RiivolutionBootWidget::LoadMatchingXMLs() { const std::string& riivolution_dir = File::GetUserPath(D_RIIVOLUTION_IDX); + const auto config = LoadConfigXML(riivolution_dir); for (const std::string& path : Common::DoFileSearch({riivolution_dir + "riivolution"}, {".xml"})) { auto parsed = DiscIO::Riivolution::ParseFile(path); if (!parsed || !parsed->IsValidForGame(m_game_id, m_revision, m_disc_number)) continue; - MakeGUIForParsedFile(path, *parsed); + if (config) + DiscIO::Riivolution::ApplyConfigDefaults(&*parsed, *config); + MakeGUIForParsedFile(path, riivolution_dir, *parsed); } } @@ -129,15 +136,19 @@ void RiivolutionBootWidget::OpenXML() continue; } - MakeGUIForParsedFile(p, *parsed); + auto root = FindRoot(p); + const auto config = LoadConfigXML(root); + if (config) + DiscIO::Riivolution::ApplyConfigDefaults(&*parsed, *config); + MakeGUIForParsedFile(p, std::move(root), *parsed); } } -void RiivolutionBootWidget::MakeGUIForParsedFile(const std::string& path, +void RiivolutionBootWidget::MakeGUIForParsedFile(const std::string& path, std::string root, DiscIO::Riivolution::Disc input_disc) { const size_t disc_index = m_discs.size(); - const auto& disc = m_discs.emplace_back(DiscWithRoot{std::move(input_disc), FindRoot(path)}); + const auto& disc = m_discs.emplace_back(DiscWithRoot{std::move(input_disc), std::move(root)}); auto* disc_box = new QGroupBox(QFileInfo(QString::fromStdString(path)).fileName()); auto* disc_layout = new QVBoxLayout(); @@ -206,8 +217,50 @@ void RiivolutionBootWidget::MakeGUIForParsedFile(const std::string& path, m_patch_section_layout->addWidget(disc_box); } +std::optional +RiivolutionBootWidget::LoadConfigXML(const std::string& root_directory) +{ + // The way Riivolution stores settings only makes sense for standard game IDs. + if (!(m_game_id.size() == 4 || m_game_id.size() == 6)) + return std::nullopt; + + return DiscIO::Riivolution::ParseConfigFile( + fmt::format("{}/riivolution/config/{}.xml", root_directory, m_game_id.substr(0, 4))); +} + +void RiivolutionBootWidget::SaveConfigXMLs() +{ + if (!(m_game_id.size() == 4 || m_game_id.size() == 6)) + return; + + std::unordered_map map; + for (const auto& disc : m_discs) + { + auto config = map.try_emplace(disc.root); + auto& config_options = config.first->second.m_options; + for (const auto& section : disc.disc.m_sections) + { + for (const auto& option : section.m_options) + { + std::string id = option.m_id.empty() ? (section.m_name + option.m_name) : option.m_id; + config_options.emplace_back( + DiscIO::Riivolution::ConfigOption{std::move(id), option.m_selected_choice}); + } + } + } + + for (const auto& config : map) + { + DiscIO::Riivolution::WriteConfigFile( + fmt::format("{}/riivolution/config/{}.xml", config.first, m_game_id.substr(0, 4)), + config.second); + } +} + void RiivolutionBootWidget::BootGame() { + SaveConfigXMLs(); + m_patches.clear(); for (const auto& disc : m_discs) { diff --git a/Source/Core/DolphinQt/RiivolutionBootWidget.h b/Source/Core/DolphinQt/RiivolutionBootWidget.h index d0f78dbb57..5200ca2151 100644 --- a/Source/Core/DolphinQt/RiivolutionBootWidget.h +++ b/Source/Core/DolphinQt/RiivolutionBootWidget.h @@ -30,7 +30,10 @@ private: void LoadMatchingXMLs(); void OpenXML(); - void MakeGUIForParsedFile(const std::string& path, DiscIO::Riivolution::Disc input_disc); + void MakeGUIForParsedFile(const std::string& path, std::string root, + DiscIO::Riivolution::Disc input_disc); + std::optional LoadConfigXML(const std::string& root_directory); + void SaveConfigXMLs(); void BootGame(); std::string m_game_id;