From 051afd21e730005ea24ce3c8743962beb3085031 Mon Sep 17 00:00:00 2001
From: t895 <clombardo169@gmail.com>
Date: Thu, 28 Dec 2023 23:24:23 -0500
Subject: [PATCH] frontend_common: config: Refactor WriteSetting to stricter
 types

Previously this could cause problems if a version of the template generated for WriteSetting didn't use the type you needed (e.g. floating point values). Now these are all ready without having to be used within frontend_common first.
---
 .../app/src/main/jni/android_config.cpp       |   5 +-
 src/frontend_common/config.cpp                | 194 ++++++++++--------
 src/frontend_common/config.h                  |  28 ++-
 src/yuzu/configuration/qt_config.cpp          |  69 ++++---
 src/yuzu_cmd/sdl_config.cpp                   |  26 +--
 5 files changed, 188 insertions(+), 134 deletions(-)

diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp
index 9c3a5a9b29..fb17ab6f60 100644
--- a/src/android/app/src/main/jni/android_config.cpp
+++ b/src/android/app/src/main/jni/android_config.cpp
@@ -114,8 +114,9 @@ void AndroidConfig::SavePathValues() {
     for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) {
         SetArrayIndex(i);
         const auto& game_dir = AndroidSettings::values.game_dirs[i];
-        WriteSetting(std::string("path"), game_dir.path);
-        WriteSetting(std::string("deep_scan"), game_dir.deep_scan, std::make_optional(false));
+        WriteStringSetting(std::string("path"), game_dir.path);
+        WriteBooleanSetting(std::string("deep_scan"), game_dir.deep_scan,
+                            std::make_optional(false));
     }
     EndArray();
 
diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp
index d9f99148bc..51576b4eeb 100644
--- a/src/frontend_common/config.cpp
+++ b/src/frontend_common/config.cpp
@@ -403,59 +403,63 @@ void Config::SavePlayerValues(const std::size_t player_index) {
             // No custom profile selected
             return;
         }
-        WriteSetting(std::string(player_prefix).append("profile_name"), player.profile_name,
-                     std::make_optional(std::string("")));
+        WriteStringSetting(std::string(player_prefix).append("profile_name"), player.profile_name,
+                           std::make_optional(std::string("")));
     }
 
