From 535bca7d9f81baa4bd4244903fbb2f3434edde1f Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:05:44 +0300 Subject: [PATCH] Move config implementations to a .cpp file. (#133) --- UnleashedRecomp/app.cpp | 1 + UnleashedRecomp/locale/config_locale.cpp | 4 +- UnleashedRecomp/ui/installer_wizard.cpp | 1 + UnleashedRecomp/user/config.cpp | 464 +++++++++++++++++++ UnleashedRecomp/user/config.h | 541 ++--------------------- UnleashedRecomp/user/config_def.h | 83 ++++ 6 files changed, 588 insertions(+), 506 deletions(-) create mode 100644 UnleashedRecomp/user/config_def.h diff --git a/UnleashedRecomp/app.cpp b/UnleashedRecomp/app.cpp index c485193..a8bff74 100644 --- a/UnleashedRecomp/app.cpp +++ b/UnleashedRecomp/app.cpp @@ -7,6 +7,7 @@ #include #include #include +#include void App::Restart(std::vector restartArgs) { diff --git a/UnleashedRecomp/locale/config_locale.cpp b/UnleashedRecomp/locale/config_locale.cpp index 6d95c97..36871dc 100644 --- a/UnleashedRecomp/locale/config_locale.cpp +++ b/UnleashedRecomp/locale/config_locale.cpp @@ -19,10 +19,10 @@ */ #define CONFIG_DEFINE_LOCALE(name) \ - CONFIG_LOCALE Config::g_##name##_locale = + CONFIG_LOCALE g_##name##_locale = #define CONFIG_DEFINE_ENUM_LOCALE(type) \ - CONFIG_ENUM_LOCALE(type) Config::g_##type##_locale = + CONFIG_ENUM_LOCALE(type) g_##type##_locale = CONFIG_DEFINE_LOCALE(Language) { diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index 2f77444..230e999 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/UnleashedRecomp/user/config.cpp b/UnleashedRecomp/user/config.cpp index 7d0b235..0696ad2 100644 --- a/UnleashedRecomp/user/config.cpp +++ b/UnleashedRecomp/user/config.cpp @@ -1,5 +1,469 @@ #include "config.h" #include +#include +#include + +std::vector g_configDefinitions; + +#define CONFIG_DEFINE_ENUM_TEMPLATE(type) \ + static std::unordered_map g_##type##_template = + +CONFIG_DEFINE_ENUM_TEMPLATE(ELanguage) +{ + { "English", ELanguage::English }, + { "Japanese", ELanguage::Japanese }, + { "German", ELanguage::German }, + { "French", ELanguage::French }, + { "Spanish", ELanguage::Spanish }, + { "Italian", ELanguage::Italian } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EUnleashGaugeBehaviour) +{ + { "Original", EUnleashGaugeBehaviour::Original }, + { "Revised", EUnleashGaugeBehaviour::Revised } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ETimeOfDayTransition) +{ + { "Xbox", ETimeOfDayTransition::Xbox }, + { "PlayStation", ETimeOfDayTransition::PlayStation } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EControllerIcons) +{ + { "Auto", EControllerIcons::Auto }, + { "Xbox", EControllerIcons::Xbox }, + { "PlayStation", EControllerIcons::PlayStation } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) +{ + { "English", EVoiceLanguage::English }, + { "Japanese", EVoiceLanguage::Japanese } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) +{ +#ifdef SWA_D3D12 + { "D3D12", EGraphicsAPI::D3D12 }, +#endif + { "Vulkan", EGraphicsAPI::Vulkan } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EWindowState) +{ + { "Normal", EWindowState::Normal }, + { "Maximised", EWindowState::Maximised }, + { "Maximized", EWindowState::Maximised } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EAspectRatio) +{ + { "Auto", EAspectRatio::Auto }, + { "16:9", EAspectRatio::Wide }, + { "4:3", EAspectRatio::Narrow }, + { "Original 4:3", EAspectRatio::OriginalNarrow }, +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ETripleBuffering) +{ + { "Auto", ETripleBuffering::Auto }, + { "On", ETripleBuffering::On }, + { "Off", ETripleBuffering::Off } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EAntiAliasing) +{ + { "None", EAntiAliasing::None }, + { "2x MSAA", EAntiAliasing::MSAA2x }, + { "4x MSAA", EAntiAliasing::MSAA4x }, + { "8x MSAA", EAntiAliasing::MSAA8x } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EShadowResolution) +{ + { "Original", EShadowResolution::Original }, + { "512", EShadowResolution::x512 }, + { "1024", EShadowResolution::x1024 }, + { "2048", EShadowResolution::x2048 }, + { "4096", EShadowResolution::x4096 }, + { "8192", EShadowResolution::x8192 }, +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EGITextureFiltering) +{ + { "Bilinear", EGITextureFiltering::Bilinear }, + { "Bicubic", EGITextureFiltering::Bicubic } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EDepthOfFieldQuality) +{ + { "Auto", EDepthOfFieldQuality::Auto }, + { "Low", EDepthOfFieldQuality::Low }, + { "Medium", EDepthOfFieldQuality::Medium }, + { "High", EDepthOfFieldQuality::High }, + { "Ultra", EDepthOfFieldQuality::Ultra } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EMotionBlur) +{ + { "Off", EMotionBlur::Off }, + { "Original", EMotionBlur::Original }, + { "Enhanced", EMotionBlur::Enhanced } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ECutsceneAspectRatio) +{ + { "Original", ECutsceneAspectRatio::Original }, + { "Unlocked", ECutsceneAspectRatio::Unlocked } +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EUIScaleMode) +{ + { "Edge", EUIScaleMode::Edge }, + { "Centre", EUIScaleMode::Centre }, + { "Center", EUIScaleMode::Centre } +}; + +#undef CONFIG_DEFINE +#define CONFIG_DEFINE(section, type, name, defaultValue) \ + ConfigDef Config::name{section, #name, defaultValue}; + +#undef CONFIG_DEFINE_HIDDEN +#define CONFIG_DEFINE_HIDDEN(section, type, name, defaultValue) \ + ConfigDef Config::name{section, #name, defaultValue}; + +#undef CONFIG_DEFINE_LOCALISED +#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) \ + extern CONFIG_LOCALE g_##name##_locale; \ + ConfigDef Config::name{section, #name, &g_##name##_locale, defaultValue}; + +#undef CONFIG_DEFINE_ENUM +#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) \ + ConfigDef Config::name{section, #name, defaultValue, &g_##type##_template}; + +#undef CONFIG_DEFINE_ENUM_LOCALISED +#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) \ + extern CONFIG_LOCALE g_##name##_locale; \ + extern CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ + ConfigDef Config::name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; + +#undef CONFIG_DEFINE_CALLBACK +#define CONFIG_DEFINE_CALLBACK(section, type, name, defaultValue, readCallback) \ + extern CONFIG_LOCALE g_##name##_locale; \ + ConfigDef Config::name{section, #name, defaultValue, [](ConfigDef* def) readCallback}; + +#include "config_def.h" + +// CONFIG_DEFINE +template +ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue) : Section(section), Name(name), DefaultValue(defaultValue) +{ + g_configDefinitions.emplace_back(this); +} + +// CONFIG_DEFINE_LOCALISED +template +ConfigDef::ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue) +{ + g_configDefinitions.emplace_back(this); +} + +// CONFIG_DEFINE_ENUM +template +ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate) : Section(section), Name(name), DefaultValue(defaultValue), EnumTemplate(enumTemplate) +{ + for (const auto& pair : *EnumTemplate) + EnumTemplateReverse[pair.second] = pair.first; + + g_configDefinitions.emplace_back(this); +} + +// CONFIG_DEFINE_ENUM_LOCALISED +template +ConfigDef::ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue), EnumTemplate(enumTemplate), EnumLocale(enumLocale) +{ + for (const auto& pair : *EnumTemplate) + EnumTemplateReverse[pair.second] = pair.first; + + g_configDefinitions.emplace_back(this); +} + +// CONFIG_DEFINE_CALLBACK +template +ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback) : Section(section), Name(name), DefaultValue(defaultValue), Callback(callback) +{ + g_configDefinitions.emplace_back(this); +} + +template +ConfigDef::~ConfigDef() = default; + +template +bool ConfigDef::IsHidden() +{ + return isHidden && !IsLoadedFromConfig; +} + +template +void ConfigDef::ReadValue(toml::v3::ex::parse_result& toml) +{ + if (auto pSection = toml[Section].as_table()) + { + const auto& section = *pSection; + + if constexpr (std::is_same::value) + { + Value = section[Name].value_or(DefaultValue); + } + else if constexpr (std::is_enum_v) + { + auto value = section[Name].value_or(std::string()); + auto it = EnumTemplate->find(value); + + if (it != EnumTemplate->end()) + { + Value = it->second; + } + else + { + Value = DefaultValue; + } + } + else + { + Value = section[Name].value_or(DefaultValue); + } + + if (Callback) + Callback(this); + + if (pSection->contains(Name)) + IsLoadedFromConfig = true; + } +} + +template +void ConfigDef::MakeDefault() +{ + Value = DefaultValue; +} + +template +std::string_view ConfigDef::GetSection() const +{ + return Section; +} + +template +std::string_view ConfigDef::GetName() const +{ + return Name; +} + +template +std::string ConfigDef::GetNameLocalised(ELanguage language) const +{ + if (!Locale) + return Name; + + if (!Locale->count(language)) + { + if (Locale->count(ELanguage::English)) + { + return std::get<0>(Locale->at(ELanguage::English)); + } + else + { + return Name; + } + } + + return std::get<0>(Locale->at(language)); +} + +template +std::string ConfigDef::GetDescription(ELanguage language) const +{ + if (!Locale) + return ""; + + if (!Locale->count(language)) + { + if (Locale->count(ELanguage::English)) + { + return std::get<1>(Locale->at(ELanguage::English)); + } + else + { + return ""; + } + } + + return std::get<1>(Locale->at(language)); +} + +template +bool ConfigDef::IsDefaultValue() const +{ + return Value == DefaultValue; +} + +template +const void* ConfigDef::GetValue() const +{ + return &Value; +} + +template +std::string ConfigDef::GetValueLocalised(ELanguage language) const +{ + CONFIG_ENUM_LOCALE(T)* locale = nullptr; + + if constexpr (std::is_enum_v) + { + locale = EnumLocale; + } + else if constexpr (std::is_same_v) + { + return Value + ? Localise("Common_On") + : Localise("Common_Off"); + } + + if (!locale) + return ToString(false); + + if (!locale->count(language)) + { + if (locale->count(ELanguage::English)) + { + language = ELanguage::English; + } + else + { + return ToString(false); + } + } + + auto strings = locale->at(language); + + if (!strings.count(Value)) + return ToString(false); + + return std::get<0>(strings.at(Value)); +} + +template +std::string ConfigDef::GetValueDescription(ELanguage language) const +{ + CONFIG_ENUM_LOCALE(T)* locale = nullptr; + + if constexpr (std::is_enum_v) + { + locale = EnumLocale; + } + else if constexpr (std::is_same_v) + { + return ""; + } + + if (!locale) + return ""; + + if (!locale->count(language)) + { + if (locale->count(ELanguage::English)) + { + language = ELanguage::English; + } + else + { + return ""; + } + } + + auto strings = locale->at(language); + + if (!strings.count(Value)) + return ""; + + return std::get<1>(strings.at(Value)); +} + +template +std::string ConfigDef::GetDefinition(bool withSection) const +{ + std::string result; + + if (withSection) + result += "[" + Section + "]\n"; + + result += Name + " = " + ToString(); + + return result; +} + +template +std::string ConfigDef::ToString(bool strWithQuotes) const +{ + std::string result = "N/A"; + + if constexpr (std::is_same_v) + { + result = fmt::format("{}", Value); + + if (strWithQuotes) + result = fmt::format("\"{}\"", result); + } + else if constexpr (std::is_enum_v) + { + auto it = EnumTemplateReverse.find(Value); + + if (it != EnumTemplateReverse.end()) + result = fmt::format("{}", it->second); + + if (strWithQuotes) + result = fmt::format("\"{}\"", result); + } + else + { + result = fmt::format("{}", Value); + } + + return result; +} + +template +void ConfigDef::GetLocaleStrings(std::vector& localeStrings) const +{ + if (Locale != nullptr) + { + for (auto& [language, nameAndDesc] : *Locale) + { + localeStrings.push_back(std::get<0>(nameAndDesc)); + localeStrings.push_back(std::get<1>(nameAndDesc)); + } + } + + if (EnumLocale != nullptr) + { + for (auto& [language, locale] : *EnumLocale) + { + for (auto& [value, nameAndDesc] : locale) + { + localeStrings.push_back(std::get<0>(nameAndDesc)); + localeStrings.push_back(std::get<1>(nameAndDesc)); + } + } + } +} + +std::filesystem::path Config::GetConfigPath() +{ + return GetUserPath() / "config.toml"; +} void Config::Load() { diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 367b9da..597c792 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -1,8 +1,6 @@ #pragma once #include -#include -#include class IConfigDef { @@ -24,47 +22,12 @@ public: virtual void GetLocaleStrings(std::vector& localeStrings) const = 0; }; -#define CONFIG_LOCALE std::unordered_map> +#define CONFIG_LOCALE std::unordered_map> #define CONFIG_ENUM_LOCALE(type) std::unordered_map>> -#define CONFIG_DEFINE(section, type, name, defaultValue) \ - static inline ConfigDef name{section, #name, defaultValue}; +#define WINDOWPOS_CENTRED 0x2FFF0000 -#define CONFIG_DEFINE_HIDDEN(section, type, name, defaultValue) \ - static inline ConfigDef name{section, #name, defaultValue}; - -#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) \ - static CONFIG_LOCALE g_##name##_locale; \ - static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue}; - -#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) \ - static inline ConfigDef name{section, #name, defaultValue, &g_##type##_template}; - -#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) \ - static CONFIG_LOCALE g_##name##_locale; \ - static CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ - static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; - -#define CONFIG_DEFINE_CALLBACK(section, type, name, defaultValue, readCallback) \ - static CONFIG_LOCALE g_##name##_locale; \ - static inline ConfigDef name{section, #name, defaultValue, [](ConfigDef* def) readCallback}; - -#define CONFIG_DEFINE_ENUM_TEMPLATE(type) \ - inline std::unordered_map g_##type##_template = - -#define WINDOWPOS_CENTRED 0x2FFF0000 - -inline std::vector g_configDefinitions; - -CONFIG_DEFINE_ENUM_TEMPLATE(ELanguage) -{ - { "English", ELanguage::English }, - { "Japanese", ELanguage::Japanese }, - { "German", ELanguage::German }, - { "French", ELanguage::French }, - { "Spanish", ELanguage::Spanish }, - { "Italian", ELanguage::Italian } -}; +extern std::vector g_configDefinitions; enum class EUnleashGaugeBehaviour : uint32_t { @@ -72,24 +35,12 @@ enum class EUnleashGaugeBehaviour : uint32_t Revised }; -CONFIG_DEFINE_ENUM_TEMPLATE(EUnleashGaugeBehaviour) -{ - { "Original", EUnleashGaugeBehaviour::Original }, - { "Revised", EUnleashGaugeBehaviour::Revised } -}; - enum class ETimeOfDayTransition : uint32_t { Xbox, PlayStation }; -CONFIG_DEFINE_ENUM_TEMPLATE(ETimeOfDayTransition) -{ - { "Xbox", ETimeOfDayTransition::Xbox }, - { "PlayStation", ETimeOfDayTransition::PlayStation } -}; - enum class EControllerIcons : uint32_t { Auto, @@ -97,25 +48,12 @@ enum class EControllerIcons : uint32_t PlayStation }; -CONFIG_DEFINE_ENUM_TEMPLATE(EControllerIcons) -{ - { "Auto", EControllerIcons::Auto }, - { "Xbox", EControllerIcons::Xbox }, - { "PlayStation", EControllerIcons::PlayStation } -}; - enum class EVoiceLanguage : uint32_t { English, Japanese }; -CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) -{ - { "English", EVoiceLanguage::English }, - { "Japanese", EVoiceLanguage::Japanese } -}; - enum class EGraphicsAPI : uint32_t { #ifdef SWA_D3D12 @@ -124,27 +62,12 @@ enum class EGraphicsAPI : uint32_t Vulkan }; -CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) -{ -#ifdef SWA_D3D12 - { "D3D12", EGraphicsAPI::D3D12 }, -#endif - { "Vulkan", EGraphicsAPI::Vulkan } -}; - enum class EWindowState : uint32_t { Normal, Maximised }; -CONFIG_DEFINE_ENUM_TEMPLATE(EWindowState) -{ - { "Normal", EWindowState::Normal }, - { "Maximised", EWindowState::Maximised }, - { "Maximized", EWindowState::Maximised } -}; - enum class EAspectRatio : uint32_t { Auto, @@ -153,14 +76,6 @@ enum class EAspectRatio : uint32_t OriginalNarrow }; -CONFIG_DEFINE_ENUM_TEMPLATE(EAspectRatio) -{ - { "Auto", EAspectRatio::Auto }, - { "16:9", EAspectRatio::Wide }, - { "4:3", EAspectRatio::Narrow }, - { "Original 4:3", EAspectRatio::OriginalNarrow }, -}; - enum class ETripleBuffering : uint32_t { Auto, @@ -168,13 +83,6 @@ enum class ETripleBuffering : uint32_t Off }; -CONFIG_DEFINE_ENUM_TEMPLATE(ETripleBuffering) -{ - { "Auto", ETripleBuffering::Auto }, - { "On", ETripleBuffering::On }, - { "Off", ETripleBuffering::Off } -}; - static constexpr int32_t FPS_MIN = 15; static constexpr int32_t FPS_MAX = 240; @@ -186,14 +94,6 @@ enum class EAntiAliasing : uint32_t MSAA8x = 8 }; -CONFIG_DEFINE_ENUM_TEMPLATE(EAntiAliasing) -{ - { "None", EAntiAliasing::None }, - { "2x MSAA", EAntiAliasing::MSAA2x }, - { "4x MSAA", EAntiAliasing::MSAA4x }, - { "8x MSAA", EAntiAliasing::MSAA8x } -}; - enum class EShadowResolution : int32_t { Original = -1, @@ -204,28 +104,12 @@ enum class EShadowResolution : int32_t x8192 = 8192 }; -CONFIG_DEFINE_ENUM_TEMPLATE(EShadowResolution) -{ - { "Original", EShadowResolution::Original }, - { "512", EShadowResolution::x512 }, - { "1024", EShadowResolution::x1024 }, - { "2048", EShadowResolution::x2048 }, - { "4096", EShadowResolution::x4096 }, - { "8192", EShadowResolution::x8192 }, -}; - enum class EGITextureFiltering : uint32_t { Bilinear, Bicubic }; -CONFIG_DEFINE_ENUM_TEMPLATE(EGITextureFiltering) -{ - { "Bilinear", EGITextureFiltering::Bilinear }, - { "Bicubic", EGITextureFiltering::Bicubic } -}; - enum class EDepthOfFieldQuality : uint32_t { Auto, @@ -235,15 +119,6 @@ enum class EDepthOfFieldQuality : uint32_t Ultra }; -CONFIG_DEFINE_ENUM_TEMPLATE(EDepthOfFieldQuality) -{ - { "Auto", EDepthOfFieldQuality::Auto }, - { "Low", EDepthOfFieldQuality::Low }, - { "Medium", EDepthOfFieldQuality::Medium }, - { "High", EDepthOfFieldQuality::High }, - { "Ultra", EDepthOfFieldQuality::Ultra } -}; - enum class EMotionBlur : uint32_t { Off, @@ -251,38 +126,18 @@ enum class EMotionBlur : uint32_t Enhanced }; -CONFIG_DEFINE_ENUM_TEMPLATE(EMotionBlur) -{ - { "Off", EMotionBlur::Off }, - { "Original", EMotionBlur::Original }, - { "Enhanced", EMotionBlur::Enhanced } -}; - enum class ECutsceneAspectRatio : uint32_t { Original, Unlocked }; -CONFIG_DEFINE_ENUM_TEMPLATE(ECutsceneAspectRatio) -{ - { "Original", ECutsceneAspectRatio::Original }, - { "Unlocked", ECutsceneAspectRatio::Unlocked } -}; - enum class EUIScaleMode : uint32_t { Edge, Centre }; -CONFIG_DEFINE_ENUM_TEMPLATE(EUIScaleMode) -{ - { "Edge", EUIScaleMode::Edge }, - { "Centre", EUIScaleMode::Centre }, - { "Center", EUIScaleMode::Centre } -}; - template class ConfigDef final : public IConfigDef { @@ -301,294 +156,44 @@ public: bool IsLoadedFromConfig{}; // CONFIG_DEFINE - ConfigDef(std::string section, std::string name, T defaultValue) : Section(section), Name(name), DefaultValue(defaultValue) - { - g_configDefinitions.emplace_back(this); - } + ConfigDef(std::string section, std::string name, T defaultValue); // CONFIG_DEFINE_LOCALISED - ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue) - { - g_configDefinitions.emplace_back(this); - } + ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue); // CONFIG_DEFINE_ENUM - ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate) : Section(section), Name(name), DefaultValue(defaultValue), EnumTemplate(enumTemplate) - { - for (const auto& pair : *EnumTemplate) - EnumTemplateReverse[pair.second] = pair.first; - - g_configDefinitions.emplace_back(this); - } + ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate); // CONFIG_DEFINE_ENUM_LOCALISED - ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue), EnumTemplate(enumTemplate), EnumLocale(enumLocale) - { - for (const auto& pair : *EnumTemplate) - EnumTemplateReverse[pair.second] = pair.first; - - g_configDefinitions.emplace_back(this); - } + ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale); // CONFIG_DEFINE_CALLBACK - ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback) : Section(section), Name(name), DefaultValue(defaultValue), Callback(callback) - { - g_configDefinitions.emplace_back(this); - } + ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback); - bool IsHidden() override - { - return isHidden && !IsLoadedFromConfig; - } + ConfigDef(const ConfigDef&) = delete; + ConfigDef(ConfigDef&&) = delete; + ~ConfigDef(); - void ReadValue(toml::v3::ex::parse_result& toml) override - { - if (auto pSection = toml[Section].as_table()) - { - const auto& section = *pSection; + bool IsHidden() override; - if constexpr (std::is_same::value) - { - Value = section[Name].value_or(DefaultValue); - } - else if constexpr (std::is_enum_v) - { - auto value = section[Name].value_or(std::string()); - auto it = EnumTemplate->find(value); + void ReadValue(toml::v3::ex::parse_result& toml) override; + void MakeDefault() override; - if (it != EnumTemplate->end()) - { - Value = it->second; - } - else - { - Value = DefaultValue; - } - } - else - { - Value = section[Name].value_or(DefaultValue); - } + std::string_view GetSection() const override; + std::string_view GetName() const override; + std::string GetNameLocalised(ELanguage language) const override; + std::string GetDescription(ELanguage language) const override; - if (Callback) - Callback(this); + bool IsDefaultValue() const override; + const void* GetValue() const override; - if (pSection->contains(Name)) - IsLoadedFromConfig = true; - } - } + std::string GetValueLocalised(ELanguage language) const override; + std::string GetValueDescription(ELanguage language) const override; - void MakeDefault() override - { - Value = DefaultValue; - } + std::string GetDefinition(bool withSection = false) const override; + std::string ToString(bool strWithQuotes = true) const override; - std::string_view GetSection() const override - { - return Section; - } - - std::string_view GetName() const override - { - return Name; - } - - std::string GetNameLocalised(ELanguage language) const override - { - if (!Locale) - return Name; - - if (!Locale->count(language)) - { - if (Locale->count(ELanguage::English)) - { - return std::get<0>(Locale->at(ELanguage::English)); - } - else - { - return Name; - } - } - - return std::get<0>(Locale->at(language)); - } - - std::string GetDescription(ELanguage language) const override - { - if (!Locale) - return ""; - - if (!Locale->count(language)) - { - if (Locale->count(ELanguage::English)) - { - return std::get<1>(Locale->at(ELanguage::English)); - } - else - { - return ""; - } - } - - return std::get<1>(Locale->at(language)); - } - - bool IsDefaultValue() const override - { - return Value == DefaultValue; - } - - const void* GetValue() const override - { - return &Value; - } - - std::string GetValueLocalised(ELanguage language) const override - { - CONFIG_ENUM_LOCALE(T)* locale = nullptr; - - if constexpr (std::is_enum_v) - { - locale = EnumLocale; - } - else if constexpr (std::is_same_v) - { - return Value - ? Localise("Common_On") - : Localise("Common_Off"); - } - - if (!locale) - return ToString(false); - - if (!locale->count(language)) - { - if (locale->count(ELanguage::English)) - { - language = ELanguage::English; - } - else - { - return ToString(false); - } - } - - auto strings = locale->at(language); - - if (!strings.count(Value)) - return ToString(false); - - return std::get<0>(strings.at(Value)); - } - - std::string GetValueDescription(ELanguage language) const override - { - CONFIG_ENUM_LOCALE(T)* locale = nullptr; - - if constexpr (std::is_enum_v) - { - locale = EnumLocale; - } - else if constexpr (std::is_same_v) - { - return ""; - } - - if (!locale) - return ""; - - if (!locale->count(language)) - { - if (locale->count(ELanguage::English)) - { - language = ELanguage::English; - } - else - { - return ""; - } - } - - auto strings = locale->at(language); - - if (!strings.count(Value)) - return ""; - - return std::get<1>(strings.at(Value)); - } - - std::string GetDefinition(bool withSection = false) const override - { - std::string result; - - if (withSection) - result += "[" + Section + "]\n"; - - result += Name + " = " + ToString(); - - return result; - } - - std::string ToString(bool strWithQuotes = true) const override - { - std::string result = "N/A"; - - if constexpr (std::is_same_v) - { - result = fmt::format("{}", Value); - - if (strWithQuotes) - result = fmt::format("\"{}\"", result); - } - else if constexpr (std::is_enum_v) - { - auto it = EnumTemplateReverse.find(Value); - - if (it != EnumTemplateReverse.end()) - result = fmt::format("{}", it->second); - - if (strWithQuotes) - result = fmt::format("\"{}\"", result); - } - else - { - result = fmt::format("{}", Value); - } - - return result; - } - - void GetLocaleStrings(std::vector& localeStrings) const override - { - if (Locale != nullptr) - { - for (auto& [language, nameAndDesc] : *Locale) - { - localeStrings.push_back(std::get<0>(nameAndDesc)); - localeStrings.push_back(std::get<1>(nameAndDesc)); - } - } - - if (EnumLocale != nullptr) - { - for (auto& [language, locale] : *EnumLocale) - { - for (auto& [value, nameAndDesc] : locale) - { - localeStrings.push_back(std::get<0>(nameAndDesc)); - localeStrings.push_back(std::get<1>(nameAndDesc)); - } - } - } - } - - ConfigDef& operator=(const ConfigDef& other) - { - if (this != &other) - Value = other.Value; - - return *this; - } + void GetLocaleStrings(std::vector& localeStrings) const override; operator T() const { @@ -601,94 +206,22 @@ public: } }; +#define CONFIG_DECLARE(type, name) static ConfigDef name; +#define CONFIG_DECLARE_HIDDEN(type, name) static ConfigDef name; + +#define CONFIG_DEFINE(section, type, name, defaultValue) CONFIG_DECLARE(type, name) +#define CONFIG_DEFINE_HIDDEN(section, type, name, defaultValue) CONFIG_DECLARE_HIDDEN(type, name) +#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name) +#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) CONFIG_DECLARE(type, name) +#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name) +#define CONFIG_DEFINE_CALLBACK(section, type, name, defaultValue, readCallback) CONFIG_DECLARE(type, name) + class Config { public: - CONFIG_DEFINE_ENUM_LOCALISED("System", ELanguage, Language, ELanguage::English); - CONFIG_DEFINE_LOCALISED("System", bool, Hints, true); - CONFIG_DEFINE_LOCALISED("System", bool, ControlTutorial, true); - CONFIG_DEFINE_LOCALISED("System", bool, AchievementNotifications, true); - CONFIG_DEFINE_ENUM_LOCALISED("System", ETimeOfDayTransition, TimeOfDayTransition, ETimeOfDayTransition::Xbox); + #include "config_def.h" - CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraX, false); - CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraY, false); - CONFIG_DEFINE_LOCALISED("Input", bool, Vibration, true); - CONFIG_DEFINE_LOCALISED("Input", bool, AllowBackgroundInput, false); - CONFIG_DEFINE_ENUM_LOCALISED("Input", EControllerIcons, ControllerIcons, EControllerIcons::Auto); - - CONFIG_DEFINE_LOCALISED("Audio", float, MasterVolume, 1.0f); - CONFIG_DEFINE_LOCALISED("Audio", float, MusicVolume, 1.0f); - CONFIG_DEFINE_LOCALISED("Audio", float, EffectsVolume, 1.0f); - CONFIG_DEFINE_ENUM_LOCALISED("Audio", EVoiceLanguage, VoiceLanguage, EVoiceLanguage::English); - CONFIG_DEFINE_LOCALISED("Audio", bool, Subtitles, true); - CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); - CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); - -#ifdef SWA_D3D12 - CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12); -#else - CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan); -#endif - - CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED); - CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); - CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowSize, -1); - CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280); - CONFIG_DEFINE("Video", int32_t, WindowHeight, 720); - CONFIG_DEFINE_ENUM("Video", EWindowState, WindowState, EWindowState::Normal); - - CONFIG_DEFINE_CALLBACK("Video", int32_t, Monitor, 0, - { - def->Locale = &g_Monitor_locale; - - Window_SetDisplay(def->Value); - }); - - CONFIG_DEFINE_ENUM_LOCALISED("Video", EAspectRatio, AspectRatio, EAspectRatio::Auto); - - CONFIG_DEFINE_CALLBACK("Video", float, ResolutionScale, 1.0f, - { - def->Locale = &g_ResolutionScale_locale; - def->Value = std::clamp(def->Value, 0.25f, 2.0f); - }); - - CONFIG_DEFINE_CALLBACK("Video", bool, Fullscreen, true, - { - def->Locale = &g_Fullscreen_locale; - - Window_SetFullscreen(def->Value); - Window_SetDisplay(Monitor); - }); - - CONFIG_DEFINE_LOCALISED("Video", bool, VSync, true); - CONFIG_DEFINE_ENUM("Video", ETripleBuffering, TripleBuffering, ETripleBuffering::Auto); - CONFIG_DEFINE_LOCALISED("Video", int32_t, FPS, 60); - CONFIG_DEFINE("Video", uint32_t, MaxFrameLatency, 2); - CONFIG_DEFINE_LOCALISED("Video", float, Brightness, 0.5f); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EAntiAliasing, AntiAliasing, EAntiAliasing::MSAA4x); - CONFIG_DEFINE_LOCALISED("Video", bool, TransparencyAntiAliasing, true); - CONFIG_DEFINE("Video", uint32_t, AnisotropicFiltering, 16); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EShadowResolution, ShadowResolution, EShadowResolution::x4096); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EGITextureFiltering, GITextureFiltering, EGITextureFiltering::Bicubic); - CONFIG_DEFINE_ENUM("Video", EDepthOfFieldQuality, DepthOfFieldQuality, EDepthOfFieldQuality::Auto); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EMotionBlur, MotionBlur, EMotionBlur::Original); - CONFIG_DEFINE_LOCALISED("Video", bool, XboxColorCorrection, false); - CONFIG_DEFINE_ENUM_LOCALISED("Video", ECutsceneAspectRatio, CutsceneAspectRatio, ECutsceneAspectRatio::Original); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Edge); - - CONFIG_DEFINE_HIDDEN("Exports", bool, AllowCancellingUnleash, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, DisableAutoSaveWarning, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, DisableDLCIcon, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, FixUnleashOutOfControlDrain, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, HomingAttackOnBoost, true); - CONFIG_DEFINE_HIDDEN("Exports", bool, SaveScoreAtCheckpoints, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, SkipIntroLogos, false); - CONFIG_DEFINE_HIDDEN("Exports", bool, UseOfficialTitleOnTitleBar, false); - - static std::filesystem::path GetConfigPath() - { - return GetUserPath() / "config.toml"; - } + static std::filesystem::path GetConfigPath(); static void Load(); static void Save(); diff --git a/UnleashedRecomp/user/config_def.h b/UnleashedRecomp/user/config_def.h new file mode 100644 index 0000000..cca938f --- /dev/null +++ b/UnleashedRecomp/user/config_def.h @@ -0,0 +1,83 @@ +// This file gets included in both config.h and config.cpp, with their own macros changing +// the preprocessed output. The header is only going to have the declarations this way. + +CONFIG_DEFINE_ENUM_LOCALISED("System", ELanguage, Language, ELanguage::English); +CONFIG_DEFINE_LOCALISED("System", bool, Hints, true); +CONFIG_DEFINE_LOCALISED("System", bool, ControlTutorial, true); +CONFIG_DEFINE_LOCALISED("System", bool, AchievementNotifications, true); +CONFIG_DEFINE_ENUM_LOCALISED("System", ETimeOfDayTransition, TimeOfDayTransition, ETimeOfDayTransition::Xbox); + +CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraX, false); +CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraY, false); +CONFIG_DEFINE_LOCALISED("Input", bool, Vibration, true); +CONFIG_DEFINE_LOCALISED("Input", bool, AllowBackgroundInput, false); +CONFIG_DEFINE_ENUM_LOCALISED("Input", EControllerIcons, ControllerIcons, EControllerIcons::Auto); + +CONFIG_DEFINE_LOCALISED("Audio", float, MasterVolume, 1.0f); +CONFIG_DEFINE_LOCALISED("Audio", float, MusicVolume, 1.0f); +CONFIG_DEFINE_LOCALISED("Audio", float, EffectsVolume, 1.0f); +CONFIG_DEFINE_ENUM_LOCALISED("Audio", EVoiceLanguage, VoiceLanguage, EVoiceLanguage::English); +CONFIG_DEFINE_LOCALISED("Audio", bool, Subtitles, true); +CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); +CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); + +#ifdef SWA_D3D12 +CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12); +#else +CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan); +#endif + +CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED); +CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); +CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowSize, -1); +CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280); +CONFIG_DEFINE("Video", int32_t, WindowHeight, 720); +CONFIG_DEFINE_ENUM("Video", EWindowState, WindowState, EWindowState::Normal); + +CONFIG_DEFINE_CALLBACK("Video", int32_t, Monitor, 0, +{ + def->Locale = &g_Monitor_locale; + + Window_SetDisplay(def->Value); +}); + +CONFIG_DEFINE_ENUM_LOCALISED("Video", EAspectRatio, AspectRatio, EAspectRatio::Auto); + +CONFIG_DEFINE_CALLBACK("Video", float, ResolutionScale, 1.0f, +{ + def->Locale = &g_ResolutionScale_locale; + def->Value = std::clamp(def->Value, 0.25f, 2.0f); +}); + +CONFIG_DEFINE_CALLBACK("Video", bool, Fullscreen, true, +{ + def->Locale = &g_Fullscreen_locale; + + Window_SetFullscreen(def->Value); + Window_SetDisplay(Monitor); +}); + +CONFIG_DEFINE_LOCALISED("Video", bool, VSync, true); +CONFIG_DEFINE_ENUM("Video", ETripleBuffering, TripleBuffering, ETripleBuffering::Auto); +CONFIG_DEFINE_LOCALISED("Video", int32_t, FPS, 60); +CONFIG_DEFINE("Video", uint32_t, MaxFrameLatency, 2); +CONFIG_DEFINE_LOCALISED("Video", float, Brightness, 0.5f); +CONFIG_DEFINE_ENUM_LOCALISED("Video", EAntiAliasing, AntiAliasing, EAntiAliasing::MSAA4x); +CONFIG_DEFINE_LOCALISED("Video", bool, TransparencyAntiAliasing, true); +CONFIG_DEFINE("Video", uint32_t, AnisotropicFiltering, 16); +CONFIG_DEFINE_ENUM_LOCALISED("Video", EShadowResolution, ShadowResolution, EShadowResolution::x4096); +CONFIG_DEFINE_ENUM_LOCALISED("Video", EGITextureFiltering, GITextureFiltering, EGITextureFiltering::Bicubic); +CONFIG_DEFINE_ENUM("Video", EDepthOfFieldQuality, DepthOfFieldQuality, EDepthOfFieldQuality::Auto); +CONFIG_DEFINE_ENUM_LOCALISED("Video", EMotionBlur, MotionBlur, EMotionBlur::Original); +CONFIG_DEFINE_LOCALISED("Video", bool, XboxColorCorrection, false); +CONFIG_DEFINE_ENUM_LOCALISED("Video", ECutsceneAspectRatio, CutsceneAspectRatio, ECutsceneAspectRatio::Original); +CONFIG_DEFINE_ENUM_LOCALISED("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Edge); + +CONFIG_DEFINE_HIDDEN("Exports", bool, AllowCancellingUnleash, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, DisableAutoSaveWarning, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, DisableDLCIcon, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, FixUnleashOutOfControlDrain, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, HomingAttackOnBoost, true); +CONFIG_DEFINE_HIDDEN("Exports", bool, SaveScoreAtCheckpoints, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, SkipIntroLogos, false); +CONFIG_DEFINE_HIDDEN("Exports", bool, UseOfficialTitleOnTitleBar, false);