3
0
Fork 0
forked from suyu/suyu

Merge pull request #6321 from lat9nq/per-game-cpu

configuration: Add CPU tab to game properties and slight per-game settings rework
This commit is contained in:
bunnei 2021-05-20 20:10:56 -07:00 committed by GitHub
commit 7626ca3343
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 290 additions and 302 deletions

View file

@ -42,7 +42,7 @@ void LogSettings() {
log_setting("System_RegionIndex", values.region_index.GetValue()); log_setting("System_RegionIndex", values.region_index.GetValue());
log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue()); log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
log_setting("Core_UseMultiCore", values.use_multi_core.GetValue()); log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
log_setting("CPU_Accuracy", values.cpu_accuracy); log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue());
log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue()); log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue()); log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue());
log_setting("Renderer_FrameLimit", values.frame_limit.GetValue()); log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
@ -106,6 +106,12 @@ void RestoreGlobalState(bool is_powered_on) {
// Core // Core
values.use_multi_core.SetGlobal(true); values.use_multi_core.SetGlobal(true);
// CPU
values.cpu_accuracy.SetGlobal(true);
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
// Renderer // Renderer
values.renderer_backend.SetGlobal(true); values.renderer_backend.SetGlobal(true);
values.vulkan_device.SetGlobal(true); values.vulkan_device.SetGlobal(true);
@ -130,7 +136,6 @@ void RestoreGlobalState(bool is_powered_on) {
values.region_index.SetGlobal(true); values.region_index.SetGlobal(true);
values.time_zone_index.SetGlobal(true); values.time_zone_index.SetGlobal(true);
values.rng_seed.SetGlobal(true); values.rng_seed.SetGlobal(true);
values.custom_rtc.SetGlobal(true);
values.sound_index.SetGlobal(true); values.sound_index.SetGlobal(true);
// Controls // Controls

View file

@ -115,7 +115,7 @@ struct Values {
Setting<bool> use_multi_core; Setting<bool> use_multi_core;
// Cpu // Cpu
CPUAccuracy cpu_accuracy; Setting<CPUAccuracy> cpu_accuracy;
bool cpuopt_page_tables; bool cpuopt_page_tables;
bool cpuopt_block_linking; bool cpuopt_block_linking;
@ -126,9 +126,9 @@ struct Values {
bool cpuopt_misc_ir; bool cpuopt_misc_ir;
bool cpuopt_reduce_misalign_checks; bool cpuopt_reduce_misalign_checks;
bool cpuopt_unsafe_unfuse_fma; Setting<bool> cpuopt_unsafe_unfuse_fma;
bool cpuopt_unsafe_reduce_fp_error; Setting<bool> cpuopt_unsafe_reduce_fp_error;
bool cpuopt_unsafe_inaccurate_nan; Setting<bool> cpuopt_unsafe_inaccurate_nan;
// Renderer // Renderer
Setting<RendererBackend> renderer_backend; Setting<RendererBackend> renderer_backend;
@ -157,7 +157,7 @@ struct Values {
// System // System
Setting<std::optional<u32>> rng_seed; Setting<std::optional<u32>> rng_seed;
// Measured in seconds since epoch // Measured in seconds since epoch
Setting<std::optional<std::chrono::seconds>> custom_rtc; std::optional<std::chrono::seconds> custom_rtc;
// 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`
std::chrono::seconds custom_rtc_differential; std::chrono::seconds custom_rtc_differential;

View file

@ -142,7 +142,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
config.far_code_offset = 256 * 1024 * 1024; config.far_code_offset = 256 * 1024 * 1024;
// Safe optimizations // Safe optimizations
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) { if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
if (!Settings::values.cpuopt_page_tables) { if (!Settings::values.cpuopt_page_tables) {
config.page_table = nullptr; config.page_table = nullptr;
} }
@ -170,15 +170,15 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
} }
// Unsafe optimizations // Unsafe optimizations
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) { if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
config.unsafe_optimizations = true; config.unsafe_optimizations = true;
if (Settings::values.cpuopt_unsafe_unfuse_fma) { if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
} }
if (Settings::values.cpuopt_unsafe_reduce_fp_error) { if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
} }
if (Settings::values.cpuopt_unsafe_inaccurate_nan) { if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
} }
} }

View file

@ -182,7 +182,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
config.far_code_offset = 256 * 1024 * 1024; config.far_code_offset = 256 * 1024 * 1024;
// Safe optimizations // Safe optimizations
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) { if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
if (!Settings::values.cpuopt_page_tables) { if (!Settings::values.cpuopt_page_tables) {
config.page_table = nullptr; config.page_table = nullptr;
} }
@ -210,15 +210,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
} }
// Unsafe optimizations // Unsafe optimizations
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) { if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
config.unsafe_optimizations = true; config.unsafe_optimizations = true;
if (Settings::values.cpuopt_unsafe_unfuse_fma) { if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
} }
if (Settings::values.cpuopt_unsafe_reduce_fp_error) { if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
} }
if (Settings::values.cpuopt_unsafe_inaccurate_nan) { if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
} }
} }

