summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/settings.cpp1
-rw-r--r--src/common/settings.h114
-rw-r--r--src/core/core.cpp20
-rw-r--r--src/core/file_sys/control_metadata.cpp3
-rw-r--r--src/core/file_sys/patch_manager.cpp4
-rw-r--r--src/core/hle/service/ns/ns.cpp2
-rw-r--r--src/core/hle/service/set/set.cpp10
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp232
-rw-r--r--src/yuzu/configuration/configure_system.h17
-rw-r--r--src/yuzu/configuration/configure_system.ui509
-rw-r--r--src/yuzu/configuration/shared_translation.cpp43
-rw-r--r--src/yuzu/configuration/shared_widget.cpp179
-rw-r--r--src/yuzu/configuration/shared_widget.h13
-rw-r--r--src/yuzu_cmd/config.cpp1
18 files changed, 508 insertions, 648 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index b7a0c063f..605fe7f86 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -162,6 +162,7 @@ const char* TranslateCategory(Category category) {
162 case Category::RendererDebug: 162 case Category::RendererDebug:
163 return "Renderer"; 163 return "Renderer";
164 case Category::System: 164 case Category::System:
165 case Category::SystemAudio:
165 return "System"; 166 return "System";
166 case Category::DataStorage: 167 case Category::DataStorage:
167 return "Data Storage"; 168 return "Data Storage";
diff --git a/src/common/settings.h b/src/common/settings.h
index fdadb06a1..1f95bd7d5 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -20,6 +20,86 @@
20 20
21namespace Settings { 21namespace Settings {
22 22
23enum class Language : u32 {
24 Japanese,
25 EnglishAmerican,
26 French,
27 German,
28 Italian,
29 Spanish,
30 Chinese,
31 Korean,
32 Dutch,
33 Portuguese,
34 Russian,
35 Taiwanese,
36 EnglishBritish,
37 FrenchCanadian,
38 SpanishLatin,
39 ChineseSimplified,
40 ChineseTraditional,
41 PortugueseBrazilian,
42};
43
44enum class Region : u32 {
45 Japan,
46 USA,
47 Europe,
48 Australia,
49 China,
50 Korea,
51 Taiwan,
52};
53
54enum class TimeZone : u32 {
55 Auto,
56 Default,
57 CET,
58 CST6CDT,
59 Cuba,
60 EET,
61 Egypt,
62 Eire,
63 EST,
64 EST5EDT,
65 GB,
66 GBEire,
67 GMT,
68 GMTPlusZero,
69 GMTMinusZero,
70 GMTZero,
71 Greenwich,
72 Hongkong,
73 HST,
74 Iceland,
75 Iran,
76 Israel,
77 Jamaica,
78 Japan,
79 Kwajalein,
80 Libya,
81 MET,
82 MST,
83 MST7MDT,
84 Navajo,
85 NZ,
86 NZCHAT,
87 Poland,
88 Portugal,
89 PRC,
90 PST8PDT,
91 ROC,
92 ROK,
93 Singapore,
94 Turkey,
95 UCT,
96 Universal,
97 UTC,
98 W_SU,
99 WET,
100 Zulu,
101};
102
23enum class AnisotropyMode : u32 { 103enum class AnisotropyMode : u32 {
24 Automatic = 0, 104 Automatic = 0,
25 Default = 1, 105 Default = 1,
@@ -134,6 +214,7 @@ enum class Category : u32 {
134 RendererAdvanced, 214 RendererAdvanced,
135 RendererDebug, 215 RendererDebug,
136 System, 216 System,
217 SystemAudio,
137 DataStorage, 218 DataStorage,
138 Debugging, 219 Debugging,
139 DebuggingGraphics, 220 DebuggingGraphics,
@@ -810,22 +891,31 @@ struct Values {
810 SwitchableSetting<u8, false> bg_blue{linkage, 0, "bg_blue", Category::Renderer, true, true}; 891 SwitchableSetting<u8, false> bg_blue{linkage, 0, "bg_blue", Category::Renderer, true, true};
811 892
812 // System 893 // System
813 SwitchableSetting<bool> rng_seed_enabled{linkage, false, "rng_seed_enabled", Category::System}; 894 SwitchableSetting<bool> rng_seed_enabled{linkage, false, "rng_seed_enabled",
814 SwitchableSetting<u32> rng_seed{linkage, 0, "rng_seed", Category::System}; 895 Category::System, true, true};
815 Setting<std::string> device_name{linkage, "Yuzu", "device_name", Category::System}; 896 SwitchableSetting<u32> rng_seed{linkage, 0, "rng_seed", Category::System, true, true};
897 Setting<std::string> device_name{linkage, "Yuzu", "device_name", Category::System, true, true};
816 // Measured in seconds since epoch 898 // Measured in seconds since epoch
817 Setting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System}; 899 SwitchableSetting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled",
818 Setting<s64> custom_rtc{linkage, 0, "custom_rtc", Category::System}; 900 Category::System, true, true};
901 SwitchableSetting<s64> custom_rtc{linkage, 0, "custom_rtc", Category::System, true, true};
819 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` 902 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
820 s64 custom_rtc_differential; 903 s64 custom_rtc_differential;
821 904
822 Setting<s32> current_user{linkage, 0, "current_user", Category::System}; 905 Setting<s32> current_user{linkage, 0, "current_user", Category::System};
823 SwitchableSetting<s32, true> language_index{linkage, 1, 0, 17, "language_index", 906 SwitchableSetting<Language, true> language_index{linkage,
824 Category::System}; 907 Language::EnglishAmerican,
825 SwitchableSetting<s32, true> region_index{linkage, 1, 0, 6, "region_index", Category::System}; 908 Language::Japanese,
826 SwitchableSetting<s32, true> time_zone_index{linkage, 0, 0, 45, "time_zone_index", 909 Language::PortugueseBrazilian,
827 Category::System}; 910 "language_index",
828 SwitchableSetting<s32, true> sound_index{linkage, 1, 0, 2, "sound_index", Category::System}; 911 Category::System};
912 SwitchableSetting<Region, true> region_index{linkage, Region::USA, Region::Japan,
913 Region::Taiwan, "region_index", Category::System};
914 SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
915 TimeZone::Auto, TimeZone::Zulu,
916 "time_zone_index", Category::System};
917 SwitchableSetting<s32, true> sound_index{
918 linkage, 1, 0, 2, "sound_index", Category::SystemAudio};
829 919
830 SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System}; 920 SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System};
831 921
@@ -837,7 +927,7 @@ struct Values {
837#ifdef _WIN32 927#ifdef _WIN32
838 true 928 true
839#else 929#else
840 false 930 false
841#endif 931#endif
842 }; 932 };
843 Setting<bool> controller_navigation{linkage, true, "controller_navigation", Category::Controls}; 933 Setting<bool> controller_navigation{linkage, true, "controller_navigation", Category::Controls};
diff --git a/src/core/core.cpp b/src/core/core.cpp
index da1baa892..e2902a91f 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -145,13 +145,7 @@ struct System::Impl {
145 core_timing.SetMulticore(is_multicore); 145 core_timing.SetMulticore(is_multicore);
146 core_timing.Initialize([&system]() { system.RegisterHostThread(); }); 146 core_timing.Initialize([&system]() { system.RegisterHostThread(); });
147 147
148 const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); 148 RefreshTime();
149 const auto current_time =
150 std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
151 Settings::values.custom_rtc_differential =
152 (Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
153 : current_time) -
154 current_time;
155 149
156 // Create a default fs if one doesn't already exist. 150 // Create a default fs if one doesn't already exist.
157 if (virtual_filesystem == nullptr) { 151 if (virtual_filesystem == nullptr) {
@@ -188,6 +182,16 @@ struct System::Impl {
188 Initialize(system); 182 Initialize(system);
189 } 183 }
190 184
185 void RefreshTime() {
186 const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
187 const auto current_time =
188 std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
189 Settings::values.custom_rtc_differential =
190 (Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
191 : current_time) -
192 current_time;
193 }
194
191 void Run() { 195 void Run() {
192 std::unique_lock<std::mutex> lk(suspend_guard); 196 std::unique_lock<std::mutex> lk(suspend_guard);
193 197
@@ -1022,6 +1026,8 @@ void System::Exit() {
1022} 1026}
1023 1027
1024void System::ApplySettings() { 1028void System::ApplySettings() {
1029 impl->RefreshTime();
1030
1025 if (IsPoweredOn()) { 1031 if (IsPoweredOn()) {
1026 Renderer().RefreshBaseSettings(); 1032 Renderer().RefreshBaseSettings();
1027 } 1033 }
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index cd9ac2e75..0697c29ae 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -68,7 +68,8 @@ NACP::NACP(VirtualFile file) {
68NACP::~NACP() = default; 68NACP::~NACP() = default;
69 69
70const LanguageEntry& NACP::GetLanguageEntry() const { 70const LanguageEntry& NACP::GetLanguageEntry() const {
71 Language language = language_to_codes[Settings::values.language_index.GetValue()]; 71 Language language =
72 language_to_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
72 73
73 { 74 {
74 const auto& language_entry = raw.language_entries.at(static_cast<u8>(language)); 75 const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index d3286b352..2ba1b34a4 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -626,8 +626,8 @@ PatchManager::Metadata PatchManager::ParseControlNCA(const NCA& nca) const {
626 auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file); 626 auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file);
627 627
628 // Get language code from settings 628 // Get language code from settings
629 const auto language_code = 629 const auto language_code = Service::Set::GetLanguageCodeFromIndex(
630 Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); 630 static_cast<u32>(Settings::values.language_index.GetValue()));
631 631
632 // Convert to application language and get priority list 632 // Convert to application language and get priority list
633 const auto application_language = 633 const auto application_language =
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 376067a95..91c5a2182 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -409,7 +409,7 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
409 409
410 // Get language code from settings 410 // Get language code from settings
411 const auto language_code = 411 const auto language_code =
412 Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); 412 Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue()));
413 413
414 // Convert to application language, get priority list 414 // Convert to application language, get priority list
415 const auto application_language = ConvertToApplicationLanguage(language_code); 415 const auto application_language = ConvertToApplicationLanguage(language_code);
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index f5788b481..83f888c54 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -93,7 +93,8 @@ void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entri
93} 93}
94 94
95void GetKeyCodeMapImpl(HLERequestContext& ctx) { 95void GetKeyCodeMapImpl(HLERequestContext& ctx) {
96 const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; 96 const auto language_code =
97 available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
97 const auto key_code = 98 const auto key_code =
98 std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), 99 std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
99 [=](const auto& element) { return element.first == language_code; }); 100 [=](const auto& element) { return element.first == language_code; });
@@ -162,7 +163,7 @@ void SET::GetQuestFlag(HLERequestContext& ctx) {
162 163
163 IPC::ResponseBuilder rb{ctx, 3}; 164 IPC::ResponseBuilder rb{ctx, 3};
164 rb.Push(ResultSuccess); 165 rb.Push(ResultSuccess);
165 rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue())); 166 rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue()));
166} 167}
167 168
168void SET::GetLanguageCode(HLERequestContext& ctx) { 169void SET::GetLanguageCode(HLERequestContext& ctx) {
@@ -170,7 +171,8 @@ void SET::GetLanguageCode(HLERequestContext& ctx) {
170 171
171 IPC::ResponseBuilder rb{ctx, 4}; 172 IPC::ResponseBuilder rb{ctx, 4};
172 rb.Push(ResultSuccess); 173 rb.Push(ResultSuccess);
173 rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); 174 rb.PushEnum(
175 available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]);
174} 176}
175 177
176void SET::GetRegionCode(HLERequestContext& ctx) { 178void SET::GetRegionCode(HLERequestContext& ctx) {
@@ -178,7 +180,7 @@ void SET::GetRegionCode(HLERequestContext& ctx) {
178 180
179 IPC::ResponseBuilder rb{ctx, 3}; 181 IPC::ResponseBuilder rb{ctx, 3};
180 rb.Push(ResultSuccess); 182 rb.Push(ResultSuccess);
181 rb.Push(Settings::values.region_index.GetValue()); 183 rb.Push(static_cast<u32>(Settings::values.region_index.GetValue()));
182} 184}
183 185
184void SET::GetKeyCodeMap(HLERequestContext& ctx) { 186void SET::GetKeyCodeMap(HLERequestContext& ctx) {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 3181a9528..28ee5d492 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -696,6 +696,7 @@ void Config::ReadSystemValues() {
696 qt_config->beginGroup(QStringLiteral("System")); 696 qt_config->beginGroup(QStringLiteral("System"));
697 697
698 ReadCategory(Settings::Category::System); 698 ReadCategory(Settings::Category::System);
699 ReadCategory(Settings::Category::SystemAudio);
699 700
700 qt_config->endGroup(); 701 qt_config->endGroup();
701} 702}
@@ -1134,6 +1135,7 @@ void Config::SaveSystemValues() {
1134 qt_config->beginGroup(QStringLiteral("System")); 1135 qt_config->beginGroup(QStringLiteral("System"));
1135 1136
1136 WriteCategory(Settings::Category::System); 1137 WriteCategory(Settings::Category::System);
1138 WriteCategory(Settings::Category::SystemAudio);
1137 1139
1138 qt_config->endGroup(); 1140 qt_config->endGroup();
1139} 1141}
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 8baa8de1e..3a94fee9e 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -48,7 +48,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
48 input_tab{std::make_unique<ConfigureInput>(system_, this)}, 48 input_tab{std::make_unique<ConfigureInput>(system_, this)},
49 network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, 49 network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
50 profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)}, 50 profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
51 system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, this)}, 51 system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, *translations, this)},
52 ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>( 52 ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>(
53 this)} { 53 this)} {
54 Settings::SetConfiguringGlobal(true); 54 Settings::SetConfiguringGlobal(true);
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index ae3cf269f..977aed42d 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -240,7 +240,7 @@ void ConfigureGraphics::Setup() {
240 return new ConfigurationShared::Widget( 240 return new ConfigurationShared::Widget(
241 setting, translations, this, runtime_lock, apply_funcs, 241 setting, translations, this, runtime_lock, apply_funcs,
242 ConfigurationShared::RequestType::SpinBox, true, 1.0f, 242 ConfigurationShared::RequestType::SpinBox, true, 1.0f,
243 &Settings::values.speed_limit, QStringLiteral("%")); 243 &Settings::values.speed_limit, "%");
244 } else { 244 } else {
245 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, 245 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
246 apply_funcs); 246 apply_funcs);
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 5548fc2ba..c39855334 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -58,7 +58,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
58 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, 58 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
59 tab_group, *translations, this); 59 tab_group, *translations, this);
60 input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); 60 input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
61 system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, this); 61 system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *translations, this);
62 62
63 ui->setupUi(this); 63 ui->setupUi(this);
64 64
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 4872a475b..dedbad57f 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -2,17 +2,22 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <chrono> 4#include <chrono>
5#include <forward_list>
5#include <optional> 6#include <optional>
6 7
8#include <QDateTimeEdit>
7#include <QFileDialog> 9#include <QFileDialog>
8#include <QGraphicsItem> 10#include <QGraphicsItem>
11#include <QLineEdit>
9#include <QMessageBox> 12#include <QMessageBox>
10#include "common/settings.h" 13#include "common/settings.h"
11#include "core/core.h" 14#include "core/core.h"
12#include "core/hle/service/time/time_manager.h" 15#include "core/hle/service/time/time_manager.h"
13#include "ui_configure_system.h" 16#include "ui_configure_system.h"
17#include "yuzu/configuration/config.h"
14#include "yuzu/configuration/configuration_shared.h" 18#include "yuzu/configuration/configuration_shared.h"
15#include "yuzu/configuration/configure_system.h" 19#include "yuzu/configuration/configure_system.h"
20#include "yuzu/configuration/shared_widget.h"
16 21
17constexpr std::array<u32, 7> LOCALE_BLOCKLIST{ 22constexpr std::array<u32, 7> LOCALE_BLOCKLIST{
18 // pzzefezrpnkzeidfej 23 // pzzefezrpnkzeidfej
@@ -39,44 +44,42 @@ static bool IsValidLocale(u32 region_index, u32 language_index) {
39 44
40ConfigureSystem::ConfigureSystem( 45ConfigureSystem::ConfigureSystem(
41 Core::System& system_, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, 46 Core::System& system_, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
42 QWidget* parent) 47 ConfigurationShared::TranslationMap& translations_, QWidget* parent)
43 : Tab(group, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} { 48 : Tab(group, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_},
49 translations{translations_} {
44 ui->setupUi(this); 50 ui->setupUi(this);
45 51
46 connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) { 52 Setup();
47 ui->rng_seed_edit->setEnabled(state == Qt::Checked); 53
54 connect(rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
55 rng_seed_edit->setEnabled(state == Qt::Checked);
48 if (state != Qt::Checked) { 56 if (state != Qt::Checked) {
49 ui->rng_seed_edit->setText(QStringLiteral("00000000")); 57 rng_seed_edit->setText(QStringLiteral("00000000"));
50 } 58 }
51 }); 59 });
52 60
53 connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) { 61 connect(custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
54 ui->custom_rtc_edit->setEnabled(state == Qt::Checked); 62 custom_rtc_edit->setEnabled(state == Qt::Checked);
55 if (state != Qt::Checked) { 63 if (state != Qt::Checked) {
56 ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); 64 custom_rtc_edit->setDateTime(QDateTime::currentDateTime());
57 } 65 }
58 }); 66 });
59 67
60 const auto locale_check = [this](int index) { 68 const auto locale_check = [this](int index) {
61 const auto region_index = ConfigurationShared::GetComboboxIndex( 69 const auto region_index = combo_region->currentIndex();
62 Settings::values.region_index.GetValue(true), ui->combo_region); 70 const auto language_index = combo_language->currentIndex();
63 const auto language_index = ConfigurationShared::GetComboboxIndex(
64 Settings::values.language_index.GetValue(true), ui->combo_language);
65 const bool valid_locale = IsValidLocale(region_index, language_index); 71 const bool valid_locale = IsValidLocale(region_index, language_index);
66 ui->label_warn_invalid_locale->setVisible(!valid_locale); 72 ui->label_warn_invalid_locale->setVisible(!valid_locale);
67 if (!valid_locale) { 73 if (!valid_locale) {
68 ui->label_warn_invalid_locale->setText( 74 ui->label_warn_invalid_locale->setText(
69 tr("Warning: \"%1\" is not a valid language for region \"%2\"") 75 tr("Warning: \"%1\" is not a valid language for region \"%2\"")
70 .arg(ui->combo_language->currentText()) 76 .arg(combo_language->currentText())
71 .arg(ui->combo_region->currentText())); 77 .arg(combo_region->currentText()));
72 } 78 }
73 }; 79 };
74 80
75 connect(ui->combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, 81 connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
76 locale_check); 82 connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
77 connect(ui->combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
78
79 SetupPerGameUI();
80 83
81 SetConfiguration(); 84 SetConfiguration();
82} 85}
@@ -95,137 +98,94 @@ void ConfigureSystem::RetranslateUI() {
95 ui->retranslateUi(this); 98 ui->retranslateUi(this);
96} 99}
97 100
98void ConfigureSystem::SetConfiguration() { 101void ConfigureSystem::Setup() {
99 enabled = !system.IsPoweredOn(); 102 const bool runtime_lock = !system.IsPoweredOn();
100 const auto rng_seed = QStringLiteral("%1") 103 auto& core_layout = *ui->core_widget->layout();
101 .arg(Settings::values.rng_seed.GetValue(), 8, 16, QLatin1Char{'0'}) 104 auto& system_layout = *ui->system_widget->layout();
102 .toUpper();
103 const auto rtc_time = Settings::values.custom_rtc_enabled
104 ? Settings::values.custom_rtc.GetValue()
105 : QDateTime::currentSecsSinceEpoch();
106
107 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed_enabled.GetValue());
108 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed_enabled.GetValue() &&
109 Settings::values.rng_seed.UsingGlobal());
110 ui->rng_seed_edit->setText(rng_seed);
111
112 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc_enabled.GetValue());
113 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue());
114 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
115 ui->device_name_edit->setText(
116 QString::fromUtf8(Settings::values.device_name.GetValue().c_str()));
117 ui->use_unsafe_extended_memory_layout->setEnabled(enabled);
118 ui->use_unsafe_extended_memory_layout->setChecked(
119 Settings::values.use_unsafe_extended_memory_layout.GetValue());
120
121 if (Settings::IsConfiguringGlobal()) {
122 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
123 ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue());
124 ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue());
125 } else {
126 ConfigurationShared::SetPerGameSetting(ui->combo_language,
127 &Settings::values.language_index);
128 ConfigurationShared::SetPerGameSetting(ui->combo_region, &Settings::values.region_index);
129 ConfigurationShared::SetPerGameSetting(ui->combo_time_zone,
130 &Settings::values.time_zone_index);
131
132 ConfigurationShared::SetHighlight(ui->label_language,
133 !Settings::values.language_index.UsingGlobal());
134 ConfigurationShared::SetHighlight(ui->label_region,
135 !Settings::values.region_index.UsingGlobal());
136 ConfigurationShared::SetHighlight(ui->label_timezone,
137 !Settings::values.time_zone_index.UsingGlobal());
138 }
139}
140 105
141void ConfigureSystem::ReadSystemSettings() {} 106 std::map<std::string, QWidget*> core_hold{};
107 std::map<bool, std::map<std::string, QWidget*>> system_hold{};
142 108
143void ConfigureSystem::ApplyConfiguration() { 109 std::forward_list<Settings::BasicSetting*> settings;
144 // Allow setting custom RTC even if system is powered on, 110 auto push = [&settings](std::forward_list<Settings::BasicSetting*>& list) {
145 // to allow in-game time to be fast forwarded 111 for (auto setting : list) {
146 if (Settings::IsConfiguringGlobal()) { 112 settings.push_front(setting);
147 if (ui->custom_rtc_checkbox->isChecked()) {
148 Settings::values.custom_rtc_enabled = true;
149 Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
150 if (system.IsPoweredOn()) {
151 const s64 posix_time{Settings::values.custom_rtc.GetValue() +
152 Service::Time::TimeManager::GetExternalTimeZoneOffset()};
153 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
154 }
155 } else {
156 Settings::values.custom_rtc_enabled = false;
157 } 113 }
158 } 114 };
159 115
160 Settings::values.device_name = ui->device_name_edit->text().toStdString(); 116 push(Settings::values.linkage.by_category[Settings::Category::Core]);
117 push(Settings::values.linkage.by_category[Settings::Category::System]);
118
119 for (auto setting : settings) {
120 ConfigurationShared::Widget* widget = [=]() {
121 if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) {
122 return new ConfigurationShared::Widget(
123 setting, translations, this, runtime_lock, apply_funcs,
124 ConfigurationShared::RequestType::DateTimeEdit, true, 1.0f,
125 &Settings::values.custom_rtc);
126 } else if (setting->Id() == Settings::values.rng_seed_enabled.Id()) {
127 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
128 apply_funcs,
129 ConfigurationShared::RequestType::HexEdit,
130 true, 1.0f, &Settings::values.rng_seed);
131 } else {
132 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
133
134 apply_funcs);
135 }
136 }();
161 137
162 if (!enabled) { 138 if (!widget->Valid()) {
163 return; 139 delete widget;
164 } 140 continue;
141 }
142
143 if (setting->Id() == Settings::values.rng_seed_enabled.Id()) {
144 rng_seed_checkbox = widget->checkbox;
145 rng_seed_edit = widget->line_edit;
165 146
166 ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index, ui->combo_language); 147 if (!Settings::values.rng_seed_enabled.GetValue()) {
167 ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_index, ui->combo_region); 148 rng_seed_edit->setEnabled(false);
168 ConfigurationShared::ApplyPerGameSetting(&Settings::values.time_zone_index,
169 ui->combo_time_zone);
170 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_unsafe_extended_memory_layout,
171 ui->use_unsafe_extended_memory_layout,
172 use_unsafe_extended_memory_layout);
173
174 if (Settings::IsConfiguringGlobal()) {
175 // Guard if during game and set to game-specific value
176 if (Settings::values.rng_seed.UsingGlobal()) {
177 Settings::values.rng_seed_enabled = ui->rng_seed_checkbox->isChecked();
178 if (ui->rng_seed_checkbox->isChecked()) {
179 Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
180 } 149 }
150 } else if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) {
151 custom_rtc_checkbox = widget->checkbox;
152 custom_rtc_edit = widget->date_time_edit;
153
154 custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue());
155 } else if (setting->Id() == Settings::values.region_index.Id()) {
156
157 combo_region = widget->combobox;
158 } else if (setting->Id() == Settings::values.language_index.Id()) {
159 combo_language = widget->combobox;
181 } 160 }
182 } else { 161
183 switch (use_rng_seed) { 162 switch (setting->Category()) {
184 case ConfigurationShared::CheckState::On: 163 case Settings::Category::Core:
185 case ConfigurationShared::CheckState::Off: 164 core_hold[setting->GetLabel()] = widget;
186 Settings::values.rng_seed_enabled.SetGlobal(false);
187 Settings::values.rng_seed.SetGlobal(false);
188 if (ui->rng_seed_checkbox->isChecked()) {
189 Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
190 }
191 break;
192 case ConfigurationShared::CheckState::Global:
193 Settings::values.rng_seed_enabled.SetGlobal(true);
194 Settings::values.rng_seed.SetGlobal(true);
195 break; 165 break;
196 case ConfigurationShared::CheckState::Count: 166 case Settings::Category::System:
167 system_hold[setting->IsEnum()].insert(std::pair{setting->GetLabel(), widget});
197 break; 168 break;
169 default:
170 delete widget;
198 } 171 }
199 } 172 }
173 for (const auto& [label, widget] : core_hold) {
174 core_layout.addWidget(widget);
175 }
176 for (const auto& [label, widget] : system_hold[true]) {
177 system_layout.addWidget(widget);
178 }
179 for (const auto& [label, widget] : system_hold[false]) {
180 system_layout.addWidget(widget);
181 }
200} 182}
201 183
202void ConfigureSystem::SetupPerGameUI() { 184void ConfigureSystem::SetConfiguration() {}
203 if (Settings::IsConfiguringGlobal()) {
204 ui->combo_language->setEnabled(Settings::values.language_index.UsingGlobal());
205 ui->combo_region->setEnabled(Settings::values.region_index.UsingGlobal());
206 ui->combo_time_zone->setEnabled(Settings::values.time_zone_index.UsingGlobal());
207 ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal());
208 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal());
209 185
210 return; 186void ConfigureSystem::ApplyConfiguration() {
187 const bool powered_on = system.IsPoweredOn();
188 for (const auto& func : apply_funcs) {
189 func(powered_on);
211 } 190 }
212
213 ConfigurationShared::SetColoredComboBox(ui->combo_language, ui->label_language,
214 Settings::values.language_index.GetValue(true));
215 ConfigurationShared::SetColoredComboBox(ui->combo_region, ui->label_region,
216 Settings::values.region_index.GetValue(true));
217 ConfigurationShared::SetColoredComboBox(ui->combo_time_zone, ui->label_timezone,
218 Settings::values.time_zone_index.GetValue(true));
219
220 ConfigurationShared::SetColoredTristate(
221 ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(),
222 Settings::values.rng_seed_enabled.GetValue(),
223 Settings::values.rng_seed_enabled.GetValue(true), use_rng_seed);
224
225 ConfigurationShared::SetColoredTristate(ui->use_unsafe_extended_memory_layout,
226 Settings::values.use_unsafe_extended_memory_layout,
227 use_unsafe_extended_memory_layout);
228
229 ui->custom_rtc_checkbox->setVisible(false);
230 ui->custom_rtc_edit->setVisible(false);
231} 191}
diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h
index 6064b5b40..87b575060 100644
--- a/src/yuzu/configuration/configure_system.h
+++ b/src/yuzu/configuration/configure_system.h
@@ -3,11 +3,15 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <forward_list>
7#include <functional>
6#include <memory> 8#include <memory>
7 9
8#include <QWidget> 10#include <QWidget>
9#include "yuzu/configuration/configuration_shared.h" 11#include "yuzu/configuration/configuration_shared.h"
10 12
13class QDateTimeEdit;
14
11namespace Core { 15namespace Core {
12class System; 16class System;
13} 17}
@@ -20,6 +24,7 @@ class ConfigureSystem : public ConfigurationShared::Tab {
20public: 24public:
21 explicit ConfigureSystem(Core::System& system_, 25 explicit ConfigureSystem(Core::System& system_,
22 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, 26 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
27 ConfigurationShared::TranslationMap& translations,
23 QWidget* parent = nullptr); 28 QWidget* parent = nullptr);
24 ~ConfigureSystem() override; 29 ~ConfigureSystem() override;
25 30
@@ -30,9 +35,9 @@ private:
30 void changeEvent(QEvent* event) override; 35 void changeEvent(QEvent* event) override;
31 void RetranslateUI(); 36 void RetranslateUI();
32 37
33 void ReadSystemSettings(); 38 void Setup();
34 39
35 void SetupPerGameUI(); 40 std::forward_list<std::function<void(bool)>> apply_funcs{};
36 41
37 std::unique_ptr<Ui::ConfigureSystem> ui; 42 std::unique_ptr<Ui::ConfigureSystem> ui;
38 bool enabled = false; 43 bool enabled = false;
@@ -41,4 +46,12 @@ private:
41 ConfigurationShared::CheckState use_unsafe_extended_memory_layout; 46 ConfigurationShared::CheckState use_unsafe_extended_memory_layout;
42 47
43 Core::System& system; 48 Core::System& system;
49 ConfigurationShared::TranslationMap& translations;
50
51 QCheckBox* rng_seed_checkbox;
52 QLineEdit* rng_seed_edit;
53 QCheckBox* custom_rtc_checkbox;
54 QDateTimeEdit* custom_rtc_edit;
55 QComboBox* combo_region;
56 QComboBox* combo_language;
44}; 57};
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index e0caecd5e..a5a3e2dc3 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -6,7 +6,7 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>366</width> 9 <width>605</width>
10 <height>483</height> 10 <height>483</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
@@ -22,470 +22,53 @@
22 <item> 22 <item>
23 <widget class="QGroupBox" name="group_system_settings"> 23 <widget class="QGroupBox" name="group_system_settings">
24 <property name="title"> 24 <property name="title">
25 <string>System Settings</string> 25 <string>System</string>
26 </property> 26 </property>
27 <layout class="QVBoxLayout" name="verticalLayout_2"> 27 <layout class="QVBoxLayout" name="verticalLayout_2">
28 <item> 28 <item>
29 <layout class="QGridLayout" name="gridLayout_2"> 29 <widget class="QWidget" name="system_widget" native="true">
30 <item row="1" column="0"> 30 <layout class="QVBoxLayout" name="verticalLayout_3">
31 <widget class="QLabel" name="label_region"> 31 <property name="leftMargin">
32 <property name="text"> 32 <number>0</number>
33 <string>Region:</string> 33 </property>
34 </property> 34 <property name="topMargin">
35 </widget> 35 <number>0</number>
36 </item> 36 </property>
37 <item row="2" column="1"> 37 <property name="rightMargin">
38 <widget class="QComboBox" name="combo_time_zone"> 38 <number>0</number>
39 <item> 39 </property>
40 <property name="text"> 40 <property name="bottomMargin">
41 <string>Auto</string> 41 <number>0</number>
42 </property> 42 </property>
43 </item> 43 </layout>
44 <item> 44 </widget>
45 <property name="text"> 45 </item>
46 <string>Default</string> 46 </layout>
47 </property> 47 </widget>
48 </item> 48 </item>
49 <item> 49 <item>
50 <property name="text"> 50 <widget class="QGroupBox" name="groupBox">
51 <string>CET</string> 51 <property name="title">
52 </property> 52 <string>Core</string>
53 </item> 53 </property>
54 <item> 54 <layout class="QVBoxLayout" name="verticalLayout_6">
55 <property name="text"> 55 <item>
56 <string>CST6CDT</string> 56 <widget class="QWidget" name="core_widget" native="true">
57 </property> 57 <layout class="QVBoxLayout" name="verticalLayout_5">
58 </item> 58 <property name="leftMargin">
59 <item> 59 <number>0</number>
60 <property name="text"> 60 </property>
61 <string>Cuba</string> 61 <property name="topMargin">
62 </property> 62 <number>0</number>
63 </item> 63 </property>
64 <item> 64 <property name="rightMargin">
65 <property name="text"> 65 <number>0</number>
66 <string>EET</string> 66 </property>
67 </property> 67 <property name="bottomMargin">
68 </item> 68 <number>0</number>
69 <item> 69 </property>
70 <property name="text"> 70 </layout>
71 <string>Egypt</string> 71 </widget>
72 </property>
73 </item>
74 <item>
75 <property name="text">
76 <string>Eire</string>
77 </property>
78 </item>
79 <item>
80 <property name="text">
81 <string>EST</string>
82 </property>
83 </item>
84 <item>
85 <property name="text">
86 <string>EST5EDT</string>
87 </property>
88 </item>
89 <item>
90 <property name="text">
91 <string>GB</string>
92 </property>
93 </item>
94 <item>
95 <property name="text">
96 <string>GB-Eire</string>
97 </property>
98 </item>
99 <item>
100 <property name="text">
101 <string>GMT</string>
102 </property>
103 </item>
104 <item>
105 <property name="text">
106 <string>GMT+0</string>
107 </property>
108 </item>
109 <item>
110 <property name="text">
111 <string>GMT-0</string>
112 </property>
113 </item>
114 <item>
115 <property name="text">
116 <string>GMT0</string>
117 </property>
118 </item>
119 <item>
120 <property name="text">
121 <string>Greenwich</string>
122 </property>
123 </item>
124 <item>
125 <property name="text">
126 <string>Hongkong</string>
127 </property>
128 </item>
129 <item>
130 <property name="text">
131 <string>HST</string>
132 </property>
133 </item>
134 <item>
135 <property name="text">
136 <string>Iceland</string>
137 </property>
138 </item>
139 <item>
140 <property name="text">
141 <string>Iran</string>
142 </property>
143 </item>
144 <item>
145 <property name="text">
146 <string>Israel</string>
147 </property>
148 </item>
149 <item>
150 <property name="text">
151 <string>Jamaica</string>
152 </property>
153 </item>
154 <item>
155 <property name="text">
156 <string>Japan</string>
157 </property>
158 </item>
159 <item>
160 <property name="text">
161 <string>Kwajalein</string>
162 </property>
163 </item>
164 <item>
165 <property name="text">
166 <string>Libya</string>
167 </property>
168 </item>
169 <item>
170 <property name="text">
171 <string>MET</string>
172 </property>
173 </item>
174 <item>
175 <property name="text">
176 <string>MST</string>
177 </property>
178 </item>
179 <item>
180 <property name="text">
181 <string>MST7MDT</string>
182 </property>
183 </item>
184 <item>
185 <property name="text">
186 <string>Navajo</string>
187 </property>
188 </item>
189 <item>
190 <property name="text">
191 <string>NZ</string>
192 </property>
193 </item>
194 <item>
195 <property name="text">
196 <string>NZ-CHAT</string>
197 </property>
198 </item>
199 <item>
200 <property name="text">
201 <string>Poland</string>
202 </property>
203 </item>
204 <item>
205 <property name="text">
206 <string>Portugal</string>
207 </property>
208 </item>
209 <item>
210 <property name="text">
211 <string>PRC</string>
212 </property>
213 </item>
214 <item>
215 <property name="text">
216 <string>PST8PDT</string>
217 </property>
218 </item>
219 <item>
220 <property name="text">
221 <string>ROC</string>
222 </property>
223 </item>
224 <item>
225 <property name="text">
226 <string>ROK</string>
227 </property>
228 </item>
229 <item>
230 <property name="text">
231 <string>Singapore</string>
232 </property>
233 </item>
234 <item>
235 <property name="text">
236 <string>Turkey</string>
237 </property>
238 </item>
239 <item>
240 <property name="text">
241 <string>UCT</string>
242 </property>
243 </item>
244 <item>
245 <property name="text">
246 <string>Universal</string>
247 </property>
248 </item>
249 <item>
250 <property name="text">
251 <string>UTC</string>
252 </property>
253 </item>
254 <item>
255 <property name="text">
256 <string>W-SU</string>
257 </property>
258 </item>
259 <item>
260 <property name="text">
261 <string>WET</string>
262 </property>
263 </item>
264 <item>
265 <property name="text">
266 <string>Zulu</string>
267 </property>
268 </item>
269 </widget>
270 </item>
271 <item row="1" column="1">
272 <widget class="QComboBox" name="combo_region">
273 <item>
274 <property name="text">
275 <string>Japan</string>
276 </property>
277 </item>
278 <item>
279 <property name="text">
280 <string>USA</string>
281 </property>
282 </item>
283 <item>
284 <property name="text">
285 <string>Europe</string>
286 </property>
287 </item>
288 <item>
289 <property name="text">
290 <string>Australia</string>
291 </property>
292 </item>
293 <item>
294 <property name="text">
295 <string>China</string>
296 </property>
297 </item>
298 <item>
299 <property name="text">
300 <string>Korea</string>
301 </property>
302 </item>
303 <item>
304 <property name="text">
305 <string>Taiwan</string>
306 </property>
307 </item>
308 </widget>
309 </item>
310 <item row="2" column="0">
311 <widget class="QLabel" name="label_timezone">
312 <property name="text">
313 <string>Time Zone:</string>
314 </property>
315 </widget>
316 </item>
317 <item row="0" column="1">
318 <widget class="QComboBox" name="combo_language">
319 <property name="toolTip">
320 <string>Note: this can be overridden when region setting is auto-select</string>
321 </property>
322 <item>
323 <property name="text">
324 <string>Japanese (日本語)</string>
325 </property>
326 </item>
327 <item>
328 <property name="text">
329 <string>American English</string>
330 </property>
331 </item>
332 <item>
333 <property name="text">
334 <string>French (français)</string>
335 </property>
336 </item>
337 <item>
338 <property name="text">
339 <string>German (Deutsch)</string>
340 </property>
341 </item>
342 <item>
343 <property name="text">
344 <string>Italian (italiano)</string>
345 </property>
346 </item>
347 <item>
348 <property name="text">
349 <string>Spanish (español)</string>
350 </property>
351 </item>
352 <item>
353 <property name="text">
354 <string>Chinese</string>
355 </property>
356 </item>
357 <item>
358 <property name="text">
359 <string>Korean (한국어)</string>
360 </property>
361 </item>
362 <item>
363 <property name="text">
364 <string>Dutch (Nederlands)</string>
365 </property>
366 </item>
367 <item>
368 <property name="text">
369 <string>Portuguese (português)</string>
370 </property>
371 </item>
372 <item>
373 <property name="text">
374 <string>Russian (Русский)</string>
375 </property>
376 </item>
377 <item>
378 <property name="text">
379 <string>Taiwanese</string>
380 </property>
381 </item>
382 <item>
383 <property name="text">
384 <string>British English</string>
385 </property>
386 </item>
387 <item>
388 <property name="text">
389 <string>Canadian French</string>
390 </property>
391 </item>
392 <item>
393 <property name="text">
394 <string>Latin American Spanish</string>
395 </property>
396 </item>
397 <item>
398 <property name="text">
399 <string>Simplified Chinese</string>
400 </property>
401 </item>
402 <item>
403 <property name="text">
404 <string>Traditional Chinese (正體中文)</string>
405 </property>
406 </item>
407 <item>
408 <property name="text">
409 <string>Brazilian Portuguese (português do Brasil)</string>
410 </property>
411 </item>
412 </widget>
413 </item>
414 <item row="4" column="0">
415 <widget class="QCheckBox" name="custom_rtc_checkbox">
416 <property name="text">
417 <string>Custom RTC</string>
418 </property>
419 </widget>
420 </item>
421 <item row="0" column="0">
422 <widget class="QLabel" name="label_language">
423 <property name="text">
424 <string>Language</string>
425 </property>
426 </widget>
427 </item>
428 <item row="5" column="0">
429 <widget class="QCheckBox" name="rng_seed_checkbox">
430 <property name="text">
431 <string>RNG Seed</string>
432 </property>
433 </widget>
434 </item>
435 <item row="6" column="0">
436 <widget class="QLabel" name="device_name_label">
437 <property name="text">
438 <string>Device Name</string>
439 </property>
440 </widget>
441 </item>
442 <item row="4" column="1">
443 <widget class="QDateTimeEdit" name="custom_rtc_edit">
444 <property name="minimumDate">
445 <date>
446 <year>1970</year>
447 <month>1</month>
448 <day>1</day>
449 </date>
450 </property>
451 </widget>
452 </item>
453 <item row="6" column="1">
454 <widget class="QLineEdit" name="device_name_edit">
455 <property name="maxLength">
456 <number>128</number>
457 </property>
458 </widget>
459 </item>
460 <item row="5" column="1">
461 <widget class="QLineEdit" name="rng_seed_edit">
462 <property name="sizePolicy">
463 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
464 <horstretch>0</horstretch>
465 <verstretch>0</verstretch>
466 </sizepolicy>
467 </property>
468 <property name="font">
469 <font>
470 <family>Lucida Console</family>
471 </font>
472 </property>
473 <property name="inputMask">
474 <string notr="true">HHHHHHHH</string>
475 </property>
476 <property name="maxLength">
477 <number>8</number>
478 </property>
479 </widget>
480 </item>
481 <item row="7" column="0">
482 <widget class="QCheckBox" name="use_unsafe_extended_memory_layout">
483 <property name="text">
484 <string>Unsafe extended memory layout (8GB DRAM)</string>
485 </property>
486 </widget>
487 </item>
488 </layout>
489 </item> 72 </item>
490 </layout> 73 </layout>
491 </widget> 74 </widget>
@@ -506,7 +89,7 @@
506 <item> 89 <item>
507 <widget class="QLabel" name="label_warn_invalid_locale"> 90 <widget class="QLabel" name="label_warn_invalid_locale">
508 <property name="text"> 91 <property name="text">
509 <string></string> 92 <string/>
510 </property> 93 </property>
511 <property name="wordWrap"> 94 <property name="wordWrap">
512 <bool>true</bool> 95 <bool>true</bool>
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index d38815e77..dc9f15cdd 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -109,15 +109,16 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
109 109
110 // System 110 // System
111 INSERT(Settings, rng_seed_enabled, "RNG Seed", ""); 111 INSERT(Settings, rng_seed_enabled, "RNG Seed", "");
112 INSERT(Settings, rng_seed, "RNG Seed", ""); 112 INSERT(Settings, rng_seed, "", "");
113 INSERT(Settings, device_name, "Device Name", ""); 113 INSERT(Settings, device_name, "Device Name", "");
114 INSERT(Settings, custom_rtc_enabled, "Custom RTC", ""); 114 INSERT(Settings, custom_rtc_enabled, "Custom RTC", "");
115 INSERT(Settings, custom_rtc, "Custom RTC", ""); 115 INSERT(Settings, custom_rtc, "", "");
116 INSERT(Settings, language_index, "Language:", ""); 116 INSERT(Settings, language_index, "Language:", "");
117 INSERT(Settings, region_index, "Region:", ""); 117 INSERT(Settings, region_index, "Region:", "");
118 INSERT(Settings, time_zone_index, "Time Zone:", ""); 118 INSERT(Settings, time_zone_index, "Time Zone:", "");
119 INSERT(Settings, sound_index, "Sound Output Mode:", ""); 119 INSERT(Settings, sound_index, "Sound Output Mode:", "");
120 INSERT(Settings, use_docked_mode, "", ""); 120 INSERT(Settings, use_docked_mode, "", "");
121 INSERT(Settings, current_user, "", "");
121 122
122 // Controls 123 // Controls
123 124
@@ -231,6 +232,44 @@ std::forward_list<QString> ComboboxEnumeration(std::type_index type, QWidget* pa
231 return { 232 return {
232 tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"), 233 tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"),
233 }; 234 };
235 } else if (type == typeid(Settings::Language)) {
236 return {
237 tr("Japanese (日本語)"),
238 tr("American English"),
239 tr("French (français)"),
240 tr("German (Deutsch)"),
241 tr("Italian (italiano)"),
242 tr("Spanish (español)"),
243 tr("Chinese"),
244 tr("Korean (한국어)"),
245 tr("Dutch (Nederlands)"),
246 tr("Portuguese (português)"),
247 tr("Russian (Русский)"),
248 tr("Taiwanese"),
249 tr("British English"),
250 tr("Canadian French"),
251 tr("Latin American Spanish"),
252 tr("Simplified Chinese"),
253 tr("Traditional Chinese (正體中文)"),
254 tr("Brazilian Portuguese (português do Brasil)"),
255 };
256 } else if (type == typeid(Settings::Region)) {
257 return {
258 tr("Japan"), tr("USA"), tr("Europe"), tr("Australia"),
259 tr("China"), tr("Korea"), tr("Taiwan"),
260 };
261 } else if (type == typeid(Settings::TimeZone)) {
262 return {
263 tr("Auto"), tr("Default"), tr("CET"), tr("CST6CDT"), tr("Cuba"),
264 tr("EET"), tr("Egypt"), tr("Eire"), tr("EST"), tr("EST5EDT"),
265 tr("GB"), tr("GB-Eire"), tr("GMT"), tr("GMT+0"), tr("GMT-0"),
266 tr("GMT0"), tr("Greenwich"), tr("Hongkong"), tr("HST"), tr("Iceland"),
267 tr("Iran"), tr("Israel"), tr("Jamaica"), tr("Kwajalein"), tr("Libya"),
268 tr("MET"), tr("MST"), tr("MST7MDT"), tr("Navajo"), tr("NZ"),
269 tr("NZ-CHAT"), tr("Poland"), tr("Portugal"), tr("PRC"), tr("PST8PDT"),
270 tr("ROC"), tr("ROK"), tr("Singapore"), tr("Turkey"), tr("UCT"),
271 tr("W-SU"), tr("WET"), tr("Zulu"),
272 };
234 } 273 }
235 274
236 return {}; 275 return {};
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp
index d1113f793..0d553c67f 100644
--- a/src/yuzu/configuration/shared_widget.cpp
+++ b/src/yuzu/configuration/shared_widget.cpp
@@ -1,5 +1,7 @@
1#include <functional> 1#include <functional>
2#include <limits>
2#include <QCheckBox> 3#include <QCheckBox>
4#include <QDateTimeEdit>
3#include <QHBoxLayout> 5#include <QHBoxLayout>
4#include <QIcon> 6#include <QIcon>
5#include <QLabel> 7#include <QLabel>
@@ -9,6 +11,9 @@
9#include <QSpinBox> 11#include <QSpinBox>
10#include <QWidget> 12#include <QWidget>
11#include <qabstractbutton.h> 13#include <qabstractbutton.h>
14#include <qabstractspinbox.h>
15#include <qnamespace.h>
16#include <qvalidator.h>
12#include "common/common_types.h" 17#include "common/common_types.h"
13#include "common/settings.h" 18#include "common/settings.h"
14#include "yuzu/configuration/configuration_shared.h" 19#include "yuzu/configuration/configuration_shared.h"
@@ -25,7 +30,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting,
25 QStyle* style = parent->style(); 30 QStyle* style = parent->style();
26 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); 31 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
27 QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); 32 QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent);
28 restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); 33 restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
29 34
30 QSizePolicy sp_retain = restore_button->sizePolicy(); 35 QSizePolicy sp_retain = restore_button->sizePolicy();
31 sp_retain.setRetainSizeWhenHidden(true); 36 sp_retain.setRetainSizeWhenHidden(true);
@@ -241,6 +246,67 @@ void Widget::CreateSlider(const QString& name, bool reversed, float multiplier,
241 } 246 }
242} 247}
243 248
249void Widget::CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting,
250 std::function<void()>& load_func) {
251 if (other_setting == nullptr) {
252 LOG_WARNING(Frontend, "Extra setting is null or not an integer");
253 return;
254 }
255 created = true;
256
257 std::function<void()> checkbox_load_func;
258 CreateCheckBox(label, checkbox_load_func);
259
260 auto to_hex = [=](const std::string& input) {
261 return QString::fromStdString(fmt::format("{:08x}", std::stoi(input)));
262 };
263
264 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
265 const QString default_val = to_hex(other_setting->ToString());
266
267 line_edit = new QLineEdit(this);
268 line_edit->setText(default_val);
269
270 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
271
272 layout->insertWidget(1, line_edit);
273
274 line_edit->setMaxLength(8);
275 QRegExpValidator* regex =
276 new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit};
277 line_edit->setValidator(regex);
278
279 auto hex_to_dec = [=]() -> std::string {
280 return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
281 };
282
283 if (Settings::IsConfiguringGlobal()) {
284 load_func = [=]() {
285 checkbox_load_func();
286 other_setting->LoadString(hex_to_dec());
287 };
288 } else {
289 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
290 line_edit->setText(to_hex(other_setting->ToStringGlobal()));
291 });
292
293 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) {
294 restore_button->setEnabled(true);
295 restore_button->setVisible(true);
296 });
297
298 load_func = [=]() {
299 checkbox_load_func();
300
301 const bool using_global = !restore_button->isEnabled();
302 other_setting->SetGlobal(using_global);
303 if (!using_global) {
304 other_setting->LoadString(hex_to_dec());
305 }
306 };
307 }
308}
309
244void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, 310void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting,
245 std::function<void()>& load_func) { 311 std::function<void()>& load_func) {
246 if (other_setting == nullptr) { 312 if (other_setting == nullptr) {
@@ -268,8 +334,9 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
268 other_setting->LoadString(line_edit->text().toStdString()); 334 other_setting->LoadString(line_edit->text().toStdString());
269 }; 335 };
270 } else { 336 } else {
271 QObject::connect(restore_button, &QAbstractButton::clicked, 337 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
272 [=](bool) { line_edit->setText(default_val); }); 338 line_edit->setText(QString::fromStdString(other_setting->ToStringGlobal()));
339 });
273 340
274 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { 341 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) {
275 restore_button->setEnabled(true); 342 restore_button->setEnabled(true);
@@ -279,7 +346,7 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
279 load_func = [=]() { 346 load_func = [=]() {
280 checkbox_load_func(); 347 checkbox_load_func();
281 348
282 const bool using_global = !restore_button->isVisible(); 349 const bool using_global = !restore_button->isEnabled();
283 other_setting->SetGlobal(using_global); 350 other_setting->SetGlobal(using_global);
284 if (!using_global) { 351 if (!using_global) {
285 other_setting->LoadString(line_edit->text().toStdString()); 352 other_setting->LoadString(line_edit->text().toStdString());
@@ -289,7 +356,8 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
289} 356}
290 357
291void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, 358void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting,
292 std::function<void()>& load_func, const QString& suffix) { 359 std::function<void()>& load_func,
360 const std::string& suffix) {
293 if (other_setting == nullptr && IsInt(other_setting->TypeId())) { 361 if (other_setting == nullptr && IsInt(other_setting->TypeId())) {
294 LOG_WARNING(Frontend, "Extra setting is null or not an integer"); 362 LOG_WARNING(Frontend, "Extra setting is null or not an integer");
295 return; 363 return;
@@ -308,7 +376,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
308 const int default_val = std::stoi(other_setting->ToString()); 376 const int default_val = std::stoi(other_setting->ToString());
309 spinbox->setRange(min_val, max_val); 377 spinbox->setRange(min_val, max_val);
310 spinbox->setValue(default_val); 378 spinbox->setValue(default_val);
311 spinbox->setSuffix(suffix); 379 spinbox->setSuffix(QString::fromStdString(suffix));
312 spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 380 spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
313 381
314 layout->insertWidget(1, spinbox); 382 layout->insertWidget(1, spinbox);
@@ -320,7 +388,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
320 }; 388 };
321 } else { 389 } else {
322 QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) { 390 QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) {
323 spinbox->setValue(std::stoi(other_setting->ToString())); 391 spinbox->setValue(std::stoi(other_setting->ToStringGlobal()));
324 }); 392 });
325 393
326 QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) { 394 QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) {
@@ -331,7 +399,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
331 load_func = [=]() { 399 load_func = [=]() {
332 checkbox_load_func(); 400 checkbox_load_func();
333 401
334 const bool using_global = !restore_button->isVisible(); 402 const bool using_global = !restore_button->isEnabled();
335 other_setting->SetGlobal(using_global); 403 other_setting->SetGlobal(using_global);
336 if (!using_global) { 404 if (!using_global) {
337 other_setting->LoadString(std::to_string(spinbox->value())); 405 other_setting->LoadString(std::to_string(spinbox->value()));
@@ -340,6 +408,81 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
340 } 408 }
341} 409}
342 410
411// Currently tailored to custom_rtc
412void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label,
413 Settings::BasicSetting* other_setting,
414 std::function<void()>& load_func) {
415 if (other_setting == nullptr) {
416 LOG_WARNING(Frontend, "Extra setting is null or not an integer");
417 return;
418 }
419 created = true;
420
421 std::function<void()> checkbox_load_func;
422 CreateCheckBox(label, checkbox_load_func);
423
424 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
425 const bool disabled = setting.ToString() != "true";
426 const long long current_time = QDateTime::currentSecsSinceEpoch();
427 const s64 the_time = disabled ? current_time : std::stoll(other_setting->ToString());
428 const auto default_val = QDateTime::fromSecsSinceEpoch(the_time);
429
430 date_time_edit = new QDateTimeEdit(this);
431 date_time_edit->setDateTime(default_val);
432
433 date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0));
434
435 date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
436 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
437
438 layout->insertWidget(1, date_time_edit);
439
440 if (Settings::IsConfiguringGlobal()) {
441 load_func = [=]() {
442 checkbox_load_func();
443 if (checkbox->checkState() == Qt::Unchecked) {
444 return;
445 }
446
447 other_setting->LoadString(
448 std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()));
449 };
450 } else {
451 auto get_clear_val = [=]() {
452 return QDateTime::fromSecsSinceEpoch([=]() {
453 if (checkbox->checkState() == Qt::Checked) {
454 return std::stoll(other_setting->ToStringGlobal());
455 }
456 return current_time;
457 }());
458 };
459
460 QObject::connect(restore_button, &QAbstractButton::clicked,
461 [=](bool) { date_time_edit->setDateTime(get_clear_val()); });
462
463 QObject::connect(date_time_edit, &QDateTimeEdit::editingFinished, [=]() {
464 if (date_time_edit->dateTime() != get_clear_val()) {
465 restore_button->setEnabled(true);
466 restore_button->setVisible(true);
467 }
468 });
469
470 load_func = [=]() {
471 checkbox_load_func();
472 if (checkbox->checkState() == Qt::Unchecked) {
473 return;
474 }
475
476 const bool using_global = !restore_button->isEnabled();
477 other_setting->SetGlobal(using_global);
478 if (!using_global) {
479 other_setting->LoadString(
480 std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()));
481 }
482 };
483 }
484}
485
343bool Widget::Valid() { 486bool Widget::Valid() {
344 return created; 487 return created;
345} 488}
@@ -350,7 +493,7 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
350 QWidget* parent_, bool runtime_lock, 493 QWidget* parent_, bool runtime_lock,
351 std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request, 494 std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request,
352 bool managed, float multiplier, Settings::BasicSetting* other_setting, 495 bool managed, float multiplier, Settings::BasicSetting* other_setting,
353 const QString& format) 496 const std::string& string)
354 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} { 497 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} {
355 if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { 498 if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
356 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); 499 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
@@ -379,19 +522,26 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
379 522
380 if (type == typeid(bool)) { 523 if (type == typeid(bool)) {
381 switch (request) { 524 switch (request) {
382 case RequestType::SpinBox:
383 CreateCheckBoxWithSpinBox(label, other_setting, load_func, format);
384 break;
385 case RequestType::Default: 525 case RequestType::Default:
386 CreateCheckBox(label, load_func); 526 CreateCheckBox(label, load_func);
387 break; 527 break;
528 case RequestType::SpinBox:
529 CreateCheckBoxWithSpinBox(label, other_setting, load_func, string);
530 break;
531 case RequestType::HexEdit:
532 CreateCheckBoxWithHexEdit(label, other_setting, load_func);
533 break;
388 case RequestType::LineEdit: 534 case RequestType::LineEdit:
389 CreateCheckBoxWithLineEdit(label, other_setting, load_func); 535 CreateCheckBoxWithLineEdit(label, other_setting, load_func);
390 break; 536 break;
537 case RequestType::DateTimeEdit:
538 CreateCheckBoxWithDateTimeEdit(label, other_setting, load_func);
539 break;
391 case RequestType::ComboBox: 540 case RequestType::ComboBox:
392 case RequestType::Slider: 541 case RequestType::Slider:
393 case RequestType::ReverseSlider: 542 case RequestType::ReverseSlider:
394 case RequestType::MaxEnum: 543 case RequestType::MaxEnum:
544 LOG_DEBUG(Frontend, "Requested widget is unimplemented.");
395 break; 545 break;
396 } 546 }
397 } else if (setting.IsEnum()) { 547 } else if (setting.IsEnum()) {
@@ -409,10 +559,15 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
409 case RequestType::ComboBox: 559 case RequestType::ComboBox:
410 CreateCombobox(label, managed, load_func); 560 CreateCombobox(label, managed, load_func);
411 break; 561 break;
562 case RequestType::DateTimeEdit:
412 case RequestType::SpinBox: 563 case RequestType::SpinBox:
564 case RequestType::HexEdit:
413 case RequestType::MaxEnum: 565 case RequestType::MaxEnum:
566 LOG_DEBUG(Frontend, "Requested widget is unimplemented.");
414 break; 567 break;
415 } 568 }
569 } else if (type == typeid(std::string)) {
570 CreateLineEdit(label, managed, load_func);
416 } 571 }
417 572
418 if (!created) { 573 if (!created) {
diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h
index 88a864b42..9923aa2ea 100644
--- a/src/yuzu/configuration/shared_widget.h
+++ b/src/yuzu/configuration/shared_widget.h
@@ -9,6 +9,7 @@ class QComboBox;
9class QLineEdit; 9class QLineEdit;
10class QSlider; 10class QSlider;
11class QCheckBox; 11class QCheckBox;
12class QDateTimeEdit;
12 13
13namespace Settings { 14namespace Settings {
14class BasicSetting; 15class BasicSetting;
@@ -23,6 +24,8 @@ enum class RequestType {
23 Slider, 24 Slider,
24 ReverseSlider, 25 ReverseSlider,
25 LineEdit, 26 LineEdit,
27 HexEdit,
28 DateTimeEdit,
26 MaxEnum, 29 MaxEnum,
27}; 30};
28 31
@@ -33,8 +36,7 @@ public:
33 Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, 36 Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
34 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, 37 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
35 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, 38 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f,
36 Settings::BasicSetting* other_setting = nullptr, 39 Settings::BasicSetting* other_setting = nullptr, const std::string& format = "");
37 const QString& format = QStringLiteral(""));
38 virtual ~Widget(); 40 virtual ~Widget();
39 41
40 bool Valid(); 42 bool Valid();
@@ -48,13 +50,18 @@ public:
48 QCheckBox* checkbox{}; 50 QCheckBox* checkbox{};
49 QSlider* slider{}; 51 QSlider* slider{};
50 QComboBox* combobox{}; 52 QComboBox* combobox{};
53 QDateTimeEdit* date_time_edit{};
51 54
52private: 55private:
53 void CreateCheckBox(const QString& label, std::function<void()>& load_func); 56 void CreateCheckBox(const QString& label, std::function<void()>& load_func);
54 void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, 57 void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting,
55 std::function<void()>& load_func); 58 std::function<void()>& load_func);
59 void CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting,
60 std::function<void()>& load_func);
56 void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, 61 void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting,
57 std::function<void()>& load_func, const QString& suffix); 62 std::function<void()>& load_func, const std::string& suffix);
63 void CreateCheckBoxWithDateTimeEdit(const QString& label, Settings::BasicSetting* other_setting,
64 std::function<void()>& load_func);
58 void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func); 65 void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func);
59 void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func); 66 void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func);
60 void CreateSlider(const QString& label, bool reversed, float multiplier, 67 void CreateSlider(const QString& label, bool reversed, float multiplier,
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index f8cbf8034..c42d98709 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -229,6 +229,7 @@ void Config::ReadValues() {
229 ReadCategory(Settings::Category::RendererAdvanced); 229 ReadCategory(Settings::Category::RendererAdvanced);
230 ReadCategory(Settings::Category::RendererDebug); 230 ReadCategory(Settings::Category::RendererDebug);
231 ReadCategory(Settings::Category::System); 231 ReadCategory(Settings::Category::System);
232 ReadCategory(Settings::Category::SystemAudio);
232 ReadCategory(Settings::Category::DataStorage); 233 ReadCategory(Settings::Category::DataStorage);
233 ReadCategory(Settings::Category::Debugging); 234 ReadCategory(Settings::Category::Debugging);
234 ReadCategory(Settings::Category::DebuggingGraphics); 235 ReadCategory(Settings::Category::DebuggingGraphics);