diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/settings.h | 452 | 
1 files changed, 182 insertions, 270 deletions
| diff --git a/src/common/settings.h b/src/common/settings.h index a507744a2..3583a2e70 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -101,15 +101,15 @@ struct ResolutionScalingInfo {      }  }; -/** The BasicSetting class is a simple resource manager. It defines a label and default value - * alongside the actual value of the setting for simpler and less-error prone use with frontend - * configurations. Setting a default value and label is required, though subclasses may deviate from - * this requirement. +/** The Setting class is a simple resource manager. It defines a label and default value alongside + * the actual value of the setting for simpler and less-error prone use with frontend + * configurations. Specifying a default value and label is required. A minimum and maximum range can + * be specified for sanitization.   */  template <typename Type> -class BasicSetting { +class Setting {  protected: -    BasicSetting() = default; +    Setting() = default;      /**       * Only sets the setting to the given initializer, leaving the other members to their default @@ -117,7 +117,7 @@ protected:       *       * @param global_val Initial value of the setting       */ -    explicit BasicSetting(const Type& global_val) : global{global_val} {} +    explicit Setting(const Type& val) : value{val} {}  public:      /** @@ -126,9 +126,22 @@ public:       * @param default_val Intial value of the setting, and default value of the setting       * @param name Label for the setting       */ -    explicit BasicSetting(const Type& default_val, const std::string& name) -        : default_value{default_val}, global{default_val}, label{name} {} -    virtual ~BasicSetting() = default; +    explicit Setting(const Type& default_val, const std::string& name) +        : value{default_val}, default_value{default_val}, ranged{false}, label{name} {} +    virtual ~Setting() = default; + +    /** +     * Sets a default value, minimum value, maximum value, and label. +     * +     * @param default_val Intial value of the setting, and default value of the setting +     * @param min_val Sets the minimum allowed value of the setting +     * @param max_val Sets the maximum allowed value of the setting +     * @param name Label for the setting +     */ +    explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val, +                     const std::string& name) +        : value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val}, +          ranged{true}, label{name} {}      /**       *  Returns a reference to the setting's value. @@ -136,17 +149,17 @@ public:       * @returns A reference to the setting       */      [[nodiscard]] virtual const Type& GetValue() const { -        return global; +        return value;      }      /**       * Sets the setting to the given value.       * -     * @param value The desired value +     * @param val The desired value       */ -    virtual void SetValue(const Type& value) { -        Type temp{value}; -        std::swap(global, temp); +    virtual void SetValue(const Type& val) { +        Type temp{(ranged) ? std::clamp(val, minimum, maximum) : val}; +        std::swap(value, temp);      }      /** @@ -170,14 +183,14 @@ public:      /**       * Assigns a value to the setting.       * -     * @param value The desired setting value +     * @param val The desired setting value       *       * @returns A reference to the setting       */ -    virtual const Type& operator=(const Type& value) { -        Type temp{value}; -        std::swap(global, temp); -        return global; +    virtual const Type& operator=(const Type& val) { +        Type temp{(ranged) ? std::clamp(val, minimum, maximum) : val}; +        std::swap(value, temp); +        return value;      }      /** @@ -186,72 +199,28 @@ public:       * @returns A reference to the setting       */      explicit virtual operator const Type&() const { -        return global; +        return value;      }  protected: +    Type value{};               ///< The setting      const Type default_value{}; ///< The default value -    Type global{};              ///< The setting +    const Type maximum{};       ///< Maximum allowed value of the setting +    const Type minimum{};       ///< Minimum allowed value of the setting +    const bool ranged;          ///< The setting has sanitization ranges      const std::string label{};  ///< The setting's label  };  /** - * BasicRangedSetting class is intended for use with quantifiable settings that need a more - * restrictive range than implicitly defined by its type. Implements a minimum and maximum that is - * simply used to sanitize SetValue and the assignment overload. - */ -template <typename Type> -class BasicRangedSetting : virtual public BasicSetting<Type> { -public: -    /** -     * Sets a default value, minimum value, maximum value, and label. -     * -     * @param default_val Intial value of the setting, and default value of the setting -     * @param min_val Sets the minimum allowed value of the setting -     * @param max_val Sets the maximum allowed value of the setting -     * @param name Label for the setting -     */ -    explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val, -                                const std::string& name) -        : BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {} -    virtual ~BasicRangedSetting() = default; - -    /** -     * Like BasicSetting's SetValue, except value is clamped to the range of the setting. -     * -     * @param value The desired value -     */ -    void SetValue(const Type& value) override { -        this->global = std::clamp(value, minimum, maximum); -    } - -    /** -     * Like BasicSetting's assignment overload, except value is clamped to the range of the setting. -     * -     * @param value The desired value -     * @returns A reference to the setting's value -     */ -    const Type& operator=(const Type& value) override { -        this->global = std::clamp(value, minimum, maximum); -        return this->global; -    } - -    const Type minimum; ///< Minimum allowed value of the setting -    const Type maximum; ///< Maximum allowed value of the setting -}; - -/** - * The Setting class is a slightly more complex version of the BasicSetting class. This adds a + * The SwitchableSetting class is a slightly more complex version of the Setting class. This adds a   * custom setting to switch to when a guest application specifically requires it. The effect is that   * other components of the emulator can access the setting's intended value without any need for the   * component to ask whether the custom or global setting is needed at the moment.   *   * By default, the global setting is used. - * - * Like the BasicSetting, this requires setting a default value and label to use.   */  template <typename Type> -class Setting : virtual public BasicSetting<Type> { +class SwitchableSetting : virtual public Setting<Type> {  public:      /**       * Sets a default value, label, and setting value. @@ -259,9 +228,21 @@ public:       * @param default_val Intial value of the setting, and default value of the setting       * @param name Label for the setting       */ -    explicit Setting(const Type& default_val, const std::string& name) -        : BasicSetting<Type>(default_val, name) {} -    virtual ~Setting() = default; +    explicit SwitchableSetting(const Type& default_val, const std::string& name) +        : Setting<Type>{default_val, name} {} +    virtual ~SwitchableSetting() = default; + +    /** +     * Sets a default value, minimum value, maximum value, and label. +     * +     * @param default_val Intial value of the setting, and default value of the setting +     * @param min_val Sets the minimum allowed value of the setting +     * @param max_val Sets the maximum allowed value of the setting +     * @param name Label for the setting +     */ +    explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val, +                               const std::string& name) +        : Setting<Type>{default_val, min_val, max_val, name} {}      /**       * Tells this setting to represent either the global or custom setting when other member @@ -292,13 +273,13 @@ public:       */      [[nodiscard]] virtual const Type& GetValue() const override {          if (use_global) { -            return this->global; +            return this->value;          }          return custom;      }      [[nodiscard]] virtual const Type& GetValue(bool need_global) const {          if (use_global || need_global) { -            return this->global; +            return this->value;          }          return custom;      } @@ -306,12 +287,12 @@ public:      /**       * Sets the current setting value depending on the global state.       * -     * @param value The new value +     * @param val The new value       */ -    void SetValue(const Type& value) override { -        Type temp{value}; +    void SetValue(const Type& val) override { +        Type temp{(this->ranged) ? std::clamp(val, this->minimum, this->maximum) : val};          if (use_global) { -            std::swap(this->global, temp); +            std::swap(this->value, temp);          } else {              std::swap(custom, temp);          } @@ -320,15 +301,15 @@ public:      /**       * Assigns the current setting value depending on the global state.       * -     * @param value The new value +     * @param val The new value       *       * @returns A reference to the current setting value       */ -    const Type& operator=(const Type& value) override { -        Type temp{value}; +    const Type& operator=(const Type& val) override { +        Type temp{(this->ranged) ? std::clamp(val, this->minimum, this->maximum) : val};          if (use_global) { -            std::swap(this->global, temp); -            return this->global; +            std::swap(this->value, temp); +            return this->value;          }          std::swap(custom, temp);          return custom; @@ -341,7 +322,7 @@ public:       */      virtual explicit operator const Type&() const override {          if (use_global) { -            return this->global; +            return this->value;          }          return custom;      } @@ -352,75 +333,6 @@ protected:  };  /** - * RangedSetting is a Setting that implements a maximum and minimum value for its setting. Intended - * for use with quantifiable settings. - */ -template <typename Type> -class RangedSetting final : public BasicRangedSetting<Type>, public Setting<Type> { -public: -    /** -     * Sets a default value, minimum value, maximum value, and label. -     * -     * @param default_val Intial value of the setting, and default value of the setting -     * @param min_val Sets the minimum allowed value of the setting -     * @param max_val Sets the maximum allowed value of the setting -     * @param name Label for the setting -     */ -    explicit RangedSetting(const Type& default_val, const Type& min_val, const Type& max_val, -                           const std::string& name) -        : BasicSetting<Type>{default_val, name}, -          BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val, -                                                                                       name} {} -    virtual ~RangedSetting() = default; - -    // The following are needed to avoid a MSVC bug -    // (source: https://stackoverflow.com/questions/469508) -    [[nodiscard]] const Type& GetValue() const override { -        return Setting<Type>::GetValue(); -    } -    [[nodiscard]] const Type& GetValue(bool need_global) const override { -        return Setting<Type>::GetValue(need_global); -    } -    explicit operator const Type&() const override { -        if (this->use_global) { -            return this->global; -        } -        return this->custom; -    } - -    /** -     * Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the -     * appropriate value depending on the global state. -     * -     * @param value The desired value -     */ -    void SetValue(const Type& value) override { -        const Type temp = std::clamp(value, this->minimum, this->maximum); -        if (this->use_global) { -            this->global = temp; -        } -        this->custom = temp; -    } - -    /** -     * Like BasicSetting's assignment overload, except value is clamped to the range of the setting. -     * Uses the appropriate value depending on the global state. -     * -     * @param value The desired value -     * @returns A reference to the setting's value -     */ -    const Type& operator=(const Type& value) override { -        const Type temp = std::clamp(value, this->minimum, this->maximum); -        if (this->use_global) { -            this->global = temp; -            return this->global; -        } -        this->custom = temp; -        return this->custom; -    } -}; - -/**   * The InputSetting class allows for getting a reference to either the global or custom members.   * This is required as we cannot easily modify the values of user-defined types within containers   * using the SetValue() member function found in the Setting class. The primary purpose of this @@ -431,7 +343,7 @@ template <typename Type>  class InputSetting final {  public:      InputSetting() = default; -    explicit InputSetting(Type val) : BasicSetting<Type>(val) {} +    explicit InputSetting(Type val) : Setting<Type>(val) {}      ~InputSetting() = default;      void SetGlobal(bool to_global) {          use_global = to_global; @@ -459,175 +371,175 @@ struct TouchFromButtonMap {  struct Values {      // Audio -    BasicSetting<std::string> audio_device_id{"auto", "output_device"}; -    BasicSetting<std::string> sink_id{"auto", "output_engine"}; -    BasicSetting<bool> audio_muted{false, "audio_muted"}; -    RangedSetting<u8> volume{100, 0, 100, "volume"}; +    Setting<std::string> audio_device_id{"auto", "output_device"}; +    Setting<std::string> sink_id{"auto", "output_engine"}; +    Setting<bool> audio_muted{false, "audio_muted"}; +    SwitchableSetting<u8> volume{100, 0, 100, "volume"};      // Core -    Setting<bool> use_multi_core{true, "use_multi_core"}; -    Setting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"}; +    SwitchableSetting<bool> use_multi_core{true, "use_multi_core"}; +    SwitchableSetting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"};      // Cpu -    RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto, -                                            CPUAccuracy::Paranoid, "cpu_accuracy"}; +    SwitchableSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto, +                                                CPUAccuracy::Paranoid, "cpu_accuracy"};      // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021 -    BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"}; -    BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"}; - -    BasicSetting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"}; -    BasicSetting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"}; -    BasicSetting<bool> cpuopt_return_stack_buffer{true, "cpuopt_return_stack_buffer"}; -    BasicSetting<bool> cpuopt_fast_dispatcher{true, "cpuopt_fast_dispatcher"}; -    BasicSetting<bool> cpuopt_context_elimination{true, "cpuopt_context_elimination"}; -    BasicSetting<bool> cpuopt_const_prop{true, "cpuopt_const_prop"}; -    BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"}; -    BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"}; -    BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; -    BasicSetting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"}; -    BasicSetting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"}; - -    Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; -    Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; -    Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"}; -    Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"}; -    Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; -    Setting<bool> cpuopt_unsafe_ignore_global_monitor{true, "cpuopt_unsafe_ignore_global_monitor"}; +    Setting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"}; +    Setting<bool> cpu_debug_mode{false, "cpu_debug_mode"}; + +    Setting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"}; +    Setting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"}; +    Setting<bool> cpuopt_return_stack_buffer{true, "cpuopt_return_stack_buffer"}; +    Setting<bool> cpuopt_fast_dispatcher{true, "cpuopt_fast_dispatcher"}; +    Setting<bool> cpuopt_context_elimination{true, "cpuopt_context_elimination"}; +    Setting<bool> cpuopt_const_prop{true, "cpuopt_const_prop"}; +    Setting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"}; +    Setting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"}; +    Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; +    Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"}; +    Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"}; + +    SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; +    SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; +    SwitchableSetting<bool> cpuopt_unsafe_ignore_standard_fpcr{ +        true, "cpuopt_unsafe_ignore_standard_fpcr"}; +    SwitchableSetting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"}; +    SwitchableSetting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; +    SwitchableSetting<bool> cpuopt_unsafe_ignore_global_monitor{ +        true, "cpuopt_unsafe_ignore_global_monitor"};      // Renderer -    RangedSetting<RendererBackend> renderer_backend{ +    SwitchableSetting<RendererBackend> renderer_backend{          RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"}; -    BasicSetting<bool> renderer_debug{false, "debug"}; -    BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"}; -    BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"}; -    BasicSetting<bool> disable_shader_loop_safety_checks{false, -                                                         "disable_shader_loop_safety_checks"}; -    Setting<int> vulkan_device{0, "vulkan_device"}; +    Setting<bool> renderer_debug{false, "debug"}; +    Setting<bool> renderer_shader_feedback{false, "shader_feedback"}; +    Setting<bool> enable_nsight_aftermath{false, "nsight_aftermath"}; +    Setting<bool> disable_shader_loop_safety_checks{false, "disable_shader_loop_safety_checks"}; +    SwitchableSetting<int> vulkan_device{0, "vulkan_device"};      ResolutionScalingInfo resolution_info{}; -    Setting<ResolutionSetup> resolution_setup{ResolutionSetup::Res1X, "resolution_setup"}; -    Setting<ScalingFilter> scaling_filter{ScalingFilter::Bilinear, "scaling_filter"}; -    Setting<AntiAliasing> anti_aliasing{AntiAliasing::None, "anti_aliasing"}; +    SwitchableSetting<ResolutionSetup> resolution_setup{ResolutionSetup::Res1X, "resolution_setup"}; +    SwitchableSetting<ScalingFilter> scaling_filter{ScalingFilter::Bilinear, "scaling_filter"}; +    SwitchableSetting<AntiAliasing> anti_aliasing{AntiAliasing::None, "anti_aliasing"};      // *nix platforms may have issues with the borderless windowed fullscreen mode.      // Default to exclusive fullscreen on these platforms for now. -    RangedSetting<FullscreenMode> fullscreen_mode{ +    SwitchableSetting<FullscreenMode> fullscreen_mode{  #ifdef _WIN32          FullscreenMode::Borderless,  #else          FullscreenMode::Exclusive,  #endif          FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"}; -    RangedSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"}; -    RangedSetting<int> max_anisotropy{0, 0, 5, "max_anisotropy"}; -    Setting<bool> use_speed_limit{true, "use_speed_limit"}; -    RangedSetting<u16> speed_limit{100, 0, 9999, "speed_limit"}; -    Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"}; -    RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal, -                                            GPUAccuracy::Extreme, "gpu_accuracy"}; -    Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; -    Setting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"}; -    Setting<bool> accelerate_astc{true, "accelerate_astc"}; -    Setting<bool> use_vsync{true, "use_vsync"}; -    RangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"}; -    BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"}; -    RangedSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL, -                                                ShaderBackend::SPIRV, "shader_backend"}; -    Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; -    Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; - -    Setting<u8> bg_red{0, "bg_red"}; -    Setting<u8> bg_green{0, "bg_green"}; -    Setting<u8> bg_blue{0, "bg_blue"}; +    SwitchableSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"}; +    SwitchableSetting<int> max_anisotropy{0, 0, 5, "max_anisotropy"}; +    SwitchableSetting<bool> use_speed_limit{true, "use_speed_limit"}; +    SwitchableSetting<u16> speed_limit{100, 0, 9999, "speed_limit"}; +    SwitchableSetting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"}; +    SwitchableSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal, +                                                GPUAccuracy::Extreme, "gpu_accuracy"}; +    SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; +    SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"}; +    SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"}; +    SwitchableSetting<bool> use_vsync{true, "use_vsync"}; +    SwitchableSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"}; +    Setting<bool> disable_fps_limit{false, "disable_fps_limit"}; +    SwitchableSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL, +                                                    ShaderBackend::SPIRV, "shader_backend"}; +    SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; +    SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; + +    SwitchableSetting<u8> bg_red{0, "bg_red"}; +    SwitchableSetting<u8> bg_green{0, "bg_green"}; +    SwitchableSetting<u8> bg_blue{0, "bg_blue"};      // System -    Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"}; +    SwitchableSetting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};      // Measured in seconds since epoch      std::optional<s64> custom_rtc;      // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`      s64 custom_rtc_differential; -    BasicSetting<s32> current_user{0, "current_user"}; -    RangedSetting<s32> language_index{1, 0, 17, "language_index"}; -    RangedSetting<s32> region_index{1, 0, 6, "region_index"}; -    RangedSetting<s32> time_zone_index{0, 0, 45, "time_zone_index"}; -    RangedSetting<s32> sound_index{1, 0, 2, "sound_index"}; +    Setting<s32> current_user{0, "current_user"}; +    SwitchableSetting<s32> language_index{1, 0, 17, "language_index"}; +    SwitchableSetting<s32> region_index{1, 0, 6, "region_index"}; +    SwitchableSetting<s32> time_zone_index{0, 0, 45, "time_zone_index"}; +    SwitchableSetting<s32> sound_index{1, 0, 2, "sound_index"};      // Controls      InputSetting<std::array<PlayerInput, 10>> players; -    Setting<bool> use_docked_mode{true, "use_docked_mode"}; +    SwitchableSetting<bool> use_docked_mode{true, "use_docked_mode"}; -    BasicSetting<bool> enable_raw_input{false, "enable_raw_input"}; -    BasicSetting<bool> controller_navigation{true, "controller_navigation"}; +    Setting<bool> enable_raw_input{false, "enable_raw_input"}; +    Setting<bool> controller_navigation{true, "controller_navigation"}; -    Setting<bool> vibration_enabled{true, "vibration_enabled"}; -    Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; +    SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"}; +    SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; -    Setting<bool> motion_enabled{true, "motion_enabled"}; -    BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"}; -    BasicSetting<bool> enable_udp_controller{false, "enable_udp_controller"}; +    SwitchableSetting<bool> motion_enabled{true, "motion_enabled"}; +    Setting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"}; +    Setting<bool> enable_udp_controller{false, "enable_udp_controller"}; -    BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"}; -    BasicSetting<bool> tas_enable{false, "tas_enable"}; -    BasicSetting<bool> tas_loop{false, "tas_loop"}; +    Setting<bool> pause_tas_on_load{true, "pause_tas_on_load"}; +    Setting<bool> tas_enable{false, "tas_enable"}; +    Setting<bool> tas_loop{false, "tas_loop"}; -    BasicSetting<bool> mouse_panning{false, "mouse_panning"}; -    BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; -    BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; +    Setting<bool> mouse_panning{false, "mouse_panning"}; +    Setting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; +    Setting<bool> mouse_enabled{false, "mouse_enabled"}; -    BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; -    BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"}; +    Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; +    Setting<bool> keyboard_enabled{false, "keyboard_enabled"}; -    BasicSetting<bool> debug_pad_enabled{false, "debug_pad_enabled"}; +    Setting<bool> debug_pad_enabled{false, "debug_pad_enabled"};      ButtonsRaw debug_pad_buttons;      AnalogsRaw debug_pad_analogs;      TouchscreenInput touchscreen; -    BasicSetting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850", -                                           "touch_device"}; -    BasicSetting<int> touch_from_button_map_index{0, "touch_from_button_map"}; +    Setting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850", "touch_device"}; +    Setting<int> touch_from_button_map_index{0, "touch_from_button_map"};      std::vector<TouchFromButtonMap> touch_from_button_maps; -    BasicSetting<bool> enable_ring_controller{true, "enable_ring_controller"}; +    Setting<bool> enable_ring_controller{true, "enable_ring_controller"};      RingconRaw ringcon_analogs;      // Data Storage -    BasicSetting<bool> use_virtual_sd{true, "use_virtual_sd"}; -    BasicSetting<bool> gamecard_inserted{false, "gamecard_inserted"}; -    BasicSetting<bool> gamecard_current_game{false, "gamecard_current_game"}; -    BasicSetting<std::string> gamecard_path{std::string(), "gamecard_path"}; +    Setting<bool> use_virtual_sd{true, "use_virtual_sd"}; +    Setting<bool> gamecard_inserted{false, "gamecard_inserted"}; +    Setting<bool> gamecard_current_game{false, "gamecard_current_game"}; +    Setting<std::string> gamecard_path{std::string(), "gamecard_path"};      // Debugging      bool record_frame_times; -    BasicSetting<bool> use_gdbstub{false, "use_gdbstub"}; -    BasicSetting<u16> gdbstub_port{6543, "gdbstub_port"}; -    BasicSetting<std::string> program_args{std::string(), "program_args"}; -    BasicSetting<bool> dump_exefs{false, "dump_exefs"}; -    BasicSetting<bool> dump_nso{false, "dump_nso"}; -    BasicSetting<bool> dump_shaders{false, "dump_shaders"}; -    BasicSetting<bool> dump_macros{false, "dump_macros"}; -    BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"}; -    BasicSetting<bool> reporting_services{false, "reporting_services"}; -    BasicSetting<bool> quest_flag{false, "quest_flag"}; -    BasicSetting<bool> disable_macro_jit{false, "disable_macro_jit"}; -    BasicSetting<bool> extended_logging{false, "extended_logging"}; -    BasicSetting<bool> use_debug_asserts{false, "use_debug_asserts"}; -    BasicSetting<bool> use_auto_stub{false, "use_auto_stub"}; -    BasicSetting<bool> enable_all_controllers{false, "enable_all_controllers"}; +    Setting<bool> use_gdbstub{false, "use_gdbstub"}; +    Setting<u16> gdbstub_port{6543, "gdbstub_port"}; +    Setting<std::string> program_args{std::string(), "program_args"}; +    Setting<bool> dump_exefs{false, "dump_exefs"}; +    Setting<bool> dump_nso{false, "dump_nso"}; +    Setting<bool> dump_shaders{false, "dump_shaders"}; +    Setting<bool> dump_macros{false, "dump_macros"}; +    Setting<bool> enable_fs_access_log{false, "enable_fs_access_log"}; +    Setting<bool> reporting_services{false, "reporting_services"}; +    Setting<bool> quest_flag{false, "quest_flag"}; +    Setting<bool> disable_macro_jit{false, "disable_macro_jit"}; +    Setting<bool> extended_logging{false, "extended_logging"}; +    Setting<bool> use_debug_asserts{false, "use_debug_asserts"}; +    Setting<bool> use_auto_stub{false, "use_auto_stub"}; +    Setting<bool> enable_all_controllers{false, "enable_all_controllers"};      // Miscellaneous -    BasicSetting<std::string> log_filter{"*:Info", "log_filter"}; -    BasicSetting<bool> use_dev_keys{false, "use_dev_keys"}; +    Setting<std::string> log_filter{"*:Info", "log_filter"}; +    Setting<bool> use_dev_keys{false, "use_dev_keys"};      // Network -    BasicSetting<std::string> network_interface{std::string(), "network_interface"}; +    Setting<std::string> network_interface{std::string(), "network_interface"};      // WebService -    BasicSetting<bool> enable_telemetry{true, "enable_telemetry"}; -    BasicSetting<std::string> web_api_url{"https://api.yuzu-emu.org", "web_api_url"}; -    BasicSetting<std::string> yuzu_username{std::string(), "yuzu_username"}; -    BasicSetting<std::string> yuzu_token{std::string(), "yuzu_token"}; +    Setting<bool> enable_telemetry{true, "enable_telemetry"}; +    Setting<std::string> web_api_url{"https://api.yuzu-emu.org", "web_api_url"}; +    Setting<std::string> yuzu_username{std::string(), "yuzu_username"}; +    Setting<std::string> yuzu_token{std::string(), "yuzu_token"};      // Add-Ons      std::map<u64, std::vector<std::string>> disabled_addons; | 
