Add GFX property tabs to game properties window, allowing them to be set to the user game ini.

Creates a layer outside the game config layer system and passes it to the created gfx widows, so as to not interfere with the global config system.

Supports multiple game properties being open at once.
Supports editing while a game is playing, but the options only save and update the active game when the window is closed.
Right-clicking will remove a property from the game ini.

Does not support a few options that would require heavily editing the GFX widgets.  This is for options using the ConfigBool, etc system. Other options can be added later.
This commit is contained in:
TryTwo 2024-09-17 23:29:13 -07:00
parent 5fe9e2f6ed
commit b290fb8841
20 changed files with 561 additions and 155 deletions

View File

@ -5,6 +5,7 @@
#include <QEvent>
#include <QFont>
#include <QMouseEvent>
#include <QSignalBlocker>
#include "Common/Config/Config.h"
@ -12,22 +13,67 @@
#include "DolphinQt/Settings.h"
ConfigBool::ConfigBool(const QString& label, const Config::Info<bool>& setting, bool reverse)
: ToolTipCheckBox(label), m_setting(setting), m_reverse(reverse)
: ConfigBool(label, setting, nullptr, reverse)
{
}
ConfigBool::ConfigBool(const QString& label, const Config::Info<bool>& setting,
std::shared_ptr<Config::Layer> target_layer, bool reverse)
: ToolTipCheckBox(label), m_setting(setting), m_layer(target_layer), m_reverse(reverse)
{
if (m_layer == nullptr)
{
setChecked(Config::Get(m_setting) ^ reverse);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setChecked(Config::Get(m_setting) ^ m_reverse);
});
}
else
{
setChecked(m_layer->Get(m_setting) ^ reverse);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(m_layer->Exists(m_setting.GetLocation()));
setFont(bf);
const QSignalBlocker blocker(this);
setChecked(m_layer->Get(m_setting) ^ m_reverse);
});
}
connect(this, &QCheckBox::toggled, this, &ConfigBool::Update);
setChecked(Config::Get(m_setting) ^ reverse);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setChecked(Config::Get(m_setting) ^ m_reverse);
});
}
void ConfigBool::Update()
{
Config::SetBaseOrCurrent(m_setting, static_cast<bool>(isChecked() ^ m_reverse));
const bool value = static_cast<bool>(isChecked() ^ m_reverse);
if (m_layer != nullptr)
{
m_layer->Set(m_setting, value);
Config::OnConfigChanged();
return;
}
Config::SetBaseOrCurrent(m_setting, value);
}
void ConfigBool::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::RightButton && m_layer != nullptr)
{
m_layer->DeleteKey(m_setting.GetLocation());
Config::OnConfigChanged();
}
else
{
QCheckBox::mousePressEvent(event);
}
}

View File

@ -9,17 +9,22 @@ namespace Config
{
template <typename T>
class Info;
}
class Layer;
} // namespace Config
class ConfigBool : public ToolTipCheckBox
{
Q_OBJECT
public:
ConfigBool(const QString& label, const Config::Info<bool>& setting, bool reverse = false);
ConfigBool(const QString& label, const Config::Info<bool>& setting,
std::shared_ptr<Config::Layer> target_layer, bool reverse = false);
private:
void Update();
void mousePressEvent(QMouseEvent* event) override;
const Config::Info<bool>& m_setting;
std::shared_ptr<Config::Layer> m_layer;
bool m_reverse;
};

View File

@ -3,34 +3,75 @@
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include <QMouseEvent>
#include <QSignalBlocker>
#include "Common/Config/Config.h"
#include "DolphinQt/Settings.h"
ConfigChoice::ConfigChoice(const QStringList& options, const Config::Info<int>& setting)
: m_setting(setting)
ConfigChoice::ConfigChoice(const QStringList& options, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> layer)
: m_setting(setting), m_layer(layer)
{
addItems(options);
connect(this, &QComboBox::currentIndexChanged, this, &ConfigChoice::Update);
setCurrentIndex(Config::Get(m_setting));
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
if (m_layer == nullptr)
{
setCurrentIndex(Config::Get(m_setting));
});
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setCurrentIndex(Config::Get(m_setting));
});
}
else
{
setCurrentIndex(m_layer->Get(m_setting));
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(m_layer->Exists(m_setting.GetLocation()));
setFont(bf);
const QSignalBlocker blocker(this);
setCurrentIndex(m_layer->Get(m_setting));
});
}
connect(this, &QComboBox::currentIndexChanged, this, &ConfigChoice::Update);
}
void ConfigChoice::Update(int choice)
{
if (m_layer != nullptr)
{
m_layer->Set(m_setting, choice);
Config::OnConfigChanged();
return;
}
Config::SetBaseOrCurrent(m_setting, choice);
}
void ConfigChoice::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::RightButton && m_layer != nullptr)
{
m_layer->DeleteKey(m_setting.GetLocation());
Config::OnConfigChanged();
}
else
{
QComboBox::mousePressEvent(event);
}
}
// ConfigStringChoice does not appear to need local game ini logic.
ConfigStringChoice::ConfigStringChoice(const std::vector<std::string>& options,
const Config::Info<std::string>& setting)
: m_setting(setting), m_text_is_data(true)

View File

@ -15,12 +15,15 @@ class ConfigChoice : public ToolTipComboBox
{
Q_OBJECT
public:
ConfigChoice(const QStringList& options, const Config::Info<int>& setting);
ConfigChoice(const QStringList& options, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> layer = nullptr);
private:
void Update(int choice);
void mousePressEvent(QMouseEvent* event) override;
Config::Info<int> m_setting;
std::shared_ptr<Config::Layer> m_layer = nullptr;
};
class ConfigStringChoice : public ToolTipComboBox

View File

