summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/audio_out.cpp3
-rw-r--r--src/common/settings.cpp16
-rw-r--r--src/common/settings.h406
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/frontend/applets/profile_select.cpp2
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp3
-rw-r--r--src/core/hle/service/am/am.cpp2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp6
-rw-r--r--src/core/hle/service/set/set.cpp2
-rw-r--r--src/core/loader/nro.cpp4
-rw-r--r--src/core/loader/nso.cpp4
-rw-r--r--src/core/reporter.cpp2
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/input_common/mouse/mouse_poller.cpp3
-rw-r--r--src/input_common/touch_from_button.cpp3
-rw-r--r--src/input_common/udp/client.cpp4
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp15
-rw-r--r--src/yuzu/configuration/config.cpp591
-rw-r--r--src/yuzu/configuration/config.h75
-rw-r--r--src/yuzu/configuration/configure_audio.cpp8
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp21
-rw-r--r--src/yuzu/configuration/configure_debug.cpp23
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp11
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp12
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp11
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp11
-rw-r--r--src/yuzu/configuration/configure_service.cpp2
-rw-r--r--src/yuzu/configuration/configure_web.cpp10
-rw-r--r--src/yuzu/main.cpp5
-rw-r--r--src/yuzu_cmd/config.cpp196
-rw-r--r--src/yuzu_cmd/config.h6
-rw-r--r--src/yuzu_cmd/yuzu.cpp2
32 files changed, 807 insertions, 660 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index 20a756dce..44a899d08 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -30,7 +30,8 @@ StreamPtr AudioOut::OpenStream(Core::Timing::CoreTiming& core_timing, u32 sample
30 u32 num_channels, std::string&& name, 30 u32 num_channels, std::string&& name,
31 Stream::ReleaseCallback&& release_callback) { 31 Stream::ReleaseCallback&& release_callback) {
32 if (!sink) { 32 if (!sink) {
33 sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); 33 sink = CreateSinkFromID(Settings::values.sink_id.GetValue(),
34 Settings::values.audio_device_id.GetValue());
34 } 35 }
35 36
36 return std::make_shared<Stream>( 37 return std::make_shared<Stream>(
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index e1bb4b7ff..0061e29cc 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -41,7 +41,7 @@ void LogSettings() {
41 LOG_INFO(Config, "yuzu Configuration:"); 41 LOG_INFO(Config, "yuzu Configuration:");
42 log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue()); 42 log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
43 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0)); 43 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
44 log_setting("System_CurrentUser", values.current_user); 44 log_setting("System_CurrentUser", values.current_user.GetValue());
45 log_setting("System_LanguageIndex", values.language_index.GetValue()); 45 log_setting("System_LanguageIndex", values.language_index.GetValue());
46 log_setting("System_RegionIndex", values.region_index.GetValue()); 46 log_setting("System_RegionIndex", values.region_index.GetValue());
47 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue()); 47 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
@@ -61,18 +61,18 @@ void LogSettings() {
61 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); 61 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
62 log_setting("Renderer_UseGarbageCollection", values.use_caches_gc.GetValue()); 62 log_setting("Renderer_UseGarbageCollection", values.use_caches_gc.GetValue());
63 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); 63 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
64 log_setting("Audio_OutputEngine", values.sink_id); 64 log_setting("Audio_OutputEngine", values.sink_id.GetValue());
65 log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); 65 log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
66 log_setting("Audio_OutputDevice", values.audio_device_id); 66 log_setting("Audio_OutputDevice", values.audio_device_id.GetValue());
67 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); 67 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue());
68 log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir)); 68 log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir));
69 log_path("DataStorage_ConfigDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir)); 69 log_path("DataStorage_ConfigDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir));
70 log_path("DataStorage_LoadDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir)); 70 log_path("DataStorage_LoadDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir));
71 log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir)); 71 log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir));
72 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); 72 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
73 log_setting("Debugging_ProgramArgs", values.program_args); 73 log_setting("Debugging_ProgramArgs", values.program_args.GetValue());
74 log_setting("Services_BCATBackend", values.bcat_backend); 74 log_setting("Services_BCATBackend", values.bcat_backend.GetValue());
75 log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local); 75 log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue());
76} 76}
77 77
78bool IsConfiguringGlobal() { 78bool IsConfiguringGlobal() {
@@ -94,7 +94,7 @@ bool IsGPULevelHigh() {
94 94
95bool IsFastmemEnabled() { 95bool IsFastmemEnabled() {
96 if (values.cpu_accuracy.GetValue() == CPUAccuracy::DebugMode) { 96 if (values.cpu_accuracy.GetValue() == CPUAccuracy::DebugMode) {
97 return values.cpuopt_fastmem; 97 return static_cast<bool>(values.cpuopt_fastmem);
98 } 98 }
99 return true; 99 return true;
100} 100}
diff --git a/src/common/settings.h b/src/common/settings.h
index dd2d8d4d8..13896debf 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -10,10 +10,12 @@
10#include <map> 10#include <map>
11#include <optional> 11#include <optional>
12#include <string> 12#include <string>
13#include <utility>
13#include <vector> 14#include <vector>
14 15
15#include "common/common_types.h" 16#include "common/common_types.h"
16#include "common/settings_input.h" 17#include "common/settings_input.h"
18#include "input_common/udp/client.h"
17 19
18namespace Settings { 20namespace Settings {
19 21
@@ -34,73 +36,236 @@ enum class CPUAccuracy : u32 {
34 DebugMode = 2, 36 DebugMode = 2,
35}; 37};
36 38
39/** The BasicSetting class is a simple resource manager. It defines a label and default value
40 * alongside the actual value of the setting for simpler and less-error prone use with frontend
41 * configurations. Setting a default value and label is required, though subclasses may deviate from
42 * this requirement.
43 */
37template <typename Type> 44template <typename Type>
38class Setting final { 45class BasicSetting {
46protected:
47 BasicSetting() = default;
48
49 /**
50 * Only sets the setting to the given initializer, leaving the other members to their default
51 * initializers.
52 *
53 * @param global_val Initial value of the setting
54 */
55 explicit BasicSetting(const Type& global_val) : global{global_val} {}
56
39public: 57public:
40 explicit Setting(Type val) : global{val} { 58 /**
41 default_value = val; 59 * Sets a default value, label, and setting value.
60 *
61 * @param default_val Intial value of the setting, and default value of the setting
62 * @param name Label for the setting
63 */
64 explicit BasicSetting(const Type& default_val, const std::string& name)
65 : default_value{default_val}, global{default_val}, label{name} {}
66 ~BasicSetting() = default;
67
68 /**
69 * Returns a reference to the setting's value.
70 *
71 * @returns A reference to the setting
72 */
73 [[nodiscard]] const Type& GetValue() const {
74 return global;
75 }
76
77 /**
78 * Sets the setting to the given value.
79 *
80 * @param value The desired value
81 */
82 void SetValue(const Type& value) {
83 Type temp{value};
84 std::swap(global, temp);
42 } 85 }
86
87 /**
88 * Returns the value that this setting was created with.
89 *
90 * @returns A reference to the default value
91 */
92 [[nodiscard]] const Type& GetDefault() const {
93 return default_value;
94 }
95
96 /**
97 * Returns the label this setting was created with.
98 *
99 * @returns A reference to the label
100 */
101 [[nodiscard]] const std::string& GetLabel() const {
102 return label;
103 }
104
105 /**
106 * Assigns a value to the setting.
107 *
108 * @param value The desired setting value
109 *
110 * @returns A reference to the setting
111 */
112 const Type& operator=(const Type& value) {
113 Type temp{value};
114 std::swap(global, temp);
115 return global;
116 }
117
118 /**
119 * Returns a reference to the setting.
120 *
121 * @returns A reference to the setting
122 */
123 explicit operator const Type&() const {
124 return global;
125 }
126
127protected:
128 const Type default_value{}; ///< The default value
129 Type global{}; ///< The setting
130 const std::string label{}; ///< The setting's label
131};
132
133/**
134 * The Setting class is a slightly more complex version of the BasicSetting class. This adds a
135 * custom setting to switch to when a guest application specifically requires it. The effect is that
136 * other components of the emulator can access the setting's intended value without any need for the
137 * component to ask whether the custom or global setting is needed at the moment.
138 *
139 * By default, the global setting is used.
140 *
141 * Like the BasicSetting, this requires setting a default value and label to use.
142 */
143template <typename Type>
144class Setting final : public BasicSetting<Type> {
145public:
146 /**
147 * Sets a default value, label, and setting value.
148 *
149 * @param default_val Intial value of the setting, and default value of the setting
150 * @param name Label for the setting
151 */
152 explicit Setting(const Type& default_val, const std::string& name)
153 : BasicSetting<Type>(default_val, name) {}
43 ~Setting() = default; 154 ~Setting() = default;
155
156 /**
157 * Tells this setting to represent either the global or custom setting when other member
158 * functions are used. Setting to_global to true means using the global setting, to false
159 * false for the custom setting.
160 *
161 * @param to_global Whether to use the global or custom setting.
162 */
44 void SetGlobal(bool to_global) { 163 void SetGlobal(bool to_global) {
45 use_global = to_global; 164 use_global = to_global;
46 } 165 }
47 bool UsingGlobal() const { 166
167 /**
168 * Returns whether this setting is using the global setting or not.
169 *
170 * @returns The global state
171 */
172 [[nodiscard]] bool UsingGlobal() const {
48 return use_global; 173 return use_global;
49 } 174 }
50 Type GetValue(bool need_global = false) const { 175
176 /**
177 * Returns either the global or custom setting depending on the values of this setting's global
178 * state or if the global value was specifically requested.
179 *
180 * @param need_global Request global value regardless of setting's state; defaults to false
181 *
182 * @returns The required value of the setting
183 */
184 [[nodiscard]] const Type& GetValue(bool need_global = false) const {
51 if (use_global || need_global) { 185 if (use_global || need_global) {
52 return global; 186 return this->global;
53 } 187 }
54 return local; 188 return custom;
55 } 189 }
190
191 /**
192 * Sets the current setting value depending on the global state.
193 *
194 * @param value The new value
195 */
56 void SetValue(const Type& value) { 196 void SetValue(const Type& value) {
197 Type temp{value};
57 if (use_global) { 198 if (use_global) {
58 global = value; 199 std::swap(this->global, temp);
59 } else { 200 } else {
60 local = value; 201 std::swap(custom, temp);
61 } 202 }
62 } 203 }
63 Type GetDefault() const { 204
64 return default_value; 205 /**
206 * Assigns the current setting value depending on the global state.
207 *
208 * @param value The new value
209 *
210 * @returns A reference to the current setting value
211 */
212 const Type& operator=(const Type& value) {
213 Type temp{value};
214 if (use_global) {
215 std::swap(this->global, temp);
216 return this->global;
217 }
218 std::swap(custom, temp);
219 return custom;
220 }
221
222 /**
223 * Returns the current setting value depending on the global state.
224 *
225 * @returns A reference to the current setting value
226 */
227 explicit operator const Type&() const {
228 if (use_global) {
229 return this->global;
230 }
231 return custom;
65 } 232 }
66 233
67private: 234private:
68 bool use_global = true; 235 bool use_global{true}; ///< The setting's global state
69 Type global{}; 236 Type custom{}; ///< The custom value of the setting
70 Type local{};
71 Type default_value{};
72}; 237};
73 238
74/** 239/**
75 * The InputSetting class allows for getting a reference to either the global or local members. 240 * The InputSetting class allows for getting a reference to either the global or custom members.
76 * This is required as we cannot easily modify the values of user-defined types within containers 241 * This is required as we cannot easily modify the values of user-defined types within containers
77 * using the SetValue() member function found in the Setting class. The primary purpose of this 242 * using the SetValue() member function found in the Setting class. The primary purpose of this
78 * class is to store an array of 10 PlayerInput structs for both the global and local (per-game) 243 * class is to store an array of 10 PlayerInput structs for both the global and custom setting and
79 * setting and allows for easily accessing and modifying both settings. 244 * allows for easily accessing and modifying both settings.
80 */ 245 */
81template <typename Type> 246template <typename Type>
82class InputSetting final { 247class InputSetting final {
83public: 248public:
84 InputSetting() = default; 249 InputSetting() = default;
85 explicit InputSetting(Type val) : global{val} {} 250 explicit InputSetting(Type val) : BasicSetting<Type>(val) {}
86 ~InputSetting() = default; 251 ~InputSetting() = default;
87 void SetGlobal(bool to_global) { 252 void SetGlobal(bool to_global) {
88 use_global = to_global; 253 use_global = to_global;
89 } 254 }
90 bool UsingGlobal() const { 255 [[nodiscard]] bool UsingGlobal() const {
91 return use_global; 256 return use_global;
92 } 257 }
93 Type& GetValue(bool need_global = false) { 258 [[nodiscard]] Type& GetValue(bool need_global = false) {
94 if (use_global || need_global) { 259 if (use_global || need_global) {
95 return global; 260 return global;
96 } 261 }
97 return local; 262 return custom;
98 } 263 }
99 264
100private: 265private:
101 bool use_global = true; 266 bool use_global{true}; ///< The setting's global state
102 Type global{}; 267 Type global{}; ///< The setting
103 Type local{}; 268 Type custom{}; ///< The custom setting value
104}; 269};
105 270
106struct TouchFromButtonMap { 271struct TouchFromButtonMap {
@@ -110,152 +275,155 @@ struct TouchFromButtonMap {
110 275
111struct Values { 276struct Values {
112 // Audio 277 // Audio
113 std::string audio_device_id; 278 BasicSetting<std::string> audio_device_id{"auto", "output_device"};
114 std::string sink_id; 279 BasicSetting<std::string> sink_id{"auto", "output_engine"};
115 bool audio_muted; 280 BasicSetting<bool> audio_muted{false, "audio_muted"};
116 Setting<bool> enable_audio_stretching{true}; 281 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
117 Setting<float> volume{1.0f}; 282 Setting<float> volume{1.0f, "volume"};
118 283
119 // Core 284 // Core
120 Setting<bool> use_multi_core{true}; 285 Setting<bool> use_multi_core{true, "use_multi_core"};
121 286
122 // Cpu 287 // Cpu
123 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Accurate}; 288 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Accurate, "cpu_accuracy"};
124 289
125 bool cpuopt_page_tables; 290 BasicSetting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"};
126 bool cpuopt_block_linking; 291 BasicSetting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"};
127 bool cpuopt_return_stack_buffer; 292 BasicSetting<bool> cpuopt_return_stack_buffer{true, "cpuopt_return_stack_buffer"};
128 bool cpuopt_fast_dispatcher; 293 BasicSetting<bool> cpuopt_fast_dispatcher{true, "cpuopt_fast_dispatcher"};
129 bool cpuopt_context_elimination; 294 BasicSetting<bool> cpuopt_context_elimination{true, "cpuopt_context_elimination"};
130 bool cpuopt_const_prop; 295 BasicSetting<bool> cpuopt_const_prop{true, "cpuopt_const_prop"};
131 bool cpuopt_misc_ir; 296 BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"};
132 bool cpuopt_reduce_misalign_checks; 297 BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"};
133 bool cpuopt_fastmem; 298 BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
134 299
135 Setting<bool> cpuopt_unsafe_unfuse_fma{true}; 300 Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
136 Setting<bool> cpuopt_unsafe_reduce_fp_error{true}; 301 Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"};
137 Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true}; 302 Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"};
138 Setting<bool> cpuopt_unsafe_inaccurate_nan{true}; 303 Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"};
139 Setting<bool> cpuopt_unsafe_fastmem_check{true}; 304 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
140 305
141 // Renderer 306 // Renderer
142 Setting<RendererBackend> renderer_backend{RendererBackend::OpenGL}; 307 Setting<RendererBackend> renderer_backend{RendererBackend::OpenGL, "backend"};
143 bool renderer_debug; 308 BasicSetting<bool> renderer_debug{false, "debug"};
144 Setting<int> vulkan_device{0}; 309 Setting<int> vulkan_device{0, "vulkan_device"};
145 310
146 Setting<u16> resolution_factor{0}; 311 Setting<u16> resolution_factor{0, "resolution_factor"};
147 // *nix platforms may have issues with the borderless windowed fullscreen mode. 312 // *nix platforms may have issues with the borderless windowed fullscreen mode.
148 // Default to exclusive fullscreen on these platforms for now. 313 // Default to exclusive fullscreen on these platforms for now.
149 Setting<int> fullscreen_mode{ 314 Setting<int> fullscreen_mode{
150#ifdef _WIN32 315#ifdef _WIN32
151 0 316 0,
152#else 317#else
153 1 318 1,
154#endif 319#endif
155 }; 320 "fullscreen_mode"};
156 Setting<int> aspect_ratio{0}; 321 Setting<int> aspect_ratio{0, "aspect_ratio"};
157 Setting<int> max_anisotropy{0}; 322 Setting<int> max_anisotropy{0, "max_anisotropy"};
158 Setting<bool> use_frame_limit{true}; 323 Setting<bool> use_frame_limit{true, "use_frame_limit"};
159 Setting<u16> frame_limit{100}; 324 Setting<u16> frame_limit{100, "frame_limit"};
160 Setting<bool> use_disk_shader_cache{true}; 325 Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
161 Setting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High}; 326 Setting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, "gpu_accuracy"};
162 Setting<bool> use_asynchronous_gpu_emulation{true}; 327 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
163 Setting<bool> use_nvdec_emulation{true}; 328 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
164 Setting<bool> accelerate_astc{true}; 329 Setting<bool> accelerate_astc{true, "accelerate_astc"};
165 Setting<bool> use_vsync{true}; 330 Setting<bool> use_vsync{true, "use_vsync"};
166 Setting<bool> disable_fps_limit{false}; 331 Setting<bool> disable_fps_limit{false, "disable_fps_limit"};
167 Setting<bool> use_assembly_shaders{false}; 332 Setting<bool> use_assembly_shaders{false, "use_assembly_shaders"};
168 Setting<bool> use_asynchronous_shaders{false}; 333 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
169 Setting<bool> use_fast_gpu_time{true}; 334 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
170 Setting<bool> use_caches_gc{false}; 335 Setting<bool> use_caches_gc{false, "use_caches_gc"};
171 336
172 Setting<float> bg_red{0.0f}; 337 Setting<float> bg_red{0.0f, "bg_red"};
173 Setting<float> bg_green{0.0f}; 338 Setting<float> bg_green{0.0f, "bg_green"};
174 Setting<float> bg_blue{0.0f}; 339 Setting<float> bg_blue{0.0f, "bg_blue"};
175 340
176 // System 341 // System
177 Setting<std::optional<u32>> rng_seed{std::optional<u32>()}; 342 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
178 // Measured in seconds since epoch 343 // Measured in seconds since epoch
179 std::optional<std::chrono::seconds> custom_rtc; 344 std::optional<std::chrono::seconds> custom_rtc;
180 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` 345 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
181 std::chrono::seconds custom_rtc_differential; 346 std::chrono::seconds custom_rtc_differential;
182 347
183 s32 current_user; 348 BasicSetting<s32> current_user{0, "current_user"};
184 Setting<s32> language_index{1}; 349 Setting<s32> language_index{1, "language_index"};
185 Setting<s32> region_index{1}; 350 Setting<s32> region_index{1, "region_index"};
186 Setting<s32> time_zone_index{0}; 351 Setting<s32> time_zone_index{0, "time_zone_index"};
187 Setting<s32> sound_index{1}; 352 Setting<s32> sound_index{1, "sound_index"};
188 353
189 // Controls 354 // Controls
190 InputSetting<std::array<PlayerInput, 10>> players; 355 InputSetting<std::array<PlayerInput, 10>> players;
191 356
192 Setting<bool> use_docked_mode{true}; 357 Setting<bool> use_docked_mode{true, "use_docked_mode"};
193 358
194 Setting<bool> vibration_enabled{true}; 359 Setting<bool> vibration_enabled{true, "vibration_enabled"};
195 Setting<bool> enable_accurate_vibrations{false}; 360 Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
196 361
197 Setting<bool> motion_enabled{true}; 362 Setting<bool> motion_enabled{true, "motion_enabled"};
198 std::string motion_device; 363 BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01",
199 std::string udp_input_servers; 364 "motion_device"};
365 BasicSetting<std::string> udp_input_servers{InputCommon::CemuhookUDP::DEFAULT_SRV,
366 "udp_input_servers"};
200 367
201 bool mouse_panning; 368 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
202 float mouse_panning_sensitivity; 369 BasicSetting<float> mouse_panning_sensitivity{1.0f, "mouse_panning_sensitivity"};
203 bool mouse_enabled; 370 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
204 std::string mouse_device; 371 std::string mouse_device;
205 MouseButtonsRaw mouse_buttons; 372 MouseButtonsRaw mouse_buttons;
206 373
207 bool emulate_analog_keyboard; 374 BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
208 bool keyboard_enabled; 375 BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"};
209 KeyboardKeysRaw keyboard_keys; 376 KeyboardKeysRaw keyboard_keys;
210 KeyboardModsRaw keyboard_mods; 377 KeyboardModsRaw keyboard_mods;
211 378
212 bool debug_pad_enabled; 379 BasicSetting<bool> debug_pad_enabled{false, "debug_pad_enabled"};
213 ButtonsRaw debug_pad_buttons; 380 ButtonsRaw debug_pad_buttons;
214 AnalogsRaw debug_pad_analogs; 381 AnalogsRaw debug_pad_analogs;
215 382
216 TouchscreenInput touchscreen; 383 TouchscreenInput touchscreen;
217 384
218 bool use_touch_from_button; 385 BasicSetting<bool> use_touch_from_button{false, "use_touch_from_button"};
219 std::string touch_device; 386 BasicSetting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850",
220 int touch_from_button_map_index; 387 "touch_device"};
388 BasicSetting<int> touch_from_button_map_index{0, "touch_from_button_map"};
221 std::vector<TouchFromButtonMap> touch_from_button_maps; 389 std::vector<TouchFromButtonMap> touch_from_button_maps;
222 390
223 std::atomic_bool is_device_reload_pending{true}; 391 std::atomic_bool is_device_reload_pending{true};
224 392
225 // Data Storage 393 // Data Storage
226 bool use_virtual_sd; 394 BasicSetting<bool> use_virtual_sd{true, "use_virtual_sd"};
227 bool gamecard_inserted; 395 BasicSetting<bool> gamecard_inserted{false, "gamecard_inserted"};
228 bool gamecard_current_game; 396 BasicSetting<bool> gamecard_current_game{false, "gamecard_current_game"};
229 std::string gamecard_path; 397 BasicSetting<std::string> gamecard_path{std::string(), "gamecard_path"};
230 398
231 // Debugging 399 // Debugging
232 bool record_frame_times; 400 bool record_frame_times;
233 bool use_gdbstub; 401 BasicSetting<bool> use_gdbstub{false, "use_gdbstub"};
234 u16 gdbstub_port; 402 BasicSetting<u16> gdbstub_port{0, "gdbstub_port"};
235 std::string program_args; 403 BasicSetting<std::string> program_args{std::string(), "program_args"};
236 bool dump_exefs; 404 BasicSetting<bool> dump_exefs{false, "dump_exefs"};
237 bool dump_nso; 405 BasicSetting<bool> dump_nso{false, "dump_nso"};
238 bool enable_fs_access_log; 406 BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"};
239 bool reporting_services; 407 BasicSetting<bool> reporting_services{false, "reporting_services"};
240 bool quest_flag; 408 BasicSetting<bool> quest_flag{false, "quest_flag"};
241 bool disable_macro_jit; 409 BasicSetting<bool> disable_macro_jit{false, "disable_macro_jit"};
242 bool extended_logging; 410 BasicSetting<bool> extended_logging{false, "extended_logging"};
243 bool use_debug_asserts; 411 BasicSetting<bool> use_debug_asserts{false, "use_debug_asserts"};
244 bool use_auto_stub; 412 BasicSetting<bool> use_auto_stub{false, "use_auto_stub"};
245 413
246 // Miscellaneous 414 // Miscellaneous
247 std::string log_filter; 415 BasicSetting<std::string> log_filter{"*:Info", "log_filter"};
248 bool use_dev_keys; 416 BasicSetting<bool> use_dev_keys{false, "use_dev_keys"};
249 417
250 // Services 418 // Services
251 std::string bcat_backend; 419 BasicSetting<std::string> bcat_backend{"none", "bcat_backend"};
252 bool bcat_boxcat_local; 420 BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"};
253 421
254 // WebService 422 // WebService
255 bool enable_telemetry; 423 BasicSetting<bool> enable_telemetry{true, "enable_telemetry"};
256 std::string web_api_url; 424 BasicSetting<std::string> web_api_url{"https://api.yuzu-emu.org", "web_api_url"};
257 std::string yuzu_username; 425 BasicSetting<std::string> yuzu_username{std::string(), "yuzu_username"};
258 std::string yuzu_token; 426 BasicSetting<std::string> yuzu_token{std::string(), "yuzu_token"};
259 427
260 // Add-Ons 428 // Add-Ons
261 std::map<u64, std::vector<std::string>> disabled_addons; 429 std::map<u64, std::vector<std::string>> disabled_addons;
diff --git a/src/core/core.cpp b/src/core/core.cpp
index e6f1aa0e7..fc6ec9512 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -263,9 +263,9 @@ struct System::Impl {
263 if (Settings::values.gamecard_inserted) { 263 if (Settings::values.gamecard_inserted) {
264 if (Settings::values.gamecard_current_game) { 264 if (Settings::values.gamecard_current_game) {
265 fs_controller.SetGameCard(GetGameFileFromPath(virtual_filesystem, filepath)); 265 fs_controller.SetGameCard(GetGameFileFromPath(virtual_filesystem, filepath));
266 } else if (!Settings::values.gamecard_path.empty()) { 266 } else if (!Settings::values.gamecard_path.GetValue().empty()) {
267 fs_controller.SetGameCard( 267 fs_controller.SetGameCard(GetGameFileFromPath(
268 GetGameFileFromPath(virtual_filesystem, Settings::values.gamecard_path)); 268 virtual_filesystem, static_cast<std::string>(Settings::values.gamecard_path)));
269 } 269 }
270 } 270 }
271 271
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp
index 8d960d1ca..4c58c310f 100644
--- a/src/core/frontend/applets/profile_select.cpp
+++ b/src/core/frontend/applets/profile_select.cpp
@@ -13,7 +13,7 @@ ProfileSelectApplet::~ProfileSelectApplet() = default;
13void DefaultProfileSelectApplet::SelectProfile( 13void DefaultProfileSelectApplet::SelectProfile(
14 std::function<void(std::optional<Common::UUID>)> callback) const { 14 std::function<void(std::optional<Common::UUID>)> callback) const {
15 Service::Account::ProfileManager manager; 15 Service::Account::ProfileManager manager;
16 callback(manager.GetUser(Settings::values.current_user).value_or(Common::UUID{})); 16 callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
17 LOG_INFO(Service_ACC, "called, selecting current user instead of prompting..."); 17 LOG_INFO(Service_ACC, "called, selecting current user instead of prompting...");
18} 18}
19 19
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index f72d5d561..24a1c9157 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -48,7 +48,8 @@ ProfileManager::ProfileManager() {
48 CreateNewUser(UUID::Generate(), "yuzu"); 48 CreateNewUser(UUID::Generate(), "yuzu");
49 } 49 }
50 50
51 auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); 51 auto current =
52 std::clamp<int>(static_cast<s32>(Settings::values.current_user), 0, MAX_USERS - 1);
52 53
53 // If user index don't exist. Load the first user and change the active user 54 // If user index don't exist. Load the first user and change the active user
54 if (!UserExistsIndex(current)) { 55 if (!UserExistsIndex(current)) {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index b578153d3..23ebc1138 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1443,7 +1443,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1443 params.is_account_selected = 1; 1443 params.is_account_selected = 1;
1444 1444
1445 Account::ProfileManager profile_manager{}; 1445 Account::ProfileManager profile_manager{};
1446 const auto uuid = profile_manager.GetUser(Settings::values.current_user); 1446 const auto uuid = profile_manager.GetUser(static_cast<s32>(Settings::values.current_user));
1447 ASSERT(uuid); 1447 ASSERT(uuid);
1448 params.current_user = uuid->uuid; 1448 params.current_user = uuid->uuid;
1449 1449
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index f03b2666a..e742db48f 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -179,7 +179,7 @@ private:
179 IPC::ResponseBuilder rb{ctx, 3}; 179 IPC::ResponseBuilder rb{ctx, 3};
180 rb.Push(ResultSuccess); 180 rb.Push(ResultSuccess);
181 181
182 if (Settings::values.bcat_backend == "none") { 182 if (Settings::values.bcat_backend.GetValue() == "none") {
183 rb.PushEnum(RequestState::NotSubmitted); 183 rb.PushEnum(RequestState::NotSubmitted);
184 } else { 184 } else {
185 rb.PushEnum(RequestState::Connected); 185 rb.PushEnum(RequestState::Connected);
@@ -384,7 +384,7 @@ private:
384 384
385 IPC::ResponseBuilder rb{ctx, 3}; 385 IPC::ResponseBuilder rb{ctx, 3};
386 rb.Push(ResultSuccess); 386 rb.Push(ResultSuccess);
387 if (Settings::values.bcat_backend == "none") { 387 if (Settings::values.bcat_backend.GetValue() == "none") {
388 rb.Push<u8>(0); 388 rb.Push<u8>(0);
389 } else { 389 } else {
390 rb.Push<u8>(1); 390 rb.Push<u8>(1);
@@ -395,7 +395,7 @@ private:
395 395
396 IPC::ResponseBuilder rb{ctx, 3}; 396 IPC::ResponseBuilder rb{ctx, 3};
397 rb.Push(ResultSuccess); 397 rb.Push(ResultSuccess);
398 if (Settings::values.bcat_backend == "none") { 398 if (Settings::values.bcat_backend.GetValue() == "none") {
399 rb.Push<u8>(0); 399 rb.Push<u8>(0);
400 } else { 400 } else {
401 rb.Push<u8>(1); 401 rb.Push<u8>(1);
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index ece2a74c6..522a604a5 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -160,7 +160,7 @@ void SET::GetQuestFlag(Kernel::HLERequestContext& ctx) {
160 160
161 IPC::ResponseBuilder rb{ctx, 3}; 161 IPC::ResponseBuilder rb{ctx, 3};
162 rb.Push(ResultSuccess); 162 rb.Push(ResultSuccess);
163 rb.Push(static_cast<u32>(Settings::values.quest_flag)); 163 rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue()));
164} 164}
165 165
166void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { 166void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 618555202..951ea966e 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -155,8 +155,8 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
155 codeset.segments[i].size = PageAlignSize(nro_header.segments[i].size); 155 codeset.segments[i].size = PageAlignSize(nro_header.segments[i].size);
156 } 156 }
157 157
158 if (!Settings::values.program_args.empty()) { 158 if (!Settings::values.program_args.GetValue().empty()) {
159 const auto arg_data = Settings::values.program_args; 159 const auto arg_data = Settings::values.program_args.GetValue();
160 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; 160 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE;
161 NSOArgumentHeader args_header{ 161 NSOArgumentHeader args_header{
162 NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; 162 NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}};
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 0f5cfda68..4a2224c02 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -104,8 +104,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
104 codeset.segments[i].size = nso_header.segments[i].size; 104 codeset.segments[i].size = nso_header.segments[i].size;
105 } 105 }
106 106
107 if (should_pass_arguments && !Settings::values.program_args.empty()) { 107 if (should_pass_arguments && !Settings::values.program_args.GetValue().empty()) {
108 const auto arg_data{Settings::values.program_args}; 108 const auto arg_data{Settings::values.program_args.GetValue()};
109 109
110 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; 110 codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE;
111 NSOArgumentHeader args_header{ 111 NSOArgumentHeader args_header{
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 82b0f535a..cfaf50105 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -397,7 +397,7 @@ void Reporter::ClearFSAccessLog() const {
397} 397}
398 398
399bool Reporter::IsReportingEnabled() const { 399bool Reporter::IsReportingEnabled() const {
400 return Settings::values.reporting_services; 400 return Settings::values.reporting_services.GetValue();
401} 401}
402 402
403} // namespace Core 403} // namespace Core
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index d4c23ced2..44b8bab5b 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -212,7 +212,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
212 212
213 // Log user configuration information 213 // Log user configuration information
214 constexpr auto field_type = Telemetry::FieldType::UserConfig; 214 constexpr auto field_type = Telemetry::FieldType::UserConfig;
215 AddField(field_type, "Audio_SinkId", Settings::values.sink_id); 215 AddField(field_type, "Audio_SinkId", Settings::values.sink_id.GetValue());
216 AddField(field_type, "Audio_EnableAudioStretching", 216 AddField(field_type, "Audio_EnableAudioStretching",
217 Settings::values.enable_audio_stretching.GetValue()); 217 Settings::values.enable_audio_stretching.GetValue());
218 AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); 218 AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue());
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
index 758f7af1f..4861a131e 100644
--- a/src/input_common/mouse/mouse_poller.cpp
+++ b/src/input_common/mouse/mouse_poller.cpp
@@ -84,7 +84,8 @@ public:
84 std::lock_guard lock{mutex}; 84 std::lock_guard lock{mutex};
85 const auto axis_value = 85 const auto axis_value =
86 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis)); 86 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
87 return axis_value * Settings::values.mouse_panning_sensitivity / (100.0f * range); 87 return axis_value * Settings::values.mouse_panning_sensitivity.GetValue() /
88 (100.0f * range);
88 } 89 }
89 90
90 std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { 91 std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
diff --git a/src/input_common/touch_from_button.cpp b/src/input_common/touch_from_button.cpp
index 5b24fd8bf..87207f48f 100644
--- a/src/input_common/touch_from_button.cpp
+++ b/src/input_common/touch_from_button.cpp
@@ -12,8 +12,7 @@ namespace InputCommon {
12class TouchFromButtonDevice final : public Input::TouchDevice { 12class TouchFromButtonDevice final : public Input::TouchDevice {
13public: 13public:
14 TouchFromButtonDevice() { 14 TouchFromButtonDevice() {
15 const auto button_index = 15 const auto button_index = Settings::values.touch_from_button_map_index.GetValue();
16 static_cast<std::size_t>(Settings::values.touch_from_button_map_index);
17 const auto& buttons = Settings::values.touch_from_button_maps[button_index].buttons; 16 const auto& buttons = Settings::values.touch_from_button_maps[button_index].buttons;
18 17
19 for (const auto& config_entry : buttons) { 18 for (const auto& config_entry : buttons) {
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index bc1dfab3d..9b0aec797 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -201,7 +201,7 @@ bool Client::DeviceConnected(std::size_t pad) const {
201void Client::ReloadSockets() { 201void Client::ReloadSockets() {
202 Reset(); 202 Reset();
203 203
204 std::stringstream servers_ss(Settings::values.udp_input_servers); 204 std::stringstream servers_ss(static_cast<std::string>(Settings::values.udp_input_servers));
205 std::string server_token; 205 std::string server_token;
206 std::size_t client = 0; 206 std::size_t client = 0;
207 while (std::getline(servers_ss, server_token, ',')) { 207 while (std::getline(servers_ss, server_token, ',')) {
@@ -370,7 +370,7 @@ std::optional<std::size_t> Client::GetUnusedFingerID() const {
370 370
371void Client::UpdateTouchInput(Response::TouchPad& touch_pad, std::size_t client, std::size_t id) { 371void Client::UpdateTouchInput(Response::TouchPad& touch_pad, std::size_t client, std::size_t id) {
372 // TODO: Use custom calibration per device 372 // TODO: Use custom calibration per device
373 const Common::ParamPackage touch_param(Settings::values.touch_device); 373 const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
374 const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100)); 374 const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100));
375 const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50)); 375 const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50));
376 const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800)); 376 const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800));
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 3986eb172..2bab2b4f5 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -97,19 +97,14 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
97 Core::Frontend::EmuWindow& emu_window, 97 Core::Frontend::EmuWindow& emu_window,
98 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, 98 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
99 std::unique_ptr<Core::Frontend::GraphicsContext> context_) try 99 std::unique_ptr<Core::Frontend::GraphicsContext> context_) try
100 : RendererBase(emu_window, std::move(context_)), 100 : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_),
101 telemetry_session(telemetry_session_), 101 cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary()),
102 cpu_memory(cpu_memory_),
103 gpu(gpu_),
104 library(OpenLibrary()),
105 instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, 102 instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
106 true, Settings::values.renderer_debug)), 103 true, Settings::values.renderer_debug.GetValue())),
107 debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), 104 debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
108 surface(CreateSurface(instance, render_window)), 105 surface(CreateSurface(instance, render_window)),
109 device(CreateDevice(instance, dld, *surface)), 106 device(CreateDevice(instance, dld, *surface)), memory_allocator(device, false),
110 memory_allocator(device, false), 107 state_tracker(gpu), scheduler(device, state_tracker),
111 state_tracker(gpu),
112 scheduler(device, state_tracker),
113 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, 108 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
114 render_window.GetFramebufferLayout().height, false), 109 render_window.GetFramebufferLayout().height, false),
115 blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, scheduler, 110 blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, scheduler,
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 2ad0ac32e..d36aaade2 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -272,6 +272,82 @@ void Config::Initialize(const std::string& config_name) {
272 } 272 }
273} 273}
274 274
275// Explicity std::string definition: Qt can't implicitly convert a std::string to a QVariant, nor
276// can it implicitly convert a QVariant back to a {std::,Q}string
277template <>
278void Config::ReadBasicSetting(Settings::BasicSetting<std::string>& setting) {
279 const QString name = QString::fromStdString(setting.GetLabel());
280 if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
281 setting.SetValue(setting.GetDefault());
282 } else {
283 setting.SetValue(qt_config->value(name, QString::fromStdString(setting.GetDefault()))
284 .toString()
285 .toStdString());
286 }
287}
288template <typename Type>
289void Config::ReadBasicSetting(Settings::BasicSetting<Type>& setting) {
290 const QString name = QString::fromStdString(setting.GetLabel());
291 if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
292 setting.SetValue(setting.GetDefault());
293 } else {
294 setting.SetValue(
295 static_cast<QVariant>(qt_config->value(name, setting.GetDefault())).value<Type>());
296 }
297}
298
299// Explicit std::string definition: Qt can't implicitly convert a std::string to a QVariant
300template <>
301void Config::WriteBasicSetting(const Settings::BasicSetting<std::string>& setting) {
302 const QString name = QString::fromStdString(setting.GetLabel());
303 qt_config->setValue(name + QStringLiteral("/default"),
304 setting.GetValue() == setting.GetDefault());
305 qt_config->setValue(name, QString::fromStdString(setting.GetValue()));
306}
307// Explicit float definition: use a double as Qt doesn't write legible floats to config files
308template <>
309void Config::WriteBasicSetting(const Settings::BasicSetting<float>& setting) {
310 const QString name = QString::fromStdString(setting.GetLabel());
311 const double value = setting.GetValue();
312 qt_config->setValue(name + QStringLiteral("/default"),
313 setting.GetValue() == setting.GetDefault());
314 qt_config->setValue(name, value);
315}
316template <typename Type>
317void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
318 const QString name = QString::fromStdString(setting.GetLabel());
319 qt_config->setValue(name + QStringLiteral("/default"),
320 setting.GetValue() == setting.GetDefault());
321 qt_config->setValue(name, setting.GetValue());
322}
323
324// Explicit float definition: use a double as Qt doesn't write legible floats to config files
325template <>
326void Config::WriteGlobalSetting(const Settings::Setting<float>& setting) {
327 const QString name = QString::fromStdString(setting.GetLabel());
328 const double value = setting.GetValue(global);
329 if (!global) {
330 qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
331 }
332 if (global || !setting.UsingGlobal()) {
333 qt_config->setValue(name + QStringLiteral("/default"),
334 setting.GetValue(global) == setting.GetDefault());
335 qt_config->setValue(name, value);
336 }
337}
338template <typename Type>
339void Config::WriteGlobalSetting(const Settings::Setting<Type>& setting) {
340 QString name = QString::fromStdString(setting.GetLabel());
341 if (!global) {
342 qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
343 }
344 if (global || !setting.UsingGlobal()) {
345 qt_config->setValue(name + QStringLiteral("/default"),
346 setting.GetValue(global) == setting.GetDefault());
347 qt_config->setValue(name, setting.GetValue(global));
348 }
349}
350
275void Config::ReadPlayerValue(std::size_t player_index) { 351void Config::ReadPlayerValue(std::size_t player_index) {
276 const QString player_prefix = [this, player_index] { 352 const QString player_prefix = [this, player_index] {
277 if (type == ConfigType::InputProfile) { 353 if (type == ConfigType::InputProfile) {
@@ -395,8 +471,7 @@ void Config::ReadPlayerValue(std::size_t player_index) {
395} 471}
396 472
397void Config::ReadDebugValues() { 473void Config::ReadDebugValues() {
398 Settings::values.debug_pad_enabled = 474 ReadBasicSetting(Settings::values.debug_pad_enabled);
399 ReadSetting(QStringLiteral("debug_pad_enabled"), false).toBool();
400 475
401 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 476 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
402 const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); 477 const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
@@ -432,8 +507,7 @@ void Config::ReadDebugValues() {
432} 507}
433 508
434void Config::ReadKeyboardValues() { 509void Config::ReadKeyboardValues() {
435 Settings::values.keyboard_enabled = 510 ReadBasicSetting(Settings::values.keyboard_enabled);
436 ReadSetting(QStringLiteral("keyboard_enabled"), false).toBool();
437 511
438 std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(), 512 std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(),
439 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); 513 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
@@ -446,7 +520,7 @@ void Config::ReadKeyboardValues() {
446} 520}
447 521
448void Config::ReadMouseValues() { 522void Config::ReadMouseValues() {
449 Settings::values.mouse_enabled = ReadSetting(QStringLiteral("mouse_enabled"), false).toBool(); 523 ReadBasicSetting(Settings::values.mouse_enabled);
450 524
451 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { 525 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
452 const std::string default_param = 526 const std::string default_param =
@@ -481,18 +555,11 @@ void Config::ReadAudioValues() {
481 qt_config->beginGroup(QStringLiteral("Audio")); 555 qt_config->beginGroup(QStringLiteral("Audio"));
482 556
483 if (global) { 557 if (global) {
484 Settings::values.sink_id = 558 ReadBasicSetting(Settings::values.audio_device_id);
485 ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto")) 559 ReadBasicSetting(Settings::values.sink_id);
486 .toString()
487 .toStdString();
488 Settings::values.audio_device_id =
489 ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto"))
490 .toString()
491 .toStdString();
492 } 560 }
493 ReadSettingGlobal(Settings::values.enable_audio_stretching, 561 ReadGlobalSetting(Settings::values.enable_audio_stretching);
494 QStringLiteral("enable_audio_stretching")); 562 ReadGlobalSetting(Settings::values.volume);
495 ReadSettingGlobal(Settings::values.volume, QStringLiteral("volume"));
496 563
497 qt_config->endGroup(); 564 qt_config->endGroup();
498} 565}
@@ -509,13 +576,11 @@ void Config::ReadControlValues() {
509 ReadTouchscreenValues(); 576 ReadTouchscreenValues();
510 ReadMotionTouchValues(); 577 ReadMotionTouchValues();
511 578
512 Settings::values.emulate_analog_keyboard = 579 ReadBasicSetting(Settings::values.emulate_analog_keyboard);
513 ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool();
514 Settings::values.mouse_panning = false; 580 Settings::values.mouse_panning = false;
515 Settings::values.mouse_panning_sensitivity = 581 ReadBasicSetting(Settings::values.mouse_panning_sensitivity);
516 ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 1).toFloat();
517 582
518 ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode")); 583 ReadGlobalSetting(Settings::values.use_docked_mode);
519 584
520 // Disable docked mode if handheld is selected 585 // Disable docked mode if handheld is selected
521 const auto controller_type = Settings::values.players.GetValue()[0].controller_type; 586 const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
@@ -523,10 +588,9 @@ void Config::ReadControlValues() {
523 Settings::values.use_docked_mode.SetValue(false); 588 Settings::values.use_docked_mode.SetValue(false);
524 } 589 }
525 590
526 ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled")); 591 ReadGlobalSetting(Settings::values.vibration_enabled);
527 ReadSettingGlobal(Settings::values.enable_accurate_vibrations, 592 ReadGlobalSetting(Settings::values.enable_accurate_vibrations);
528 QStringLiteral("enable_accurate_vibrations")); 593 ReadGlobalSetting(Settings::values.motion_enabled);
529 ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"));
530 594
531 qt_config->endGroup(); 595 qt_config->endGroup();
532} 596}
@@ -564,33 +628,19 @@ void Config::ReadMotionTouchValues() {
564 } 628 }
565 qt_config->endArray(); 629 qt_config->endArray();
566 630
567 Settings::values.motion_device = 631 ReadBasicSetting(Settings::values.motion_device);
568 ReadSetting(QStringLiteral("motion_device"), 632 ReadBasicSetting(Settings::values.touch_device);
569 QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01")) 633 ReadBasicSetting(Settings::values.use_touch_from_button);
570 .toString() 634 ReadBasicSetting(Settings::values.touch_from_button_map_index);
571 .toStdString(); 635 Settings::values.touch_from_button_map_index = std::clamp(
572 Settings::values.touch_device = 636 Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
573 ReadSetting(QStringLiteral("touch_device"), 637 ReadBasicSetting(Settings::values.udp_input_servers);
574 QStringLiteral("min_x:100,min_y:50,max_x:1800,max_y:850"))
575 .toString()
576 .toStdString();
577 Settings::values.use_touch_from_button =
578 ReadSetting(QStringLiteral("use_touch_from_button"), false).toBool();
579 Settings::values.touch_from_button_map_index =
580 ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();
581 Settings::values.touch_from_button_map_index =
582 std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
583 Settings::values.udp_input_servers =
584 ReadSetting(QStringLiteral("udp_input_servers"),
585 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV))
586 .toString()
587 .toStdString();
588} 638}
589 639
590void Config::ReadCoreValues() { 640void Config::ReadCoreValues() {
591 qt_config->beginGroup(QStringLiteral("Core")); 641 qt_config->beginGroup(QStringLiteral("Core"));
592 642
593 ReadSettingGlobal(Settings::values.use_multi_core, QStringLiteral("use_multi_core")); 643 ReadGlobalSetting(Settings::values.use_multi_core);
594 644
595 qt_config->endGroup(); 645 qt_config->endGroup();
596} 646}
@@ -598,7 +648,7 @@ void Config::ReadCoreValues() {
598void Config::ReadDataStorageValues() { 648void Config::ReadDataStorageValues() {
599 qt_config->beginGroup(QStringLiteral("Data Storage")); 649 qt_config->beginGroup(QStringLiteral("Data Storage"));
600 650
601 Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool(); 651 ReadBasicSetting(Settings::values.use_virtual_sd);
602 FS::SetYuzuPath( 652 FS::SetYuzuPath(
603 FS::YuzuPath::NANDDir, 653 FS::YuzuPath::NANDDir,
604 qt_config 654 qt_config
@@ -627,12 +677,9 @@ void Config::ReadDataStorageValues() {
627 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir))) 677 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)))
628 .toString() 678 .toString()
629 .toStdString()); 679 .toStdString());
630 Settings::values.gamecard_inserted = 680 ReadBasicSetting(Settings::values.gamecard_inserted);
631 ReadSetting(QStringLiteral("gamecard_inserted"), false).toBool(); 681 ReadBasicSetting(Settings::values.gamecard_current_game);
632 Settings::values.gamecard_current_game = 682 ReadBasicSetting(Settings::values.gamecard_path);
633 ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool();
634 Settings::values.gamecard_path =
635 ReadSetting(QStringLiteral("gamecard_path"), QString{}).toString().toStdString();
636 683
637 qt_config->endGroup(); 684 qt_config->endGroup();
638} 685}
@@ -643,34 +690,24 @@ void Config::ReadDebuggingValues() {
643 // Intentionally not using the QT default setting as this is intended to be changed in the ini 690 // Intentionally not using the QT default setting as this is intended to be changed in the ini
644 Settings::values.record_frame_times = 691 Settings::values.record_frame_times =
645 qt_config->value(QStringLiteral("record_frame_times"), false).toBool(); 692 qt_config->value(QStringLiteral("record_frame_times"), false).toBool();
646 Settings::values.program_args = 693 ReadBasicSetting(Settings::values.program_args);
647 ReadSetting(QStringLiteral("program_args"), QString{}).toString().toStdString(); 694 ReadBasicSetting(Settings::values.dump_exefs);
648 Settings::values.dump_exefs = ReadSetting(QStringLiteral("dump_exefs"), false).toBool(); 695 ReadBasicSetting(Settings::values.dump_nso);
649 Settings::values.dump_nso = ReadSetting(QStringLiteral("dump_nso"), false).toBool(); 696 ReadBasicSetting(Settings::values.enable_fs_access_log);
650 Settings::values.enable_fs_access_log = 697 ReadBasicSetting(Settings::values.reporting_services);
651 ReadSetting(QStringLiteral("enable_fs_access_log"), false).toBool(); 698 ReadBasicSetting(Settings::values.quest_flag);
652 Settings::values.reporting_services = 699 ReadBasicSetting(Settings::values.disable_macro_jit);
653 ReadSetting(QStringLiteral("reporting_services"), false).toBool(); 700 ReadBasicSetting(Settings::values.extended_logging);
654 Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool(); 701 ReadBasicSetting(Settings::values.use_debug_asserts);
655 Settings::values.disable_macro_jit = 702 ReadBasicSetting(Settings::values.use_auto_stub);
656 ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
657 Settings::values.extended_logging =
658 ReadSetting(QStringLiteral("extended_logging"), false).toBool();
659 Settings::values.use_debug_asserts =
660 ReadSetting(QStringLiteral("use_debug_asserts"), false).toBool();
661 Settings::values.use_auto_stub = ReadSetting(QStringLiteral("use_auto_stub"), false).toBool();
662 703
663 qt_config->endGroup(); 704 qt_config->endGroup();
664} 705}
665 706
666void Config::ReadServiceValues() { 707void Config::ReadServiceValues() {
667 qt_config->beginGroup(QStringLiteral("Services")); 708 qt_config->beginGroup(QStringLiteral("Services"));
668 Settings::values.bcat_backend = 709 ReadBasicSetting(Settings::values.bcat_backend);
669 ReadSetting(QStringLiteral("bcat_backend"), QStringLiteral("none")) 710 ReadBasicSetting(Settings::values.bcat_boxcat_local);
670 .toString()
671 .toStdString();
672 Settings::values.bcat_boxcat_local =
673 ReadSetting(QStringLiteral("bcat_boxcat_local"), false).toBool();
674 qt_config->endGroup(); 711 qt_config->endGroup();
675} 712}
676 713
@@ -696,11 +733,8 @@ void Config::ReadDisabledAddOnValues() {
696void Config::ReadMiscellaneousValues() { 733void Config::ReadMiscellaneousValues() {
697 qt_config->beginGroup(QStringLiteral("Miscellaneous")); 734 qt_config->beginGroup(QStringLiteral("Miscellaneous"));
698 735
699 Settings::values.log_filter = 736 ReadBasicSetting(Settings::values.log_filter);
700 ReadSetting(QStringLiteral("log_filter"), QStringLiteral("*:Info")) 737 ReadBasicSetting(Settings::values.use_dev_keys);
701 .toString()
702 .toStdString();
703 Settings::values.use_dev_keys = ReadSetting(QStringLiteral("use_dev_keys"), false).toBool();
704 738
705 qt_config->endGroup(); 739 qt_config->endGroup();
706} 740}
@@ -750,38 +784,24 @@ void Config::ReadPathValues() {
750void Config::ReadCpuValues() { 784void Config::ReadCpuValues() {
751 qt_config->beginGroup(QStringLiteral("Cpu")); 785 qt_config->beginGroup(QStringLiteral("Cpu"));
752 786
753 ReadSettingGlobal(Settings::values.cpu_accuracy, QStringLiteral("cpu_accuracy")); 787 ReadGlobalSetting(Settings::values.cpu_accuracy);
754 788
755 ReadSettingGlobal(Settings::values.cpuopt_unsafe_unfuse_fma, 789 ReadGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma);
756 QStringLiteral("cpuopt_unsafe_unfuse_fma")); 790 ReadGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error);
757 ReadSettingGlobal(Settings::values.cpuopt_unsafe_reduce_fp_error, 791 ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
758 QStringLiteral("cpuopt_unsafe_reduce_fp_error")); 792 ReadGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
759 ReadSettingGlobal(Settings::values.cpuopt_unsafe_ignore_standard_fpcr, 793 ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
760 QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"));
761 ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
762 QStringLiteral("cpuopt_unsafe_inaccurate_nan"));
763 ReadSettingGlobal(Settings::values.cpuopt_unsafe_fastmem_check,
764 QStringLiteral("cpuopt_unsafe_fastmem_check"));
765 794
766 if (global) { 795 if (global) {
767 Settings::values.cpuopt_page_tables = 796 ReadBasicSetting(Settings::values.cpuopt_page_tables);
768 ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool(); 797 ReadBasicSetting(Settings::values.cpuopt_block_linking);
769 Settings::values.cpuopt_block_linking = 798 ReadBasicSetting(Settings::values.cpuopt_return_stack_buffer);
770 ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool(); 799 ReadBasicSetting(Settings::values.cpuopt_fast_dispatcher);
771 Settings::values.cpuopt_return_stack_buffer = 800 ReadBasicSetting(Settings::values.cpuopt_context_elimination);
772 ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool(); 801 ReadBasicSetting(Settings::values.cpuopt_const_prop);
773 Settings::values.cpuopt_fast_dispatcher = 802 ReadBasicSetting(Settings::values.cpuopt_misc_ir);
774 ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool(); 803 ReadBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
775 Settings::values.cpuopt_context_elimination = 804 ReadBasicSetting(Settings::values.cpuopt_fastmem);
776 ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool();
777 Settings::values.cpuopt_const_prop =
778 ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool();
779 Settings::values.cpuopt_misc_ir =
780 ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
781 Settings::values.cpuopt_reduce_misalign_checks =
782 ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
783 Settings::values.cpuopt_fastmem =
784 ReadSetting(QStringLiteral("cpuopt_fastmem"), true).toBool();
785 } 805 }
786 806
787 qt_config->endGroup(); 807 qt_config->endGroup();
@@ -790,32 +810,28 @@ void Config::ReadCpuValues() {
790void Config::ReadRendererValues() { 810void Config::ReadRendererValues() {
791 qt_config->beginGroup(QStringLiteral("Renderer")); 811 qt_config->beginGroup(QStringLiteral("Renderer"));
792 812
793 ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend")); 813 ReadGlobalSetting(Settings::values.renderer_backend);
794 ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false); 814 ReadBasicSetting(Settings::values.renderer_debug);
795 ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device")); 815 ReadGlobalSetting(Settings::values.vulkan_device);
796 ReadSettingGlobal(Settings::values.fullscreen_mode, QStringLiteral("fullscreen_mode")); 816 ReadGlobalSetting(Settings::values.fullscreen_mode);
797 ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio")); 817 ReadGlobalSetting(Settings::values.aspect_ratio);
798 ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy")); 818 ReadGlobalSetting(Settings::values.max_anisotropy);
799 ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit")); 819 ReadGlobalSetting(Settings::values.use_frame_limit);
800 ReadSettingGlobal(Settings::values.frame_limit, QStringLiteral("frame_limit")); 820 ReadGlobalSetting(Settings::values.frame_limit);
801 ReadSettingGlobal(Settings::values.use_disk_shader_cache, 821 ReadGlobalSetting(Settings::values.use_disk_shader_cache);
802 QStringLiteral("use_disk_shader_cache")); 822 ReadGlobalSetting(Settings::values.gpu_accuracy);
803 ReadSettingGlobal(Settings::values.gpu_accuracy, QStringLiteral("gpu_accuracy")); 823 ReadGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
804 ReadSettingGlobal(Settings::values.use_asynchronous_gpu_emulation, 824 ReadGlobalSetting(Settings::values.use_nvdec_emulation);
805 QStringLiteral("use_asynchronous_gpu_emulation")); 825 ReadGlobalSetting(Settings::values.accelerate_astc);
806 ReadSettingGlobal(Settings::values.use_nvdec_emulation, QStringLiteral("use_nvdec_emulation")); 826 ReadGlobalSetting(Settings::values.use_vsync);
807 ReadSettingGlobal(Settings::values.accelerate_astc, QStringLiteral("accelerate_astc")); 827 ReadGlobalSetting(Settings::values.disable_fps_limit);
808 ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync")); 828 ReadGlobalSetting(Settings::values.use_assembly_shaders);
809 ReadSettingGlobal(Settings::values.disable_fps_limit, QStringLiteral("disable_fps_limit")); 829 ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
810 ReadSettingGlobal(Settings::values.use_assembly_shaders, 830 ReadGlobalSetting(Settings::values.use_fast_gpu_time);
811 QStringLiteral("use_assembly_shaders")); 831 ReadGlobalSetting(Settings::values.use_caches_gc);
812 ReadSettingGlobal(Settings::values.use_asynchronous_shaders, 832 ReadGlobalSetting(Settings::values.bg_red);
813 QStringLiteral("use_asynchronous_shaders")); 833 ReadGlobalSetting(Settings::values.bg_green);
814 ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time")); 834 ReadGlobalSetting(Settings::values.bg_blue);
815 ReadSettingGlobal(Settings::values.use_caches_gc, QStringLiteral("use_caches_gc"));
816 ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"));
817 ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"));
818 ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"));
819 835
820 qt_config->endGroup(); 836 qt_config->endGroup();
821} 837}
@@ -860,15 +876,15 @@ void Config::ReadShortcutValues() {
860void Config::ReadSystemValues() { 876void Config::ReadSystemValues() {
861 qt_config->beginGroup(QStringLiteral("System")); 877 qt_config->beginGroup(QStringLiteral("System"));
862 878
863 ReadSettingGlobal(Settings::values.current_user, QStringLiteral("current_user"), 0); 879 ReadBasicSetting(Settings::values.current_user);
864 Settings::values.current_user = 880 Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
865 std::clamp<int>(Settings::values.current_user, 0, Service::Account::MAX_USERS - 1); 881 Service::Account::MAX_USERS - 1);
866 882
867 ReadSettingGlobal(Settings::values.language_index, QStringLiteral("language_index")); 883 ReadGlobalSetting(Settings::values.language_index);
868 884
869 ReadSettingGlobal(Settings::values.region_index, QStringLiteral("region_index")); 885 ReadGlobalSetting(Settings::values.region_index);
870 886
871 ReadSettingGlobal(Settings::values.time_zone_index, QStringLiteral("time_zone_index")); 887 ReadGlobalSetting(Settings::values.time_zone_index);
872 888
873 bool rng_seed_enabled; 889 bool rng_seed_enabled;
874 ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false); 890 ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false);
@@ -894,7 +910,7 @@ void Config::ReadSystemValues() {
894 } 910 }
895 } 911 }
896 912
897 ReadSettingGlobal(Settings::values.sound_index, QStringLiteral("sound_index")); 913 ReadGlobalSetting(Settings::values.sound_index);
898 914
899 qt_config->endGroup(); 915 qt_config->endGroup();
900} 916}
@@ -978,16 +994,10 @@ void Config::ReadUILayoutValues() {
978void Config::ReadWebServiceValues() { 994void Config::ReadWebServiceValues() {
979 qt_config->beginGroup(QStringLiteral("WebService")); 995 qt_config->beginGroup(QStringLiteral("WebService"));
980 996
981 Settings::values.enable_telemetry = 997 ReadBasicSetting(Settings::values.enable_telemetry);
982 ReadSetting(QStringLiteral("enable_telemetry"), true).toBool(); 998 ReadBasicSetting(Settings::values.web_api_url);
983 Settings::values.web_api_url = 999 ReadBasicSetting(Settings::values.yuzu_username);
984 ReadSetting(QStringLiteral("web_api_url"), QStringLiteral("https://api.yuzu-emu.org")) 1000 ReadBasicSetting(Settings::values.yuzu_token);
985 .toString()
986 .toStdString();
987 Settings::values.yuzu_username =
988 ReadSetting(QStringLiteral("yuzu_username")).toString().toStdString();
989 Settings::values.yuzu_token =
990 ReadSetting(QStringLiteral("yuzu_token")).toString().toStdString();
991 1001
992 qt_config->endGroup(); 1002 qt_config->endGroup();
993} 1003}
@@ -1073,7 +1083,7 @@ void Config::SavePlayerValue(std::size_t player_index) {
1073} 1083}
1074 1084
1075void Config::SaveDebugValues() { 1085void Config::SaveDebugValues() {
1076 WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false); 1086 WriteBasicSetting(Settings::values.debug_pad_enabled);
1077 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 1087 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
1078 const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); 1088 const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
1079 WriteSetting(QStringLiteral("debug_pad_") + 1089 WriteSetting(QStringLiteral("debug_pad_") +
@@ -1093,7 +1103,7 @@ void Config::SaveDebugValues() {
1093} 1103}
1094 1104
1095void Config::SaveMouseValues() { 1105void Config::SaveMouseValues() {
1096 WriteSetting(QStringLiteral("mouse_enabled"), Settings::values.mouse_enabled, false); 1106 WriteBasicSetting(Settings::values.mouse_enabled);
1097 1107
1098 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { 1108 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
1099 const std::string default_param = 1109 const std::string default_param =
@@ -1116,19 +1126,11 @@ void Config::SaveTouchscreenValues() {
1116} 1126}
1117 1127
1118void Config::SaveMotionTouchValues() { 1128void Config::SaveMotionTouchValues() {
1119 WriteSetting(QStringLiteral("motion_device"), 1129 WriteBasicSetting(Settings::values.motion_device);
1120 QString::fromStdString(Settings::values.motion_device), 1130 WriteBasicSetting(Settings::values.touch_device);
1121 QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01")); 1131 WriteBasicSetting(Settings::values.use_touch_from_button);
1122 WriteSetting(QStringLiteral("touch_device"), 1132 WriteBasicSetting(Settings::values.touch_from_button_map_index);
1123 QString::fromStdString(Settings::values.touch_device), 1133 WriteBasicSetting(Settings::values.udp_input_servers);
1124 QStringLiteral("engine:emu_window"));
1125 WriteSetting(QStringLiteral("use_touch_from_button"), Settings::values.use_touch_from_button,
1126 false);
1127 WriteSetting(QStringLiteral("touch_from_button_map"),
1128 Settings::values.touch_from_button_map_index, 0);
1129 WriteSetting(QStringLiteral("udp_input_servers"),
1130 QString::fromStdString(Settings::values.udp_input_servers),
1131 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV));
1132 1134
1133 qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps")); 1135 qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
1134 for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) { 1136 for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
@@ -1171,15 +1173,11 @@ void Config::SaveAudioValues() {
1171 qt_config->beginGroup(QStringLiteral("Audio")); 1173 qt_config->beginGroup(QStringLiteral("Audio"));
1172 1174
1173 if (global) { 1175 if (global) {
1174 WriteSetting(QStringLiteral("output_engine"), 1176 WriteBasicSetting(Settings::values.sink_id);
1175 QString::fromStdString(Settings::values.sink_id), QStringLiteral("auto")); 1177 WriteBasicSetting(Settings::values.audio_device_id);
1176 WriteSetting(QStringLiteral("output_device"),
1177 QString::fromStdString(Settings::values.audio_device_id),
1178 QStringLiteral("auto"));
1179 } 1178 }
1180 WriteSettingGlobal(QStringLiteral("enable_audio_stretching"), 1179 WriteGlobalSetting(Settings::values.enable_audio_stretching);
1181 Settings::values.enable_audio_stretching); 1180 WriteGlobalSetting(Settings::values.volume);
1182 WriteSettingGlobal(QStringLiteral("volume"), Settings::values.volume);
1183 1181
1184 qt_config->endGroup(); 1182 qt_config->endGroup();
1185} 1183}
@@ -1195,29 +1193,21 @@ void Config::SaveControlValues() {
1195 SaveTouchscreenValues(); 1193 SaveTouchscreenValues();
1196 SaveMotionTouchValues(); 1194 SaveMotionTouchValues();
1197 1195
1198 WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode); 1196 WriteGlobalSetting(Settings::values.use_docked_mode);
1199 WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled); 1197 WriteGlobalSetting(Settings::values.vibration_enabled);
1200 WriteSettingGlobal(QStringLiteral("enable_accurate_vibrations"), 1198 WriteGlobalSetting(Settings::values.enable_accurate_vibrations);
1201 Settings::values.enable_accurate_vibrations); 1199 WriteGlobalSetting(Settings::values.motion_enabled);
1202 WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled); 1200 WriteBasicSetting(Settings::values.keyboard_enabled);
1203 WriteSetting(QStringLiteral("motion_device"), 1201 WriteBasicSetting(Settings::values.emulate_analog_keyboard);
1204 QString::fromStdString(Settings::values.motion_device), 1202 WriteBasicSetting(Settings::values.mouse_panning_sensitivity);
1205 QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01")); 1203
1206 WriteSetting(QStringLiteral("touch_device"),
1207 QString::fromStdString(Settings::values.touch_device),
1208 QStringLiteral("engine:emu_window"));
1209 WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
1210 WriteSetting(QStringLiteral("emulate_analog_keyboard"),
1211 Settings::values.emulate_analog_keyboard, false);
1212 WriteSetting(QStringLiteral("mouse_panning_sensitivity"),
1213 Settings::values.mouse_panning_sensitivity, 1.0f);
1214 qt_config->endGroup(); 1204 qt_config->endGroup();
1215} 1205}
1216 1206
1217void Config::SaveCoreValues() { 1207void Config::SaveCoreValues() {
1218 qt_config->beginGroup(QStringLiteral("Core")); 1208 qt_config->beginGroup(QStringLiteral("Core"));
1219 1209
1220 WriteSettingGlobal(QStringLiteral("use_multi_core"), Settings::values.use_multi_core); 1210 WriteGlobalSetting(Settings::values.use_multi_core);
1221 1211
1222 qt_config->endGroup(); 1212 qt_config->endGroup();
1223} 1213}
@@ -1225,7 +1215,7 @@ void Config::SaveCoreValues() {
1225void Config::SaveDataStorageValues() { 1215void Config::SaveDataStorageValues() {
1226 qt_config->beginGroup(QStringLiteral("Data Storage")); 1216 qt_config->beginGroup(QStringLiteral("Data Storage"));
1227 1217
1228 WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true); 1218 WriteBasicSetting(Settings::values.use_virtual_sd);
1229 WriteSetting(QStringLiteral("nand_directory"), 1219 WriteSetting(QStringLiteral("nand_directory"),
1230 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)), 1220 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)),
1231 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); 1221 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
@@ -1238,11 +1228,9 @@ void Config::SaveDataStorageValues() {
1238 WriteSetting(QStringLiteral("dump_directory"), 1228 WriteSetting(QStringLiteral("dump_directory"),
1239 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)), 1229 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)),
1240 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); 1230 QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
1241 WriteSetting(QStringLiteral("gamecard_inserted"), Settings::values.gamecard_inserted, false); 1231 WriteBasicSetting(Settings::values.gamecard_inserted);
1242 WriteSetting(QStringLiteral("gamecard_current_game"), Settings::values.gamecard_current_game, 1232 WriteBasicSetting(Settings::values.gamecard_current_game);
1243 false); 1233 WriteBasicSetting(Settings::values.gamecard_path);
1244 WriteSetting(QStringLiteral("gamecard_path"),
1245 QString::fromStdString(Settings::values.gamecard_path), QString{});
1246 1234
1247 qt_config->endGroup(); 1235 qt_config->endGroup();
1248} 1236}
@@ -1252,24 +1240,23 @@ void Config::SaveDebuggingValues() {
1252 1240
1253 // Intentionally not using the QT default setting as this is intended to be changed in the ini 1241 // Intentionally not using the QT default setting as this is intended to be changed in the ini
1254 qt_config->setValue(QStringLiteral("record_frame_times"), Settings::values.record_frame_times); 1242 qt_config->setValue(QStringLiteral("record_frame_times"), Settings::values.record_frame_times);
1255 WriteSetting(QStringLiteral("program_args"), 1243 WriteBasicSetting(Settings::values.program_args);
1256 QString::fromStdString(Settings::values.program_args), QString{}); 1244 WriteBasicSetting(Settings::values.dump_exefs);
1257 WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false); 1245 WriteBasicSetting(Settings::values.dump_nso);
1258 WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false); 1246 WriteBasicSetting(Settings::values.enable_fs_access_log);
1259 WriteSetting(QStringLiteral("enable_fs_access_log"), Settings::values.enable_fs_access_log, 1247 WriteBasicSetting(Settings::values.quest_flag);
1260 false); 1248 WriteBasicSetting(Settings::values.use_debug_asserts);
1261 WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false); 1249 WriteBasicSetting(Settings::values.disable_macro_jit);
1262 WriteSetting(QStringLiteral("use_debug_asserts"), Settings::values.use_debug_asserts, false);
1263 WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
1264 1250
1265 qt_config->endGroup(); 1251 qt_config->endGroup();
1266} 1252}
1267 1253
1268void Config::SaveServiceValues() { 1254void Config::SaveServiceValues() {
1269 qt_config->beginGroup(QStringLiteral("Services")); 1255 qt_config->beginGroup(QStringLiteral("Services"));
1270 WriteSetting(QStringLiteral("bcat_backend"), 1256
1271 QString::fromStdString(Settings::values.bcat_backend), QStringLiteral("none")); 1257 WriteBasicSetting(Settings::values.bcat_backend);
1272 WriteSetting(QStringLiteral("bcat_boxcat_local"), Settings::values.bcat_boxcat_local, false); 1258 WriteBasicSetting(Settings::values.bcat_boxcat_local);
1259
1273 qt_config->endGroup(); 1260 qt_config->endGroup();
1274} 1261}
1275 1262
@@ -1295,9 +1282,8 @@ void Config::SaveDisabledAddOnValues() {
1295void Config::SaveMiscellaneousValues() { 1282void Config::SaveMiscellaneousValues() {
1296 qt_config->beginGroup(QStringLiteral("Miscellaneous")); 1283 qt_config->beginGroup(QStringLiteral("Miscellaneous"));
1297 1284
1298 WriteSetting(QStringLiteral("log_filter"), QString::fromStdString(Settings::values.log_filter), 1285 WriteBasicSetting(Settings::values.log_filter);
1299 QStringLiteral("*:Info")); 1286 WriteBasicSetting(Settings::values.use_dev_keys);
1300 WriteSetting(QStringLiteral("use_dev_keys"), Settings::values.use_dev_keys, false);
1301 1287
1302 qt_config->endGroup(); 1288 qt_config->endGroup();
1303} 1289}
@@ -1325,38 +1311,27 @@ void Config::SavePathValues() {
1325void Config::SaveCpuValues() { 1311void Config::SaveCpuValues() {
1326 qt_config->beginGroup(QStringLiteral("Cpu")); 1312 qt_config->beginGroup(QStringLiteral("Cpu"));
1327 1313
1328 WriteSettingGlobal(QStringLiteral("cpu_accuracy"), 1314 WriteSetting(QStringLiteral("cpu_accuracy"),
1329 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)), 1315 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)),
1330 Settings::values.cpu_accuracy.UsingGlobal(), 1316 static_cast<u32>(Settings::values.cpu_accuracy.GetDefault()),
1331 static_cast<u32>(Settings::values.cpu_accuracy.GetDefault())); 1317 Settings::values.cpu_accuracy.UsingGlobal());
1332 1318
1333 WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_unfuse_fma"), 1319 WriteGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma);
1334 Settings::values.cpuopt_unsafe_unfuse_fma); 1320 WriteGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error);
1335 WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_reduce_fp_error"), 1321 WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
1336 Settings::values.cpuopt_unsafe_reduce_fp_error); 1322 WriteGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
1337 WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"), 1323 WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
1338 Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
1339 WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
1340 Settings::values.cpuopt_unsafe_inaccurate_nan);
1341 WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_fastmem_check"),
1342 Settings::values.cpuopt_unsafe_fastmem_check);
1343 1324
1344 if (global) { 1325 if (global) {
1345 WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables, 1326 WriteBasicSetting(Settings::values.cpuopt_page_tables);
1346 true); 1327 WriteBasicSetting(Settings::values.cpuopt_block_linking);
1347 WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking, 1328 WriteBasicSetting(Settings::values.cpuopt_return_stack_buffer);
1348 true); 1329 WriteBasicSetting(Settings::values.cpuopt_fast_dispatcher);
1349 WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"), 1330 WriteBasicSetting(Settings::values.cpuopt_context_elimination);
1350 Settings::values.cpuopt_return_stack_buffer, true); 1331 WriteBasicSetting(Settings::values.cpuopt_const_prop);
1351 WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"), 1332 WriteBasicSetting(Settings::values.cpuopt_misc_ir);
1352 Settings::values.cpuopt_fast_dispatcher, true); 1333 WriteBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
1353 WriteSetting(QStringLiteral("cpuopt_context_elimination"), 1334 WriteBasicSetting(Settings::values.cpuopt_fastmem);
1354 Settings::values.cpuopt_context_elimination, true);
1355 WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true);
1356 WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
1357 WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
1358 Settings::values.cpuopt_reduce_misalign_checks, true);
1359 WriteSetting(QStringLiteral("cpuopt_fastmem"), Settings::values.cpuopt_fastmem, true);
1360 } 1335 }
1361 1336
1362 qt_config->endGroup(); 1337 qt_config->endGroup();
@@ -1365,38 +1340,34 @@ void Config::SaveCpuValues() {
1365void Config::SaveRendererValues() { 1340void Config::SaveRendererValues() {
1366 qt_config->beginGroup(QStringLiteral("Renderer")); 1341 qt_config->beginGroup(QStringLiteral("Renderer"));
1367 1342
1368 WriteSettingGlobal(QStringLiteral("backend"), 1343 WriteSetting(QString::fromStdString(Settings::values.renderer_backend.GetLabel()),
1369 static_cast<u32>(Settings::values.renderer_backend.GetValue(global)), 1344 static_cast<u32>(Settings::values.renderer_backend.GetValue(global)),
1370 Settings::values.renderer_backend.UsingGlobal(), 1345 static_cast<u32>(Settings::values.renderer_backend.GetDefault()),
1371 static_cast<u32>(Settings::values.renderer_backend.GetDefault())); 1346 Settings::values.renderer_backend.UsingGlobal());
1372 WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug); 1347 WriteBasicSetting(Settings::values.renderer_debug);
1373 WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device); 1348 WriteGlobalSetting(Settings::values.vulkan_device);
1374 WriteSettingGlobal(QStringLiteral("fullscreen_mode"), Settings::values.fullscreen_mode); 1349 WriteGlobalSetting(Settings::values.fullscreen_mode);
1375 WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio); 1350 WriteGlobalSetting(Settings::values.aspect_ratio);
1376 WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy); 1351 WriteGlobalSetting(Settings::values.max_anisotropy);
1377 WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit); 1352 WriteGlobalSetting(Settings::values.use_frame_limit);
1378 WriteSettingGlobal(QStringLiteral("frame_limit"), Settings::values.frame_limit); 1353 WriteGlobalSetting(Settings::values.frame_limit);
1379 WriteSettingGlobal(QStringLiteral("use_disk_shader_cache"), 1354 WriteGlobalSetting(Settings::values.use_disk_shader_cache);
1380 Settings::values.use_disk_shader_cache); 1355 WriteSetting(QString::fromStdString(Settings::values.gpu_accuracy.GetLabel()),
1381 WriteSettingGlobal(QStringLiteral("gpu_accuracy"), 1356 static_cast<u32>(Settings::values.gpu_accuracy.GetValue(global)),
1382 static_cast<u32>(Settings::values.gpu_accuracy.GetValue(global)), 1357 static_cast<u32>(Settings::values.gpu_accuracy.GetDefault()),
1383 Settings::values.gpu_accuracy.UsingGlobal(), 1358 Settings::values.gpu_accuracy.UsingGlobal());
1384 static_cast<u32>(Settings::values.gpu_accuracy.GetDefault())); 1359 WriteGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
1385 WriteSettingGlobal(QStringLiteral("use_asynchronous_gpu_emulation"), 1360 WriteGlobalSetting(Settings::values.use_nvdec_emulation);
1386 Settings::values.use_asynchronous_gpu_emulation); 1361 WriteGlobalSetting(Settings::values.accelerate_astc);
1387 WriteSettingGlobal(QStringLiteral("use_nvdec_emulation"), Settings::values.use_nvdec_emulation); 1362 WriteGlobalSetting(Settings::values.use_vsync);
1388 WriteSettingGlobal(QStringLiteral("accelerate_astc"), Settings::values.accelerate_astc); 1363 WriteGlobalSetting(Settings::values.disable_fps_limit);
1389 WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync); 1364 WriteGlobalSetting(Settings::values.use_assembly_shaders);
1390 WriteSettingGlobal(QStringLiteral("disable_fps_limit"), Settings::values.disable_fps_limit); 1365 WriteGlobalSetting(Settings::values.use_asynchronous_shaders);
1391 WriteSettingGlobal(QStringLiteral("use_assembly_shaders"), 1366 WriteGlobalSetting(Settings::values.use_fast_gpu_time);
1392 Settings::values.use_assembly_shaders); 1367 WriteGlobalSetting(Settings::values.use_caches_gc);
1393 WriteSettingGlobal(QStringLiteral("use_asynchronous_shaders"), 1368 WriteGlobalSetting(Settings::values.bg_red);
1394 Settings::values.use_asynchronous_shaders); 1369 WriteGlobalSetting(Settings::values.bg_green);
1395 WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time); 1370 WriteGlobalSetting(Settings::values.bg_blue);
1396 WriteSettingGlobal(QStringLiteral("use_caches_gc"), Settings::values.use_caches_gc);
1397 WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red);
1398 WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green);
1399 WriteSettingGlobal(QStringLiteral("bg_blue"), Settings::values.bg_blue);
1400 1371
1401 qt_config->endGroup(); 1372 qt_config->endGroup();
1402} 1373}
@@ -1435,17 +1406,16 @@ void Config::SaveShortcutValues() {
1435void Config::SaveSystemValues() { 1406void Config::SaveSystemValues() {
1436 qt_config->beginGroup(QStringLiteral("System")); 1407 qt_config->beginGroup(QStringLiteral("System"));
1437 1408
1438 WriteSetting(QStringLiteral("current_user"), Settings::values.current_user); 1409 WriteBasicSetting(Settings::values.current_user);
1439 WriteSettingGlobal(QStringLiteral("language_index"), Settings::values.language_index); 1410 WriteGlobalSetting(Settings::values.language_index);
1440 WriteSettingGlobal(QStringLiteral("region_index"), Settings::values.region_index); 1411 WriteGlobalSetting(Settings::values.region_index);
1441 WriteSettingGlobal(QStringLiteral("time_zone_index"), Settings::values.time_zone_index); 1412 WriteGlobalSetting(Settings::values.time_zone_index);
1442 1413
1443 WriteSettingGlobal(QStringLiteral("rng_seed_enabled"), 1414 WriteSetting(QStringLiteral("rng_seed_enabled"),
1444 Settings::values.rng_seed.GetValue(global).has_value(), 1415 Settings::values.rng_seed.GetValue(global).has_value(),
1445 Settings::values.rng_seed.UsingGlobal(), false); 1416 Settings::values.rng_seed.UsingGlobal(), false);
1446 WriteSettingGlobal(QStringLiteral("rng_seed"), 1417 WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.GetValue(global).value_or(0),
1447 Settings::values.rng_seed.GetValue(global).value_or(0), 1418 Settings::values.rng_seed.UsingGlobal(), 0);
1448 Settings::values.rng_seed.UsingGlobal(), 0);
1449 1419
1450 if (global) { 1420 if (global) {
1451 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(), 1421 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
@@ -1456,7 +1426,7 @@ void Config::SaveSystemValues() {
1456 0); 1426 0);
1457 } 1427 }
1458 1428
1459 WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index); 1429 WriteGlobalSetting(Settings::values.sound_index);
1460 1430
1461 qt_config->endGroup(); 1431 qt_config->endGroup();
1462} 1432}
@@ -1530,13 +1500,10 @@ void Config::SaveUILayoutValues() {
1530void Config::SaveWebServiceValues() { 1500void Config::SaveWebServiceValues() {
1531 qt_config->beginGroup(QStringLiteral("WebService")); 1501 qt_config->beginGroup(QStringLiteral("WebService"));
1532 1502
1533 WriteSetting(QStringLiteral("enable_telemetry"), Settings::values.enable_telemetry, true); 1503 WriteBasicSetting(Settings::values.enable_telemetry);
1534 WriteSetting(QStringLiteral("web_api_url"), 1504 WriteBasicSetting(Settings::values.web_api_url);
1535 QString::fromStdString(Settings::values.web_api_url), 1505 WriteBasicSetting(Settings::values.yuzu_username);
1536 QStringLiteral("https://api.yuzu-emu.org")); 1506 WriteBasicSetting(Settings::values.yuzu_token);
1537 WriteSetting(QStringLiteral("yuzu_username"),
1538 QString::fromStdString(Settings::values.yuzu_username));
1539 WriteSetting(QStringLiteral("yuzu_token"), QString::fromStdString(Settings::values.yuzu_token));
1540 1507
1541 qt_config->endGroup(); 1508 qt_config->endGroup();
1542} 1509}
@@ -1555,25 +1522,15 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value)
1555 return result; 1522 return result;
1556} 1523}
1557 1524
1558QVariant Config::ReadSetting(const QString& name, Settings::CPUAccuracy default_value) const {
1559 return ReadSetting(name, static_cast<u32>(default_value));
1560}
1561
1562QVariant Config::ReadSetting(const QString& name, Settings::GPUAccuracy default_value) const {
1563 return ReadSetting(name, static_cast<u32>(default_value));
1564}
1565
1566QVariant Config::ReadSetting(const QString& name, Settings::RendererBackend default_value) const {
1567 return ReadSetting(name, static_cast<u32>(default_value));
1568}
1569
1570template <typename Type> 1525template <typename Type>
1571void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name) { 1526void Config::ReadGlobalSetting(Settings::Setting<Type>& setting) {
1527 QString name = QString::fromStdString(setting.GetLabel());
1572 const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); 1528 const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
1573 setting.SetGlobal(use_global); 1529 setting.SetGlobal(use_global);
1574 const Type& default_value = setting.GetDefault();
1575 if (global || !use_global) { 1530 if (global || !use_global) {
1576 setting.SetValue(static_cast<QVariant>(ReadSetting(name, default_value)).value<Type>()); 1531 setting.SetValue(static_cast<QVariant>(
1532 ReadSetting(name, QVariant::fromValue<Type>(setting.GetDefault())))
1533 .value<Type>());
1577 } 1534 }
1578} 1535}
1579 1536
@@ -1596,20 +1553,8 @@ void Config::WriteSetting(const QString& name, const QVariant& value,
1596 qt_config->setValue(name, value); 1553 qt_config->setValue(name, value);
1597} 1554}
1598 1555
1599template <typename Type> 1556void Config::WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
1600void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting) { 1557 bool use_global) {
1601 if (!global) {
1602 qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
1603 }
1604 if (global || !setting.UsingGlobal()) {
1605 qt_config->setValue(name + QStringLiteral("/default"),
1606 setting.GetValue(global) == setting.GetDefault());
1607 qt_config->setValue(name, setting.GetValue(global));
1608 }
1609}
1610
1611void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
1612 const QVariant& default_value) {
1613 if (!global) { 1558 if (!global) {
1614 qt_config->setValue(name + QStringLiteral("/use_global"), use_global); 1559 qt_config->setValue(name + QStringLiteral("/use_global"), use_global);
1615 } 1560 }
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 62501997c..96f9b6de1 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -102,28 +102,75 @@ private:
102 void SaveUILayoutValues(); 102 void SaveUILayoutValues();
103 void SaveWebServiceValues(); 103 void SaveWebServiceValues();
104 104
105 /**
106 * Reads a setting from the qt_config.
107 *
108 * @param name The setting's identifier
109 * @param default_value The value to use when the setting is not already present in the config
110 */
105 QVariant ReadSetting(const QString& name) const; 111 QVariant ReadSetting(const QString& name) const;
106 QVariant ReadSetting(const QString& name, const QVariant& default_value) const; 112 QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
107 QVariant ReadSetting(const QString& name, Settings::CPUAccuracy default_value) const; 113
108 QVariant ReadSetting(const QString& name, Settings::GPUAccuracy default_value) const; 114 /**
109 QVariant ReadSetting(const QString& name, Settings::RendererBackend default_value) const; 115 * Only reads a setting from the qt_config if the current config is a global config, or if the
110 // Templated ReadSettingGlobal functions will also look for the use_global setting and set 116 * current config is a custom config and the setting is overriding the global setting. Otherwise
111 // both the value and the global state properly 117 * it does nothing.
112 template <typename Type> 118 *
113 void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name); 119 * @param setting The variable to be modified
120 * @param name The setting's identifier
121 * @param default_value The value to use when the setting is not already present in the config
122 */
114 template <typename Type> 123 template <typename Type>
115 void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const; 124 void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
116 // Templated WriteSettingGlobal functions will also write the global state if needed and will 125
117 // skip writing the actual setting if it defers to the global value 126 /**
127 * Writes a setting to the qt_config.
128 *
129 * @param name The setting's idetentifier
130 * @param value Value of the setting
131 * @param default_value Default of the setting if not present in qt_config
132 * @param use_global Specifies if the custom or global config should be in use, for custom
133 * configs
134 */
118 void WriteSetting(const QString& name, const QVariant& value); 135 void WriteSetting(const QString& name, const QVariant& value);
119 void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); 136 void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
137 void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
138 bool use_global);
139
140 /**
141 * Reads a value from the qt_config and applies it to the setting, using its label and default
142 * value. If the config is a custom config, this will also read the global state of the setting
143 * and apply that information to it.
144 *
145 * @param The setting
146 */
120 template <typename Type> 147 template <typename Type>
121 void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting); 148 void ReadGlobalSetting(Settings::Setting<Type>& setting);
149
150 /**
151 * Sets a value to the qt_config using the setting's label and default value. If the config is a
152 * custom config, it will apply the global state, and the custom value if needed.
153 *
154 * @param The setting
155 */
156 template <typename Type>
157 void WriteGlobalSetting(const Settings::Setting<Type>& setting);
158
159 /**
160 * Reads a value from the qt_config using the setting's label and default value and applies the
161 * value to the setting.
162 *
163 * @param The setting
164 */
165 template <typename Type>
166 void ReadBasicSetting(Settings::BasicSetting<Type>& setting);
167
168 /** Sets a value from the setting in the qt_config using the setting's label and default value.
169 *
170 * @param The setting
171 */
122 template <typename Type> 172 template <typename Type>
123 void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting, 173 void WriteBasicSetting(const Settings::BasicSetting<Type>& setting);
124 const QVariant& default_value);
125 void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
126 const QVariant& default_value);
127 174
128 ConfigType type; 175 ConfigType type;
129 std::unique_ptr<QSettings> qt_config; 176 std::unique_ptr<QSettings> qt_config;
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index fc0191432..5aba1a3b2 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -69,7 +69,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
69 [[maybe_unused]] const QSignalBlocker blocker(ui->output_sink_combo_box); 69 [[maybe_unused]] const QSignalBlocker blocker(ui->output_sink_combo_box);
70 70
71 int new_sink_index = 0; 71 int new_sink_index = 0;
72 const QString sink_id = QString::fromStdString(Settings::values.sink_id); 72 const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
73 for (int index = 0; index < ui->output_sink_combo_box->count(); index++) { 73 for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
74 if (ui->output_sink_combo_box->itemText(index) == sink_id) { 74 if (ui->output_sink_combo_box->itemText(index) == sink_id) {
75 new_sink_index = index; 75 new_sink_index = index;
@@ -83,7 +83,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
83void ConfigureAudio::SetAudioDeviceFromDeviceID() { 83void ConfigureAudio::SetAudioDeviceFromDeviceID() {
84 int new_device_index = -1; 84 int new_device_index = -1;
85 85
86 const QString device_id = QString::fromStdString(Settings::values.audio_device_id); 86 const QString device_id = QString::fromStdString(Settings::values.audio_device_id.GetValue());
87 for (int index = 0; index < ui->audio_device_combo_box->count(); index++) { 87 for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
88 if (ui->audio_device_combo_box->itemText(index) == device_id) { 88 if (ui->audio_device_combo_box->itemText(index) == device_id) {
89 new_device_index = index; 89 new_device_index = index;
@@ -106,9 +106,9 @@ void ConfigureAudio::ApplyConfiguration() {
106 Settings::values.sink_id = 106 Settings::values.sink_id =
107 ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) 107 ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
108 .toStdString(); 108 .toStdString();
109 Settings::values.audio_device_id = 109 Settings::values.audio_device_id.SetValue(
110 ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex()) 110 ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
111 .toStdString(); 111 .toStdString());
112 112
113 // Guard if during game and set to game-specific value 113 // Guard if during game and set to game-specific value
114 if (Settings::values.volume.UsingGlobal()) { 114 if (Settings::values.volume.UsingGlobal()) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index e25c52baf..98e2d2be5 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -24,23 +24,26 @@ void ConfigureCpuDebug::SetConfiguration() {
24 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); 24 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
25 25
26 ui->cpuopt_page_tables->setEnabled(runtime_lock); 26 ui->cpuopt_page_tables->setEnabled(runtime_lock);
27 ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables); 27 ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables.GetValue());
28 ui->cpuopt_block_linking->setEnabled(runtime_lock); 28 ui->cpuopt_block_linking->setEnabled(runtime_lock);
29 ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking); 29 ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking.GetValue());
30 ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock); 30 ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
31 ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer); 31 ui->cpuopt_return_stack_buffer->setChecked(
32 Settings::values.cpuopt_return_stack_buffer.GetValue());
32 ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock); 33 ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
33 ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher); 34 ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher.GetValue());
34 ui->cpuopt_context_elimination->setEnabled(runtime_lock); 35 ui->cpuopt_context_elimination->setEnabled(runtime_lock);
35 ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination); 36 ui->cpuopt_context_elimination->setChecked(
37 Settings::values.cpuopt_context_elimination.GetValue());
36 ui->cpuopt_const_prop->setEnabled(runtime_lock); 38 ui->cpuopt_const_prop->setEnabled(runtime_lock);
37 ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop); 39 ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop.GetValue());
38 ui->cpuopt_misc_ir->setEnabled(runtime_lock); 40 ui->cpuopt_misc_ir->setEnabled(runtime_lock);
39 ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir); 41 ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir.GetValue());
40 ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock); 42 ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
41 ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks); 43 ui->cpuopt_reduce_misalign_checks->setChecked(
44 Settings::values.cpuopt_reduce_misalign_checks.GetValue());
42 ui->cpuopt_fastmem->setEnabled(runtime_lock); 45 ui->cpuopt_fastmem->setEnabled(runtime_lock);
43 ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem); 46 ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem.GetValue());
44} 47}
45 48
46void ConfigureCpuDebug::ApplyConfiguration() { 49void ConfigureCpuDebug::ApplyConfiguration() {
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 15d6a5ad7..7d15d54b8 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -32,19 +32,20 @@ void ConfigureDebug::SetConfiguration() {
32 32
33 ui->toggle_console->setEnabled(runtime_lock); 33 ui->toggle_console->setEnabled(runtime_lock);
34 ui->toggle_console->setChecked(UISettings::values.show_console); 34 ui->toggle_console->setChecked(UISettings::values.show_console);
35 ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter)); 35 ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
36 ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); 36 ui->homebrew_args_edit->setText(
37 QString::fromStdString(Settings::values.program_args.GetValue()));
37 ui->fs_access_log->setEnabled(runtime_lock); 38 ui->fs_access_log->setEnabled(runtime_lock);
38 ui->fs_access_log->setChecked(Settings::values.enable_fs_access_log); 39 ui->fs_access_log->setChecked(Settings::values.enable_fs_access_log.GetValue());
39 ui->reporting_services->setChecked(Settings::values.reporting_services); 40 ui->reporting_services->setChecked(Settings::values.reporting_services.GetValue());
40 ui->quest_flag->setChecked(Settings::values.quest_flag); 41 ui->quest_flag->setChecked(Settings::values.quest_flag.GetValue());
41 ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts); 42 ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts.GetValue());
42 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub); 43 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub.GetValue());
43 ui->enable_graphics_debugging->setEnabled(runtime_lock); 44 ui->enable_graphics_debugging->setEnabled(runtime_lock);
44 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); 45 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue());
45 ui->disable_macro_jit->setEnabled(runtime_lock); 46 ui->disable_macro_jit->setEnabled(runtime_lock);
46 ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit); 47 ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
47 ui->extended_logging->setChecked(Settings::values.extended_logging); 48 ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
48} 49}
49 50
50void ConfigureDebug::ApplyConfiguration() { 51void ConfigureDebug::ApplyConfiguration() {
@@ -61,7 +62,7 @@ void ConfigureDebug::ApplyConfiguration() {
61 Settings::values.extended_logging = ui->extended_logging->isChecked(); 62 Settings::values.extended_logging = ui->extended_logging->isChecked();
62 Debugger::ToggleConsole(); 63 Debugger::ToggleConsole();
63 Common::Log::Filter filter; 64 Common::Log::Filter filter;
64 filter.ParseFilterString(Settings::values.log_filter); 65 filter.ParseFilterString(Settings::values.log_filter.GetValue());
65 Common::Log::SetGlobalFilter(filter); 66 Common::Log::SetGlobalFilter(filter);
66} 67}
67 68
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index d223c40ea..d0b5c6efe 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -43,16 +43,17 @@ void ConfigureFilesystem::setConfiguration() {
43 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir))); 43 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir)));
44 ui->sdmc_directory_edit->setText( 44 ui->sdmc_directory_edit->setText(
45 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::SDMCDir))); 45 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::SDMCDir)));
46 ui->gamecard_path_edit->setText(QString::fromStdString(Settings::values.gamecard_path)); 46 ui->gamecard_path_edit->setText(
47 QString::fromStdString(Settings::values.gamecard_path.GetValue()));
47 ui->dump_path_edit->setText( 48 ui->dump_path_edit->setText(
48 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::DumpDir))); 49 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::DumpDir)));
49 ui->load_path_edit->setText( 50 ui->load_path_edit->setText(
50 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::LoadDir))); 51 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::LoadDir)));
51 52
52 ui->gamecard_inserted->setChecked(Settings::values.gamecard_inserted); 53 ui->gamecard_inserted->setChecked(Settings::values.gamecard_inserted.GetValue());
53 ui->gamecard_current_game->setChecked(Settings::values.gamecard_current_game); 54 ui->gamecard_current_game->setChecked(Settings::values.gamecard_current_game.GetValue());
54 ui->dump_exefs->setChecked(Settings::values.dump_exefs); 55 ui->dump_exefs->setChecked(Settings::values.dump_exefs.GetValue());
55 ui->dump_nso->setChecked(Settings::values.dump_nso); 56 ui->dump_nso->setChecked(Settings::values.dump_nso.GetValue());
56 57
57 ui->cache_game_list->setChecked(UISettings::values.cache_game_list); 58 ui->cache_game_list->setChecked(UISettings::values.cache_game_list);
58 59
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index d8d3b83dc..2f1419b5b 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -148,12 +148,12 @@ void ConfigureInputAdvanced::LoadConfiguration() {
148 } 148 }
149 } 149 }
150 150
151 ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled); 151 ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled.GetValue());
152 ui->mouse_enabled->setChecked(Settings::values.mouse_enabled); 152 ui->mouse_enabled->setChecked(Settings::values.mouse_enabled.GetValue());
153 ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled); 153 ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled.GetValue());
154 ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard); 154 ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard.GetValue());
155 ui->mouse_panning->setChecked(Settings::values.mouse_panning); 155 ui->mouse_panning->setChecked(Settings::values.mouse_panning.GetValue());
156 ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity); 156 ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity.GetValue());
157 ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled); 157 ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled);
158 158
159 UpdateUIEnabled(); 159 UpdateUIEnabled();
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 6a5d625df..f8e08c422 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -101,15 +101,16 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
101ConfigureMotionTouch::~ConfigureMotionTouch() = default; 101ConfigureMotionTouch::~ConfigureMotionTouch() = default;
102 102
103void ConfigureMotionTouch::SetConfiguration() { 103void ConfigureMotionTouch::SetConfiguration() {
104 const Common::ParamPackage motion_param(Settings::values.motion_device); 104 const Common::ParamPackage motion_param(Settings::values.motion_device.GetValue());
105 const Common::ParamPackage touch_param(Settings::values.touch_device); 105 const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
106 106
107 ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); 107 ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button.GetValue());
108 touch_from_button_maps = Settings::values.touch_from_button_maps; 108 touch_from_button_maps = Settings::values.touch_from_button_maps;
109 for (const auto& touch_map : touch_from_button_maps) { 109 for (const auto& touch_map : touch_from_button_maps) {
110 ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name)); 110 ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
111 } 111 }
112 ui->touch_from_button_map->setCurrentIndex(Settings::values.touch_from_button_map_index); 112 ui->touch_from_button_map->setCurrentIndex(
113 Settings::values.touch_from_button_map_index.GetValue());
113 ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f)); 114 ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f));
114 115
115 min_x = touch_param.Get("min_x", 100); 116 min_x = touch_param.Get("min_x", 100);
@@ -124,7 +125,7 @@ void ConfigureMotionTouch::SetConfiguration() {
124 udp_server_list_model->setStringList({}); 125 udp_server_list_model->setStringList({});
125 ui->udp_server_list->setModel(udp_server_list_model); 126 ui->udp_server_list->setModel(udp_server_list_model);
126 127
127 std::stringstream ss(Settings::values.udp_input_servers); 128 std::stringstream ss(Settings::values.udp_input_servers.GetValue());
128 std::string token; 129 std::string token;
129 130
130 while (std::getline(ss, token, ',')) { 131 while (std::getline(ss, token, ',')) {
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index f5881e58d..ac849b01d 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -166,7 +166,7 @@ void ConfigureProfileManager::PopulateUserList() {
166void ConfigureProfileManager::UpdateCurrentUser() { 166void ConfigureProfileManager::UpdateCurrentUser() {
167 ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS); 167 ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS);
168 168
169 const auto& current_user = profile_manager->GetUser(Settings::values.current_user); 169 const auto& current_user = profile_manager->GetUser(Settings::values.current_user.GetValue());
170 ASSERT(current_user); 170 ASSERT(current_user);
171 const auto username = GetAccountUsername(*profile_manager, *current_user); 171 const auto username = GetAccountUsername(*profile_manager, *current_user);
172 172
@@ -245,15 +245,18 @@ void ConfigureProfileManager::DeleteUser() {
245 this, tr("Confirm Delete"), 245 this, tr("Confirm Delete"),
246 tr("You are about to delete user with name \"%1\". Are you sure?").arg(username)); 246 tr("You are about to delete user with name \"%1\". Are you sure?").arg(username));
247 247
248 if (confirm == QMessageBox::No) 248 if (confirm == QMessageBox::No) {
249 return; 249 return;
250 }
250 251
251 if (Settings::values.current_user == tree_view->currentIndex().row()) 252 if (Settings::values.current_user.GetValue() == tree_view->currentIndex().row()) {
252 Settings::values.current_user = 0; 253 Settings::values.current_user = 0;
254 }
253 UpdateCurrentUser(); 255 UpdateCurrentUser();
254 256
255 if (!profile_manager->RemoveUser(*uuid)) 257 if (!profile_manager->RemoveUser(*uuid)) {
256 return; 258 return;
259 }
257 260
258 item_model->removeRows(tree_view->currentIndex().row(), 1); 261 item_model->removeRows(tree_view->currentIndex().row(), 1);
259 tree_view->clearSelection(); 262 tree_view->clearSelection();
diff --git a/src/yuzu/configuration/configure_service.cpp b/src/yuzu/configuration/configure_service.cpp
index 6d954a67f..4aa424803 100644
--- a/src/yuzu/configuration/configure_service.cpp
+++ b/src/yuzu/configuration/configure_service.cpp
@@ -65,7 +65,7 @@ void ConfigureService::RetranslateUi() {
65 65
66void ConfigureService::SetConfiguration() { 66void ConfigureService::SetConfiguration() {
67 const int index = 67 const int index =
68 ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend)); 68 ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend.GetValue()));
69 ui->bcat_source->setCurrentIndex(index == -1 ? 0 : index); 69 ui->bcat_source->setCurrentIndex(index == -1 ? 0 : index);
70} 70}
71 71
diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp
index f3f3b54d6..0fd76dc2c 100644
--- a/src/yuzu/configuration/configure_web.cpp
+++ b/src/yuzu/configuration/configure_web.cpp
@@ -88,15 +88,15 @@ void ConfigureWeb::SetConfiguration() {
88 ui->web_signup_link->setOpenExternalLinks(true); 88 ui->web_signup_link->setOpenExternalLinks(true);
89 ui->web_token_info_link->setOpenExternalLinks(true); 89 ui->web_token_info_link->setOpenExternalLinks(true);
90 90
91 if (Settings::values.yuzu_username.empty()) { 91 if (Settings::values.yuzu_username.GetValue().empty()) {
92 ui->username->setText(tr("Unspecified")); 92 ui->username->setText(tr("Unspecified"));
93 } else { 93 } else {
94 ui->username->setText(QString::fromStdString(Settings::values.yuzu_username)); 94 ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
95 } 95 }
96 96
97 ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry); 97 ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry.GetValue());
98 ui->edit_token->setText(QString::fromStdString( 98 ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken(
99 GenerateDisplayToken(Settings::values.yuzu_username, Settings::values.yuzu_token))); 99 Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue())));
100 100
101 // Connect after setting the values, to avoid calling OnLoginChanged now 101 // Connect after setting the values, to avoid calling OnLoginChanged now
102 connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged); 102 connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 6f5b2f6d6..d9375fc77 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -176,7 +176,7 @@ static void InitializeLogging() {
176 using namespace Common; 176 using namespace Common;
177 177
178 Log::Filter log_filter; 178 Log::Filter log_filter;
179 log_filter.ParseFilterString(Settings::values.log_filter); 179 log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
180 Log::SetGlobalFilter(log_filter); 180 Log::SetGlobalFilter(log_filter);
181 181
182 const auto log_dir = FS::GetYuzuPath(FS::YuzuPath::LogDir); 182 const auto log_dir = FS::GetYuzuPath(FS::YuzuPath::LogDir);
@@ -2443,7 +2443,8 @@ void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_tex
2443} 2443}
2444 2444
2445void GMainWindow::OnMenuReportCompatibility() { 2445void GMainWindow::OnMenuReportCompatibility() {
2446 if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) { 2446 if (!Settings::values.yuzu_token.GetValue().empty() &&
2447 !Settings::values.yuzu_username.GetValue().empty()) {
2447 CompatDB compatdb{this}; 2448 CompatDB compatdb{this};
2448 compatdb.exec(); 2449 compatdb.exec();
2449 } else { 2450 } else {
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 60bf66ec0..2c8d3f683 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -241,6 +241,24 @@ static const std::array<int, 8> keyboard_mods{
241 SDL_SCANCODE_RCTRL, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_RALT, SDL_SCANCODE_RGUI, 241 SDL_SCANCODE_RCTRL, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_RALT, SDL_SCANCODE_RGUI,
242}; 242};
243 243
244template <>
245void Config::ReadSetting(const std::string& group, Settings::BasicSetting<float> setting) {
246 setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault());
247}
248template <>
249void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string> setting) {
250 setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
251}
252template <>
253void Config::ReadSetting(const std::string& group, Settings::BasicSetting<bool> setting) {
254 setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
255}
256template <typename Type>
257void Config::ReadSetting(const std::string& group, Settings::BasicSetting<Type> setting) {
258 setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(),
259 static_cast<long>(setting.GetDefault())));
260}
261
244void Config::ReadValues() { 262void Config::ReadValues() {
245 // Controls 263 // Controls
246 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { 264 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
@@ -264,8 +282,7 @@ void Config::ReadValues() {
264 } 282 }
265 } 283 }
266 284
267 Settings::values.mouse_enabled = 285 ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
268 sdl2_config->GetBoolean("ControlsGeneral", "mouse_enabled", false);
269 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { 286 for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
270 std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]); 287 std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
271 Settings::values.mouse_buttons[i] = sdl2_config->Get( 288 Settings::values.mouse_buttons[i] = sdl2_config->Get(
@@ -275,14 +292,11 @@ void Config::ReadValues() {
275 Settings::values.mouse_buttons[i] = default_param; 292 Settings::values.mouse_buttons[i] = default_param;
276 } 293 }
277 294
278 Settings::values.motion_device = sdl2_config->Get( 295 ReadSetting("ControlsGeneral", Settings::values.motion_device);
279 "ControlsGeneral", "motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01");
280 296
281 Settings::values.keyboard_enabled = 297 ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
282 sdl2_config->GetBoolean("ControlsGeneral", "keyboard_enabled", false);
283 298
284 Settings::values.debug_pad_enabled = 299 ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
285 sdl2_config->GetBoolean("ControlsGeneral", "debug_pad_enabled", false);
286 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 300 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
287 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); 301 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
288 Settings::values.debug_pad_buttons[i] = sdl2_config->Get( 302 Settings::values.debug_pad_buttons[i] = sdl2_config->Get(
@@ -303,12 +317,9 @@ void Config::ReadValues() {
303 Settings::values.debug_pad_analogs[i] = default_param; 317 Settings::values.debug_pad_analogs[i] = default_param;
304 } 318 }
305 319
306 Settings::values.vibration_enabled.SetValue( 320 ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
307 sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true)); 321 ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
308 Settings::values.enable_accurate_vibrations.SetValue( 322 ReadSetting("ControlsGeneral", Settings::values.motion_enabled);
309 sdl2_config->GetBoolean("ControlsGeneral", "enable_accurate_vibrations", false));
310 Settings::values.motion_enabled.SetValue(
311 sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
312 Settings::values.touchscreen.enabled = 323 Settings::values.touchscreen.enabled =
313 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true); 324 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
314 Settings::values.touchscreen.rotation_angle = 325 Settings::values.touchscreen.rotation_angle =
@@ -349,13 +360,11 @@ void Config::ReadValues() {
349 Settings::TouchFromButtonMap{"default", {}}); 360 Settings::TouchFromButtonMap{"default", {}});
350 num_touch_from_button_maps = 1; 361 num_touch_from_button_maps = 1;
351 } 362 }
352 Settings::values.use_touch_from_button = 363 ReadSetting("ControlsGeneral", Settings::values.use_touch_from_button);
353 sdl2_config->GetBoolean("ControlsGeneral", "use_touch_from_button", false); 364 Settings::values.touch_from_button_map_index = std::clamp(
354 Settings::values.touch_from_button_map_index = 365 Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
355 std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
356 366
357 Settings::values.udp_input_servers = 367 ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
358 sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV);
359 368
360 std::transform(keyboard_keys.begin(), keyboard_keys.end(), 369 std::transform(keyboard_keys.begin(), keyboard_keys.end(),
361 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); 370 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
@@ -367,8 +376,7 @@ void Config::ReadValues() {
367 Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam); 376 Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam);
368 377
369 // Data Storage 378 // Data Storage
370 Settings::values.use_virtual_sd = 379 ReadSetting("Data Storage", Settings::values.use_virtual_sd);
371 sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
372 FS::SetYuzuPath(FS::YuzuPath::NANDDir, 380 FS::SetYuzuPath(FS::YuzuPath::NANDDir,
373 sdl2_config->Get("Data Storage", "nand_directory", 381 sdl2_config->Get("Data Storage", "nand_directory",
374 FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); 382 FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
@@ -381,18 +389,16 @@ void Config::ReadValues() {
381 FS::SetYuzuPath(FS::YuzuPath::DumpDir, 389 FS::SetYuzuPath(FS::YuzuPath::DumpDir,
382 sdl2_config->Get("Data Storage", "dump_directory", 390 sdl2_config->Get("Data Storage", "dump_directory",
383 FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); 391 FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
384 Settings::values.gamecard_inserted = 392 ReadSetting("Data Storage", Settings::values.gamecard_inserted);
385 sdl2_config->GetBoolean("Data Storage", "gamecard_inserted", false); 393 ReadSetting("Data Storage", Settings::values.gamecard_current_game);
386 Settings::values.gamecard_current_game = 394 ReadSetting("Data Storage", Settings::values.gamecard_path);
387 sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false);
388 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
389 395
390 // System 396 // System
391 Settings::values.use_docked_mode.SetValue( 397 ReadSetting("System", Settings::values.use_docked_mode);
392 sdl2_config->GetBoolean("System", "use_docked_mode", true));
393 398
394 Settings::values.current_user = std::clamp<int>( 399 ReadSetting("System", Settings::values.current_user);
395 sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); 400 Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
401 Service::Account::MAX_USERS - 1);
396 402
397 const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); 403 const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
398 if (rng_seed_enabled) { 404 if (rng_seed_enabled) {
@@ -409,89 +415,60 @@ void Config::ReadValues() {
409 Settings::values.custom_rtc = std::nullopt; 415 Settings::values.custom_rtc = std::nullopt;
410 } 416 }
411 417
412 Settings::values.language_index.SetValue( 418 ReadSetting("System", Settings::values.language_index);
413 sdl2_config->GetInteger("System", "language_index", 1)); 419 ReadSetting("System", Settings::values.time_zone_index);
414 Settings::values.time_zone_index.SetValue(
415 sdl2_config->GetInteger("System", "time_zone_index", 0));
416 420
417 // Core 421 // Core
418 Settings::values.use_multi_core.SetValue( 422 ReadSetting("Core", Settings::values.use_multi_core);
419 sdl2_config->GetBoolean("Core", "use_multi_core", true));
420 423
421 // Renderer 424 // Renderer
422 const int renderer_backend = sdl2_config->GetInteger( 425 ReadSetting("Renderer", Settings::values.renderer_backend);
423 "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); 426 ReadSetting("Renderer", Settings::values.renderer_debug);
424 Settings::values.renderer_backend.SetValue( 427 ReadSetting("Renderer", Settings::values.vulkan_device);
425 static_cast<Settings::RendererBackend>(renderer_backend)); 428
426 Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); 429 ReadSetting("Renderer", Settings::values.aspect_ratio);
427 Settings::values.vulkan_device.SetValue( 430 ReadSetting("Renderer", Settings::values.max_anisotropy);
428 sdl2_config->GetInteger("Renderer", "vulkan_device", 0)); 431 ReadSetting("Renderer", Settings::values.use_frame_limit);
429 432 ReadSetting("Renderer", Settings::values.frame_limit);
430 Settings::values.aspect_ratio.SetValue( 433 ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
431 static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0))); 434 ReadSetting("Renderer", Settings::values.gpu_accuracy);
432 Settings::values.max_anisotropy.SetValue( 435 ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
433 static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0))); 436 ReadSetting("Renderer", Settings::values.use_vsync);
434 Settings::values.use_frame_limit.SetValue( 437 ReadSetting("Renderer", Settings::values.disable_fps_limit);
435 sdl2_config->GetBoolean("Renderer", "use_frame_limit", true)); 438 ReadSetting("Renderer", Settings::values.use_assembly_shaders);
436 Settings::values.frame_limit.SetValue( 439 ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
437 static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100))); 440 ReadSetting("Renderer", Settings::values.use_nvdec_emulation);
438 Settings::values.use_disk_shader_cache.SetValue( 441 ReadSetting("Renderer", Settings::values.accelerate_astc);
439 sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false)); 442 ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
440 const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 1); 443
441 Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level)); 444 ReadSetting("Renderer", Settings::values.bg_red);
442 Settings::values.use_asynchronous_gpu_emulation.SetValue( 445 ReadSetting("Renderer", Settings::values.bg_green);
443 sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", true)); 446 ReadSetting("Renderer", Settings::values.bg_blue);
444 Settings::values.use_vsync.SetValue(
445 static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
446 Settings::values.disable_fps_limit.SetValue(
447 sdl2_config->GetBoolean("Renderer", "disable_fps_limit", false));
448 Settings::values.use_assembly_shaders.SetValue(
449 sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", true));
450 Settings::values.use_asynchronous_shaders.SetValue(
451 sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
452 Settings::values.use_nvdec_emulation.SetValue(
453 sdl2_config->GetBoolean("Renderer", "use_nvdec_emulation", true));
454 Settings::values.accelerate_astc.SetValue(
455 sdl2_config->GetBoolean("Renderer", "accelerate_astc", true));
456 Settings::values.use_fast_gpu_time.SetValue(
457 sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
458
459 Settings::values.bg_red.SetValue(
460 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)));
461 Settings::values.bg_green.SetValue(
462 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)));
463 Settings::values.bg_blue.SetValue(
464 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)));
465 447
466 // Audio 448 // Audio
467 Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); 449 ReadSetting("Audio", Settings::values.sink_id);
468 Settings::values.enable_audio_stretching.SetValue( 450 ReadSetting("Audio", Settings::values.enable_audio_stretching);
469 sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true)); 451 ReadSetting("Audio", Settings::values.audio_device_id);
470 Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); 452 ReadSetting("Audio", Settings::values.volume);
471 Settings::values.volume.SetValue(
472 static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)));
473 453
474 // Miscellaneous 454 // Miscellaneous
475 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); 455 // log_filter has a different default here than from common
476 Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false); 456 Settings::values.log_filter =
457 sdl2_config->Get("Miscellaneous", Settings::values.log_filter.GetLabel(), "*:Trace");
458 ReadSetting("Miscellaneous", Settings::values.use_dev_keys);
477 459
478 // Debugging 460 // Debugging
479 Settings::values.record_frame_times = 461 Settings::values.record_frame_times =
480 sdl2_config->GetBoolean("Debugging", "record_frame_times", false); 462 sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
481 Settings::values.program_args = sdl2_config->Get("Debugging", "program_args", ""); 463 ReadSetting("Debugging", Settings::values.program_args);
482 Settings::values.dump_exefs = sdl2_config->GetBoolean("Debugging", "dump_exefs", false); 464 ReadSetting("Debugging", Settings::values.dump_exefs);
483 Settings::values.dump_nso = sdl2_config->GetBoolean("Debugging", "dump_nso", false); 465 ReadSetting("Debugging", Settings::values.dump_nso);
484 Settings::values.enable_fs_access_log = 466 ReadSetting("Debugging", Settings::values.enable_fs_access_log);
485 sdl2_config->GetBoolean("Debugging", "enable_fs_access_log", false); 467 ReadSetting("Debugging", Settings::values.reporting_services);
486 Settings::values.reporting_services = 468 ReadSetting("Debugging", Settings::values.quest_flag);
487 sdl2_config->GetBoolean("Debugging", "reporting_services", false); 469 ReadSetting("Debugging", Settings::values.use_debug_asserts);
488 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); 470 ReadSetting("Debugging", Settings::values.use_auto_stub);
489 Settings::values.use_debug_asserts = 471 ReadSetting("Debugging", Settings::values.disable_macro_jit);
490 sdl2_config->GetBoolean("Debugging", "use_debug_asserts", false);
491 Settings::values.use_auto_stub = sdl2_config->GetBoolean("Debugging", "use_auto_stub", false);
492
493 Settings::values.disable_macro_jit =
494 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
495 472
496 const auto title_list = sdl2_config->Get("AddOns", "title_ids", ""); 473 const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
497 std::stringstream ss(title_list); 474 std::stringstream ss(title_list);
@@ -511,17 +488,14 @@ void Config::ReadValues() {
511 } 488 }
512 489
513 // Web Service 490 // Web Service
514 Settings::values.enable_telemetry = 491 ReadSetting("WebService", Settings::values.enable_telemetry);
515 sdl2_config->GetBoolean("WebService", "enable_telemetry", true); 492 ReadSetting("WebService", Settings::values.web_api_url);
516 Settings::values.web_api_url = 493 ReadSetting("WebService", Settings::values.yuzu_username);
517 sdl2_config->Get("WebService", "web_api_url", "https://api.yuzu-emu.org"); 494 ReadSetting("WebService", Settings::values.yuzu_token);
518 Settings::values.yuzu_username = sdl2_config->Get("WebService", "yuzu_username", "");
519 Settings::values.yuzu_token = sdl2_config->Get("WebService", "yuzu_token", "");
520 495
521 // Services 496 // Services
522 Settings::values.bcat_backend = sdl2_config->Get("Services", "bcat_backend", "none"); 497 ReadSetting("Services", Settings::values.bcat_backend);
523 Settings::values.bcat_boxcat_local = 498 ReadSetting("Services", Settings::values.bcat_boxcat_local);
524 sdl2_config->GetBoolean("Services", "bcat_boxcat_local", false);
525} 499}
526 500
527void Config::Reload() { 501void Config::Reload() {
diff --git a/src/yuzu_cmd/config.h b/src/yuzu_cmd/config.h
index 807199278..bf0103dee 100644
--- a/src/yuzu_cmd/config.h
+++ b/src/yuzu_cmd/config.h
@@ -8,6 +8,8 @@
8#include <memory> 8#include <memory>
9#include <string> 9#include <string>
10 10
11#include "common/settings.h"
12
11class INIReader; 13class INIReader;
12 14
13class Config { 15class Config {
@@ -22,4 +24,8 @@ public:
22 ~Config(); 24 ~Config();
23 25
24 void Reload(); 26 void Reload();
27
28private:
29 template <typename Type>
30 void ReadSetting(const std::string& group, Settings::BasicSetting<Type> setting);
25}; 31};
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 50e388312..9607cdcb1 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -78,7 +78,7 @@ static void InitializeLogging() {
78 using namespace Common; 78 using namespace Common;
79 79
80 Log::Filter log_filter(Log::Level::Debug); 80 Log::Filter log_filter(Log::Level::Debug);
81 log_filter.ParseFilterString(Settings::values.log_filter); 81 log_filter.ParseFilterString(static_cast<std::string>(Settings::values.log_filter));
82 Log::SetGlobalFilter(log_filter); 82 Log::SetGlobalFilter(log_filter);
83 83
84 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>()); 84 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());