configure_system: Implement with for loop

This commit is contained in:
lat9nq 2023-05-10 17:57:25 -04:00
parent 56960bf9f8
commit 8e15146026
18 changed files with 514 additions and 654 deletions

View file

@ -162,6 +162,7 @@ const char* TranslateCategory(Category category) {
case Category::RendererDebug: case Category::RendererDebug:
return "Renderer"; return "Renderer";
case Category::System: case Category::System:
case Category::SystemAudio:
return "System"; return "System";
case Category::DataStorage: case Category::DataStorage:
return "Data Storage"; return "Data Storage";

View file

@ -20,6 +20,86 @@
namespace Settings { namespace Settings {
enum class Language : u32 {
Japanese,
EnglishAmerican,
French,
German,
Italian,
Spanish,
Chinese,
Korean,
Dutch,
Portuguese,
Russian,
Taiwanese,
EnglishBritish,
FrenchCanadian,
SpanishLatin,
ChineseSimplified,
ChineseTraditional,
PortugueseBrazilian,
};
enum class Region : u32 {
Japan,
USA,
Europe,
Australia,
China,
Korea,
Taiwan,
};
enum class TimeZone : u32 {
Auto,
Default,
CET,
CST6CDT,
Cuba,
EET,
Egypt,
Eire,
EST,
EST5EDT,
GB,
GBEire,
GMT,
GMTPlusZero,
GMTMinusZero,
GMTZero,
Greenwich,
Hongkong,
HST,
Iceland,
Iran,
Israel,
Jamaica,
Japan,
Kwajalein,
Libya,
MET,
MST,
MST7MDT,
Navajo,
NZ,
NZCHAT,
Poland,
Portugal,
PRC,
PST8PDT,
ROC,
ROK,
Singapore,
Turkey,
UCT,
Universal,
UTC,
W_SU,
WET,
Zulu,
};
enum class AnisotropyMode : u32 { enum class AnisotropyMode : u32 {
Automatic = 0, Automatic = 0,
Default = 1, Default = 1,
@ -134,6 +214,7 @@ enum class Category : u32 {
RendererAdvanced, RendererAdvanced,
RendererDebug, RendererDebug,
System, System,
SystemAudio,
DataStorage, DataStorage,
Debugging, Debugging,
DebuggingGraphics, DebuggingGraphics,
@ -810,22 +891,31 @@ struct Values {
SwitchableSetting<u8, false> bg_blue{linkage, 0, "bg_blue", Category::Renderer, true, true}; SwitchableSetting<u8, false> bg_blue{linkage, 0, "bg_blue", Category::Renderer, true, true};
// System // System
SwitchableSetting<bool> rng_seed_enabled{linkage, false, "rng_seed_enabled", Category::System}; SwitchableSetting<bool> rng_seed_enabled{linkage, false, "rng_seed_enabled",
SwitchableSetting<u32> rng_seed{linkage, 0, "rng_seed", Category::System}; Category::System, true, true};
Setting<std::string> device_name{linkage, "Yuzu", "device_name", Category::System}; SwitchableSetting<u32> rng_seed{linkage, 0, "rng_seed", Category::System, true, true};
Setting<std::string> device_name{linkage, "Yuzu", "device_name", Category::System, true, true};
// Measured in seconds since epoch // Measured in seconds since epoch
Setting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System}; SwitchableSetting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled",
Setting<s64> custom_rtc{linkage, 0, "custom_rtc", Category::System}; Category::System, true, true};
SwitchableSetting<s64> custom_rtc{linkage, 0, "custom_rtc", Category::System, true, true};
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
s64 custom_rtc_differential; s64 custom_rtc_differential;
Setting<s32> current_user{linkage, 0, "current_user", Category::System}; Setting<s32> current_user{linkage, 0, "current_user", Category::System};
SwitchableSetting<s32, true> language_index{linkage, 1, 0, 17, "language_index", SwitchableSetting<Language, true> language_index{linkage,
Category::System}; Language::EnglishAmerican,
SwitchableSetting<s32, true> region_index{linkage, 1, 0, 6, "region_index", Category::System}; Language::Japanese,
SwitchableSetting<s32, true> time_zone_index{linkage, 0, 0, 45, "time_zone_index", Language::PortugueseBrazilian,
Category::System}; "language_index",
SwitchableSetting<s32, true> sound_index{linkage, 1, 0, 2, "sound_index", Category::System}; Category::System};
SwitchableSetting<Region, true> region_index{linkage, Region::USA, Region::Japan,
Region::Taiwan, "region_index", Category::System};
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
TimeZone::Auto, TimeZone::Zulu,
"time_zone_index", Category::System};
SwitchableSetting<s32, true> sound_index{
linkage, 1, 0, 2, "sound_index", Category::SystemAudio};
SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System}; SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System};
@ -837,7 +927,7 @@ struct Values {
#ifdef _WIN32 #ifdef _WIN32
true true
#else #else
false false
#endif #endif
}; };
Setting<bool> controller_navigation{linkage, true, "controller_navigation", Category::Controls}; Setting<bool> controller_navigation{linkage, true, "controller_navigation", Category::Controls};

View file

@ -145,13 +145,7 @@ struct System::Impl {
core_timing.SetMulticore(is_multicore); core_timing.SetMulticore(is_multicore);
core_timing.Initialize([&system]() { system.RegisterHostThread(); }); core_timing.Initialize([&system]() { system.RegisterHostThread(); });
const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); RefreshTime();
const auto current_time =
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
Settings::values.custom_rtc_differential =
(Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
: current_time) -
current_time;
// Create a default fs if one doesn't already exist. // Create a default fs if one doesn't already exist.
if (virtual_filesystem == nullptr) { if (virtual_filesystem == nullptr) {
@ -188,6 +182,16 @@ struct System::Impl {
Initialize(system); Initialize(system);
} }
void RefreshTime() {
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
const auto current_time =
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
Settings::values.custom_rtc_differential =
(Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
: current_time) -
current_time;
}
void Run() { void Run() {
std::unique_lock<std::mutex> lk(suspend_guard); std::unique_lock<std::mutex> lk(suspend_guard);
@ -1022,6 +1026,8 @@ void System::Exit() {
} }
void System::ApplySettings() { void System::ApplySettings() {
impl->RefreshTime();
if (IsPoweredOn()) { if (IsPoweredOn()) {
Renderer().RefreshBaseSettings(); Renderer().RefreshBaseSettings();
} }

View file

@ -68,7 +68,8 @@ NACP::NACP(VirtualFile file) {
NACP::~NACP() = default; NACP::~NACP() = default;
const LanguageEntry& NACP::GetLanguageEntry() const { const LanguageEntry& NACP::GetLanguageEntry() const {
Language language = language_to_codes[Settings::values.language_index.GetValue()]; Language language =
language_to_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
{ {
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language)); const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));

View file

@ -626,8 +626,8 @@ PatchManager::Metadata PatchManager::ParseControlNCA(const NCA& nca) const {
auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file); auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file);
// Get language code from settings // Get language code from settings
const auto language_code = const auto language_code = Service::Set::GetLanguageCodeFromIndex(
Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); static_cast<u32>(Settings::values.language_index.GetValue()));
// Convert to application language and get priority list // Convert to application language and get priority list
const auto application_language = const auto application_language =

View file

@ -409,7 +409,7 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
// Get language code from settings // Get language code from settings
const auto language_code = const auto language_code =
Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue()));
// Convert to application language, get priority list // Convert to application language, get priority list
const auto application_language = ConvertToApplicationLanguage(language_code); const auto application_language = ConvertToApplicationLanguage(language_code);

View file

@ -93,7 +93,8 @@ void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entri
} }
void GetKeyCodeMapImpl(HLERequestContext& ctx) { void GetKeyCodeMapImpl(HLERequestContext& ctx) {
const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; const auto language_code =
available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
const auto key_code = const auto key_code =
std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
[=](const auto& element) { return element.first == language_code; }); [=](const auto& element) { return element.first == language_code; });
@ -162,7 +163,7 @@ void SET::GetQuestFlag(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue())); rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue()));
} }
void SET::GetLanguageCode(HLERequestContext& ctx) { void SET::GetLanguageCode(HLERequestContext& ctx) {
@ -170,7 +171,8 @@ void SET::GetLanguageCode(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); rb.PushEnum(
available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]);
} }
void SET::GetRegionCode(HLERequestContext& ctx) { void SET::GetRegionCode(HLERequestContext& ctx) {
@ -178,7 +180,7 @@ void SET::GetRegionCode(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push(Settings::values.region_index.GetValue()); rb.Push(static_cast<u32>(Settings::values.region_index.GetValue()));
} }
void SET::GetKeyCodeMap(HLERequestContext& ctx) { void SET::GetKeyCodeMap(HLERequestContext& ctx) {

View file

@ -696,6 +696,7 @@ void Config::ReadSystemValues() {
qt_config->beginGroup(QStringLiteral("System")); qt_config->beginGroup(QStringLiteral("System"));
ReadCategory(Settings::Category::System); ReadCategory(Settings::Category::System);
ReadCategory(Settings::Category::SystemAudio);
qt_config->endGroup(); qt_config->endGroup();
} }
@ -1134,6 +1135,7 @@ void Config::SaveSystemValues() {
qt_config->beginGroup(QStringLiteral("System")); qt_config->beginGroup(QStringLiteral("System"));
WriteCategory(Settings::Category::System); WriteCategory(Settings::Category::System);
WriteCategory(Settings::Category::SystemAudio);
qt_config->endGroup(); qt_config->endGroup();
} }

View file

@ -48,7 +48,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
input_tab{std::make_unique<ConfigureInput>(system_, this)}, input_tab{std::make_unique<ConfigureInput>(system_, this)},
network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)}, profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, this)}, system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, *translations, this)},
ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>( ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>(
this)} { this)} {
Settings::SetConfiguringGlobal(true); Settings::SetConfiguringGlobal(true);

View file

@ -240,7 +240,7 @@ void ConfigureGraphics::Setup() {
return new ConfigurationShared::Widget( return new ConfigurationShared::Widget(
setting, translations, this, runtime_lock, apply_funcs, setting, translations, this, runtime_lock, apply_funcs,
ConfigurationShared::RequestType::SpinBox, true, 1.0f, ConfigurationShared::RequestType::SpinBox, true, 1.0f,
&Settings::values.speed_limit, QStringLiteral("%")); &Settings::values.speed_limit, "%");
} else { } else {
return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
apply_funcs); apply_funcs);