@ -3,6 +3,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigInteger.h"
#include <QMouseEvent>
#include <QSignalBlocker>
#include "Common/Config/Config.h"
@ -10,26 +11,69 @@
#include "DolphinQt/Settings.h"
ConfigInteger::ConfigInteger(int minimum, int maximum, const Config::Info<int>& setting, int step)
: ToolTipSpinBox(), m_setting(setting)
: ConfigInteger(minimum, maximum, setting, nullptr, step)
{
}
ConfigInteger::ConfigInteger(int minimum, int maximum, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> layer, int step)
: ToolTipSpinBox(), m_setting(setting), m_layer(layer)
{
setMinimum(minimum);
setMaximum(maximum);
setSingleStep(step);
setValue(Config::Get(setting));
if (m_layer == nullptr)
{
setValue(Config::Get(setting));
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setValue(Config::Get(m_setting));
});
}
else
{
setValue(m_layer->Get(setting));
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(m_layer->Exists(m_setting.GetLocation()));
setFont(bf);
const QSignalBlocker blocker(this);
setValue(m_layer->Get(m_setting));
});
}
connect(this, &ConfigInteger::valueChanged, this, &ConfigInteger::Update);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setValue(Config::Get(m_setting));
});
}
void ConfigInteger::Update(int value)
{
if (m_layer != nullptr)
{
m_layer->Set(m_setting, value);
Config::OnConfigChanged();
return;
}
Config::SetBaseOrCurrent(m_setting, value);
}
void ConfigInteger::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::RightButton && m_layer != nullptr)
{
m_layer->DeleteKey(m_setting.GetLocation());
Config::OnConfigChanged();
}
else
{
QSpinBox::mousePressEvent(event);
}
}

View File

@ -9,15 +9,22 @@ namespace Config
{
template <typename T>
class Info;
}
class Layer;
} // namespace Config
class ConfigInteger : public ToolTipSpinBox
{
Q_OBJECT
public:
ConfigInteger(int minimum, int maximum, const Config::Info<int>& setting, int step = 1);
ConfigInteger(int minimum, int maximum, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> target_layer, int step = 1);
void Update(int value);
private:
void mousePressEvent(QMouseEvent* event) override;
const Config::Info<int>& m_setting;
std::shared_ptr<Config::Layer> m_layer;
};

View File

@ -3,33 +3,61 @@
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
#include <QMouseEvent>
#include <QSignalBlocker>
#include "Common/Config/Config.h"
#include "DolphinQt/Settings.h"
ConfigRadioInt::ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value)
: ToolTipRadioButton(label), m_setting(setting), m_value(value)
ConfigRadioInt::ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value,
std::shared_ptr<Config::Layer> target_layer)
: ToolTipRadioButton(label), m_setting(setting), m_value(value), m_layer(target_layer)
{
setChecked(Config::Get(m_setting) == m_value);
connect(this, &QRadioButton::toggled, this, &ConfigRadioInt::Update);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
if (m_layer == nullptr)
{
setChecked(Config::Get(m_setting) == m_value);
});
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setChecked(Config::Get(m_setting) == m_value);
});
}
else
{
setChecked(m_layer->Get(m_setting) == m_value);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(m_layer->Exists(m_setting.GetLocation()));
setFont(bf);
const QSignalBlocker blocker(this);
setChecked(m_layer->Get(m_setting) == m_value);
});
}
connect(this, &QRadioButton::toggled, this, &ConfigRadioInt::Update);
}
void ConfigRadioInt::Update()
{
if (isChecked())
{
Config::SetBaseOrCurrent(m_setting, m_value);
if (m_layer != nullptr)
{
m_layer->Set(m_setting, m_value);
Config::OnConfigChanged();
}
else
{
Config::SetBaseOrCurrent(m_setting, m_value);
}
emit OnSelected(m_value);
}
else
@ -37,3 +65,16 @@ void ConfigRadioInt::Update()
emit OnDeselected(m_value);
}
}
void ConfigRadioInt::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::RightButton && m_layer != nullptr)
{
m_layer->DeleteKey(m_setting.GetLocation());
Config::OnConfigChanged();
}
else
{
QRadioButton::mousePressEvent(event);
}
}

View File

@ -11,7 +11,8 @@ class ConfigRadioInt : public ToolTipRadioButton
{
Q_OBJECT
public:
ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value);
ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value,
std::shared_ptr<Config::Layer> target_layer = nullptr);
signals:
// Since selecting a new radio button deselects the old one, ::toggled will generate two signals.
@ -21,7 +22,9 @@ signals:
private:
void Update();
void mousePressEvent(QMouseEvent* event) override;
Config::Info<int> m_setting;
std::shared_ptr<Config::Layer> m_layer;
int m_value;
};

View File

@ -3,6 +3,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include <QMouseEvent>
#include <QSignalBlocker>
#include "Common/Config/Config.h"
@ -10,27 +11,68 @@
#include "DolphinQt/Settings.h"
ConfigSlider::ConfigSlider(int minimum, int maximum, const Config::Info<int>& setting, int tick)
: ToolTipSlider(Qt::Horizontal), m_setting(setting)
: ConfigSlider(minimum, maximum, setting, nullptr, tick)
{
}
ConfigSlider::ConfigSlider(int minimum, int maximum, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> target_layer, int tick)
: ToolTipSlider(Qt::Horizontal), m_setting(setting), m_layer(target_layer)
{
setMinimum(minimum);
setMaximum(maximum);
setTickInterval(tick);
setValue(Config::Get(setting));
if (m_layer == nullptr)
{
setValue(Config::Get(setting));
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setValue(Config::Get(m_setting));
});
}
else
{
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(m_layer->Exists(m_setting.GetLocation()));
setFont(bf);
const QSignalBlocker blocker(this);
setValue(m_layer->Get(m_setting));
});
}
connect(this, &ConfigSlider::valueChanged, this, &ConfigSlider::Update);
connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
const QSignalBlocker blocker(this);
setValue(Config::Get(m_setting));
});
}
void ConfigSlider::Update(int value)
{
if (m_layer != nullptr)
{
m_layer->Set(m_setting, value);
Config::OnConfigChanged();
return;
}
Config::SetBaseOrCurrent(m_setting, value);
}
void ConfigSlider::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::RightButton && m_layer != nullptr)
{
m_layer->DeleteKey(m_setting.GetLocation());
Config::OnConfigChanged();
}
else
{
QSlider::mousePressEvent(event);
}
}

