summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Morph2020-09-28 10:00:15 -0400
committerGravatar Morph2020-11-15 23:33:20 -0500
commit8f2959f6804e0d1048ecaa6f4046622e069fe7db (patch)
tree06451ddcfcc588d2803eaa908afa085bea7782de
parentudp/client: Reduce testing period to 5 seconds (diff)
downloadyuzu-8f2959f6804e0d1048ecaa6f4046622e069fe7db.tar.gz
yuzu-8f2959f6804e0d1048ecaa6f4046622e069fe7db.tar.xz
yuzu-8f2959f6804e0d1048ecaa6f4046622e069fe7db.zip
settings: Preparation for per-game input settings
-rw-r--r--src/core/frontend/applets/controller.cpp4
-rw-r--r--src/core/frontend/framebuffer_layout.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/am/applets/controller.cpp2
-rw-r--r--src/core/hle/service/apm/controller.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp42
-rw-r--r--src/core/hle/service/hid/hid.cpp4
-rw-r--r--src/core/hle/service/vi/vi.cpp2
-rw-r--r--src/core/settings.cpp8
-rw-r--r--src/core/settings.h57
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/yuzu/applets/controller.cpp30
-rw-r--r--src/yuzu/configuration/config.cpp24
-rw-r--r--src/yuzu/configuration/configure_input.cpp24
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp4
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp8
-rw-r--r--src/yuzu/main.cpp23
-rw-r--r--src/yuzu_cmd/config.cpp25
-rw-r--r--src/yuzu_tester/config.cpp14
19 files changed, 167 insertions, 115 deletions
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 5582091f4..1ac2fb80c 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -27,7 +27,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
27 ->GetAppletResource() 27 ->GetAppletResource()
28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad); 28 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
29 29
30 auto& players = Settings::values.players; 30 auto& players = Settings::values.players.GetValue();
31 31
32 const std::size_t min_supported_players = 32 const std::size_t min_supported_players =
33 parameters.enable_single_mode ? 1 : parameters.min_players; 33 parameters.enable_single_mode ? 1 : parameters.min_players;
@@ -66,7 +66,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
66 npad.MapSettingsTypeToNPad(Settings::ControllerType::RightJoycon), index); 66 npad.MapSettingsTypeToNPad(Settings::ControllerType::RightJoycon), index);
67 } 67 }
68 } else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld && 68 } else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
69 !Settings::values.use_docked_mode) { 69 !Settings::values.use_docked_mode.GetValue()) {
70 // We should *never* reach here under any normal circumstances. 70 // We should *never* reach here under any normal circumstances.
71 npad.AddNewControllerAt(npad.MapSettingsTypeToNPad(Settings::ControllerType::Handheld), 71 npad.AddNewControllerAt(npad.MapSettingsTypeToNPad(Settings::ControllerType::Handheld),
72 index); 72 index);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 1acc82497..b9a270a55 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -47,7 +47,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
47FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) { 47FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) {
48 u32 width, height; 48 u32 width, height;
49 49
50 if (Settings::values.use_docked_mode) { 50 if (Settings::values.use_docked_mode.GetValue()) {
51 width = ScreenDocked::Width * res_scale; 51 width = ScreenDocked::Width * res_scale;
52 height = ScreenDocked::Height * res_scale; 52 height = ScreenDocked::Height * res_scale;
53 } else { 53 } else {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 2ce742e35..eb097738a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -751,7 +751,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
751 IPC::ResponseBuilder rb{ctx, 4}; 751 IPC::ResponseBuilder rb{ctx, 4};
752 rb.Push(RESULT_SUCCESS); 752 rb.Push(RESULT_SUCCESS);
753 753
754 if (Settings::values.use_docked_mode) { 754 if (Settings::values.use_docked_mode.GetValue()) {
755 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * 755 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
756 static_cast<u32>(Settings::values.resolution_factor.GetValue())); 756 static_cast<u32>(Settings::values.resolution_factor.GetValue()));
757 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * 757 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
@@ -824,7 +824,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
824} 824}
825 825
826void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { 826void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
827 const bool use_docked_mode{Settings::values.use_docked_mode}; 827 const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()};
828 LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); 828 LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
829 829
830 IPC::ResponseBuilder rb{ctx, 3}; 830 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index a0152b4ea..43b79412e 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -222,7 +222,7 @@ void Controller::Execute() {
222void Controller::ConfigurationComplete() { 222void Controller::ConfigurationComplete() {
223 ControllerSupportResultInfo result_info{}; 223 ControllerSupportResultInfo result_info{};
224 224
225 const auto& players = Settings::values.players; 225 const auto& players = Settings::values.players.GetValue();
226 226
227 // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters. 227 // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
228 // Otherwise, only count connected players from P1-P8. 228 // Otherwise, only count connected players from P1-P8.
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 25a886238..ce993bad3 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -69,7 +69,8 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
69} 69}
70 70
71PerformanceMode Controller::GetCurrentPerformanceMode() const { 71PerformanceMode Controller::GetCurrentPerformanceMode() const {
72 return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld; 72 return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Docked
73 : PerformanceMode::Handheld;
73} 74}
74 75
75PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) { 76PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index c4b26196a..15d5fa6e8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -184,11 +184,14 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
184 controller.single_color.button_color = 0; 184 controller.single_color.button_color = 0;
185 185
186 controller.dual_color_error = ColorReadError::ReadOk; 186 controller.dual_color_error = ColorReadError::ReadOk;
187 controller.left_color.body_color = Settings::values.players[controller_idx].body_color_left; 187 controller.left_color.body_color =
188 controller.left_color.button_color = Settings::values.players[controller_idx].button_color_left; 188 Settings::values.players.GetValue()[controller_idx].body_color_left;
189 controller.right_color.body_color = Settings::values.players[controller_idx].body_color_right; 189 controller.left_color.button_color =
190 Settings::values.players.GetValue()[controller_idx].button_color_left;
191 controller.right_color.body_color =
192 Settings::values.players.GetValue()[controller_idx].body_color_right;
190 controller.right_color.button_color = 193 controller.right_color.button_color =
191 Settings::values.players[controller_idx].button_color_right; 194 Settings::values.players.GetValue()[controller_idx].button_color_right;
192 195
193 controller.battery_level[0] = BATTERY_FULL; 196 controller.battery_level[0] = BATTERY_FULL;
194 controller.battery_level[1] = BATTERY_FULL; 197 controller.battery_level[1] = BATTERY_FULL;
@@ -218,8 +221,9 @@ void Controller_NPad::OnInit() {
218 style.pokeball.Assign(1); 221 style.pokeball.Assign(1);
219 } 222 }
220 223
221 std::transform(Settings::values.players.begin(), Settings::values.players.end(), 224 std::transform(Settings::values.players.GetValue().begin(),
222 connected_controllers.begin(), [](const Settings::PlayerInput& player) { 225 Settings::values.players.GetValue().end(), connected_controllers.begin(),
226 [](const Settings::PlayerInput& player) {
223 return ControllerHolder{MapSettingsTypeToNPad(player.controller_type), 227 return ControllerHolder{MapSettingsTypeToNPad(player.controller_type),
224 player.connected}; 228 player.connected};
225 }); 229 });
@@ -227,12 +231,13 @@ void Controller_NPad::OnInit() {
227 // Connect the Player 1 or Handheld controller if none are connected. 231 // Connect the Player 1 or Handheld controller if none are connected.
228 if (std::none_of(connected_controllers.begin(), connected_controllers.end(), 232 if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
229 [](const ControllerHolder& controller) { return controller.is_connected; })) { 233 [](const ControllerHolder& controller) { return controller.is_connected; })) {
230 const auto controller = MapSettingsTypeToNPad(Settings::values.players[0].controller_type); 234 const auto controller =
235 MapSettingsTypeToNPad(Settings::values.players.GetValue()[0].controller_type);
231 if (controller == NPadControllerType::Handheld) { 236 if (controller == NPadControllerType::Handheld) {
232 Settings::values.players[HANDHELD_INDEX].connected = true; 237 Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
233 connected_controllers[HANDHELD_INDEX] = {controller, true}; 238 connected_controllers[HANDHELD_INDEX] = {controller, true};
234 } else { 239 } else {
235 Settings::values.players[0].connected = true; 240 Settings::values.players.GetValue()[0].connected = true;
236 connected_controllers[0] = {controller, true}; 241 connected_controllers[0] = {controller, true};
237 } 242 }
238 } 243 }
@@ -255,7 +260,7 @@ void Controller_NPad::OnInit() {
255} 260}
256 261
257void Controller_NPad::OnLoadInputDevices() { 262void Controller_NPad::OnLoadInputDevices() {
258 const auto& players = Settings::values.players; 263 const auto& players = Settings::values.players.GetValue();
259 for (std::size_t i = 0; i < players.size(); ++i) { 264 for (std::size_t i = 0; i < players.size(); ++i) {
260 std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, 265 std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
261 players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END, 266 players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
@@ -528,7 +533,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
528 // Try to read sixaxis sensor states 533 // Try to read sixaxis sensor states
529 std::array<MotionDevice, 2> motion_devices; 534 std::array<MotionDevice, 2> motion_devices;
530 535
531 if (sixaxis_sensors_enabled && Settings::values.motion_enabled) { 536 if (sixaxis_sensors_enabled && Settings::values.motion_enabled.GetValue()) {
532 sixaxis_at_rest = true; 537 sixaxis_at_rest = true;
533 for (std::size_t e = 0; e < motion_devices.size(); ++e) { 538 for (std::size_t e = 0; e < motion_devices.size(); ++e) {
534 const auto& device = motions[i][e]; 539 const auto& device = motions[i][e];
@@ -666,7 +671,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controllers,
666 const std::vector<Vibration>& vibrations) { 671 const std::vector<Vibration>& vibrations) {
667 LOG_TRACE(Service_HID, "called"); 672 LOG_TRACE(Service_HID, "called");
668 673
669 if (!Settings::values.vibration_enabled || !can_controllers_vibrate) { 674 if (!Settings::values.vibration_enabled.GetValue() || !can_controllers_vibrate) {
670 return; 675 return;
671 } 676 }
672 bool success = true; 677 bool success = true;
@@ -714,16 +719,17 @@ void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::siz
714 } 719 }
715 720
716 if (controller == NPadControllerType::Handheld) { 721 if (controller == NPadControllerType::Handheld) {
717 Settings::values.players[HANDHELD_INDEX].controller_type = 722 Settings::values.players.GetValue()[HANDHELD_INDEX].controller_type =
718 MapNPadToSettingsType(controller); 723 MapNPadToSettingsType(controller);
719 Settings::values.players[HANDHELD_INDEX].connected = true; 724 Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
720 connected_controllers[HANDHELD_INDEX] = {controller, true}; 725 connected_controllers[HANDHELD_INDEX] = {controller, true};
721 InitNewlyAddedController(HANDHELD_INDEX); 726 InitNewlyAddedController(HANDHELD_INDEX);
722 return; 727 return;
723 } 728 }
724 729
725 Settings::values.players[npad_index].controller_type = MapNPadToSettingsType(controller); 730 Settings::values.players.GetValue()[npad_index].controller_type =
726 Settings::values.players[npad_index].connected = true; 731 MapNPadToSettingsType(controller);
732 Settings::values.players.GetValue()[npad_index].connected = true;
727 connected_controllers[npad_index] = {controller, true}; 733 connected_controllers[npad_index] = {controller, true};
728 InitNewlyAddedController(npad_index); 734 InitNewlyAddedController(npad_index);
729} 735}
@@ -733,7 +739,7 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
733} 739}
734 740
735void Controller_NPad::DisconnectNPadAtIndex(std::size_t npad_index) { 741void Controller_NPad::DisconnectNPadAtIndex(std::size_t npad_index) {
736 Settings::values.players[npad_index].connected = false; 742 Settings::values.players.GetValue()[npad_index].connected = false;
737 connected_controllers[npad_index].is_connected = false; 743 connected_controllers[npad_index].is_connected = false;
738 744
739 auto& controller = shared_memory_entries[npad_index]; 745 auto& controller = shared_memory_entries[npad_index];
@@ -895,7 +901,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
895 return false; 901 return false;
896 } 902 }
897 // Handheld should not be supported in docked mode 903 // Handheld should not be supported in docked mode
898 if (Settings::values.use_docked_mode) { 904 if (Settings::values.use_docked_mode.GetValue()) {
899 return false; 905 return false;
900 } 906 }
901 907
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 50f709b25..fb57dec02 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -935,7 +935,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
935void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { 935void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
936 IPC::RequestParser rp{ctx}; 936 IPC::RequestParser rp{ctx};
937 const auto can_vibrate{rp.Pop<bool>()}; 937 const auto can_vibrate{rp.Pop<bool>()};
938 Settings::values.vibration_enabled = can_vibrate; 938 Settings::values.vibration_enabled.SetValue(can_vibrate);
939 939
940 LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); 940 LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
941 941
@@ -948,7 +948,7 @@ void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
948 948
949 IPC::ResponseBuilder rb{ctx, 3}; 949 IPC::ResponseBuilder rb{ctx, 3};
950 rb.Push(RESULT_SUCCESS); 950 rb.Push(RESULT_SUCCESS);
951 rb.Push(Settings::values.vibration_enabled); 951 rb.Push(Settings::values.vibration_enabled.GetValue());
952} 952}
953 953
954void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 954void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 5b0e371fe..55e00dd93 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -771,7 +771,7 @@ private:
771 IPC::ResponseBuilder rb{ctx, 6}; 771 IPC::ResponseBuilder rb{ctx, 6};
772 rb.Push(RESULT_SUCCESS); 772 rb.Push(RESULT_SUCCESS);
773 773
774 if (Settings::values.use_docked_mode) { 774 if (Settings::values.use_docked_mode.GetValue()) {
775 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * 775 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
776 static_cast<u32>(Settings::values.resolution_factor.GetValue())); 776 static_cast<u32>(Settings::values.resolution_factor.GetValue()));
777 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * 777 rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 0587b9374..aadbc3932 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -49,7 +49,7 @@ void LogSettings() {
49 }; 49 };
50 50
51 LOG_INFO(Config, "yuzu Configuration:"); 51 LOG_INFO(Config, "yuzu Configuration:");
52 log_setting("Controls_UseDockedMode", values.use_docked_mode); 52 log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
53 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0)); 53 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
54 log_setting("System_CurrentUser", values.current_user); 54 log_setting("System_CurrentUser", values.current_user);
55 log_setting("System_LanguageIndex", values.language_index.GetValue()); 55 log_setting("System_LanguageIndex", values.language_index.GetValue());
@@ -145,6 +145,12 @@ void RestoreGlobalState() {
145 values.rng_seed.SetGlobal(true); 145 values.rng_seed.SetGlobal(true);
146 values.custom_rtc.SetGlobal(true); 146 values.custom_rtc.SetGlobal(true);
147 values.sound_index.SetGlobal(true); 147 values.sound_index.SetGlobal(true);
148
149 // Controls
150 values.players.SetGlobal(true);
151 values.use_docked_mode.SetGlobal(true);
152 values.vibration_enabled.SetGlobal(true);
153 values.motion_enabled.SetGlobal(true);
148} 154}
149 155
150void Sanitize() { 156void Sanitize() {
diff --git a/src/core/settings.h b/src/core/settings.h
index 28616a574..edd2a00ca 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -65,6 +65,38 @@ private:
65 Type local{}; 65 Type local{};
66}; 66};
67 67
68/**
69 * The InputSetting class allows for getting a reference to either the global or local members.
70 * This is required as we cannot easily modify the values of user-defined types within containers
71 * using the SetValue() member function found in the Setting class. The primary purpose of this
72 * class is to store an array of 10 PlayerInput structs for both the global and local (per-game)
73 * setting and allows for easily accessing and modifying both settings.
74 */
75template <typename Type>
76class InputSetting final {
77public:
78 InputSetting() = default;
79 explicit InputSetting(Type val) : global{val} {}
80 ~InputSetting() = default;
81 void SetGlobal(bool to_global) {
82 use_global = to_global;
83 }
84 bool UsingGlobal() const {
85 return use_global;
86 }
87 Type& GetValue(bool need_global = false) {
88 if (use_global || need_global) {
89 return global;
90 }
91 return local;
92 }
93
94private:
95 bool use_global = true;
96 Type global{};
97 Type local{};
98};
99
68struct TouchFromButtonMap { 100struct TouchFromButtonMap {
69 std::string name; 101 std::string name;
70 std::vector<std::string> buttons; 102 std::vector<std::string> buttons;
@@ -133,9 +165,17 @@ struct Values {
133 Setting<s32> sound_index; 165 Setting<s32> sound_index;
134 166
135 // Controls 167 // Controls
136 std::array<PlayerInput, 10> players; 168 InputSetting<std::array<PlayerInput, 10>> players;
169
170 Setting<bool> use_docked_mode;
137 171
138 bool use_docked_mode; 172 Setting<bool> vibration_enabled;
173
174 Setting<bool> motion_enabled;
175 std::string motion_device;
176 std::string udp_input_address;
177 u16 udp_input_port;
178 u8 udp_pad_index;
139 179
140 bool mouse_enabled; 180 bool mouse_enabled;
141 std::string mouse_device; 181 std::string mouse_device;
@@ -149,20 +189,15 @@ struct Values {
149 ButtonsRaw debug_pad_buttons; 189 ButtonsRaw debug_pad_buttons;
150 AnalogsRaw debug_pad_analogs; 190 AnalogsRaw debug_pad_analogs;
151 191
152 bool vibration_enabled;
153
154 bool motion_enabled;
155 std::string motion_device;
156 std::string touch_device;
157 TouchscreenInput touchscreen; 192 TouchscreenInput touchscreen;
158 std::atomic_bool is_device_reload_pending{true}; 193
159 bool use_touch_from_button; 194 bool use_touch_from_button;
195 std::string touch_device;
160 int touch_from_button_map_index; 196 int touch_from_button_map_index;
161 std::string udp_input_address;
162 u16 udp_input_port;
163 u8 udp_pad_index;
164 std::vector<TouchFromButtonMap> touch_from_button_maps; 197 std::vector<TouchFromButtonMap> touch_from_button_maps;
165 198
199 std::atomic_bool is_device_reload_pending{true};
200
166 // Data Storage 201 // Data Storage
167 bool use_virtual_sd; 202 bool use_virtual_sd;
168 bool gamecard_inserted; 203 bool gamecard_inserted;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index ebc19e18a..e0908186b 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -213,7 +213,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
213 Settings::values.use_assembly_shaders.GetValue()); 213 Settings::values.use_assembly_shaders.GetValue());
214 AddField(field_type, "Renderer_UseAsynchronousShaders", 214 AddField(field_type, "Renderer_UseAsynchronousShaders",
215 Settings::values.use_asynchronous_shaders.GetValue()); 215 Settings::values.use_asynchronous_shaders.GetValue());
216 AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode); 216 AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue());
217} 217}
218 218
219bool TelemetrySession::SubmitTestcase() { 219bool TelemetrySession::SubmitTestcase() {
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index ee770f315..7697fe434 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -261,26 +261,26 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
261 UpdateControllerState(index); 261 UpdateControllerState(index);
262 } 262 }
263 263
264 const bool pre_docked_mode = Settings::values.use_docked_mode; 264 const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
265 Settings::values.use_docked_mode = ui->radioDocked->isChecked(); 265 Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
266 OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode); 266 OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
267 267
268 Settings::values.vibration_enabled = ui->vibrationGroup->isChecked(); 268 Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
269} 269}
270 270
271void QtControllerSelectorDialog::LoadConfiguration() { 271void QtControllerSelectorDialog::LoadConfiguration() {
272 for (std::size_t index = 0; index < NUM_PLAYERS; ++index) { 272 for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
273 const auto connected = Settings::values.players[index].connected || 273 const auto connected = Settings::values.players.GetValue()[index].connected ||
274 (index == 0 && Settings::values.players[8].connected); 274 (index == 0 && Settings::values.players.GetValue()[8].connected);
275 player_groupboxes[index]->setChecked(connected); 275 player_groupboxes[index]->setChecked(connected);
276 connected_controller_checkboxes[index]->setChecked(connected); 276 connected_controller_checkboxes[index]->setChecked(connected);
277 emulated_controllers[index]->setCurrentIndex( 277 emulated_controllers[index]->setCurrentIndex(
278 GetIndexFromControllerType(Settings::values.players[index].controller_type)); 278 GetIndexFromControllerType(Settings::values.players.GetValue()[index].controller_type));
279 } 279 }
280 280
281 UpdateDockedState(Settings::values.players[8].connected); 281 UpdateDockedState(Settings::values.players.GetValue()[8].connected);
282 282
283 ui->vibrationGroup->setChecked(Settings::values.vibration_enabled); 283 ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
284} 284}
285 285
286void QtControllerSelectorDialog::CallConfigureInputDialog() { 286void QtControllerSelectorDialog::CallConfigureInputDialog() {
@@ -448,7 +448,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
448} 448}
449 449
450void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) { 450void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {
451 auto& player = Settings::values.players[player_index]; 451 auto& player = Settings::values.players.GetValue()[player_index];
452 452
453 player.controller_type = 453 player.controller_type =
454 GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex()); 454 GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex());
@@ -461,7 +461,7 @@ void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index)
461 } 461 }
462 462
463 // Player 1 and Handheld 463 // Player 1 and Handheld
464 auto& handheld = Settings::values.players[8]; 464 auto& handheld = Settings::values.players.GetValue()[8];
465 // If Handheld is selected, copy all the settings from Player 1 to Handheld. 465 // If Handheld is selected, copy all the settings from Player 1 to Handheld.
466 if (player.controller_type == Settings::ControllerType::Handheld) { 466 if (player.controller_type == Settings::ControllerType::Handheld) {
467 handheld = player; 467 handheld = player;
@@ -527,8 +527,8 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) {
527 ui->radioDocked->setEnabled(!is_handheld); 527 ui->radioDocked->setEnabled(!is_handheld);
528 ui->radioUndocked->setEnabled(!is_handheld); 528 ui->radioUndocked->setEnabled(!is_handheld);
529 529
530 ui->radioDocked->setChecked(Settings::values.use_docked_mode); 530 ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
531 ui->radioUndocked->setChecked(!Settings::values.use_docked_mode); 531 ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
532 532
533 // Also force into undocked mode if the controller type is handheld. 533 // Also force into undocked mode if the controller type is handheld.
534 if (is_handheld) { 534 if (is_handheld) {
@@ -571,8 +571,8 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
571 571
572 for (std::size_t index = max_supported_players; index < NUM_PLAYERS; ++index) { 572 for (std::size_t index = max_supported_players; index < NUM_PLAYERS; ++index) {
573 // Disconnect any unsupported players here and disable or hide them if applicable. 573 // Disconnect any unsupported players here and disable or hide them if applicable.
574 Settings::values.players[index].connected = false; 574 Settings::values.players.GetValue()[index].connected = false;
575 UpdateController(Settings::values.players[index].controller_type, index, false); 575 UpdateController(Settings::values.players.GetValue()[index].controller_type, index, false);
576 // Hide the player widgets when max_supported_controllers is less than or equal to 4. 576 // Hide the player widgets when max_supported_controllers is less than or equal to 4.
577 if (max_supported_players <= 4) { 577 if (max_supported_players <= 4) {
578 player_widgets[index]->hide(); 578 player_widgets[index]->hide();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 618f991b0..296c58f58 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -276,7 +276,7 @@ void Config::ReadPlayerValue(std::size_t player_index) {
276 } 276 }
277 }(); 277 }();
278 278
279 auto& player = Settings::values.players[player_index]; 279 auto& player = Settings::values.players.GetValue()[player_index];
280 280
281 if (player_prefix.isEmpty()) { 281 if (player_prefix.isEmpty()) {
282 const auto controller = static_cast<Settings::ControllerType>( 282 const auto controller = static_cast<Settings::ControllerType>(
@@ -481,7 +481,7 @@ void Config::ReadAudioValues() {
481void Config::ReadControlValues() { 481void Config::ReadControlValues() {
482 qt_config->beginGroup(QStringLiteral("Controls")); 482 qt_config->beginGroup(QStringLiteral("Controls"));
483 483
484 for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { 484 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
485 ReadPlayerValue(p); 485 ReadPlayerValue(p);
486 } 486 }
487 ReadDebugValues(); 487 ReadDebugValues();
@@ -490,11 +490,10 @@ void Config::ReadControlValues() {
490 ReadTouchscreenValues(); 490 ReadTouchscreenValues();
491 ReadMotionTouchValues(); 491 ReadMotionTouchValues();
492 492
493 Settings::values.vibration_enabled = 493 ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false);
494 ReadSetting(QStringLiteral("vibration_enabled"), true).toBool(); 494 ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
495 Settings::values.motion_enabled = ReadSetting(QStringLiteral("motion_enabled"), true).toBool(); 495 true);
496 Settings::values.use_docked_mode = 496 ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
497 ReadSetting(QStringLiteral("use_docked_mode"), false).toBool();
498 497
499 qt_config->endGroup(); 498 qt_config->endGroup();
500} 499}
@@ -976,7 +975,7 @@ void Config::SavePlayerValue(std::size_t player_index) {
976 } 975 }
977 }(); 976 }();
978 977
979 const auto& player = Settings::values.players[player_index]; 978 const auto& player = Settings::values.players.GetValue()[player_index];
980 979
981 WriteSetting(QStringLiteral("%1type").arg(player_prefix), 980 WriteSetting(QStringLiteral("%1type").arg(player_prefix),
982 static_cast<u8>(player.controller_type), 981 static_cast<u8>(player.controller_type),
@@ -1140,7 +1139,7 @@ void Config::SaveAudioValues() {
1140void Config::SaveControlValues() { 1139void Config::SaveControlValues() {
1141 qt_config->beginGroup(QStringLiteral("Controls")); 1140 qt_config->beginGroup(QStringLiteral("Controls"));
1142 1141
1143 for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { 1142 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
1144 SavePlayerValue(p); 1143 SavePlayerValue(p);
1145 } 1144 }
1146 SaveDebugValues(); 1145 SaveDebugValues();
@@ -1148,8 +1147,10 @@ void Config::SaveControlValues() {
1148 SaveTouchscreenValues(); 1147 SaveTouchscreenValues();
1149 SaveMotionTouchValues(); 1148 SaveMotionTouchValues();
1150 1149
1151 WriteSetting(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled, true); 1150 WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
1152 WriteSetting(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true); 1151 WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
1152 true);
1153 WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
1153 WriteSetting(QStringLiteral("motion_device"), 1154 WriteSetting(QStringLiteral("motion_device"),
1154 QString::fromStdString(Settings::values.motion_device), 1155 QString::fromStdString(Settings::values.motion_device),
1155 QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01")); 1156 QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"));
@@ -1157,7 +1158,6 @@ void Config::SaveControlValues() {
1157 QString::fromStdString(Settings::values.touch_device), 1158 QString::fromStdString(Settings::values.touch_device),
1158 QStringLiteral("engine:emu_window")); 1159 QStringLiteral("engine:emu_window"));
1159 WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false); 1160 WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
1160 WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
1161 1161
1162 qt_config->endGroup(); 1162 qt_config->endGroup();
1163} 1163}
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 523ece426..9a4de4c5d 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -181,12 +181,12 @@ void ConfigureInput::ApplyConfiguration() {
181 181
182 advanced->ApplyConfiguration(); 182 advanced->ApplyConfiguration();
183 183
184 const bool pre_docked_mode = Settings::values.use_docked_mode; 184 const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
185 Settings::values.use_docked_mode = ui->radioDocked->isChecked(); 185 Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
186 OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode); 186 OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
187 187
188 Settings::values.vibration_enabled = ui->vibrationGroup->isChecked(); 188 Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
189 Settings::values.motion_enabled = ui->motionGroup->isChecked(); 189 Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
190} 190}
191 191
192void ConfigureInput::changeEvent(QEvent* event) { 192void ConfigureInput::changeEvent(QEvent* event) {
@@ -203,16 +203,16 @@ void ConfigureInput::RetranslateUI() {
203 203
204void ConfigureInput::LoadConfiguration() { 204void ConfigureInput::LoadConfiguration() {
205 LoadPlayerControllerIndices(); 205 LoadPlayerControllerIndices();
206 UpdateDockedState(Settings::values.players[8].connected); 206 UpdateDockedState(Settings::values.players.GetValue()[8].connected);
207 207
208 ui->vibrationGroup->setChecked(Settings::values.vibration_enabled); 208 ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
209 ui->motionGroup->setChecked(Settings::values.motion_enabled); 209 ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
210} 210}
211 211
212void ConfigureInput::LoadPlayerControllerIndices() { 212void ConfigureInput::LoadPlayerControllerIndices() {
213 for (std::size_t i = 0; i < player_connected.size(); ++i) { 213 for (std::size_t i = 0; i < player_connected.size(); ++i) {
214 const auto connected = Settings::values.players[i].connected || 214 const auto connected = Settings::values.players.GetValue()[i].connected ||
215 (i == 0 && Settings::values.players[8].connected); 215 (i == 0 && Settings::values.players.GetValue()[8].connected);
216 player_connected[i]->setChecked(connected); 216 player_connected[i]->setChecked(connected);
217 } 217 }
218} 218}
@@ -241,8 +241,8 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) {
241 ui->radioDocked->setEnabled(!is_handheld); 241 ui->radioDocked->setEnabled(!is_handheld);
242 ui->radioUndocked->setEnabled(!is_handheld); 242 ui->radioUndocked->setEnabled(!is_handheld);
243 243
244 ui->radioDocked->setChecked(Settings::values.use_docked_mode); 244 ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
245 ui->radioUndocked->setChecked(!Settings::values.use_docked_mode); 245 ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
246 246
247 // Also force into undocked mode if the controller type is handheld. 247 // Also force into undocked mode if the controller type is handheld.
248 if (is_handheld) { 248 if (is_handheld) {
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 3715db0ab..3074be833 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -107,7 +107,7 @@ void ConfigureInputAdvanced::OnControllerButtonClick(int player_idx, int button_
107 107
108void ConfigureInputAdvanced::ApplyConfiguration() { 108void ConfigureInputAdvanced::ApplyConfiguration() {
109 for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) { 109 for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
110 auto& player = Settings::values.players[player_idx]; 110 auto& player = Settings::values.players.GetValue()[player_idx];
111 std::array<u32, 4> colors{}; 111 std::array<u32, 4> colors{};
112 std::transform(controllers_colors[player_idx].begin(), controllers_colors[player_idx].end(), 112 std::transform(controllers_colors[player_idx].begin(), controllers_colors[player_idx].end(),
113 colors.begin(), [](QColor color) { return color.rgb(); }); 113 colors.begin(), [](QColor color) { return color.rgb(); });
@@ -126,7 +126,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() {
126 126
127void ConfigureInputAdvanced::LoadConfiguration() { 127void ConfigureInputAdvanced::LoadConfiguration() {
128 for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) { 128 for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
129 auto& player = Settings::values.players[player_idx]; 129 auto& player = Settings::values.players.GetValue()[player_idx];
130 std::array<u32, 4> colors = { 130 std::array<u32, 4> colors = {
131 player.body_color_left, 131 player.body_color_left,
132 player.button_color_left, 132 player.button_color_left,
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index b4de2f6af..213a76224 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -544,7 +544,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
544ConfigureInputPlayer::~ConfigureInputPlayer() = default; 544ConfigureInputPlayer::~ConfigureInputPlayer() = default;
545 545
546void ConfigureInputPlayer::ApplyConfiguration() { 546void ConfigureInputPlayer::ApplyConfiguration() {
547 auto& player = Settings::values.players[player_index]; 547 auto& player = Settings::values.players.GetValue()[player_index];
548 auto& buttons = debug ? Settings::values.debug_pad_buttons : player.buttons; 548 auto& buttons = debug ? Settings::values.debug_pad_buttons : player.buttons;
549 auto& analogs = debug ? Settings::values.debug_pad_analogs : player.analogs; 549 auto& analogs = debug ? Settings::values.debug_pad_analogs : player.analogs;
550 550
@@ -572,7 +572,7 @@ void ConfigureInputPlayer::ApplyConfiguration() {
572 } 572 }
573 573
574 // Player 1 and Handheld 574 // Player 1 and Handheld
575 auto& handheld = Settings::values.players[HANDHELD_INDEX]; 575 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
576 // If Handheld is selected, copy all the settings from Player 1 to Handheld. 576 // If Handheld is selected, copy all the settings from Player 1 to Handheld.
577 if (player.controller_type == Settings::ControllerType::Handheld) { 577 if (player.controller_type == Settings::ControllerType::Handheld) {
578 handheld = player; 578 handheld = player;
@@ -609,7 +609,7 @@ void ConfigureInputPlayer::RetranslateUI() {
609} 609}
610 610
611void ConfigureInputPlayer::LoadConfiguration() { 611void ConfigureInputPlayer::LoadConfiguration() {
612 auto& player = Settings::values.players[player_index]; 612 auto& player = Settings::values.players.GetValue()[player_index];
613 if (debug) { 613 if (debug) {
614 std::transform(Settings::values.debug_pad_buttons.begin(), 614 std::transform(Settings::values.debug_pad_buttons.begin(),
615 Settings::values.debug_pad_buttons.end(), buttons_param.begin(), 615 Settings::values.debug_pad_buttons.end(), buttons_param.begin(),
@@ -636,7 +636,7 @@ void ConfigureInputPlayer::LoadConfiguration() {
636 ui->comboControllerType->setCurrentIndex(static_cast<int>(player.controller_type)); 636 ui->comboControllerType->setCurrentIndex(static_cast<int>(player.controller_type));
637 ui->groupConnectedController->setChecked( 637 ui->groupConnectedController->setChecked(
638 player.connected || 638 player.connected ||
639 (player_index == 0 && Settings::values.players[HANDHELD_INDEX].connected)); 639 (player_index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected));
640} 640}
641 641
642void ConfigureInputPlayer::ConnectPlayer(bool connected) { 642void ConfigureInputPlayer::ConnectPlayer(bool connected) {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 4a3dea2a5..54a46827f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -551,13 +551,14 @@ void GMainWindow::InitializeWidgets() {
551 dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); 551 dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
552 dock_status_button->setFocusPolicy(Qt::NoFocus); 552 dock_status_button->setFocusPolicy(Qt::NoFocus);
553 connect(dock_status_button, &QPushButton::clicked, [&] { 553 connect(dock_status_button, &QPushButton::clicked, [&] {
554 Settings::values.use_docked_mode = !Settings::values.use_docked_mode; 554 Settings::values.use_docked_mode.SetValue(!Settings::values.use_docked_mode.GetValue());
555 dock_status_button->setChecked(Settings::values.use_docked_mode); 555 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
556 OnDockedModeChanged(!Settings::values.use_docked_mode, Settings::values.use_docked_mode); 556 OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(),
557 Settings::values.use_docked_mode.GetValue());
557 }); 558 });
558 dock_status_button->setText(tr("DOCK")); 559 dock_status_button->setText(tr("DOCK"));
559 dock_status_button->setCheckable(true); 560 dock_status_button->setCheckable(true);
560 dock_status_button->setChecked(Settings::values.use_docked_mode); 561 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
561 statusBar()->insertPermanentWidget(0, dock_status_button); 562 statusBar()->insertPermanentWidget(0, dock_status_button);
562 563
563 // Setup ASync button 564 // Setup ASync button
@@ -796,10 +797,11 @@ void GMainWindow::InitializeHotkeys() {
796 }); 797 });
797 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this), 798 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this),
798 &QShortcut::activated, this, [&] { 799 &QShortcut::activated, this, [&] {
799 Settings::values.use_docked_mode = !Settings::values.use_docked_mode; 800 Settings::values.use_docked_mode.SetValue(
800 OnDockedModeChanged(!Settings::values.use_docked_mode, 801 !Settings::values.use_docked_mode.GetValue());
801 Settings::values.use_docked_mode); 802 OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(),
802 dock_status_button->setChecked(Settings::values.use_docked_mode); 803 Settings::values.use_docked_mode.GetValue());
804 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
803 }); 805 });
804 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this), 806 connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
805 &QShortcut::activated, this, 807 &QShortcut::activated, this,
@@ -2405,7 +2407,8 @@ void GMainWindow::MigrateConfigFiles() {
2405 const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini"))); 2407 const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini")));
2406 2408
2407 Common::FS::CreateFullPath(fmt::format("{}custom" DIR_SEP, config_dir_str)); 2409 Common::FS::CreateFullPath(fmt::format("{}custom" DIR_SEP, config_dir_str));
2408 for (QStringList::const_iterator it = config_dir_list.constBegin(); it != config_dir_list.constEnd(); ++it) { 2410 for (QStringList::const_iterator it = config_dir_list.constBegin();
2411 it != config_dir_list.constEnd(); ++it) {
2409 const auto filename = it->toStdString(); 2412 const auto filename = it->toStdString();
2410 if (filename.find_first_not_of("0123456789abcdefACBDEF", 0) < 16) { 2413 if (filename.find_first_not_of("0123456789abcdefACBDEF", 0) < 16) {
2411 continue; 2414 continue;
@@ -2477,7 +2480,7 @@ void GMainWindow::UpdateStatusBar() {
2477} 2480}
2478 2481
2479void GMainWindow::UpdateStatusButtons() { 2482void GMainWindow::UpdateStatusButtons() {
2480 dock_status_button->setChecked(Settings::values.use_docked_mode); 2483 dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
2481 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); 2484 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
2482 Settings::values.use_asynchronous_gpu_emulation.SetValue( 2485 Settings::values.use_asynchronous_gpu_emulation.SetValue(
2483 Settings::values.use_asynchronous_gpu_emulation.GetValue() || 2486 Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 334038ef9..feee02fcd 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -228,24 +228,24 @@ static const std::array<int, 8> keyboard_mods{
228 228
229void Config::ReadValues() { 229void Config::ReadValues() {
230 // Controls 230 // Controls
231 for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { 231 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
232 const auto group = fmt::format("ControlsP{}", p); 232 const auto group = fmt::format("ControlsP{}", p);
233 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 233 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
234 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); 234 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
235 Settings::values.players[p].buttons[i] = 235 Settings::values.players.GetValue()[p].buttons[i] =
236 sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param); 236 sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param);
237 if (Settings::values.players[p].buttons[i].empty()) 237 if (Settings::values.players.GetValue()[p].buttons[i].empty())
238 Settings::values.players[p].buttons[i] = default_param; 238 Settings::values.players.GetValue()[p].buttons[i] = default_param;
239 } 239 }
240 240
241 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { 241 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
242 std::string default_param = InputCommon::GenerateAnalogParamFromKeys( 242 std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
243 default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], 243 default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
244 default_analogs[i][3], default_analogs[i][4], 0.5f); 244 default_analogs[i][3], default_analogs[i][4], 0.5f);
245 Settings::values.players[p].analogs[i] = 245 Settings::values.players.GetValue()[p].analogs[i] =
246 sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param); 246 sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param);
247 if (Settings::values.players[p].analogs[i].empty()) 247 if (Settings::values.players.GetValue()[p].analogs[i].empty())
248 Settings::values.players[p].analogs[i] = default_param; 248 Settings::values.players.GetValue()[p].analogs[i] = default_param;
249 } 249 }
250 } 250 }
251 251
@@ -288,10 +288,10 @@ void Config::ReadValues() {
288 Settings::values.debug_pad_analogs[i] = default_param; 288 Settings::values.debug_pad_analogs[i] = default_param;
289 } 289 }
290 290
291 Settings::values.vibration_enabled = 291 Settings::values.vibration_enabled.SetValue(
292 sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true); 292 sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
293 Settings::values.motion_enabled = 293 Settings::values.motion_enabled.SetValue(
294 sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true); 294 sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
295 Settings::values.touchscreen.enabled = 295 Settings::values.touchscreen.enabled =
296 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true); 296 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
297 Settings::values.touchscreen.device = 297 Settings::values.touchscreen.device =
@@ -343,7 +343,8 @@ void Config::ReadValues() {
343 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); 343 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
344 344
345 // System 345 // System
346 Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); 346 Settings::values.use_docked_mode.SetValue(
347 sdl2_config->GetBoolean("System", "use_docked_mode", false));
347 const auto size = sdl2_config->GetInteger("System", "users_size", 0); 348 const auto size = sdl2_config->GetInteger("System", "users_size", 0);
348 349
349 Settings::values.current_user = std::clamp<int>( 350 Settings::values.current_user = std::clamp<int>(
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp
index bc273fb51..3a8a333f0 100644
--- a/src/yuzu_tester/config.cpp
+++ b/src/yuzu_tester/config.cpp
@@ -47,13 +47,13 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
47 47
48void Config::ReadValues() { 48void Config::ReadValues() {
49 // Controls 49 // Controls
50 for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { 50 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
51 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 51 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
52 Settings::values.players[p].buttons[i] = ""; 52 Settings::values.players.GetValue()[p].buttons[i] = "";
53 } 53 }
54 54
55 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { 55 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
56 Settings::values.players[p].analogs[i] = ""; 56 Settings::values.players.GetValue()[p].analogs[i] = "";
57 } 57 }
58 } 58 }
59 59
@@ -75,8 +75,8 @@ void Config::ReadValues() {
75 Settings::values.debug_pad_analogs[i] = ""; 75 Settings::values.debug_pad_analogs[i] = "";
76 } 76 }
77 77
78 Settings::values.vibration_enabled = true; 78 Settings::values.vibration_enabled.SetValue(true);
79 Settings::values.motion_enabled = true; 79 Settings::values.motion_enabled.SetValue(true);
80 Settings::values.touchscreen.enabled = ""; 80 Settings::values.touchscreen.enabled = "";
81 Settings::values.touchscreen.device = ""; 81 Settings::values.touchscreen.device = "";
82 Settings::values.touchscreen.finger = 0; 82 Settings::values.touchscreen.finger = 0;
@@ -84,8 +84,8 @@ void Config::ReadValues() {
84 Settings::values.touchscreen.diameter_x = 15; 84 Settings::values.touchscreen.diameter_x = 15;
85 Settings::values.touchscreen.diameter_y = 15; 85 Settings::values.touchscreen.diameter_y = 15;
86 86
87 Settings::values.use_docked_mode = 87 Settings::values.use_docked_mode.SetValue(
88 sdl2_config->GetBoolean("Controls", "use_docked_mode", false); 88 sdl2_config->GetBoolean("Controls", "use_docked_mode", false));
89 89
90 // Data Storage 90 // Data Storage
91 Settings::values.use_virtual_sd = 91 Settings::values.use_virtual_sd =