View file

@ -58,7 +58,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
tab_group, *translations, this); tab_group, *translations, this);
input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, this); system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *translations, this);
ui->setupUi(this); ui->setupUi(this);

View file

@ -2,17 +2,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono> #include <chrono>
#include <forward_list>
#include <optional> #include <optional>
#include <QDateTimeEdit>
#include <QFileDialog> #include <QFileDialog>
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QLineEdit>
#include <QMessageBox> #include <QMessageBox>
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/time/time_manager.h" #include "core/hle/service/time/time_manager.h"
#include "ui_configure_system.h" #include "ui_configure_system.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_system.h" #include "yuzu/configuration/configure_system.h"
#include "yuzu/configuration/shared_widget.h"
constexpr std::array<u32, 7> LOCALE_BLOCKLIST{ constexpr std::array<u32, 7> LOCALE_BLOCKLIST{
// pzzefezrpnkzeidfej // pzzefezrpnkzeidfej
@ -39,44 +44,42 @@ static bool IsValidLocale(u32 region_index, u32 language_index) {
ConfigureSystem::ConfigureSystem( ConfigureSystem::ConfigureSystem(
Core::System& system_, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, Core::System& system_, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
QWidget* parent) ConfigurationShared::TranslationMap& translations_, QWidget* parent)
: Tab(group, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} { : Tab(group, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_},
translations{translations_} {
ui->setupUi(this); ui->setupUi(this);
connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) { Setup();
ui->rng_seed_edit->setEnabled(state == Qt::Checked);
connect(rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
rng_seed_edit->setEnabled(state == Qt::Checked);
if (state != Qt::Checked) { if (state != Qt::Checked) {
ui->rng_seed_edit->setText(QStringLiteral("00000000")); rng_seed_edit->setText(QStringLiteral("00000000"));
} }
}); });
connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) { connect(custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
ui->custom_rtc_edit->setEnabled(state == Qt::Checked); custom_rtc_edit->setEnabled(state == Qt::Checked);
if (state != Qt::Checked) { if (state != Qt::Checked) {
ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); custom_rtc_edit->setDateTime(QDateTime::currentDateTime());
} }
}); });
const auto locale_check = [this](int index) { const auto locale_check = [this](int index) {
const auto region_index = ConfigurationShared::GetComboboxIndex( const auto region_index = combo_region->currentIndex();
Settings::values.region_index.GetValue(true), ui->combo_region); const auto language_index = combo_language->currentIndex();
const auto language_index = ConfigurationShared::GetComboboxIndex(
Settings::values.language_index.GetValue(true), ui->combo_language);
const bool valid_locale = IsValidLocale(region_index, language_index); const bool valid_locale = IsValidLocale(region_index, language_index);
ui->label_warn_invalid_locale->setVisible(!valid_locale); ui->label_warn_invalid_locale->setVisible(!valid_locale);
if (!valid_locale) { if (!valid_locale) {
ui->label_warn_invalid_locale->setText( ui->label_warn_invalid_locale->setText(
tr("Warning: \"%1\" is not a valid language for region \"%2\"") tr("Warning: \"%1\" is not a valid language for region \"%2\"")
.arg(ui->combo_language->currentText()) .arg(combo_language->currentText())
.arg(ui->combo_region->currentText())); .arg(combo_region->currentText()));
} }
}; };
connect(ui->combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
locale_check); connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
connect(ui->combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
SetupPerGameUI();
SetConfiguration(); SetConfiguration();
} }
@ -95,137 +98,94 @@ void ConfigureSystem::RetranslateUI() {
ui->retranslateUi(this); ui->retranslateUi(this);
} }
void ConfigureSystem::SetConfiguration() { void ConfigureSystem::Setup() {
enabled = !system.IsPoweredOn(); const bool runtime_lock = !system.IsPoweredOn();
const auto rng_seed = QStringLiteral("%1") auto& core_layout = *ui->core_widget->layout();
.arg(Settings::values.rng_seed.GetValue(), 8, 16, QLatin1Char{'0'}) auto& system_layout = *ui->system_widget->layout();
.toUpper();
const auto rtc_time = Settings::values.custom_rtc_enabled
? Settings::values.custom_rtc.GetValue()
: QDateTime::currentSecsSinceEpoch();
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed_enabled.GetValue()); std::map<std::string, QWidget*> core_hold{};
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed_enabled.GetValue() && std::map<bool, std::map<std::string, QWidget*>> system_hold{};
Settings::values.rng_seed.UsingGlobal());
ui->rng_seed_edit->setText(rng_seed);
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc_enabled.GetValue()); std::forward_list<Settings::BasicSetting*> settings;
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue()); auto push = [&settings](std::forward_list<Settings::BasicSetting*>& list) {
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time)); for (auto setting : list) {
ui->device_name_edit->setText( settings.push_front(setting);
QString::fromUtf8(Settings::values.device_name.GetValue().c_str())); }
ui->use_unsafe_extended_memory_layout->setEnabled(enabled); };
ui->use_unsafe_extended_memory_layout->setChecked(
Settings::values.use_unsafe_extended_memory_layout.GetValue());
if (Settings::IsConfiguringGlobal()) { push(Settings::values.linkage.by_category[Settings::Category::Core]);
ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); push(Settings::values.linkage.by_category[Settings::Category::System]);
ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue());
ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue());
} else {
ConfigurationShared::SetPerGameSetting(ui->combo_language,
&Settings::values.language_index);
ConfigurationShared::SetPerGameSetting(ui->combo_region, &Settings::values.region_index);
ConfigurationShared::SetPerGameSetting(ui->combo_time_zone,
&Settings::values.time_zone_index);
ConfigurationShared::SetHighlight(ui->label_language, for (auto setting : settings) {
!Settings::values.language_index.UsingGlobal()); ConfigurationShared::Widget* widget = [=]() {
ConfigurationShared::SetHighlight(ui->label_region, if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) {
!Settings::values.region_index.UsingGlobal()); return new ConfigurationShared::Widget(
ConfigurationShared::SetHighlight(ui->label_timezone, setting, translations, this, runtime_lock, apply_funcs,
!Settings::values.time_zone_index.UsingGlobal()); ConfigurationShared::RequestType::DateTimeEdit, true, 1.0f,
&Settings::values.custom_rtc);
} else if (setting->Id() == Settings::values.rng_seed_enabled.Id()) {
return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
apply_funcs,
ConfigurationShared::RequestType::HexEdit,
true, 1.0f, &Settings::values.rng_seed);
} else {
return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
apply_funcs);
}
}();
if (!widget->Valid()) {
delete widget;
continue;
}
if (setting->Id() == Settings::values.rng_seed_enabled.Id()) {
rng_seed_checkbox = widget->checkbox;
rng_seed_edit = widget->line_edit;
if (!Settings::values.rng_seed_enabled.GetValue()) {
rng_seed_edit->setEnabled(false);
}
} else if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) {
custom_rtc_checkbox = widget->checkbox;
custom_rtc_edit = widget->date_time_edit;
custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue());
} else if (setting->Id() == Settings::values.region_index.Id()) {
combo_region = widget->combobox;
} else if (setting->Id() == Settings::values.language_index.Id()) {
combo_language = widget->combobox;
}
switch (setting->Category()) {
case Settings::Category::Core:
core_hold[setting->GetLabel()] = widget;
break;
case Settings::Category::System:
system_hold[setting->IsEnum()].insert(std::pair{setting->GetLabel(), widget});
break;
default:
delete widget;
}
}
for (const auto& [label, widget] : core_hold) {
core_layout.addWidget(widget);
}
for (const auto& [label, widget] : system_hold[true]) {
system_layout.addWidget(widget);
}
for (const auto& [label, widget] : system_hold[false]) {
system_layout.addWidget(widget);
} }
} }
void ConfigureSystem::ReadSystemSettings() {} void ConfigureSystem::SetConfiguration() {}
void ConfigureSystem::ApplyConfiguration() { void ConfigureSystem::ApplyConfiguration() {
// Allow setting custom RTC even if system is powered on, const bool powered_on = system.IsPoweredOn();
// to allow in-game time to be fast forwarded for (const auto& func : apply_funcs) {
if (Settings::IsConfiguringGlobal()) { func(powered_on);
if (ui->custom_rtc_checkbox->isChecked()) {
Settings::values.custom_rtc_enabled = true;
Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
if (system.IsPoweredOn()) {
const s64 posix_time{Settings::values.custom_rtc.GetValue() +
Service::Time::TimeManager::GetExternalTimeZoneOffset()};
system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
}
} else {
Settings::values.custom_rtc_enabled = false;
}
}
Settings::values.device_name = ui->device_name_edit->text().toStdString();
if (!enabled) {
return;
}
ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index, ui->combo_language);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_index, ui->combo_region);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.time_zone_index,
ui->combo_time_zone);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_unsafe_extended_memory_layout,
ui->use_unsafe_extended_memory_layout,
use_unsafe_extended_memory_layout);
if (Settings::IsConfiguringGlobal()) {
// Guard if during game and set to game-specific value
if (Settings::values.rng_seed.UsingGlobal()) {
Settings::values.rng_seed_enabled = ui->rng_seed_checkbox->isChecked();
if (ui->rng_seed_checkbox->isChecked()) {
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
}
}
} else {
switch (use_rng_seed) {
case ConfigurationShared::CheckState::On:
case ConfigurationShared::CheckState::Off:
Settings::values.rng_seed_enabled.SetGlobal(false);
Settings::values.rng_seed.SetGlobal(false);
if (ui->rng_seed_checkbox->isChecked()) {
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
}
break;
case ConfigurationShared::CheckState::Global:
Settings::values.rng_seed_enabled.SetGlobal(true);
Settings::values.rng_seed.SetGlobal(true);
break;
case ConfigurationShared::CheckState::Count:
break;
}
} }
} }
void ConfigureSystem::SetupPerGameUI() {
if (Settings::IsConfiguringGlobal()) {
ui->combo_language->setEnabled(Settings::values.language_index.UsingGlobal());
ui->combo_region->setEnabled(Settings::values.region_index.UsingGlobal());
ui->combo_time_zone->setEnabled(Settings::values.time_zone_index.UsingGlobal());
ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal());
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal());
return;
}
ConfigurationShared::SetColoredComboBox(ui->combo_language, ui->label_language,
Settings::values.language_index.GetValue(true));
ConfigurationShared::SetColoredComboBox(ui->combo_region, ui->label_region,
Settings::values.region_index.GetValue(true));
ConfigurationShared::SetColoredComboBox(ui->combo_time_zone, ui->label_timezone,
Settings::values.time_zone_index.GetValue(true));
ConfigurationShared::SetColoredTristate(
ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(),
Settings::values.rng_seed_enabled.GetValue(),
Settings::values.rng_seed_enabled.GetValue(true), use_rng_seed);
ConfigurationShared::SetColoredTristate(ui->use_unsafe_extended_memory_layout,
Settings::values.use_unsafe_extended_memory_layout,
use_unsafe_extended_memory_layout);
ui->custom_rtc_checkbox->setVisible(false);
ui->custom_rtc_edit->setVisible(false);
}