View file

@ -173,7 +173,7 @@ struct System::Impl {
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()); std::chrono::system_clock::now().time_since_epoch());
Settings::values.custom_rtc_differential = Settings::values.custom_rtc_differential =
Settings::values.custom_rtc.GetValue().value_or(current_time) - current_time; Settings::values.custom_rtc.value_or(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)

View file

@ -736,10 +736,16 @@ void Config::ReadPathValues() {
void Config::ReadCpuValues() { void Config::ReadCpuValues() {
qt_config->beginGroup(QStringLiteral("Cpu")); qt_config->beginGroup(QStringLiteral("Cpu"));
if (global) { ReadSettingGlobal(Settings::values.cpu_accuracy, QStringLiteral("cpu_accuracy"), 0);
Settings::values.cpu_accuracy = static_cast<Settings::CPUAccuracy>(
ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt());
ReadSettingGlobal(Settings::values.cpuopt_unsafe_unfuse_fma,
QStringLiteral("cpuopt_unsafe_unfuse_fma"), true);
ReadSettingGlobal(Settings::values.cpuopt_unsafe_reduce_fp_error,
QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
if (global) {
Settings::values.cpuopt_page_tables = Settings::values.cpuopt_page_tables =
ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool(); ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
Settings::values.cpuopt_block_linking = Settings::values.cpuopt_block_linking =
@ -756,13 +762,6 @@ void Config::ReadCpuValues() {
ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool(); ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
Settings::values.cpuopt_reduce_misalign_checks = Settings::values.cpuopt_reduce_misalign_checks =
ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool(); ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
Settings::values.cpuopt_unsafe_unfuse_fma =
ReadSetting(QStringLiteral("cpuopt_unsafe_unfuse_fma"), true).toBool();
Settings::values.cpuopt_unsafe_reduce_fp_error =
ReadSetting(QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true).toBool();
Settings::values.cpuopt_unsafe_inaccurate_nan =
ReadSetting(QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true).toBool();
} }
qt_config->endGroup(); qt_config->endGroup();
@ -869,17 +868,14 @@ void Config::ReadSystemValues() {
} }
} }
bool custom_rtc_enabled; if (global) {
ReadSettingGlobal(custom_rtc_enabled, QStringLiteral("custom_rtc_enabled"), false); const auto custom_rtc_enabled =
bool custom_rtc_global = ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
global || qt_config->value(QStringLiteral("custom_rtc/use_global"), true).toBool();
Settings::values.custom_rtc.SetGlobal(custom_rtc_global);
if (global || !custom_rtc_global) {
if (custom_rtc_enabled) { if (custom_rtc_enabled) {
Settings::values.custom_rtc.SetValue( Settings::values.custom_rtc =
std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong())); std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
} else { } else {
Settings::values.custom_rtc.SetValue(std::nullopt); Settings::values.custom_rtc = std::nullopt;
} }
} }
@ -1313,10 +1309,19 @@ void Config::SavePathValues() {
void Config::SaveCpuValues() { void Config::SaveCpuValues() {
qt_config->beginGroup(QStringLiteral("Cpu")); qt_config->beginGroup(QStringLiteral("Cpu"));
if (global) { WriteSettingGlobal(QStringLiteral("cpu_accuracy"),
WriteSetting(QStringLiteral("cpu_accuracy"), static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)),
static_cast<int>(Settings::values.cpu_accuracy), 0); Settings::values.cpu_accuracy.UsingGlobal(),
static_cast<u32>(Settings::CPUAccuracy::Accurate));
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_unfuse_fma"),
Settings::values.cpuopt_unsafe_unfuse_fma, true);
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_reduce_fp_error"),
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
if (global) {
WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables, WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
true); true);
WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking, WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
@ -1331,13 +1336,6 @@ void Config::SaveCpuValues() {
WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true); WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
Settings::values.cpuopt_reduce_misalign_checks, true); Settings::values.cpuopt_reduce_misalign_checks, true);
WriteSetting(QStringLiteral("cpuopt_unsafe_unfuse_fma"),
Settings::values.cpuopt_unsafe_unfuse_fma, true);
WriteSetting(QStringLiteral("cpuopt_unsafe_reduce_fp_error"),
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
WriteSetting(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
} }
qt_config->endGroup(); qt_config->endGroup();
@ -1432,14 +1430,14 @@ void Config::SaveSystemValues() {
Settings::values.rng_seed.GetValue(global).value_or(0), Settings::values.rng_seed.GetValue(global).value_or(0),
Settings::values.rng_seed.UsingGlobal(), 0); Settings::values.rng_seed.UsingGlobal(), 0);
WriteSettingGlobal(QStringLiteral("custom_rtc_enabled"), if (global) {
Settings::values.custom_rtc.GetValue(global).has_value(), WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
Settings::values.custom_rtc.UsingGlobal(), false); false);
WriteSettingGlobal( WriteSetting(QStringLiteral("custom_rtc"),
QStringLiteral("custom_rtc"),
QVariant::fromValue<long long>( QVariant::fromValue<long long>(
Settings::values.custom_rtc.GetValue(global).value_or(std::chrono::seconds{}).count()), Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
Settings::values.custom_rtc.UsingGlobal(), 0); 0);
}
WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1); WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1);