-    WriteSetting(std::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
-                 std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
+    WriteIntegerSetting(
+        std::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
+        std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
 
     if (!player_prefix.empty() || !Settings::IsConfiguringGlobal()) {
-        WriteSetting(std::string(player_prefix).append("connected"), player.connected,
-                     std::make_optional(player_index == 0));
-        WriteSetting(std::string(player_prefix).append("vibration_enabled"),
-                     player.vibration_enabled, std::make_optional(true));
-        WriteSetting(std::string(player_prefix).append("vibration_strength"),
-                     player.vibration_strength, std::make_optional(100));
-        WriteSetting(std::string(player_prefix).append("body_color_left"), player.body_color_left,
-                     std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
-        WriteSetting(std::string(player_prefix).append("body_color_right"), player.body_color_right,
-                     std::make_optional(Settings::JOYCON_BODY_NEON_RED));
-        WriteSetting(std::string(player_prefix).append("button_color_left"),
-                     player.button_color_left,
-                     std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
-        WriteSetting(std::string(player_prefix).append("button_color_right"),
-                     player.button_color_right,
-                     std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
+        WriteBooleanSetting(std::string(player_prefix).append("connected"), player.connected,
+                            std::make_optional(player_index == 0));
+        WriteIntegerSetting(std::string(player_prefix).append("vibration_enabled"),
+                            player.vibration_enabled, std::make_optional(true));
+        WriteIntegerSetting(std::string(player_prefix).append("vibration_strength"),
+                            player.vibration_strength, std::make_optional(100));
+        WriteIntegerSetting(std::string(player_prefix).append("body_color_left"),
+                            player.body_color_left,
+                            std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
+        WriteIntegerSetting(std::string(player_prefix).append("body_color_right"),
+                            player.body_color_right,
+                            std::make_optional(Settings::JOYCON_BODY_NEON_RED));
+        WriteIntegerSetting(std::string(player_prefix).append("button_color_left"),
+                            player.button_color_left,
+                            std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
+        WriteIntegerSetting(std::string(player_prefix).append("button_color_right"),
+                            player.button_color_right,
+                            std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
     }
 }
 
 void Config::SaveTouchscreenValues() {
     const auto& touchscreen = Settings::values.touchscreen;
 
-    WriteSetting(std::string("touchscreen_enabled"), touchscreen.enabled, std::make_optional(true));
+    WriteBooleanSetting(std::string("touchscreen_enabled"), touchscreen.enabled,
+                        std::make_optional(true));
 
-    WriteSetting(std::string("touchscreen_angle"), touchscreen.rotation_angle,
-                 std::make_optional(static_cast<u32>(0)));
-    WriteSetting(std::string("touchscreen_diameter_x"), touchscreen.diameter_x,
-                 std::make_optional(static_cast<u32>(15)));
-    WriteSetting(std::string("touchscreen_diameter_y"), touchscreen.diameter_y,
-                 std::make_optional(static_cast<u32>(15)));
+    WriteIntegerSetting(std::string("touchscreen_angle"), touchscreen.rotation_angle,
+                        std::make_optional(static_cast<u32>(0)));
+    WriteIntegerSetting(std::string("touchscreen_diameter_x"), touchscreen.diameter_x,
+                        std::make_optional(static_cast<u32>(15)));
+    WriteIntegerSetting(std::string("touchscreen_diameter_y"), touchscreen.diameter_y,
+                        std::make_optional(static_cast<u32>(15)));
 }
 
 void Config::SaveMotionTouchValues() {
     BeginArray(std::string("touch_from_button_maps"));
     for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
         SetArrayIndex(static_cast<int>(p));
-        WriteSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
-                     std::make_optional(std::string("default")));
+        WriteStringSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
+                           std::make_optional(std::string("default")));
 
         BeginArray(std::string("entries"));
         for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
              ++q) {
             SetArrayIndex(static_cast<int>(q));
-            WriteSetting(std::string("bind"),
-                         Settings::values.touch_from_button_maps[p].buttons[q]);
+            WriteStringSetting(std::string("bind"),
+                               Settings::values.touch_from_button_maps[p].buttons[q]);
         }
         EndArray(); // entries
     }
@@ -520,16 +524,16 @@ void Config::SaveCoreValues() {
 void Config::SaveDataStorageValues() {
     BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
 
-    WriteSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir),
-                 std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
-    WriteSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir),
-                 std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
-    WriteSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir),
-                 std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
-    WriteSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir),
-                 std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
-    WriteSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir),
-                 std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
+    WriteStringSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir),
+                       std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
+    WriteStringSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir),
+                       std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
+    WriteStringSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir),
+                       std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
+    WriteStringSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir),
+                       std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
+    WriteStringSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir),
+                       std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
 
     WriteCategory(Settings::Category::DataStorage);
 