View File

@ -9,15 +9,22 @@ namespace Config
{
template <typename T>
class Info;
}
class Layer;
} // namespace Config
class ConfigSlider : public ToolTipSlider
{
Q_OBJECT
public:
ConfigSlider(int minimum, int maximum, const Config::Info<int>& setting, int tick = 0);
ConfigSlider(int minimum, int maximum, const Config::Info<int>& setting,
std::shared_ptr<Config::Layer> target_layer, int tick = 0);
void Update(int value);
private:
void mousePressEvent(QMouseEvent* event) override;
std::shared_ptr<Config::Layer> m_layer;
const Config::Info<int>& m_setting;
};

View File

@ -14,6 +14,8 @@
#include <QVBoxLayout>
#include "Common/CommonPaths.h"
#include "Common/Config/Config.h"
#include "Common/Config/Layer.h"
#include "Common/FileUtil.h"
#include "Core/ConfigLoaders/GameConfigLoader.h"
@ -21,6 +23,11 @@
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include "DolphinQt/Config/GameConfigEdit.h"
#include "DolphinQt/Config/Graphics/AdvancedWidget.h"
#include "DolphinQt/Config/Graphics/EnhancementsWidget.h"
#include "DolphinQt/Config/Graphics/GeneralWidget.h"
#include "DolphinQt/Config/Graphics/HacksWidget.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "UICommon/GameFile.h"
@ -55,6 +62,9 @@ GameConfigWidget::GameConfigWidget(const UICommon::GameFile& game) : m_game(game
m_gameini_local_path =
QString::fromStdString(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
m_layer = std::make_shared<Config::Layer>(
std::move(ConfigLoaders::GenerateLocalGameConfigLoader(m_game_id, m_game.GetRevision())));
CreateWidgets();
LoadSettings();
ConnectWidgets();
@ -156,11 +166,10 @@ void GameConfigWidget::CreateWidgets()
settings_layout->addWidget(core_box);
settings_layout->addWidget(stereoscopy_box);
auto* general_layout = new QGridLayout;
general_layout->addWidget(settings_box, 0, 0, 1, -1);
general_layout->addWidget(m_refresh_config, 1, 0, 1, -1);
auto* general_layout = new QVBoxLayout;
general_layout->addWidget(settings_box);
general_layout->addWidget(m_refresh_config);
general_layout->addStretch();
for (QCheckBox* item :
{m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, m_emulate_disc_speed,
@ -196,15 +205,71 @@ void GameConfigWidget::CreateWidgets()
auto* layout = new QVBoxLayout;
auto* tab_widget = new QTabWidget;
tab_widget->addTab(general_widget, tr("General"));
tab_widget->addTab(advanced_widget, tr("Editor"));
const int editor_index = tab_widget->indexOf(advanced_widget);
// GFX settings tabs.
auto* tab_widget2 = new QTabWidget;
tab_widget->addTab(tab_widget2, tr("GFX"));
const int gfx_index = tab_widget->indexOf(tab_widget2);
tab_widget2->addTab(GetWrappedWidget(new GeneralWidget(this, m_layer), this, 125, 100),
tr("General"));
tab_widget2->addTab(GetWrappedWidget(new EnhancementsWidget(this, m_layer), this, 125, 100),
tr("Enhancements"));
tab_widget2->addTab(GetWrappedWidget(new HacksWidget(this, m_layer), this, 125, 100),
tr("Hacks"));
tab_widget2->addTab(GetWrappedWidget(new AdvancedWidget(this, m_layer), this, 125, 100),
tr("Advanced"));
connect(
tab_widget, &QTabWidget::currentChanged, this, [this, gfx_index, editor_index](int index) {
// Update the ini editor after editing the GFX tabs.
if (index == editor_index)
{
// Layer only auto-saves when it is destroyed.
m_layer->Save();
m_local_tab->removeTab(0);
auto* edit = new GameConfigEdit(
nullptr,
QString::fromStdString(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini"),
false);
m_local_tab->addTab(edit, QString::fromStdString(m_game_id + ".ini"));
}
// Update GFX tabs after using ini editor.
if (index == gfx_index)
{
// Load won't clear/reset deleted keys, so everything is wiped before loading.
m_layer->DeleteAllKeys();
m_layer->Load();
Config::OnConfigChanged();
}
});
// The advanced tab's length will oversize the scrollbar on the other tabs.
layout->addWidget(tab_widget);
setLayout(layout);
}
GameConfigWidget::~GameConfigWidget()
{
// If a game is running and the game properties window is closed, update local game layer with any
// new changes. Not sure if doing it more frequently is safe.
auto local_layer = Config::GetLayer(Config::LayerType::LocalGame);
if (local_layer && SConfig::GetInstance().GetGameID() == m_game_id)
{
// m_layer saves when closing the window, but it happens too late.
m_layer->Save();
local_layer->DeleteAllKeys();
local_layer->Load();
Config::OnConfigChanged();
}
}
void GameConfigWidget::ConnectWidgets()
{
// Buttons

View File

@ -15,6 +15,11 @@ namespace UICommon
class GameFile;
}
namespace Config
{
class Layer;
} // namespace Config
class QCheckBox;
class QComboBox;
class QPushButton;
@ -27,6 +32,7 @@ class GameConfigWidget : public QWidget
Q_OBJECT
public:
explicit GameConfigWidget(const UICommon::GameFile& game);
~GameConfigWidget();
private:
void CreateWidgets();
@ -65,6 +71,7 @@ private:
const UICommon::GameFile& m_game;
std::string m_game_id;
std::shared_ptr<Config::Layer> m_layer;
Common::IniFile m_gameini_local;
Common::IniFile m_gameini_default;

View File

@ -19,6 +19,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigInteger.h"
#include "DolphinQt/Config/GameConfigWidget.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
@ -47,6 +48,15 @@ AdvancedWidget::AdvancedWidget(GraphicsWindow* parent)
Core::State::Uninitialized);
}
AdvancedWidget::AdvancedWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer)
: m_game_layer(layer)
{
CreateWidgets();
LoadSettings();
ConnectWidgets();
AddDescriptions();
}
void AdvancedWidget::CreateWidgets()
{
auto* main_layout = new QVBoxLayout;
@ -56,17 +66,19 @@ void AdvancedWidget::CreateWidgets()
auto* performance_layout = new QGridLayout();
performance_box->setLayout(performance_layout);
m_show_fps = new ConfigBool(tr("Show FPS"), Config::GFX_SHOW_FPS);
m_show_ftimes = new ConfigBool(tr("Show Frame Times"), Config::GFX_SHOW_FTIMES);
m_show_vps = new ConfigBool(tr("Show VPS"), Config::GFX_SHOW_VPS);
m_show_vtimes = new ConfigBool(tr("Show VBlank Times"), Config::GFX_SHOW_VTIMES);
m_show_graphs = new ConfigBool(tr("Show Performance Graphs"), Config::GFX_SHOW_GRAPHS);
m_show_speed = new ConfigBool(tr("Show % Speed"), Config::GFX_SHOW_SPEED);
m_show_speed_colors = new ConfigBool(tr("Show Speed Colors"), Config::GFX_SHOW_SPEED_COLORS);
m_perf_samp_window = new ConfigInteger(0, 10000, Config::GFX_PERF_SAMP_WINDOW, 100);
m_show_fps = new ConfigBool(tr("Show FPS"), Config::GFX_SHOW_FPS, m_game_layer);
m_show_ftimes = new ConfigBool(tr("Show Frame Times"), Config::GFX_SHOW_FTIMES, m_game_layer);
m_show_vps = new ConfigBool(tr("Show VPS"), Config::GFX_SHOW_VPS, m_game_layer);
m_show_vtimes = new ConfigBool(tr("Show VBlank Times"), Config::GFX_SHOW_VTIMES, m_game_layer);
m_show_graphs =
new ConfigBool(tr("Show Performance Graphs"), Config::GFX_SHOW_GRAPHS, m_game_layer);
m_show_speed = new ConfigBool(tr("Show % Speed"), Config::GFX_SHOW_SPEED, m_game_layer);
m_show_speed_colors =
new ConfigBool(tr("Show Speed Colors"), Config::GFX_SHOW_SPEED_COLORS, m_game_layer);
m_perf_samp_window = new ConfigInteger(0, 10000, Config::GFX_PERF_SAMP_WINDOW, m_game_layer, 100);
m_perf_samp_window->SetTitle(tr("Performance Sample Window (ms)"));
m_log_render_time =
new ConfigBool(tr("Log Render Time to File"), Config::GFX_LOG_RENDER_TIME_TO_FILE);
m_log_render_time = new ConfigBool(tr("Log Render Time to File"),
Config::GFX_LOG_RENDER_TIME_TO_FILE, m_game_layer);
performance_layout->addWidget(m_show_fps, 0, 0);
performance_layout->addWidget(m_show_ftimes, 0, 1);
@ -84,14 +96,16 @@ void AdvancedWidget::CreateWidgets()
auto* debugging_layout = new QGridLayout();
debugging_box->setLayout(debugging_layout);
m_enable_wireframe = new ConfigBool(tr("Enable Wireframe"), Config::GFX_ENABLE_WIREFRAME);
m_show_statistics = new ConfigBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS);
m_show_proj_statistics =
new ConfigBool(tr("Show Projection Statistics"), Config::GFX_OVERLAY_PROJ_STATS);
m_enable_wireframe =
new ConfigBool(tr("Enable Wireframe"), Config::GFX_ENABLE_WIREFRAME, m_game_layer);
m_show_statistics =
new ConfigBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS, m_game_layer);
m_show_proj_statistics = new ConfigBool(tr("Show Projection Statistics"),
Config::GFX_OVERLAY_PROJ_STATS, m_game_layer);
m_enable_format_overlay =
new ConfigBool(tr("Texture Format Overlay"), Config::GFX_TEXFMT_OVERLAY_ENABLE);
m_enable_api_validation =
new ConfigBool(tr("Enable API Validation Layers"), Config::GFX_ENABLE_VALIDATION_LAYER);
new ConfigBool(tr("Texture Format Overlay"), Config::GFX_TEXFMT_OVERLAY_ENABLE, m_game_layer);
m_enable_api_validation = new ConfigBool(tr("Enable API Validation Layers"),
Config::GFX_ENABLE_VALIDATION_LAYER, m_game_layer);
debugging_layout->addWidget(m_enable_wireframe, 0, 0);
debugging_layout->addWidget(m_show_statistics, 0, 1);
@ -104,13 +118,14 @@ void AdvancedWidget::CreateWidgets()
auto* utility_layout = new QGridLayout();
utility_box->setLayout(utility_layout);
m_load_custom_textures = new ConfigBool(tr("Load Custom Textures"), Config::GFX_HIRES_TEXTURES);
m_prefetch_custom_textures =
new ConfigBool(tr("Prefetch Custom Textures"), Config::GFX_CACHE_HIRES_TEXTURES);
m_load_custom_textures =
new ConfigBool(tr("Load Custom Textures"), Config::GFX_HIRES_TEXTURES, m_game_layer);
m_prefetch_custom_textures = new ConfigBool(tr("Prefetch Custom Textures"),
Config::GFX_CACHE_HIRES_TEXTURES, m_game_layer);
m_dump_efb_target = new ConfigBool(tr("Dump EFB Target"), Config::GFX_DUMP_EFB_TARGET);
m_dump_xfb_target = new ConfigBool(tr("Dump XFB Target"), Config::GFX_DUMP_XFB_TARGET);
m_disable_vram_copies =
new ConfigBool(tr("Disable EFB VRAM Copies"), Config::GFX_HACK_DISABLE_COPY_TO_VRAM);
m_disable_vram_copies = new ConfigBool(tr("Disable EFB VRAM Copies"),
Config::GFX_HACK_DISABLE_COPY_TO_VRAM, m_game_layer);
m_enable_graphics_mods = new ToolTipCheckBox(tr("Enable Graphics Mods"));
utility_layout->addWidget(m_load_custom_textures, 0, 0);
@ -143,10 +158,12 @@ void AdvancedWidget::CreateWidgets()
m_frame_dumps_resolution_type =
new ConfigChoice({tr("Window Resolution"), tr("Aspect Ratio Corrected Internal Resolution"),
tr("Raw Internal Resolution")},
Config::GFX_FRAME_DUMPS_RESOLUTION_TYPE);
m_dump_use_ffv1 = new ConfigBool(tr("Use Lossless Codec (FFV1)"), Config::GFX_USE_FFV1);
m_dump_bitrate = new ConfigInteger(0, 1000000, Config::GFX_BITRATE_KBPS, 1000);
m_png_compression_level = new ConfigInteger(0, 9, Config::GFX_PNG_COMPRESSION_LEVEL);
Config::GFX_FRAME_DUMPS_RESOLUTION_TYPE, m_game_layer);
m_dump_use_ffv1 =
new ConfigBool(tr("Use Lossless Codec (FFV1)"), Config::GFX_USE_FFV1, m_game_layer);
m_dump_bitrate = new ConfigInteger(0, 1000000, Config::GFX_BITRATE_KBPS, m_game_layer, 1000);
m_png_compression_level =
new ConfigInteger(0, 9, Config::GFX_PNG_COMPRESSION_LEVEL, m_game_layer);
dump_layout->addWidget(new QLabel(tr("Resolution Type:")), 0, 0);
dump_layout->addWidget(m_frame_dumps_resolution_type, 0, 1);
@ -164,14 +181,15 @@ void AdvancedWidget::CreateWidgets()
auto* misc_layout = new QGridLayout();
misc_box->setLayout(misc_layout);
m_enable_cropping = new ConfigBool(tr("Crop"), Config::GFX_CROP);
m_enable_cropping = new ConfigBool(tr("Crop"), Config::GFX_CROP, m_game_layer);
m_enable_prog_scan = new ToolTipCheckBox(tr("Enable Progressive Scan"));
m_backend_multithreading =
new ConfigBool(tr("Backend Multithreading"), Config::GFX_BACKEND_MULTITHREADING);
m_backend_multithreading = new ConfigBool(tr("Backend Multithreading"),
Config::GFX_BACKEND_MULTITHREADING, m_game_layer);
m_prefer_vs_for_point_line_expansion = new ConfigBool(
// i18n: VS is short for vertex shaders.
tr("Prefer VS for Point/Line Expansion"), Config::GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION);
m_cpu_cull = new ConfigBool(tr("Cull Vertices on the CPU"), Config::GFX_CPU_CULL);
tr("Prefer VS for Point/Line Expansion"), Config::GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION,
m_game_layer);
m_cpu_cull = new ConfigBool(tr("Cull Vertices on the CPU"), Config::GFX_CPU_CULL, m_game_layer);
misc_layout->addWidget(m_enable_cropping, 0, 0);
misc_layout->addWidget(m_enable_prog_scan, 0, 1);
@ -180,7 +198,7 @@ void AdvancedWidget::CreateWidgets()
misc_layout->addWidget(m_cpu_cull, 2, 0);
#ifdef _WIN32
m_borderless_fullscreen =
new ConfigBool(tr("Borderless Fullscreen"), Config::GFX_BORDERLESS_FULLSCREEN);
new ConfigBool(tr("Borderless Fullscreen"), Config::GFX_BORDERLESS_FULLSCREEN, m_game_layer);
misc_layout->addWidget(m_borderless_fullscreen, 2, 1);
#endif
@ -190,10 +208,10 @@ void AdvancedWidget::CreateWidgets()
auto* experimental_layout = new QGridLayout();
experimental_box->setLayout(experimental_layout);
m_defer_efb_access_invalidation =
new ConfigBool(tr("Defer EFB Cache Invalidation"), Config::GFX_HACK_EFB_DEFER_INVALIDATION);
m_manual_texture_sampling =
new ConfigBool(tr("Manual Texture Sampling"), Config::GFX_HACK_FAST_TEXTURE_SAMPLING, true);
m_defer_efb_access_invalidation = new ConfigBool(
tr("Defer EFB Cache Invalidation"), Config::GFX_HACK_EFB_DEFER_INVALIDATION, m_game_layer);
m_manual_texture_sampling = new ConfigBool(
tr("Manual Texture Sampling"), Config::GFX_HACK_FAST_TEXTURE_SAMPLING, m_game_layer, true);
experimental_layout->addWidget(m_defer_efb_access_invalidation, 0, 0);
experimental_layout->addWidget(m_manual_texture_sampling, 0, 1);