View file

@ -132,5 +132,6 @@ private:
}; };
// These metatype declarations cannot be in common/settings.h because core is devoid of QT // These metatype declarations cannot be in common/settings.h because core is devoid of QT
Q_DECLARE_METATYPE(Settings::CPUAccuracy);
Q_DECLARE_METATYPE(Settings::RendererBackend); Q_DECLARE_METATYPE(Settings::RendererBackend);
Q_DECLARE_METATYPE(Settings::GPUAccuracy); Q_DECLARE_METATYPE(Settings::GPUAccuracy);

View file

@ -13,6 +13,9 @@
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting, void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
const QCheckBox* checkbox, const QCheckBox* checkbox,
const CheckState& tracker) { const CheckState& tracker) {
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
setting->SetValue(checkbox->checkState());
} else if (!Settings::IsConfiguringGlobal()) {
if (tracker == CheckState::Global) { if (tracker == CheckState::Global) {
setting->SetGlobal(true); setting->SetGlobal(true);
} else { } else {
@ -20,9 +23,13 @@ void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
setting->SetValue(checkbox->checkState()); setting->SetValue(checkbox->checkState());
} }
} }
}
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting, void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting,
const QComboBox* combobox) { const QComboBox* combobox) {
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
setting->SetValue(combobox->currentIndex());
} else if (!Settings::IsConfiguringGlobal()) {
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
setting->SetGlobal(true); setting->SetGlobal(true);
} else { } else {
@ -30,16 +37,6 @@ void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting,
setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET); setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET);
} }
} }
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting,
const QComboBox* combobox) {
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
setting->SetGlobal(true);
} else {
setting->SetGlobal(false);
setting->SetValue(static_cast<Settings::RendererBackend>(
combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET));
}
} }
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox, void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
@ -51,27 +48,6 @@ void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
} }
} }
void ConfigurationShared::SetPerGameSetting(QComboBox* combobox,
const Settings::Setting<int>* setting) {
combobox->setCurrentIndex(setting->UsingGlobal()
? ConfigurationShared::USE_GLOBAL_INDEX
: setting->GetValue() + ConfigurationShared::USE_GLOBAL_OFFSET);
}
void ConfigurationShared::SetPerGameSetting(
QComboBox* combobox, const Settings::Setting<Settings::RendererBackend>* setting) {
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
: static_cast<int>(setting->GetValue()) +
ConfigurationShared::USE_GLOBAL_OFFSET);
}
void ConfigurationShared::SetPerGameSetting(
QComboBox* combobox, const Settings::Setting<Settings::GPUAccuracy>* setting) {
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
: static_cast<int>(setting->GetValue()) +
ConfigurationShared::USE_GLOBAL_OFFSET);
}
void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) { void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
if (highlighted) { if (highlighted) {
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }") widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")

View file

@ -15,37 +15,45 @@ constexpr int USE_GLOBAL_INDEX = 0;
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1; constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
constexpr int USE_GLOBAL_OFFSET = 2; constexpr int USE_GLOBAL_OFFSET = 2;
// CheckBoxes require a tracker for their state since we emulate a tristate CheckBox
enum class CheckState { enum class CheckState {
Off, Off, // Checkbox overrides to off/false
On, On, // Checkbox overrides to on/true
Global, Global, // Checkbox defers to the global state
Count, Count, // Simply the number of states, not a valid checkbox state
}; };
// Global-aware apply and set functions // Global-aware apply and set functions
// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox, void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox,
const CheckState& tracker); const CheckState& tracker);
void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox); void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox);
void ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting,
const QComboBox* combobox);
void ApplyPerGameSetting(Settings::Setting<Settings::GPUAccuracy>* setting,
const QComboBox* combobox);
// Sets a Qt UI element given a Settings::Setting
void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting); void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting);
void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<int>* setting);
void SetPerGameSetting(QComboBox* combobox,
const Settings::Setting<Settings::RendererBackend>* setting);
void SetPerGameSetting(QComboBox* combobox,
const Settings::Setting<Settings::GPUAccuracy>* setting);
template <typename Type>
void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<Type>* setting) {
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
: static_cast<int>(setting->GetValue()) +
ConfigurationShared::USE_GLOBAL_OFFSET);
}
// (Un)highlights a Qt UI element
void SetHighlight(QWidget* widget, bool highlighted); void SetHighlight(QWidget* widget, bool highlighted);
// Sets up a QCheckBox like a tristate one, given a Setting
void SetColoredTristate(QCheckBox* checkbox, const Settings::Setting<bool>& setting, void SetColoredTristate(QCheckBox* checkbox, const Settings::Setting<bool>& setting,
CheckState& tracker); CheckState& tracker);
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state, void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
CheckState& tracker); CheckState& tracker);
// Sets up coloring of a QWidget `target` based on the state of a QComboBox, and calls
// InsertGlobalItem
void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global); void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global);
// Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox
void InsertGlobalItem(QComboBox* combobox, int global_index); void InsertGlobalItem(QComboBox* combobox, int global_index);
} // namespace ConfigurationShared } // namespace ConfigurationShared