View file

@ -3,11 +3,15 @@
#pragma once #pragma once
#include <forward_list>
#include <functional>
#include <memory> #include <memory>
#include <QWidget> #include <QWidget>
#include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configuration_shared.h"
class QDateTimeEdit;
namespace Core { namespace Core {
class System; class System;
} }
@ -20,6 +24,7 @@ class ConfigureSystem : public ConfigurationShared::Tab {
public: public:
explicit ConfigureSystem(Core::System& system_, explicit ConfigureSystem(Core::System& system_,
std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
ConfigurationShared::TranslationMap& translations,
QWidget* parent = nullptr); QWidget* parent = nullptr);
~ConfigureSystem() override; ~ConfigureSystem() override;
@ -30,9 +35,9 @@ private:
void changeEvent(QEvent* event) override; void changeEvent(QEvent* event) override;
void RetranslateUI(); void RetranslateUI();
void ReadSystemSettings(); void Setup();
void SetupPerGameUI(); std::forward_list<std::function<void(bool)>> apply_funcs{};
std::unique_ptr<Ui::ConfigureSystem> ui; std::unique_ptr<Ui::ConfigureSystem> ui;
bool enabled = false; bool enabled = false;
@ -41,4 +46,12 @@ private:
ConfigurationShared::CheckState use_unsafe_extended_memory_layout; ConfigurationShared::CheckState use_unsafe_extended_memory_layout;
Core::System& system; Core::System& system;
ConfigurationShared::TranslationMap& translations;
QCheckBox* rng_seed_checkbox;
QLineEdit* rng_seed_edit;
QCheckBox* custom_rtc_checkbox;
QDateTimeEdit* custom_rtc_edit;
QComboBox* combo_region;
QComboBox* combo_language;
}; };

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>366</width> <width>605</width>
<height>483</height> <height>483</height>
</rect> </rect>
</property> </property>
@ -22,470 +22,53 @@
<item> <item>
<widget class="QGroupBox" name="group_system_settings"> <widget class="QGroupBox" name="group_system_settings">
<property name="title"> <property name="title">
<string>System Settings</string> <string>System</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QGridLayout" name="gridLayout_2"> <widget class="QWidget" name="system_widget" native="true">
<item row="1" column="0"> <layout class="QVBoxLayout" name="verticalLayout_3">
<widget class="QLabel" name="label_region"> <property name="leftMargin">
<property name="text"> <number>0</number>
<string>Region:</string> </property>
</property> <property name="topMargin">
</widget> <number>0</number>
</item> </property>
<item row="2" column="1"> <property name="rightMargin">
<widget class="QComboBox" name="combo_time_zone"> <number>0</number>
<item> </property>
<property name="text"> <property name="bottomMargin">
<string>Auto</string> <number>0</number>
</property> </property>
</item> </layout>
<item> </widget>
<property name="text"> </item>
<string>Default</string> </layout>
</property> </widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QGroupBox" name="groupBox">
<string>CET</string> <property name="title">
</property> <string>Core</string>
</item> </property>
<item> <layout class="QVBoxLayout" name="verticalLayout_6">
<property name="text"> <item>
<string>CST6CDT</string> <widget class="QWidget" name="core_widget" native="true">
</property> <layout class="QVBoxLayout" name="verticalLayout_5">
</item> <property name="leftMargin">
<item> <number>0</number>
<property name="text"> </property>
<string>Cuba</string> <property name="topMargin">
</property> <number>0</number>
</item> </property>
<item> <property name="rightMargin">
<property name="text"> <number>0</number>
<string>EET</string> </property>
</property> <property name="bottomMargin">
</item> <number>0</number>
<item> </property>
<property name="text"> </layout>
<string>Egypt</string> </widget>
</property>
</item>
<item>
<property name="text">
<string>Eire</string>
</property>
</item>
<item>
<property name="text">
<string>EST</string>
</property>
</item>
<item>
<property name="text">
<string>EST5EDT</string>
</property>
</item>
<item>
<property name="text">
<string>GB</string>
</property>
</item>
<item>
<property name="text">
<string>GB-Eire</string>
</property>
</item>
<item>
<property name="text">
<string>GMT</string>
</property>
</item>
<item>
<property name="text">
<string>GMT+0</string>
</property>
</item>
<item>
<property name="text">
<string>GMT-0</string>
</property>
</item>
<item>
<property name="text">
<string>GMT0</string>
</property>
</item>
<item>
<property name="text">
<string>Greenwich</string>
</property>
</item>
<item>
<property name="text">
<string>Hongkong</string>
</property>
</item>
<item>
<property name="text">
<string>HST</string>
</property>
</item>
<item>
<property name="text">
<string>Iceland</string>
</property>
</item>
<item>
<property name="text">
<string>Iran</string>
</property>
</item>
<item>
<property name="text">
<string>Israel</string>
</property>
</item>
<item>
<property name="text">
<string>Jamaica</string>
</property>
</item>
<item>
<property name="text">
<string>Japan</string>
</property>
</item>
<item>
<property name="text">
<string>Kwajalein</string>
</property>
</item>
<item>
<property name="text">
<string>Libya</string>
</property>
</item>
<item>
<property name="text">
<string>MET</string>
</property>
</item>
<item>
<property name="text">
<string>MST</string>
</property>
</item>
<item>
<property name="text">
<string>MST7MDT</string>
</property>
</item>
<item>
<property name="text">
<string>Navajo</string>
</property>
</item>
<item>
<property name="text">
<string>NZ</string>
</property>
</item>
<item>
<property name="text">
<string>NZ-CHAT</string>
</property>
</item>
<item>
<property name="text">
<string>Poland</string>
</property>
</item>
<item>
<property name="text">
<string>Portugal</string>
</property>
</item>
<item>
<property name="text">
<string>PRC</string>
</property>
</item>
<item>
<property name="text">
<string>PST8PDT</string>
</property>
</item>
<item>
<property name="text">
<string>ROC</string>
</property>
</item>
<item>
<property name="text">
<string>ROK</string>
</property>
</item>
<item>
<property name="text">
<string>Singapore</string>
</property>
</item>
<item>
<property name="text">
<string>Turkey</string>
</property>
</item>
<item>
<property name="text">
<string>UCT</string>
</property>
</item>
<item>
<property name="text">
<string>Universal</string>
</property>
</item>
<item>
<property name="text">
<string>UTC</string>
</property>
</item>
<item>
<property name="text">
<string>W-SU</string>
</property>
</item>
<item>
<property name="text">
<string>WET</string>
</property>
</item>
<item>
<property name="text">
<string>Zulu</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="combo_region">
<item>
<property name="text">
<string>Japan</string>
</property>
</item>
<item>
<property name="text">
<string>USA</string>
</property>
</item>
<item>
<property name="text">
<string>Europe</string>
</property>
</item>
<item>
<property name="text">
<string>Australia</string>
</property>
</item>
<item>
<property name="text">
<string>China</string>
</property>
</item>
<item>
<property name="text">
<string>Korea</string>
</property>
</item>
<item>
<property name="text">
<string>Taiwan</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_timezone">
<property name="text">
<string>Time Zone:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="combo_language">
<property name="toolTip">
<string>Note: this can be overridden when region setting is auto-select</string>
</property>
<item>
<property name="text">
<string>Japanese (日本語)</string>
</property>
</item>
<item>
<property name="text">
<string>American English</string>
</property>
</item>
<item>
<property name="text">
<string>French (français)</string>
</property>
</item>
<item>
<property name="text">
<string>German (Deutsch)</string>
</property>
</item>
<item>
<property name="text">
<string>Italian (italiano)</string>
</property>
</item>
<item>
<property name="text">
<string>Spanish (español)</string>
</property>
</item>
<item>
<property name="text">
<string>Chinese</string>
</property>
</item>
<item>
<property name="text">
<string>Korean (한국어)</string>
</property>
</item>
<item>
<property name="text">
<string>Dutch (Nederlands)</string>
</property>
</item>
<item>
<property name="text">
<string>Portuguese (português)</string>
</property>
</item>
<item>
<property name="text">
<string>Russian (Русский)</string>
</property>
</item>
<item>
<property name="text">
<string>Taiwanese</string>
</property>
</item>
<item>
<property name="text">
<string>British English</string>
</property>
</item>
<item>
<property name="text">
<string>Canadian French</string>
</property>
</item>
<item>
<property name="text">
<string>Latin American Spanish</string>
</property>
</item>
<item>
<property name="text">
<string>Simplified Chinese</string>
</property>
</item>
<item>
<property name="text">
<string>Traditional Chinese (正體中文)</string>
</property>
</item>
<item>
<property name="text">
<string>Brazilian Portuguese (português do Brasil)</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="custom_rtc_checkbox">
<property name="text">
<string>Custom RTC</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_language">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="rng_seed_checkbox">
<property name="text">
<string>RNG Seed</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="device_name_label">
<property name="text">
<string>Device Name</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDateTimeEdit" name="custom_rtc_edit">
<property name="minimumDate">
<date>
<year>1970</year>
<month>1</month>
<day>1</day>
</date>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="device_name_edit">
<property name="maxLength">
<number>128</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="rng_seed_edit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Lucida Console</family>
</font>
</property>
<property name="inputMask">
<string notr="true">HHHHHHHH</string>
</property>
<property name="maxLength">
<number>8</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="use_unsafe_extended_memory_layout">
<property name="text">
<string>Unsafe extended memory layout (8GB DRAM)</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -506,7 +89,7 @@
<item> <item>
<widget class="QLabel" name="label_warn_invalid_locale"> <widget class="QLabel" name="label_warn_invalid_locale">
<property name="text"> <property name="text">
<string></string> <string/>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