View File

@ -8,17 +8,24 @@
class ConfigBool;
class ConfigChoice;
class ConfigInteger;
class GameConfigWidget;
class GraphicsWindow;
class QCheckBox;
class QComboBox;
class QSpinBox;
class ToolTipCheckBox;
namespace Config
{
class Layer;
} // namespace Config
class AdvancedWidget final : public QWidget
{
Q_OBJECT
public:
explicit AdvancedWidget(GraphicsWindow* parent);
AdvancedWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer);
private:
void LoadSettings();
@ -76,4 +83,6 @@ private:
// Experimental
ConfigBool* m_defer_efb_access_invalidation;
ConfigBool* m_manual_texture_sampling;
std::shared_ptr<Config::Layer> m_game_layer = nullptr;
};

View File

@ -18,6 +18,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include "DolphinQt/Config/GameConfigWidget.h"
#include "DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/Graphics/PostProcessingConfigWindow.h"
@ -45,6 +46,16 @@ EnhancementsWidget::EnhancementsWidget(GraphicsWindow* parent) : m_block_save(fa
&EnhancementsWidget::LoadSettings);
}
EnhancementsWidget::EnhancementsWidget(GameConfigWidget* parent,
std::shared_ptr<Config::Layer> layer)
: m_game_layer(layer)
{
CreateWidgets();
LoadSettings();
ConnectWidgets();
AddDescriptions();
}
constexpr int TEXTURE_FILTERING_DEFAULT = 0;
constexpr int TEXTURE_FILTERING_ANISO_2X = 1;
constexpr int TEXTURE_FILTERING_ANISO_4X = 2;
@ -104,7 +115,7 @@ void EnhancementsWidget::CreateWidgets()
}
}
m_ir_combo = new ConfigChoice(resolution_options, Config::GFX_EFB_SCALE);
m_ir_combo = new ConfigChoice(resolution_options, Config::GFX_EFB_SCALE, m_game_layer);
m_ir_combo->setMaxVisibleItems(visible_resolution_option_count);
m_aa_combo = new ToolTipComboBox();
@ -146,19 +157,22 @@ void EnhancementsWidget::CreateWidgets()
m_pp_effect = new ToolTipComboBox();
m_configure_pp_effect = new NonDefaultQPushButton(tr("Configure"));
m_scaled_efb_copy = new ConfigBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_SCALED);
m_scaled_efb_copy =
new ConfigBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_SCALED, m_game_layer);
m_per_pixel_lighting =
new ConfigBool(tr("Per-Pixel Lighting"), Config::GFX_ENABLE_PIXEL_LIGHTING);
new ConfigBool(tr("Per-Pixel Lighting"), Config::GFX_ENABLE_PIXEL_LIGHTING, m_game_layer);
m_widescreen_hack = new ConfigBool(tr("Widescreen Hack"), Config::GFX_WIDESCREEN_HACK);
m_disable_fog = new ConfigBool(tr("Disable Fog"), Config::GFX_DISABLE_FOG);
m_widescreen_hack =
new ConfigBool(tr("Widescreen Hack"), Config::GFX_WIDESCREEN_HACK, m_game_layer);
m_disable_fog = new ConfigBool(tr("Disable Fog"), Config::GFX_DISABLE_FOG, m_game_layer);
m_force_24bit_color =
new ConfigBool(tr("Force 24-Bit Color"), Config::GFX_ENHANCE_FORCE_TRUE_COLOR);
m_disable_copy_filter =
new ConfigBool(tr("Disable Copy Filter"), Config::GFX_ENHANCE_DISABLE_COPY_FILTER);
m_arbitrary_mipmap_detection = new ConfigBool(tr("Arbitrary Mipmap Detection"),
Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION);
m_hdr = new ConfigBool(tr("HDR Post-Processing"), Config::GFX_ENHANCE_HDR_OUTPUT);
new ConfigBool(tr("Force 24-Bit Color"), Config::GFX_ENHANCE_FORCE_TRUE_COLOR, m_game_layer);
m_disable_copy_filter = new ConfigBool(tr("Disable Copy Filter"),
Config::GFX_ENHANCE_DISABLE_COPY_FILTER, m_game_layer);
m_arbitrary_mipmap_detection =
new ConfigBool(tr("Arbitrary Mipmap Detection"),
Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION, m_game_layer);
m_hdr = new ConfigBool(tr("HDR Post-Processing"), Config::GFX_ENHANCE_HDR_OUTPUT, m_game_layer);
int row = 0;
enhancements_layout->addWidget(new QLabel(tr("Internal Resolution:")), row, 0);
@ -209,15 +223,16 @@ void EnhancementsWidget::CreateWidgets()
m_3d_mode = new ConfigChoice({tr("Off"), tr("Side-by-Side"), tr("Top-and-Bottom"), tr("Anaglyph"),
tr("HDMI 3D"), tr("Passive")},
Config::GFX_STEREO_MODE);
m_3d_depth = new ConfigSlider(0, Config::GFX_STEREO_DEPTH_MAXIMUM, Config::GFX_STEREO_DEPTH);
Config::GFX_STEREO_MODE, m_game_layer);
m_3d_depth =
new ConfigSlider(0, Config::GFX_STEREO_DEPTH_MAXIMUM, Config::GFX_STEREO_DEPTH, m_game_layer);
m_3d_convergence = new ConfigSlider(0, Config::GFX_STEREO_CONVERGENCE_MAXIMUM,
Config::GFX_STEREO_CONVERGENCE, 100);
Config::GFX_STEREO_CONVERGENCE, m_game_layer, 100);
m_3d_swap_eyes = new ConfigBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES);
m_3d_swap_eyes = new ConfigBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES, m_game_layer);
m_3d_per_eye_resolution =
new ConfigBool(tr("Use Full Resolution Per Eye"), Config::GFX_STEREO_PER_EYE_RESOLUTION_FULL);
m_3d_per_eye_resolution = new ConfigBool(
tr("Use Full Resolution Per Eye"), Config::GFX_STEREO_PER_EYE_RESOLUTION_FULL, m_game_layer);
stereoscopy_layout->addWidget(new QLabel(tr("Stereoscopic 3D Mode:")), 0, 0);
stereoscopy_layout->addWidget(m_3d_mode, 0, 1);