View file

@ -99,6 +99,9 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
} }
void ConfigureAudio::ApplyConfiguration() { void ConfigureAudio::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
ui->toggle_audio_stretching, enable_audio_stretching);
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
Settings::values.sink_id = Settings::values.sink_id =
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
@ -108,19 +111,12 @@ void ConfigureAudio::ApplyConfiguration() {
.toStdString(); .toStdString();
// Guard if during game and set to game-specific value // Guard if during game and set to game-specific value
if (Settings::values.enable_audio_stretching.UsingGlobal()) {
Settings::values.enable_audio_stretching.SetValue(
ui->toggle_audio_stretching->isChecked());
}
if (Settings::values.volume.UsingGlobal()) { if (Settings::values.volume.UsingGlobal()) {
Settings::values.volume.SetValue( Settings::values.volume.SetValue(
static_cast<float>(ui->volume_slider->sliderPosition()) / static_cast<float>(ui->volume_slider->sliderPosition()) /
ui->volume_slider->maximum()); ui->volume_slider->maximum());
} }
} else { } else {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
ui->toggle_audio_stretching,
enable_audio_stretching);
if (ui->volume_combo_box->currentIndex() == 0) { if (ui->volume_combo_box->currentIndex() == 0) {
Settings::values.volume.SetGlobal(true); Settings::values.volume.SetGlobal(true);
} else { } else {

View file

@ -10,11 +10,14 @@
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
#include "ui_configure_cpu.h" #include "ui_configure_cpu.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_cpu.h" #include "yuzu/configuration/configure_cpu.h"
ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) { ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) {
ui->setupUi(this); ui->setupUi(this);
SetupPerGameUI();
SetConfiguration(); SetConfiguration();
connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this, connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
@ -29,19 +32,29 @@ void ConfigureCpu::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
ui->accuracy->setEnabled(runtime_lock); ui->accuracy->setEnabled(runtime_lock);
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
UpdateGroup(static_cast<int>(Settings::values.cpu_accuracy));
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock); ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma);
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock); ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
ui->cpuopt_unsafe_reduce_fp_error->setChecked(Settings::values.cpuopt_unsafe_reduce_fp_error);
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock); ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
ui->cpuopt_unsafe_inaccurate_nan->setChecked(Settings::values.cpuopt_unsafe_inaccurate_nan);
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
} else {
ConfigurationShared::SetPerGameSetting(ui->accuracy, &Settings::values.cpu_accuracy);
ConfigurationShared::SetHighlight(ui->widget_accuracy,
!Settings::values.cpu_accuracy.UsingGlobal());
}
UpdateGroup(ui->accuracy->currentIndex());
} }
void ConfigureCpu::AccuracyUpdated(int index) { void ConfigureCpu::AccuracyUpdated(int index) {
if (static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) { if (Settings::IsConfiguringGlobal() &&
static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"), const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
tr("CPU Debug Mode is only intended for developer " tr("CPU Debug Mode is only intended for developer "
"use. Are you sure you want to enable this?"), "use. Are you sure you want to enable this?"),
@ -54,16 +67,39 @@ void ConfigureCpu::AccuracyUpdated(int index) {
} }
void ConfigureCpu::UpdateGroup(int index) { void ConfigureCpu::UpdateGroup(int index) {
ui->unsafe_group->setVisible(static_cast<Settings::CPUAccuracy>(index) == if (!Settings::IsConfiguringGlobal()) {
Settings::CPUAccuracy::Unsafe); index -= ConfigurationShared::USE_GLOBAL_OFFSET;
}
const auto accuracy = static_cast<Settings::CPUAccuracy>(index);
ui->unsafe_group->setVisible(accuracy == Settings::CPUAccuracy::Unsafe);
} }
void ConfigureCpu::ApplyConfiguration() { void ConfigureCpu::ApplyConfiguration() {
Settings::values.cpu_accuracy = ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma,
static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex()); ui->cpuopt_unsafe_unfuse_fma,
Settings::values.cpuopt_unsafe_unfuse_fma = ui->cpuopt_unsafe_unfuse_fma->isChecked(); cpuopt_unsafe_unfuse_fma);
Settings::values.cpuopt_unsafe_reduce_fp_error = ui->cpuopt_unsafe_reduce_fp_error->isChecked(); ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_reduce_fp_error,
Settings::values.cpuopt_unsafe_inaccurate_nan = ui->cpuopt_unsafe_inaccurate_nan->isChecked(); ui->cpuopt_unsafe_reduce_fp_error,
cpuopt_unsafe_reduce_fp_error);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
ui->cpuopt_unsafe_inaccurate_nan,
cpuopt_unsafe_inaccurate_nan);
if (Settings::IsConfiguringGlobal()) {
// Guard if during game and set to game-specific value
if (Settings::values.cpu_accuracy.UsingGlobal()) {
Settings::values.cpu_accuracy.SetValue(
static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex()));
}
} else {
if (ui->accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
Settings::values.cpu_accuracy.SetGlobal(true);
} else {
Settings::values.cpu_accuracy.SetGlobal(false);
Settings::values.cpu_accuracy.SetValue(static_cast<Settings::CPUAccuracy>(
ui->accuracy->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET));
}
}
} }
void ConfigureCpu::changeEvent(QEvent* event) { void ConfigureCpu::changeEvent(QEvent* event) {
@ -77,3 +113,25 @@ void ConfigureCpu::changeEvent(QEvent* event) {
void ConfigureCpu::RetranslateUI() { void ConfigureCpu::RetranslateUI() {
ui->retranslateUi(this); ui->retranslateUi(this);
} }
void ConfigureCpu::SetupPerGameUI() {
if (Settings::IsConfiguringGlobal()) {
return;
}
ConfigurationShared::SetColoredComboBox(
ui->accuracy, ui->widget_accuracy,
static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true)));
ui->accuracy->removeItem(static_cast<u32>(Settings::CPUAccuracy::DebugMode) +
ConfigurationShared::USE_GLOBAL_OFFSET);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma,
Settings::values.cpuopt_unsafe_unfuse_fma,
cpuopt_unsafe_unfuse_fma);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_reduce_fp_error,
Settings::values.cpuopt_unsafe_reduce_fp_error,
cpuopt_unsafe_reduce_fp_error);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
Settings::values.cpuopt_unsafe_inaccurate_nan,
cpuopt_unsafe_inaccurate_nan);
}