@@ -540,7 +544,7 @@ void Config::SaveDebuggingValues() {
     BeginGroup(Settings::TranslateCategory(Settings::Category::Debugging));
 
     // Intentionally not using the QT default setting as this is intended to be changed in the ini
-    WriteSetting(std::string("record_frame_times"), Settings::values.record_frame_times);
+    WriteBooleanSetting(std::string("record_frame_times"), Settings::values.record_frame_times);
 
     WriteCategory(Settings::Category::Debugging);
     WriteCategory(Settings::Category::DebuggingGraphics);
@@ -564,11 +568,13 @@ void Config::SaveDisabledAddOnValues() {
     BeginArray(std::string(""));
     for (const auto& elem : Settings::values.disabled_addons) {
         SetArrayIndex(i);
-        WriteSetting(std::string("title_id"), elem.first, std::make_optional(static_cast<u64>(0)));
+        WriteIntegerSetting(std::string("title_id"), elem.first,
+                            std::make_optional(static_cast<u64>(0)));
         BeginArray(std::string("disabled"));
         for (std::size_t j = 0; j < elem.second.size(); ++j) {
             SetArrayIndex(static_cast<int>(j));
-            WriteSetting(std::string("d"), elem.second[j], std::make_optional(std::string("")));
+            WriteStringSetting(std::string("d"), elem.second[j],
+                               std::make_optional(std::string("")));
         }
         EndArray(); // disabled
         ++i;
@@ -609,8 +615,8 @@ void Config::SaveRendererValues() {
 void Config::SaveScreenshotValues() {
     BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots));
 
-    WriteSetting(std::string("screenshot_path"),
-                 FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir));
+    WriteStringSetting(std::string("screenshot_path"),
+                       FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir));
     WriteCategory(Settings::Category::Screenshots);
 
     EndGroup();
@@ -746,46 +752,70 @@ bool Config::Exists(const std::string& section, const std::string& key) const {
     return !value.empty();
 }
 
-template <typename Type>
-void Config::WriteSetting(const std::string& key, const Type& value,
-                          const std::optional<Type>& default_value,
-                          const std::optional<bool>& use_global) {
-    std::string full_key = GetFullKey(key, false);
+void Config::WriteBooleanSetting(const std::string& key, const bool& value,
+                                 const std::optional<bool>& default_value,
+                                 const std::optional<bool>& use_global) {
+    std::optional<std::string> string_default = std::nullopt;
+    if (default_value.has_value()) {
+        string_default = std::make_optional(ToString(default_value.value()));
+    }
+    WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
+}
 
-    std::string saved_value;
-    std::string string_default;
-    if constexpr (std::is_same_v<Type, std::string>) {
-        saved_value.append(AdjustOutputString(value));
-        if (default_value.has_value()) {
-            string_default.append(AdjustOutputString(default_value.value()));
-        }
-    } else {
-        saved_value.append(AdjustOutputString(ToString(value)));
-        if (default_value.has_value()) {
-            string_default.append(ToString(default_value.value()));
-        }
+template <typename T>
+std::enable_if_t<std::is_integral_v<T>> Config::WriteIntegerSetting(
+    const std::string& key, const T& value, const std::optional<T>& default_value,
+    const std::optional<bool>& use_global) {
+    std::optional<std::string> string_default = std::nullopt;
+    if (default_value.has_value()) {
+        string_default = std::make_optional(ToString(default_value.value()));
+    }
+    WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
+}
+
+void Config::WriteDoubleSetting(const std::string& key, const double& value,
+                                const std::optional<double>& default_value,
+                                const std::optional<bool>& use_global) {
+    std::optional<std::string> string_default = std::nullopt;
+    if (default_value.has_value()) {
+        string_default = std::make_optional(ToString(default_value.value()));
     }
+    WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
+}
 
-    if (default_value.has_value() && use_global.has_value()) {
+void Config::WriteStringSetting(const std::string& key, const std::string& value,
+                                const std::optional<std::string>& default_value,
+                                const std::optional<bool>& use_global) {
+    std::optional string_default = default_value;
+    if (default_value.has_value()) {
+        string_default.value().append(AdjustOutputString(default_value.value()));
+    }
+    WritePreparedSetting(key, AdjustOutputString(value), string_default, use_global);
+}
+
+void Config::WritePreparedSetting(const std::string& key, const std::string& adjusted_value,
+                                  const std::optional<std::string>& adjusted_default_value,
+                                  const std::optional<bool>& use_global) {
+    std::string full_key = GetFullKey(key, false);
+    if (adjusted_default_value.has_value() && use_global.has_value()) {
         if (!global) {
-            WriteSettingInternal(std::string(full_key).append("\\global"),
-                                 ToString(use_global.value()));
+            WriteString(std::string(full_key).append("\\global"), ToString(use_global.value()));
         }
         if (global || use_global.value() == false) {
-            WriteSettingInternal(std::string(full_key).append("\\default"),
-                                 ToString(string_default == saved_value));
-            WriteSettingInternal(full_key, saved_value);
+            WriteString(std::string(full_key).append("\\default"),
+                        ToString(adjusted_default_value == adjusted_value));
+            WriteString(full_key, adjusted_value);
         }
-    } else if (default_value.has_value() && !use_global.has_value()) {
-        WriteSettingInternal(std::string(full_key).append("\\default"),
-                             ToString(string_default == saved_value));
-        WriteSettingInternal(full_key, saved_value);
+    } else if (adjusted_default_value.has_value() && !use_global.has_value()) {
+        WriteString(std::string(full_key).append("\\default"),
+                    ToString(adjusted_default_value == adjusted_value));
+        WriteString(full_key, adjusted_value);
     } else {
-        WriteSettingInternal(full_key, saved_value);
+        WriteString(full_key, adjusted_value);
     }
 }
 
-void Config::WriteSettingInternal(const std::string& key, const std::string& value) {
+void Config::WriteString(const std::string& key, const std::string& value) {
     config->SetValue(GetSection().c_str(), key.c_str(), value.c_str());
 }
 
@@ -861,17 +891,17 @@ void Config::WriteSettingGeneric(const Settings::BasicSetting* const setting) {
     std::string key = AdjustKey(setting->GetLabel());
     if (setting->Switchable()) {
         if (!global) {
-            WriteSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
+            WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
         }
         if (global || !setting->UsingGlobal()) {
-            WriteSetting(std::string(key).append("\\default"),
-                         setting->ToString() == setting->DefaultToString());
-            WriteSetting(key, setting->ToString());
+            WriteBooleanSetting(std::string(key).append("\\default"),
+                                setting->ToString() == setting->DefaultToString());
+            WriteStringSetting(key, setting->ToString());
         }
     } else if (global) {
-        WriteSetting(std::string(key).append("\\default"),
-                     setting->ToString() == setting->DefaultToString());
-        WriteSetting(key, setting->ToString());
+        WriteBooleanSetting(std::string(key).append("\\default"),
+                            setting->ToString() == setting->DefaultToString());
+        WriteStringSetting(key, setting->ToString());
     }
 }
 
diff --git a/src/frontend_common/config.h b/src/frontend_common/config.h
index b3812af17f..e73cf6929f 100644
--- a/src/frontend_common/config.h
+++ b/src/frontend_common/config.h
@@ -154,11 +154,20 @@ protected:
      * @param use_global Specifies if the custom or global config should be in use, for custom
      * configs
      */
-    template <typename Type = int>
-    void WriteSetting(const std::string& key, const Type& value,
-                      const std::optional<Type>& default_value = std::nullopt,
-                      const std::optional<bool>& use_global = std::nullopt);
-    void WriteSettingInternal(const std::string& key, const std::string& value);
+    void WriteBooleanSetting(const std::string& key, const bool& value,
+                             const std::optional<bool>& default_value = std::nullopt,
+                             const std::optional<bool>& use_global = std::nullopt);
+    template <typename T>
+    std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
+        const std::string& key, const T& value,
+        const std::optional<T>& default_value = std::nullopt,
+        const std::optional<bool>& use_global = std::nullopt);
+    void WriteDoubleSetting(const std::string& key, const double& value,
+                            const std::optional<double>& default_value = std::nullopt,
+                            const std::optional<bool>& use_global = std::nullopt);
+    void WriteStringSetting(const std::string& key, const std::string& value,
+                            const std::optional<std::string>& default_value = std::nullopt,
+                            const std::optional<bool>& use_global = std::nullopt);
 
     void ReadCategory(Settings::Category category);
     void WriteCategory(Settings::Category category);
@@ -175,8 +184,10 @@ protected:
             return value_ ? "true" : "false";
         } else if constexpr (std::is_same_v<T, u64>) {
             return std::to_string(static_cast<u64>(value_));
-        } else {
+        } else if constexpr (std::is_same_v<T, s64>) {
             return std::to_string(static_cast<s64>(value_));
+        } else {
+            return std::to_string(value_);
         }
     }
 
@@ -197,6 +208,11 @@ protected:
     const bool global;
 
 private:
+    void WritePreparedSetting(const std::string& key, const std::string& adjusted_value,
+                              const std::optional<std::string>& adjusted_default_value,
+                              const std::optional<bool>& use_global);
+    void WriteString(const std::string& key, const std::string& value);
+
     inline static std::array<char, 19> special_characters = {'!', '#', '$',  '%',  '^', '&', '*',
                                                              '|', ';', '\'', '\"', ',', '<', '.',
                                                              '>', '?', '`',  '~',  '='};
diff --git a/src/yuzu/configuration/qt_config.cpp b/src/yuzu/configuration/qt_config.cpp
index a71000b72f..6aca71d7c4 100644
--- a/src/yuzu/configuration/qt_config.cpp
+++ b/src/yuzu/configuration/qt_config.cpp
@@ -348,43 +348,45 @@ void QtConfig::SaveQtPlayerValues(const std::size_t player_index) {
 
     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
-                     player.buttons[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
+                           player.buttons[i], std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
         const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
             default_analogs[i][3], default_stick_mod[i], 0.5f);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
-                     player.analogs[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
+                           player.analogs[i], std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
-                     player.motions[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
+                           player.motions[i], std::make_optional(default_param));
     }
 }
 
 void QtConfig::SaveDebugControlValues() {
     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
-        WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
-                     Settings::values.debug_pad_buttons[i], std::make_optional(default_param));
+        WriteStringSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
+                           Settings::values.debug_pad_buttons[i],
+                           std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
         const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
             default_analogs[i][3], default_stick_mod[i], 0.5f);
-        WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
-                     Settings::values.debug_pad_analogs[i], std::make_optional(default_param));
+        WriteStringSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
+                           Settings::values.debug_pad_analogs[i],
+                           std::make_optional(default_param));
     }
 }
 
 void QtConfig::SaveHidbusValues() {
     const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
         0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
-    WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
-                 std::make_optional(default_param));
+    WriteStringSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
+                       std::make_optional(default_param));
 }
 
 void QtConfig::SaveQtControlValues() {
@@ -409,19 +411,20 @@ void QtConfig::SavePathValues() {
 
     WriteCategory(Settings::Category::Paths);
 
-    WriteSetting(std::string("romsPath"), UISettings::values.roms_path);
+    WriteStringSetting(std::string("romsPath"), UISettings::values.roms_path);
     BeginArray(std::string("gamedirs"));
     for (int i = 0; i < UISettings::values.game_dirs.size(); ++i) {
         SetArrayIndex(i);
         const auto& game_dir = UISettings::values.game_dirs[i];
-        WriteSetting(std::string("path"), game_dir.path);
-        WriteSetting(std::string("deep_scan"), game_dir.deep_scan, std::make_optional(false));
-        WriteSetting(std::string("expanded"), game_dir.expanded, std::make_optional(true));
+        WriteStringSetting(std::string("path"), game_dir.path);
+        WriteBooleanSetting(std::string("deep_scan"), game_dir.deep_scan,
+                            std::make_optional(false));
+        WriteBooleanSetting(std::string("expanded"), game_dir.expanded, std::make_optional(true));
     }
     EndArray();
 
-    WriteSetting(std::string("recentFiles"),
-                 UISettings::values.recent_files.join(QStringLiteral(", ")).toStdString());
+    WriteStringSetting(std::string("recentFiles"),
+                       UISettings::values.recent_files.join(QStringLiteral(", ")).toStdString());
 
     EndGroup();
 }
@@ -438,14 +441,14 @@ void QtConfig::SaveShortcutValues() {
         BeginGroup(group);
         BeginGroup(name);
 
-        WriteSetting(std::string("KeySeq"), shortcut.keyseq,
-                     std::make_optional(default_hotkey.keyseq));
-        WriteSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq,
-                     std::make_optional(default_hotkey.controller_keyseq));
-        WriteSetting(std::string("Context"), shortcut.context,
-                     std::make_optional(default_hotkey.context));
-        WriteSetting(std::string("Repeat"), shortcut.repeat,
-                     std::make_optional(default_hotkey.repeat));
+        WriteStringSetting(std::string("KeySeq"), shortcut.keyseq,
+                           std::make_optional(default_hotkey.keyseq));
+        WriteStringSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq,
+                           std::make_optional(default_hotkey.controller_keyseq));
+        WriteIntegerSetting(std::string("Context"), shortcut.context,
+                            std::make_optional(default_hotkey.context));
+        WriteBooleanSetting(std::string("Repeat"), shortcut.repeat,
+                            std::make_optional(default_hotkey.repeat));
 
         EndGroup(); // name
         EndGroup(); // group
