From 7f708e8d77fb6237407f49246622dbe1b445d536 Mon Sep 17 00:00:00 2001
From: lat9nq <22451773+lat9nq@users.noreply.github.com>
Date: Wed, 21 Jun 2023 04:32:13 -0400
Subject: [PATCH] settings: Define paired settings

settings_common: Remove unused optional
---
 src/common/settings.h          | 21 +++++++++++++++------
 src/common/settings_common.cpp |  9 +++++++--
 src/common/settings_common.h   | 11 +++++++++--
 src/common/settings_setting.h  | 29 ++++++++++++++++++-----------
 4 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/src/common/settings.h b/src/common/settings.h
index c78dd85c82..b87301d4e6 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -150,9 +150,16 @@ struct Values {
         linkage, false, "use_unsafe_extended_memory_layout", Category::Core};
     SwitchableSetting<bool> use_speed_limit{
         linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, false, true};
-    SwitchableSetting<u16, true> speed_limit{
-        linkage, 100, 0, 9999, "speed_limit", Category::Core, Specialization::Countable,
-        true,    true};
+    SwitchableSetting<u16, true> speed_limit{linkage,
+                                             100,
+                                             0,
+                                             9999,
+                                             "speed_limit",
+                                             Category::Core,
+                                             Specialization::Countable,
+                                             true,
+                                             true,
+                                             &use_speed_limit};
 
     // Cpu
     SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage,           CpuAccuracy::Auto,
@@ -339,13 +346,15 @@ struct Values {
     SwitchableSetting<bool> custom_rtc_enabled{
         linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
     SwitchableSetting<s64> custom_rtc{
-        linkage, 0, "custom_rtc", Category::System, Specialization::Time, true, true};
+        linkage, 0,    "custom_rtc",       Category::System, Specialization::Time,
+        true,    true, &custom_rtc_enabled};
     // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
     s64 custom_rtc_differential;
     SwitchableSetting<bool> rng_seed_enabled{
         linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true};
-    SwitchableSetting<u32> rng_seed{linkage, 0,   "rng_seed", Category::System, Specialization::Hex,
-                                    true,    true};
+    SwitchableSetting<u32> rng_seed{
+        linkage, 0,    "rng_seed",       Category::System, Specialization::Hex,
+        true,    true, &rng_seed_enabled};
     Setting<std::string> device_name{
         linkage, "yuzu", "device_name", Category::System, Specialization::Default, true, true};
 
diff --git a/src/common/settings_common.cpp b/src/common/settings_common.cpp
index 3e86c73472..53d4548f57 100644
--- a/src/common/settings_common.cpp
+++ b/src/common/settings_common.cpp
@@ -8,9 +8,10 @@ namespace Settings {
 
 BasicSetting::BasicSetting(Linkage& linkage, const std::string& name, enum Category category_,
                            bool save_, bool runtime_modifiable_,
-                           enum Specialization specialization_)
+                           enum Specialization specialization_, BasicSetting* other_setting_)
     : label{name}, category{category_}, id{linkage.count}, save{save_},
-      runtime_modifiable{runtime_modifiable_}, specialization{specialization_} {
+      runtime_modifiable{runtime_modifiable_}, specialization{specialization_},
+      other_setting{other_setting_} {
     linkage.by_category[category].push_front(this);
     linkage.count++;
 }
@@ -43,6 +44,10 @@ Specialization BasicSetting::Specialization() const {
     return specialization;
 }
 
+BasicSetting* BasicSetting::PairedSetting() const {
+    return other_setting;
+}
+
 const std::string& BasicSetting::GetLabel() const {
     return label;
 }
diff --git a/src/common/settings_common.h b/src/common/settings_common.h
index 664c807f1d..ad005ca4e4 100644
--- a/src/common/settings_common.h
+++ b/src/common/settings_common.h
@@ -75,7 +75,8 @@ public:
 class BasicSetting {
 protected:
     explicit BasicSetting(Linkage& linkage, const std::string& name, enum Category category_,
-                          bool save_, bool runtime_modifiable_, Specialization spec);
+                          bool save_, bool runtime_modifiable_, Specialization spec,
+                          BasicSetting* other_setting);
 
 public:
     virtual ~BasicSetting();
@@ -196,6 +197,11 @@ public:
      */
     [[nodiscard]] enum Specialization Specialization() const;
 
+    /**
+     * @returns Another BasicSetting if one is paired, or nullptr otherwise.
+     */
+    [[nodiscard]] BasicSetting* PairedSetting() const;
+
     /**
      * Returns the label this setting was created with.
      *
@@ -236,7 +242,8 @@ private:
     const bool
         runtime_modifiable; ///< Suggests if the setting can be modified while a guest is running
     const enum Specialization
-        specialization; ///< Extra data to identify representation of a setting
+        specialization;                ///< Extra data to identify representation of a setting
+    BasicSetting* const other_setting; ///< A paired setting
 };
 
 } // namespace Settings
diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h
index 9805a5b5dc..dd91250a1d 100644
--- a/src/common/settings_setting.h
+++ b/src/common/settings_setting.h
@@ -37,9 +37,11 @@ public:
     explicit Setting(Linkage& linkage, const Type& default_val, const std::string& name,
                      enum Category category_,
                      enum Specialization specialization = Specialization::Default,
-                     bool save_ = true, bool runtime_modifiable_ = false)
+                     bool save_ = true, bool runtime_modifiable_ = false,
+                     BasicSetting* other_setting = nullptr)
         requires(!ranged)
-        : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization),
+        : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization,
+                       other_setting),
           value{default_val}, default_value{default_val} {}
     virtual ~Setting() = default;
 
@@ -56,9 +58,11 @@ public:
     explicit Setting(Linkage& linkage, const Type& default_val, const Type& min_val,
                      const Type& max_val, const std::string& name, enum Category category_,
                      enum Specialization specialization = Specialization::Default,
-                     bool save_ = true, bool runtime_modifiable_ = false)
+                     bool save_ = true, bool runtime_modifiable_ = false,
+                     BasicSetting* other_setting = nullptr)
         requires(ranged)
-        : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization),
+        : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization,
+                       other_setting),
           value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val} {}
 
     /**
@@ -235,10 +239,12 @@ public:
     explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
                                Category category_,
                                enum Specialization specialization = Specialization::Default,
-                               bool save_ = true, bool runtime_modifiable_ = false)
+                               bool save_ = true, bool runtime_modifiable_ = false,
+                               BasicSetting* other_setting = nullptr)
         requires(!ranged)
-        : Setting<Type, false>{linkage, default_val,        name, category_, specialization,
-                               save_,   runtime_modifiable_} {
+        : Setting<Type, false>{
+              linkage, default_val,         name,         category_, specialization,
+              save_,   runtime_modifiable_, other_setting} {
         linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
     }
     virtual ~SwitchableSetting() = default;
@@ -256,11 +262,12 @@ public:
     explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
                                const Type& max_val, const std::string& name, Category category_,
                                enum Specialization specialization = Specialization::Default,
-                               bool save_ = true, bool runtime_modifiable_ = false)
+                               bool save_ = true, bool runtime_modifiable_ = false,
+                               BasicSetting* other_setting = nullptr)
         requires(ranged)
-        : Setting<Type, true>{linkage,        default_val, min_val,
-                              max_val,        name,        category_,
-                              specialization, save_,       runtime_modifiable_} {
+        : Setting<Type, true>{
+              linkage, default_val,         min_val,      max_val, name, category_, specialization,
+              save_,   runtime_modifiable_, other_setting} {
         linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
     }