summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar lat9nq2021-07-23 12:41:07 -0400
committerGravatar lat9nq2021-07-30 13:33:21 -0400
commita1f19b61f84f709ba20c350da34956c5455a6956 (patch)
tree41fa169bc46040180fa165697b6477fd2dbe98ad
parentMerge pull request #6767 from ReinUsesLisp/fold-float-pack (diff)
downloadyuzu-a1f19b61f84f709ba20c350da34956c5455a6956.tar.gz
yuzu-a1f19b61f84f709ba20c350da34956c5455a6956.tar.xz
yuzu-a1f19b61f84f709ba20c350da34956c5455a6956.zip
settings: Implement setting ranges
Clamps the setting's values against the specified minimum and maximum values.
Diffstat (limited to '')
-rw-r--r--src/common/settings.h170
1 files changed, 152 insertions, 18 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index cfc1ab46f..51f9a179b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -142,6 +142,67 @@ protected:
142}; 142};
143 143
144/** 144/**
145 * BasicRangedSetting class is intended for use with quantifiable settings that need a more
146 * restrictive range than implicitly defined by its type. Implements a minimum and maximum that is
147 * simply used to sanitize SetValue and the assignment overload.
148 */
149template <typename Type>
150class BasicRangedSetting : virtual public BasicSetting<Type> {
151public:
152 /**
153 * Sets a default value, minimum value, maximum value, and label.
154 *
155 * @param default_val Intial value of the setting, and default value of the setting
156 * @param min_val Sets the minimum allowed value of the setting
157 * @param max_val Sets the maximum allowed value of the setting
158 * @param name Label for the setting
159 */
160 explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
161 const std::string& name)
162 : BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {}
163 ~BasicRangedSetting() = default;
164
165 /**
166 * Like BasicSetting's SetValue, except value is clamped to the range of the setting.
167 *
168 * @param value The desired value
169 */
170 void SetValue(const Type& value) {
171 Type temp;
172 if (value < minimum) {
173 temp = std::move(minimum);
174 } else if (value > maximum) {
175 temp = std::move(maximum);
176 } else {
177 temp = std::move(value);
178 }
179 std::swap(this->global, temp);
180 }
181
182 /**
183 * Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
184 *
185 * @param value The desired value
186 * @returns A reference to the setting's value
187 */
188 const Type& operator=(const Type& value) {
189 Type temp;
190 if (value < minimum) {
191 temp = std::move(minimum);
192 } else if (value > maximum) {
193 temp = std::move(maximum);
194 } else {
195 temp = std::move(value);
196 }
197 std::swap(this->global, temp);
198 return this->global;
199 }
200
201 const Type minimum; ///< Minimum allowed value of the setting
202 const Type maximum; ///< Maximum allowed value of the setting
203};
204
205/**
145 * The Setting class is a slightly more complex version of the BasicSetting class. This adds a 206 * 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 207 * 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 208 * other components of the emulator can access the setting's intended value without any need for the
@@ -152,7 +213,7 @@ protected:
152 * Like the BasicSetting, this requires setting a default value and label to use. 213 * Like the BasicSetting, this requires setting a default value and label to use.
153 */ 214 */
154template <typename Type> 215template <typename Type>
155class Setting final : public BasicSetting<Type> { 216class Setting : virtual public BasicSetting<Type> {
156public: 217public:
157 /** 218 /**
158 * Sets a default value, label, and setting value. 219 * Sets a default value, label, and setting value.
@@ -241,12 +302,81 @@ public:
241 return custom; 302 return custom;
242 } 303 }
243 304
244private: 305protected:
245 bool use_global{true}; ///< The setting's global state 306 bool use_global{true}; ///< The setting's global state
246 Type custom{}; ///< The custom value of the setting 307 Type custom{}; ///< The custom value of the setting
247}; 308};
248 309
249/** 310/**
311 * RangedSetting is a Setting that implements a maximum and minimum value for its setting. Intended
312 * for use with quantifiable settings.
313 */
314template <typename Type>
315class RangedSetting final : public BasicRangedSetting<Type>, public Setting<Type> {
316public:
317 /**
318 * Sets a default value, minimum value, maximum value, and label.
319 *
320 * @param default_val Intial value of the setting, and default value of the setting
321 * @param min_val Sets the minimum allowed value of the setting
322 * @param max_val Sets the maximum allowed value of the setting
323 * @param name Label for the setting
324 */
325 explicit RangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
326 const std::string& name)
327 : BasicSetting<Type>{default_val, name},
328 BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val,
329 name} {}
330 ~RangedSetting() = default;
331
332 /**
333 * Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the
334 * appropriate value depending on the global state.
335 *
336 * @param value The desired value
337 */
338 void SetValue(const Type& value) {
339 Type temp;
340 if (value < this->minimum) {
341 temp = std::move(this->minimum);
342 } else if (value > this->maximum) {
343 temp = std::move(this->maximum);
344 } else {
345 temp = std::move(value);
346 }
347 if (this->use_global) {
348 std::swap(this->global, temp);
349 } else {
350 std::swap(this->custom, temp);
351 }
352 }
353
354 /**
355 * Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
356 * Uses the appropriate value depending on the global state.
357 *
358 * @param value The desired value
359 * @returns A reference to the setting's value
360 */
361 const Type& operator=(const Type& value) {
362 Type temp;
363 if (value < this->minimum) {
364 temp = std::move(this->minimum);
365 } else if (value > this->maximum) {
366 temp = std::move(this->maximum);
367 } else {
368 temp = std::move(value);
369 }
370 if (this->use_global) {
371 std::swap(this->global, temp);
372 return this->global;
373 }
374 std::swap(this->custom, temp);
375 return this->custom;
376 }
377};
378
379/**
250 * The InputSetting class allows for getting a reference to either the global or custom members. 380 * 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 381 * 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 382 * using the SetValue() member function found in the Setting class. The primary purpose of this
@@ -289,13 +419,14 @@ struct Values {
289 BasicSetting<std::string> sink_id{"auto", "output_engine"}; 419 BasicSetting<std::string> sink_id{"auto", "output_engine"};
290 BasicSetting<bool> audio_muted{false, "audio_muted"}; 420 BasicSetting<bool> audio_muted{false, "audio_muted"};
291 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"}; 421 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
292 Setting<u8> volume{100, "volume"}; 422 RangedSetting<u8> volume{100, 0, 100, "volume"};
293 423
294 // Core 424 // Core
295 Setting<bool> use_multi_core{true, "use_multi_core"}; 425 Setting<bool> use_multi_core{true, "use_multi_core"};
296 426
297 // Cpu 427 // Cpu
298 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, "cpu_accuracy"}; 428 RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
429 CPUAccuracy::Unsafe, "cpu_accuracy"};
299 // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021 430 // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021
300 BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"}; 431 BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"};
301 BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"}; 432 BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"};
@@ -317,7 +448,8 @@ struct Values {
317 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; 448 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
318 449
319 // Renderer 450 // Renderer
320 Setting<RendererBackend> renderer_backend{RendererBackend::OpenGL, "backend"}; 451 RangedSetting<RendererBackend> renderer_backend{
452 RendererBackend::OpenGL, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"};
321 BasicSetting<bool> renderer_debug{false, "debug"}; 453 BasicSetting<bool> renderer_debug{false, "debug"};
322 BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"}; 454 BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
323 BasicSetting<bool> disable_shader_loop_safety_checks{false, 455 BasicSetting<bool> disable_shader_loop_safety_checks{false,
@@ -327,26 +459,28 @@ struct Values {
327 Setting<u16> resolution_factor{1, "resolution_factor"}; 459 Setting<u16> resolution_factor{1, "resolution_factor"};
328 // *nix platforms may have issues with the borderless windowed fullscreen mode. 460 // *nix platforms may have issues with the borderless windowed fullscreen mode.
329 // Default to exclusive fullscreen on these platforms for now. 461 // Default to exclusive fullscreen on these platforms for now.
330 Setting<FullscreenMode> fullscreen_mode{ 462 RangedSetting<FullscreenMode> fullscreen_mode{
331#ifdef _WIN32 463#ifdef _WIN32
332 FullscreenMode::Borderless, 464 FullscreenMode::Borderless,
333#else 465#else
334 FullscreenMode::Exclusive, 466 FullscreenMode::Exclusive,
335#endif 467#endif
336 "fullscreen_mode"}; 468 FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
337 Setting<int> aspect_ratio{0, "aspect_ratio"}; 469 RangedSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"};
338 Setting<int> max_anisotropy{0, "max_anisotropy"}; 470 RangedSetting<int> max_anisotropy{0, 0, 4, "max_anisotropy"};
339 Setting<bool> use_speed_limit{true, "use_speed_limit"}; 471 Setting<bool> use_speed_limit{true, "use_speed_limit"};
340 Setting<u16> speed_limit{100, "speed_limit"}; 472 RangedSetting<u16> speed_limit{100, 0, 9999, "speed_limit"};
341 Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"}; 473 Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
342 Setting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, "gpu_accuracy"}; 474 RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
475 GPUAccuracy::Extreme, "gpu_accuracy"};
343 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; 476 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
344 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; 477 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
345 Setting<bool> accelerate_astc{true, "accelerate_astc"}; 478 Setting<bool> accelerate_astc{true, "accelerate_astc"};
346 Setting<bool> use_vsync{true, "use_vsync"}; 479 Setting<bool> use_vsync{true, "use_vsync"};
347 BasicSetting<u16> fps_cap{1000, "fps_cap"}; 480 BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
348 BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"}; 481 BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
349 Setting<ShaderBackend> shader_backend{ShaderBackend::GLASM, "shader_backend"}; 482 RangedSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL,
483 ShaderBackend::SPIRV, "shader_backend"};
350 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; 484 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
351 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; 485 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
352 Setting<bool> use_caches_gc{false, "use_caches_gc"}; 486 Setting<bool> use_caches_gc{false, "use_caches_gc"};
@@ -363,10 +497,10 @@ struct Values {
363 std::chrono::seconds custom_rtc_differential; 497 std::chrono::seconds custom_rtc_differential;
364 498
365 BasicSetting<s32> current_user{0, "current_user"}; 499 BasicSetting<s32> current_user{0, "current_user"};
366 Setting<s32> language_index{1, "language_index"}; 500 RangedSetting<s32> language_index{1, 0, 16, "language_index"};
367 Setting<s32> region_index{1, "region_index"}; 501 RangedSetting<s32> region_index{1, 0, 6, "region_index"};
368 Setting<s32> time_zone_index{0, "time_zone_index"}; 502 RangedSetting<s32> time_zone_index{0, 0, 45, "time_zone_index"};
369 Setting<s32> sound_index{1, "sound_index"}; 503 RangedSetting<s32> sound_index{1, 0, 2, "sound_index"};
370 504
371 // Controls 505 // Controls
372 InputSetting<std::array<PlayerInput, 10>> players; 506 InputSetting<std::array<PlayerInput, 10>> players;
@@ -383,7 +517,7 @@ struct Values {
383 "udp_input_servers"}; 517 "udp_input_servers"};
384 518
385 BasicSetting<bool> mouse_panning{false, "mouse_panning"}; 519 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
386 BasicSetting<u8> mouse_panning_sensitivity{10, "mouse_panning_sensitivity"}; 520 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
387 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; 521 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
388 std::string mouse_device; 522 std::string mouse_device;
389 MouseButtonsRaw mouse_buttons; 523 MouseButtonsRaw mouse_buttons;