View file

@ -109,15 +109,16 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
// System // System
INSERT(Settings, rng_seed_enabled, "RNG Seed", ""); INSERT(Settings, rng_seed_enabled, "RNG Seed", "");
INSERT(Settings, rng_seed, "RNG Seed", ""); INSERT(Settings, rng_seed, "", "");
INSERT(Settings, device_name, "Device Name", ""); INSERT(Settings, device_name, "Device Name", "");
INSERT(Settings, custom_rtc_enabled, "Custom RTC", ""); INSERT(Settings, custom_rtc_enabled, "Custom RTC", "");
INSERT(Settings, custom_rtc, "Custom RTC", ""); INSERT(Settings, custom_rtc, "", "");
INSERT(Settings, language_index, "Language:", ""); INSERT(Settings, language_index, "Language:", "");
INSERT(Settings, region_index, "Region:", ""); INSERT(Settings, region_index, "Region:", "");
INSERT(Settings, time_zone_index, "Time Zone:", ""); INSERT(Settings, time_zone_index, "Time Zone:", "");
INSERT(Settings, sound_index, "Sound Output Mode:", ""); INSERT(Settings, sound_index, "Sound Output Mode:", "");
INSERT(Settings, use_docked_mode, "", ""); INSERT(Settings, use_docked_mode, "", "");
INSERT(Settings, current_user, "", "");
// Controls // Controls
@ -231,6 +232,44 @@ std::forward_list<QString> ComboboxEnumeration(std::type_index type, QWidget* pa
return { return {
tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"), tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"),
}; };
} else if (type == typeid(Settings::Language)) {
return {
tr("Japanese (日本語)"),
tr("American English"),
tr("French (français)"),
tr("German (Deutsch)"),
tr("Italian (italiano)"),
tr("Spanish (español)"),
tr("Chinese"),
tr("Korean (한국어)"),
tr("Dutch (Nederlands)"),
tr("Portuguese (português)"),
tr("Russian (Русский)"),
tr("Taiwanese"),
tr("British English"),
tr("Canadian French"),
tr("Latin American Spanish"),
tr("Simplified Chinese"),
tr("Traditional Chinese (正體中文)"),
tr("Brazilian Portuguese (português do Brasil)"),
};
} else if (type == typeid(Settings::Region)) {
return {
tr("Japan"), tr("USA"), tr("Europe"), tr("Australia"),
tr("China"), tr("Korea"), tr("Taiwan"),
};
} else if (type == typeid(Settings::TimeZone)) {
return {
tr("Auto"), tr("Default"), tr("CET"), tr("CST6CDT"), tr("Cuba"),
tr("EET"), tr("Egypt"), tr("Eire"), tr("EST"), tr("EST5EDT"),
tr("GB"), tr("GB-Eire"), tr("GMT"), tr("GMT+0"), tr("GMT-0"),
tr("GMT0"), tr("Greenwich"), tr("Hongkong"), tr("HST"), tr("Iceland"),
tr("Iran"), tr("Israel"), tr("Jamaica"), tr("Kwajalein"), tr("Libya"),
tr("MET"), tr("MST"), tr("MST7MDT"), tr("Navajo"), tr("NZ"),
tr("NZ-CHAT"), tr("Poland"), tr("Portugal"), tr("PRC"), tr("PST8PDT"),
tr("ROC"), tr("ROK"), tr("Singapore"), tr("Turkey"), tr("UCT"),
tr("W-SU"), tr("WET"), tr("Zulu"),
};
} }
return {}; return {};