@@ -460,9 +463,10 @@ void QtConfig::SaveUIValues() {
     WriteCategory(Settings::Category::Ui);
     WriteCategory(Settings::Category::UiGeneral);
 
-    WriteSetting(std::string("theme"), UISettings::values.theme,
-                 std::make_optional(std::string(
-                     UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second)));
+    WriteStringSetting(
+        std::string("theme"), UISettings::values.theme,
+        std::make_optional(std::string(
+            UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second)));
 
     SaveUIGamelistValues();
     SaveUILayoutValues();
@@ -482,7 +486,7 @@ void QtConfig::SaveUIGamelistValues() {
     BeginArray(std::string("favorites"));
     for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) {
         SetArrayIndex(i);
-        WriteSetting(std::string("program_id"), UISettings::values.favorited_ids[i]);
+        WriteIntegerSetting(std::string("program_id"), UISettings::values.favorited_ids[i]);
     }
     EndArray(); // favorites
 
@@ -506,14 +510,15 @@ void QtConfig::SaveMultiplayerValues() {
     BeginArray(std::string("username_ban_list"));
     for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) {
         SetArrayIndex(static_cast<int>(i));
-        WriteSetting(std::string("username"), UISettings::values.multiplayer_ban_list.first[i]);
+        WriteStringSetting(std::string("username"),
+                           UISettings::values.multiplayer_ban_list.first[i]);
     }
     EndArray(); // username_ban_list
 
     BeginArray(std::string("ip_ban_list"));
     for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) {
         SetArrayIndex(static_cast<int>(i));
-        WriteSetting(std::string("ip"), UISettings::values.multiplayer_ban_list.second[i]);
+        WriteStringSetting(std::string("ip"), UISettings::values.multiplayer_ban_list.second[i]);
     }
     EndArray(); // ip_ban_list
 