View file

@ -8,6 +8,10 @@
#include <QWidget> #include <QWidget>
#include "common/settings.h" #include "common/settings.h"
namespace ConfigurationShared {
enum class CheckState;
}
namespace Ui { namespace Ui {
class ConfigureCpu; class ConfigureCpu;
} }
@ -30,5 +34,11 @@ private:
void SetConfiguration(); void SetConfiguration();
void SetupPerGameUI();
std::unique_ptr<Ui::ConfigureCpu> ui; std::unique_ptr<Ui::ConfigureCpu> ui;
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
}; };

View file

@ -23,9 +23,10 @@
</property> </property>
<layout class="QVBoxLayout"> <layout class="QVBoxLayout">
<item> <item>
<layout class="QHBoxLayout"> <widget class="QWidget" name="widget_accuracy" native="true">
<layout class="QHBoxLayout" name="layout_accuracy">
<item> <item>
<widget class="QLabel"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Accuracy:</string> <string>Accuracy:</string>
</property> </property>
@ -51,14 +52,15 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item> </item>
<item> <item>
<widget class="QLabel"> <widget class="QLabel" name="label">
<property name="wordWrap">
<bool>1</bool>
</property>
<property name="text"> <property name="text">
<string>We recommend setting accuracy to "Accurate".</string> <string>We recommend setting accuracy to &quot;Accurate&quot;.</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -76,49 +78,49 @@
</property> </property>
<layout class="QVBoxLayout"> <layout class="QVBoxLayout">
<item> <item>
<widget class="QLabel"> <widget class="QLabel" name="label">
<property name="wordWrap">
<bool>1</bool>
</property>
<property name="text"> <property name="text">
<string>These settings reduce accuracy for speed.</string> <string>These settings reduce accuracy for speed.</string>
</property> </property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma"> <widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma">
<property name="text">
<string>Unfuse FMA (improve performance on CPUs without FMA)</string>
</property>
<property name="toolTip"> <property name="toolTip">
<string> <string>
&lt;div&gt;This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.&lt;/div&gt; &lt;div&gt;This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.&lt;/div&gt;
</string> </string>
</property> </property>
<property name="text">
<string>Unfuse FMA (improve performance on CPUs without FMA)</string>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error"> <widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error">
<property name="text">
<string>Faster FRSQRTE and FRECPE</string>
</property>
<property name="toolTip"> <property name="toolTip">
<string> <string>
&lt;div&gt;This option improves the speed of some approximate floating-point functions by using less accurate native approximations.&lt;/div&gt; &lt;div&gt;This option improves the speed of some approximate floating-point functions by using less accurate native approximations.&lt;/div&gt;
</string> </string>
</property> </property>
<property name="text">
<string>Faster FRSQRTE and FRECPE</string>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan"> <widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan">
<property name="text">
<string>Inaccurate NaN handling</string>
</property>
<property name="toolTip"> <property name="toolTip">
<string> <string>
&lt;div&gt;This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.&lt;/div&gt; &lt;div&gt;This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.&lt;/div&gt;
</string> </string>
</property> </property>
<property name="text">
<string>Inaccurate NaN handling</string>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View file

@ -50,6 +50,9 @@ void ConfigureGeneral::SetConfiguration() {
} }
void ConfigureGeneral::ApplyConfiguration() { void ConfigureGeneral::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
use_multi_core);
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked(); UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked();
@ -62,13 +65,7 @@ void ConfigureGeneral::ApplyConfiguration() {
Qt::Checked); Qt::Checked);
Settings::values.frame_limit.SetValue(ui->frame_limit->value()); Settings::values.frame_limit.SetValue(ui->frame_limit->value());
} }
if (Settings::values.use_multi_core.UsingGlobal()) {
Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked());
}
} else { } else {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core,
ui->use_multi_core, use_multi_core);
bool global_frame_limit = use_frame_limit == ConfigurationShared::CheckState::Global; bool global_frame_limit = use_frame_limit == ConfigurationShared::CheckState::Global;
Settings::values.use_frame_limit.SetGlobal(global_frame_limit); Settings::values.use_frame_limit.SetGlobal(global_frame_limit);
Settings::values.frame_limit.SetGlobal(global_frame_limit); Settings::values.frame_limit.SetGlobal(global_frame_limit);
@ -94,6 +91,9 @@ void ConfigureGeneral::RetranslateUI() {
void ConfigureGeneral::SetupPerGameUI() { void ConfigureGeneral::SetupPerGameUI() {
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
// Disables each setting if:
// - A game is running (thus settings in use), and
// - A non-global setting is applied.
ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal()); ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal());
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal()); ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());

View file

@ -106,6 +106,19 @@ void ConfigureGraphics::SetConfiguration() {
} }
void ConfigureGraphics::ApplyConfiguration() { void ConfigureGraphics::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.fullscreen_mode,
ui->fullscreen_mode_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio,
ui->aspect_ratio_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
ui->use_disk_shader_cache, use_disk_shader_cache);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
ui->use_asynchronous_gpu_emulation,
use_asynchronous_gpu_emulation);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_nvdec_emulation,
ui->use_nvdec_emulation, use_nvdec_emulation);
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
// Guard if during game and set to game-specific value // Guard if during game and set to game-specific value
if (Settings::values.renderer_backend.UsingGlobal()) { if (Settings::values.renderer_backend.UsingGlobal()) {
@ -114,22 +127,6 @@ void ConfigureGraphics::ApplyConfiguration() {
if (Settings::values.vulkan_device.UsingGlobal()) { if (Settings::values.vulkan_device.UsingGlobal()) {
Settings::values.vulkan_device.SetValue(vulkan_device); Settings::values.vulkan_device.SetValue(vulkan_device);
} }
if (Settings::values.fullscreen_mode.UsingGlobal()) {
Settings::values.fullscreen_mode.SetValue(ui->fullscreen_mode_combobox->currentIndex());
}
if (Settings::values.aspect_ratio.UsingGlobal()) {
Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex());
}
if (Settings::values.use_disk_shader_cache.UsingGlobal()) {
Settings::values.use_disk_shader_cache.SetValue(ui->use_disk_shader_cache->isChecked());
}
if (Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()) {
Settings::values.use_asynchronous_gpu_emulation.SetValue(
ui->use_asynchronous_gpu_emulation->isChecked());
}
if (Settings::values.use_nvdec_emulation.UsingGlobal()) {
Settings::values.use_nvdec_emulation.SetValue(ui->use_nvdec_emulation->isChecked());
}
if (Settings::values.bg_red.UsingGlobal()) { if (Settings::values.bg_red.UsingGlobal()) {
Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF())); Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF())); Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
@ -150,19 +147,6 @@ void ConfigureGraphics::ApplyConfiguration() {
} }
} }
ConfigurationShared::ApplyPerGameSetting(&Settings::values.fullscreen_mode,
ui->fullscreen_mode_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio,
ui->aspect_ratio_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
ui->use_disk_shader_cache, use_disk_shader_cache);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
ui->use_asynchronous_gpu_emulation,
use_asynchronous_gpu_emulation);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_nvdec_emulation,
ui->use_nvdec_emulation, use_nvdec_emulation);
if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
Settings::values.bg_red.SetGlobal(true); Settings::values.bg_red.SetGlobal(true);
Settings::values.bg_green.SetGlobal(true); Settings::values.bg_green.SetGlobal(true);

View file