View File

@ -10,6 +10,7 @@
class ConfigBool;
class ConfigChoice;
class ConfigSlider;
class GameConfigWidget;
class GraphicsWindow;
class QCheckBox;
class QComboBox;
@ -19,11 +20,17 @@ class ToolTipComboBox;
class ToolTipPushButton;
enum class StereoMode : int;
namespace Config
{
class Layer;
} // namespace Config
class EnhancementsWidget final : public QWidget
{
Q_OBJECT
public:
explicit EnhancementsWidget(GraphicsWindow* parent);
EnhancementsWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer);
private:
void LoadSettings();
@ -60,6 +67,7 @@ private:
ConfigBool* m_3d_swap_eyes;
ConfigBool* m_3d_per_eye_resolution;
std::shared_ptr<Config::Layer> m_game_layer = nullptr;
int m_msaa_modes;
bool m_block_save;
};

View File

@ -23,6 +23,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigInteger.h"
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
#include "DolphinQt/Config/GameConfigWidget.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
@ -48,6 +49,15 @@ GeneralWidget::GeneralWidget(GraphicsWindow* parent)
Core::State::Uninitialized);
}
GeneralWidget::GeneralWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer)
: m_game_layer(layer)
{
CreateWidgets();
LoadSettings();
ConnectWidgets();
AddDescriptions();
}
void GeneralWidget::CreateWidgets()
{
auto* main_layout = new QVBoxLayout;
@ -59,21 +69,22 @@ void GeneralWidget::CreateWidgets()
m_backend_combo = new ToolTipComboBox();
m_aspect_combo = new ConfigChoice({tr("Auto"), tr("Force 16:9"), tr("Force 4:3"),
tr("Stretch to Window"), tr("Custom"), tr("Custom (Stretch)")},
Config::GFX_ASPECT_RATIO);
Config::GFX_ASPECT_RATIO, m_game_layer);
m_custom_aspect_label = new QLabel(tr("Custom Aspect Ratio:"));
m_custom_aspect_label->setHidden(true);
constexpr int MAX_CUSTOM_ASPECT_RATIO_RESOLUTION = 10000;
m_custom_aspect_width = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION,
Config::GFX_CUSTOM_ASPECT_RATIO_WIDTH);
Config::GFX_CUSTOM_ASPECT_RATIO_WIDTH, m_game_layer);
m_custom_aspect_width->setEnabled(false);
m_custom_aspect_width->setHidden(true);
m_custom_aspect_height = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION,
Config::GFX_CUSTOM_ASPECT_RATIO_HEIGHT);
Config::GFX_CUSTOM_ASPECT_RATIO_HEIGHT, m_game_layer);
m_custom_aspect_height->setEnabled(false);
m_custom_aspect_height->setHidden(true);
m_adapter_combo = new ToolTipComboBox;
m_enable_vsync = new ConfigBool(tr("V-Sync"), Config::GFX_VSYNC);
m_enable_fullscreen = new ConfigBool(tr("Start in Fullscreen"), Config::MAIN_FULLSCREEN);
m_enable_vsync = new ConfigBool(tr("V-Sync"), Config::GFX_VSYNC, m_game_layer);
m_enable_fullscreen =
new ConfigBool(tr("Start in Fullscreen"), Config::MAIN_FULLSCREEN, m_game_layer);
m_video_box->setLayout(m_video_layout);
@ -103,11 +114,14 @@ void GeneralWidget::CreateWidgets()
auto* m_options_box = new QGroupBox(tr("Other"));
auto* m_options_layout = new QGridLayout();
m_show_ping = new ConfigBool(tr("Show NetPlay Ping"), Config::GFX_SHOW_NETPLAY_PING);
m_autoadjust_window_size =
new ConfigBool(tr("Auto-Adjust Window Size"), Config::MAIN_RENDER_WINDOW_AUTOSIZE);
m_show_messages = new ConfigBool(tr("Show NetPlay Messages"), Config::GFX_SHOW_NETPLAY_MESSAGES);
m_render_main_window = new ConfigBool(tr("Render to Main Window"), Config::MAIN_RENDER_TO_MAIN);
m_show_ping =
new ConfigBool(tr("Show NetPlay Ping"), Config::GFX_SHOW_NETPLAY_PING, m_game_layer);
m_autoadjust_window_size = new ConfigBool(tr("Auto-Adjust Window Size"),
Config::MAIN_RENDER_WINDOW_AUTOSIZE, m_game_layer);
m_show_messages =
new ConfigBool(tr("Show NetPlay Messages"), Config::GFX_SHOW_NETPLAY_MESSAGES, m_game_layer);
m_render_main_window =
new ConfigBool(tr("Render to Main Window"), Config::MAIN_RENDER_TO_MAIN, m_game_layer);
m_options_box->setLayout(m_options_layout);
@ -129,13 +143,13 @@ void GeneralWidget::CreateWidgets()
}};
for (size_t i = 0; i < modes.size(); i++)
{
m_shader_compilation_mode[i] =
new ConfigRadioInt(tr(modes[i]), Config::GFX_SHADER_COMPILATION_MODE, static_cast<int>(i));
m_shader_compilation_mode[i] = new ConfigRadioInt(
tr(modes[i]), Config::GFX_SHADER_COMPILATION_MODE, static_cast<int>(i), m_game_layer);
shader_compilation_layout->addWidget(m_shader_compilation_mode[i], static_cast<int>(i / 2),
static_cast<int>(i % 2));
}
m_wait_for_shaders = new ConfigBool(tr("Compile Shaders Before Starting"),
Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING);
Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING, m_game_layer);
shader_compilation_layout->addWidget(m_wait_for_shaders);
shader_compilation_box->setLayout(shader_compilation_layout);

