diff --git a/CMakeLists.txt b/CMakeLists.txt index 4df3db2b..b92dd932 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,8 @@ if(ENABLE_QT_GUI) find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent) qt_standard_project_setup() set(CMAKE_AUTORCC ON) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTOUIC ON) endif() set(AUDIO_CORE src/audio_core/sdl_audio.cpp @@ -546,10 +548,13 @@ set(QT_GUI src/qt_gui/elf_viewer.h src/qt_gui/main_window_themes.cpp src/qt_gui/main_window_themes.h + src/qt_gui/settings_dialog.cpp + src/qt_gui/settings_dialog.h + src/qt_gui/settings_dialog.ui src/qt_gui/main.cpp ${EMULATOR} ${RESOURCE_FILES} - ) +) endif() if (ENABLE_QT_GUI) diff --git a/src/common/config.cpp b/src/common/config.cpp index f676ab94..c105650b 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -114,6 +114,66 @@ bool vkValidationSyncEnabled() { return vkValidationSync; } +void setScreenWidth(u32 width) { + screenWidth = width; +} + +void setScreenHeight(u32 height) { + screenHeight = height; +} + +void setDebugDump(bool enable) { + isDebugDump = enable; +} + +void setShowSplash(bool enable) { + isShowSplash = enable; +} + +void setNullGpu(bool enable) { + isNullGpu = enable; +} + +void setDumpShaders(bool enable) { + shouldDumpShaders = enable; +} + +void setDumpPM4(bool enable) { + shouldDumpPM4 = enable; +} + +void setVkValidation(bool enable) { + vkValidation = enable; +} + +void setVkSyncValidation(bool enable) { + vkValidationSync = enable; +} + +void setRdocEnabled(bool enable) { + rdocEnable = enable; +} + +void setVblankDiv(u32 value) { + vblankDivider = value; +} + +void setFullscreenMode(bool enable) { + isFullscreen = enable; +} + +void setNeoMode(bool enable) { + isNeo = enable; +} + +void setLogType(std::string type) { + logType = type; +} + +void setLogFilter(std::string type) { + logFilter = type; +} + void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { main_window_geometry_x = x; main_window_geometry_y = y; @@ -356,4 +416,22 @@ void save(const std::filesystem::path& path) { file << data; file.close(); } + +void setDefaultValues() { + isNeo = false; + isFullscreen = false; + screenWidth = 1280; + screenHeight = 720; + logFilter = ""; + logType = "async"; + isDebugDump = false; + isShowSplash = false; + isNullGpu = false; + shouldDumpShaders = false; + shouldDumpPM4 = false; + vblankDivider = 1; + vkValidation = false; + rdocEnable = false; +} + } // namespace Config diff --git a/src/common/config.h b/src/common/config.h index 53c88ec9..6174b1e1 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -29,6 +29,24 @@ bool dumpPM4(); bool isRdocEnabled(); u32 vblankDiv(); +void setDebugDump(bool enable); +void setShowSplash(bool enable); +void setNullGpu(bool enable); +void setDumpShaders(bool enable); +void setDumpPM4(bool enable); +void setVblankDiv(u32 value); +void setScreenWidth(u32 width); +void setScreenHeight(u32 height); +void setFullscreenMode(bool enable); +void setNeoMode(bool enable); + +void setLogType(std::string type); +void setLogFilter(std::string type); + +void setVkValidation(bool enable); +void setVkSyncValidation(bool enable); +void setRdocEnabled(bool enable); + bool vkValidationEnabled(); bool vkValidationSyncEnabled(); @@ -64,7 +82,8 @@ std::vector getPkgViewer(); std::vector getElfViewer(); std::vector getRecentFiles(); +void setDefaultValues(); + // settings u32 GetLanguage(); - }; // namespace Config diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index 646433ee..55bd5640 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -15,6 +15,7 @@ #include "core/loader.h" #include "game_install_dialog.h" #include "main_window.h" +#include "settings_dialog.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); @@ -185,6 +186,11 @@ void MainWindow::CreateConnects() { connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this, &MainWindow::StartGame); + connect(ui->settingsButton, &QPushButton::clicked, this, [this]() { + auto settingsDialog = new SettingsDialog(this); + settingsDialog->exec(); + }); + connect(ui->setIconSizeTinyAct, &QAction::triggered, this, [this]() { if (isTableList) { m_game_list_frame->icon_size = diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp new file mode 100644 index 00000000..88c91ef6 --- /dev/null +++ b/src/qt_gui/settings_dialog.cpp @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "settings_dialog.h" +#include "ui_settings_dialog.h" + +SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::SettingsDialog) { + ui->setupUi(this); + ui->tabWidgetSettings->setUsesScrollButtons(false); + const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + + ui->buttonBox->button(QDialogButtonBox::StandardButton::Close)->setFocus(); + + LoadValuesFromConfig(); + + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close); + + connect(ui->buttonBox, &QDialogButtonBox::clicked, this, + [this, config_dir](QAbstractButton* button) { + if (button == ui->buttonBox->button(QDialogButtonBox::Save)) { + Config::save(config_dir / "config.toml"); + QWidget::close(); + } else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) { + Config::save(config_dir / "config.toml"); + } else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) { + Config::setDefaultValues(); + LoadValuesFromConfig(); + } + }); + + connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this, [this]() { + ui->buttonBox->button(QDialogButtonBox::StandardButton::Close)->setFocus(); + }); + + // GPU TAB + { + // TODO: Implement graphics device changing + + connect(ui->widthSpinBox, &QSpinBox::valueChanged, this, + [](int val) { Config::setScreenWidth(val); }); + + connect(ui->heightSpinBox, &QSpinBox::valueChanged, this, + [](int val) { Config::setScreenHeight(val); }); + + connect(ui->vblankSpinBox, &QSpinBox::valueChanged, this, + [](int val) { Config::setVblankDiv(val); }); + + connect(ui->dumpShadersCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setDumpShaders(val); }); + + connect(ui->nullGpuCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setNullGpu(val); }); + + connect(ui->dumpPM4CheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setDumpPM4(val); }); + } + + // GENERAL TAB + { + connect(ui->fullscreenCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setFullscreenMode(val); }); + + connect(ui->showSplashCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setShowSplash(val); }); + + connect(ui->ps4proCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setNeoMode(val); }); + + connect(ui->logTypeComboBox, &QComboBox::currentTextChanged, this, + [](const QString& text) { Config::setLogType(text.toStdString()); }); + + connect(ui->logFilterLineEdit, &QLineEdit::textChanged, this, + [](const QString& text) { Config::setLogFilter(text.toStdString()); }); + } + + // DEBUG TAB + { + connect(ui->debugDump, &QCheckBox::stateChanged, this, + [](int val) { Config::setDebugDump(val); }); + + connect(ui->vkValidationCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setVkValidation(val); }); + + connect(ui->vkSyncValidationCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setVkSyncValidation(val); }); + + connect(ui->rdocCheckBox, &QCheckBox::stateChanged, this, + [](int val) { Config::setRdocEnabled(val); }); + } +} + +void SettingsDialog::LoadValuesFromConfig() { + ui->widthSpinBox->setValue(Config::getScreenWidth()); + ui->heightSpinBox->setValue(Config::getScreenHeight()); + ui->vblankSpinBox->setValue(Config::vblankDiv()); + ui->dumpShadersCheckBox->setChecked(Config::dumpShaders()); + ui->nullGpuCheckBox->setChecked(Config::nullGpu()); + ui->dumpPM4CheckBox->setChecked(Config::dumpPM4()); + + ui->fullscreenCheckBox->setChecked(Config::isFullscreenMode()); + ui->showSplashCheckBox->setChecked(Config::showSplash()); + ui->ps4proCheckBox->setChecked(Config::isNeoMode()); + ui->logTypeComboBox->setCurrentText(QString::fromStdString(Config::getLogType())); + ui->logFilterLineEdit->setText(QString::fromStdString(Config::getLogFilter())); + + ui->debugDump->setChecked(Config::debugDump()); + ui->vkValidationCheckBox->setChecked(Config::vkValidationEnabled()); + ui->vkSyncValidationCheckBox->setChecked(Config::vkValidationSyncEnabled()); + ui->rdocCheckBox->setChecked(Config::isRdocEnabled()); +} + +int SettingsDialog::exec() { + return QDialog::exec(); +} + +SettingsDialog::~SettingsDialog() {} \ No newline at end of file diff --git a/src/qt_gui/settings_dialog.h b/src/qt_gui/settings_dialog.h new file mode 100644 index 00000000..2bffa795 --- /dev/null +++ b/src/qt_gui/settings_dialog.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/config.h" +#include "common/path_util.h" + +namespace Ui { +class SettingsDialog; +} + +class SettingsDialog : public QDialog { + Q_OBJECT +public: + explicit SettingsDialog(QWidget* parent = nullptr); + ~SettingsDialog(); + + int exec() override; + +private: + void LoadValuesFromConfig(); + + std::unique_ptr ui; +}; diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui new file mode 100644 index 00000000..507980eb --- /dev/null +++ b/src/qt_gui/settings_dialog.ui @@ -0,0 +1,646 @@ + + + SettingsDialog + + + Qt::WindowModality::WindowModal + + + + 0 + 0 + 1024 + 768 + + + + + 0 + 0 + + + + Settings + + + + :/images/shadps4.ico:/images/shadps4.ico + + + + + + QFrame::Shape::NoFrame + + + true + + + + true + + + + 0 + 0 + 1006 + 720 + + + + + 0 + 0 + + + + 1 + + + + GPU + + + + + + + + + + Graphics Device + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + + 6 + + + 0 + + + + + + + Width + + + + + + true + + + QAbstractSpinBox::CorrectionMode::CorrectToNearestValue + + + false + + + 0 + + + 9999 + + + 1280 + + + + + + + + + + Height + + + + + + true + + + true + + + QAbstractSpinBox::CorrectionMode::CorrectToNearestValue + + + false + + + 0 + + + 9999 + + + 720 + + + + + + + + + + + + + + 6 + + + 0 + + + + + + + Vblank Divider + + + + + + true + + + true + + + QAbstractSpinBox::CorrectionMode::CorrectToNearestValue + + + false + + + 1 + + + 9999 + + + 1 + + + + + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + 12 + + + 12 + + + + + Additional Settings + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + + + + Enable Shaders Dumping + + + + + + + Enable NULL GPU + + + + + + + Enable PM4 Dumping + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + General + + + + + + + + + + Emulator Settings + + + + + + Enable Fullscreen + + + + + + + Show Splash + + + + + + + Is PS4 Pro + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + + + + + Logger Settings + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Log Type + + + + + + + async + + + + + sync + + + + + + + + + + + + + + 6 + + + 0 + + + + + + + Log Filter + + + + + + + + + + + + + + + + + + + + + + + Additional Settings + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + Debug + + + + + + + + true + + + General + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + + + + + + Enable Debug Dumping + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + Enable Vulkan Validation Layers + + + + + + + Enable Vulkan Synchronization Validation + + + + + + + Enable RenderDoc Debugging + + + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + + + QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::RestoreDefaults|QDialogButtonBox::StandardButton::Save + + + + + + + +