mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-07-01 17:17:58 -05:00
Merge pull request #10839 from lat9nq/pgc-plus
general: Reimplement per-game configurations
This commit is contained in:
@ -143,6 +143,10 @@ add_executable(yuzu
|
||||
configuration/configure_web.ui
|
||||
configuration/input_profiles.cpp
|
||||
configuration/input_profiles.h
|
||||
configuration/shared_translation.cpp
|
||||
configuration/shared_translation.h
|
||||
configuration/shared_widget.cpp
|
||||
configuration/shared_widget.h
|
||||
debugger/console.cpp
|
||||
debugger/console.h
|
||||
debugger/controller.cpp
|
||||
@ -231,6 +235,12 @@ if (WIN32 AND YUZU_CRASH_DUMPS)
|
||||
target_compile_definitions(yuzu PRIVATE -DYUZU_DBGHELP)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
target_compile_definitions(yuzu PRIVATE
|
||||
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE>
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB COMPAT_LIST
|
||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,7 +52,7 @@ public:
|
||||
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
|
||||
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
|
||||
static const std::map<bool, QString> use_docked_mode_texts_map;
|
||||
static const std::map<Settings::GPUAccuracy, QString> gpu_accuracy_texts_map;
|
||||
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map;
|
||||
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
|
||||
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;
|
||||
|
||||
@ -74,7 +74,6 @@ private:
|
||||
void ReadKeyboardValues();
|
||||
void ReadMouseValues();
|
||||
void ReadTouchscreenValues();
|
||||
void ReadMousePanningValues();
|
||||
void ReadMotionTouchValues();
|
||||
void ReadHidbusValues();
|
||||
void ReadIrCameraValues();
|
||||
@ -99,13 +98,13 @@ private:
|
||||
void ReadUILayoutValues();
|
||||
void ReadWebServiceValues();
|
||||
void ReadMultiplayerValues();
|
||||
void ReadNetworkValues();
|
||||
|
||||
void SaveValues();
|
||||
void SavePlayerValue(std::size_t player_index);
|
||||
void SaveDebugValues();
|
||||
void SaveMouseValues();
|
||||
void SaveTouchscreenValues();
|
||||
void SaveMousePanningValues();
|
||||
void SaveMotionTouchValues();
|
||||
void SaveHidbusValues();
|
||||
void SaveIrCameraValues();
|
||||
@ -140,18 +139,6 @@ private:
|
||||
QVariant ReadSetting(const QString& name) const;
|
||||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
||||
|
||||
/**
|
||||
* Only reads a setting from the qt_config if the current config is a global config, or if the
|
||||
* current config is a custom config and the setting is overriding the global setting. Otherwise
|
||||
* it does nothing.
|
||||
*
|
||||
* @param setting The variable to be modified
|
||||
* @param name The setting's identifier
|
||||
* @param default_value The value to use when the setting is not already present in the config
|
||||
*/
|
||||
template <typename Type>
|
||||
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
|
||||
|
||||
/**
|
||||
* Writes a setting to the qt_config.
|
||||
*
|
||||
@ -166,50 +153,20 @@ private:
|
||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
|
||||
bool use_global);
|
||||
|
||||
/**
|
||||
* Reads a value from the qt_config and applies it to the setting, using its label and default
|
||||
* value. If the config is a custom config, this will also read the global state of the setting
|
||||
* and apply that information to it.
|
||||
*
|
||||
* @param The setting
|
||||
*/
|
||||
template <typename Type, bool ranged>
|
||||
void ReadGlobalSetting(Settings::SwitchableSetting<Type, ranged>& setting);
|
||||
void ReadCategory(Settings::Category category);
|
||||
void WriteCategory(Settings::Category category);
|
||||
void ReadSettingGeneric(Settings::BasicSetting* const setting);
|
||||
void WriteSettingGeneric(Settings::BasicSetting* const setting) const;
|
||||
|
||||
/**
|
||||
* Sets a value to the qt_config using the setting's label and default value. If the config is a
|
||||
* custom config, it will apply the global state, and the custom value if needed.
|
||||
*
|
||||
* @param The setting
|
||||
*/
|
||||
template <typename Type, bool ranged>
|
||||
void WriteGlobalSetting(const Settings::SwitchableSetting<Type, ranged>& setting);
|
||||
|
||||
/**
|
||||
* Reads a value from the qt_config using the setting's label and default value and applies the
|
||||
* value to the setting.
|
||||
*
|
||||
* @param The setting
|
||||
*/
|
||||
template <typename Type, bool ranged>
|
||||
void ReadBasicSetting(Settings::Setting<Type, ranged>& setting);
|
||||
|
||||
/** Sets a value from the setting in the qt_config using the setting's label and default value.
|
||||
*
|
||||
* @param The setting
|
||||
*/
|
||||
template <typename Type, bool ranged>
|
||||
void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting);
|
||||
|
||||
ConfigType type;
|
||||
const ConfigType type;
|
||||
std::unique_ptr<QSettings> qt_config;
|
||||
std::string qt_config_loc;
|
||||
bool global;
|
||||
const bool global;
|
||||
};
|
||||
|
||||
// These metatype declarations cannot be in common/settings.h because core is devoid of QT
|
||||
Q_DECLARE_METATYPE(Settings::CPUAccuracy);
|
||||
Q_DECLARE_METATYPE(Settings::GPUAccuracy);
|
||||
Q_DECLARE_METATYPE(Settings::CpuAccuracy);
|
||||
Q_DECLARE_METATYPE(Settings::GpuAccuracy);
|
||||
Q_DECLARE_METATYPE(Settings::FullscreenMode);
|
||||
Q_DECLARE_METATYPE(Settings::NvdecEmulation);
|
||||
Q_DECLARE_METATYPE(Settings::ResolutionSetup);
|
||||
@ -218,3 +175,4 @@ Q_DECLARE_METATYPE(Settings::AntiAliasing);
|
||||
Q_DECLARE_METATYPE(Settings::RendererBackend);
|
||||
Q_DECLARE_METATYPE(Settings::ShaderBackend);
|
||||
Q_DECLARE_METATYPE(Settings::AstcRecompression);
|
||||
Q_DECLARE_METATYPE(Settings::AstcDecodeMode);
|
||||
|
@ -1,104 +1,19 @@
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "common/settings.h"
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_per_game.h"
|
||||
|
||||
void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting,
|
||||
const QCheckBox* checkbox,
|
||||
const CheckState& tracker) {
|
||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
||||
setting->SetValue(checkbox->checkState());
|
||||
} else if (!Settings::IsConfiguringGlobal()) {
|
||||
if (tracker == CheckState::Global) {
|
||||
setting->SetGlobal(true);
|
||||
} else {
|
||||
setting->SetGlobal(false);
|
||||
setting->SetValue(checkbox->checkState());
|
||||
}
|
||||
namespace ConfigurationShared {
|
||||
|
||||
Tab::Tab(std::shared_ptr<std::vector<Tab*>> group, QWidget* parent) : QWidget(parent) {
|
||||
if (group != nullptr) {
|
||||
group->push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
|
||||
const Settings::SwitchableSetting<bool>* setting) {
|
||||
if (setting->UsingGlobal()) {
|
||||
checkbox->setCheckState(Qt::PartiallyChecked);
|
||||
} else {
|
||||
checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
Tab::~Tab() = default;
|
||||
|
||||
void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
|
||||
if (highlighted) {
|
||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")
|
||||
.arg(widget->objectName()));
|
||||
} else {
|
||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }")
|
||||
.arg(widget->objectName()));
|
||||
}
|
||||
widget->show();
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox,
|
||||
const Settings::SwitchableSetting<bool>& setting,
|
||||
CheckState& tracker) {
|
||||
if (setting.UsingGlobal()) {
|
||||
tracker = CheckState::Global;
|
||||
} else {
|
||||
tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off;
|
||||
}
|
||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, setting, &tracker] {
|
||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
||||
static_cast<int>(CheckState::Count));
|
||||
if (tracker == CheckState::Global) {
|
||||
checkbox->setChecked(setting.GetValue(true));
|
||||
}
|
||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||
});
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state,
|
||||
bool global_state, CheckState& tracker) {
|
||||
if (global) {
|
||||
tracker = CheckState::Global;
|
||||
} else {
|
||||
tracker = (state == global_state) ? CheckState::On : CheckState::Off;
|
||||
}
|
||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, global_state, &tracker] {
|
||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
||||
static_cast<int>(CheckState::Count));
|
||||
if (tracker == CheckState::Global) {
|
||||
checkbox->setChecked(global_state);
|
||||
}
|
||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||
});
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target, int global) {
|
||||
InsertGlobalItem(combobox, global);
|
||||
QObject::connect(combobox, qOverload<int>(&QComboBox::activated), target,
|
||||
[target](int index) { SetHighlight(target, index != 0); });
|
||||
}
|
||||
|
||||
void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) {
|
||||
const QString use_global_text =
|
||||
ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index));
|
||||
combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
|
||||
combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
|
||||
}
|
||||
|
||||
int ConfigurationShared::GetComboboxIndex(int global_setting_index, const QComboBox* combobox) {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
return combobox->currentIndex();
|
||||
}
|
||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
return global_setting_index;
|
||||
}
|
||||
return combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET;
|
||||
}
|
||||
} // namespace ConfigurationShared
|
||||
|
@ -3,73 +3,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include "common/settings.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <qobjectdefs.h>
|
||||
|
||||
class QObject;
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
constexpr int USE_GLOBAL_INDEX = 0;
|
||||
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
|
||||
constexpr int USE_GLOBAL_OFFSET = 2;
|
||||
class Tab : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
// CheckBoxes require a tracker for their state since we emulate a tristate CheckBox
|
||||
enum class CheckState {
|
||||
Off, // Checkbox overrides to off/false
|
||||
On, // Checkbox overrides to on/true
|
||||
Global, // Checkbox defers to the global state
|
||||
Count, // Simply the number of states, not a valid checkbox state
|
||||
public:
|
||||
explicit Tab(std::shared_ptr<std::vector<Tab*>> group, QWidget* parent = nullptr);
|
||||
~Tab();
|
||||
|
||||
virtual void ApplyConfiguration() = 0;
|
||||
virtual void SetConfiguration() = 0;
|
||||
};
|
||||
|
||||
// Global-aware apply and set functions
|
||||
|
||||
// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
|
||||
void ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting, const QCheckBox* checkbox,
|
||||
const CheckState& tracker);
|
||||
template <typename Type, bool ranged>
|
||||
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
||||
const QComboBox* combobox) {
|
||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
||||
setting->SetValue(static_cast<Type>(combobox->currentIndex()));
|
||||
} else if (!Settings::IsConfiguringGlobal()) {
|
||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
setting->SetGlobal(true);
|
||||
} else {
|
||||
setting->SetGlobal(false);
|
||||
setting->SetValue(static_cast<Type>(combobox->currentIndex() -
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sets a Qt UI element given a Settings::Setting
|
||||
void SetPerGameSetting(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>* setting);
|
||||
|
||||
template <typename Type, bool ranged>
|
||||
void SetPerGameSetting(QComboBox* combobox,
|
||||
const Settings::SwitchableSetting<Type, ranged>* 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);
|
||||
|
||||
// Sets up a QCheckBox like a tristate one, given a Setting
|
||||
void SetColoredTristate(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>& setting,
|
||||
CheckState& tracker);
|
||||
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
|
||||
CheckState& tracker);
|
||||
|
||||
// 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);
|
||||
|
||||
// Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox
|
||||
void InsertGlobalItem(QComboBox* combobox, int global_index);
|
||||
|
||||
// Returns the correct index of a QComboBox taking into account global configuration
|
||||
int GetComboboxIndex(int global_setting_index, const QComboBox* combobox);
|
||||
|
||||
} // namespace ConfigurationShared
|
||||
|
@ -48,11 +48,34 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Some settings are only available when a game is not running.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -1,87 +1,112 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "audio_core/sink/sink.h"
|
||||
#include "audio_core/sink/sink_details.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_common.h"
|
||||
#include "core/core.h"
|
||||
#include "ui_configure_audio.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_audio.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
ConfigureAudio::ConfigureAudio(const Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} {
|
||||
ConfigureAudio::ConfigureAudio(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: Tab(group_, parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} {
|
||||
ui->setupUi(this);
|
||||
|
||||
InitializeAudioSinkComboBox();
|
||||
|
||||
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
||||
&ConfigureAudio::SetVolumeIndicatorText);
|
||||
connect(ui->sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigureAudio::UpdateAudioDevices);
|
||||
|
||||
ui->volume_label->setVisible(Settings::IsConfiguringGlobal());
|
||||
ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal());
|
||||
|
||||
SetupPerGameUI();
|
||||
Setup(builder);
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
const bool is_powered_on = system_.IsPoweredOn();
|
||||
ui->sink_combo_box->setEnabled(!is_powered_on);
|
||||
ui->output_combo_box->setEnabled(!is_powered_on);
|
||||
ui->input_combo_box->setEnabled(!is_powered_on);
|
||||
}
|
||||
|
||||
ConfigureAudio::~ConfigureAudio() = default;
|
||||
|
||||
void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
|
||||
auto& layout = *ui->audio_widget->layout();
|
||||
|
||||
std::vector<Settings::BasicSetting*> settings;
|
||||
|
||||
std::map<u32, QWidget*> hold;
|
||||
|
||||
auto push = [&](Settings::Category category) {
|
||||
for (auto* setting : Settings::values.linkage.by_category[category]) {
|
||||
settings.push_back(setting);
|
||||
}
|
||||
};
|
||||
|
||||
push(Settings::Category::Audio);
|
||||
push(Settings::Category::SystemAudio);
|
||||
|
||||
for (auto* setting : settings) {
|
||||
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
hold.emplace(std::pair{setting->Id(), widget});
|
||||
|
||||
if (setting->Id() == Settings::values.sink_id.Id()) {
|
||||
// TODO (lat9nq): Let the system manage sink_id
|
||||
sink_combo_box = widget->combobox;
|
||||
InitializeAudioSinkComboBox();
|
||||
|
||||
connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigureAudio::UpdateAudioDevices);
|
||||
} else if (setting->Id() == Settings::values.audio_output_device_id.Id()) {
|
||||
// Keep track of output (and input) device comboboxes to populate them with system
|
||||
// devices, which are determined at run time
|
||||
output_device_combo_box = widget->combobox;
|
||||
} else if (setting->Id() == Settings::values.audio_input_device_id.Id()) {
|
||||
input_device_combo_box = widget->combobox;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [id, widget] : hold) {
|
||||
layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetConfiguration() {
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetOutputSinkFromSinkID();
|
||||
|
||||
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
||||
UpdateAudioDevices(ui->sink_combo_box->currentIndex());
|
||||
UpdateAudioDevices(sink_combo_box->currentIndex());
|
||||
|
||||
SetAudioDevicesFromDeviceID();
|
||||
|
||||
const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
|
||||
ui->volume_slider->setValue(volume_value);
|
||||
ui->toggle_background_mute->setChecked(UISettings::values.mute_when_in_background.GetValue());
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
if (Settings::values.volume.UsingGlobal()) {
|
||||
ui->volume_combo_box->setCurrentIndex(0);
|
||||
ui->volume_slider->setEnabled(false);
|
||||
} else {
|
||||
ui->volume_combo_box->setCurrentIndex(1);
|
||||
ui->volume_slider->setEnabled(true);
|
||||
}
|
||||
ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index);
|
||||
ConfigurationShared::SetHighlight(ui->mode_label,
|
||||
!Settings::values.sound_index.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->volume_layout,
|
||||
!Settings::values.volume.UsingGlobal());
|
||||
} else {
|
||||
ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue());
|
||||
}
|
||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
||||
[[maybe_unused]] const QSignalBlocker blocker(ui->sink_combo_box);
|
||||
[[maybe_unused]] const QSignalBlocker blocker(sink_combo_box);
|
||||
|
||||
int new_sink_index = 0;
|
||||
const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
|
||||
for (int index = 0; index < ui->sink_combo_box->count(); index++) {
|
||||
if (ui->sink_combo_box->itemText(index) == sink_id) {
|
||||
const QString sink_id = QString::fromStdString(Settings::values.sink_id.ToString());
|
||||
for (int index = 0; index < sink_combo_box->count(); index++) {
|
||||
if (sink_combo_box->itemText(index) == sink_id) {
|
||||
new_sink_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui->sink_combo_box->setCurrentIndex(new_sink_index);
|
||||
sink_combo_box->setCurrentIndex(new_sink_index);
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetAudioDevicesFromDeviceID() {
|
||||
@ -89,57 +114,42 @@ void ConfigureAudio::SetAudioDevicesFromDeviceID() {
|
||||
|
||||
const QString output_device_id =
|
||||
QString::fromStdString(Settings::values.audio_output_device_id.GetValue());
|
||||
for (int index = 0; index < ui->output_combo_box->count(); index++) {
|
||||
if (ui->output_combo_box->itemText(index) == output_device_id) {
|
||||
for (int index = 0; index < output_device_combo_box->count(); index++) {
|
||||
if (output_device_combo_box->itemText(index) == output_device_id) {
|
||||
new_device_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui->output_combo_box->setCurrentIndex(new_device_index);
|
||||
output_device_combo_box->setCurrentIndex(new_device_index);
|
||||
|
||||
new_device_index = -1;
|
||||
const QString input_device_id =
|
||||
QString::fromStdString(Settings::values.audio_input_device_id.GetValue());
|
||||
for (int index = 0; index < ui->input_combo_box->count(); index++) {
|
||||
if (ui->input_combo_box->itemText(index) == input_device_id) {
|
||||
for (int index = 0; index < input_device_combo_box->count(); index++) {
|
||||
if (input_device_combo_box->itemText(index) == input_device_id) {
|
||||
new_device_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui->input_combo_box->setCurrentIndex(new_device_index);
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
|
||||
ui->volume_indicator->setText(tr("%1%", "Volume percentage (e.g. 50%)").arg(percentage));
|
||||
input_device_combo_box->setCurrentIndex(new_device_index);
|
||||
}
|
||||
|
||||
void ConfigureAudio::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound);
|
||||
const bool is_powered_on = system.IsPoweredOn();
|
||||
for (const auto& apply_func : apply_funcs) {
|
||||
apply_func(is_powered_on);
|
||||
}
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
Settings::values.sink_id =
|
||||
ui->sink_combo_box->itemText(ui->sink_combo_box->currentIndex()).toStdString();
|
||||
Settings::values.sink_id.LoadString(
|
||||
sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString());
|
||||
Settings::values.audio_output_device_id.SetValue(
|
||||
ui->output_combo_box->itemText(ui->output_combo_box->currentIndex()).toStdString());
|
||||
output_device_combo_box->itemText(output_device_combo_box->currentIndex())
|
||||
.toStdString());
|
||||
Settings::values.audio_input_device_id.SetValue(
|
||||
ui->input_combo_box->itemText(ui->input_combo_box->currentIndex()).toStdString());
|
||||
UISettings::values.mute_when_in_background = ui->toggle_background_mute->isChecked();
|
||||
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.volume.UsingGlobal()) {
|
||||
const auto volume = static_cast<u8>(ui->volume_slider->value());
|
||||
Settings::values.volume.SetValue(volume);
|
||||
}
|
||||
} else {
|
||||
if (ui->volume_combo_box->currentIndex() == 0) {
|
||||
Settings::values.volume.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.volume.SetGlobal(false);
|
||||
const auto volume = static_cast<u8>(ui->volume_slider->value());
|
||||
Settings::values.volume.SetValue(volume);
|
||||
}
|
||||
input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,54 +162,31 @@ void ConfigureAudio::changeEvent(QEvent* event) {
|
||||
}
|
||||
|
||||
void ConfigureAudio::UpdateAudioDevices(int sink_index) {
|
||||
ui->output_combo_box->clear();
|
||||
ui->output_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
output_device_combo_box->clear();
|
||||
output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
|
||||
const std::string sink_id = ui->sink_combo_box->itemText(sink_index).toStdString();
|
||||
const auto sink_id =
|
||||
Settings::ToEnum<Settings::AudioEngine>(sink_combo_box->itemText(sink_index).toStdString());
|
||||
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, false)) {
|
||||
ui->output_combo_box->addItem(QString::fromStdString(device));
|
||||
output_device_combo_box->addItem(QString::fromStdString(device));
|
||||
}
|
||||
|
||||
ui->input_combo_box->clear();
|
||||
ui->input_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
input_device_combo_box->clear();
|
||||
input_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) {
|
||||
ui->input_combo_box->addItem(QString::fromStdString(device));
|
||||
input_device_combo_box->addItem(QString::fromStdString(device));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureAudio::InitializeAudioSinkComboBox() {
|
||||
ui->sink_combo_box->clear();
|
||||
ui->sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
sink_combo_box->clear();
|
||||
sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||
|
||||
for (const auto& id : AudioCore::Sink::GetSinkIDs()) {
|
||||
ui->sink_combo_box->addItem(QString::fromUtf8(id.data(), static_cast<s32>(id.length())));
|
||||
sink_combo_box->addItem(QString::fromStdString(Settings::CanonicalizeEnum(id)));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureAudio::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetupPerGameUI() {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal());
|
||||
ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationShared::SetColoredComboBox(ui->combo_sound, ui->mode_label,
|
||||
Settings::values.sound_index.GetValue(true));
|
||||
|
||||
connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||
ui->volume_slider->setEnabled(index == 1);
|
||||
ConfigurationShared::SetHighlight(ui->volume_layout, index == 1);
|
||||
});
|
||||
|
||||
ui->sink_combo_box->setVisible(false);
|
||||
ui->sink_label->setVisible(false);
|
||||
ui->output_combo_box->setVisible(false);
|
||||
ui->output_label->setVisible(false);
|
||||
ui->input_combo_box->setVisible(false);
|
||||
ui->input_label->setVisible(false);
|
||||
}
|
||||
|
@ -3,30 +3,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureAudio;
|
||||
}
|
||||
|
||||
class ConfigureAudio : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureAudio : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureAudio(const Core::System& system_, QWidget* parent = nullptr);
|
||||
explicit ConfigureAudio(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||
~ConfigureAudio() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
@ -39,11 +44,16 @@ private:
|
||||
|
||||
void SetOutputSinkFromSinkID();
|
||||
void SetAudioDevicesFromDeviceID();
|
||||
void SetVolumeIndicatorText(int percentage);
|
||||
|
||||
void SetupPerGameUI();
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
|
||||
std::unique_ptr<Ui::ConfigureAudio> ui;
|
||||
|
||||
const Core::System& system;
|
||||
|
||||
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||
|
||||
QComboBox* sink_combo_box;
|
||||
QComboBox* output_device_combo_box;
|
||||
QComboBox* input_device_combo_box;
|
||||
};
|
||||
|
@ -21,80 +21,14 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="engine_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="sink_label">
|
||||
<property name="text">
|
||||
<string>Output Engine:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="sink_combo_box"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="output_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="output_label">
|
||||
<property name="text">
|
||||
<string>Output Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="output_combo_box"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="input_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="input_label">
|
||||
<property name="text">
|
||||
<string>Input Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="input_combo_box"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="mode_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="mode_label">
|
||||
<property name="text">
|
||||
<string>Sound Output Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_sound">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Mono</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Surround</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="volume_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<widget class="QWidget" name="audio_widget" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777213</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -107,89 +41,9 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="volume_combo_box">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global volume</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set volume:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volume_label">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="volume_slider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volume_indicator">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 %</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="mute_layout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_background_mute">
|
||||
<property name="text">
|
||||
<string>Mute audio when in background</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -1,88 +1,92 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
#include <QComboBox>
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "configuration/shared_widget.h"
|
||||
#include "core/core.h"
|
||||
#include "ui_configure_cpu.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_cpu.h"
|
||||
|
||||
ConfigureCpu::ConfigureCpu(const Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_} {
|
||||
ConfigureCpu::ConfigureCpu(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_},
|
||||
combobox_translations(builder.ComboboxTranslations()) {
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
Setup(builder);
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
connect(accuracy_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigureCpu::UpdateGroup);
|
||||
}
|
||||
|
||||
ConfigureCpu::~ConfigureCpu() = default;
|
||||
|
||||
void ConfigureCpu::SetConfiguration() {
|
||||
const bool runtime_lock = !system.IsPoweredOn();
|
||||
void ConfigureCpu::SetConfiguration() {}
|
||||
void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
|
||||
auto* accuracy_layout = ui->widget_accuracy->layout();
|
||||
auto* unsafe_layout = ui->unsafe_widget->layout();
|
||||
std::map<u32, QWidget*> unsafe_hold{};
|
||||
|
||||
ui->accuracy->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_ignore_global_monitor->setEnabled(runtime_lock);
|
||||
std::vector<Settings::BasicSetting*> settings;
|
||||
const auto push = [&](Settings::Category category) {
|
||||
for (const auto setting : Settings::values.linkage.by_category[category]) {
|
||||
settings.push_back(setting);
|
||||
}
|
||||
};
|
||||
|
||||
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_ignore_standard_fpcr->setChecked(
|
||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue());
|
||||
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
|
||||
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
|
||||
ui->cpuopt_unsafe_fastmem_check->setChecked(
|
||||
Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
|
||||
ui->cpuopt_unsafe_ignore_global_monitor->setChecked(
|
||||
Settings::values.cpuopt_unsafe_ignore_global_monitor.GetValue());
|
||||
push(Settings::Category::Cpu);
|
||||
push(Settings::Category::CpuUnsafe);
|
||||
|
||||
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());
|
||||
for (const auto setting : settings) {
|
||||
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setting->Id() == Settings::values.cpu_accuracy.Id()) {
|
||||
// Keep track of cpu_accuracy combobox to display/hide the unsafe settings
|
||||
accuracy_layout->addWidget(widget);
|
||||
accuracy_combobox = widget->combobox;
|
||||
} else {
|
||||
// Presently, all other settings here are unsafe checkboxes
|
||||
unsafe_hold.insert({setting->Id(), widget});
|
||||
}
|
||||
}
|
||||
UpdateGroup(ui->accuracy->currentIndex());
|
||||
|
||||
for (const auto& [label, widget] : unsafe_hold) {
|
||||
unsafe_layout->addWidget(widget);
|
||||
}
|
||||
|
||||
UpdateGroup(accuracy_combobox->currentIndex());
|
||||
}
|
||||
|
||||
void ConfigureCpu::UpdateGroup(int index) {
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
index -= ConfigurationShared::USE_GLOBAL_OFFSET;
|
||||
}
|
||||
const auto accuracy = static_cast<Settings::CPUAccuracy>(index);
|
||||
ui->unsafe_group->setVisible(accuracy == Settings::CPUAccuracy::Unsafe);
|
||||
const auto accuracy = static_cast<Settings::CpuAccuracy>(
|
||||
combobox_translations.at(Settings::EnumMetadata<Settings::CpuAccuracy>::Index())[index]
|
||||
.first);
|
||||
ui->unsafe_group->setVisible(accuracy == Settings::CpuAccuracy::Unsafe);
|
||||
}
|
||||
|
||||
void ConfigureCpu::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_accuracy, ui->accuracy);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma,
|
||||
ui->cpuopt_unsafe_unfuse_fma,
|
||||
cpuopt_unsafe_unfuse_fma);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_reduce_fp_error,
|
||||
ui->cpuopt_unsafe_reduce_fp_error,
|
||||
cpuopt_unsafe_reduce_fp_error);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
||||
ui->cpuopt_unsafe_ignore_standard_fpcr,
|
||||
cpuopt_unsafe_ignore_standard_fpcr);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||
ui->cpuopt_unsafe_inaccurate_nan,
|
||||
cpuopt_unsafe_inaccurate_nan);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
|
||||
ui->cpuopt_unsafe_fastmem_check,
|
||||
cpuopt_unsafe_fastmem_check);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_global_monitor,
|
||||
ui->cpuopt_unsafe_ignore_global_monitor,
|
||||
cpuopt_unsafe_ignore_global_monitor);
|
||||
const bool is_powered_on = system.IsPoweredOn();
|
||||
for (const auto& apply_func : apply_funcs) {
|
||||
apply_func(is_powered_on);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureCpu::changeEvent(QEvent* event) {
|
||||
@ -96,32 +100,3 @@ void ConfigureCpu::changeEvent(QEvent* event) {
|
||||
void ConfigureCpu::RetranslateUI() {
|
||||
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)));
|
||||
|
||||
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_ignore_standard_fpcr,
|
||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
||||
cpuopt_unsafe_ignore_standard_fpcr);
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
|
||||
Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||
cpuopt_unsafe_inaccurate_nan);
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
|
||||
Settings::values.cpuopt_unsafe_fastmem_check,
|
||||
cpuopt_unsafe_fastmem_check);
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_global_monitor,
|
||||
Settings::values.cpuopt_unsafe_ignore_global_monitor,
|
||||
cpuopt_unsafe_ignore_global_monitor);
|
||||
}
|
||||
|
@ -4,29 +4,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureCpu;
|
||||
}
|
||||
|
||||
class ConfigureCpu : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureCpu : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureCpu(const Core::System& system_, QWidget* parent = nullptr);
|
||||
explicit ConfigureCpu(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||
~ConfigureCpu() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
@ -34,16 +39,14 @@ private:
|
||||
|
||||
void UpdateGroup(int index);
|
||||
|
||||
void SetupPerGameUI();
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
|
||||
std::unique_ptr<Ui::ConfigureCpu> ui;
|
||||
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor;
|
||||
|
||||
const Core::System& system;
|
||||
|
||||
const ConfigurationShared::ComboboxTranslationMap& combobox_translations;
|
||||
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||
|
||||
QComboBox* accuracy_combobox;
|
||||
};
|
||||
|
@ -16,9 +16,12 @@
|
||||
<property name="accessibleName">
|
||||
<string>CPU</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<layout class="QVBoxLayout" name="vboxlayout_2" stretch="0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout">
|
||||
<layout class="QVBoxLayout" name="vboxlayout">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
@ -27,38 +30,19 @@
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_accuracy" native="true">
|
||||
<layout class="QHBoxLayout" name="layout_accuracy">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_accuracy">
|
||||
<property name="text">
|
||||
<string>Accuracy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="accuracy">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Accurate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unsafe</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Paranoid (disables most optimizations)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -75,10 +59,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="unsafe_group">
|
||||
<property name="title">
|
||||
@ -96,105 +76,44 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unfuse FMA (improve performance on CPUs without FMA)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves the speed of some approximate floating-point functions by using less accurate native approximations.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faster FRSQRTE and FRECPE</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_standard_fpcr">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves the speed of 32 bits ASIMD floating-point functions by running with incorrect rounding modes.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faster ASIMD instructions (32 bits only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Inaccurate NaN handling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_fastmem_check">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves speed by eliminating a safety check before every memory read/write in guest. Disabling it may allow a game to read/write the emulator's memory.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable address space checks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_global_monitor">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ignore global monitor</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="unsafe_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="unsafe_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_disable_info">
|
||||
<property name="text">
|
||||
<string>CPU settings are available only when game is not running.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
@ -2,360 +2,549 @@
|
||||
<ui version="4.0">
|
||||
<class>ConfigureDebug</class>
|
||||
<widget class="QScrollArea" name="ConfigureDebug">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>831</width>
|
||||
<height>760</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Debugger</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_gdbstub">
|
||||
<property name="text">
|
||||
<string>Enable GDB Stub</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="gdbport_spinbox">
|
||||
<property name="minimum">
|
||||
<number>1024</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Logging</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_1">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Global Log Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="log_filter_edit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="toggle_console">
|
||||
<property name="text">
|
||||
<string>Show Log in Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="open_log_button">
|
||||
<property name="text">
|
||||
<string>Open Log Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="extended_logging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, the max size of the log increases from 100 MB to 1 GB</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Extended Logging**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Homebrew</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<widget class="QWidget" name="widget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>829</width>
|
||||
<height>758</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Arguments String</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="homebrew_args_edit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="enable_graphics_debugging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, the graphics API enters a slower debugging mode</string>
|
||||
<property name="title">
|
||||
<string>Debugger</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Graphics Debugging</string>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QWidget" name="debug_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_gdbstub">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable GDB Stub</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="horizontalWidget_3" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="gdbport_spinbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1024</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="enable_nsight_aftermath">
|
||||
<property name="toolTip">
|
||||
<string>When checked, it enables Nsight Aftermath crash dumps</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Nsight Aftermath</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="dump_shaders">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Game Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="dump_macros">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the macro programs of the GPU</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Maxwell Macros</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="disable_macro_jit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Macro JIT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="disable_macro_hle">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Macro HLE</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enable_shader_feedback">
|
||||
<property name="toolTip">
|
||||
<string>When checked, yuzu will log statistics about the compiled pipeline cache</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Shader Feedback</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disable_loop_safety_checks">
|
||||
<property name="toolTip">
|
||||
<string>When checked, it executes shaders without loop logic changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Loop safety checks</string>
|
||||
<property name="title">
|
||||
<string>Logging</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_1">
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="open_log_button">
|
||||
<property name="text">
|
||||
<string>Open Log Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QWidget" name="logging_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Global Log Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="log_filter_edit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="extended_logging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, the max size of the log increases from 100 MB to 1 GB</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Extended Logging**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="toggle_console">
|
||||
<property name="text">
|
||||
<string>Show Log in Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Debugging</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="reporting_services">
|
||||
<property name="text">
|
||||
<string>Enable Verbose Reporting Services**</string>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Homebrew</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Arguments String</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="homebrew_args_edit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="disable_loop_safety_checks">
|
||||
<property name="toolTip">
|
||||
<string>When checked, it executes shaders without loop logic changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Loop safety checks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="dump_shaders">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Game Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="disable_macro_hle">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Macro HLE</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="disable_macro_jit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Macro JIT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="enable_graphics_debugging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, the graphics API enters a slower debugging mode</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Graphics Debugging</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="dump_macros">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the macro programs of the GPU</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Maxwell Macros</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enable_shader_feedback">
|
||||
<property name="toolTip">
|
||||
<string>When checked, yuzu will log statistics about the compiled pipeline cache</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Shader Feedback</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="enable_nsight_aftermath">
|
||||
<property name="toolTip">
|
||||
<string>When checked, it enables Nsight Aftermath crash dumps</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Nsight Aftermath</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="fs_access_log">
|
||||
<property name="text">
|
||||
<string>Enable FS Access Log</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="perform_vulkan_check">
|
||||
<property name="toolTip">
|
||||
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Perform Startup Vulkan Check</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="disable_web_applet">
|
||||
<property name="text">
|
||||
<string>Disable Web Applet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="enable_all_controllers">
|
||||
<property name="text">
|
||||
<string>Enable All Controller Types</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="use_auto_stub">
|
||||
<property name="text">
|
||||
<string>Enable Auto-Stub**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="quest_flag">
|
||||
<property name="text">
|
||||
<string>Kiosk (Quest) Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enable_cpu_debugging">
|
||||
<property name="text">
|
||||
<string>Enable CPU Debugging</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="use_debug_asserts">
|
||||
<property name="text">
|
||||
<string>Enable Debug Asserts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="dump_audio_commands">
|
||||
<property name="toolTip">
|
||||
<string>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Audio Commands To Console**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="create_crash_dumps">
|
||||
<property name="text">
|
||||
<string>Create Minidump After Crash</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Debugging</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="fs_access_log">
|
||||
<property name="text">
|
||||
<string>Enable FS Access Log</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="create_crash_dumps">
|
||||
<property name="text">
|
||||
<string>Create Minidump After Crash</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="dump_audio_commands">
|
||||
<property name="toolTip">
|
||||
<string>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Audio Commands To Console**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="reporting_services">
|
||||
<property name="text">
|
||||
<string>Enable Verbose Reporting Services**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="quest_flag">
|
||||
<property name="text">
|
||||
<string>Kiosk (Quest) Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enable_cpu_debugging">
|
||||
<property name="text">
|
||||
<string>Enable CPU Debugging</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="use_debug_asserts">
|
||||
<property name="text">
|
||||
<string>Enable Debug Asserts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="use_auto_stub">
|
||||
<property name="text">
|
||||
<string>Enable Auto-Stub**</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="enable_all_controllers">
|
||||
<property name="text">
|
||||
<string>Enable All Controller Types</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="disable_web_applet">
|
||||
<property name="text">
|
||||
<string>Disable Web Applet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="perform_vulkan_check">
|
||||
<property name="toolTip">
|
||||
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Perform Startup Vulkan Check</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>**This will be reset automatically when yuzu closes.</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>**This will be reset automatically when yuzu closes.</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>log_filter_edit</tabstop>
|
||||
@ -366,14 +555,11 @@
|
||||
<tabstop>enable_graphics_debugging</tabstop>
|
||||
<tabstop>enable_shader_feedback</tabstop>
|
||||
<tabstop>enable_nsight_aftermath</tabstop>
|
||||
<tabstop>disable_macro_jit</tabstop>
|
||||
<tabstop>disable_loop_safety_checks</tabstop>
|
||||
<tabstop>fs_access_log</tabstop>
|
||||
<tabstop>reporting_services</tabstop>
|
||||
<tabstop>quest_flag</tabstop>
|
||||
<tabstop>enable_cpu_debugging</tabstop>
|
||||
<tabstop>use_debug_asserts</tabstop>
|
||||
<tabstop>use_auto_stub</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -32,21 +32,23 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
||||
Core::System& system_, bool enable_web_config)
|
||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
|
||||
registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_,
|
||||
this)},
|
||||
cpu_tab{std::make_unique<ConfigureCpu>(system_, this)},
|
||||
registry(registry_), system{system_}, builder{std::make_unique<ConfigurationShared::Builder>(
|
||||
this, !system_.IsPoweredOn())},
|
||||
audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *builder, this)},
|
||||
cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, *builder, this)},
|
||||
debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)},
|
||||
filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
|
||||
general_tab{std::make_unique<ConfigureGeneral>(system_, this)},
|
||||
graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)},
|
||||
general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *builder, this)},
|
||||
graphics_advanced_tab{
|
||||
std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, *builder, this)},
|
||||
graphics_tab{std::make_unique<ConfigureGraphics>(
|
||||
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
|
||||
this)},
|
||||
nullptr, *builder, this)},
|
||||
hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)},
|
||||
input_tab{std::make_unique<ConfigureInput>(system_, this)},
|
||||
network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
|
||||
profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
|
||||
system_tab{std::make_unique<ConfigureSystem>(system_, this)},
|
||||
system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, *builder, this)},
|
||||
ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>(
|
||||
this)} {
|
||||
Settings::SetConfiguringGlobal(true);
|
||||
@ -95,6 +97,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||
|
||||
adjustSize();
|
||||
ui->selectorList->setCurrentRow(0);
|
||||
|
||||
// Selects the leftmost button on the bottom bar (Cancel as of writing)
|
||||
ui->buttonBox->setFocus();
|
||||
}
|
||||
|
||||
ConfigureDialog::~ConfigureDialog() = default;
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QDialog>
|
||||
#include "configuration/shared_widget.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
|
||||
namespace Core {
|
||||
@ -69,6 +72,8 @@ private:
|
||||
HotkeyRegistry& registry;
|
||||
|
||||
Core::System& system;
|
||||
std::unique_ptr<ConfigurationShared::Builder> builder;
|
||||
std::vector<ConfigurationShared::Tab*> tab_group;
|
||||
|
||||
std::unique_ptr<ConfigureAudio> audio_tab;
|
||||
std::unique_ptr<ConfigureCpu> cpu_tab;
|
||||
|
@ -3,57 +3,60 @@
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <QMessageBox>
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "ui_configure_general.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_general.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
ConfigureGeneral::ConfigureGeneral(const Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGeneral>()}, system{system_} {
|
||||
ConfigureGeneral::ConfigureGeneral(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGeneral>()}, system{system_} {
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
Setup(builder);
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
|
||||
[this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
|
||||
}
|
||||
|
||||
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
||||
&ConfigureGeneral::ResetDefaults);
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
ui->button_reset_defaults->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||
|
||||
void ConfigureGeneral::SetConfiguration() {
|
||||
const bool runtime_lock = !system.IsPoweredOn();
|
||||
void ConfigureGeneral::SetConfiguration() {}
|
||||
|
||||
ui->use_multi_core->setEnabled(runtime_lock);
|
||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
|
||||
void ConfigureGeneral::Setup(const ConfigurationShared::Builder& builder) {
|
||||
QLayout& layout = *ui->general_widget->layout();
|
||||
|
||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
||||
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
|
||||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue());
|
||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
||||
ui->toggle_controller_applet_disabled->setEnabled(runtime_lock);
|
||||
ui->toggle_controller_applet_disabled->setChecked(
|
||||
UISettings::values.controller_applet_disabled.GetValue());
|
||||
std::map<u32, QWidget*> hold{};
|
||||
|
||||
ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
|
||||
ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
|
||||
for (const auto setting :
|
||||
UISettings::values.linkage.by_category[Settings::Category::UiGeneral]) {
|
||||
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
|
||||
ui->button_reset_defaults->setEnabled(runtime_lock);
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
|
||||
} else {
|
||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
|
||||
use_speed_limit != ConfigurationShared::CheckState::Global);
|
||||
hold.emplace(setting->Id(), widget);
|
||||
}
|
||||
|
||||
for (const auto& [id, widget] : hold) {
|
||||
layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,32 +80,9 @@ void ConfigureGeneral::ResetDefaults() {
|
||||
}
|
||||
|
||||
void ConfigureGeneral::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
|
||||
use_multi_core);
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||
UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked();
|
||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||
UISettings::values.controller_applet_disabled =
|
||||
ui->toggle_controller_applet_disabled->isChecked();
|
||||
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.use_speed_limit.UsingGlobal()) {
|
||||
Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
|
||||
Qt::Checked);
|
||||
Settings::values.speed_limit.SetValue(ui->speed_limit->value());
|
||||
}
|
||||
} else {
|
||||
bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global;
|
||||
Settings::values.use_speed_limit.SetGlobal(global_speed_limit);
|
||||
Settings::values.speed_limit.SetGlobal(global_speed_limit);
|
||||
if (!global_speed_limit) {
|
||||
Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
|
||||
Qt::Checked);
|
||||
Settings::values.speed_limit.SetValue(ui->speed_limit->value());
|
||||
}
|
||||
bool powered_on = system.IsPoweredOn();
|
||||
for (const auto& func : apply_funcs) {
|
||||
func(powered_on);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,33 +97,3 @@ void ConfigureGeneral::changeEvent(QEvent* event) {
|
||||
void ConfigureGeneral::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureGeneral::SetupPerGameUI() {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
// Disables each setting if:
|
||||
// - A game is running (thus settings in use), and
|
||||
// - A non-global setting is applied.
|
||||
ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
|
||||
ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ui->toggle_check_exit->setVisible(false);
|
||||
ui->toggle_user_on_boot->setVisible(false);
|
||||
ui->toggle_background_pause->setVisible(false);
|
||||
ui->toggle_hide_mouse->setVisible(false);
|
||||
ui->toggle_controller_applet_disabled->setVisible(false);
|
||||
|
||||
ui->button_reset_defaults->setVisible(false);
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit,
|
||||
Settings::values.use_speed_limit, use_speed_limit);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
|
||||
use_multi_core);
|
||||
|
||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
|
||||
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
|
||||
(use_speed_limit != ConfigurationShared::CheckState::Global));
|
||||
});
|
||||
}
|
||||
|
@ -5,48 +5,49 @@
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
class ConfigureDialog;
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
class HotkeyRegistry;
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureGeneral;
|
||||
}
|
||||
|
||||
class ConfigureGeneral : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureGeneral : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureGeneral(const Core::System& system_, QWidget* parent = nullptr);
|
||||
explicit ConfigureGeneral(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder,
|
||||
QWidget* parent = nullptr);
|
||||
~ConfigureGeneral() override;
|
||||
|
||||
void SetResetCallback(std::function<void()> callback);
|
||||
void ResetDefaults();
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
private:
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::function<void()> reset_callback;
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||
|
||||
ConfigurationShared::CheckState use_speed_limit;
|
||||
ConfigurationShared::CheckState use_multi_core;
|
||||
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||
|
||||
const Core::System& system;
|
||||
};
|
||||
|
@ -26,77 +26,22 @@
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="GeneralHorizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_speed_limit">
|
||||
<property name="text">
|
||||
<string>Limit Speed Percent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="speed_limit">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_multi_core">
|
||||
<property name="text">
|
||||
<string>Multicore CPU Emulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_check_exit">
|
||||
<property name="text">
|
||||
<string>Confirm exit while emulation is running</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_user_on_boot">
|
||||
<property name="text">
|
||||
<string>Prompt for user on game boot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_background_pause">
|
||||
<property name="text">
|
||||
<string>Pause emulation when in background</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_hide_mouse">
|
||||
<property name="text">
|
||||
<string>Hide mouse on inactivity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_controller_applet_disabled">
|
||||
<property name="text">
|
||||
<string>Disable controller applet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QWidget" name="general_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <QBoxLayout>
|
||||
@ -15,23 +16,29 @@
|
||||
#include <QComboBox>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QStringLiteral>
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#include <qabstractbutton.h>
|
||||
#include <qboxlayout.h>
|
||||
#include <qcoreevent.h>
|
||||
#include <qglobal.h>
|
||||
#include <qgridlayout.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/dynamic_library.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "core/core.h"
|
||||
#include "ui_configure_graphics.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/qt_common.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
@ -46,9 +53,9 @@ static constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode) {
|
||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
case Settings::VSyncMode::Mailbox:
|
||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
case Settings::VSyncMode::FIFO:
|
||||
case Settings::VSyncMode::Fifo:
|
||||
return VK_PRESENT_MODE_FIFO_KHR;
|
||||
case Settings::VSyncMode::FIFORelaxed:
|
||||
case Settings::VSyncMode::FifoRelaxed:
|
||||
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
||||
default:
|
||||
return VK_PRESENT_MODE_FIFO_KHR;
|
||||
@ -62,50 +69,67 @@ static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode)
|
||||
case VK_PRESENT_MODE_MAILBOX_KHR:
|
||||
return Settings::VSyncMode::Mailbox;
|
||||
case VK_PRESENT_MODE_FIFO_KHR:
|
||||
return Settings::VSyncMode::FIFO;
|
||||
return Settings::VSyncMode::Fifo;
|
||||
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
|
||||
return Settings::VSyncMode::FIFORelaxed;
|
||||
return Settings::VSyncMode::FifoRelaxed;
|
||||
default:
|
||||
return Settings::VSyncMode::FIFO;
|
||||
return Settings::VSyncMode::Fifo;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigureGraphics::ConfigureGraphics(const Core::System& system_,
|
||||
std::vector<VkDeviceInfo::Record>& records_,
|
||||
const std::function<void()>& expose_compute_option_,
|
||||
QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, records{records_},
|
||||
expose_compute_option{expose_compute_option_}, system{system_} {
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: ConfigurationShared::Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphics>()},
|
||||
records{records_}, expose_compute_option{expose_compute_option_}, system{system_},
|
||||
combobox_translations{builder.ComboboxTranslations()},
|
||||
shader_mapping{
|
||||
combobox_translations.at(Settings::EnumMetadata<Settings::ShaderBackend>::Index())} {
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||
RetrieveVulkanDevices();
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
Setup(builder);
|
||||
|
||||
for (const auto& device : vulkan_devices) {
|
||||
ui->device->addItem(device);
|
||||
vulkan_device_combobox->addItem(device);
|
||||
}
|
||||
|
||||
ui->backend->addItem(QStringLiteral("GLSL"));
|
||||
ui->backend->addItem(tr("GLASM (Assembly Shaders, NVIDIA Only)"));
|
||||
ui->backend->addItem(tr("SPIR-V (Experimental, Mesa Only)"));
|
||||
UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
|
||||
Settings::values.bg_green.GetValue(),
|
||||
Settings::values.bg_blue.GetValue()));
|
||||
UpdateAPILayout();
|
||||
PopulateVSyncModeSelection(); //< must happen after UpdateAPILayout
|
||||
|
||||
SetupPerGameUI();
|
||||
// VSync setting needs to be determined after populating the VSync combobox
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
const auto vsync_mode_setting = Settings::values.vsync_mode.GetValue();
|
||||
const auto vsync_mode = VSyncSettingToMode(vsync_mode_setting);
|
||||
int index{};
|
||||
for (const auto mode : vsync_mode_combobox_enum_map) {
|
||||
if (mode == vsync_mode) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (static_cast<unsigned long>(index) < vsync_mode_combobox_enum_map.size()) {
|
||||
vsync_mode_combobox->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
|
||||
connect(api_combobox, qOverload<int>(&QComboBox::activated), this, [this] {
|
||||
UpdateAPILayout();
|
||||
PopulateVSyncModeSelection();
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
ConfigurationShared::SetHighlight(
|
||||
ui->api_widget, ui->api->currentIndex() != ConfigurationShared::USE_GLOBAL_INDEX);
|
||||
}
|
||||
});
|
||||
connect(ui->device, qOverload<int>(&QComboBox::activated), this, [this](int device) {
|
||||
UpdateDeviceSelection(device);
|
||||
PopulateVSyncModeSelection();
|
||||
});
|
||||
connect(ui->backend, qOverload<int>(&QComboBox::activated), this,
|
||||
connect(vulkan_device_combobox, qOverload<int>(&QComboBox::activated), this,
|
||||
[this](int device) {
|
||||
UpdateDeviceSelection(device);
|
||||
PopulateVSyncModeSelection();
|
||||
});
|
||||
connect(shader_backend_combobox, qOverload<int>(&QComboBox::activated), this,
|
||||
[this](int backend) { UpdateShaderBackendSelection(backend); });
|
||||
|
||||
connect(ui->bg_button, &QPushButton::clicked, this, [this] {
|
||||
@ -116,39 +140,45 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_,
|
||||
UpdateBackgroundColorButton(new_bg_color);
|
||||
});
|
||||
|
||||
ui->api->setEnabled(!UISettings::values.has_broken_vulkan && ui->api->isEnabled());
|
||||
api_combobox->setEnabled(!UISettings::values.has_broken_vulkan && api_combobox->isEnabled());
|
||||
ui->api_widget->setEnabled(
|
||||
(!UISettings::values.has_broken_vulkan || Settings::IsConfiguringGlobal()) &&
|
||||
ui->api_widget->isEnabled());
|
||||
ui->bg_label->setVisible(Settings::IsConfiguringGlobal());
|
||||
ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
||||
|
||||
connect(ui->fsr_sharpening_slider, &QSlider::valueChanged, this,
|
||||
&ConfigureGraphics::SetFSRIndicatorText);
|
||||
ui->fsr_sharpening_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
||||
ui->fsr_sharpening_label->setVisible(Settings::IsConfiguringGlobal());
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->bg_widget->setEnabled(Settings::values.bg_red.UsingGlobal());
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphics::PopulateVSyncModeSelection() {
|
||||
const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
|
||||
if (backend == Settings::RendererBackend::Null) {
|
||||
ui->vsync_mode_combobox->setEnabled(false);
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
return;
|
||||
}
|
||||
ui->vsync_mode_combobox->setEnabled(true);
|
||||
|
||||
const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
|
||||
if (backend == Settings::RendererBackend::Null) {
|
||||
vsync_mode_combobox->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
vsync_mode_combobox->setEnabled(true);
|
||||
|
||||
const int current_index = //< current selected vsync mode from combobox
|
||||
ui->vsync_mode_combobox->currentIndex();
|
||||
vsync_mode_combobox->currentIndex();
|
||||
const auto current_mode = //< current selected vsync mode as a VkPresentModeKHR
|
||||
current_index == -1 ? VSyncSettingToMode(Settings::values.vsync_mode.GetValue())
|
||||
: vsync_mode_combobox_enum_map[current_index];
|
||||
int index{};
|
||||
const int device{ui->device->currentIndex()}; //< current selected Vulkan device
|
||||
const int device{vulkan_device_combobox->currentIndex()}; //< current selected Vulkan device
|
||||
if (device == -1) {
|
||||
// Invalid device
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& present_modes = //< relevant vector of present modes for the selected device or API
|
||||
backend == Settings::RendererBackend::Vulkan ? device_present_modes[device]
|
||||
: default_present_modes;
|
||||
|
||||
ui->vsync_mode_combobox->clear();
|
||||
vsync_mode_combobox->clear();
|
||||
vsync_mode_combobox_enum_map.clear();
|
||||
vsync_mode_combobox_enum_map.reserve(present_modes.size());
|
||||
for (const auto present_mode : present_modes) {
|
||||
@ -157,10 +187,10 @@ void ConfigureGraphics::PopulateVSyncModeSelection() {
|
||||
continue;
|
||||
}
|
||||
|
||||
ui->vsync_mode_combobox->insertItem(index, mode_name);
|
||||
vsync_mode_combobox->insertItem(index, mode_name);
|
||||
vsync_mode_combobox_enum_map.push_back(present_mode);
|
||||
if (present_mode == current_mode) {
|
||||
ui->vsync_mode_combobox->setCurrentIndex(index);
|
||||
vsync_mode_combobox->setCurrentIndex(index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
@ -186,112 +216,124 @@ void ConfigureGraphics::UpdateShaderBackendSelection(int backend) {
|
||||
|
||||
ConfigureGraphics::~ConfigureGraphics() = default;
|
||||
|
||||
void ConfigureGraphics::SetConfiguration() {
|
||||
const bool runtime_lock = !system.IsPoweredOn();
|
||||
void ConfigureGraphics::SetConfiguration() {}
|
||||
|
||||
ui->api_widget->setEnabled(runtime_lock);
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
|
||||
ui->use_disk_shader_cache->setEnabled(runtime_lock);
|
||||
ui->nvdec_emulation_widget->setEnabled(runtime_lock);
|
||||
ui->resolution_combobox->setEnabled(runtime_lock);
|
||||
ui->accelerate_astc->setEnabled(runtime_lock);
|
||||
ui->vsync_mode_layout->setEnabled(runtime_lock ||
|
||||
Settings::values.renderer_backend.GetValue() ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||
ui->use_asynchronous_gpu_emulation->setChecked(
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
ui->accelerate_astc->setChecked(Settings::values.accelerate_astc.GetValue());
|
||||
void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
||||
QLayout* api_layout = ui->api_widget->layout();
|
||||
QWidget* api_grid_widget = new QWidget(this);
|
||||
QVBoxLayout* api_grid_layout = new QVBoxLayout(api_grid_widget);
|
||||
api_grid_layout->setContentsMargins(0, 0, 0, 0);
|
||||
api_layout->addWidget(api_grid_widget);
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
|
||||
ui->fullscreen_mode_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.fullscreen_mode.GetValue()));
|
||||
ui->nvdec_emulation->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.nvdec_emulation.GetValue()));
|
||||
ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
|
||||
ui->resolution_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.resolution_setup.GetValue()));
|
||||
ui->scaling_filter_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.scaling_filter.GetValue()));
|
||||
ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue());
|
||||
ui->anti_aliasing_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.anti_aliasing.GetValue()));
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
|
||||
ConfigurationShared::SetHighlight(ui->api_widget,
|
||||
!Settings::values.renderer_backend.UsingGlobal());
|
||||
QLayout& graphics_layout = *ui->graphics_widget->layout();
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->nvdec_emulation,
|
||||
&Settings::values.nvdec_emulation);
|
||||
ConfigurationShared::SetHighlight(ui->nvdec_emulation_widget,
|
||||
!Settings::values.nvdec_emulation.UsingGlobal());
|
||||
std::map<u32, QWidget*> hold_graphics;
|
||||
std::vector<QWidget*> hold_api;
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->fullscreen_mode_combobox,
|
||||
&Settings::values.fullscreen_mode);
|
||||
ConfigurationShared::SetHighlight(ui->fullscreen_mode_label,
|
||||
!Settings::values.fullscreen_mode.UsingGlobal());
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox,
|
||||
&Settings::values.aspect_ratio);
|
||||
ConfigurationShared::SetHighlight(ui->ar_label,
|
||||
!Settings::values.aspect_ratio.UsingGlobal());
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->resolution_combobox,
|
||||
&Settings::values.resolution_setup);
|
||||
ConfigurationShared::SetHighlight(ui->resolution_label,
|
||||
!Settings::values.resolution_setup.UsingGlobal());
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->scaling_filter_combobox,
|
||||
&Settings::values.scaling_filter);
|
||||
ConfigurationShared::SetHighlight(ui->scaling_filter_label,
|
||||
!Settings::values.scaling_filter.UsingGlobal());
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->anti_aliasing_combobox,
|
||||
&Settings::values.anti_aliasing);
|
||||
ConfigurationShared::SetHighlight(ui->anti_aliasing_label,
|
||||
!Settings::values.anti_aliasing.UsingGlobal());
|
||||
|
||||
ui->fsr_sharpening_combobox->setCurrentIndex(
|
||||
Settings::values.fsr_sharpening_slider.UsingGlobal() ? 0 : 1);
|
||||
ui->fsr_sharpening_slider->setEnabled(
|
||||
!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
||||
ui->fsr_sharpening_value->setEnabled(!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout,
|
||||
!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
||||
ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue());
|
||||
|
||||
ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1);
|
||||
ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal());
|
||||
}
|
||||
UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
|
||||
Settings::values.bg_green.GetValue(),
|
||||
Settings::values.bg_blue.GetValue()));
|
||||
UpdateAPILayout();
|
||||
PopulateVSyncModeSelection(); //< must happen after UpdateAPILayout
|
||||
SetFSRIndicatorText(ui->fsr_sharpening_slider->sliderPosition());
|
||||
|
||||
// VSync setting needs to be determined after populating the VSync combobox
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
const auto vsync_mode_setting = Settings::values.vsync_mode.GetValue();
|
||||
const auto vsync_mode = VSyncSettingToMode(vsync_mode_setting);
|
||||
int index{};
|
||||
for (const auto mode : vsync_mode_combobox_enum_map) {
|
||||
if (mode == vsync_mode) {
|
||||
break;
|
||||
for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
|
||||
ConfigurationShared::Widget* widget = [&]() {
|
||||
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
||||
// FSR needs a reversed slider and a 0.5 multiplier
|
||||
return builder.BuildWidget(
|
||||
setting, apply_funcs, ConfigurationShared::RequestType::ReverseSlider, true,
|
||||
0.5f, nullptr, tr("%", "FSR sharpening percentage (e.g. 50%)"));
|
||||
} else {
|
||||
return builder.BuildWidget(setting, apply_funcs);
|
||||
}
|
||||
index++;
|
||||
}();
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (static_cast<unsigned long>(index) < vsync_mode_combobox_enum_map.size()) {
|
||||
ui->vsync_mode_combobox->setCurrentIndex(index);
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setting->Id() == Settings::values.renderer_backend.Id()) {
|
||||
// Add the renderer combobox now so it's at the top
|
||||
api_grid_layout->addWidget(widget);
|
||||
api_combobox = widget->combobox;
|
||||
api_restore_global_button = widget->restore_button;
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(api_restore_global_button, &QAbstractButton::clicked,
|
||||
[this](bool) { UpdateAPILayout(); });
|
||||
|
||||
// Detach API's restore button and place it where we want
|
||||
// Lets us put it on the side, and it will automatically scale if there's a
|
||||
// second combobox (shader_backend, vulkan_device)
|
||||
widget->layout()->removeWidget(api_restore_global_button);
|
||||
api_layout->addWidget(api_restore_global_button);
|
||||
}
|
||||
} else if (setting->Id() == Settings::values.vulkan_device.Id()) {
|
||||
// Keep track of vulkan_device's combobox so we can populate it
|
||||
hold_api.push_back(widget);
|
||||
vulkan_device_combobox = widget->combobox;
|
||||
vulkan_device_widget = widget;
|
||||
} else if (setting->Id() == Settings::values.shader_backend.Id()) {
|
||||
// Keep track of shader_backend's combobox so we can populate it
|
||||
hold_api.push_back(widget);
|
||||
shader_backend_combobox = widget->combobox;
|
||||
shader_backend_widget = widget;
|
||||
} else if (setting->Id() == Settings::values.vsync_mode.Id()) {
|
||||
// Keep track of vsync_mode's combobox so we can populate it
|
||||
vsync_mode_combobox = widget->combobox;
|
||||
hold_graphics.emplace(setting->Id(), widget);
|
||||
} else {
|
||||
hold_graphics.emplace(setting->Id(), widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphics::SetFSRIndicatorText(int percentage) {
|
||||
ui->fsr_sharpening_value->setText(
|
||||
tr("%1%", "FSR sharpening percentage (e.g. 50%)").arg(100 - (percentage / 2)));
|
||||
for (const auto& [id, widget] : hold_graphics) {
|
||||
graphics_layout.addWidget(widget);
|
||||
}
|
||||
|
||||
for (auto widget : hold_api) {
|
||||
api_grid_layout->addWidget(widget);
|
||||
}
|
||||
|
||||
// Background color is too specific to build into the new system, so we manage it here
|
||||
// (3 settings, all collected into a single widget with a QColor to manage on top)
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
apply_funcs.push_back([this](bool powered_on) {
|
||||
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||
});
|
||||
} else {
|
||||
QPushButton* bg_restore_button = ConfigurationShared::Widget::CreateRestoreGlobalButton(
|
||||
Settings::values.bg_red.UsingGlobal(), ui->bg_widget);
|
||||
ui->bg_widget->layout()->addWidget(bg_restore_button);
|
||||
|
||||
QObject::connect(bg_restore_button, &QAbstractButton::clicked,
|
||||
[bg_restore_button, this](bool) {
|
||||
const int r = Settings::values.bg_red.GetValue(true);
|
||||
const int g = Settings::values.bg_green.GetValue(true);
|
||||
const int b = Settings::values.bg_blue.GetValue(true);
|
||||
UpdateBackgroundColorButton(QColor::fromRgb(r, g, b));
|
||||
|
||||
bg_restore_button->setVisible(false);
|
||||
bg_restore_button->setEnabled(false);
|
||||
});
|
||||
|
||||
QObject::connect(ui->bg_button, &QAbstractButton::clicked, [bg_restore_button](bool) {
|
||||
bg_restore_button->setVisible(true);
|
||||
bg_restore_button->setEnabled(true);
|
||||
});
|
||||
|
||||
apply_funcs.push_back([bg_restore_button, this](bool powered_on) {
|
||||
const bool using_global = !bg_restore_button->isEnabled();
|
||||
Settings::values.bg_red.SetGlobal(using_global);
|
||||
Settings::values.bg_green.SetGlobal(using_global);
|
||||
Settings::values.bg_blue.SetGlobal(using_global);
|
||||
if (!using_global) {
|
||||
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const QString ConfigureGraphics::TranslateVSyncMode(VkPresentModeKHR mode,
|
||||
@ -315,130 +357,48 @@ const QString ConfigureGraphics::TranslateVSyncMode(VkPresentModeKHR mode,
|
||||
}
|
||||
}
|
||||
|
||||
int ConfigureGraphics::FindIndex(u32 enumeration, int value) const {
|
||||
for (u32 i = 0; i < combobox_translations.at(enumeration).size(); i++) {
|
||||
if (combobox_translations.at(enumeration)[i].first == static_cast<u32>(value)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ConfigureGraphics::ApplyConfiguration() {
|
||||
const auto resolution_setup = static_cast<Settings::ResolutionSetup>(
|
||||
ui->resolution_combobox->currentIndex() -
|
||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
|
||||
const auto scaling_filter = static_cast<Settings::ScalingFilter>(
|
||||
ui->scaling_filter_combobox->currentIndex() -
|
||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
|
||||
const auto anti_aliasing = static_cast<Settings::AntiAliasing>(
|
||||
ui->anti_aliasing_combobox->currentIndex() -
|
||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
|
||||
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.accelerate_astc, ui->accelerate_astc,
|
||||
accelerate_astc);
|
||||
const bool powered_on = system.IsPoweredOn();
|
||||
for (const auto& func : apply_funcs) {
|
||||
func(powered_on);
|
||||
}
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.renderer_backend.UsingGlobal()) {
|
||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
||||
}
|
||||
if (Settings::values.nvdec_emulation.UsingGlobal()) {
|
||||
Settings::values.nvdec_emulation.SetValue(GetCurrentNvdecEmulation());
|
||||
}
|
||||
if (Settings::values.shader_backend.UsingGlobal()) {
|
||||
Settings::values.shader_backend.SetValue(shader_backend);
|
||||
}
|
||||
if (Settings::values.vulkan_device.UsingGlobal()) {
|
||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
||||
}
|
||||
if (Settings::values.bg_red.UsingGlobal()) {
|
||||
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||
}
|
||||
if (Settings::values.resolution_setup.UsingGlobal()) {
|
||||
Settings::values.resolution_setup.SetValue(resolution_setup);
|
||||
}
|
||||
if (Settings::values.scaling_filter.UsingGlobal()) {
|
||||
Settings::values.scaling_filter.SetValue(scaling_filter);
|
||||
}
|
||||
if (Settings::values.anti_aliasing.UsingGlobal()) {
|
||||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
||||
}
|
||||
Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value());
|
||||
|
||||
const auto mode = vsync_mode_combobox_enum_map[ui->vsync_mode_combobox->currentIndex()];
|
||||
const auto mode = vsync_mode_combobox_enum_map[vsync_mode_combobox->currentIndex()];
|
||||
const auto vsync_mode = PresentModeToSetting(mode);
|
||||
Settings::values.vsync_mode.SetValue(vsync_mode);
|
||||
} else {
|
||||
if (ui->resolution_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.resolution_setup.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.resolution_setup.SetGlobal(false);
|
||||
Settings::values.resolution_setup.SetValue(resolution_setup);
|
||||
}
|
||||
if (ui->scaling_filter_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.scaling_filter.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.scaling_filter.SetGlobal(false);
|
||||
Settings::values.scaling_filter.SetValue(scaling_filter);
|
||||
}
|
||||
if (ui->anti_aliasing_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.anti_aliasing.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.anti_aliasing.SetGlobal(false);
|
||||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
||||
}
|
||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.renderer_backend.SetGlobal(true);
|
||||
Settings::values.shader_backend.SetGlobal(true);
|
||||
Settings::values.vulkan_device.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.renderer_backend.SetGlobal(false);
|
||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
||||
switch (GetCurrentGraphicsBackend()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
case Settings::RendererBackend::Null:
|
||||
Settings::values.shader_backend.SetGlobal(false);
|
||||
Settings::values.vulkan_device.SetGlobal(true);
|
||||
Settings::values.shader_backend.SetValue(shader_backend);
|
||||
break;
|
||||
case Settings::RendererBackend::Vulkan:
|
||||
Settings::values.shader_backend.SetGlobal(true);
|
||||
Settings::values.vulkan_device.SetGlobal(false);
|
||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ui->nvdec_emulation->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.nvdec_emulation.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.nvdec_emulation.SetGlobal(false);
|
||||
Settings::values.nvdec_emulation.SetValue(GetCurrentNvdecEmulation());
|
||||
}
|
||||
|
||||
if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.bg_red.SetGlobal(true);
|
||||
Settings::values.bg_green.SetGlobal(true);
|
||||
Settings::values.bg_blue.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.bg_red.SetGlobal(false);
|
||||
Settings::values.bg_green.SetGlobal(false);
|
||||
Settings::values.bg_blue.SetGlobal(false);
|
||||
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||
}
|
||||
|
||||
if (ui->fsr_sharpening_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.fsr_sharpening_slider.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.fsr_sharpening_slider.SetGlobal(false);
|
||||
Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value());
|
||||
Settings::values.vulkan_device.SetGlobal(true);
|
||||
Settings::values.shader_backend.SetGlobal(true);
|
||||
if (Settings::IsConfiguringGlobal() ||
|
||||
(!Settings::IsConfiguringGlobal() && api_restore_global_button->isEnabled())) {
|
||||
auto backend = static_cast<Settings::RendererBackend>(
|
||||
combobox_translations
|
||||
.at(Settings::EnumMetadata<
|
||||
Settings::RendererBackend>::Index())[api_combobox->currentIndex()]
|
||||
.first);
|
||||
switch (backend) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
Settings::values.shader_backend.SetGlobal(Settings::IsConfiguringGlobal());
|
||||
Settings::values.shader_backend.SetValue(static_cast<Settings::ShaderBackend>(
|
||||
shader_mapping[shader_backend_combobox->currentIndex()].first));
|
||||
break;
|
||||
case Settings::RendererBackend::Vulkan:
|
||||
Settings::values.vulkan_device.SetGlobal(Settings::IsConfiguringGlobal());
|
||||
Settings::values.vulkan_device.SetValue(vulkan_device_combobox->currentIndex());
|
||||
break;
|
||||
case Settings::RendererBackend::Null:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -466,36 +426,26 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
|
||||
}
|
||||
|
||||
void ConfigureGraphics::UpdateAPILayout() {
|
||||
if (!Settings::IsConfiguringGlobal() &&
|
||||
ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue(true);
|
||||
shader_backend = Settings::values.shader_backend.GetValue(true);
|
||||
ui->device_widget->setEnabled(false);
|
||||
ui->backend_widget->setEnabled(false);
|
||||
} else {
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||
shader_backend = Settings::values.shader_backend.GetValue();
|
||||
ui->device_widget->setEnabled(true);
|
||||
ui->backend_widget->setEnabled(true);
|
||||
}
|
||||
bool runtime_lock = !system.IsPoweredOn();
|
||||
bool need_global = !(Settings::IsConfiguringGlobal() || api_restore_global_button->isEnabled());
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue(need_global);
|
||||
shader_backend = Settings::values.shader_backend.GetValue(need_global);
|
||||
vulkan_device_widget->setEnabled(!need_global && runtime_lock);
|
||||
shader_backend_widget->setEnabled(!need_global && runtime_lock);
|
||||
|
||||
switch (GetCurrentGraphicsBackend()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
ui->backend->setCurrentIndex(static_cast<u32>(shader_backend));
|
||||
ui->device_widget->setVisible(false);
|
||||
ui->backend_widget->setVisible(true);
|
||||
break;
|
||||
case Settings::RendererBackend::Vulkan:
|
||||
if (static_cast<int>(vulkan_device) < ui->device->count()) {
|
||||
ui->device->setCurrentIndex(vulkan_device);
|
||||
}
|
||||
ui->device_widget->setVisible(true);
|
||||
ui->backend_widget->setVisible(false);
|
||||
break;
|
||||
case Settings::RendererBackend::Null:
|
||||
ui->device_widget->setVisible(false);
|
||||
ui->backend_widget->setVisible(false);
|
||||
break;
|
||||
const auto current_backend = GetCurrentGraphicsBackend();
|
||||
const bool is_opengl = current_backend == Settings::RendererBackend::OpenGL;
|
||||
const bool is_vulkan = current_backend == Settings::RendererBackend::Vulkan;
|
||||
|
||||
vulkan_device_widget->setVisible(is_vulkan);
|
||||
shader_backend_widget->setVisible(is_opengl);
|
||||
|
||||
if (is_opengl) {
|
||||
shader_backend_combobox->setCurrentIndex(
|
||||
FindIndex(Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
|
||||
static_cast<int>(shader_backend)));
|
||||
} else if (is_vulkan && static_cast<int>(vulkan_device) < vulkan_device_combobox->count()) {
|
||||
vulkan_device_combobox->setCurrentIndex(vulkan_device);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,92 +465,11 @@ void ConfigureGraphics::RetrieveVulkanDevices() {
|
||||
}
|
||||
|
||||
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex());
|
||||
if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) {
|
||||
return Settings::values.renderer_backend.GetValue(true);
|
||||
}
|
||||
|
||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.renderer_backend.SetGlobal(true);
|
||||
return Settings::values.renderer_backend.GetValue();
|
||||
}
|
||||
Settings::values.renderer_backend.SetGlobal(false);
|
||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex() -
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
Settings::NvdecEmulation ConfigureGraphics::GetCurrentNvdecEmulation() const {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
return static_cast<Settings::NvdecEmulation>(ui->nvdec_emulation->currentIndex());
|
||||
}
|
||||
|
||||
if (ui->nvdec_emulation->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.nvdec_emulation.SetGlobal(true);
|
||||
return Settings::values.nvdec_emulation.GetValue();
|
||||
}
|
||||
Settings::values.nvdec_emulation.SetGlobal(false);
|
||||
return static_cast<Settings::NvdecEmulation>(ui->nvdec_emulation->currentIndex() -
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
void ConfigureGraphics::SetupPerGameUI() {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
||||
ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
||||
ui->fullscreen_mode_combobox->setEnabled(Settings::values.fullscreen_mode.UsingGlobal());
|
||||
ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal());
|
||||
ui->resolution_combobox->setEnabled(Settings::values.resolution_setup.UsingGlobal());
|
||||
ui->scaling_filter_combobox->setEnabled(Settings::values.scaling_filter.UsingGlobal());
|
||||
ui->fsr_sharpening_slider->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal());
|
||||
ui->anti_aliasing_combobox->setEnabled(Settings::values.anti_aliasing.UsingGlobal());
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(
|
||||
Settings::values.use_asynchronous_gpu_emulation.UsingGlobal());
|
||||
ui->nvdec_emulation->setEnabled(Settings::values.nvdec_emulation.UsingGlobal());
|
||||
ui->accelerate_astc->setEnabled(Settings::values.accelerate_astc.UsingGlobal());
|
||||
ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||
ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal());
|
||||
ui->fsr_slider_layout->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
connect(ui->bg_combobox, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||
ui->bg_button->setEnabled(index == 1);
|
||||
ConfigurationShared::SetHighlight(ui->bg_layout, index == 1);
|
||||
});
|
||||
|
||||
connect(ui->fsr_sharpening_combobox, qOverload<int>(&QComboBox::activated), this,
|
||||
[this](int index) {
|
||||
ui->fsr_sharpening_slider->setEnabled(index == 1);
|
||||
ui->fsr_sharpening_value->setEnabled(index == 1);
|
||||
ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout, index == 1);
|
||||
});
|
||||
|
||||
ConfigurationShared::SetColoredTristate(
|
||||
ui->use_disk_shader_cache, Settings::values.use_disk_shader_cache, use_disk_shader_cache);
|
||||
ConfigurationShared::SetColoredTristate(ui->accelerate_astc, Settings::values.accelerate_astc,
|
||||
accelerate_astc);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_gpu_emulation,
|
||||
Settings::values.use_asynchronous_gpu_emulation,
|
||||
use_asynchronous_gpu_emulation);
|
||||
|
||||
ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label,
|
||||
Settings::values.aspect_ratio.GetValue(true));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->fullscreen_mode_combobox, ui->fullscreen_mode_label,
|
||||
static_cast<int>(Settings::values.fullscreen_mode.GetValue(true)));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->resolution_combobox, ui->resolution_label,
|
||||
static_cast<int>(Settings::values.resolution_setup.GetValue(true)));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->scaling_filter_combobox, ui->scaling_filter_label,
|
||||
static_cast<int>(Settings::values.scaling_filter.GetValue(true)));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->anti_aliasing_combobox, ui->anti_aliasing_label,
|
||||
static_cast<int>(Settings::values.anti_aliasing.GetValue(true)));
|
||||
ConfigurationShared::InsertGlobalItem(
|
||||
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
|
||||
ConfigurationShared::InsertGlobalItem(
|
||||
ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true)));
|
||||
|
||||
ui->vsync_mode_layout->setVisible(false);
|
||||
return static_cast<Settings::RendererBackend>(
|
||||
combobox_translations.at(Settings::EnumMetadata<Settings::RendererBackend>::Index())
|
||||
.at(api_combobox->currentIndex())
|
||||
.first);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <typeindex>
|
||||
#include <vector>
|
||||
#include <QColor>
|
||||
#include <QString>
|
||||
@ -12,10 +14,14 @@
|
||||
#include <qobjectdefs.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include "common/common_types.h"
|
||||
#include "configuration/shared_translation.h"
|
||||
#include "vk_device_info.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
class QPushButton;
|
||||
class QEvent;
|
||||
class QObject;
|
||||
class QComboBox;
|
||||
|
||||
namespace Settings {
|
||||
enum class NvdecEmulation : u32;
|
||||
@ -27,31 +33,33 @@ namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureGraphics;
|
||||
}
|
||||
|
||||
class ConfigureGraphics : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureGraphics : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureGraphics(const Core::System& system_,
|
||||
std::vector<VkDeviceInfo::Record>& records,
|
||||
const std::function<void()>& expose_compute_option_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder,
|
||||
QWidget* parent = nullptr);
|
||||
~ConfigureGraphics() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
|
||||
void PopulateVSyncModeSelection();
|
||||
void UpdateBackgroundColorButton(QColor color);
|
||||
void UpdateAPILayout();
|
||||
@ -60,34 +68,40 @@ private:
|
||||
|
||||
void RetrieveVulkanDevices();
|
||||
|
||||
void SetFSRIndicatorText(int percentage);
|
||||
/* Turns a Vulkan present mode into a textual string for a UI
|
||||
* (and eventually for a human to read) */
|
||||
const QString TranslateVSyncMode(VkPresentModeKHR mode,
|
||||
Settings::RendererBackend backend) const;
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
Settings::RendererBackend GetCurrentGraphicsBackend() const;
|
||||
Settings::NvdecEmulation GetCurrentNvdecEmulation() const;
|
||||
|
||||
int FindIndex(u32 enumeration, int value) const;
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||
QColor bg_color;
|
||||
|
||||
ConfigurationShared::CheckState use_nvdec_emulation;
|
||||
ConfigurationShared::CheckState accelerate_astc;
|
||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||
ConfigurationShared::CheckState use_asynchronous_gpu_emulation;
|
||||
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||
|
||||
std::vector<VkDeviceInfo::Record>& records;
|
||||
std::vector<QString> vulkan_devices;
|
||||
std::vector<std::vector<VkPresentModeKHR>> device_present_modes;
|
||||
std::vector<VkPresentModeKHR>
|
||||
vsync_mode_combobox_enum_map; //< Keeps track of which present mode corresponds to which
|
||||
// selection in the combobox
|
||||
vsync_mode_combobox_enum_map{}; //< Keeps track of which present mode corresponds to which
|
||||
// selection in the combobox
|
||||
u32 vulkan_device{};
|
||||
Settings::ShaderBackend shader_backend{};
|
||||
const std::function<void()>& expose_compute_option;
|
||||
|
||||
const Core::System& system;
|
||||
const ConfigurationShared::ComboboxTranslationMap& combobox_translations;
|
||||
const std::vector<std::pair<u32, QString>>& shader_mapping;
|
||||
|
||||
QPushButton* api_restore_global_button;
|
||||
QComboBox* vulkan_device_combobox;
|
||||
QComboBox* api_combobox;
|
||||
QComboBox* shader_backend_combobox;
|
||||
QComboBox* vsync_mode_combobox;
|
||||
QWidget* vulkan_device_widget;
|
||||
QWidget* api_widget;
|
||||
QWidget* shader_backend_widget;
|
||||
};
|
||||
|
@ -27,7 +27,7 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QWidget" name="api_widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -40,115 +40,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="4" column="0">
|
||||
<widget class="QWidget" name="backend_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="backend_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="backend_label">
|
||||
<property name="text">
|
||||
<string>Shader Backend:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="backend"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QWidget" name="device_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="device_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="device_label">
|
||||
<property name="text">
|
||||
<string>Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="device"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="api_layout_2" native="true">
|
||||
<layout class="QHBoxLayout" name="api_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="api_label">
|
||||
<property name="text">
|
||||
<string>API:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="api">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">OpenGL</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Vulkan</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -168,29 +59,8 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_disk_shader_cache">
|
||||
<property name="text">
|
||||
<string>Use disk pipeline cache</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_asynchronous_gpu_emulation">
|
||||
<property name="text">
|
||||
<string>Use asynchronous GPU emulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="accelerate_astc">
|
||||
<property name="text">
|
||||
<string>Accelerate ASTC texture decoding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="vsync_mode_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<widget class="QWidget" name="graphics_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -203,32 +73,12 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="vsync_mode_label">
|
||||
<property name="text">
|
||||
<string>VSync Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="vsync_mode_combobox">
|
||||
<property name="toolTip">
|
||||
<string>FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.
|
||||
FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.
|
||||
Mailbox can have lower latency than FIFO and does not tear but may drop frames.
|
||||
Immediate (no synchronization) just presents whatever is available and can exhibit tearing.</string>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="nvdec_emulation_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="nvdec_emulation_layout">
|
||||
<widget class="QWidget" name="bg_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="bg_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -242,535 +92,35 @@ Immediate (no synchronization) just presents whatever is available and can exhib
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="nvdec_emulation_label">
|
||||
<property name="text">
|
||||
<string>NVDEC emulation:</string>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="nvdec_emulation">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No Video Output</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CPU Video Decoding</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>GPU Video Decoding (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="fullscreen_mode_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="fullscreen_mode_label">
|
||||
<property name="text">
|
||||
<string>Fullscreen Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="fullscreen_mode_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Borderless Windowed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Exclusive Fullscreen</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="aspect_ratio_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ar_label">
|
||||
<property name="text">
|
||||
<string>Aspect Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="aspect_ratio_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default (16:9)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force 4:3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force 21:9</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force 16:10</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stretch to Window</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="resolution_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="resolution_label">
|
||||
<property name="text">
|
||||
<string>Resolution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="resolution_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0.5X (360p/540p) [EXPERIMENTAL]</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0.75X (540p/810p) [EXPERIMENTAL]</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1X (720p/1080p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1.5X (1080p/1620p) [EXPERIMENTAL]</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2X (1440p/2160p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3X (2160p/3240p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4X (2880p/4320p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5X (3600p/5400p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6X (4320p/6480p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7X (5040p/7560p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8X (5760p/8640p)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="scaling_filter_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="scaling_filter_label">
|
||||
<property name="text">
|
||||
<string>Window Adapting Filter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="scaling_filter_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nearest Neighbor</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bilinear</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bicubic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Gaussian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ScaleForce</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>AMD FidelityFX™️ Super Resolution</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="anti_aliasing_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="anti_aliasing_label">
|
||||
<property name="text">
|
||||
<string>Anti-Aliasing Method:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="anti_aliasing_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>FXAA</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>SMAA</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="fsr_sharpening_layout" native="true">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="fsr_sharpening_label_group">
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="fsr_sharpening_combobox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global FSR Sharpness</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set FSR Sharpness</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="fsr_sharpening_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FSR Sharpness:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="fsr_slider_layout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="fsr_sharpening_slider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="fsr_sharpening_value">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>100%</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="bg_layout" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="bg_combobox">
|
||||
<property name="currentText">
|
||||
<string>Use global background color</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global background color</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set background color:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="bg_label">
|
||||
<property name="text">
|
||||
<string>Background Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="bg_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1,104 +1,68 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <vector>
|
||||
#include <QLabel>
|
||||
#include <qnamespace.h>
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "ui_configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
|
||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
|
||||
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
Setup(builder);
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
ui->enable_compute_pipelines_checkbox->setVisible(false);
|
||||
checkbox_enable_compute_pipelines->setVisible(false);
|
||||
}
|
||||
|
||||
ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
||||
|
||||
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||
const bool runtime_lock = !system.IsPoweredOn();
|
||||
ui->use_reactive_flushing->setEnabled(runtime_lock);
|
||||
ui->async_present->setEnabled(runtime_lock);
|
||||
ui->renderer_force_max_clock->setEnabled(runtime_lock);
|
||||
ui->async_astc->setEnabled(runtime_lock);
|
||||
ui->astc_recompression_combobox->setEnabled(runtime_lock);
|
||||
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
|
||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
||||
ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock);
|
||||
void ConfigureGraphicsAdvanced::SetConfiguration() {}
|
||||
|
||||
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
|
||||
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
||||
ui->use_reactive_flushing->setChecked(Settings::values.use_reactive_flushing.GetValue());
|
||||
ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
|
||||
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
||||
ui->use_vulkan_driver_pipeline_cache->setChecked(
|
||||
Settings::values.use_vulkan_driver_pipeline_cache.GetValue());
|
||||
ui->enable_compute_pipelines_checkbox->setChecked(
|
||||
Settings::values.enable_compute_pipelines.GetValue());
|
||||
ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue());
|
||||
ui->barrier_feedback_loops_checkbox->setChecked(
|
||||
Settings::values.barrier_feedback_loops.GetValue());
|
||||
void ConfigureGraphicsAdvanced::Setup(const ConfigurationShared::Builder& builder) {
|
||||
auto& layout = *ui->populate_target->layout();
|
||||
std::map<u32, QWidget*> hold{}; // A map will sort the data for us
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->gpu_accuracy->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue()));
|
||||
ui->anisotropic_filtering_combobox->setCurrentIndex(
|
||||
Settings::values.max_anisotropy.GetValue());
|
||||
ui->astc_recompression_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.astc_recompression.GetValue()));
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy);
|
||||
ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox,
|
||||
&Settings::values.max_anisotropy);
|
||||
ConfigurationShared::SetPerGameSetting(ui->astc_recompression_combobox,
|
||||
&Settings::values.astc_recompression);
|
||||
ConfigurationShared::SetHighlight(ui->label_gpu_accuracy,
|
||||
!Settings::values.gpu_accuracy.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->af_label,
|
||||
!Settings::values.max_anisotropy.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->label_astc_recompression,
|
||||
!Settings::values.astc_recompression.UsingGlobal());
|
||||
for (auto setting :
|
||||
Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
|
||||
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
hold.emplace(setting->Id(), widget);
|
||||
|
||||
// Keep track of enable_compute_pipelines so we can display it when needed
|
||||
if (setting->Id() == Settings::values.enable_compute_pipelines.Id()) {
|
||||
checkbox_enable_compute_pipelines = widget;
|
||||
}
|
||||
}
|
||||
for (const auto& [id, widget] : hold) {
|
||||
layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_presentation,
|
||||
ui->async_present, async_present);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock,
|
||||
ui->renderer_force_max_clock,
|
||||
renderer_force_max_clock);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
||||
ui->anisotropic_filtering_combobox);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_reactive_flushing,
|
||||
ui->use_reactive_flushing, use_reactive_flushing);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc,
|
||||
async_astc);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.astc_recompression,
|
||||
ui->astc_recompression_combobox);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
||||
ui->use_asynchronous_shaders,
|
||||
use_asynchronous_shaders);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
|
||||
ui->use_fast_gpu_time, use_fast_gpu_time);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache,
|
||||
ui->use_vulkan_driver_pipeline_cache,
|
||||
use_vulkan_driver_pipeline_cache);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines,
|
||||
ui->enable_compute_pipelines_checkbox,
|
||||
enable_compute_pipelines);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate,
|
||||
ui->use_video_framerate_checkbox, use_video_framerate);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.barrier_feedback_loops,
|
||||
ui->barrier_feedback_loops_checkbox,
|
||||
barrier_feedback_loops);
|
||||
const bool is_powered_on = system.IsPoweredOn();
|
||||
for (const auto& func : apply_funcs) {
|
||||
func(is_powered_on);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||
@ -113,71 +77,6 @@ void ConfigureGraphicsAdvanced::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||
// Disable if not global (only happens during game)
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
||||
ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
|
||||
ui->renderer_force_max_clock->setEnabled(
|
||||
Settings::values.renderer_force_max_clock.UsingGlobal());
|
||||
ui->use_reactive_flushing->setEnabled(Settings::values.use_reactive_flushing.UsingGlobal());
|
||||
ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal());
|
||||
ui->astc_recompression_combobox->setEnabled(
|
||||
Settings::values.astc_recompression.UsingGlobal());
|
||||
ui->use_asynchronous_shaders->setEnabled(
|
||||
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
||||
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
|
||||
ui->use_vulkan_driver_pipeline_cache->setEnabled(
|
||||
Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal());
|
||||
ui->anisotropic_filtering_combobox->setEnabled(
|
||||
Settings::values.max_anisotropy.UsingGlobal());
|
||||
ui->enable_compute_pipelines_checkbox->setEnabled(
|
||||
Settings::values.enable_compute_pipelines.UsingGlobal());
|
||||
ui->use_video_framerate_checkbox->setEnabled(
|
||||
Settings::values.use_video_framerate.UsingGlobal());
|
||||
ui->barrier_feedback_loops_checkbox->setEnabled(
|
||||
Settings::values.barrier_feedback_loops.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->async_present, Settings::values.async_presentation,
|
||||
async_present);
|
||||
ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
|
||||
Settings::values.renderer_force_max_clock,
|
||||
renderer_force_max_clock);
|
||||
ConfigurationShared::SetColoredTristate(
|
||||
ui->use_reactive_flushing, Settings::values.use_reactive_flushing, use_reactive_flushing);
|
||||
ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc,
|
||||
async_astc);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
|
||||
Settings::values.use_asynchronous_shaders,
|
||||
use_asynchronous_shaders);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
|
||||
Settings::values.use_fast_gpu_time, use_fast_gpu_time);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache,
|
||||
Settings::values.use_vulkan_driver_pipeline_cache,
|
||||
use_vulkan_driver_pipeline_cache);
|
||||
ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox,
|
||||
Settings::values.enable_compute_pipelines,
|
||||
enable_compute_pipelines);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox,
|
||||
Settings::values.use_video_framerate,
|
||||
use_video_framerate);
|
||||
ConfigurationShared::SetColoredTristate(ui->barrier_feedback_loops_checkbox,
|
||||
Settings::values.barrier_feedback_loops,
|
||||
barrier_feedback_loops);
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->gpu_accuracy, ui->label_gpu_accuracy,
|
||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->anisotropic_filtering_combobox, ui->af_label,
|
||||
static_cast<int>(Settings::values.max_anisotropy.GetValue(true)));
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->astc_recompression_combobox, ui->label_astc_recompression,
|
||||
static_cast<int>(Settings::values.astc_recompression.GetValue(true)));
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::ExposeComputeOption() {
|
||||
ui->enable_compute_pipelines_checkbox->setVisible(true);
|
||||
checkbox_enable_compute_pipelines->setVisible(true);
|
||||
}
|
||||
|
@ -4,51 +4,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureGraphicsAdvanced;
|
||||
}
|
||||
|
||||
class ConfigureGraphicsAdvanced : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureGraphicsAdvanced : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent = nullptr);
|
||||
explicit ConfigureGraphicsAdvanced(
|
||||
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||
~ConfigureGraphicsAdvanced() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
void ExposeComputeOption();
|
||||
|
||||
private:
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
||||
|
||||
ConfigurationShared::CheckState async_present;
|
||||
ConfigurationShared::CheckState renderer_force_max_clock;
|
||||
ConfigurationShared::CheckState use_vsync;
|
||||
ConfigurationShared::CheckState async_astc;
|
||||
ConfigurationShared::CheckState use_reactive_flushing;
|
||||
ConfigurationShared::CheckState use_asynchronous_shaders;
|
||||
ConfigurationShared::CheckState use_fast_gpu_time;
|
||||
ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
|
||||
ConfigurationShared::CheckState enable_compute_pipelines;
|
||||
ConfigurationShared::CheckState use_video_framerate;
|
||||
ConfigurationShared::CheckState barrier_feedback_loops;
|
||||
|
||||
const Core::System& system;
|
||||
|
||||
std::vector<std::function<void(bool)>> apply_funcs;
|
||||
|
||||
QWidget* checkbox_enable_compute_pipelines{};
|
||||
};
|
||||
|
@ -26,8 +26,8 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QWidget" name="gpu_accuracy_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<widget class="QWidget" name="populate_target" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -40,233 +40,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_gpu_accuracy">
|
||||
<property name="text">
|
||||
<string>Accuracy Level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="gpu_accuracy">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">High</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Extreme(very slow)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="astc_recompression_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_astc_recompression">
|
||||
<property name="text">
|
||||
<string>ASTC recompression:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="astc_recompression_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Uncompressed (Best quality)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BC1 (Low quality)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BC3 (Medium quality)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="async_present">
|
||||
<property name="text">
|
||||
<string>Enable asynchronous presentation (Vulkan only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="renderer_force_max_clock">
|
||||
<property name="toolTip">
|
||||
<string>Runs work in the background while waiting for graphics commands to keep the GPU from lowering its clock speed.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Force maximum clocks (Vulkan only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="async_astc">
|
||||
<property name="toolTip">
|
||||
<string>Enables asynchronous ASTC texture decoding, which may reduce load time stutter. This feature is experimental.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Decode ASTC textures asynchronously (Hack)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_reactive_flushing">
|
||||
<property name="toolTip">
|
||||
<string>Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Reactive Flushing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_asynchronous_shaders">
|
||||
<property name="toolTip">
|
||||
<string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use asynchronous shader building (Hack)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_fast_gpu_time">
|
||||
<property name="toolTip">
|
||||
<string>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Fast GPU Time (Hack)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache">
|
||||
<property name="toolTip">
|
||||
<string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Vulkan pipeline cache</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enable_compute_pipelines_checkbox">
|
||||
<property name="toolTip">
|
||||
<string>Enable compute pipelines, required by some games. This setting only exists for Intel proprietary drivers, and may crash if enabled.
|
||||
Compute pipelines are always enabled on all other drivers.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Compute Pipelines (Intel Vulkan only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_video_framerate_checkbox">
|
||||
<property name="toolTip">
|
||||
<string>Run the game at normal speed during video playback, even when the framerate is unlocked.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sync to framerate of video playback</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="barrier_feedback_loops_checkbox">
|
||||
<property name="toolTip">
|
||||
<string>Improves rendering of transparency effects in specific games.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Barrier feedback loops</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="af_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="af_label">
|
||||
<property name="text">
|
||||
<string>Anisotropic Filtering:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="anisotropic_filtering_combobox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2x</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4x</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8x</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>16x</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
#include "common/fs/fs_util.h"
|
||||
#include "configuration/shared_widget.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
@ -24,9 +25,9 @@
|
||||
#include "core/loader/loader.h"
|
||||
#include "ui_configure_per_game.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_audio.h"
|
||||
#include "yuzu/configuration/configure_cpu.h"
|
||||
#include "yuzu/configuration/configure_general.h"
|
||||
#include "yuzu/configuration/configure_graphics.h"
|
||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/configure_input_per_game.h"
|
||||
@ -41,26 +42,28 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
|
||||
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
||||
Core::System& system_)
|
||||
: QDialog(parent),
|
||||
ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} {
|
||||
ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_},
|
||||
builder{std::make_unique<ConfigurationShared::Builder>(this, !system_.IsPoweredOn())},
|
||||
tab_group{std::make_shared<std::vector<ConfigurationShared::Tab*>>()} {
|
||||
const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
|
||||
const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
|
||||
: fmt::format("{:016X}", title_id);
|
||||
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
||||
|
||||
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
|
||||
audio_tab = std::make_unique<ConfigureAudio>(system_, this);
|
||||
cpu_tab = std::make_unique<ConfigureCpu>(system_, this);
|
||||
general_tab = std::make_unique<ConfigureGeneral>(system_, this);
|
||||
graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this);
|
||||
audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *builder, this);
|
||||
cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *builder, this);
|
||||
graphics_advanced_tab =
|
||||
std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *builder, this);
|
||||
graphics_tab = std::make_unique<ConfigureGraphics>(
|
||||
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this);
|
||||
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
|
||||
tab_group, *builder, this);
|
||||
input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
|
||||
system_tab = std::make_unique<ConfigureSystem>(system_, this);
|
||||
system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *builder, this);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->tabWidget->addTab(addons_tab.get(), tr("Add-Ons"));
|
||||
ui->tabWidget->addTab(general_tab.get(), tr("General"));
|
||||
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
||||
ui->tabWidget->addTab(cpu_tab.get(), tr("CPU"));
|
||||
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
||||
@ -88,13 +91,10 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
|
||||
ConfigurePerGame::~ConfigurePerGame() = default;
|
||||
|
||||
void ConfigurePerGame::ApplyConfiguration() {
|
||||
for (const auto tab : *tab_group) {
|
||||
tab->ApplyConfiguration();
|
||||
}
|
||||
addons_tab->ApplyConfiguration();
|
||||
general_tab->ApplyConfiguration();
|
||||
cpu_tab->ApplyConfiguration();
|
||||
system_tab->ApplyConfiguration();
|
||||
graphics_tab->ApplyConfiguration();
|
||||
graphics_advanced_tab->ApplyConfiguration();
|
||||
audio_tab->ApplyConfiguration();
|
||||
input_tab->ApplyConfiguration();
|
||||
|
||||
system.ApplySettings();
|
||||
|
@ -10,9 +10,12 @@
|
||||
#include <QDialog>
|
||||
#include <QList>
|
||||
|
||||
#include "configuration/shared_widget.h"
|
||||
#include "core/file_sys/vfs_types.h"
|
||||
#include "vk_device_info.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
@ -25,7 +28,6 @@ class InputSubsystem;
|
||||
class ConfigurePerGameAddons;
|
||||
class ConfigureAudio;
|
||||
class ConfigureCpu;
|
||||
class ConfigureGeneral;
|
||||
class ConfigureGraphics;
|
||||
class ConfigureGraphicsAdvanced;
|
||||
class ConfigureInputPerGame;
|
||||
@ -73,11 +75,12 @@ private:
|
||||
std::unique_ptr<Config> game_config;
|
||||
|
||||
Core::System& system;
|
||||
std::unique_ptr<ConfigurationShared::Builder> builder;
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> tab_group;
|
||||
|
||||
std::unique_ptr<ConfigurePerGameAddons> addons_tab;
|
||||
std::unique_ptr<ConfigureAudio> audio_tab;
|
||||
std::unique_ptr<ConfigureCpu> cpu_tab;
|
||||
std::unique_ptr<ConfigureGeneral> general_tab;
|
||||
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
|
||||
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
||||
std::unique_ptr<ConfigureInputPerGame> input_tab;
|
||||
|
@ -2,6 +2,14 @@
|
||||
<ui version="4.0">
|
||||
<class>ConfigurePerGame</class>
|
||||
<widget class="QDialog" name="ConfigurePerGame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>900</width>
|
||||
<height>607</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>900</width>
|
||||
@ -225,20 +233,31 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Some settings are only available when a game is not running.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -3,16 +3,23 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QFileDialog>
|
||||
#include <QGraphicsItem>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/time/time_manager.h"
|
||||
#include "ui_configure_system.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_system.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
|
||||
constexpr std::array<u32, 7> LOCALE_BLOCKLIST{
|
||||
// pzzefezrpnkzeidfej
|
||||
@ -37,44 +44,32 @@ static bool IsValidLocale(u32 region_index, u32 language_index) {
|
||||
return ((LOCALE_BLOCKLIST.at(region_index) >> language_index) & 1) == 0;
|
||||
}
|
||||
|
||||
ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} {
|
||||
ConfigureSystem::ConfigureSystem(Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} {
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
ui->rng_seed_edit->setEnabled(state == Qt::Checked);
|
||||
if (state != Qt::Checked) {
|
||||
ui->rng_seed_edit->setText(QStringLiteral("00000000"));
|
||||
}
|
||||
});
|
||||
Setup(builder);
|
||||
|
||||
connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
ui->custom_rtc_edit->setEnabled(state == Qt::Checked);
|
||||
if (state != Qt::Checked) {
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime());
|
||||
}
|
||||
});
|
||||
|
||||
const auto locale_check = [this](int index) {
|
||||
const auto region_index = ConfigurationShared::GetComboboxIndex(
|
||||
Settings::values.region_index.GetValue(true), ui->combo_region);
|
||||
const auto language_index = ConfigurationShared::GetComboboxIndex(
|
||||
Settings::values.language_index.GetValue(true), ui->combo_language);
|
||||
const auto locale_check = [this]() {
|
||||
const auto region_index = combo_region->currentIndex();
|
||||
const auto language_index = combo_language->currentIndex();
|
||||
const bool valid_locale = IsValidLocale(region_index, language_index);
|
||||
ui->label_warn_invalid_locale->setVisible(!valid_locale);
|
||||
if (!valid_locale) {
|
||||
ui->label_warn_invalid_locale->setText(
|
||||
tr("Warning: \"%1\" is not a valid language for region \"%2\"")
|
||||
.arg(ui->combo_language->currentText())
|
||||
.arg(ui->combo_region->currentText()));
|
||||
.arg(combo_language->currentText())
|
||||
.arg(combo_region->currentText()));
|
||||
}
|
||||
};
|
||||
|
||||
connect(ui->combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
locale_check);
|
||||
connect(ui->combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
||||
connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
||||
connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
||||
|
||||
SetupPerGameUI();
|
||||
ui->label_warn_invalid_locale->setVisible(false);
|
||||
locale_check();
|
||||
|
||||
SetConfiguration();
|
||||
}
|
||||
@ -93,137 +88,66 @@ void ConfigureSystem::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureSystem::SetConfiguration() {
|
||||
enabled = !system.IsPoweredOn();
|
||||
const auto rng_seed =
|
||||
QStringLiteral("%1")
|
||||
.arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
|
||||
.toUpper();
|
||||
const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch());
|
||||
void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
|
||||
auto& core_layout = *ui->core_widget->layout();
|
||||
auto& system_layout = *ui->system_widget->layout();
|
||||
|
||||
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
|
||||
Settings::values.rng_seed.UsingGlobal());
|
||||
ui->rng_seed_edit->setText(rng_seed);
|
||||
std::map<u32, QWidget*> core_hold{};
|
||||
std::map<u32, QWidget*> system_hold{};
|
||||
|
||||
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
|
||||
ui->device_name_edit->setText(
|
||||
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());
|
||||
std::vector<Settings::BasicSetting*> settings;
|
||||
auto push = [&settings](auto& list) {
|
||||
for (auto setting : list) {
|
||||
settings.push_back(setting);
|
||||
}
|
||||
};
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
|
||||
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);
|
||||
push(Settings::values.linkage.by_category[Settings::Category::Core]);
|
||||
push(Settings::values.linkage.by_category[Settings::Category::System]);
|
||||
|
||||
ConfigurationShared::SetHighlight(ui->label_language,
|
||||
!Settings::values.language_index.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->label_region,
|
||||
!Settings::values.region_index.UsingGlobal());
|
||||
ConfigurationShared::SetHighlight(ui->label_timezone,
|
||||
!Settings::values.time_zone_index.UsingGlobal());
|
||||
for (auto setting : settings) {
|
||||
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!widget->Valid()) {
|
||||
widget->deleteLater();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setting->Id() == Settings::values.region_index.Id()) {
|
||||
// Keep track of the region_index (and langauge_index) combobox to validate the selected
|
||||
// settings
|
||||
combo_region = widget->combobox;
|
||||
} else if (setting->Id() == Settings::values.language_index.Id()) {
|
||||
combo_language = widget->combobox;
|
||||
}
|
||||
|
||||
switch (setting->GetCategory()) {
|
||||
case Settings::Category::Core:
|
||||
core_hold.emplace(setting->Id(), widget);
|
||||
break;
|
||||
case Settings::Category::System:
|
||||
system_hold.emplace(setting->Id(), widget);
|
||||
break;
|
||||
default:
|
||||
widget->deleteLater();
|
||||
}
|
||||
}
|
||||
for (const auto& [label, widget] : core_hold) {
|
||||
core_layout.addWidget(widget);
|
||||
}
|
||||
for (const auto& [id, widget] : system_hold) {
|
||||
system_layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureSystem::ReadSystemSettings() {}
|
||||
void ConfigureSystem::SetConfiguration() {}
|
||||
|
||||
void ConfigureSystem::ApplyConfiguration() {
|
||||
// Allow setting custom RTC even if system is powered on,
|
||||
// to allow in-game time to be fast forwarded
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
||||
Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
|
||||
if (system.IsPoweredOn()) {
|
||||
const s64 posix_time{*Settings::values.custom_rtc};
|
||||
system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
|
||||
}
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (ui->rng_seed_checkbox->isChecked()) {
|
||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (use_rng_seed) {
|
||||
case ConfigurationShared::CheckState::On:
|
||||
case ConfigurationShared::CheckState::Off:
|
||||
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));
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
break;
|
||||
case ConfigurationShared::CheckState::Global:
|
||||
Settings::values.rng_seed.SetGlobal(false);
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
Settings::values.rng_seed.SetGlobal(true);
|
||||
break;
|
||||
case ConfigurationShared::CheckState::Count:
|
||||
break;
|
||||
}
|
||||
const bool powered_on = system.IsPoweredOn();
|
||||
for (const auto& func : apply_funcs) {
|
||||
func(powered_on);
|
||||
}
|
||||
}
|
||||
|
||||
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.GetValue().has_value(),
|
||||
Settings::values.rng_seed.GetValue(true).has_value(), 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);
|
||||
}
|
||||
|
@ -3,45 +3,53 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class QComboBox;
|
||||
class QDateTimeEdit;
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace ConfigurationShared {
|
||||
enum class CheckState;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureSystem;
|
||||
}
|
||||
|
||||
class ConfigureSystem : public QWidget {
|
||||
Q_OBJECT
|
||||
namespace ConfigurationShared {
|
||||
class Builder;
|
||||
}
|
||||
|
||||
class ConfigureSystem : public ConfigurationShared::Tab {
|
||||
public:
|
||||
explicit ConfigureSystem(Core::System& system_, QWidget* parent = nullptr);
|
||||
explicit ConfigureSystem(Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||
const ConfigurationShared::Builder& builder,
|
||||
QWidget* parent = nullptr);
|
||||
~ConfigureSystem() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void SetConfiguration();
|
||||
void ApplyConfiguration() override;
|
||||
void SetConfiguration() override;
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void ReadSystemSettings();
|
||||
void Setup(const ConfigurationShared::Builder& builder);
|
||||
|
||||
void SetupPerGameUI();
|
||||
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||
|
||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||
bool enabled = false;
|
||||
|
||||
ConfigurationShared::CheckState use_rng_seed;
|
||||
ConfigurationShared::CheckState use_unsafe_extended_memory_layout;
|
||||
|
||||
Core::System& system;
|
||||
|
||||
QComboBox* combo_region;
|
||||
QComboBox* combo_language;
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>366</width>
|
||||
<width>605</width>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -22,470 +22,63 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="group_system_settings">
|
||||
<property name="title">
|
||||
<string>System Settings</string>
|
||||
<string>System</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_region">
|
||||
<property name="text">
|
||||
<string>Region:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="combo_time_zone">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CET</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CST6CDT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Cuba</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>EET</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Egypt</string>
|
||||
</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>
|
||||
<widget class="QWidget" name="system_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_warn_invalid_locale">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Core</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QWidget" name="core_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -503,26 +96,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_warn_invalid_locale">
|
||||
<property name="text">
|
||||
<string></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_disable_info">
|
||||
<property name="text">
|
||||
<string>System settings are available only when game is not running.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
388
src/yuzu/configuration/shared_translation.cpp
Normal file
388
src/yuzu/configuration/shared_translation.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/time_zone.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <QWidget>
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "common/settings_setting.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
||||
std::unique_ptr<TranslationMap> translations = std::make_unique<TranslationMap>();
|
||||
const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
|
||||
|
||||
#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \
|
||||
translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{tr((NAME)), tr((TOOLTIP))}})
|
||||
|
||||
// A setting can be ignored by giving it a blank name
|
||||
|
||||
// Audio
|
||||
INSERT(Settings, sink_id, "Output Engine:", "");
|
||||
INSERT(Settings, audio_output_device_id, "Output Device:", "");
|
||||
INSERT(Settings, audio_input_device_id, "Input Device:", "");
|
||||
INSERT(Settings, audio_muted, "Mute audio when in background", "");
|
||||
INSERT(Settings, volume, "Volume:", "");
|
||||
INSERT(Settings, dump_audio_commands, "", "");
|
||||
|
||||
// Core
|
||||
INSERT(Settings, use_multi_core, "Multicore CPU Emulation", "");
|
||||
INSERT(Settings, memory_layout_mode, "Memory Layout", "");
|
||||
INSERT(Settings, use_speed_limit, "", "");
|
||||
INSERT(Settings, speed_limit, "Limit Speed Percent", "");
|
||||
|
||||
// Cpu
|
||||
INSERT(Settings, cpu_accuracy, "Accuracy:", "");
|
||||
|
||||
// Cpu Debug
|
||||
|
||||
// Cpu Unsafe
|
||||
INSERT(Settings, cpuopt_unsafe_unfuse_fma,
|
||||
"Unfuse FMA (improve performance on CPUs without FMA)",
|
||||
"This option improves speed by reducing accuracy of fused-multiply-add instructions on "
|
||||
"CPUs without native FMA support.");
|
||||
INSERT(Settings, cpuopt_unsafe_reduce_fp_error, "Faster FRSQRTE and FRECPE",
|
||||
"This option improves the speed of some approximate floating-point functions by using "
|
||||
"less accurate native approximations.");
|
||||
INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, "Faster ASIMD instructions (32 bits only)",
|
||||
"This option improves the speed of 32 bits ASIMD floating-point functions by running "
|
||||
"with incorrect rounding modes.");
|
||||
INSERT(Settings, cpuopt_unsafe_inaccurate_nan, "Inaccurate NaN handling",
|
||||
"This option improves speed by removing NaN checking. Please note this also reduces "
|
||||
"accuracy of certain floating-point instructions.");
|
||||
INSERT(
|
||||
Settings, cpuopt_unsafe_fastmem_check, "Disable address space checks",
|
||||
"This option improves speed by eliminating a safety check before every memory read/write "
|
||||
"in guest. Disabling it may allow a game to read/write the emulator's memory.");
|
||||
INSERT(Settings, cpuopt_unsafe_ignore_global_monitor, "Ignore global monitor",
|
||||
"This option improves speed by relying only on the semantics of cmpxchg to ensure "
|
||||
"safety of exclusive access instructions. Please note this may result in deadlocks and "
|
||||
"other race conditions.");
|
||||
|
||||
// Renderer
|
||||
INSERT(Settings, renderer_backend, "API:", "");
|
||||
INSERT(Settings, vulkan_device, "Device:", "");
|
||||
INSERT(Settings, shader_backend, "Shader Backend:", "");
|
||||
INSERT(Settings, resolution_setup, "Resolution:", "");
|
||||
INSERT(Settings, scaling_filter, "Window Adapting Filter:", "");
|
||||
INSERT(Settings, fsr_sharpening_slider, "FSR Sharpness:", "");
|
||||
INSERT(Settings, anti_aliasing, "Anti-Aliasing Method:", "");
|
||||
INSERT(Settings, fullscreen_mode, "Fullscreen Mode:", "");
|
||||
INSERT(Settings, aspect_ratio, "Aspect Ratio:", "");
|
||||
INSERT(Settings, use_disk_shader_cache, "Use disk pipeline cache", "");
|
||||
INSERT(Settings, use_asynchronous_gpu_emulation, "Use asynchronous GPU emulation", "");
|
||||
INSERT(Settings, nvdec_emulation, "NVDEC emulation:", "");
|
||||
INSERT(Settings, accelerate_astc, "ASTC Decoding Method:", "");
|
||||
INSERT(Settings, astc_recompression, "ASTC Recompression Method:", "");
|
||||
INSERT(Settings, vsync_mode, "VSync Mode:",
|
||||
"FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
|
||||
"refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from "
|
||||
"a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop "
|
||||
"frames.\nImmediate (no synchronization) just presents whatever is available and can "
|
||||
"exhibit tearing.");
|
||||
INSERT(Settings, bg_red, "", "");
|
||||
INSERT(Settings, bg_green, "", "");
|
||||
INSERT(Settings, bg_blue, "", "");
|
||||
|
||||
// Renderer (Advanced Graphics)
|
||||
INSERT(Settings, async_presentation, "Enable asynchronous presentation (Vulkan only)", "");
|
||||
INSERT(Settings, renderer_force_max_clock, "Force maximum clocks (Vulkan only)",
|
||||
"Runs work in the background while waiting for graphics commands to keep the GPU from "
|
||||
"lowering its clock speed.");
|
||||
INSERT(Settings, max_anisotropy, "Anisotropic Filtering:", "");
|
||||
INSERT(Settings, gpu_accuracy, "Accuracy Level:", "");
|
||||
INSERT(Settings, use_asynchronous_shaders, "Use asynchronous shader building (Hack)",
|
||||
"Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
|
||||
"is experimental.");
|
||||
INSERT(Settings, use_fast_gpu_time, "Use Fast GPU Time (Hack)",
|
||||
"Enables Fast GPU Time. This option will force most games to run at their highest "
|
||||
"native resolution.");
|
||||
INSERT(Settings, use_vulkan_driver_pipeline_cache, "Use Vulkan pipeline cache",
|
||||
"Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
|
||||
"time significantly in cases where the Vulkan driver does not store pipeline cache "
|
||||
"files internally.");
|
||||
INSERT(Settings, enable_compute_pipelines, "Enable Compute Pipelines (Intel Vulkan Only)",
|
||||
"Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
|
||||
"proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
|
||||
"on all other drivers.");
|
||||
INSERT(Settings, use_reactive_flushing, "Enable Reactive Flushing",
|
||||
"Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
|
||||
"syncing.");
|
||||
INSERT(Settings, use_video_framerate, "Sync to framerate of video playback",
|
||||
"Run the game at normal speed during video playback, even when the framerate is "
|
||||
"unlocked.");
|
||||
INSERT(Settings, barrier_feedback_loops, "Barrier feedback loops",
|
||||
"Improves rendering of transparency effects in specific games.");
|
||||
|
||||
// Renderer (Debug)
|
||||
|
||||
// System
|
||||
INSERT(Settings, rng_seed, "RNG Seed", "");
|
||||
INSERT(Settings, rng_seed_enabled, "", "");
|
||||
INSERT(Settings, device_name, "Device Name", "");
|
||||
INSERT(Settings, custom_rtc, "Custom RTC", "");
|
||||
INSERT(Settings, custom_rtc_enabled, "", "");
|
||||
INSERT(Settings, language_index,
|
||||
"Language:", "Note: this can be overridden when region setting is auto-select");
|
||||
INSERT(Settings, region_index, "Region:", "");
|
||||
INSERT(Settings, time_zone_index, "Time Zone:", "");
|
||||
INSERT(Settings, sound_index, "Sound Output Mode:", "");
|
||||
INSERT(Settings, use_docked_mode, "", "");
|
||||
INSERT(Settings, current_user, "", "");
|
||||
|
||||
// Controls
|
||||
|
||||
// Data Storage
|
||||
|
||||
// Debugging
|
||||
|
||||
// Debugging Graphics
|
||||
|
||||
// Network
|
||||
|
||||
// Web Service
|
||||
|
||||
// Ui
|
||||
|
||||
// Ui General
|
||||
INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", "");
|
||||
INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", "");
|
||||
INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", "");
|
||||
INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", "");
|
||||
INSERT(UISettings, controller_applet_disabled, "Disable controller applet", "");
|
||||
|
||||
// Ui Debugging
|
||||
|
||||
// Ui Multiplayer
|
||||
|
||||
// Ui Games list
|
||||
|
||||
#undef INSERT
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
|
||||
std::unique_ptr<ComboboxTranslationMap> translations =
|
||||
std::make_unique<ComboboxTranslationMap>();
|
||||
const auto& tr = [&](const char* text, const char* context = "") {
|
||||
return parent->tr(text, context);
|
||||
};
|
||||
|
||||
#define PAIR(ENUM, VALUE, TRANSLATION) \
|
||||
{ static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION) }
|
||||
#define CTX_PAIR(ENUM, VALUE, TRANSLATION, CONTEXT) \
|
||||
{ static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION, CONTEXT) }
|
||||
|
||||
// Intentionally skipping VSyncMode to let the UI fill that one out
|
||||
|
||||
translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(),
|
||||
{
|
||||
PAIR(AstcDecodeMode, Cpu, "CPU"),
|
||||
PAIR(AstcDecodeMode, Gpu, "GPU"),
|
||||
PAIR(AstcDecodeMode, CpuAsynchronous, "CPU Asynchronous"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
|
||||
{
|
||||
PAIR(AstcRecompression, Uncompressed, "Uncompressed (Best quality)"),
|
||||
PAIR(AstcRecompression, Bc1, "BC1 (Low quality)"),
|
||||
PAIR(AstcRecompression, Bc3, "BC3 (Medium quality)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
|
||||
{
|
||||
#ifdef HAS_OPENGL
|
||||
PAIR(RendererBackend, OpenGL, "OpenGL"),
|
||||
#endif
|
||||
PAIR(RendererBackend, Vulkan, "Vulkan"),
|
||||
PAIR(RendererBackend, Null, "Null"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
|
||||
{
|
||||
PAIR(ShaderBackend, Glsl, "GLSL"),
|
||||
PAIR(ShaderBackend, Glasm, "GLASM (Assembly Shaders, NVIDIA Only)"),
|
||||
PAIR(ShaderBackend, SpirV, "SPIR-V (Experimental, Mesa Only)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(),
|
||||
{
|
||||
PAIR(GpuAccuracy, Normal, "Normal"),
|
||||
PAIR(GpuAccuracy, High, "High"),
|
||||
PAIR(GpuAccuracy, Extreme, "Extreme"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
|
||||
{
|
||||
PAIR(CpuAccuracy, Auto, "Auto"),
|
||||
PAIR(CpuAccuracy, Accurate, "Accurate"),
|
||||
PAIR(CpuAccuracy, Unsafe, "Unsafe"),
|
||||
PAIR(CpuAccuracy, Paranoid, "Paranoid (disables most optimizations)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(),
|
||||
{
|
||||
PAIR(FullscreenMode, Borderless, "Borderless Windowed"),
|
||||
PAIR(FullscreenMode, Exclusive, "Exclusive Fullscreen"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(),
|
||||
{
|
||||
PAIR(NvdecEmulation, Off, "No Video Output"),
|
||||
PAIR(NvdecEmulation, Cpu, "CPU Video Decoding"),
|
||||
PAIR(NvdecEmulation, Gpu, "GPU Video Decoding (Default)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
|
||||
{
|
||||
PAIR(ResolutionSetup, Res1_2X, "0.5X (360p/540p) [EXPERIMENTAL]"),
|
||||
PAIR(ResolutionSetup, Res3_4X, "0.75X (540p/810p) [EXPERIMENTAL]"),
|
||||
PAIR(ResolutionSetup, Res1X, "1X (720p/1080p)"),
|
||||
PAIR(ResolutionSetup, Res3_2X, "1.5X (1080p/1620p) [EXPERIMENTAL]"),
|
||||
PAIR(ResolutionSetup, Res2X, "2X (1440p/2160p)"),
|
||||
PAIR(ResolutionSetup, Res3X, "3X (2160p/3240p)"),
|
||||
PAIR(ResolutionSetup, Res4X, "4X (2880p/4320p)"),
|
||||
PAIR(ResolutionSetup, Res5X, "5X (3600p/5400p)"),
|
||||
PAIR(ResolutionSetup, Res6X, "6X (4320p/6480p)"),
|
||||
PAIR(ResolutionSetup, Res7X, "7X (5040p/7560p)"),
|
||||
PAIR(ResolutionSetup, Res8X, "8X (5760p/8640p)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(),
|
||||
{
|
||||
PAIR(ScalingFilter, NearestNeighbor, "Nearest Neighbor"),
|
||||
PAIR(ScalingFilter, Bilinear, "Bilinear"),
|
||||
PAIR(ScalingFilter, Bicubic, "Bicubic"),
|
||||
PAIR(ScalingFilter, Gaussian, "Gaussian"),
|
||||
PAIR(ScalingFilter, ScaleForce, "ScaleForce"),
|
||||
PAIR(ScalingFilter, Fsr, "AMD FidelityFX™️ Super Resolution"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
||||
{
|
||||
PAIR(AntiAliasing, None, "None"),
|
||||
PAIR(AntiAliasing, Fxaa, "FXAA"),
|
||||
PAIR(AntiAliasing, Smaa, "SMAA"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
|
||||
{
|
||||
PAIR(AspectRatio, R16_9, "Default (16:9)"),
|
||||
PAIR(AspectRatio, R4_3, "Force 4:3"),
|
||||
PAIR(AspectRatio, R21_9, "Force 21:9"),
|
||||
PAIR(AspectRatio, R16_10, "Force 16:10"),
|
||||
PAIR(AspectRatio, Stretch, "Stretch to Window"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(),
|
||||
{
|
||||
PAIR(AnisotropyMode, Automatic, "Automatic"),
|
||||
PAIR(AnisotropyMode, Default, "Default"),
|
||||
PAIR(AnisotropyMode, X2, "2x"),
|
||||
PAIR(AnisotropyMode, X4, "4x"),
|
||||
PAIR(AnisotropyMode, X8, "8x"),
|
||||
PAIR(AnisotropyMode, X16, "16x"),
|
||||
}});
|
||||
translations->insert(
|
||||
{Settings::EnumMetadata<Settings::Language>::Index(),
|
||||
{
|
||||
PAIR(Language, Japanese, "Japanese (日本語)"),
|
||||
PAIR(Language, EnglishAmerican, "American English"),
|
||||
PAIR(Language, French, "French (français)"),
|
||||
PAIR(Language, German, "German (Deutsch)"),
|
||||
PAIR(Language, Italian, "Italian (italiano)"),
|
||||
PAIR(Language, Spanish, "Spanish (español)"),
|
||||
PAIR(Language, Chinese, "Chinese"),
|
||||
PAIR(Language, Korean, "Korean (한국어)"),
|
||||
PAIR(Language, Dutch, "Dutch (Nederlands)"),
|
||||
PAIR(Language, Portuguese, "Portuguese (português)"),
|
||||
PAIR(Language, Russian, "Russian (Русский)"),
|
||||
PAIR(Language, Taiwanese, "Taiwanese"),
|
||||
PAIR(Language, EnglishBritish, "British English"),
|
||||
PAIR(Language, FrenchCanadian, "Canadian French"),
|
||||
PAIR(Language, SpanishLatin, "Latin American Spanish"),
|
||||
PAIR(Language, ChineseSimplified, "Simplified Chinese"),
|
||||
PAIR(Language, ChineseTraditional, "Traditional Chinese (正體中文)"),
|
||||
PAIR(Language, PortugueseBrazilian, "Brazilian Portuguese (português do Brasil)"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
|
||||
{
|
||||
PAIR(Region, Japan, "Japan"),
|
||||
PAIR(Region, Usa, "USA"),
|
||||
PAIR(Region, Europe, "Europe"),
|
||||
PAIR(Region, Australia, "Australia"),
|
||||
PAIR(Region, China, "China"),
|
||||
PAIR(Region, Korea, "Korea"),
|
||||
PAIR(Region, Taiwan, "Taiwan"),
|
||||
}});
|
||||
translations->insert(
|
||||
{Settings::EnumMetadata<Settings::TimeZone>::Index(),
|
||||
{
|
||||
{static_cast<u32>(Settings::TimeZone::Auto),
|
||||
tr("Auto (%1)", "Auto select time zone")
|
||||
.arg(QString::fromStdString(
|
||||
Settings::GetTimeZoneString(Settings::TimeZone::Auto)))},
|
||||
{static_cast<u32>(Settings::TimeZone::Default),
|
||||
tr("Default (%1)", "Default time zone")
|
||||
.arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))},
|
||||
PAIR(TimeZone, Cet, "CET"),
|
||||
PAIR(TimeZone, Cst6Cdt, "CST6CDT"),
|
||||
PAIR(TimeZone, Cuba, "Cuba"),
|
||||
PAIR(TimeZone, Eet, "EET"),
|
||||
PAIR(TimeZone, Egypt, "Egypt"),
|
||||
PAIR(TimeZone, Eire, "Eire"),
|
||||
PAIR(TimeZone, Est, "EST"),
|
||||
PAIR(TimeZone, Est5Edt, "EST5EDT"),
|
||||
PAIR(TimeZone, Gb, "GB"),
|
||||
PAIR(TimeZone, GbEire, "GB-Eire"),
|
||||
PAIR(TimeZone, Gmt, "GMT"),
|
||||
PAIR(TimeZone, GmtPlusZero, "GMT+0"),
|
||||
PAIR(TimeZone, GmtMinusZero, "GMT-0"),
|
||||
PAIR(TimeZone, GmtZero, "GMT0"),
|
||||
PAIR(TimeZone, Greenwich, "Greenwich"),
|
||||
PAIR(TimeZone, Hongkong, "Hongkong"),
|
||||
PAIR(TimeZone, Hst, "HST"),
|
||||
PAIR(TimeZone, Iceland, "Iceland"),
|
||||
PAIR(TimeZone, Iran, "Iran"),
|
||||
PAIR(TimeZone, Israel, "Israel"),
|
||||
PAIR(TimeZone, Jamaica, "Jamaica"),
|
||||
PAIR(TimeZone, Japan, "Japan"),
|
||||
PAIR(TimeZone, Kwajalein, "Kwajalein"),
|
||||
PAIR(TimeZone, Libya, "Libya"),
|
||||
PAIR(TimeZone, Met, "MET"),
|
||||
PAIR(TimeZone, Mst, "MST"),
|
||||
PAIR(TimeZone, Mst7Mdt, "MST7MDT"),
|
||||
PAIR(TimeZone, Navajo, "Navajo"),
|
||||
PAIR(TimeZone, Nz, "NZ"),
|
||||
PAIR(TimeZone, NzChat, "NZ-CHAT"),
|
||||
PAIR(TimeZone, Poland, "Poland"),
|
||||
PAIR(TimeZone, Portugal, "Portugal"),
|
||||
PAIR(TimeZone, Prc, "PRC"),
|
||||
PAIR(TimeZone, Pst8Pdt, "PST8PDT"),
|
||||
PAIR(TimeZone, Roc, "ROC"),
|
||||
PAIR(TimeZone, Rok, "ROK"),
|
||||
PAIR(TimeZone, Singapore, "Singapore"),
|
||||
PAIR(TimeZone, Turkey, "Turkey"),
|
||||
PAIR(TimeZone, Uct, "UCT"),
|
||||
PAIR(TimeZone, Universal, "Universal"),
|
||||
PAIR(TimeZone, Utc, "UTC"),
|
||||
PAIR(TimeZone, WSu, "W-SU"),
|
||||
PAIR(TimeZone, Wet, "WET"),
|
||||
PAIR(TimeZone, Zulu, "Zulu"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(),
|
||||
{
|
||||
PAIR(AudioMode, Mono, "Mono"),
|
||||
PAIR(AudioMode, Stereo, "Stereo"),
|
||||
PAIR(AudioMode, Surround, "Surround"),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(),
|
||||
{
|
||||
PAIR(MemoryLayout, Memory_4Gb, "4GB DRAM (Default)"),
|
||||
PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"),
|
||||
PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"),
|
||||
}});
|
||||
|
||||
#undef PAIR
|
||||
#undef CTX_PAIR
|
||||
|
||||
return translations;
|
||||
}
|
||||
} // namespace ConfigurationShared
|
25
src/yuzu/configuration/shared_translation.h
Normal file
25
src/yuzu/configuration/shared_translation.h
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include "common/common_types.h"
|
||||
|
||||
class QWidget;
|
||||
|
||||
namespace ConfigurationShared {
|
||||
using TranslationMap = std::map<u32, std::pair<QString, QString>>;
|
||||
using ComboboxTranslations = std::vector<std::pair<u32, QString>>;
|
||||
using ComboboxTranslationMap = std::map<u32, ComboboxTranslations>;
|
||||
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
|
||||
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent);
|
||||
|
||||
} // namespace ConfigurationShared
|
642
src/yuzu/configuration/shared_widget.cpp
Normal file
642
src/yuzu/configuration/shared_widget.cpp
Normal file
@ -0,0 +1,642 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QAbstractSlider>
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTime>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QSizePolicy>
|
||||
#include <QSlider>
|
||||
#include <QSpinBox>
|
||||
#include <QStyle>
|
||||
#include <QValidator>
|
||||
#include <QVariant>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#include <fmt/core.h>
|
||||
#include <qglobal.h>
|
||||
#include <qnamespace.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_common.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
static int restore_button_count = 0;
|
||||
|
||||
static std::string RelevantDefault(const Settings::BasicSetting& setting) {
|
||||
return Settings::IsConfiguringGlobal() ? setting.DefaultToString() : setting.ToStringGlobal();
|
||||
}
|
||||
|
||||
static QString DefaultSuffix(QWidget* parent, Settings::BasicSetting& setting) {
|
||||
const auto tr = [parent](const char* text, const char* context) {
|
||||
return parent->tr(text, context);
|
||||
};
|
||||
|
||||
if ((setting.Specialization() & Settings::SpecializationAttributeMask) ==
|
||||
Settings::Specialization::Percentage) {
|
||||
std::string context{fmt::format("{} percentage (e.g. 50%)", setting.GetLabel())};
|
||||
return tr("%", context.c_str());
|
||||
}
|
||||
|
||||
return QStringLiteral("");
|
||||
}
|
||||
|
||||
QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) {
|
||||
restore_button_count++;
|
||||
|
||||
QStyle* style = parent->style();
|
||||
QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton));
|
||||
QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent);
|
||||
restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count));
|
||||
restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
|
||||
// Workaround for dark theme causing min-width to be much larger than 0
|
||||
restore_button->setStyleSheet(
|
||||
QStringLiteral("QAbstractButton#%1 { min-width: 0px }").arg(restore_button->objectName()));
|
||||
|
||||
QSizePolicy sp_retain = restore_button->sizePolicy();
|
||||
sp_retain.setRetainSizeWhenHidden(true);
|
||||
restore_button->setSizePolicy(sp_retain);
|
||||
|
||||
restore_button->setEnabled(!using_global);
|
||||
restore_button->setVisible(!using_global);
|
||||
|
||||
return restore_button;
|
||||
}
|
||||
|
||||
QLabel* Widget::CreateLabel(const QString& text) {
|
||||
QLabel* qt_label = new QLabel(text, this->parent);
|
||||
qt_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
return qt_label;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
checkbox = new QCheckBox(label, this);
|
||||
checkbox->setCheckState(bool_setting->ToString() == "true" ? Qt::CheckState::Checked
|
||||
: Qt::CheckState::Unchecked);
|
||||
checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
if (!bool_setting->Save() && !Settings::IsConfiguringGlobal() && runtime_lock) {
|
||||
checkbox->setEnabled(false);
|
||||
}
|
||||
|
||||
serializer = [this]() {
|
||||
return checkbox->checkState() == Qt::CheckState::Checked ? "true" : "false";
|
||||
};
|
||||
|
||||
restore_func = [this, bool_setting]() {
|
||||
checkbox->setCheckState(RelevantDefault(*bool_setting) == "true" ? Qt::Checked
|
||||
: Qt::Unchecked);
|
||||
};
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(checkbox, &QCheckBox::clicked, [touch]() { touch(); });
|
||||
}
|
||||
|
||||
return checkbox;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
const auto type = setting.EnumIndex();
|
||||
|
||||
combobox = new QComboBox(this);
|
||||
combobox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
const ComboboxTranslations* enumeration{nullptr};
|
||||
if (combobox_enumerations.contains(type)) {
|
||||
enumeration = &combobox_enumerations.at(type);
|
||||
for (const auto& [id, name] : *enumeration) {
|
||||
combobox->addItem(name);
|
||||
}
|
||||
} else {
|
||||
return combobox;
|
||||
}
|
||||
|
||||
const auto find_index = [=](u32 value) -> int {
|
||||
for (u32 i = 0; i < enumeration->size(); i++) {
|
||||
if (enumeration->at(i).first == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
const u32 setting_value = std::stoi(setting.ToString());
|
||||
combobox->setCurrentIndex(find_index(setting_value));
|
||||
|
||||
serializer = [this, enumeration]() {
|
||||
int current = combobox->currentIndex();
|
||||
return std::to_string(enumeration->at(current).first);
|
||||
};
|
||||
|
||||
restore_func = [this, find_index]() {
|
||||
const u32 global_value = std::stoi(RelevantDefault(setting));
|
||||
combobox->setCurrentIndex(find_index(global_value));
|
||||
};
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated),
|
||||
[touch]() { touch(); });
|
||||
}
|
||||
|
||||
return combobox;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch, bool managed) {
|
||||
const QString text = QString::fromStdString(setting.ToString());
|
||||
line_edit = new QLineEdit(this);
|
||||
line_edit->setText(text);
|
||||
|
||||
serializer = [this]() { return line_edit->text().toStdString(); };
|
||||
|
||||
if (!managed) {
|
||||
return line_edit;
|
||||
}
|
||||
|
||||
restore_func = [this]() {
|
||||
line_edit->setText(QString::fromStdString(RelevantDefault(setting)));
|
||||
};
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(line_edit, &QLineEdit::textChanged, [touch]() { touch(); });
|
||||
}
|
||||
|
||||
return line_edit;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
if (!setting.Ranged()) {
|
||||
LOG_ERROR(Frontend, "\"{}\" is not a ranged setting, but a slider was requested.",
|
||||
setting.GetLabel());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget* container = new QWidget(this);
|
||||
QHBoxLayout* layout = new QHBoxLayout(container);
|
||||
|
||||
slider = new QSlider(Qt::Horizontal, this);
|
||||
QLabel* feedback = new QLabel(this);
|
||||
|
||||
layout->addWidget(slider);
|
||||
layout->addWidget(feedback);
|
||||
|
||||
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int max_val = std::stoi(setting.MaxVal());
|
||||
|
||||
QString suffix =
|
||||
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
|
||||
|
||||
const QString use_format = QStringLiteral("%1").append(suffix);
|
||||
|
||||
QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) {
|
||||
int present = (reversed ? max_val - value : value) * multiplier + 0.5f;
|
||||
feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>()));
|
||||
});
|
||||
|
||||
slider->setMinimum(std::stoi(setting.MinVal()));
|
||||
slider->setMaximum(max_val);
|
||||
slider->setValue(std::stoi(setting.ToString()));
|
||||
|
||||
slider->setInvertedAppearance(reversed);
|
||||
|
||||
serializer = [this]() { return std::to_string(slider->value()); };
|
||||
restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); };
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); });
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateSpinBox(const QString& given_suffix,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
const int min_val =
|
||||
setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min();
|
||||
const int max_val =
|
||||
setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max();
|
||||
const int default_val = std::stoi(setting.ToString());
|
||||
|
||||
QString suffix =
|
||||
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
|
||||
|
||||
spinbox = new QSpinBox(this);
|
||||
spinbox->setRange(min_val, max_val);
|
||||
spinbox->setValue(default_val);
|
||||
spinbox->setSuffix(suffix);
|
||||
spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
|
||||
serializer = [this]() { return std::to_string(spinbox->value()); };
|
||||
|
||||
restore_func = [this]() {
|
||||
auto value{std::stol(RelevantDefault(setting))};
|
||||
spinbox->setValue(value);
|
||||
};
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() {
|
||||
if (spinbox->value() != std::stoi(setting.ToStringGlobal())) {
|
||||
touch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return spinbox;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
auto* data_component = CreateLineEdit(serializer, restore_func, touch, false);
|
||||
if (data_component == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto to_hex = [=](const std::string& input) {
|
||||
return QString::fromStdString(fmt::format("{:08x}", std::stoul(input)));
|
||||
};
|
||||
|
||||
QRegularExpressionValidator* regex = new QRegularExpressionValidator(
|
||||
QRegularExpression{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit);
|
||||
|
||||
const QString default_val = to_hex(setting.ToString());
|
||||
|
||||
line_edit->setText(default_val);
|
||||
line_edit->setMaxLength(8);
|
||||
line_edit->setValidator(regex);
|
||||
|
||||
auto hex_to_dec = [this]() -> std::string {
|
||||
return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
|
||||
};
|
||||
|
||||
serializer = [hex_to_dec]() { return hex_to_dec(); };
|
||||
|
||||
restore_func = [this, to_hex]() { line_edit->setText(to_hex(RelevantDefault(setting))); };
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
|
||||
QObject::connect(line_edit, &QLineEdit::textChanged, [touch]() { touch(); });
|
||||
}
|
||||
|
||||
return line_edit;
|
||||
}
|
||||
|
||||
QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch) {
|
||||
const long long current_time = QDateTime::currentSecsSinceEpoch();
|
||||
const s64 the_time = disabled ? current_time : std::stoll(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);
|
||||
|
||||
serializer = [this]() { return std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()); };
|
||||
|
||||
auto get_clear_val = [this, restrict, current_time]() {
|
||||
return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() {
|
||||
if (restrict && checkbox->checkState() == Qt::Checked) {
|
||||
return std::stoll(RelevantDefault(setting));
|
||||
}
|
||||
return current_time;
|
||||
}());
|
||||
};
|
||||
|
||||
restore_func = [this, get_clear_val]() { date_time_edit->setDateTime(get_clear_val()); };
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
QObject::connect(date_time_edit, &QDateTimeEdit::editingFinished,
|
||||
[this, get_clear_val, touch]() {
|
||||
if (date_time_edit->dateTime() != get_clear_val()) {
|
||||
touch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return date_time_edit;
|
||||
}
|
||||
|
||||
void Widget::SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
|
||||
RequestType request, float multiplier,
|
||||
Settings::BasicSetting* other_setting, const QString& suffix) {
|
||||
created = true;
|
||||
const auto type = setting.TypeId();
|
||||
|
||||
QLayout* layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
if (other_setting == nullptr) {
|
||||
other_setting = setting.PairedSetting();
|
||||
}
|
||||
|
||||
const bool require_checkbox =
|
||||
other_setting != nullptr && other_setting->TypeId() == typeid(bool);
|
||||
|
||||
if (other_setting != nullptr && other_setting->TypeId() != typeid(bool)) {
|
||||
LOG_WARNING(
|
||||
Frontend,
|
||||
"Extra setting \"{}\" specified but is not bool, refusing to create checkbox for it.",
|
||||
other_setting->GetLabel());
|
||||
}
|
||||
|
||||
std::function<std::string()> checkbox_serializer = []() -> std::string { return {}; };
|
||||
std::function<void()> checkbox_restore_func = []() {};
|
||||
|
||||
std::function<void()> touch = []() {};
|
||||
std::function<std::string()> serializer = []() -> std::string { return {}; };
|
||||
std::function<void()> restore_func = []() {};
|
||||
|
||||
QWidget* data_component{nullptr};
|
||||
|
||||
request = [&]() {
|
||||
if (request != RequestType::Default) {
|
||||
return request;
|
||||
}
|
||||
switch (setting.Specialization() & Settings::SpecializationTypeMask) {
|
||||
case Settings::Specialization::Default:
|
||||
return RequestType::Default;
|
||||
case Settings::Specialization::Time:
|
||||
return RequestType::DateTimeEdit;
|
||||
case Settings::Specialization::Hex:
|
||||
return RequestType::HexEdit;
|
||||
case Settings::Specialization::RuntimeList:
|
||||
managed = false;
|
||||
[[fallthrough]];
|
||||
case Settings::Specialization::List:
|
||||
return RequestType::ComboBox;
|
||||
case Settings::Specialization::Scalar:
|
||||
return RequestType::Slider;
|
||||
case Settings::Specialization::Countable:
|
||||
return RequestType::SpinBox;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return request;
|
||||
}();
|
||||
|
||||
if (!Settings::IsConfiguringGlobal() && managed) {
|
||||
restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this);
|
||||
|
||||
touch = [this]() {
|
||||
LOG_DEBUG(Frontend, "Enabling custom setting for \"{}\"", setting.GetLabel());
|
||||
restore_button->setEnabled(true);
|
||||
restore_button->setVisible(true);
|
||||
};
|
||||
}
|
||||
|
||||
if (require_checkbox) {
|
||||
QWidget* lhs =
|
||||
CreateCheckBox(other_setting, label, checkbox_serializer, checkbox_restore_func, touch);
|
||||
layout->addWidget(lhs);
|
||||
} else if (setting.TypeId() != typeid(bool)) {
|
||||
QLabel* qt_label = CreateLabel(label);
|
||||
layout->addWidget(qt_label);
|
||||
}
|
||||
|
||||
if (setting.TypeId() == typeid(bool)) {
|
||||
data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch);
|
||||
} else if (setting.IsEnum()) {
|
||||
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||
} else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) ||
|
||||
type == typeid(s64) || type == typeid(u8)) {
|
||||
switch (request) {
|
||||
case RequestType::Slider:
|
||||
case RequestType::ReverseSlider:
|
||||
data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix,
|
||||
serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::Default:
|
||||
case RequestType::LineEdit:
|
||||
data_component = CreateLineEdit(serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::DateTimeEdit:
|
||||
data_component = CreateDateTimeEdit(other_setting->ToString() != "true", true,
|
||||
serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::SpinBox:
|
||||
data_component = CreateSpinBox(suffix, serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::HexEdit:
|
||||
data_component = CreateHexEdit(serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::ComboBox:
|
||||
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
} else if (type == typeid(std::string)) {
|
||||
switch (request) {
|
||||
case RequestType::Default:
|
||||
case RequestType::LineEdit:
|
||||
data_component = CreateLineEdit(serializer, restore_func, touch);
|
||||
break;
|
||||
case RequestType::ComboBox:
|
||||
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
if (data_component == nullptr) {
|
||||
LOG_ERROR(Frontend, "Failed to create widget for \"{}\"", setting.GetLabel());
|
||||
created = false;
|
||||
return;
|
||||
}
|
||||
|
||||
layout->addWidget(data_component);
|
||||
|
||||
if (!managed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
load_func = [this, serializer, checkbox_serializer, require_checkbox, other_setting]() {
|
||||
if (require_checkbox && other_setting->UsingGlobal()) {
|
||||
other_setting->LoadString(checkbox_serializer());
|
||||
}
|
||||
if (setting.UsingGlobal()) {
|
||||
setting.LoadString(serializer());
|
||||
}
|
||||
};
|
||||
} else {
|
||||
layout->addWidget(restore_button);
|
||||
|
||||
QObject::connect(restore_button, &QAbstractButton::clicked,
|
||||
[this, restore_func, checkbox_restore_func](bool) {
|
||||
LOG_DEBUG(Frontend, "Restore global state for \"{}\"",
|
||||
setting.GetLabel());
|
||||
|
||||
restore_button->setEnabled(false);
|
||||
restore_button->setVisible(false);
|
||||
|
||||
checkbox_restore_func();
|
||||
restore_func();
|
||||
});
|
||||
|
||||
load_func = [this, serializer, require_checkbox, checkbox_serializer, other_setting]() {
|
||||
bool using_global = !restore_button->isEnabled();
|
||||
setting.SetGlobal(using_global);
|
||||
if (!using_global) {
|
||||
setting.LoadString(serializer());
|
||||
}
|
||||
if (require_checkbox) {
|
||||
other_setting->SetGlobal(using_global);
|
||||
if (!using_global) {
|
||||
other_setting->LoadString(checkbox_serializer());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (other_setting != nullptr) {
|
||||
const auto reset = [restore_func, data_component](int state) {
|
||||
data_component->setEnabled(state == Qt::Checked);
|
||||
if (state != Qt::Checked) {
|
||||
restore_func();
|
||||
}
|
||||
};
|
||||
connect(checkbox, &QCheckBox::stateChanged, reset);
|
||||
reset(checkbox->checkState());
|
||||
}
|
||||
}
|
||||
|
||||
bool Widget::Valid() const {
|
||||
return created;
|
||||
}
|
||||
|
||||
Widget::~Widget() = default;
|
||||
|
||||
Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_,
|
||||
const ComboboxTranslationMap& combobox_translations_, QWidget* parent_,
|
||||
bool runtime_lock_, std::vector<std::function<void(bool)>>& apply_funcs_,
|
||||
RequestType request, bool managed, float multiplier,
|
||||
Settings::BasicSetting* other_setting, const QString& suffix)
|
||||
: QWidget(parent_), parent{parent_}, translations{translations_},
|
||||
combobox_enumerations{combobox_translations_}, setting{*setting_}, apply_funcs{apply_funcs_},
|
||||
runtime_lock{runtime_lock_} {
|
||||
if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
|
||||
LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
const int id = setting.Id();
|
||||
|
||||
const auto [label, tooltip] = [&]() {
|
||||
const auto& setting_label = setting.GetLabel();
|
||||
if (translations.contains(id)) {
|
||||
return std::pair{translations.at(id).first, translations.at(id).second};
|
||||
}
|
||||
LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label);
|
||||
return std::pair{QString::fromStdString(setting_label), QStringLiteral("")};
|
||||
}();
|
||||
|
||||
if (label == QStringLiteral("")) {
|
||||
LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...",
|
||||
setting.GetLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
std::function<void()> load_func = []() {};
|
||||
|
||||
SetupComponent(label, load_func, managed, request, multiplier, other_setting, suffix);
|
||||
|
||||
if (!created) {
|
||||
LOG_WARNING(Frontend, "No widget was created for \"{}\"", setting.GetLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
apply_funcs.push_back([load_func, setting_](bool powered_on) {
|
||||
if (setting_->RuntimeModfiable() || !powered_on) {
|
||||
load_func();
|
||||
}
|
||||
});
|
||||
|
||||
bool enable = runtime_lock || setting.RuntimeModfiable();
|
||||
if (setting.Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) {
|
||||
enable &= setting.UsingGlobal();
|
||||
}
|
||||
this->setEnabled(enable);
|
||||
|
||||
this->setToolTip(tooltip);
|
||||
}
|
||||
|
||||
Builder::Builder(QWidget* parent_, bool runtime_lock_)
|
||||
: translations{InitializeTranslations(parent_)},
|
||||
combobox_translations{ComboboxEnumeration(parent_)}, parent{parent_}, runtime_lock{
|
||||
runtime_lock_} {}
|
||||
|
||||
Builder::~Builder() = default;
|
||||
|
||||
Widget* Builder::BuildWidget(Settings::BasicSetting* setting,
|
||||
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||
RequestType request, bool managed, float multiplier,
|
||||
Settings::BasicSetting* other_setting, const QString& suffix) const {
|
||||
if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (setting->Specialization() == Settings::Specialization::Paired) {
|
||||
LOG_DEBUG(Frontend, "\"{}\" has specialization Paired: ignoring", setting->GetLabel());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new Widget(setting, *translations, *combobox_translations, parent, runtime_lock,
|
||||
apply_funcs, request, managed, multiplier, other_setting, suffix);
|
||||
}
|
||||
|
||||
Widget* Builder::BuildWidget(Settings::BasicSetting* setting,
|
||||
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||
Settings::BasicSetting* other_setting, RequestType request,
|
||||
const QString& suffix) const {
|
||||
return BuildWidget(setting, apply_funcs, request, true, 1.0f, other_setting, suffix);
|
||||
}
|
||||
|
||||
const ComboboxTranslationMap& Builder::ComboboxTranslations() const {
|
||||
return *combobox_translations;
|
||||
}
|
||||
|
||||
} // namespace ConfigurationShared
|
161
src/yuzu/configuration/shared_widget.h
Normal file
161
src/yuzu/configuration/shared_widget.h
Normal file
@ -0,0 +1,161 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QStringLiteral>
|
||||
#include <QWidget>
|
||||
#include <qobjectdefs.h>
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QDateTimeEdit;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QObject;
|
||||
class QPushButton;
|
||||
class QSlider;
|
||||
class QSpinBox;
|
||||
|
||||
namespace Settings {
|
||||
class BasicSetting;
|
||||
} // namespace Settings
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
enum class RequestType {
|
||||
Default,
|
||||
ComboBox,
|
||||
SpinBox,
|
||||
Slider,
|
||||
ReverseSlider,
|
||||
LineEdit,
|
||||
HexEdit,
|
||||
DateTimeEdit,
|
||||
MaxEnum,
|
||||
};
|
||||
|
||||
class Widget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param setting The primary Setting to create the Widget for
|
||||
* @param translations Map of translations to display on the left side label/checkbox
|
||||
* @param combobox_translations Map of translations for enumerating combo boxes
|
||||
* @param parent Qt parent
|
||||
* @param runtime_lock Emulated guest powered on state, for use on settings that should be
|
||||
* configured during guest execution
|
||||
* @param apply_funcs_ List to append, functions to run to apply the widget state to the setting
|
||||
* @param request What type of data representation component to create -- not always respected
|
||||
* for the Setting data type
|
||||
* @param managed Set true if the caller will set up component data and handling
|
||||
* @param multiplier Value to multiply the slider feedback label
|
||||
* @param other_setting Second setting to modify, to replace the label with a checkbox
|
||||
* @param suffix Set to specify formats for Slider feedback labels or SpinBox
|
||||
*/
|
||||
explicit Widget(Settings::BasicSetting* setting, const TranslationMap& translations,
|
||||
const ComboboxTranslationMap& combobox_translations, QWidget* parent,
|
||||
bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_,
|
||||
RequestType request = RequestType::Default, bool managed = true,
|
||||
float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr,
|
||||
const QString& suffix = QStringLiteral(""));
|
||||
virtual ~Widget();
|
||||
|
||||
/**
|
||||
* @returns True if the Widget successfully created the components for the setting
|
||||
*/
|
||||
bool Valid() const;
|
||||
|
||||
/**
|
||||
* Creates a button to appear when a setting has been modified. This exists for custom
|
||||
* configurations and wasn't designed to work for the global configuration. It has public access
|
||||
* for settings that need to be unmanaged but can be custom.
|
||||
*
|
||||
* @param using_global The global state of the setting this button is for
|
||||
* @param parent QWidget parent
|
||||
*/
|
||||
[[nodiscard]] static QPushButton* CreateRestoreGlobalButton(bool using_global, QWidget* parent);
|
||||
|
||||
// Direct handles to sub components created
|
||||
QPushButton* restore_button{}; ///< Restore button for custom configurations
|
||||
QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit
|
||||
QSpinBox* spinbox{};
|
||||
QCheckBox* checkbox{};
|
||||
QSlider* slider{};
|
||||
QComboBox* combobox{};
|
||||
QDateTimeEdit* date_time_edit{};
|
||||
|
||||
private:
|
||||
void SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
|
||||
RequestType request, float multiplier,
|
||||
Settings::BasicSetting* other_setting, const QString& suffix);
|
||||
|
||||
QLabel* CreateLabel(const QString& text);
|
||||
QWidget* CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch);
|
||||
|
||||
QWidget* CreateCombobox(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch);
|
||||
QWidget* CreateLineEdit(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func, const std::function<void()>& touch,
|
||||
bool managed = true);
|
||||
QWidget* CreateHexEdit(std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||
QWidget* CreateSlider(bool reversed, float multiplier, const QString& suffix,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||
QWidget* CreateDateTimeEdit(bool disabled, bool restrict,
|
||||
std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func,
|
||||
const std::function<void()>& touch);
|
||||
QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer,
|
||||
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||
|
||||
QWidget* parent;
|
||||
const TranslationMap& translations;
|
||||
const ComboboxTranslationMap& combobox_enumerations;
|
||||
Settings::BasicSetting& setting;
|
||||
std::vector<std::function<void(bool)>>& apply_funcs;
|
||||
|
||||
bool created{false};
|
||||
bool runtime_lock{false};
|
||||
};
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
explicit Builder(QWidget* parent, bool runtime_lock);
|
||||
~Builder();
|
||||
|
||||
Widget* BuildWidget(Settings::BasicSetting* setting,
|
||||
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||
RequestType request = RequestType::Default, bool managed = true,
|
||||
float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr,
|
||||
const QString& suffix = QStringLiteral("")) const;
|
||||
|
||||
Widget* BuildWidget(Settings::BasicSetting* setting,
|
||||
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||
Settings::BasicSetting* other_setting,
|
||||
RequestType request = RequestType::Default,
|
||||
const QString& suffix = QStringLiteral("")) const;
|
||||
|
||||
const ComboboxTranslationMap& ComboboxTranslations() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<TranslationMap> translations;
|
||||
std::unique_ptr<ComboboxTranslationMap> combobox_translations;
|
||||
|
||||
QWidget* parent;
|
||||
const bool runtime_lock;
|
||||
};
|
||||
|
||||
} // namespace ConfigurationShared
|
@ -24,6 +24,7 @@
|
||||
#include "applets/qt_software_keyboard.h"
|
||||
#include "applets/qt_web_browser.h"
|
||||
#include "common/nvidia_flags.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "configuration/configure_input.h"
|
||||
#include "configuration/configure_per_game.h"
|
||||
#include "configuration/configure_tas.h"
|
||||
@ -1095,10 +1096,9 @@ void GMainWindow::InitializeWidgets() {
|
||||
aa_status_button->setFocusPolicy(Qt::NoFocus);
|
||||
connect(aa_status_button, &QPushButton::clicked, [&] {
|
||||
auto aa_mode = Settings::values.anti_aliasing.GetValue();
|
||||
if (aa_mode == Settings::AntiAliasing::LastAA) {
|
||||
aa_mode = static_cast<Settings::AntiAliasing>(static_cast<u32>(aa_mode) + 1);
|
||||
if (aa_mode == Settings::AntiAliasing::MaxEnum) {
|
||||
aa_mode = Settings::AntiAliasing::None;
|
||||
} else {
|
||||
aa_mode = static_cast<Settings::AntiAliasing>(static_cast<u32>(aa_mode) + 1);
|
||||
}
|
||||
Settings::values.anti_aliasing.SetValue(aa_mode);
|
||||
aa_status_button->setChecked(true);
|
||||
@ -1183,7 +1183,7 @@ void GMainWindow::InitializeWidgets() {
|
||||
QMenu context_menu;
|
||||
|
||||
for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) {
|
||||
if (gpu_accuracy_pair.first == Settings::GPUAccuracy::Extreme) {
|
||||
if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) {
|
||||
continue;
|
||||
}
|
||||
context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] {
|
||||
@ -3651,14 +3651,14 @@ void GMainWindow::OnToggleDockedMode() {
|
||||
|
||||
void GMainWindow::OnToggleGpuAccuracy() {
|
||||
switch (Settings::values.gpu_accuracy.GetValue()) {
|
||||
case Settings::GPUAccuracy::High: {
|
||||
Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::Normal);
|
||||
case Settings::GpuAccuracy::High: {
|
||||
Settings::values.gpu_accuracy.SetValue(Settings::GpuAccuracy::Normal);
|
||||
break;
|
||||
}
|
||||
case Settings::GPUAccuracy::Normal:
|
||||
case Settings::GPUAccuracy::Extreme:
|
||||
case Settings::GpuAccuracy::Normal:
|
||||
case Settings::GpuAccuracy::Extreme:
|
||||
default: {
|
||||
Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High);
|
||||
Settings::values.gpu_accuracy.SetValue(Settings::GpuAccuracy::High);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3702,10 +3702,9 @@ void GMainWindow::OnIncreaseVolume() {
|
||||
|
||||
void GMainWindow::OnToggleAdaptingFilter() {
|
||||
auto filter = Settings::values.scaling_filter.GetValue();
|
||||
if (filter == Settings::ScalingFilter::LastFilter) {
|
||||
filter = static_cast<Settings::ScalingFilter>(static_cast<u32>(filter) + 1);
|
||||
if (filter == Settings::ScalingFilter::MaxEnum) {
|
||||
filter = Settings::ScalingFilter::NearestNeighbor;
|
||||
} else {
|
||||
filter = static_cast<Settings::ScalingFilter>(static_cast<u32>(filter) + 1);
|
||||
}
|
||||
Settings::values.scaling_filter.SetValue(filter);
|
||||
filter_status_button->setChecked(true);
|
||||
@ -4071,7 +4070,7 @@ void GMainWindow::UpdateGPUAccuracyButton() {
|
||||
const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue();
|
||||
const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
|
||||
gpu_accuracy_button->setText(gpu_accuracy_text.toUpper());
|
||||
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GPUAccuracy::Normal);
|
||||
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal);
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateDockedButton() {
|
||||
|
@ -34,13 +34,14 @@ DirectConnectWindow::DirectConnectWindow(Core::System& system_, QWidget* parent)
|
||||
connect(watcher, &QFutureWatcher<void>::finished, this, &DirectConnectWindow::OnConnection);
|
||||
|
||||
ui->nickname->setValidator(validation.GetNickname());
|
||||
ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
|
||||
ui->nickname->setText(
|
||||
QString::fromStdString(UISettings::values.multiplayer_nickname.GetValue()));
|
||||
if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
||||
// Use yuzu Web Service user name as nickname by default
|
||||
ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
||||
}
|
||||
ui->ip->setValidator(validation.GetIP());
|
||||
ui->ip->setText(UISettings::values.multiplayer_ip.GetValue());
|
||||
ui->ip->setText(QString::fromStdString(UISettings::values.multiplayer_ip.GetValue()));
|
||||
ui->port->setValidator(validation.GetPort());
|
||||
ui->port->setText(QString::number(UISettings::values.multiplayer_port.GetValue()));
|
||||
|
||||
@ -91,8 +92,8 @@ void DirectConnectWindow::Connect() {
|
||||
}
|
||||
|
||||
// Store settings
|
||||
UISettings::values.multiplayer_nickname = ui->nickname->text();
|
||||
UISettings::values.multiplayer_ip = ui->ip->text();
|
||||
UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString();
|
||||
UISettings::values.multiplayer_ip = ui->ip->text().toStdString();
|
||||
if (ui->port->isModified() && !ui->port->text().isEmpty()) {
|
||||
UISettings::values.multiplayer_port = ui->port->text().toInt();
|
||||
} else {
|
||||
|
@ -55,12 +55,14 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||
connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host);
|
||||
|
||||
// Restore the settings:
|
||||
ui->username->setText(UISettings::values.multiplayer_room_nickname.GetValue());
|
||||
ui->username->setText(
|
||||
QString::fromStdString(UISettings::values.multiplayer_room_nickname.GetValue()));
|
||||
if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
||||
// Use yuzu Web Service user name as nickname by default
|
||||
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
||||
}
|
||||
ui->room_name->setText(UISettings::values.multiplayer_room_name.GetValue());
|
||||
ui->room_name->setText(
|
||||
QString::fromStdString(UISettings::values.multiplayer_room_name.GetValue()));
|
||||
ui->port->setText(QString::number(UISettings::values.multiplayer_room_port.GetValue()));
|
||||
ui->max_player->setValue(UISettings::values.multiplayer_max_player.GetValue());
|
||||
int index = UISettings::values.multiplayer_host_type.GetValue();
|
||||
@ -72,7 +74,8 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||
if (index != -1) {
|
||||
ui->game_list->setCurrentIndex(index);
|
||||
}
|
||||
ui->room_description->setText(UISettings::values.multiplayer_room_description.GetValue());
|
||||
ui->room_description->setText(
|
||||
QString::fromStdString(UISettings::values.multiplayer_room_description.GetValue()));
|
||||
}
|
||||
|
||||
HostRoomWindow::~HostRoomWindow() = default;
|
||||
@ -218,8 +221,8 @@ void HostRoomWindow::Host() {
|
||||
Network::NoPreferredIP, password, token);
|
||||
|
||||
// Store settings
|
||||
UISettings::values.multiplayer_room_nickname = ui->username->text();
|
||||
UISettings::values.multiplayer_room_name = ui->room_name->text();
|
||||
UISettings::values.multiplayer_room_nickname = ui->username->text().toStdString();
|
||||
UISettings::values.multiplayer_room_name = ui->room_name->text().toStdString();
|
||||
UISettings::values.multiplayer_game_id =
|
||||
ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong();
|
||||
UISettings::values.multiplayer_max_player = ui->max_player->value();
|
||||
@ -230,7 +233,8 @@ void HostRoomWindow::Host() {
|
||||
} else {
|
||||
UISettings::values.multiplayer_room_port = Network::DefaultRoomPort;
|
||||
}
|
||||
UISettings::values.multiplayer_room_description = ui->room_description->toPlainText();
|
||||
UISettings::values.multiplayer_room_description =
|
||||
ui->room_description->toPlainText().toStdString();
|
||||
ui->host->setEnabled(true);
|
||||
emit SaveConfig();
|
||||
close();
|
||||
|
@ -60,7 +60,8 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
|
||||
ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
ui->nickname->setValidator(validation.GetNickname());
|
||||
ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
|
||||
ui->nickname->setText(
|
||||
QString::fromStdString(UISettings::values.multiplayer_nickname.GetValue()));
|
||||
|
||||
// Try find the best nickname by default
|
||||
if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("yuzu")) {
|
||||
@ -202,9 +203,9 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
|
||||
// TODO(jroweboy): disable widgets and display a connecting while we wait
|
||||
|
||||
// Save settings
|
||||
UISettings::values.multiplayer_nickname = ui->nickname->text();
|
||||
UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString();
|
||||
UISettings::values.multiplayer_ip =
|
||||
proxy->data(connection_index, LobbyItemHost::HostIPRole).toString();
|
||||
proxy->data(connection_index, LobbyItemHost::HostIPRole).value<QString>().toStdString();
|
||||
UISettings::values.multiplayer_port =
|
||||
proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt();
|
||||
emit SaveConfig();
|
||||
|
@ -3,6 +3,18 @@
|
||||
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||
namespace Settings {
|
||||
template class Setting<bool>;
|
||||
template class Setting<std::string>;
|
||||
template class Setting<u16, true>;
|
||||
template class Setting<u32>;
|
||||
template class Setting<u8, true>;
|
||||
template class Setting<u8>;
|
||||
template class Setting<unsigned long long>;
|
||||
} // namespace Settings
|
||||
#endif
|
||||
|
||||
namespace UISettings {
|
||||
|
||||
const Themes themes{{
|
||||
|
@ -14,6 +14,21 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
using Settings::Category;
|
||||
using Settings::Setting;
|
||||
|
||||
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||
namespace Settings {
|
||||
extern template class Setting<bool>;
|
||||
extern template class Setting<std::string>;
|
||||
extern template class Setting<u16, true>;
|
||||
extern template class Setting<u32>;
|
||||
extern template class Setting<u8, true>;
|
||||
extern template class Setting<u8>;
|
||||
extern template class Setting<unsigned long long>;
|
||||
} // namespace Settings
|
||||
#endif
|
||||
|
||||
namespace UISettings {
|
||||
|
||||
bool IsDarkTheme();
|
||||
@ -56,6 +71,8 @@ struct GameDir {
|
||||
};
|
||||
|
||||
struct Values {
|
||||
Settings::Linkage linkage{1000};
|
||||
|
||||
QByteArray geometry;
|
||||
QByteArray state;
|
||||
|
||||
@ -64,30 +81,54 @@ struct Values {
|
||||
QByteArray gamelist_header_state;
|
||||
|
||||
QByteArray microprofile_geometry;
|
||||
Settings::Setting<bool> microprofile_visible{false, "microProfileDialogVisible"};
|
||||
Setting<bool> microprofile_visible{linkage, false, "microProfileDialogVisible",
|
||||
Category::UiLayout};
|
||||
|
||||
Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
|
||||
Settings::Setting<bool> fullscreen{false, "fullscreen"};
|
||||
Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
|
||||
Settings::Setting<bool> show_filter_bar{true, "showFilterBar"};
|
||||
Settings::Setting<bool> show_status_bar{true, "showStatusBar"};
|
||||
|
||||
Settings::Setting<bool> confirm_before_closing{true, "confirmClose"};
|
||||
Settings::Setting<bool> first_start{true, "firstStart"};
|
||||
Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
||||
Settings::Setting<bool> mute_when_in_background{false, "muteWhenInBackground"};
|
||||
Settings::Setting<bool> hide_mouse{true, "hideInactiveMouse"};
|
||||
Settings::Setting<bool> controller_applet_disabled{false, "disableControllerApplet"};
|
||||
Setting<bool> single_window_mode{linkage, true, "singleWindowMode", Category::Ui};
|
||||
Setting<bool> fullscreen{linkage, false, "fullscreen", Category::Ui};
|
||||
Setting<bool> display_titlebar{linkage, true, "displayTitleBars", Category::Ui};
|
||||
Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui};
|
||||
Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui};
|
||||
|
||||
Setting<bool> confirm_before_closing{
|
||||
linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default,
|
||||
true, true};
|
||||
Setting<bool> first_start{linkage, true, "firstStart", Category::Ui};
|
||||
Setting<bool> pause_when_in_background{linkage,
|
||||
false,
|
||||
"pauseWhenInBackground",
|
||||
Category::UiGeneral,
|
||||
Settings::Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
Setting<bool> mute_when_in_background{
|
||||
linkage, false, "muteWhenInBackground", Category::Ui, Settings::Specialization::Default,
|
||||
true, true};
|
||||
Setting<bool> hide_mouse{
|
||||
linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,
|
||||
true, true};
|
||||
Setting<bool> controller_applet_disabled{linkage, false, "disableControllerApplet",
|
||||
Category::UiGeneral};
|
||||
// Set when Vulkan is known to crash the application
|
||||
bool has_broken_vulkan = false;
|
||||
|
||||
Settings::Setting<bool> select_user_on_boot{false, "select_user_on_boot"};
|
||||
Setting<bool> select_user_on_boot{linkage,
|
||||
false,
|
||||
"select_user_on_boot",
|
||||
Category::UiGeneral,
|
||||
Settings::Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Ui};
|
||||
|
||||
// Discord RPC
|
||||
Settings::Setting<bool> enable_discord_presence{true, "enable_discord_presence"};
|
||||
Setting<bool> enable_discord_presence{linkage, true, "enable_discord_presence", Category::Ui};
|
||||
|
||||
Settings::Setting<bool> enable_screenshot_save_as{true, "enable_screenshot_save_as"};
|
||||
// logging
|
||||
Setting<bool> show_console{linkage, false, "showConsole", Category::Ui};
|
||||
|
||||
Setting<bool> enable_screenshot_save_as{linkage, true, "enable_screenshot_save_as",
|
||||
Category::Screenshots};
|
||||
|
||||
QString roms_path;
|
||||
QString symbols_path;
|
||||
@ -102,47 +143,46 @@ struct Values {
|
||||
// Shortcut name <Shortcut, context>
|
||||
std::vector<Shortcut> shortcuts;
|
||||
|
||||
Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"};
|
||||
Setting<u32> callout_flags{linkage, 0, "calloutFlags", Category::Ui};
|
||||
|
||||
// multiplayer settings
|
||||
Settings::Setting<QString> multiplayer_nickname{{}, "nickname"};
|
||||
Settings::Setting<QString> multiplayer_ip{{}, "ip"};
|
||||
Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, UINT16_MAX, "port"};
|
||||
Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
|
||||
Settings::Setting<QString> multiplayer_room_name{{}, "room_name"};
|
||||
Settings::SwitchableSetting<uint, true> multiplayer_max_player{8, 0, 8, "max_player"};
|
||||
Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, UINT16_MAX,
|
||||
"room_port"};
|
||||
Settings::SwitchableSetting<uint, true> multiplayer_host_type{0, 0, 1, "host_type"};
|
||||
Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"};
|
||||
Settings::Setting<QString> multiplayer_room_description{{}, "room_description"};
|
||||
Setting<std::string> multiplayer_nickname{linkage, {}, "nickname", Category::Multiplayer};
|
||||
Setting<std::string> multiplayer_ip{linkage, {}, "ip", Category::Multiplayer};
|
||||
Setting<u16, true> multiplayer_port{linkage, 24872, 0,
|
||||
UINT16_MAX, "port", Category::Multiplayer};
|
||||
Setting<std::string> multiplayer_room_nickname{
|
||||
linkage, {}, "room_nickname", Category::Multiplayer};
|
||||
Setting<std::string> multiplayer_room_name{linkage, {}, "room_name", Category::Multiplayer};
|
||||
Setting<u8, true> multiplayer_max_player{linkage, 8, 0, 8, "max_player", Category::Multiplayer};
|
||||
Setting<u16, true> multiplayer_room_port{linkage, 24872, 0,
|
||||
UINT16_MAX, "room_port", Category::Multiplayer};
|
||||
Setting<u8, true> multiplayer_host_type{linkage, 0, 0, 1, "host_type", Category::Multiplayer};
|
||||
Setting<unsigned long long> multiplayer_game_id{linkage, {}, "game_id", Category::Multiplayer};
|
||||
Setting<std::string> multiplayer_room_description{
|
||||
linkage, {}, "room_description", Category::Multiplayer};
|
||||
std::pair<std::vector<std::string>, std::vector<std::string>> multiplayer_ban_list;
|
||||
|
||||
// logging
|
||||
Settings::Setting<bool> show_console{false, "showConsole"};
|
||||
|
||||
// Game List
|
||||
Settings::Setting<bool> show_add_ons{true, "show_add_ons"};
|
||||
Settings::Setting<uint32_t> game_icon_size{64, "game_icon_size"};
|
||||
Settings::Setting<uint32_t> folder_icon_size{48, "folder_icon_size"};
|
||||
Settings::Setting<uint8_t> row_1_text_id{3, "row_1_text_id"};
|
||||
Settings::Setting<uint8_t> row_2_text_id{2, "row_2_text_id"};
|
||||
Setting<bool> show_add_ons{linkage, true, "show_add_ons", Category::UiGameList};
|
||||
Setting<u32> game_icon_size{linkage, 64, "game_icon_size", Category::UiGameList};
|
||||
Setting<u32> folder_icon_size{linkage, 48, "folder_icon_size", Category::UiGameList};
|
||||
Setting<u8> row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList};
|
||||
Setting<u8> row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList};
|
||||
std::atomic_bool is_game_list_reload_pending{false};
|
||||
Settings::Setting<bool> cache_game_list{true, "cache_game_list"};
|
||||
Settings::Setting<bool> favorites_expanded{true, "favorites_expanded"};
|
||||
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
||||
Setting<bool> favorites_expanded{linkage, true, "favorites_expanded", Category::UiGameList};
|
||||
QVector<u64> favorited_ids;
|
||||
|
||||
// Compatibility List
|
||||
Settings::Setting<bool> show_compat{false, "show_compat"};
|
||||
Setting<bool> show_compat{linkage, false, "show_compat", Category::UiGameList};
|
||||
|
||||
// Size & File Types Column
|
||||
Settings::Setting<bool> show_size{true, "show_size"};
|
||||
Settings::Setting<bool> show_types{true, "show_types"};
|
||||
Setting<bool> show_size{linkage, true, "show_size", Category::UiGameList};
|
||||
Setting<bool> show_types{linkage, true, "show_types", Category::UiGameList};
|
||||
|
||||
bool configuration_applied;
|
||||
bool reset_to_defaults;
|
||||
bool shortcut_already_warned{false};
|
||||
Settings::Setting<bool> disable_web_applet{true, "disable_web_applet"};
|
||||
};
|
||||
|
||||
extern Values values;
|
||||
|
Reference in New Issue
Block a user