@ -54,37 +54,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
ui->gpu_accuracy->currentIndex() - ui->gpu_accuracy->currentIndex() -
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET)); ((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
if (Settings::IsConfiguringGlobal()) {
// Must guard in case of a during-game configuration when set to be game-specific.
if (Settings::values.gpu_accuracy.UsingGlobal()) {
Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
}
if (Settings::values.use_vsync.UsingGlobal()) {
Settings::values.use_vsync.SetValue(ui->use_vsync->isChecked());
}
if (Settings::values.use_assembly_shaders.UsingGlobal()) {
Settings::values.use_assembly_shaders.SetValue(ui->use_assembly_shaders->isChecked());
}
if (Settings::values.use_asynchronous_shaders.UsingGlobal()) {
Settings::values.use_asynchronous_shaders.SetValue(
ui->use_asynchronous_shaders->isChecked());
}
if (Settings::values.use_asynchronous_shaders.UsingGlobal()) {
Settings::values.use_asynchronous_shaders.SetValue(
ui->use_asynchronous_shaders->isChecked());
}
if (Settings::values.use_fast_gpu_time.UsingGlobal()) {
Settings::values.use_fast_gpu_time.SetValue(ui->use_fast_gpu_time->isChecked());
}
if (Settings::values.max_anisotropy.UsingGlobal()) {
Settings::values.max_anisotropy.SetValue(
ui->anisotropic_filtering_combobox->currentIndex());
}
} else {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
ui->anisotropic_filtering_combobox); ui->anisotropic_filtering_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
use_vsync);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders, ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
ui->use_assembly_shaders, use_assembly_shaders); ui->use_assembly_shaders, use_assembly_shaders);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
@ -92,9 +64,13 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
use_asynchronous_shaders); use_asynchronous_shaders);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time, ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
ui->use_fast_gpu_time, use_fast_gpu_time); ui->use_fast_gpu_time, use_fast_gpu_time);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
ui->anisotropic_filtering_combobox);
if (Settings::IsConfiguringGlobal()) {
// Must guard in case of a during-game configuration when set to be game-specific.
if (Settings::values.gpu_accuracy.UsingGlobal()) {
Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
}
} else {
if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
Settings::values.gpu_accuracy.SetGlobal(true); Settings::values.gpu_accuracy.SetGlobal(true);
} else { } else {

View file

@ -52,6 +52,7 @@ ConfigurePerGame::~ConfigurePerGame() = default;
void ConfigurePerGame::ApplyConfiguration() { void ConfigurePerGame::ApplyConfiguration() {
ui->addonsTab->ApplyConfiguration(); ui->addonsTab->ApplyConfiguration();
ui->generalTab->ApplyConfiguration(); ui->generalTab->ApplyConfiguration();
ui->cpuTab->ApplyConfiguration();
ui->systemTab->ApplyConfiguration(); ui->systemTab->ApplyConfiguration();
ui->graphicsTab->ApplyConfiguration(); ui->graphicsTab->ApplyConfiguration();
ui->graphicsAdvancedTab->ApplyConfiguration(); ui->graphicsAdvancedTab->ApplyConfiguration();

View file

@ -235,6 +235,11 @@
<string>System</string> <string>System</string>
</attribute> </attribute>
</widget> </widget>
<widget class="ConfigureCpu" name="cpuTab">
<attribute name="title">
<string>CPU</string>
</attribute>
</widget>
<widget class="ConfigureGraphics" name="graphicsTab"> <widget class="ConfigureGraphics" name="graphicsTab">
<attribute name="title"> <attribute name="title">
<string>Graphics</string> <string>Graphics</string>
@ -311,6 +316,12 @@
<header>configuration/configure_per_game_addons.h</header> <header>configuration/configure_per_game_addons.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>ConfigureCpu</class>
<extends>QWidget</extends>
<header>configuration/configure_cpu.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections> <connections>

View file

@ -65,7 +65,7 @@ void ConfigureSystem::SetConfiguration() {
QStringLiteral("%1") QStringLiteral("%1")
.arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'}) .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
.toUpper(); .toUpper();
const auto rtc_time = Settings::values.custom_rtc.GetValue().value_or( const auto rtc_time = Settings::values.custom_rtc.value_or(
std::chrono::seconds(QDateTime::currentSecsSinceEpoch())); std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value()); ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
@ -73,9 +73,8 @@ void ConfigureSystem::SetConfiguration() {
Settings::values.rng_seed.UsingGlobal()); Settings::values.rng_seed.UsingGlobal());
ui->rng_seed_edit->setText(rng_seed); ui->rng_seed_edit->setText(rng_seed);
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.GetValue().has_value()); ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value() && ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
Settings::values.rng_seed.UsingGlobal());
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
@ -109,17 +108,17 @@ void ConfigureSystem::ApplyConfiguration() {
// Allow setting custom RTC even if system is powered on, // Allow setting custom RTC even if system is powered on,
// to allow in-game time to be fast forwarded // to allow in-game time to be fast forwarded
if (Settings::values.custom_rtc.UsingGlobal()) { if (Settings::IsConfiguringGlobal()) {
if (ui->custom_rtc_checkbox->isChecked()) { if (ui->custom_rtc_checkbox->isChecked()) {
Settings::values.custom_rtc.SetValue( Settings::values.custom_rtc =
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch())); std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
if (system.IsPoweredOn()) { if (system.IsPoweredOn()) {
const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() + const s64 posix_time{Settings::values.custom_rtc->count() +
Service::Time::TimeManager::GetExternalTimeZoneOffset()}; Service::Time::TimeManager::GetExternalTimeZoneOffset()};
system.GetTimeManager().UpdateLocalSystemClockTime(posix_time); system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
} }
} else { } else {
Settings::values.custom_rtc.SetValue(std::nullopt); Settings::values.custom_rtc = std::nullopt;
} }
} }
@ -127,21 +126,14 @@ void ConfigureSystem::ApplyConfiguration() {
return; 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.sound_index, ui->combo_sound);
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
// Guard if during game and set to game-specific value // Guard if during game and set to game-specific value
if (Settings::values.language_index.UsingGlobal()) {
Settings::values.language_index.SetValue(ui->combo_language->currentIndex());
}
if (Settings::values.region_index.UsingGlobal()) {
Settings::values.region_index.SetValue(ui->combo_region->currentIndex());
}
if (Settings::values.time_zone_index.UsingGlobal()) {
Settings::values.time_zone_index.SetValue(ui->combo_time_zone->currentIndex());
}
if (Settings::values.sound_index.UsingGlobal()) {
Settings::values.sound_index.SetValue(ui->combo_sound->currentIndex());
}
if (Settings::values.rng_seed.UsingGlobal()) { if (Settings::values.rng_seed.UsingGlobal()) {
if (ui->rng_seed_checkbox->isChecked()) { if (ui->rng_seed_checkbox->isChecked()) {
Settings::values.rng_seed.SetValue( Settings::values.rng_seed.SetValue(
@ -151,13 +143,6 @@ void ConfigureSystem::ApplyConfiguration() {
} }
} }
} else { } else {
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.sound_index, ui->combo_sound);
switch (use_rng_seed) { switch (use_rng_seed) {
case ConfigurationShared::CheckState::On: case ConfigurationShared::CheckState::On:
case ConfigurationShared::CheckState::Off: case ConfigurationShared::CheckState::Off:
@ -177,26 +162,6 @@ void ConfigureSystem::ApplyConfiguration() {
case ConfigurationShared::CheckState::Count: case ConfigurationShared::CheckState::Count:
break; break;
} }
switch (use_custom_rtc) {
case ConfigurationShared::CheckState::On:
case ConfigurationShared::CheckState::Off:
Settings::values.custom_rtc.SetGlobal(false);
if (ui->custom_rtc_checkbox->isChecked()) {
Settings::values.custom_rtc.SetValue(
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
} else {
Settings::values.custom_rtc.SetValue(std::nullopt);
}
break;
case ConfigurationShared::CheckState::Global:
Settings::values.custom_rtc.SetGlobal(false);
Settings::values.custom_rtc.SetValue(std::nullopt);
Settings::values.custom_rtc.SetGlobal(true);
break;
case ConfigurationShared::CheckState::Count:
break;
}
} }
system.ApplySettings(); system.ApplySettings();
@ -227,8 +192,6 @@ void ConfigureSystem::SetupPerGameUI() {
ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal()); ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal());
ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal()); ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal());
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal()); ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal());
ui->custom_rtc_checkbox->setEnabled(Settings::values.custom_rtc.UsingGlobal());
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.UsingGlobal());
return; return;
} }
@ -246,8 +209,7 @@ void ConfigureSystem::SetupPerGameUI() {
ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(), ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(),
Settings::values.rng_seed.GetValue().has_value(), Settings::values.rng_seed.GetValue().has_value(),
Settings::values.rng_seed.GetValue(true).has_value(), use_rng_seed); Settings::values.rng_seed.GetValue(true).has_value(), use_rng_seed);
ConfigurationShared::SetColoredTristate(
ui->custom_rtc_checkbox, Settings::values.custom_rtc.UsingGlobal(), ui->custom_rtc_checkbox->setVisible(false);
Settings::values.custom_rtc.GetValue().has_value(), ui->custom_rtc_edit->setVisible(false);
Settings::values.custom_rtc.GetValue(true).has_value(), use_custom_rtc);
} }

View file

@ -361,10 +361,10 @@ void Config::ReadValues() {
const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
if (custom_rtc_enabled) { if (custom_rtc_enabled) {
Settings::values.custom_rtc.SetValue( Settings::values.custom_rtc =
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0))); std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
} else { } else {
Settings::values.custom_rtc.SetValue(std::nullopt); Settings::values.custom_rtc = std::nullopt;
} }
Settings::values.language_index.SetValue( Settings::values.language_index.SetValue(