View file

@ -1,5 +1,7 @@
#include <functional> #include <functional>
#include <limits>
#include <QCheckBox> #include <QCheckBox>
#include <QDateTimeEdit>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QIcon> #include <QIcon>
#include <QLabel> #include <QLabel>
@ -9,6 +11,9 @@
#include <QSpinBox> #include <QSpinBox>
#include <QWidget> #include <QWidget>
#include <qabstractbutton.h> #include <qabstractbutton.h>
#include <qabstractspinbox.h>
#include <qnamespace.h>
#include <qvalidator.h>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings.h" #include "common/settings.h"
#include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configuration_shared.h"
@ -25,7 +30,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting,
QStyle* style = parent->style(); QStyle* style = parent->style();
QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent);
restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
QSizePolicy sp_retain = restore_button->sizePolicy(); QSizePolicy sp_retain = restore_button->sizePolicy();
sp_retain.setRetainSizeWhenHidden(true); sp_retain.setRetainSizeWhenHidden(true);
@ -241,6 +246,67 @@ void Widget::CreateSlider(const QString& name, bool reversed, float multiplier,
} }
} }
void Widget::CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func) {
if (other_setting == nullptr) {
LOG_WARNING(Frontend, "Extra setting is null or not an integer");
return;
}
created = true;
std::function<void()> checkbox_load_func;
CreateCheckBox(label, checkbox_load_func);
auto to_hex = [=](const std::string& input) {
return QString::fromStdString(fmt::format("{:08x}", std::stoi(input)));
};
QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
const QString default_val = to_hex(other_setting->ToString());
line_edit = new QLineEdit(this);
line_edit->setText(default_val);
checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->insertWidget(1, line_edit);
line_edit->setMaxLength(8);
QRegExpValidator* regex =
new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit};
line_edit->setValidator(regex);
auto hex_to_dec = [=]() -> std::string {
return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
};
if (Settings::IsConfiguringGlobal()) {
load_func = [=]() {
checkbox_load_func();
other_setting->LoadString(hex_to_dec());
};
} else {
QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
line_edit->setText(to_hex(other_setting->ToStringGlobal()));
});
QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) {
restore_button->setEnabled(true);
restore_button->setVisible(true);
});
load_func = [=]() {
checkbox_load_func();
const bool using_global = !restore_button->isEnabled();
other_setting->SetGlobal(using_global);
if (!using_global) {
other_setting->LoadString(hex_to_dec());
}
};
}
}
void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func) { std::function<void()>& load_func) {
if (other_setting == nullptr) { if (other_setting == nullptr) {
@ -268,8 +334,9 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
other_setting->LoadString(line_edit->text().toStdString()); other_setting->LoadString(line_edit->text().toStdString());
}; };
} else { } else {
QObject::connect(restore_button, &QAbstractButton::clicked, QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
[=](bool) { line_edit->setText(default_val); }); line_edit->setText(QString::fromStdString(other_setting->ToStringGlobal()));
});
QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) {
restore_button->setEnabled(true); restore_button->setEnabled(true);
@ -279,7 +346,7 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
load_func = [=]() { load_func = [=]() {
checkbox_load_func(); checkbox_load_func();
const bool using_global = !restore_button->isVisible(); const bool using_global = !restore_button->isEnabled();
other_setting->SetGlobal(using_global); other_setting->SetGlobal(using_global);
if (!using_global) { if (!using_global) {
other_setting->LoadString(line_edit->text().toStdString()); other_setting->LoadString(line_edit->text().toStdString());
@ -289,7 +356,8 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet
} }
void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func, const QString& suffix) { std::function<void()>& load_func,
const std::string& suffix) {
if (other_setting == nullptr && IsInt(other_setting->TypeId())) { if (other_setting == nullptr && IsInt(other_setting->TypeId())) {
LOG_WARNING(Frontend, "Extra setting is null or not an integer"); LOG_WARNING(Frontend, "Extra setting is null or not an integer");
return; return;
@ -308,7 +376,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
const int default_val = std::stoi(other_setting->ToString()); const int default_val = std::stoi(other_setting->ToString());
spinbox->setRange(min_val, max_val); spinbox->setRange(min_val, max_val);
spinbox->setValue(default_val); spinbox->setValue(default_val);
spinbox->setSuffix(suffix); spinbox->setSuffix(QString::fromStdString(suffix));
spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->insertWidget(1, spinbox); layout->insertWidget(1, spinbox);
@ -320,7 +388,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
}; };
} else { } else {
QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) { QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) {
spinbox->setValue(std::stoi(other_setting->ToString())); spinbox->setValue(std::stoi(other_setting->ToStringGlobal()));
}); });
QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) { QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) {
@ -331,7 +399,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
load_func = [=]() { load_func = [=]() {
checkbox_load_func(); checkbox_load_func();
const bool using_global = !restore_button->isVisible(); const bool using_global = !restore_button->isEnabled();
other_setting->SetGlobal(using_global); other_setting->SetGlobal(using_global);
if (!using_global) { if (!using_global) {
other_setting->LoadString(std::to_string(spinbox->value())); other_setting->LoadString(std::to_string(spinbox->value()));
@ -340,6 +408,81 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett
} }
} }
// Currently tailored to custom_rtc
void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label,
Settings::BasicSetting* other_setting,
std::function<void()>& load_func) {
if (other_setting == nullptr) {
LOG_WARNING(Frontend, "Extra setting is null or not an integer");
return;
}
created = true;
std::function<void()> checkbox_load_func;
CreateCheckBox(label, checkbox_load_func);
QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
const bool disabled = setting.ToString() != "true";
const long long current_time = QDateTime::currentSecsSinceEpoch();
const s64 the_time = disabled ? current_time : std::stoll(other_setting->ToString());
const auto default_val = QDateTime::fromSecsSinceEpoch(the_time);
date_time_edit = new QDateTimeEdit(this);
date_time_edit->setDateTime(default_val);
date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0));
date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->insertWidget(1, date_time_edit);
if (Settings::IsConfiguringGlobal()) {
load_func = [=]() {
checkbox_load_func();
if (checkbox->checkState() == Qt::Unchecked) {
return;
}
other_setting->LoadString(
std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()));
};
} else {
auto get_clear_val = [=]() {
return QDateTime::fromSecsSinceEpoch([=]() {
if (checkbox->checkState() == Qt::Checked) {
return std::stoll(other_setting->ToStringGlobal());
}
return current_time;
}());
};
QObject::connect(restore_button, &QAbstractButton::clicked,
[=](bool) { date_time_edit->setDateTime(get_clear_val()); });
QObject::connect(date_time_edit, &QDateTimeEdit::editingFinished, [=]() {
if (date_time_edit->dateTime() != get_clear_val()) {
restore_button->setEnabled(true);
restore_button->setVisible(true);
}
});
load_func = [=]() {
checkbox_load_func();
if (checkbox->checkState() == Qt::Unchecked) {
return;
}
const bool using_global = !restore_button->isEnabled();
other_setting->SetGlobal(using_global);
if (!using_global) {
other_setting->LoadString(
std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()));
}
};
}
}
bool Widget::Valid() { bool Widget::Valid() {
return created; return created;
} }
@ -350,7 +493,7 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
QWidget* parent_, bool runtime_lock, QWidget* parent_, bool runtime_lock,
std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request, std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request,
bool managed, float multiplier, Settings::BasicSetting* other_setting, bool managed, float multiplier, Settings::BasicSetting* other_setting,
const QString& format) const std::string& string)
: QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} { : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} {
if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
@ -379,19 +522,26 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
if (type == typeid(bool)) { if (type == typeid(bool)) {
switch (request) { switch (request) {
case RequestType::SpinBox:
CreateCheckBoxWithSpinBox(label, other_setting, load_func, format);
break;
case RequestType::Default: case RequestType::Default:
CreateCheckBox(label, load_func); CreateCheckBox(label, load_func);
break; break;
case RequestType::SpinBox:
CreateCheckBoxWithSpinBox(label, other_setting, load_func, string);
break;
case RequestType::HexEdit:
CreateCheckBoxWithHexEdit(label, other_setting, load_func);
break;
case RequestType::LineEdit: case RequestType::LineEdit:
CreateCheckBoxWithLineEdit(label, other_setting, load_func); CreateCheckBoxWithLineEdit(label, other_setting, load_func);
break; break;
case RequestType::DateTimeEdit:
CreateCheckBoxWithDateTimeEdit(label, other_setting, load_func);
break;
case RequestType::ComboBox: case RequestType::ComboBox:
case RequestType::Slider: case RequestType::Slider:
case RequestType::ReverseSlider: case RequestType::ReverseSlider:
case RequestType::MaxEnum: case RequestType::MaxEnum:
LOG_DEBUG(Frontend, "Requested widget is unimplemented.");
break; break;
} }
} else if (setting.IsEnum()) { } else if (setting.IsEnum()) {
@ -409,10 +559,15 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
case RequestType::ComboBox: case RequestType::ComboBox:
CreateCombobox(label, managed, load_func); CreateCombobox(label, managed, load_func);
break; break;
case RequestType::DateTimeEdit:
case RequestType::SpinBox: case RequestType::SpinBox:
case RequestType::HexEdit:
case RequestType::MaxEnum: case RequestType::MaxEnum:
LOG_DEBUG(Frontend, "Requested widget is unimplemented.");
break; break;
} }
} else if (type == typeid(std::string)) {
CreateLineEdit(label, managed, load_func);
} }
if (!created) { if (!created) {

View file

@ -9,6 +9,7 @@ class QComboBox;
class QLineEdit; class QLineEdit;
class QSlider; class QSlider;
class QCheckBox; class QCheckBox;
class QDateTimeEdit;
namespace Settings { namespace Settings {
class BasicSetting; class BasicSetting;
@ -23,6 +24,8 @@ enum class RequestType {
Slider, Slider,
ReverseSlider, ReverseSlider,
LineEdit, LineEdit,
HexEdit,
DateTimeEdit,
MaxEnum, MaxEnum,
}; };
@ -33,8 +36,7 @@ public:
Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f,
Settings::BasicSetting* other_setting = nullptr, Settings::BasicSetting* other_setting = nullptr, const std::string& format = "");
const QString& format = QStringLiteral(""));
virtual ~Widget(); virtual ~Widget();
bool Valid(); bool Valid();
@ -48,13 +50,18 @@ public:
QCheckBox* checkbox{}; QCheckBox* checkbox{};
QSlider* slider{}; QSlider* slider{};
QComboBox* combobox{}; QComboBox* combobox{};
QDateTimeEdit* date_time_edit{};
private: private:
void CreateCheckBox(const QString& label, std::function<void()>& load_func); void CreateCheckBox(const QString& label, std::function<void()>& load_func);
void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func); std::function<void()>& load_func);
void CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func);
void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func, const QString& suffix); std::function<void()>& load_func, const std::string& suffix);
void CreateCheckBoxWithDateTimeEdit(const QString& label, Settings::BasicSetting* other_setting,
std::function<void()>& load_func);
void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func); void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func);
void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func); void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func);
void CreateSlider(const QString& label, bool reversed, float multiplier, void CreateSlider(const QString& label, bool reversed, float multiplier,

View file

@ -229,6 +229,7 @@ void Config::ReadValues() {
ReadCategory(Settings::Category::RendererAdvanced); ReadCategory(Settings::Category::RendererAdvanced);
ReadCategory(Settings::Category::RendererDebug); ReadCategory(Settings::Category::RendererDebug);
ReadCategory(Settings::Category::System); ReadCategory(Settings::Category::System);
ReadCategory(Settings::Category::SystemAudio);
ReadCategory(Settings::Category::DataStorage); ReadCategory(Settings::Category::DataStorage);
ReadCategory(Settings::Category::Debugging); ReadCategory(Settings::Category::Debugging);
ReadCategory(Settings::Category::DebuggingGraphics); ReadCategory(Settings::Category::DebuggingGraphics);