summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/CMakeLists.txt8
-rw-r--r--src/common/fiber.cpp21
-rw-r--r--src/common/fiber.h7
-rw-r--r--src/common/settings.h452
-rw-r--r--src/core/arm/arm_interface.cpp15
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp30
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp17
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/cpu_manager.cpp51
-rw-r--r--src/core/cpu_manager.h21
-rw-r--r--src/core/debugger/gdbstub_arch.cpp8
-rw-r--r--src/core/hid/hid_types.h1
-rw-r--r--src/core/hle/kernel/k_process.cpp2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp7
-rw-r--r--src/core/hle/kernel/k_scheduler.h1
-rw-r--r--src/core/hle/kernel/k_thread.cpp22
-rw-r--r--src/core/hle/kernel/k_thread.h3
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp34
-rw-r--r--src/core/hle/service/hid/controllers/npad.h3
-rw-r--r--src/core/hle/service/hid/errors.h3
-rw-r--r--src/core/hle/service/hid/hid.cpp75
-rw-r--r--src/tests/common/fibers.cpp123
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp6
-rw-r--r--src/yuzu/configuration/config.cpp12
-rw-r--r--src/yuzu/configuration/config.h8
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp6
-rw-r--r--src/yuzu/configuration/configuration_shared.h10
-rw-r--r--src/yuzu/uisettings.h54
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/config.h4
31 files changed, 459 insertions, 555 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 39d038493..39ae573b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -36,7 +36,6 @@ if (MSVC)
# /GT - Supports fiber safety for data allocated using static thread-local storage
add_compile_options(
/MP
- /Zi
/Zm200
/Zo
/permissive-
@@ -79,6 +78,13 @@ if (MSVC)
/we5245 # 'function': unreferenced function with internal linkage has been removed
)
+ if (USE_CCACHE)
+ # when caching, we need to use /Z7 to downgrade debug info to use an older but more cachable format
+ add_compile_options(/Z7)
+ else()
+ add_compile_options(/Zi)
+ endif()
+
if (ARCHITECTURE_x86_64)
add_compile_options(/QIntel-jcc-erratum)
endif()
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index f9aeb692a..bc92b360b 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -20,10 +20,8 @@ struct Fiber::FiberImpl {
VirtualBuffer<u8> rewind_stack;
std::mutex guard;
- std::function<void(void*)> entry_point;
- std::function<void(void*)> rewind_point;
- void* rewind_parameter{};
- void* start_parameter{};
+ std::function<void()> entry_point;
+ std::function<void()> rewind_point;
std::shared_ptr<Fiber> previous_fiber;
bool is_thread_fiber{};
bool released{};
@@ -34,13 +32,8 @@ struct Fiber::FiberImpl {
boost::context::detail::fcontext_t rewind_context{};
};
-void Fiber::SetStartParameter(void* new_parameter) {
- impl->start_parameter = new_parameter;
-}
-
-void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param) {
+void Fiber::SetRewindPoint(std::function<void()>&& rewind_func) {
impl->rewind_point = std::move(rewind_func);
- impl->rewind_parameter = rewind_param;
}
void Fiber::Start(boost::context::detail::transfer_t& transfer) {
@@ -48,7 +41,7 @@ void Fiber::Start(boost::context::detail::transfer_t& transfer) {
impl->previous_fiber->impl->context = transfer.fctx;
impl->previous_fiber->impl->guard.unlock();
impl->previous_fiber.reset();
- impl->entry_point(impl->start_parameter);
+ impl->entry_point();
UNREACHABLE();
}
@@ -59,7 +52,7 @@ void Fiber::OnRewind([[maybe_unused]] boost::context::detail::transfer_t& transf
u8* tmp = impl->stack_limit;
impl->stack_limit = impl->rewind_stack_limit;
impl->rewind_stack_limit = tmp;
- impl->rewind_point(impl->rewind_parameter);
+ impl->rewind_point();
UNREACHABLE();
}
@@ -73,10 +66,8 @@ void Fiber::RewindStartFunc(boost::context::detail::transfer_t transfer) {
fiber->OnRewind(transfer);
}
-Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter)
- : impl{std::make_unique<FiberImpl>()} {
+Fiber::Fiber(std::function<void()>&& entry_point_func) : impl{std::make_unique<FiberImpl>()} {
impl->entry_point = std::move(entry_point_func);
- impl->start_parameter = start_parameter;
impl->stack_limit = impl->stack.data();
impl->rewind_stack_limit = impl->rewind_stack.data();
u8* stack_base = impl->stack_limit + default_stack_size;
diff --git a/src/common/fiber.h b/src/common/fiber.h
index 873604bc6..f24d333a3 100644
--- a/src/common/fiber.h
+++ b/src/common/fiber.h
@@ -29,7 +29,7 @@ namespace Common {
*/
class Fiber {
public:
- Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter);
+ Fiber(std::function<void()>&& entry_point_func);
~Fiber();
Fiber(const Fiber&) = delete;
@@ -43,16 +43,13 @@ public:
static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
[[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
- void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param);
+ void SetRewindPoint(std::function<void()>&& rewind_func);
void Rewind();
/// Only call from main thread's fiber
void Exit();
- /// Changes the start parameter of the fiber. Has no effect if the fiber already started
- void SetStartParameter(void* new_parameter);
-
private:
Fiber();
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;
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 0efc3732f..cef79b245 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -1,6 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef _MSC_VER
+#include <cxxabi.h>
+#endif
+
#include <map>
#include <optional>
#include "common/bit_field.h"
@@ -68,8 +72,19 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
if (symbol_set != symbols.end()) {
const auto symbol = Symbols::GetSymbolName(symbol_set->second, entry.offset);
if (symbol.has_value()) {
+#ifdef _MSC_VER
// TODO(DarkLordZach): Add demangling of symbol names.
entry.name = *symbol;
+#else
+ int status{-1};
+ char* demangled{abi::__cxa_demangle(symbol->c_str(), nullptr, nullptr, &status)};
+ if (status == 0 && demangled != nullptr) {
+ entry.name = demangled;
+ std::free(demangled);
+ } else {
+ entry.name = *symbol;
+ }
+#endif
}
}
}
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 10cf72a45..1be5fe1c1 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -427,18 +427,38 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table,
}
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system,
- u64 sp, u64 lr) {
- // No way to get accurate stack traces in A32 yet
- return {};
+ u64 fp, u64 lr, u64 pc) {
+ std::vector<BacktraceEntry> out;
+ auto& memory = system.Memory();
+
+ out.push_back({"", 0, pc, 0, ""});
+
+ // fp (= r11) points to the last frame record.
+ // Frame records are two words long:
+ // fp+0 : pointer to previous frame record
+ // fp+4 : value of lr for frame
+ while (true) {
+ out.push_back({"", 0, lr, 0, ""});
+ if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) {
+ break;
+ }
+ lr = memory.Read32(fp + 4);
+ fp = memory.Read32(fp);
+ }
+
+ SymbolicateBacktrace(system, out);
+
+ return out;
}
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktraceFromContext(
System& system, const ThreadContext32& ctx) {
- return GetBacktrace(system, ctx.cpu_registers[13], ctx.cpu_registers[14]);
+ const auto& reg = ctx.cpu_registers;
+ return GetBacktrace(system, reg[11], reg[14], reg[15]);
}
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace() const {
- return GetBacktrace(system, GetReg(13), GetReg(14));
+ return GetBacktrace(system, GetReg(11), GetReg(14), GetReg(15));
}
} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index fcbe24f0c..346e9abf8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -78,7 +78,7 @@ protected:
private:
std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const;
- static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 sp, u64 lr);
+ static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 fp, u64 lr, u64 pc);
using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
using JitCacheType =
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 92266aa9e..c437f24b8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -494,22 +494,22 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table,
}
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system,
- u64 fp, u64 lr) {
+ u64 fp, u64 lr, u64 pc) {
std::vector<BacktraceEntry> out;
auto& memory = system.Memory();
- // fp (= r29) points to the last frame record.
- // Note that this is the frame record for the *previous* frame, not the current one.
- // Note we need to subtract 4 from our last read to get the proper address
+ out.push_back({"", 0, pc, 0, ""});
+
+ // fp (= x29) points to the previous frame record.
// Frame records are two words long:
// fp+0 : pointer to previous frame record
// fp+8 : value of lr for frame
while (true) {
out.push_back({"", 0, lr, 0, ""});
- if (!fp) {
+ if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) {
break;
}
- lr = memory.Read64(fp + 8) - 4;
+ lr = memory.Read64(fp + 8);
fp = memory.Read64(fp);
}
@@ -520,11 +520,12 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::S
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktraceFromContext(
System& system, const ThreadContext64& ctx) {
- return GetBacktrace(system, ctx.cpu_registers[29], ctx.cpu_registers[30]);
+ const auto& reg = ctx.cpu_registers;
+ return GetBacktrace(system, reg[29], reg[30], ctx.pc);
}
std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace() const {
- return GetBacktrace(system, GetReg(29), GetReg(30));
+ return GetBacktrace(system, GetReg(29), GetReg(30), GetPC());
}
} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 71dbaac5e..c77a83ad7 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -73,7 +73,7 @@ private:
std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table,
std::size_t address_space_bits) const;
- static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 fp, u64 lr);
+ static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 fp, u64 lr, u64 pc);
using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
using JitCacheType =
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 9fc78f033..37d3d83b9 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -41,51 +41,32 @@ void CpuManager::Shutdown() {
}
}
-std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() {
- return GuestThreadFunction;
-}
-
-std::function<void(void*)> CpuManager::GetIdleThreadStartFunc() {
- return IdleThreadFunction;
-}
-
-std::function<void(void*)> CpuManager::GetShutdownThreadStartFunc() {
- return ShutdownThreadFunction;
-}
-
-void CpuManager::GuestThreadFunction(void* cpu_manager_) {
- CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
- if (cpu_manager->is_multicore) {
- cpu_manager->MultiCoreRunGuestThread();
+void CpuManager::GuestThreadFunction() {
+ if (is_multicore) {
+ MultiCoreRunGuestThread();
} else {
- cpu_manager->SingleCoreRunGuestThread();
+ SingleCoreRunGuestThread();
}
}
-void CpuManager::GuestRewindFunction(void* cpu_manager_) {
- CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
- if (cpu_manager->is_multicore) {
- cpu_manager->MultiCoreRunGuestLoop();
+void CpuManager::GuestRewindFunction() {
+ if (is_multicore) {
+ MultiCoreRunGuestLoop();
} else {
- cpu_manager->SingleCoreRunGuestLoop();
+ SingleCoreRunGuestLoop();
}
}
-void CpuManager::IdleThreadFunction(void* cpu_manager_) {
- CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
- if (cpu_manager->is_multicore) {
- cpu_manager->MultiCoreRunIdleThread();
+void CpuManager::IdleThreadFunction() {
+ if (is_multicore) {
+ MultiCoreRunIdleThread();
} else {
- cpu_manager->SingleCoreRunIdleThread();
+ SingleCoreRunIdleThread();
}
}
-void CpuManager::ShutdownThreadFunction(void* cpu_manager) {
- static_cast<CpuManager*>(cpu_manager)->ShutdownThread();
-}
-
-void* CpuManager::GetStartFuncParameter() {
- return this;
+void CpuManager::ShutdownThreadFunction() {
+ ShutdownThread();
}
///////////////////////////////////////////////////////////////////////////////
@@ -97,7 +78,7 @@ void CpuManager::MultiCoreRunGuestThread() {
kernel.CurrentScheduler()->OnThreadStart();
auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
auto& host_context = thread->GetHostContext();
- host_context->SetRewindPoint(GuestRewindFunction, this);
+ host_context->SetRewindPoint([this] { GuestRewindFunction(); });
MultiCoreRunGuestLoop();
}
@@ -134,7 +115,7 @@ void CpuManager::SingleCoreRunGuestThread() {
kernel.CurrentScheduler()->OnThreadStart();
auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
auto& host_context = thread->GetHostContext();
- host_context->SetRewindPoint(GuestRewindFunction, this);
+ host_context->SetRewindPoint([this] { GuestRewindFunction(); });
SingleCoreRunGuestLoop();
}
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h
index f0751fc58..76dc58ee1 100644
--- a/src/core/cpu_manager.h
+++ b/src/core/cpu_manager.h
@@ -50,10 +50,15 @@ public:
void Initialize();
void Shutdown();
- static std::function<void(void*)> GetGuestThreadStartFunc();
- static std::function<void(void*)> GetIdleThreadStartFunc();
- static std::function<void(void*)> GetShutdownThreadStartFunc();
- void* GetStartFuncParameter();
+ std::function<void()> GetGuestThreadStartFunc() {
+ return [this] { GuestThreadFunction(); };
+ }
+ std::function<void()> GetIdleThreadStartFunc() {
+ return [this] { IdleThreadFunction(); };
+ }
+ std::function<void()> GetShutdownThreadStartFunc() {
+ return [this] { ShutdownThreadFunction(); };
+ }
void PreemptSingleCore(bool from_running_enviroment = true);
@@ -62,10 +67,10 @@ public:
}
private:
- static void GuestThreadFunction(void* cpu_manager);
- static void GuestRewindFunction(void* cpu_manager);
- static void IdleThreadFunction(void* cpu_manager);
- static void ShutdownThreadFunction(void* cpu_manager);
+ void GuestThreadFunction();
+ void GuestRewindFunction();
+ void IdleThreadFunction();
+ void ShutdownThreadFunction();
void MultiCoreRunGuestThread();
void MultiCoreRunGuestLoop();
diff --git a/src/core/debugger/gdbstub_arch.cpp b/src/core/debugger/gdbstub_arch.cpp
index 750c353b9..4bef09bd7 100644
--- a/src/core/debugger/gdbstub_arch.cpp
+++ b/src/core/debugger/gdbstub_arch.cpp
@@ -191,8 +191,10 @@ std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const
const auto& gprs{context.cpu_registers};
const auto& fprs{context.vector_registers};
- if (id <= SP_REGISTER) {
+ if (id < SP_REGISTER) {
return ValueToHex(gprs[id]);
+ } else if (id == SP_REGISTER) {
+ return ValueToHex(context.sp);
} else if (id == PC_REGISTER) {
return ValueToHex(context.pc);
} else if (id == PSTATE_REGISTER) {
@@ -215,8 +217,10 @@ void GDBStubA64::RegWrite(Kernel::KThread* thread, size_t id, std::string_view v
auto& context{thread->GetContext64()};
- if (id <= SP_REGISTER) {
+ if (id < SP_REGISTER) {
context.cpu_registers[id] = HexToValue<u64>(value);
+ } else if (id == SP_REGISTER) {
+ context.sp = HexToValue<u64>(value);
} else if (id == PC_REGISTER) {
context.pc = HexToValue<u64>(value);
} else if (id == PSTATE_REGISTER) {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 9f76f9bcb..e49223016 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -272,6 +272,7 @@ enum class VibrationDeviceType : u32 {
Unknown = 0,
LinearResonantActuator = 1,
GcErm = 2,
+ N64 = 3,
};
// This is nn::hid::VibrationGcErmCommand
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 183c693e3..b662788b3 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -161,7 +161,7 @@ bool KProcess::ReleaseUserException(KThread* thread) {
std::addressof(num_waiters),
reinterpret_cast<uintptr_t>(std::addressof(exception_thread)));
next != nullptr) {
- next->SetState(ThreadState::Runnable);
+ next->EndWait(ResultSuccess);
}
KScheduler::SetSchedulerUpdateNeeded(kernel);
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index d586b3f5c..d599d2bcb 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -622,7 +622,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) {
}
KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, core_id{core_id_} {
- switch_fiber = std::make_shared<Common::Fiber>(OnSwitch, this);
+ switch_fiber = std::make_shared<Common::Fiber>([this] { SwitchToCurrent(); });
state.needs_scheduling.store(true);
state.interrupt_task_thread_runnable = false;
state.should_count_idle = false;
@@ -778,11 +778,6 @@ void KScheduler::ScheduleImpl() {
next_scheduler.SwitchContextStep2();
}
-void KScheduler::OnSwitch(void* this_scheduler) {
- KScheduler* sched = static_cast<KScheduler*>(this_scheduler);
- sched->SwitchToCurrent();
-}
-
void KScheduler::SwitchToCurrent() {
while (true) {
{
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index cc3da33f5..6a4760eca 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -170,7 +170,6 @@ private:
*/
void UpdateLastContextSwitchTime(KThread* thread, KProcess* process);
- static void OnSwitch(void* this_scheduler);
void SwitchToCurrent();
KThread* prev_thread{};
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 8d7faa662..50cb5fc90 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -246,14 +246,12 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
- ThreadType type, std::function<void(void*)>&& init_func,
- void* init_func_parameter) {
+ ThreadType type, std::function<void()>&& init_func) {
// Initialize the thread.
R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
// Initialize emulation parameters.
- thread->host_context =
- std::make_shared<Common::Fiber>(std::move(init_func), init_func_parameter);
+ thread->host_context = std::make_shared<Common::Fiber>(std::move(init_func));
thread->is_single_core = !Settings::values.use_multi_core.GetValue();
return ResultSuccess;
@@ -265,15 +263,13 @@ Result KThread::InitializeDummyThread(KThread* thread) {
Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) {
return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main,
- Core::CpuManager::GetIdleThreadStartFunc(),
- system.GetCpuManager().GetStartFuncParameter());
+ system.GetCpuManager().GetIdleThreadStartFunc());
}
Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread,
KThreadFunction func, uintptr_t arg, s32 virt_core) {
return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority,
- Core::CpuManager::GetShutdownThreadStartFunc(),
- system.GetCpuManager().GetStartFuncParameter());
+ system.GetCpuManager().GetShutdownThreadStartFunc());
}
Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
@@ -281,8 +277,7 @@ Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThr
KProcess* owner) {
system.Kernel().GlobalSchedulerContext().AddThread(thread);
return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
- ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(),
- system.GetCpuManager().GetStartFuncParameter());
+ ThreadType::User, system.GetCpuManager().GetGuestThreadStartFunc());
}
void KThread::PostDestroy(uintptr_t arg) {
@@ -485,9 +480,7 @@ void KThread::Unpin() {
// Resume any threads that began waiting on us while we were pinned.
for (auto it = pinned_waiter_list.begin(); it != pinned_waiter_list.end(); ++it) {
- if (it->GetState() == ThreadState::Waiting) {
- it->SetState(ThreadState::Runnable);
- }
+ it->EndWait(ResultSuccess);
}
}
@@ -882,6 +875,7 @@ void KThread::AddWaiterImpl(KThread* thread) {
// Keep track of how many kernel waiters we have.
if (IsKernelAddressKey(thread->GetAddressKey())) {
ASSERT((num_kernel_waiters++) >= 0);
+ KScheduler::SetSchedulerUpdateNeeded(kernel);
}
// Insert the waiter.
@@ -895,6 +889,7 @@ void KThread::RemoveWaiterImpl(KThread* thread) {
// Keep track of how many kernel waiters we have.
if (IsKernelAddressKey(thread->GetAddressKey())) {
ASSERT((num_kernel_waiters--) > 0);
+ KScheduler::SetSchedulerUpdateNeeded(kernel);
}
// Remove the waiter.
@@ -970,6 +965,7 @@ KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) {
// Keep track of how many kernel waiters we have.
if (IsKernelAddressKey(thread->GetAddressKey())) {
ASSERT((num_kernel_waiters--) > 0);
+ KScheduler::SetSchedulerUpdateNeeded(kernel);
}
it = waiter_list.erase(it);
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 94c4cd1c8..28cd7ecb0 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -729,8 +729,7 @@ private:
[[nodiscard]] static Result InitializeThread(KThread* thread, KThreadFunction func,
uintptr_t arg, VAddr user_stack_top, s32 prio,
s32 core, KProcess* owner, ThreadType type,
- std::function<void(void*)>&& init_func,
- void* init_func_parameter);
+ std::function<void()>&& init_func);
static void RestorePriority(KernelCore& kernel_ctx, KThread* thread);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index c08b0a5dc..aa7189bda 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -49,28 +49,41 @@ bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) {
}
}
-bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
+Result Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
- return npad_id && npad_type && device_index;
+
+ if (!npad_type) {
+ return VibrationInvalidStyleIndex;
+ }
+ if (!npad_id) {
+ return VibrationInvalidNpadId;
+ }
+ if (!device_index) {
+ return VibrationDeviceIndexOutOfRange;
+ }
+
+ return ResultSuccess;
}
Result Controller_NPad::VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
+ const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
+ const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
+
if (!npad_id) {
return InvalidNpadId;
}
- const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
if (!device_index) {
return NpadDeviceIndexOutOfRange;
}
// This doesn't get validated on nnsdk
- const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
if (!npad_type) {
return NpadInvalidHandle;
}
+
return ResultSuccess;
}
@@ -705,6 +718,11 @@ Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const {
}
void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
+ if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
+ ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
+ return;
+ }
+
handheld_activation_mode = activation_mode;
}
@@ -840,7 +858,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
void Controller_NPad::VibrateController(
const Core::HID::VibrationDeviceHandle& vibration_device_handle,
const Core::HID::VibrationValue& vibration_value) {
- if (!IsDeviceHandleValid(vibration_device_handle)) {
+ if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -903,7 +921,7 @@ void Controller_NPad::VibrateControllers(
Core::HID::VibrationValue Controller_NPad::GetLastVibration(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (!IsDeviceHandleValid(vibration_device_handle)) {
+ if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return {};
}
@@ -914,7 +932,7 @@ Core::HID::VibrationValue Controller_NPad::GetLastVibration(
void Controller_NPad::InitializeVibrationDevice(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
- if (!IsDeviceHandleValid(vibration_device_handle)) {
+ if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -941,7 +959,7 @@ void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
bool Controller_NPad::IsVibrationDeviceMounted(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (!IsDeviceHandleValid(vibration_device_handle)) {
+ if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return false;
}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 8b54724ed..1a589cca2 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -81,6 +81,7 @@ public:
Dual = 0,
Single = 1,
None = 2,
+ MaxActivationMode = 3,
};
// This is nn::hid::NpadCommunicationMode
@@ -196,7 +197,7 @@ public:
Core::HID::NpadButton GetAndResetPressState();
static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
- static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
+ static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
static Result VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
index 615c23b84..46282f42e 100644
--- a/src/core/hle/service/hid/errors.h
+++ b/src/core/hle/service/hid/errors.h
@@ -9,6 +9,9 @@ namespace Service::HID {
constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
+constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
+constexpr Result VibrationInvalidNpadId{ErrorModule::HID, 123};
+constexpr Result VibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423};
constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
constexpr Result NpadIsSameType{ErrorModule::HID, 602};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index dc5d0366d..78efffc50 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -778,7 +778,7 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
bool is_at_rest{};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
+ controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -786,7 +786,7 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
+ rb.Push(ResultSuccess);
rb.Push(is_at_rest);
}
@@ -803,8 +803,8 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
bool is_firmware_available{};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.IsFirmwareUpdateAvailableForSixAxisSensor(
- parameters.sixaxis_handle, is_firmware_available);
+ controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
+ is_firmware_available);
LOG_WARNING(
Service_HID,
@@ -813,7 +813,7 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
+ rb.Push(ResultSuccess);
rb.Push(is_firmware_available);
}
@@ -1083,13 +1083,13 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.DisconnectNpad(parameters.npad_id);
+ controller.DisconnectNpad(parameters.npad_id);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ rb.Push(ResultSuccess);
}
void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
@@ -1165,15 +1165,14 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
const auto parameters{rp.PopRaw<Parameters>()};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
- Controller_NPad::NpadJoyAssignmentMode::Single);
+ controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ rb.Push(ResultSuccess);
}
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
@@ -1189,15 +1188,15 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
- Controller_NPad::NpadJoyAssignmentMode::Single);
+ controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
parameters.npad_joy_device_type);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ rb.Push(ResultSuccess);
}
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
@@ -1212,14 +1211,13 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetNpadMode(parameters.npad_id, {},
- Controller_NPad::NpadJoyAssignmentMode::Dual);
+ controller.SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ rb.Push(ResultSuccess);
}
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
@@ -1412,8 +1410,11 @@ void Hid::ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) {
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
+ const auto& controller =
+ GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
Core::HID::VibrationDeviceInfo vibration_device_info;
+ bool check_device_index = false;
switch (vibration_device_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
@@ -1421,34 +1422,46 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::JoyconLeft:
case Core::HID::NpadStyleIndex::JoyconRight:
- default:
vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
+ check_device_index = true;
break;
case Core::HID::NpadStyleIndex::GameCube:
vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
break;
- case Core::HID::NpadStyleIndex::Pokeball:
+ case Core::HID::NpadStyleIndex::N64:
+ vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
+ break;
+ default:
vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
break;
}
- switch (vibration_device_handle.device_index) {
- case Core::HID::DeviceIndex::Left:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
- break;
- case Core::HID::DeviceIndex::Right:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
- break;
- case Core::HID::DeviceIndex::None:
- default:
- ASSERT_MSG(false, "DeviceIndex should never be None!");
- vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
- break;
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
+ if (check_device_index) {
+ switch (vibration_device_handle.device_index) {
+ case Core::HID::DeviceIndex::Left:
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
+ break;
+ case Core::HID::DeviceIndex::Right:
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
+ break;
+ case Core::HID::DeviceIndex::None:
+ default:
+ ASSERT_MSG(false, "DeviceIndex should never be None!");
+ break;
+ }
}
LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
vibration_device_info.type, vibration_device_info.position);
+ const auto result = controller.IsDeviceHandleValid(vibration_device_handle);
+ if (result.IsError()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+ return;
+ }
+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushRaw(vibration_device_info);
diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp
index cfc84d423..4e29f9199 100644
--- a/src/tests/common/fibers.cpp
+++ b/src/tests/common/fibers.cpp
@@ -43,7 +43,15 @@ class TestControl1 {
public:
TestControl1() = default;
- void DoWork();
+ void DoWork() {
+ const u32 id = thread_ids.Get();
+ u32 value = items[id];
+ for (u32 i = 0; i < id; i++) {
+ value++;
+ }
+ results[id] = value;
+ Fiber::YieldTo(work_fibers[id], *thread_fibers[id]);
+ }
void ExecuteThread(u32 id);
@@ -54,35 +62,16 @@ public:
std::vector<u32> results;
};
-static void WorkControl1(void* control) {
- auto* test_control = static_cast<TestControl1*>(control);
- test_control->DoWork();
-}
-
-void TestControl1::DoWork() {
- const u32 id = thread_ids.Get();
- u32 value = items[id];
- for (u32 i = 0; i < id; i++) {
- value++;
- }
- results[id] = value;
- Fiber::YieldTo(work_fibers[id], *thread_fibers[id]);
-}
-
void TestControl1::ExecuteThread(u32 id) {
thread_ids.Register(id);
auto thread_fiber = Fiber::ThreadToFiber();
thread_fibers[id] = thread_fiber;
- work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this);
+ work_fibers[id] = std::make_shared<Fiber>([this] { DoWork(); });
items[id] = rand() % 256;
Fiber::YieldTo(thread_fibers[id], *work_fibers[id]);
thread_fibers[id]->Exit();
}
-static void ThreadStart1(u32 id, TestControl1& test_control) {
- test_control.ExecuteThread(id);
-}
-
/** This test checks for fiber setup configuration and validates that fibers are
* doing all the work required.
*/
@@ -95,7 +84,7 @@ TEST_CASE("Fibers::Setup", "[common]") {
test_control.results.resize(num_threads, 0);
std::vector<std::thread> threads;
for (u32 i = 0; i < num_threads; i++) {
- threads.emplace_back(ThreadStart1, i, std::ref(test_control));
+ threads.emplace_back([&test_control, i] { test_control.ExecuteThread(i); });
}
for (u32 i = 0; i < num_threads; i++) {
threads[i].join();
@@ -167,21 +156,6 @@ public:
std::shared_ptr<Common::Fiber> fiber3;
};
-static void WorkControl2_1(void* control) {
- auto* test_control = static_cast<TestControl2*>(control);
- test_control->DoWork1();
-}
-
-static void WorkControl2_2(void* control) {
- auto* test_control = static_cast<TestControl2*>(control);
- test_control->DoWork2();
-}
-
-static void WorkControl2_3(void* control) {
- auto* test_control = static_cast<TestControl2*>(control);
- test_control->DoWork3();
-}
-
void TestControl2::ExecuteThread(u32 id) {
thread_ids.Register(id);
auto thread_fiber = Fiber::ThreadToFiber();
@@ -193,18 +167,6 @@ void TestControl2::Exit() {
thread_fibers[id]->Exit();
}
-static void ThreadStart2_1(u32 id, TestControl2& test_control) {
- test_control.ExecuteThread(id);
- test_control.CallFiber1();
- test_control.Exit();
-}
-
-static void ThreadStart2_2(u32 id, TestControl2& test_control) {
- test_control.ExecuteThread(id);
- test_control.CallFiber2();
- test_control.Exit();
-}
-
/** This test checks for fiber thread exchange configuration and validates that fibers are
* that a fiber has been successfully transferred from one thread to another and that the TLS
* region of the thread is kept while changing fibers.
@@ -212,14 +174,19 @@ static void ThreadStart2_2(u32 id, TestControl2& test_control) {
TEST_CASE("Fibers::InterExchange", "[common]") {
TestControl2 test_control{};
test_control.thread_fibers.resize(2);
- test_control.fiber1 =
- std::make_shared<Fiber>(std::function<void(void*)>{WorkControl2_1}, &test_control);
- test_control.fiber2 =
- std::make_shared<Fiber>(std::function<void(void*)>{WorkControl2_2}, &test_control);
- test_control.fiber3 =
- std::make_shared<Fiber>(std::function<void(void*)>{WorkControl2_3}, &test_control);
- std::thread thread1(ThreadStart2_1, 0, std::ref(test_control));
- std::thread thread2(ThreadStart2_2, 1, std::ref(test_control));
+ test_control.fiber1 = std::make_shared<Fiber>([&test_control] { test_control.DoWork1(); });
+ test_control.fiber2 = std::make_shared<Fiber>([&test_control] { test_control.DoWork2(); });
+ test_control.fiber3 = std::make_shared<Fiber>([&test_control] { test_control.DoWork3(); });
+ std::thread thread1{[&test_control] {
+ test_control.ExecuteThread(0);
+ test_control.CallFiber1();
+ test_control.Exit();
+ }};
+ std::thread thread2{[&test_control] {
+ test_control.ExecuteThread(1);
+ test_control.CallFiber2();
+ test_control.Exit();
+ }};
thread1.join();
thread2.join();
REQUIRE(test_control.assert1);
@@ -270,16 +237,6 @@ public:
std::shared_ptr<Common::Fiber> fiber2;
};
-static void WorkControl3_1(void* control) {
- auto* test_control = static_cast<TestControl3*>(control);
- test_control->DoWork1();
-}
-
-static void WorkControl3_2(void* control) {
- auto* test_control = static_cast<TestControl3*>(control);
- test_control->DoWork2();
-}
-
void TestControl3::ExecuteThread(u32 id) {
thread_ids.Register(id);
auto thread_fiber = Fiber::ThreadToFiber();
@@ -291,12 +248,6 @@ void TestControl3::Exit() {
thread_fibers[id]->Exit();
}
-static void ThreadStart3(u32 id, TestControl3& test_control) {
- test_control.ExecuteThread(id);
- test_control.CallFiber1();
- test_control.Exit();
-}
-
/** This test checks for one two threads racing for starting the same fiber.
* It checks execution occurred in an ordered manner and by no time there were
* two contexts at the same time.
@@ -304,12 +255,15 @@ static void ThreadStart3(u32 id, TestControl3& test_control) {
TEST_CASE("Fibers::StartRace", "[common]") {
TestControl3 test_control{};
test_control.thread_fibers.resize(2);
- test_control.fiber1 =
- std::make_shared<Fiber>(std::function<void(void*)>{WorkControl3_1}, &test_control);
- test_control.fiber2 =
- std::make_shared<Fiber>(std::function<void(void*)>{WorkControl3_2}, &test_control);
- std::thread thread1(ThreadStart3, 0, std::ref(test_control));
- std::thread thread2(ThreadStart3, 1, std::ref(test_control));
+ test_control.fiber1 = std::make_shared<Fiber>([&test_control] { test_control.DoWork1(); });
+ test_control.fiber2 = std::make_shared<Fiber>([&test_control] { test_control.DoWork2(); });
+ const auto race_function{[&test_control](u32 id) {
+ test_control.ExecuteThread(id);
+ test_control.CallFiber1();
+ test_control.Exit();
+ }};
+ std::thread thread1([&] { race_function(0); });
+ std::thread thread2([&] { race_function(1); });
thread1.join();
thread2.join();
REQUIRE(test_control.value1 == 1);
@@ -319,12 +273,10 @@ TEST_CASE("Fibers::StartRace", "[common]") {
class TestControl4;
-static void WorkControl4(void* control);
-
class TestControl4 {
public:
TestControl4() {
- fiber1 = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl4}, this);
+ fiber1 = std::make_shared<Fiber>([this] { DoWork(); });
goal_reached = false;
rewinded = false;
}
@@ -336,7 +288,7 @@ public:
}
void DoWork() {
- fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this);
+ fiber1->SetRewindPoint([this] { DoWork(); });
if (rewinded) {
goal_reached = true;
Fiber::YieldTo(fiber1, *thread_fiber);
@@ -351,11 +303,6 @@ public:
bool rewinded;
};
-static void WorkControl4(void* control) {
- auto* test_control = static_cast<TestControl4*>(control);
- test_control->DoWork();
-}
-
TEST_CASE("Fibers::Rewind", "[common]") {
TestControl4 test_control{};
test_control.Execute();
diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 283c04cd5..790edbb2a 100644
--- a/src/yuzu/applets/qt_web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -52,8 +52,8 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system,
: QWebEngineView(parent), input_subsystem{input_subsystem_},
url_interceptor(std::make_unique<UrlRequestInterceptor>()),
input_interpreter(std::make_unique<InputInterpreter>(system)),
- default_profile{QWebEngineProfile::defaultProfile()},
- global_settings{QWebEngineSettings::globalSettings()} {
+ default_profile{QWebEngineProfile::defaultProfile()}, global_settings{
+ default_profile->settings()} {
default_profile->setPersistentStoragePath(QString::fromStdString(Common::FS::PathToUTF8String(
Common::FS::GetYuzuPath(Common::FS::YuzuPath::YuzuDir) / "qtwebengine")));
@@ -78,7 +78,7 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system,
default_profile->scripts()->insert(gamepad);
default_profile->scripts()->insert(window_nx);
- default_profile->setRequestInterceptor(url_interceptor.get());
+ default_profile->setUrlRequestInterceptor(url_interceptor.get());
global_settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
global_settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 9df4752be..9686412d0 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -133,7 +133,7 @@ void Config::Initialize(const std::string& config_name) {
// Explicit std::string definition: Qt can't implicitly convert a std::string to a QVariant, nor
// can it implicitly convert a QVariant back to a {std::,Q}string
template <>
-void Config::ReadBasicSetting(Settings::BasicSetting<std::string>& setting) {
+void Config::ReadBasicSetting(Settings::Setting<std::string>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const auto default_value = QString::fromStdString(setting.GetDefault());
if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
@@ -144,7 +144,7 @@ void Config::ReadBasicSetting(Settings::BasicSetting<std::string>& setting) {
}
template <typename Type>
-void Config::ReadBasicSetting(Settings::BasicSetting<Type>& setting) {
+void Config::ReadBasicSetting(Settings::Setting<Type>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const Type default_value = setting.GetDefault();
if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
@@ -157,7 +157,7 @@ void Config::ReadBasicSetting(Settings::BasicSetting<Type>& setting) {
// Explicit std::string definition: Qt can't implicitly convert a std::string to a QVariant
template <>
-void Config::WriteBasicSetting(const Settings::BasicSetting<std::string>& setting) {
+void Config::WriteBasicSetting(const Settings::Setting<std::string>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const std::string& value = setting.GetValue();
qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
@@ -165,7 +165,7 @@ void Config::WriteBasicSetting(const Settings::BasicSetting<std::string>& settin
}
template <typename Type>
-void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
+void Config::WriteBasicSetting(const Settings::Setting<Type>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const Type value = setting.GetValue();
qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
@@ -173,7 +173,7 @@ void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
}
template <typename Type>
-void Config::WriteGlobalSetting(const Settings::Setting<Type>& setting) {
+void Config::WriteGlobalSetting(const Settings::SwitchableSetting<Type>& setting) {
const QString name = QString::fromStdString(setting.GetLabel());
const Type& value = setting.GetValue(global);
if (!global) {
@@ -1422,7 +1422,7 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value)
}
template <typename Type>
-void Config::ReadGlobalSetting(Settings::Setting<Type>& setting) {
+void Config::ReadGlobalSetting(Settings::SwitchableSetting<Type>& setting) {
QString name = QString::fromStdString(setting.GetLabel());
const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
setting.SetGlobal(use_global);
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index f0ab6bdaa..9ca878d23 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -160,7 +160,7 @@ private:
* @param The setting
*/
template <typename Type>
- void ReadGlobalSetting(Settings::Setting<Type>& setting);
+ void ReadGlobalSetting(Settings::SwitchableSetting<Type>& setting);
/**
* Sets a value to the qt_config using the setting's label and default value. If the config is a
@@ -169,7 +169,7 @@ private:
* @param The setting
*/
template <typename Type>
- void WriteGlobalSetting(const Settings::Setting<Type>& setting);
+ void WriteGlobalSetting(const Settings::SwitchableSetting<Type>& setting);
/**
* Reads a value from the qt_config using the setting's label and default value and applies the
@@ -178,14 +178,14 @@ private:
* @param The setting
*/
template <typename Type>
- void ReadBasicSetting(Settings::BasicSetting<Type>& setting);
+ void ReadBasicSetting(Settings::Setting<Type>& setting);
/** Sets a value from the setting in the qt_config using the setting's label and default value.
*
* @param The setting
*/
template <typename Type>
- void WriteBasicSetting(const Settings::BasicSetting<Type>& setting);
+ void WriteBasicSetting(const Settings::Setting<Type>& setting);
ConfigType type;
std::unique_ptr<QSettings> qt_config;
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 5190bd18b..dd4959417 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -9,7 +9,7 @@
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_per_game.h"
-void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
+void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting,
const QCheckBox* checkbox,
const CheckState& tracker) {
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
@@ -25,7 +25,7 @@ void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
}
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
- const Settings::Setting<bool>* setting) {
+ const Settings::SwitchableSetting<bool>* setting) {
if (setting->UsingGlobal()) {
checkbox->setCheckState(Qt::PartiallyChecked);
} else {
@@ -45,7 +45,7 @@ void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
}
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox,
- const Settings::Setting<bool>& setting,
+ const Settings::SwitchableSetting<bool>& setting,
CheckState& tracker) {
if (setting.UsingGlobal()) {
tracker = CheckState::Global;
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index 903a9baae..77802a367 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -25,10 +25,10 @@ enum class CheckState {
// Global-aware apply and set functions
// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
-void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox,
+void ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting, const QCheckBox* checkbox,
const CheckState& tracker);
template <typename Type>
-void ApplyPerGameSetting(Settings::Setting<Type>* setting, const QComboBox* combobox) {
+void ApplyPerGameSetting(Settings::SwitchableSetting<Type>* setting, const QComboBox* combobox) {
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
setting->SetValue(static_cast<Type>(combobox->currentIndex()));
} else if (!Settings::IsConfiguringGlobal()) {
@@ -43,10 +43,10 @@ void ApplyPerGameSetting(Settings::Setting<Type>* setting, const QComboBox* comb
}
// Sets a Qt UI element given a Settings::Setting
-void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting);
+void SetPerGameSetting(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>* setting);
template <typename Type>
-void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<Type>* setting) {
+void SetPerGameSetting(QComboBox* combobox, const Settings::SwitchableSetting<Type>* setting) {
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
: static_cast<int>(setting->GetValue()) +
ConfigurationShared::USE_GLOBAL_OFFSET);
@@ -56,7 +56,7 @@ void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<Type>* setti
void SetHighlight(QWidget* widget, bool highlighted);
// Sets up a QCheckBox like a tristate one, given a Setting
-void SetColoredTristate(QCheckBox* checkbox, const Settings::Setting<bool>& setting,
+void SetColoredTristate(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>& setting,
CheckState& tracker);
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
CheckState& tracker);
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index c64d87ace..044d88ca6 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -64,28 +64,28 @@ struct Values {
QByteArray gamelist_header_state;
QByteArray microprofile_geometry;
- Settings::BasicSetting<bool> microprofile_visible{false, "microProfileDialogVisible"};
-
- Settings::BasicSetting<bool> single_window_mode{true, "singleWindowMode"};
- Settings::BasicSetting<bool> fullscreen{false, "fullscreen"};
- Settings::BasicSetting<bool> display_titlebar{true, "displayTitleBars"};
- Settings::BasicSetting<bool> show_filter_bar{true, "showFilterBar"};
- Settings::BasicSetting<bool> show_status_bar{true, "showStatusBar"};
-
- Settings::BasicSetting<bool> confirm_before_closing{true, "confirmClose"};
- Settings::BasicSetting<bool> first_start{true, "firstStart"};
- Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
- Settings::BasicSetting<bool> mute_when_in_background{false, "muteWhenInBackground"};
- Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"};
+ Settings::Setting<bool> microprofile_visible{false, "microProfileDialogVisible"};
+
+ Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
+ Settings::Setting<bool> fullscreen{false, "fullscreen"};
+ Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
+ Settings::Setting<bool> show_filter_bar{true, "showFilterBar"};
+ Settings::Setting<bool> show_status_bar{true, "showStatusBar"};
+
+ Settings::Setting<bool> confirm_before_closing{true, "confirmClose"};
+ Settings::Setting<bool> first_start{true, "firstStart"};
+ Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
+ Settings::Setting<bool> mute_when_in_background{false, "muteWhenInBackground"};
+ Settings::Setting<bool> hide_mouse{true, "hideInactiveMouse"};
// Set when Vulkan is known to crash the application
- Settings::BasicSetting<bool> has_broken_vulkan{false, "has_broken_vulkan"};
+ Settings::Setting<bool> has_broken_vulkan{false, "has_broken_vulkan"};
- Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
+ Settings::Setting<bool> select_user_on_boot{false, "select_user_on_boot"};
// Discord RPC
- Settings::BasicSetting<bool> enable_discord_presence{true, "enable_discord_presence"};
+ Settings::Setting<bool> enable_discord_presence{true, "enable_discord_presence"};
- Settings::BasicSetting<bool> enable_screenshot_save_as{true, "enable_screenshot_save_as"};
+ Settings::Setting<bool> enable_screenshot_save_as{true, "enable_screenshot_save_as"};
QString roms_path;
QString symbols_path;
@@ -100,25 +100,25 @@ struct Values {
// Shortcut name <Shortcut, context>
std::vector<Shortcut> shortcuts;
- Settings::BasicSetting<uint32_t> callout_flags{0, "calloutFlags"};
+ Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"};
// logging
- Settings::BasicSetting<bool> show_console{false, "showConsole"};
+ Settings::Setting<bool> show_console{false, "showConsole"};
// Game List
- Settings::BasicSetting<bool> show_add_ons{true, "show_add_ons"};
- Settings::BasicSetting<uint32_t> game_icon_size{64, "game_icon_size"};
- Settings::BasicSetting<uint32_t> folder_icon_size{48, "folder_icon_size"};
- Settings::BasicSetting<uint8_t> row_1_text_id{3, "row_1_text_id"};
- Settings::BasicSetting<uint8_t> row_2_text_id{2, "row_2_text_id"};
+ Settings::Setting<bool> show_add_ons{true, "show_add_ons"};
+ Settings::Setting<uint32_t> game_icon_size{64, "game_icon_size"};
+ Settings::Setting<uint32_t> folder_icon_size{48, "folder_icon_size"};
+ Settings::Setting<uint8_t> row_1_text_id{3, "row_1_text_id"};
+ Settings::Setting<uint8_t> row_2_text_id{2, "row_2_text_id"};
std::atomic_bool is_game_list_reload_pending{false};
- Settings::BasicSetting<bool> cache_game_list{true, "cache_game_list"};
- Settings::BasicSetting<bool> favorites_expanded{true, "favorites_expanded"};
+ Settings::Setting<bool> cache_game_list{true, "cache_game_list"};
+ Settings::Setting<bool> favorites_expanded{true, "favorites_expanded"};
QVector<u64> favorited_ids;
bool configuration_applied;
bool reset_to_defaults;
- Settings::BasicSetting<bool> disable_web_applet{true, "disable_web_applet"};
+ Settings::Setting<bool> disable_web_applet{true, "disable_web_applet"};
};
extern Values values;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index fc4744fb0..903e02297 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -90,17 +90,17 @@ static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs>
}};
template <>
-void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) {
+void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
}
template <>
-void Config::ReadSetting(const std::string& group, Settings::BasicSetting<bool>& setting) {
+void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) {
setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
}
template <typename Type>
-void Config::ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting) {
+void Config::ReadSetting(const std::string& group, Settings::Setting<Type>& setting) {
setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(),
static_cast<long>(setting.GetDefault())));
}
diff --git a/src/yuzu_cmd/config.h b/src/yuzu_cmd/config.h
index f61ba23ec..ccf77d668 100644
--- a/src/yuzu_cmd/config.h
+++ b/src/yuzu_cmd/config.h
@@ -28,11 +28,11 @@ public:
private:
/**
- * Applies a value read from the sdl2_config to a BasicSetting.
+ * Applies a value read from the sdl2_config to a Setting.
*
* @param group The name of the INI group
* @param setting The yuzu setting to modify
*/
template <typename Type>
- void ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting);
+ void ReadSetting(const std::string& group, Settings::Setting<Type>& setting);
};