View File

@ -11,6 +11,7 @@ class ConfigBool;
class ConfigChoice;
class ConfigInteger;
class ConfigRadioInt;
class GameConfigWidget;
class GraphicsWindow;
class QCheckBox;
class QComboBox;
@ -19,11 +20,18 @@ class QRadioButton;
class QGridLayout;
class ToolTipComboBox;
namespace Config
{
class Layer;
} // namespace Config
class GeneralWidget final : public QWidget
{
Q_OBJECT
public:
explicit GeneralWidget(GraphicsWindow* parent);
GeneralWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer);
signals:
void BackendChanged(const QString& backend);
@ -56,4 +64,6 @@ private:
ConfigBool* m_render_main_window;
std::array<ConfigRadioInt*, 4> m_shader_compilation_mode{};
ConfigBool* m_wait_for_shaders;
std::shared_ptr<Config::Layer> m_game_layer = nullptr;
};

View File

@ -15,6 +15,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include "DolphinQt/Config/GameConfigWidget.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipSlider.h"
#include "DolphinQt/Settings.h"
@ -37,6 +38,15 @@ HacksWidget::HacksWidget(GraphicsWindow* parent)
});
}
HacksWidget::HacksWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer)
: m_game_layer(layer)
{
CreateWidgets();
LoadSettings();
ConnectWidgets();
AddDescriptions();
}
void HacksWidget::CreateWidgets()
{
auto* main_layout = new QVBoxLayout;
@ -45,14 +55,14 @@ void HacksWidget::CreateWidgets()
auto* efb_box = new QGroupBox(tr("Embedded Frame Buffer (EFB)"));
auto* efb_layout = new QGridLayout();
efb_box->setLayout(efb_layout);
m_skip_efb_cpu =
new ConfigBool(tr("Skip EFB Access from CPU"), Config::GFX_HACK_EFB_ACCESS_ENABLE, true);
m_ignore_format_changes = new ConfigBool(tr("Ignore Format Changes"),
Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, true);
m_store_efb_copies =
new ConfigBool(tr("Store EFB Copies to Texture Only"), Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
m_defer_efb_copies =
new ConfigBool(tr("Defer EFB Copies to RAM"), Config::GFX_HACK_DEFER_EFB_COPIES);
m_skip_efb_cpu = new ConfigBool(tr("Skip EFB Access from CPU"),
Config::GFX_HACK_EFB_ACCESS_ENABLE, m_game_layer, true);
m_ignore_format_changes = new ConfigBool(
tr("Ignore Format Changes"), Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, m_game_layer, true);
m_store_efb_copies = new ConfigBool(tr("Store EFB Copies to Texture Only"),
Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, m_game_layer);
m_defer_efb_copies = new ConfigBool(tr("Defer EFB Copies to RAM"),
Config::GFX_HACK_DEFER_EFB_COPIES, m_game_layer);
efb_layout->addWidget(m_skip_efb_cpu, 0, 0);
efb_layout->addWidget(m_ignore_format_changes, 0, 1);
@ -69,8 +79,8 @@ void HacksWidget::CreateWidgets()
m_accuracy->setMaximum(2);
m_accuracy->setPageStep(1);
m_accuracy->setTickPosition(QSlider::TicksBelow);
m_gpu_texture_decoding =
new ConfigBool(tr("GPU Texture Decoding"), Config::GFX_ENABLE_GPU_TEXTURE_DECODING);
m_gpu_texture_decoding = new ConfigBool(tr("GPU Texture Decoding"),
Config::GFX_ENABLE_GPU_TEXTURE_DECODING, m_game_layer);
auto* safe_label = new QLabel(tr("Safe"));
safe_label->setAlignment(Qt::AlignRight);
@ -88,11 +98,12 @@ void HacksWidget::CreateWidgets()
auto* xfb_layout = new QVBoxLayout();
xfb_box->setLayout(xfb_layout);
m_store_xfb_copies =
new ConfigBool(tr("Store XFB Copies to Texture Only"), Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM);
m_immediate_xfb = new ConfigBool(tr("Immediately Present XFB"), Config::GFX_HACK_IMMEDIATE_XFB);
m_skip_duplicate_xfbs =
new ConfigBool(tr("Skip Presenting Duplicate Frames"), Config::GFX_HACK_SKIP_DUPLICATE_XFBS);
m_store_xfb_copies = new ConfigBool(tr("Store XFB Copies to Texture Only"),
Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, m_game_layer);
m_immediate_xfb =
new ConfigBool(tr("Immediately Present XFB"), Config::GFX_HACK_IMMEDIATE_XFB, m_game_layer);
m_skip_duplicate_xfbs = new ConfigBool(tr("Skip Presenting Duplicate Frames"),
Config::GFX_HACK_SKIP_DUPLICATE_XFBS, m_game_layer);
xfb_layout->addWidget(m_store_xfb_copies);
xfb_layout->addWidget(m_immediate_xfb);
@ -104,13 +115,14 @@ void HacksWidget::CreateWidgets()
other_box->setLayout(other_layout);
m_fast_depth_calculation =
new ConfigBool(tr("Fast Depth Calculation"), Config::GFX_FAST_DEPTH_CALC);
new ConfigBool(tr("Fast Depth Calculation"), Config::GFX_FAST_DEPTH_CALC, m_game_layer);
m_disable_bounding_box =
new ConfigBool(tr("Disable Bounding Box"), Config::GFX_HACK_BBOX_ENABLE, true);
m_vertex_rounding = new ConfigBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUNDING);
m_save_texture_cache_state =
new ConfigBool(tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE);
m_vi_skip = new ConfigBool(tr("VBI Skip"), Config::GFX_HACK_VI_SKIP);
new ConfigBool(tr("Disable Bounding Box"), Config::GFX_HACK_BBOX_ENABLE, m_game_layer, true);
m_vertex_rounding =
new ConfigBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUNDING, m_game_layer);
m_save_texture_cache_state = new ConfigBool(
tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE, m_game_layer);
m_vi_skip = new ConfigBool(tr("VBI Skip"), Config::GFX_HACK_VI_SKIP, m_game_layer);
other_layout->addWidget(m_fast_depth_calculation, 0, 0);
other_layout->addWidget(m_disable_bounding_box, 0, 1);

View File

@ -6,15 +6,22 @@
#include <QWidget>
class ConfigBool;
class GameConfigWidget;
class GraphicsWindow;
class QLabel;
class ToolTipSlider;
namespace Config
{
class Layer;
} // namespace Config
class HacksWidget final : public QWidget
{
Q_OBJECT
public:
explicit HacksWidget(GraphicsWindow* parent);
HacksWidget(GameConfigWidget* parent, std::shared_ptr<Config::Layer> layer);
private:
void LoadSettings();
@ -45,6 +52,8 @@ private:
ConfigBool* m_vi_skip;
ConfigBool* m_save_texture_cache_state;
std::shared_ptr<Config::Layer> m_game_layer = nullptr;
void CreateWidgets();
void ConnectWidgets();
void AddDescriptions();