diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 7d378cf92..600b94bd5 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -389,6 +389,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)); si.SetBoolValue("Display", "LinearFiltering", true); si.SetBoolValue("Display", "IntegerScaling", false); + si.SetBoolValue("Display", "PostProcessing", false); si.SetBoolValue("Display", "ShowOSDMessages", true); si.SetBoolValue("Display", "ShowFPS", false); si.SetBoolValue("Display", "ShowVPS", false); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index f82e3ecce..d62439e34 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -129,6 +129,7 @@ void Settings::Load(SettingsInterface& si) display_active_end_offset = static_cast(si.GetIntValue("Display", "ActiveEndOffset", 0)); display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true); display_integer_scaling = si.GetBoolValue("Display", "IntegerScaling", false); + display_post_processing = si.GetBoolValue("Display", "PostProcessing", false); display_show_osd_messages = si.GetBoolValue("Display", "ShowOSDMessages", true); display_show_fps = si.GetBoolValue("Display", "ShowFPS", false); display_show_vps = si.GetBoolValue("Display", "ShowVPS", false); @@ -239,6 +240,7 @@ void Settings::Save(SettingsInterface& si) const si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio)); si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering); si.SetBoolValue("Display", "IntegerScaling", display_integer_scaling); + si.SetBoolValue("Display", "PostProcessing", display_post_processing); si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages); si.SetBoolValue("Display", "ShowFPS", display_show_fps); si.SetBoolValue("Display", "ShowVPS", display_show_vps); diff --git a/src/core/settings.h b/src/core/settings.h index 3892718ea..08373fd1c 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -106,6 +106,7 @@ struct Settings DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3; bool display_linear_filtering = true; bool display_integer_scaling = false; + bool display_post_processing = false; bool display_show_osd_messages = false; bool display_show_fps = false; bool display_show_vps = false; diff --git a/src/duckstation-qt/CMakeLists.txt b/src/duckstation-qt/CMakeLists.txt index 3d265f20b..776abe4de 100644 --- a/src/duckstation-qt/CMakeLists.txt +++ b/src/duckstation-qt/CMakeLists.txt @@ -57,6 +57,9 @@ set(SRCS postprocessingchainconfigwidget.cpp postprocessingchainconfigwidget.h postprocessingchainconfigwidget.ui + postprocessingsettingswidget.cpp + postprocessingsettingswidget.h + postprocessingsettingswidget.ui postprocessingshaderconfigwidget.cpp postprocessingshaderconfigwidget.h qtdisplaywidget.cpp diff --git a/src/duckstation-qt/displaysettingswidget.cpp b/src/duckstation-qt/displaysettingswidget.cpp index 2c3f5243f..26b276278 100644 --- a/src/duckstation-qt/displaysettingswidget.cpp +++ b/src/duckstation-qt/displaysettingswidget.cpp @@ -47,25 +47,6 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW &DisplaySettingsWidget::onGPUAdapterIndexChanged); populateGPUAdapters(); - { - std::string post_chain = g_host_interface->GetStringSettingValue("Display", "PostProcessChain"); - if (!post_chain.empty() && !m_ui.postChain->setConfigString(post_chain)) - { - QMessageBox::critical(this, tr("Error"), - tr("The current post-processing chain is invalid, it has been reset. Any changes made will " - "overwrite the existing config.")); - } - } - connect(m_ui.postChain, &PostProcessingChainConfigWidget::chainConfigStringChanged, - [this](const std::string& new_config) { - if (new_config.empty()) - m_host_interface->RemoveSettingValue("Display", "PostProcessChain"); - else - m_host_interface->SetStringSettingValue("Display", "PostProcessChain", new_config.c_str()); - - m_host_interface->applySettings(); - }); - dialog->registerWidgetHelp( m_ui.renderer, tr("Renderer"), Settings::GetRendererDisplayName(Settings::DEFAULT_GPU_RENDERER), tr("Chooses the backend to use for rendering the console/game visuals.
Depending on your system and hardware, " diff --git a/src/duckstation-qt/displaysettingswidget.ui b/src/duckstation-qt/displaysettingswidget.ui index 0e11fbfa8..8deae5e13 100644 --- a/src/duckstation-qt/displaysettingswidget.ui +++ b/src/duckstation-qt/displaysettingswidget.ui @@ -7,7 +7,7 @@ 0 0 448 - 720 + 430 @@ -153,30 +153,6 @@ - - - - Post-Processing Chain - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - @@ -192,14 +168,6 @@ - - - PostProcessingChainConfigWidget - QWidget -
duckstation-qt/postprocessingchainconfigwidget.h
- 1 -
-
diff --git a/src/duckstation-qt/duckstation-qt.vcxproj b/src/duckstation-qt/duckstation-qt.vcxproj index 9598d1651..3dc78fe92 100644 --- a/src/duckstation-qt/duckstation-qt.vcxproj +++ b/src/duckstation-qt/duckstation-qt.vcxproj @@ -58,6 +58,7 @@ + @@ -88,6 +89,7 @@ + @@ -150,6 +152,9 @@ Document + + Document + @@ -178,6 +183,7 @@ + diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 3e62e9bca..ccd342957 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -664,6 +664,8 @@ void MainWindow::connectSignals() [this]() { doSettings(SettingsDialog::Category::DisplaySettings); }); connect(m_ui.actionEnhancementSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::EnhancementSettings); }); + connect(m_ui.actionPostProcessingSettings, &QAction::triggered, + [this]() { doSettings(SettingsDialog::Category::PostProcessingSettings); }); connect(m_ui.actionAudioSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::AudioSettings); }); connect(m_ui.actionAdvancedSettings, &QAction::triggered, diff --git a/src/duckstation-qt/mainwindow.ui b/src/duckstation-qt/mainwindow.ui index f4c5c105c..a229b8b73 100644 --- a/src/duckstation-qt/mainwindow.ui +++ b/src/duckstation-qt/mainwindow.ui @@ -122,6 +122,7 @@ + @@ -359,6 +360,15 @@ &Enhancement Settings...
+ + + + :/icons/applications-graphics.png:/icons/applications-graphics.png + + + &Post-Processing Settings... + + diff --git a/src/duckstation-qt/postprocessingchainconfigwidget.cpp b/src/duckstation-qt/postprocessingchainconfigwidget.cpp index ce4e13e26..7050c0d3f 100644 --- a/src/duckstation-qt/postprocessingchainconfigwidget.cpp +++ b/src/duckstation-qt/postprocessingchainconfigwidget.cpp @@ -10,25 +10,26 @@ PostProcessingChainConfigWidget::PostProcessingChainConfigWidget(QWidget* parent { m_ui.setupUi(this); connectUi(); - updateButtonStates(); + updateButtonStates(std::nullopt); } PostProcessingChainConfigWidget::~PostProcessingChainConfigWidget() = default; void PostProcessingChainConfigWidget::connectUi() { - connect(m_ui.add, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onAddButtonClicked); - connect(m_ui.remove, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onRemoveButtonClicked); - connect(m_ui.clear, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onClearButtonClicked); - connect(m_ui.moveUp, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onMoveUpButtonClicked); - connect(m_ui.moveDown, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onMoveDownButtonClicked); - connect(m_ui.reload, &QPushButton::clicked, this, &PostProcessingChainConfigWidget::onReloadButtonClicked); - connect(m_ui.shaderSettings, &QPushButton::clicked, this, + connect(m_ui.add, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onAddButtonClicked); + connect(m_ui.remove, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onRemoveButtonClicked); + connect(m_ui.clear, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onClearButtonClicked); + connect(m_ui.moveUp, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onMoveUpButtonClicked); + connect(m_ui.moveDown, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onMoveDownButtonClicked); + // connect(m_ui.reload, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onReloadButtonClicked); + connect(m_ui.shaderSettings, &QToolButton::clicked, this, &PostProcessingChainConfigWidget::onShaderConfigButtonClicked); - connect(m_ui.shaders, &QListWidget::itemSelectionChanged, this, &PostProcessingChainConfigWidget::updateButtonStates); + connect(m_ui.shaders, &QListWidget::itemSelectionChanged, this, + &PostProcessingChainConfigWidget::onSelectedShaderChanged); - m_ui.loadPreset->setEnabled(false); - m_ui.savePreset->setEnabled(false); + // m_ui.loadPreset->setEnabled(false); + // m_ui.savePreset->setEnabled(false); } bool PostProcessingChainConfigWidget::setConfigString(const std::string_view& config_string) @@ -40,6 +41,20 @@ bool PostProcessingChainConfigWidget::setConfigString(const std::string_view& co return true; } +void PostProcessingChainConfigWidget::setOptionsButtonVisible(bool visible) +{ + if (visible) + { + m_ui.shaderSettings->setVisible(true); + m_ui.horizontalLayout->addWidget(m_ui.shaderSettings); + } + else + { + m_ui.shaderSettings->setVisible(false); + m_ui.horizontalLayout->removeWidget(m_ui.shaderSettings); + } +} + std::optional PostProcessingChainConfigWidget::getSelectedIndex() const { QList selected_items = m_ui.shaders->selectedItems(); @@ -59,7 +74,7 @@ void PostProcessingChainConfigWidget::updateList() item->setData(Qt::UserRole, QVariant(i)); } - updateButtonStates(); + updateButtonStates(std::nullopt); } void PostProcessingChainConfigWidget::configChanged() @@ -70,12 +85,11 @@ void PostProcessingChainConfigWidget::configChanged() chainConfigStringChanged(m_chain.GetConfigString()); } -void PostProcessingChainConfigWidget::updateButtonStates() +void PostProcessingChainConfigWidget::updateButtonStates(std::optional index) { - std::optional index = getSelectedIndex(); m_ui.remove->setEnabled(index.has_value()); m_ui.clear->setEnabled(!m_chain.IsEmpty()); - m_ui.reload->setEnabled(!m_chain.IsEmpty()); + // m_ui.reload->setEnabled(!m_chain.IsEmpty()); m_ui.shaderSettings->setEnabled(index.has_value() && (index.value() < m_chain.GetStageCount()) && m_chain.GetShaderStage(index.value()).HasOptions()); @@ -106,6 +120,8 @@ void PostProcessingChainConfigWidget::onAddButtonClicked() { QAction* action = menu.addAction(QString::fromStdString(shader)); connect(action, &QAction::triggered, [this, &shader]() { + chainAboutToChange(); + if (!m_chain.AddStage(shader)) { QMessageBox::critical(this, tr("Error"), tr("Failed to add shader. The log may contain more information.")); @@ -131,6 +147,7 @@ void PostProcessingChainConfigWidget::onRemoveButtonClicked() u32 index = item->data(Qt::UserRole).toUInt(); if (index < m_chain.GetStageCount()) { + chainAboutToChange(); m_chain.RemoveStage(index); updateList(); configChanged(); @@ -142,6 +159,7 @@ void PostProcessingChainConfigWidget::onClearButtonClicked() if (QMessageBox::question(this, tr("Question"), tr("Are you sure you want to clear all shader stages?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + chainAboutToChange(); m_chain.ClearStages(); updateList(); configChanged(); @@ -153,6 +171,7 @@ void PostProcessingChainConfigWidget::onMoveUpButtonClicked() std::optional index = getSelectedIndex(); if (index.has_value()) { + chainAboutToChange(); m_chain.MoveStageUp(index.value()); updateList(); configChanged(); @@ -164,6 +183,7 @@ void PostProcessingChainConfigWidget::onMoveDownButtonClicked() std::optional index = getSelectedIndex(); if (index.has_value()) { + chainAboutToChange(); m_chain.MoveStageDown(index.value()); updateList(); configChanged(); @@ -175,8 +195,8 @@ void PostProcessingChainConfigWidget::onShaderConfigButtonClicked() std::optional index = getSelectedIndex(); if (index.has_value() && index.value() < m_chain.GetStageCount()) { - PostProcessingShaderConfigWidget shader_config(this, &m_chain.GetShaderStage(index.value())); - connect(&shader_config, &PostProcessingShaderConfigWidget::configChanged, [this]() { configChanged(); }); + PostProcessingShaderConfigDialog shader_config(this, &m_chain.GetShaderStage(index.value())); + connect(&shader_config, &PostProcessingShaderConfigDialog::configChanged, [this]() { configChanged(); }); shader_config.exec(); } } @@ -185,3 +205,10 @@ void PostProcessingChainConfigWidget::onReloadButtonClicked() { QtHostInterface::GetInstance()->reloadPostProcessingShaders(); } + +void PostProcessingChainConfigWidget::onSelectedShaderChanged() +{ + std::optional index = getSelectedIndex(); + selectedShaderChanged(index.has_value() ? static_cast(index.value()) : -1); + updateButtonStates(index); +} diff --git a/src/duckstation-qt/postprocessingchainconfigwidget.h b/src/duckstation-qt/postprocessingchainconfigwidget.h index 99f787dbc..8645a4c02 100644 --- a/src/duckstation-qt/postprocessingchainconfigwidget.h +++ b/src/duckstation-qt/postprocessingchainconfigwidget.h @@ -19,9 +19,14 @@ public: PostProcessingChainConfigWidget(QWidget* parent); ~PostProcessingChainConfigWidget(); + ALWAYS_INLINE FrontendCommon::PostProcessingChain& getChain() { return m_chain; } + bool setConfigString(const std::string_view& config_string); + void setOptionsButtonVisible(bool visible); Q_SIGNALS: + void selectedShaderChanged(qint32 index); + void chainAboutToChange(); void chainConfigStringChanged(const std::string& new_config_string); private Q_SLOTS: @@ -32,13 +37,14 @@ private Q_SLOTS: void onMoveDownButtonClicked(); void onShaderConfigButtonClicked(); void onReloadButtonClicked(); - void updateButtonStates(); + void onSelectedShaderChanged(); private: void connectUi(); std::optional getSelectedIndex() const; void updateList(); void configChanged(); + void updateButtonStates(std::optional index); Ui::PostProcessingChainConfigWidget m_ui; diff --git a/src/duckstation-qt/postprocessingchainconfigwidget.ui b/src/duckstation-qt/postprocessingchainconfigwidget.ui index 82b38784a..1bfafebaa 100644 --- a/src/duckstation-qt/postprocessingchainconfigwidget.ui +++ b/src/duckstation-qt/postprocessingchainconfigwidget.ui @@ -6,18 +6,46 @@ 0 0 - 497 - 151 + 721 + 194 + + + 0 + 0 + + Form - - - + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + + + + + 0 + 0 + + Add @@ -25,10 +53,19 @@ :/icons/list-add.png:/icons/list-add.png + + Qt::ToolButtonTextBesideIcon + + + + 0 + 0 + + Remove @@ -36,10 +73,19 @@ :/icons/list-remove.png:/icons/list-remove.png + + Qt::ToolButtonTextBesideIcon + + + + 0 + 0 + + Clear @@ -47,10 +93,19 @@ :/icons/edit-clear-16.png:/icons/edit-clear-16.png + + Qt::ToolButtonTextBesideIcon + + + + 0 + 0 + + Move Up @@ -58,10 +113,19 @@ :/icons/go-up-16.png:/icons/go-up-16.png + + Qt::ToolButtonTextBesideIcon + + + + 0 + 0 + + Move Down @@ -69,69 +133,33 @@ :/icons/go-down-16.png:/icons/go-down-16.png + + Qt::ToolButtonTextBesideIcon + + + + 0 + 0 + + - Shader Settings... + Options... - :/icons/preferences-system@2x.png:/icons/preferences-system@2x.png + :/icons/preferences-system.png:/icons/preferences-system.png - - - - - - &Reload Shaders - - - - :/icons/view-refresh.png:/icons/view-refresh.png - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Load Preset - - - - - - - Save Preset + + Qt::ToolButtonTextBesideIcon - - - - - 0 - 50 - - - - diff --git a/src/duckstation-qt/postprocessingsettingswidget.cpp b/src/duckstation-qt/postprocessingsettingswidget.cpp new file mode 100644 index 000000000..d86e51fc1 --- /dev/null +++ b/src/duckstation-qt/postprocessingsettingswidget.cpp @@ -0,0 +1,103 @@ +#include "postprocessingsettingswidget.h" +#include "qthostinterface.h" +#include "settingwidgetbinder.h" +#include + +PostProcessingSettingsWidget::PostProcessingSettingsWidget(QtHostInterface* host_interface, QWidget* parent, + SettingsDialog* settings_dialog) + : QWidget(parent), m_host_interface(host_interface) +{ + m_ui.setupUi(this); + m_ui.widget->setOptionsButtonVisible(false); + m_ui.reload->setEnabled(false); + m_ui.loadPreset->setEnabled(false); + m_ui.savePreset->setEnabled(false); + updateShaderConfigPanel(-1); + connectUi(); + + SettingWidgetBinder::BindWidgetToBoolSetting(host_interface, m_ui.enablePostProcessing, "Display", "PostProcessing", + false); + + std::string post_chain = m_host_interface->GetStringSettingValue("Display", "PostProcessChain"); + if (!post_chain.empty()) + { + if (!m_ui.widget->setConfigString(post_chain)) + { + QMessageBox::critical(this, tr("Error"), + tr("The current post-processing chain is invalid, it has been reset. Any changes made will " + "overwrite the existing config.")); + } + else + { + m_ui.reload->setEnabled(true); + } + } +} + +PostProcessingSettingsWidget::~PostProcessingSettingsWidget() = default; + +void PostProcessingSettingsWidget::connectUi() +{ + connect(m_ui.reload, &QPushButton::clicked, this, &PostProcessingSettingsWidget::onReloadClicked); + connect(m_ui.widget, &PostProcessingChainConfigWidget::chainAboutToChange, this, + &PostProcessingSettingsWidget::onChainAboutToChange); + connect(m_ui.widget, &PostProcessingChainConfigWidget::selectedShaderChanged, this, + &PostProcessingSettingsWidget::onChainSelectedShaderChanged); + connect(m_ui.widget, &PostProcessingChainConfigWidget::chainConfigStringChanged, this, + &PostProcessingSettingsWidget::onConfigChanged); +} + +void PostProcessingSettingsWidget::onChainAboutToChange() +{ + updateShaderConfigPanel(-1); +} + +void PostProcessingSettingsWidget::onChainSelectedShaderChanged(qint32 index) +{ + updateShaderConfigPanel(index); +} + +void PostProcessingSettingsWidget::updateShaderConfigPanel(s32 index) +{ + if (m_shader_config) + { + m_ui.scrollArea->setWidget(nullptr); + m_ui.scrollArea->setVisible(false); + delete m_shader_config; + m_shader_config = nullptr; + } + + if (index < 0) + return; + + FrontendCommon::PostProcessingShader& shader = m_ui.widget->getChain().GetShaderStage(static_cast(index)); + if (!shader.HasOptions()) + return; + + m_shader_config = new PostProcessingShaderConfigWidget(m_ui.scrollArea, &shader); + connect(m_shader_config, &PostProcessingShaderConfigWidget::configChanged, + [this]() { onConfigChanged(m_ui.widget->getChain().GetConfigString()); }); + m_ui.scrollArea->setWidget(m_shader_config); + m_ui.scrollArea->setVisible(true); +} + +void PostProcessingSettingsWidget::onConfigChanged(const std::string& new_config) +{ + if (new_config.empty()) + { + m_host_interface->RemoveSettingValue("Display", "PostProcessChain"); + m_ui.reload->setEnabled(false); + } + else + { + m_host_interface->SetStringSettingValue("Display", "PostProcessChain", new_config.c_str()); + m_ui.reload->setEnabled(true); + } + + m_host_interface->applySettings(); +} + +void PostProcessingSettingsWidget::onReloadClicked() +{ + m_host_interface->reloadPostProcessingShaders(); +} diff --git a/src/duckstation-qt/postprocessingsettingswidget.h b/src/duckstation-qt/postprocessingsettingswidget.h new file mode 100644 index 000000000..5e4f5cbdf --- /dev/null +++ b/src/duckstation-qt/postprocessingsettingswidget.h @@ -0,0 +1,33 @@ +#pragma once +#include "postprocessingchainconfigwidget.h" +#include "postprocessingshaderconfigwidget.h" +#include "ui_postprocessingsettingswidget.h" +#include + +class QtHostInterface; +class SettingsDialog; + +class PostProcessingSettingsWidget : public QWidget +{ + Q_OBJECT + +public: + PostProcessingSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* settings_dialog); + ~PostProcessingSettingsWidget(); + +private Q_SLOTS: + void onChainAboutToChange(); + void onChainSelectedShaderChanged(qint32 index); + void onConfigChanged(const std::string& new_config); + void onReloadClicked(); + +private: + void connectUi(); + void updateShaderConfigPanel(s32 index); + + QtHostInterface* m_host_interface; + + Ui::PostProcessingSettingsWidget m_ui; + + PostProcessingShaderConfigWidget* m_shader_config = nullptr; +}; diff --git a/src/duckstation-qt/postprocessingsettingswidget.ui b/src/duckstation-qt/postprocessingsettingswidget.ui new file mode 100644 index 000000000..4eee78615 --- /dev/null +++ b/src/duckstation-qt/postprocessingsettingswidget.ui @@ -0,0 +1,160 @@ + + + PostProcessingSettingsWidget + + + + 0 + 0 + 683 + 514 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Enable Post Processing + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Reload Shaders + + + + :/icons/view-refresh.png:/icons/view-refresh.png + + + + + + + Load Preset + + + + :/icons/document-save.png:/icons/document-save.png + + + + + + + Save Preset + + + + :/icons/document-open.png:/icons/document-open.png + + + + + + + + + Post Processing Chain + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + 0 + 1 + + + + true + + + + + 0 + 0 + 681 + 390 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + PostProcessingChainConfigWidget + QWidget +
duckstation-qt/postprocessingchainconfigwidget.h
+ 1 +
+
+ + + + +
diff --git a/src/duckstation-qt/postprocessingshaderconfigwidget.cpp b/src/duckstation-qt/postprocessingshaderconfigwidget.cpp index b899bf88f..872ed6cf3 100644 --- a/src/duckstation-qt/postprocessingshaderconfigwidget.cpp +++ b/src/duckstation-qt/postprocessingshaderconfigwidget.cpp @@ -9,10 +9,8 @@ using FrontendCommon::PostProcessingShader; PostProcessingShaderConfigWidget::PostProcessingShaderConfigWidget(QWidget* parent, FrontendCommon::PostProcessingShader* shader) - : QDialog(parent), m_shader(shader) + : QWidget(parent), m_shader(shader) { - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - setWindowTitle(tr("%1 Shader Options").arg(QString::fromStdString(m_shader->GetName()))); createUi(); } @@ -20,7 +18,8 @@ PostProcessingShaderConfigWidget::~PostProcessingShaderConfigWidget() = default; void PostProcessingShaderConfigWidget::createUi() { - QGridLayout* layout = new QGridLayout(this); + m_layout = new QGridLayout(this); + m_layout->setContentsMargins(0, 0, 0, 0); u32 row = 0; for (PostProcessingShader::Option& option : m_shader->GetOptions()) @@ -38,7 +37,7 @@ void PostProcessingShaderConfigWidget::createUi() checkbox->setChecked(option.default_value[0].bool_value); option.value = option.default_value; }); - layout->addWidget(checkbox, row, 0, 1, 3, Qt::AlignLeft); + m_layout->addWidget(checkbox, row, 0, 1, 3, Qt::AlignLeft); row++; } else @@ -57,13 +56,13 @@ void PostProcessingShaderConfigWidget::createUi() label = tr("%1 (%2)").arg(QString::fromStdString(option.ui_name)).arg(tr(suffixes[i])); } - layout->addWidget(new QLabel(label, this), row, 0, 1, 1, Qt::AlignLeft); + m_layout->addWidget(new QLabel(label, this), row, 0, 1, 1, Qt::AlignLeft); QSlider* slider = new QSlider(Qt::Horizontal, this); - layout->addWidget(slider, row, 1, 1, 1, Qt::AlignLeft); + m_layout->addWidget(slider, row, 1, 1, 1, Qt::AlignLeft); QLabel* slider_label = new QLabel(this); - layout->addWidget(slider_label, row, 2, 1, 1, Qt::AlignLeft); + m_layout->addWidget(slider_label, row, 2, 1, 1, Qt::AlignLeft); if (option.type == PostProcessingShader::Option::Type::Int) { @@ -132,16 +131,7 @@ void PostProcessingShaderConfigWidget::createUi() QPushButton* reset_button = new QPushButton(tr("Reset to Defaults"), this); connect(reset_button, &QPushButton::clicked, this, &PostProcessingShaderConfigWidget::onResetToDefaultsClicked); - layout->addWidget(reset_button, row, 0, 1, 2); - - QPushButton* close_button = new QPushButton(tr("Close"), this); - connect(close_button, &QPushButton::clicked, this, &PostProcessingShaderConfigWidget::onCloseClicked); - layout->addWidget(close_button, row, 2, 1, 2); -} - -void PostProcessingShaderConfigWidget::onCloseClicked() -{ - done(0); + m_layout->addWidget(reset_button, row, 0, 1, 1); } void PostProcessingShaderConfigWidget::onResetToDefaultsClicked() @@ -149,3 +139,34 @@ void PostProcessingShaderConfigWidget::onResetToDefaultsClicked() resettingtoDefaults(); configChanged(); } + +PostProcessingShaderConfigDialog::PostProcessingShaderConfigDialog(QWidget* parent, + FrontendCommon::PostProcessingShader* shader) + : QDialog(parent) +{ + setWindowTitle(tr("%1 Shader Options").arg(QString::fromStdString(shader->GetName()))); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + QGridLayout* layout = new QGridLayout(this); + m_widget = new PostProcessingShaderConfigWidget(this, shader); + layout->addWidget(m_widget); + + connect(m_widget, &PostProcessingShaderConfigWidget::configChanged, this, + &PostProcessingShaderConfigDialog::onConfigChanged); + + QPushButton* close_button = new QPushButton(tr("Close"), this); + connect(close_button, &QPushButton::clicked, this, &PostProcessingShaderConfigDialog::onCloseClicked); + m_widget->getLayout()->addWidget(close_button, m_widget->getLayout()->rowCount() - 1, 2, 1, 2); +} + +PostProcessingShaderConfigDialog::~PostProcessingShaderConfigDialog() = default; + +void PostProcessingShaderConfigDialog::onConfigChanged() +{ + configChanged(); +} + +void PostProcessingShaderConfigDialog::onCloseClicked() +{ + done(0); +} diff --git a/src/duckstation-qt/postprocessingshaderconfigwidget.h b/src/duckstation-qt/postprocessingshaderconfigwidget.h index 8453cec77..d253e7346 100644 --- a/src/duckstation-qt/postprocessingshaderconfigwidget.h +++ b/src/duckstation-qt/postprocessingshaderconfigwidget.h @@ -1,8 +1,11 @@ #pragma once #include "frontend-common/postprocessing_shader.h" #include +#include -class PostProcessingShaderConfigWidget : public QDialog +class QGridLayout; + +class PostProcessingShaderConfigWidget : public QWidget { Q_OBJECT @@ -10,17 +13,38 @@ public: PostProcessingShaderConfigWidget(QWidget* parent, FrontendCommon::PostProcessingShader* shader); ~PostProcessingShaderConfigWidget(); + QGridLayout* getLayout() { return m_layout; } + Q_SIGNALS: void configChanged(); void resettingtoDefaults(); private Q_SLOTS: - void onCloseClicked(); void onResetToDefaultsClicked(); -private: +protected: void createUi(); FrontendCommon::PostProcessingShader* m_shader; + QGridLayout* m_layout; +}; + +class PostProcessingShaderConfigDialog : public QDialog +{ + Q_OBJECT + +public: + PostProcessingShaderConfigDialog(QWidget* parent, FrontendCommon::PostProcessingShader* shader); + ~PostProcessingShaderConfigDialog(); + +Q_SIGNALS: + void configChanged(); + +private Q_SLOTS: + void onConfigChanged(); + void onCloseClicked(); + +private: + PostProcessingShaderConfigWidget* m_widget; }; diff --git a/src/duckstation-qt/resources/icons/applications-graphics.png b/src/duckstation-qt/resources/icons/applications-graphics.png new file mode 100644 index 000000000..89db8e081 Binary files /dev/null and b/src/duckstation-qt/resources/icons/applications-graphics.png differ diff --git a/src/duckstation-qt/resources/icons/applications-graphics@2x.png b/src/duckstation-qt/resources/icons/applications-graphics@2x.png new file mode 100644 index 000000000..0b48ef78b Binary files /dev/null and b/src/duckstation-qt/resources/icons/applications-graphics@2x.png differ diff --git a/src/duckstation-qt/resources/resources.qrc b/src/duckstation-qt/resources/resources.qrc index 9e86a91e1..d45321cce 100644 --- a/src/duckstation-qt/resources/resources.qrc +++ b/src/duckstation-qt/resources/resources.qrc @@ -6,6 +6,8 @@ icons/antialias-icon@2x.png icons/applications-development.png icons/applications-development@2x.png + icons/applications-graphics.png + icons/applications-graphics@2x.png icons/applications-internet.png icons/applications-other.png icons/applications-other@2x.png diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp index a834bd624..c594738f4 100644 --- a/src/duckstation-qt/settingsdialog.cpp +++ b/src/duckstation-qt/settingsdialog.cpp @@ -9,6 +9,7 @@ #include "generalsettingswidget.h" #include "hotkeysettingswidget.h" #include "memorycardsettingswidget.h" +#include "postprocessingsettingswidget.h" #include "qthostinterface.h" #include @@ -30,6 +31,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent m_memory_card_settings = new MemoryCardSettingsWidget(host_interface, m_ui.settingsContainer, this); m_display_settings = new DisplaySettingsWidget(host_interface, m_ui.settingsContainer, this); m_enhancement_settings = new EnhancementSettingsWidget(host_interface, m_ui.settingsContainer, this); + m_post_processing_settings = new PostProcessingSettingsWidget(host_interface, m_ui.settingsContainer, this); m_audio_settings = new AudioSettingsWidget(host_interface, m_ui.settingsContainer, this); m_advanced_settings = new AdvancedSettingsWidget(host_interface, m_ui.settingsContainer, this); @@ -41,6 +43,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent m_ui.settingsContainer->insertWidget(static_cast(Category::MemoryCardSettings), m_memory_card_settings); m_ui.settingsContainer->insertWidget(static_cast(Category::DisplaySettings), m_display_settings); m_ui.settingsContainer->insertWidget(static_cast(Category::EnhancementSettings), m_enhancement_settings); + m_ui.settingsContainer->insertWidget(static_cast(Category::PostProcessingSettings), m_post_processing_settings); m_ui.settingsContainer->insertWidget(static_cast(Category::AudioSettings), m_audio_settings); m_ui.settingsContainer->insertWidget(static_cast(Category::AdvancedSettings), m_advanced_settings); @@ -88,6 +91,9 @@ void SettingsDialog::setCategoryHelpTexts() m_category_help_text[static_cast(Category::EnhancementSettings)] = tr("Enhancement Settings
These options control enhancements which can improve visuals compared " "to the original console. Mouse over each option for additional information."); + m_category_help_text[static_cast(Category::PostProcessingSettings)] = + tr("Post-Processing Settings
Post processing allows you to alter the appearance of the image " + "displayed on the screen with various filters. Shaders will be executed in sequence."); m_category_help_text[static_cast(Category::AudioSettings)] = tr("Audio Settings
These options control the audio output of the console. Mouse over an option " "for additional information."); diff --git a/src/duckstation-qt/settingsdialog.h b/src/duckstation-qt/settingsdialog.h index ea855ccf3..e01d8b08f 100644 --- a/src/duckstation-qt/settingsdialog.h +++ b/src/duckstation-qt/settingsdialog.h @@ -15,6 +15,7 @@ class ControllerSettingsWidget; class MemoryCardSettingsWidget; class DisplaySettingsWidget; class EnhancementSettingsWidget; +class PostProcessingSettingsWidget; class AudioSettingsWidget; class AdvancedSettingsWidget; @@ -33,6 +34,7 @@ public: MemoryCardSettings, DisplaySettings, EnhancementSettings, + PostProcessingSettings, AudioSettings, AdvancedSettings, Count @@ -51,6 +53,7 @@ public: EnhancementSettingsWidget* getEnhancementSettingsWidget() const { return m_enhancement_settings; } AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; } AdvancedSettingsWidget* getAdvancedSettingsWidget() const { return m_advanced_settings; } + PostProcessingSettingsWidget* getPostProcessingSettingsWidget() { return m_post_processing_settings; } void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text); bool eventFilter(QObject* object, QEvent* event) override; @@ -76,6 +79,7 @@ private: MemoryCardSettingsWidget* m_memory_card_settings = nullptr; DisplaySettingsWidget* m_display_settings = nullptr; EnhancementSettingsWidget* m_enhancement_settings = nullptr; + PostProcessingSettingsWidget *m_post_processing_settings = nullptr; AudioSettingsWidget* m_audio_settings = nullptr; AdvancedSettingsWidget* m_advanced_settings = nullptr; diff --git a/src/duckstation-qt/settingsdialog.ui b/src/duckstation-qt/settingsdialog.ui index c29ee60de..7bb715045 100644 --- a/src/duckstation-qt/settingsdialog.ui +++ b/src/duckstation-qt/settingsdialog.ui @@ -130,6 +130,15 @@ :/icons/antialias-icon.png:/icons/antialias-icon.png
+ + + Post-Processing Settings + + + + :/icons/applications-graphics.png:/icons/applications-graphics.png + + Audio Settings diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index c4fccc3f0..a65f481df 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -687,7 +687,7 @@ void CommonHostInterface::OnSystemCreated() { HostInterface::OnSystemCreated(); - if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain)) + if (g_settings.display_post_processing && !m_display->SetPostProcessingChain(g_settings.display_post_process_chain)) AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f); } @@ -1967,10 +1967,18 @@ void CommonHostInterface::CheckForSettingsChanges(const Settings& old_settings) UpdateSpeedLimiterState(); } - if (g_settings.display_post_process_chain != old_settings.display_post_process_chain) + if (g_settings.display_post_processing != old_settings.display_post_processing || + g_settings.display_post_process_chain != old_settings.display_post_process_chain) { - if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain)) - AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f); + if (g_settings.display_post_processing) + { + if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain)) + AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f); + } + else + { + m_display->SetPostProcessingChain({}); + } } } @@ -2273,7 +2281,7 @@ void CommonHostInterface::ApplyCheatCode(u32 index) void CommonHostInterface::ReloadPostProcessingShaders() { - if (!m_display) + if (!m_display || !g_settings.display_post_processing) return; if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain))