summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/settings.h162
1 files changed, 136 insertions, 26 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index a88ee045d..c4afff50b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm>
7#include <array> 8#include <array>
8#include <atomic> 9#include <atomic>
9#include <chrono> 10#include <chrono>
@@ -81,7 +82,7 @@ public:
81 * 82 *
82 * @returns A reference to the setting 83 * @returns A reference to the setting
83 */ 84 */
84 [[nodiscard]] const Type& GetValue() const { 85 [[nodiscard]] virtual const Type& GetValue() const {
85 return global; 86 return global;
86 } 87 }
87 88
@@ -90,7 +91,7 @@ public:
90 * 91 *
91 * @param value The desired value 92 * @param value The desired value
92 */ 93 */
93 void SetValue(const Type& value) { 94 virtual void SetValue(const Type& value) {
94 Type temp{value}; 95 Type temp{value};
95 std::swap(global, temp); 96 std::swap(global, temp);
96 } 97 }
@@ -120,7 +121,7 @@ public:
120 * 121 *
121 * @returns A reference to the setting 122 * @returns A reference to the setting
122 */ 123 */
123 const Type& operator=(const Type& value) { 124 virtual const Type& operator=(const Type& value) {
124 Type temp{value}; 125 Type temp{value};
125 std::swap(global, temp); 126 std::swap(global, temp);
126 return global; 127 return global;
@@ -131,7 +132,7 @@ public:
131 * 132 *
132 * @returns A reference to the setting 133 * @returns A reference to the setting
133 */ 134 */
134 explicit operator const Type&() const { 135 explicit virtual operator const Type&() const {
135 return global; 136 return global;
136 } 137 }
137 138
@@ -142,6 +143,51 @@ protected:
142}; 143};
143 144
144/** 145/**
146 * BasicRangedSetting class is intended for use with quantifiable settings that need a more
147 * restrictive range than implicitly defined by its type. Implements a minimum and maximum that is
148 * simply used to sanitize SetValue and the assignment overload.
149 */
150template <typename Type>
151class BasicRangedSetting : virtual public BasicSetting<Type> {
152public:
153 /**
154 * Sets a default value, minimum value, maximum value, and label.
155 *
156 * @param default_val Intial value of the setting, and default value of the setting
157 * @param min_val Sets the minimum allowed value of the setting
158 * @param max_val Sets the maximum allowed value of the setting
159 * @param name Label for the setting
160 */
161 explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
162 const std::string& name)
163 : BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {}
164 ~BasicRangedSetting() = default;
165
166 /**
167 * Like BasicSetting's SetValue, except value is clamped to the range of the setting.
168 *
169 * @param value The desired value
170 */
171 void SetValue(const Type& value) override {
172 this->global = std::clamp(value, minimum, maximum);
173 }
174
175 /**
176 * Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
177 *
178 * @param value The desired value
179 * @returns A reference to the setting's value
180 */
181 const Type& operator=(const Type& value) override {
182 this->global = std::clamp(value, minimum, maximum);
183 return this->global;
184 }
185
186 const Type minimum; ///< Minimum allowed value of the setting
187 const Type maximum; ///< Maximum allowed value of the setting
188};
189
190/**
145 * The Setting class is a slightly more complex version of the BasicSetting class. This adds a 191 * The Setting class is a slightly more complex version of the BasicSetting class. This adds a
146 * custom setting to switch to when a guest application specifically requires it. The effect is that 192 * custom setting to switch to when a guest application specifically requires it. The effect is that
147 * other components of the emulator can access the setting's intended value without any need for the 193 * other components of the emulator can access the setting's intended value without any need for the
@@ -152,7 +198,7 @@ protected:
152 * Like the BasicSetting, this requires setting a default value and label to use. 198 * Like the BasicSetting, this requires setting a default value and label to use.
153 */ 199 */
154template <typename Type> 200template <typename Type>
155class Setting final : public BasicSetting<Type> { 201class Setting : virtual public BasicSetting<Type> {
156public: 202public:
157 /** 203 /**
158 * Sets a default value, label, and setting value. 204 * Sets a default value, label, and setting value.
@@ -191,7 +237,13 @@ public:
191 * 237 *
192 * @returns The required value of the setting 238 * @returns The required value of the setting
193 */ 239 */
194 [[nodiscard]] const Type& GetValue(bool need_global = false) const { 240 [[nodiscard]] const Type& GetValue() const override {
241 if (use_global) {
242 return this->global;
243 }
244 return custom;
245 }
246 [[nodiscard]] const Type& GetValue(bool need_global) const {
195 if (use_global || need_global) { 247 if (use_global || need_global) {
196 return this->global; 248 return this->global;
197 } 249 }
@@ -203,7 +255,7 @@ public:
203 * 255 *
204 * @param value The new value 256 * @param value The new value
205 */ 257 */
206 void SetValue(const Type& value) { 258 void SetValue(const Type& value) override {
207 Type temp{value}; 259 Type temp{value};
208 if (use_global) { 260 if (use_global) {
209 std::swap(this->global, temp); 261 std::swap(this->global, temp);
@@ -219,7 +271,7 @@ public:
219 * 271 *
220 * @returns A reference to the current setting value 272 * @returns A reference to the current setting value
221 */ 273 */
222 const Type& operator=(const Type& value) { 274 const Type& operator=(const Type& value) override {
223 Type temp{value}; 275 Type temp{value};
224 if (use_global) { 276 if (use_global) {
225 std::swap(this->global, temp); 277 std::swap(this->global, temp);
@@ -234,19 +286,73 @@ public:
234 * 286 *
235 * @returns A reference to the current setting value 287 * @returns A reference to the current setting value
236 */ 288 */
237 explicit operator const Type&() const { 289 explicit operator const Type&() const override {
238 if (use_global) { 290 if (use_global) {
239 return this->global; 291 return this->global;
240 } 292 }
241 return custom; 293 return custom;
242 } 294 }
243 295
244private: 296protected:
245 bool use_global{true}; ///< The setting's global state 297 bool use_global{true}; ///< The setting's global state
246 Type custom{}; ///< The custom value of the setting 298 Type custom{}; ///< The custom value of the setting
247}; 299};
248 300
249/** 301/**
302 * RangedSetting is a Setting that implements a maximum and minimum value for its setting. Intended
303 * for use with quantifiable settings.
304 */
305template <typename Type>
306class RangedSetting final : public BasicRangedSetting<Type>, public Setting<Type> {
307public:
308 /**
309 * Sets a default value, minimum value, maximum value, and label.
310 *
311 * @param default_val Intial value of the setting, and default value of the setting
312 * @param min_val Sets the minimum allowed value of the setting
313 * @param max_val Sets the maximum allowed value of the setting
314 * @param name Label for the setting
315 */
316 explicit RangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
317 const std::string& name)
318 : BasicSetting<Type>{default_val, name},
319 BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val,
320 name} {}
321 ~RangedSetting() = default;
322
323 /**
324 * Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the
325 * appropriate value depending on the global state.
326 *
327 * @param value The desired value
328 */
329 void SetValue(const Type& value) override {
330 const Type temp = std::clamp(value, this->minimum, this->maximum);
331 if (this->use_global) {
332 this->global = temp;
333 }
334 this->custom = temp;
335 }
336
337 /**
338 * Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
339 * Uses the appropriate value depending on the global state.
340 *
341 * @param value The desired value
342 * @returns A reference to the setting's value
343 */
344 const Type& operator=(const Type& value) override {
345 const Type temp = std::clamp(value, this->minimum, this->maximum);
346 if (this->use_global) {
347 this->global = temp;
348 return this->global;
349 }
350 this->custom = temp;
351 return this->custom;
352 }
353};
354
355/**
250 * The InputSetting class allows for getting a reference to either the global or custom members. 356 * The InputSetting class allows for getting a reference to either the global or custom members.
251 * This is required as we cannot easily modify the values of user-defined types within containers 357 * This is required as we cannot easily modify the values of user-defined types within containers
252 * using the SetValue() member function found in the Setting class. The primary purpose of this 358 * using the SetValue() member function found in the Setting class. The primary purpose of this
@@ -289,13 +395,14 @@ struct Values {
289 BasicSetting<std::string> sink_id{"auto", "output_engine"}; 395 BasicSetting<std::string> sink_id{"auto", "output_engine"};
290 BasicSetting<bool> audio_muted{false, "audio_muted"}; 396 BasicSetting<bool> audio_muted{false, "audio_muted"};
291 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"}; 397 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
292 Setting<u8> volume{100, "volume"}; 398 RangedSetting<u8> volume{100, 0, 100, "volume"};
293 399
294 // Core 400 // Core
295 Setting<bool> use_multi_core{true, "use_multi_core"}; 401 Setting<bool> use_multi_core{true, "use_multi_core"};
296 402
297 // Cpu 403 // Cpu
298 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, "cpu_accuracy"}; 404 RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
405 CPUAccuracy::Unsafe, "cpu_accuracy"};
299 // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021 406 // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021
300 BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"}; 407 BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"};
301 BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"}; 408 BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"};
@@ -317,7 +424,8 @@ struct Values {
317 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; 424 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
318 425
319 // Renderer 426 // Renderer
320 Setting<RendererBackend> renderer_backend{RendererBackend::OpenGL, "backend"}; 427 RangedSetting<RendererBackend> renderer_backend{
428 RendererBackend::OpenGL, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"};
321 BasicSetting<bool> renderer_debug{false, "debug"}; 429 BasicSetting<bool> renderer_debug{false, "debug"};
322 BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"}; 430 BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"};
323 BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"}; 431 BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
@@ -328,26 +436,28 @@ struct Values {
328 Setting<u16> resolution_factor{1, "resolution_factor"}; 436 Setting<u16> resolution_factor{1, "resolution_factor"};
329 // *nix platforms may have issues with the borderless windowed fullscreen mode. 437 // *nix platforms may have issues with the borderless windowed fullscreen mode.
330 // Default to exclusive fullscreen on these platforms for now. 438 // Default to exclusive fullscreen on these platforms for now.
331 Setting<FullscreenMode> fullscreen_mode{ 439 RangedSetting<FullscreenMode> fullscreen_mode{
332#ifdef _WIN32 440#ifdef _WIN32
333 FullscreenMode::Borderless, 441 FullscreenMode::Borderless,
334#else 442#else
335 FullscreenMode::Exclusive, 443 FullscreenMode::Exclusive,
336#endif 444#endif
337 "fullscreen_mode"}; 445 FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
338 Setting<int> aspect_ratio{0, "aspect_ratio"}; 446 RangedSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"};
339 Setting<int> max_anisotropy{0, "max_anisotropy"}; 447 RangedSetting<int> max_anisotropy{0, 0, 4, "max_anisotropy"};
340 Setting<bool> use_speed_limit{true, "use_speed_limit"}; 448 Setting<bool> use_speed_limit{true, "use_speed_limit"};
341 Setting<u16> speed_limit{100, "speed_limit"}; 449 RangedSetting<u16> speed_limit{100, 0, 9999, "speed_limit"};
342 Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"}; 450 Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
343 Setting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, "gpu_accuracy"}; 451 RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
452 GPUAccuracy::Extreme, "gpu_accuracy"};
344 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; 453 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
345 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; 454 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
346 Setting<bool> accelerate_astc{true, "accelerate_astc"}; 455 Setting<bool> accelerate_astc{true, "accelerate_astc"};
347 Setting<bool> use_vsync{true, "use_vsync"}; 456 Setting<bool> use_vsync{true, "use_vsync"};
348 BasicSetting<u16> fps_cap{1000, "fps_cap"}; 457 BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
349 BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"}; 458 BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
350 Setting<ShaderBackend> shader_backend{ShaderBackend::GLASM, "shader_backend"}; 459 RangedSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL,
460 ShaderBackend::SPIRV, "shader_backend"};
351 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; 461 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
352 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; 462 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
353 Setting<bool> use_caches_gc{false, "use_caches_gc"}; 463 Setting<bool> use_caches_gc{false, "use_caches_gc"};
@@ -364,10 +474,10 @@ struct Values {
364 std::chrono::seconds custom_rtc_differential; 474 std::chrono::seconds custom_rtc_differential;
365 475
366 BasicSetting<s32> current_user{0, "current_user"}; 476 BasicSetting<s32> current_user{0, "current_user"};
367 Setting<s32> language_index{1, "language_index"}; 477 RangedSetting<s32> language_index{1, 0, 16, "language_index"};
368 Setting<s32> region_index{1, "region_index"}; 478 RangedSetting<s32> region_index{1, 0, 6, "region_index"};
369 Setting<s32> time_zone_index{0, "time_zone_index"}; 479 RangedSetting<s32> time_zone_index{0, 0, 45, "time_zone_index"};
370 Setting<s32> sound_index{1, "sound_index"}; 480 RangedSetting<s32> sound_index{1, 0, 2, "sound_index"};
371 481
372 // Controls 482 // Controls
373 InputSetting<std::array<PlayerInput, 10>> players; 483 InputSetting<std::array<PlayerInput, 10>> players;
@@ -384,7 +494,7 @@ struct Values {
384 "udp_input_servers"}; 494 "udp_input_servers"};
385 495
386 BasicSetting<bool> mouse_panning{false, "mouse_panning"}; 496 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
387 BasicSetting<u8> mouse_panning_sensitivity{10, "mouse_panning_sensitivity"}; 497 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
388 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; 498 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
389 std::string mouse_device; 499 std::string mouse_device;
390 MouseButtonsRaw mouse_buttons; 500 MouseButtonsRaw mouse_buttons;