diff --git a/src/yuzu_cmd/sdl_config.cpp b/src/yuzu_cmd/sdl_config.cpp
index 39fd8050c6..e81bf5d45f 100644
--- a/src/yuzu_cmd/sdl_config.cpp
+++ b/src/yuzu_cmd/sdl_config.cpp
@@ -213,43 +213,45 @@ void SdlConfig::SaveSdlPlayerValues(const std::size_t player_index) {
 
     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
-                     player.buttons[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
+                           player.buttons[i], std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
         const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
             default_analogs[i][3], default_stick_mod[i], 0.5f);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
-                     player.analogs[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
+                           player.analogs[i], std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
-        WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
-                     player.motions[i], std::make_optional(default_param));
+        WriteStringSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
+                           player.motions[i], std::make_optional(default_param));
     }
 }
 
 void SdlConfig::SaveDebugControlValues() {
     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
         const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
-        WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
-                     Settings::values.debug_pad_buttons[i], std::make_optional(default_param));
+        WriteStringSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
+                           Settings::values.debug_pad_buttons[i],
+                           std::make_optional(default_param));
     }
     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
         const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
             default_analogs[i][3], default_stick_mod[i], 0.5f);
-        WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
-                     Settings::values.debug_pad_analogs[i], std::make_optional(default_param));
+        WriteStringSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
+                           Settings::values.debug_pad_analogs[i],
+                           std::make_optional(default_param));
     }
 }
 
 void SdlConfig::SaveHidbusValues() {
     const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
         0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
-    WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
-                 std::make_optional(default_param));
+    WriteStringSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
+                       std::make_optional(default_param));
 }
 
 std::vector<Settings::BasicSetting*>& SdlConfig::FindRelevantList(Settings::Category category) {
-- 
GitLab