From 7c97c14eba15080eced71f699162e0c825d8d40d Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:37:39 +0200 Subject: [PATCH 1/9] UICommon: Move Wx Graphics Settings functions --- Source/Core/DolphinWX/VideoConfigDiag.cpp | 76 ++++------------------ Source/Core/UICommon/CMakeLists.txt | 1 + Source/Core/UICommon/VideoUtils.cpp | 77 +++++++++++++++++++++++ Source/Core/UICommon/VideoUtils.h | 22 +++++++ 4 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 Source/Core/UICommon/VideoUtils.cpp create mode 100644 Source/Core/UICommon/VideoUtils.h diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp index 687bdf7b33..2dc76ae456 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp @@ -32,6 +32,7 @@ #include "DolphinWX/Main.h" #include "DolphinWX/PostProcessingConfigDiag.h" #include "DolphinWX/WxUtils.h" +#include "UICommon/VideoUtils.h" #include "VideoCommon/PostProcessing.h" #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" @@ -307,69 +308,6 @@ static wxString gpu_texture_decoding_desc = "performance gains in some scenarios, or on systems where the CPU is the " "bottleneck.\n\nIf unsure, leave this unchecked."); -#if !defined(__APPLE__) -// Search for available resolutions - TODO: Move to Common? -static wxArrayString GetListOfResolutions() -{ - wxArrayString retlist; - retlist.Add(_("Auto")); -#ifdef _WIN32 - DWORD iModeNum = 0; - DEVMODE dmi; - ZeroMemory(&dmi, sizeof(dmi)); - dmi.dmSize = sizeof(dmi); - std::vector resos; - - while (EnumDisplaySettings(nullptr, iModeNum++, &dmi) != 0) - { - char res[100]; - sprintf(res, "%dx%d", dmi.dmPelsWidth, dmi.dmPelsHeight); - std::string strRes(res); - // Only add unique resolutions - if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) - { - resos.push_back(strRes); - retlist.Add(StrToWxStr(res)); - } - ZeroMemory(&dmi, sizeof(dmi)); - } -#elif defined(HAVE_XRANDR) && HAVE_XRANDR - std::vector resos; - main_frame->m_xrr_config->AddResolutions(resos); - for (auto res : resos) - retlist.Add(StrToWxStr(res)); -#elif defined(__APPLE__) - CFArrayRef modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), nullptr); - for (CFIndex i = 0; i < CFArrayGetCount(modes); i++) - { - std::stringstream res; - CGDisplayModeRef mode; - CFStringRef encoding; - size_t w, h; - bool is32; - - mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); - w = CGDisplayModeGetWidth(mode); - h = CGDisplayModeGetHeight(mode); - encoding = CGDisplayModeCopyPixelEncoding(mode); - is32 = CFEqual(encoding, CFSTR(IO32BitDirectPixels)); - CFRelease(encoding); - - if (!is32) - continue; - if (CGDisplayModeGetIOFlags(mode) & kDisplayModeStretchedFlag) - continue; - - res << w << "x" << h; - - retlist.Add(res.str()); - } - CFRelease(modes); -#endif - return retlist; -} -#endif - VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title) : wxDialog(parent, wxID_ANY, wxString::Format(_("Dolphin %s Graphics Configuration"), wxGetTranslation(StrToWxStr(title)))), @@ -436,7 +374,17 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title) #if !defined(__APPLE__) // display resolution { - wxArrayString res_list = GetListOfResolutions(); + wxArrayString res_list; + res_list.Add(_("Auto")); +#if defined(HAVE_XRANDR) && HAVE_XRANDR + const auto resolutions = VideoUtils::GetAvailableResolutions(main_frame->m_xrr_config); +#else + const auto resolutions = VideoUtils::GetAvailableResolutions(nullptr); +#endif + + for (const auto& res : resolutions) + res_list.Add(res); + if (res_list.empty()) res_list.Add(_("")); label_display_resolution = diff --git a/Source/Core/UICommon/CMakeLists.txt b/Source/Core/UICommon/CMakeLists.txt index 36648bbe7c..838dfb8775 100644 --- a/Source/Core/UICommon/CMakeLists.txt +++ b/Source/Core/UICommon/CMakeLists.txt @@ -3,6 +3,7 @@ set(SRCS Disassembler.cpp UICommon.cpp USBUtils.cpp + VideoUtils.cpp ) if(USE_X11) diff --git a/Source/Core/UICommon/VideoUtils.cpp b/Source/Core/UICommon/VideoUtils.cpp new file mode 100644 index 0000000000..c21cb93b8f --- /dev/null +++ b/Source/Core/UICommon/VideoUtils.cpp @@ -0,0 +1,77 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "UICommon/VideoUtils.h" + +#include "Common/Assert.h" +#include "VideoCommon/VideoConfig.h" + +#if defined(HAVE_XRANDR) && HAVE_XRANDR +#include "UICommon/X11Utils.h" +#endif + +namespace VideoUtils +{ +#if !defined(__APPLE__) +std::vector GetAvailableResolutions(X11Utils::XRRConfiguration* xrr_config) +{ + std::vector resos; +#ifdef _WIN32 + DWORD iModeNum = 0; + DEVMODE dmi; + ZeroMemory(&dmi, sizeof(dmi)); + dmi.dmSize = sizeof(dmi); + + while (EnumDisplaySettings(nullptr, iModeNum++, &dmi) != 0) + { + char res[100]; + sprintf(res, "%dx%d", dmi.dmPelsWidth, dmi.dmPelsHeight); + std::string strRes(res); + // Only add unique resolutions + if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) + { + resos.push_back(strRes); + } + ZeroMemory(&dmi, sizeof(dmi)); + } +#elif defined(HAVE_XRANDR) && HAVE_XRANDR + xrr_config->AddResolutions(resos); +#endif + return resos; +} +#endif + +std::vector GetAvailableAntialiasingModes(int& msaa_modes) +{ + std::vector modes; + const auto& aa_modes = g_Config.backend_info.AAModes; + const bool supports_ssaa = g_Config.backend_info.bSupportsSSAA; + msaa_modes = 0; + + for (const auto mode : aa_modes) + { + if (mode == 1) + { + modes.push_back("None"); + _assert_msg_(VIDEO, !supports_ssaa || msaa_modes == 0, "SSAA setting won't work correctly"); + } + else + { + modes.push_back(std::to_string(mode) + "x MSAA"); + msaa_modes++; + } + } + + if (supports_ssaa) + { + for (const auto mode : aa_modes) + { + if (mode != 1) + modes.push_back(std::to_string(mode) + "x SSAA"); + } + } + + return modes; +} +} diff --git a/Source/Core/UICommon/VideoUtils.h b/Source/Core/UICommon/VideoUtils.h new file mode 100644 index 0000000000..096abbe7b1 --- /dev/null +++ b/Source/Core/UICommon/VideoUtils.h @@ -0,0 +1,22 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +namespace X11Utils +{ +class XRRConfiguration; +} + +namespace VideoUtils +{ +#if !defined(__APPLE__) +std::vector GetAvailableResolutions(X11Utils::XRRConfiguration* xrr_config); +#endif + +std::vector GetAvailableAntialiasingModes(int& m_msaa_modes); +} From 1b1ab3119a743035b6e1877a97e3a4824d4caf38 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:39:59 +0200 Subject: [PATCH 2/9] Qt: Add Graphics option to tool bar --- Source/Core/DolphinQt2/ToolBar.cpp | 4 ++++ Source/Core/DolphinQt2/ToolBar.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Source/Core/DolphinQt2/ToolBar.cpp b/Source/Core/DolphinQt2/ToolBar.cpp index 0cea6f151f..cc5992ca52 100644 --- a/Source/Core/DolphinQt2/ToolBar.cpp +++ b/Source/Core/DolphinQt2/ToolBar.cpp @@ -83,6 +83,9 @@ void ToolBar::MakeActions() m_config_action = addAction(tr("Settings"), this, SIGNAL(SettingsPressed())); widgetForAction(m_config_action)->setMinimumWidth(button_width); + m_graphics_action = addAction(tr("Graphics"), this, SIGNAL(GraphicsPressed())); + widgetForAction(m_graphics_action)->setMinimumWidth(button_width); + m_controllers_action = addAction(tr("Controllers"), this, SIGNAL(ControllersPressed())); widgetForAction(m_controllers_action)->setMinimumWidth(button_width); m_controllers_action->setEnabled(true); @@ -98,4 +101,5 @@ void ToolBar::UpdateIcons() m_screenshot_action->setIcon(Resources::GetScaledThemeIcon("screenshot")); m_config_action->setIcon(Resources::GetScaledThemeIcon("config")); m_controllers_action->setIcon(Resources::GetScaledThemeIcon("classic")); + m_graphics_action->setIcon(Resources::GetScaledThemeIcon("graphics")); } diff --git a/Source/Core/DolphinQt2/ToolBar.h b/Source/Core/DolphinQt2/ToolBar.h index 1150a26f81..179c0f5729 100644 --- a/Source/Core/DolphinQt2/ToolBar.h +++ b/Source/Core/DolphinQt2/ToolBar.h @@ -30,6 +30,7 @@ signals: void SettingsPressed(); void ControllersPressed(); + void GraphicsPressed(); private: void MakeActions(); @@ -43,4 +44,5 @@ private: QAction* m_screenshot_action; QAction* m_config_action; QAction* m_controllers_action; + QAction* m_graphics_action; }; From 908e1e9abaf0bab44acb999f37bd472ec007488c Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:42:12 +0200 Subject: [PATCH 3/9] Qt: Implement graphics window and controls --- Source/Core/DolphinQt2/CMakeLists.txt | 12 ++ .../Config/Graphics/GraphicsBool.cpp | 49 ++++++++ .../DolphinQt2/Config/Graphics/GraphicsBool.h | 41 +++++++ .../Config/Graphics/GraphicsChoice.cpp | 28 +++++ .../Config/Graphics/GraphicsChoice.h | 24 ++++ .../Config/Graphics/GraphicsSlider.cpp | 25 ++++ .../Config/Graphics/GraphicsSlider.h | 23 ++++ .../Config/Graphics/GraphicsWidget.cpp | 23 ++++ .../Config/Graphics/GraphicsWidget.h | 34 ++++++ .../Config/Graphics/GraphicsWindow.cpp | 113 ++++++++++++++++++ .../Config/Graphics/GraphicsWindow.h | 47 ++++++++ Source/Core/DolphinQt2/MainWindow.cpp | 28 +++++ Source/Core/DolphinQt2/MainWindow.h | 3 + 13 files changed, 450 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt index 35bbb61284..8227cf5f6f 100644 --- a/Source/Core/DolphinQt2/CMakeLists.txt +++ b/Source/Core/DolphinQt2/CMakeLists.txt @@ -1,9 +1,12 @@ find_package(Qt5Widgets REQUIRED) +find_Package(Qt5Gui REQUIRED) set_property(TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_FEATURES "") message(STATUS "Found Qt version ${Qt5Core_VERSION}") include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) + add_definitions(-DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII) set(CMAKE_AUTOMOC ON) @@ -23,6 +26,15 @@ set(SRCS WiiUpdate.h Config/ControllersWindow.cpp Config/FilesystemWidget.cpp + Config/Graphics/AdvancedWidget.cpp + Config/Graphics/EnhancementsWidget.cpp + Config/Graphics/GeneralWidget.cpp + Config/Graphics/HacksWidget.cpp + Config/Graphics/GraphicsBool.cpp + Config/Graphics/GraphicsChoice.cpp + Config/Graphics/GraphicsSlider.cpp + Config/Graphics/GraphicsWidget.cpp + Config/Graphics/GraphicsWindow.cpp Config/InfoWidget.cpp Config/Mapping/GCKeyboardEmu.cpp Config/Mapping/GCPadEmu.cpp diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp new file mode 100644 index 0000000000..dae8431c0b --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp @@ -0,0 +1,49 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" + +#include "Core/Config/Config.h" + +#include + +GraphicsBool::GraphicsBool(const QString& label, const Config::ConfigInfo& setting, + bool reverse) + : QCheckBox(label), m_setting(setting), m_reverse(reverse) +{ + connect(this, &QCheckBox::toggled, this, &GraphicsBool::Update); + setChecked(Config::Get(m_setting) ^ reverse); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsBool::Update() +{ + Config::SetBaseOrCurrent(m_setting, static_cast(isChecked() ^ m_reverse)); +} + +GraphicsBoolEx::GraphicsBoolEx(const QString& label, const Config::ConfigInfo& setting, + bool reverse) + : QRadioButton(label), m_setting(setting), m_reverse(reverse) +{ + connect(this, &QCheckBox::toggled, this, &GraphicsBoolEx::Update); + setChecked(Config::Get(m_setting) ^ reverse); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsBoolEx::Update() +{ + Config::SetBaseOrCurrent(m_setting, static_cast(isChecked() ^ m_reverse)); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h new file mode 100644 index 0000000000..461a2598b1 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h @@ -0,0 +1,41 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsBool : public QCheckBox +{ + Q_OBJECT +public: + GraphicsBool(const QString& label, const Config::ConfigInfo& setting, bool reverse = false); + +private: + void Update(); + + const Config::ConfigInfo& m_setting; + bool m_reverse; +}; + +class GraphicsBoolEx : public QRadioButton +{ + Q_OBJECT +public: + GraphicsBoolEx(const QString& label, const Config::ConfigInfo& setting, + bool reverse = false); + +private: + void Update(); + + const Config::ConfigInfo& m_setting; + bool m_reverse; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp new file mode 100644 index 0000000000..9fbc537894 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp @@ -0,0 +1,28 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" + +#include "Core/Config/Config.h" + +GraphicsChoice::GraphicsChoice(const QStringList& options, const Config::ConfigInfo& setting) + : m_setting(setting) +{ + addItems(options); + connect(this, static_cast(&QComboBox::currentIndexChanged), this, + &GraphicsChoice::Update); + setCurrentIndex(Config::Get(m_setting)); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsChoice::Update(int choice) +{ + Config::SetBaseOrCurrent(m_setting, choice); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h new file mode 100644 index 0000000000..31f5e7e1fe --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h @@ -0,0 +1,24 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsChoice : public QComboBox +{ +public: + GraphicsChoice(const QStringList& options, const Config::ConfigInfo& setting); + +private: + void Update(int choice); + + const Config::ConfigInfo& m_setting; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp new file mode 100644 index 0000000000..b15f3018d2 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp @@ -0,0 +1,25 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsSlider.h" + +#include "Core/Config/Config.h" + +GraphicsSlider::GraphicsSlider(int minimum, int maximum, const Config::ConfigInfo& setting, + int tick) + : QSlider(Qt::Horizontal), m_setting(setting) +{ + setMinimum(minimum); + setMaximum(maximum); + setTickInterval(tick); + + setValue(Config::Get(setting)); + + connect(this, &GraphicsSlider::valueChanged, this, &GraphicsSlider::Update); +} + +void GraphicsSlider::Update(int value) +{ + Config::SetBaseOrCurrent(m_setting, value); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h new file mode 100644 index 0000000000..3fd54dd664 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h @@ -0,0 +1,23 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsSlider : public QSlider +{ +public: + GraphicsSlider(int minimum, int maximum, const Config::ConfigInfo& setting, int tick = 0); + void Update(int value); + +private: + const Config::ConfigInfo& m_setting; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp new file mode 100644 index 0000000000..94e316f364 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp @@ -0,0 +1,23 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +#include +#include +#include +#include +#include + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" + +GraphicsWidget::GraphicsWidget(GraphicsWindow* parent) +{ + parent->RegisterWidget(this); +} + +void GraphicsWidget::AddDescription(QWidget* widget, const char* description) +{ + emit DescriptionAdded(widget, description); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h new file mode 100644 index 0000000000..04e5a1afeb --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h @@ -0,0 +1,34 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +class GraphicsWindow; +class QFormLayout; +class QGroupBox; +class QLabel; + +class GraphicsWidget : public QWidget +{ + Q_OBJECT +public: + explicit GraphicsWidget(GraphicsWindow* parent); + +signals: + void DescriptionAdded(QWidget* widget, const char* description); + +protected: + void AddWidget(const QString& name, QWidget* widget); + void AddWidget(QWidget* widget); + + void AddDescription(QWidget* widget, const char* description); + + virtual void LoadSettings() = 0; + virtual void SaveSettings() = 0; + +private: + QFormLayout* m_main_layout; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp new file mode 100644 index 0000000000..f32623f22e --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp @@ -0,0 +1,113 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" + +#include +#include +#include +#include +#include +#include + +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/AdvancedWidget.h" +#include "DolphinQt2/Config/Graphics/EnhancementsWidget.h" +#include "DolphinQt2/Config/Graphics/GeneralWidget.h" +#include "DolphinQt2/Config/Graphics/HacksWidget.h" +#include "DolphinQt2/MainWindow.h" + +GraphicsWindow::GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindow* parent) + : QDialog(parent), m_xrr_config(xrr_config) +{ + CreateMainLayout(); + ConnectWidgets(); + + setWindowTitle(tr("Graphics")); + setWindowFlags(Qt::Window); + + OnBackendChanged(QString::fromStdString(SConfig::GetInstance().m_strVideoBackend)); + + connect(parent, &MainWindow::EmulationStarted, this, &GraphicsWindow::EmulationStarted); + connect(parent, &MainWindow::EmulationStopped, this, &GraphicsWindow::EmulationStopped); +} + +void GraphicsWindow::CreateMainLayout() +{ + auto* main_layout = new QVBoxLayout(); + auto* description_box = new QGroupBox(tr("Description")); + auto* description_layout = new QVBoxLayout(); + m_description = + new QLabel(tr("Move the mouse pointer over an option to display a detailed description.")); + m_tab_widget = new QTabWidget(); + m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok); + + description_box->setLayout(description_layout); + description_box->setMinimumHeight(205); + + m_description->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_description->setWordWrap(true); + m_description->setAlignment(Qt::AlignTop | Qt::AlignLeft); + + description_layout->addWidget(m_description); + + main_layout->addWidget(m_tab_widget); + main_layout->addWidget(description_box); + main_layout->addWidget(m_button_box); + + auto* general_widget = new GeneralWidget(m_xrr_config, this); + auto* enhancements_widget = new EnhancementsWidget(this); + auto* hacks_widget = new HacksWidget(this); + auto* advanced_widget = new AdvancedWidget(this); + + connect(general_widget, &GeneralWidget::BackendChanged, this, &GraphicsWindow::OnBackendChanged); + + m_tab_widget->addTab(general_widget, tr("General")); + m_tab_widget->addTab(enhancements_widget, tr("Enhancements")); + m_tab_widget->addTab(hacks_widget, tr("Hacks")); + m_tab_widget->addTab(advanced_widget, tr("Advanced")); + + setLayout(main_layout); +} + +void GraphicsWindow::ConnectWidgets() +{ + connect(m_button_box, &QDialogButtonBox::accepted, this, &QDialog::accept); +} + +void GraphicsWindow::OnBackendChanged(const QString& backend) +{ + setWindowTitle(tr("Dolphin %1 Graphics Configuration").arg(backend)); + emit BackendChanged(backend); +} + +void GraphicsWindow::RegisterWidget(GraphicsWidget* widget) +{ + connect(widget, &GraphicsWidget::DescriptionAdded, this, &GraphicsWindow::OnDescriptionAdded); +} + +void GraphicsWindow::OnDescriptionAdded(QWidget* widget, const char* description) +{ + m_widget_descriptions[widget] = description; + widget->installEventFilter(this); +} + +bool GraphicsWindow::eventFilter(QObject* object, QEvent* event) +{ + if (!m_widget_descriptions.contains(object)) + return false; + if (event->type() == QEvent::Enter) + { + m_description->setText(tr(m_widget_descriptions[object])); + return false; + } + + if (event->type() == QEvent::Leave) + { + m_description->setText( + tr("Move the mouse pointer over an option to display a detailed description.")); + } + + return false; +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h new file mode 100644 index 0000000000..1d3748e62d --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h @@ -0,0 +1,47 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +class GraphicsWidget; +class MainWindow; +class QLabel; +class QTabWidget; +class QDialogButtonBox; + +namespace X11Utils +{ +class XRRConfiguration; +} + +class GraphicsWindow final : public QDialog +{ + Q_OBJECT +public: + explicit GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindow* parent); + + void RegisterWidget(GraphicsWidget* widget); + bool eventFilter(QObject* object, QEvent* event) override; +signals: + void BackendChanged(const QString& backend); + void EmulationStarted(); + void EmulationStopped(); + +private: + void CreateMainLayout(); + void ConnectWidgets(); + void OnBackendChanged(const QString& backend); + void OnDescriptionAdded(QWidget* widget, const char* description); + + QTabWidget* m_tab_widget; + QLabel* m_description; + QDialogButtonBox* m_button_box; + + X11Utils::XRRConfiguration* m_xrr_config; + + QHash m_widget_descriptions; +}; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index de38910faa..da38a9dda0 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include @@ -30,6 +31,8 @@ #include "DolphinQt2/AboutDialog.h" #include "DolphinQt2/Config/ControllersWindow.h" + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" #include "DolphinQt2/Config/Mapping/MappingWindow.h" #include "DolphinQt2/Config/SettingsWindow.h" #include "DolphinQt2/Host.h" @@ -44,6 +47,11 @@ #include "UICommon/UICommon.h" +#if defined(HAVE_XRANDR) && HAVE_XRANDR +#include +#include "UICommon/X11Utils.h" +#endif + MainWindow::MainWindow() : QMainWindow(nullptr) { setWindowTitle(QString::fromStdString(scm_rev_str)); @@ -131,9 +139,21 @@ void MainWindow::CreateComponents() connect(this, &MainWindow::EmulationStopped, m_settings_window, &SettingsWindow::EmulationStopped); +#if defined(HAVE_XRANDR) && HAVE_XRANDR + m_graphics_window = new GraphicsWindow( + new X11Utils::XRRConfiguration( + static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( + "display", windowHandle())), + winId()), + this); +#else + m_graphics_window = new GraphicsWindow(nullptr, this); +#endif + InstallHotkeyFilter(m_hotkey_window); InstallHotkeyFilter(m_controllers_window); InstallHotkeyFilter(m_settings_window); + InstallHotkeyFilter(m_graphics_window); } void MainWindow::ConnectMenuBar() @@ -212,6 +232,7 @@ void MainWindow::ConnectToolBar() connect(m_tool_bar, &ToolBar::ScreenShotPressed, this, &MainWindow::ScreenShot); connect(m_tool_bar, &ToolBar::SettingsPressed, this, &MainWindow::ShowSettingsWindow); connect(m_tool_bar, &ToolBar::ControllersPressed, this, &MainWindow::ShowControllersWindow); + connect(m_tool_bar, &ToolBar::GraphicsPressed, this, &MainWindow::ShowGraphicsWindow); connect(this, &MainWindow::EmulationStarted, m_tool_bar, &ToolBar::EmulationStarted); connect(this, &MainWindow::EmulationPaused, m_tool_bar, &ToolBar::EmulationPaused); @@ -476,6 +497,13 @@ void MainWindow::ShowHotkeyDialog() m_hotkey_window->activateWindow(); } +void MainWindow::ShowGraphicsWindow() +{ + m_graphics_window->show(); + m_graphics_window->raise(); + m_graphics_window->activateWindow(); +} + void MainWindow::StateLoad() { QString path = QFileDialog::getOpenFileName(this, tr("Select a File"), QDir::currentPath(), diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index 0cd572790d..48fbf9e3f2 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -19,6 +19,7 @@ class MappingWindow; class SettingsWindow; class ControllersWindow; class DragEnterEvent; +class GraphicsWindow; class MainWindow final : public QMainWindow { @@ -82,6 +83,7 @@ private: void ShowSettingsWindow(); void ShowControllersWindow(); + void ShowGraphicsWindow(); void ShowAboutDialog(); void ShowHotkeyDialog(); @@ -101,4 +103,5 @@ private: ControllersWindow* m_controllers_window; SettingsWindow* m_settings_window; MappingWindow* m_hotkey_window; + GraphicsWindow* m_graphics_window; }; From b6690b274b88cea7277e32c8170fd142239bdc60 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:43:01 +0200 Subject: [PATCH 4/9] Qt/GraphicsSettings: Implement advanced tab --- .../Config/Graphics/AdvancedWidget.cpp | 208 ++++++++++++++++++ .../Config/Graphics/AdvancedWidget.h | 47 ++++ 2 files changed, 255 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.h diff --git a/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp new file mode 100644 index 0000000000..3f55dc75d4 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp @@ -0,0 +1,208 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/AdvancedWidget.h" + +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "VideoCommon/VideoConfig.h" + +AdvancedWidget::AdvancedWidget(GraphicsWindow* parent) : GraphicsWidget(parent) +{ + CreateWidgets(); + LoadSettings(); + ConnectWidgets(); + AddDescriptions(); + + connect(parent, &GraphicsWindow::BackendChanged, this, &AdvancedWidget::OnBackendChanged); + connect(parent, &GraphicsWindow::EmulationStarted, [this] { OnEmulationStateChanged(true); }); + connect(parent, &GraphicsWindow::EmulationStopped, [this] { OnEmulationStateChanged(false); }); + + OnBackendChanged(); +} + +void AdvancedWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + // Debugging + auto* debugging_box = new QGroupBox(tr("Debugging")); + auto* debugging_layout = new QGridLayout(); + debugging_box->setLayout(debugging_layout); + + m_enable_wireframe = new GraphicsBool(tr("Enable Wireframe"), Config::GFX_ENABLE_WIREFRAME); + m_show_statistics = new GraphicsBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS); + m_enable_format_overlay = + new GraphicsBool(tr("Texture Format Overlay"), Config::GFX_TEXFMT_OVERLAY_ENABLE); + m_enable_api_validation = + new GraphicsBool(tr("Enable API Validation Layers"), Config::GFX_ENABLE_VALIDATION_LAYER); + + debugging_layout->addWidget(m_enable_wireframe, 0, 0); + debugging_layout->addWidget(m_show_statistics, 0, 1); + debugging_layout->addWidget(m_enable_format_overlay, 1, 0); + debugging_layout->addWidget(m_enable_api_validation, 1, 1); + + // Utility + auto* utility_box = new QGroupBox(tr("Utility")); + auto* utility_layout = new QGridLayout(); + utility_box->setLayout(utility_layout); + + m_dump_textures = new GraphicsBool(tr("Dump Textures"), Config::GFX_DUMP_TEXTURES); + m_load_custom_textures = new GraphicsBool(tr("Load Custom Textures"), Config::GFX_HIRES_TEXTURES); + m_prefetch_custom_textures = + new GraphicsBool(tr("Prefetch Custom Textures"), Config::GFX_CACHE_HIRES_TEXTURES); + m_use_fullres_framedumps = new GraphicsBool(tr("Full Resolution Frame Dumps"), + Config::GFX_INTERNAL_RESOLUTION_FRAME_DUMPS); + m_dump_efb_target = new GraphicsBool(tr("Dump EFB Target"), Config::GFX_DUMP_EFB_TARGET); + m_enable_freelook = new GraphicsBool(tr("Free Look"), Config::GFX_FREE_LOOK); + m_dump_use_ffv1 = new GraphicsBool(tr("Frame Dumps Use FFV1"), Config::GFX_USE_FFV1); + + utility_layout->addWidget(m_dump_textures, 0, 0); + utility_layout->addWidget(m_load_custom_textures, 0, 1); + utility_layout->addWidget(m_prefetch_custom_textures, 1, 0); + utility_layout->addWidget(m_use_fullres_framedumps, 1, 1); + utility_layout->addWidget(m_dump_efb_target, 2, 0); + utility_layout->addWidget(m_enable_freelook, 2, 1); +#if defined(HAVE_FFMPEG) + utility_layout->addWidget(m_dump_use_ffv1, 3, -1); +#endif + + // Misc. + auto* misc_box = new QGroupBox(tr("Misc.")); + auto* misc_layout = new QGridLayout(); + misc_box->setLayout(misc_layout); + + m_enable_cropping = new GraphicsBool(tr("Crop"), Config::GFX_CROP); + m_enable_prog_scan = + new GraphicsBool(tr("Enable Progressive Scan"), Config::GFX_HACK_FORCE_PROGRESSIVE); + + misc_layout->addWidget(m_enable_cropping, 0, 0); + misc_layout->addWidget(m_enable_prog_scan, 0, 1); + +#ifdef _WIN32 + m_borderless_fullscreen = + new GraphicsBool(tr("Borderless Fullscreen"), Config::GFX_BORDERLESS_FULLSCREEN); + + misc_layout->addWidget(m_borderless_fullscreen, 1, -1); +#endif + + main_layout->addWidget(debugging_box); + main_layout->addWidget(utility_box); + main_layout->addWidget(misc_box); + + setLayout(main_layout); +} + +void AdvancedWidget::ConnectWidgets() +{ + connect(m_load_custom_textures, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings); +} + +void AdvancedWidget::LoadSettings() +{ + m_prefetch_custom_textures->setEnabled(Config::Get(Config::GFX_HIRES_TEXTURES)); +} + +void AdvancedWidget::SaveSettings() +{ + const auto hires_enabled = Config::Get(Config::GFX_HIRES_TEXTURES); + m_prefetch_custom_textures->setEnabled(hires_enabled); +} + +void AdvancedWidget::OnBackendChanged() +{ + const auto supports_fr_framedumps = g_Config.backend_info.bSupportsInternalResolutionFrameDumps; + m_use_fullres_framedumps->setEnabled(supports_fr_framedumps); +} + +void AdvancedWidget::OnEmulationStateChanged(bool running) +{ + m_enable_prog_scan->setEnabled(!running); +} + +void AdvancedWidget::AddDescriptions() +{ + static const char* TR_WIREFRAME_DESCRIPTION = + QT_TR_NOOP("Render the scene as a wireframe.\n\nIf unsure, leave this unchecked."); + static const char* TR_SHOW_STATS_DESCRIPTION = + QT_TR_NOOP("Show various rendering statistics.\n\nIf unsure, leave this unchecked."); + static const char* TR_TEXTURE_FORMAT_DECRIPTION = + QT_TR_NOOP("Modify textures to show the format they're encoded in. Needs an emulation reset " + "in most cases.\n\nIf unsure, leave this unchecked."); + static const char* TR_VALIDATION_LAYER_DESCRIPTION = + QT_TR_NOOP("Enables validation of API calls made by the video backend, which may assist in " + "debugging graphical issues.\n\nIf unsure, leave this unchecked."); + static const char* TR_DUMP_TEXTURE_DESCRIPTION = + QT_TR_NOOP("Dump decoded game textures to User/Dump/Textures//.\n\nIf unsure, leave " + "this unchecked."); + static const char* TR_LOAD_CUSTOM_TEXTURE_DESCRIPTION = QT_TR_NOOP( + "Load custom textures from User/Load/Textures//.\n\nIf unsure, leave this " + "unchecked."); + static const char* TR_CACHE_CUSTOM_TEXTURE_DESCRIPTION = + QT_TR_NOOP("Cache custom textures to system RAM on startup.\nThis can require exponentially " + "more RAM but fixes possible stuttering.\n\nIf unsure, leave this unchecked."); + static const char* TR_DUMP_EFB_DESCRIPTION = + QT_TR_NOOP("Dump the contents of EFB copies to User/Dump/Textures/.\n\nIf unsure, leave this " + "unchecked."); + static const char* TR_INTERNAL_RESOLUTION_FRAME_DUMPING_DESCRIPTION = QT_TR_NOOP( + "Create frame dumps and screenshots at the internal resolution of the renderer, rather than " + "the size of the window it is displayed within. If the aspect ratio is widescreen, the " + "output " + "image will be scaled horizontally to preserve the vertical resolution.\n\nIf unsure, leave " + "this unchecked."); +#if defined(HAVE_FFMPEG) + static const char* TR_USE_FFV1_DESCRIPTION = + QT_TR_NOOP("Encode frame dumps using the FFV1 codec.\n\nIf unsure, leave this unchecked."); +#endif + static const char* TR_FREE_LOOK_DESCRIPTION = QT_TR_NOOP( + "This feature allows you to change the game's camera.\nMove the mouse while holding the " + "right " + "mouse button to pan and while holding the middle button to move.\nHold SHIFT and press " + "one of " + "the WASD keys to move the camera by a certain step distance (SHIFT+2 to move faster and " + "SHIFT+1 to move slower). Press SHIFT+R to reset the camera and SHIFT+F to reset the " + "speed.\n\nIf unsure, leave this unchecked."); + static const char* TR_CROPPING_DESCRIPTION = + QT_TR_NOOP("Crop the picture from its native aspect ratio to 4:3 or " + "16:9.\n\nIf unsure, leave this unchecked."); + static const char* TR_PROGRESSIVE_SCAN_DESCRIPTION = QT_TR_NOOP( + "Enables progressive scan if supported by the emulated software.\nMost games don't " + "care about this.\n\nIf unsure, leave this unchecked."); +#ifdef _WIN32 + static const char* TR_BORDERLESS_FULLSCREEN_DESCRIPTION = QT_TR_NOOP( + "Implement fullscreen mode with a borderless window spanning the whole screen instead of " + "using " + "exclusive mode.\nAllows for faster transitions between fullscreen and windowed mode, but " + "slightly increases input latency, makes movement less smooth and slightly decreases " + "performance.\nExclusive mode is required for Nvidia 3D Vision to work in the Direct3D " + "backend.\n\nIf unsure, leave this unchecked."); +#endif + + AddDescription(m_enable_wireframe, TR_WIREFRAME_DESCRIPTION); + AddDescription(m_show_statistics, TR_SHOW_STATS_DESCRIPTION); + AddDescription(m_enable_format_overlay, TR_TEXTURE_FORMAT_DECRIPTION); + AddDescription(m_enable_api_validation, TR_VALIDATION_LAYER_DESCRIPTION); + AddDescription(m_dump_textures, TR_DUMP_TEXTURE_DESCRIPTION); + AddDescription(m_load_custom_textures, TR_LOAD_CUSTOM_TEXTURE_DESCRIPTION); + AddDescription(m_prefetch_custom_textures, TR_CACHE_CUSTOM_TEXTURE_DESCRIPTION); + AddDescription(m_dump_efb_target, TR_DUMP_EFB_DESCRIPTION); + AddDescription(m_use_fullres_framedumps, TR_INTERNAL_RESOLUTION_FRAME_DUMPING_DESCRIPTION); +#ifdef HAVE_FFMPEG + AddDescription(m_dump_use_ffv1, TR_USE_FFV1_DESCRIPTION); +#endif + AddDescription(m_enable_cropping, TR_CROPPING_DESCRIPTION); + AddDescription(m_enable_prog_scan, TR_PROGRESSIVE_SCAN_DESCRIPTION); + AddDescription(m_enable_freelook, TR_FREE_LOOK_DESCRIPTION); +#ifdef _WIN32 + AddDescription(m_borderless_fullscreen, TR_BORDERLESS_FULLSCREEN_DESCRIPTION); +#endif +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.h b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.h new file mode 100644 index 0000000000..fa3a419adb --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.h @@ -0,0 +1,47 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; + +class AdvancedWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit AdvancedWidget(GraphicsWindow* parent); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); + void OnBackendChanged(); + void OnEmulationStateChanged(bool running); + + // Debugging + QCheckBox* m_enable_wireframe; + QCheckBox* m_show_statistics; + QCheckBox* m_enable_format_overlay; + QCheckBox* m_enable_api_validation; + + // Utility + QCheckBox* m_dump_textures; + QCheckBox* m_prefetch_custom_textures; + QCheckBox* m_dump_efb_target; + QCheckBox* m_dump_use_ffv1; + QCheckBox* m_load_custom_textures; + QCheckBox* m_use_fullres_framedumps; + QCheckBox* m_enable_freelook; + + // Misc + QCheckBox* m_enable_cropping; + QCheckBox* m_enable_prog_scan; + QCheckBox* m_borderless_fullscreen; +}; From e64a2d4e098987518af7e32e8c06fda328f61841 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:43:38 +0200 Subject: [PATCH 5/9] Qt/GraphicsSettings: Implement enhancements tab --- .../Config/Graphics/EnhancementsWidget.cpp | 301 ++++++++++++++++++ .../Config/Graphics/EnhancementsWidget.h | 50 +++ 2 files changed, 351 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp new file mode 100644 index 0000000000..263dc50248 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp @@ -0,0 +1,301 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/EnhancementsWidget.h" + +#include + +#include +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" +#include "DolphinQt2/Config/Graphics/GraphicsSlider.h" +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "DolphinQt2/Settings.h" +#include "UICommon/VideoUtils.h" +#include "VideoCommon/PostProcessing.h" +#include "VideoCommon/VideoConfig.h" + +EnhancementsWidget::EnhancementsWidget(GraphicsWindow* parent) + : GraphicsWidget(parent), m_block_save(false) +{ + CreateWidgets(); + LoadSettings(); + ConnectWidgets(); + AddDescriptions(); + connect(parent, &GraphicsWindow::BackendChanged, + [this](const QString& backend) { LoadSettings(); }); +} + +void EnhancementsWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + // Enhancements + auto* enhancements_box = new QGroupBox(tr("Enhancements")); + auto* enhancements_layout = new QGridLayout(); + enhancements_box->setLayout(enhancements_layout); + + m_ir_combo = new GraphicsChoice( + {tr("Auto (Window Size)"), tr("Auto (Multiple of 640x528)"), tr("Native (640x528)"), + tr("1.5x Native (960x792)"), tr("2x Native (1280x1056) for 720p"), + tr("2.5x Native (1600x1320)"), tr("3x Native (1920x1584) for 1080p"), + tr("4x Native (2560x2112) for 1440p"), tr("5x Native (3200x2640)"), + tr("6x Native (3840x3168) for 4K"), tr("7x Native (4480x3696)"), + tr("8x Native (5120x4224) for 5K")}, + Config::GFX_EFB_SCALE); + + if (g_Config.iEFBScale > 11) + { + m_ir_combo->addItem(tr("Custom")); + m_ir_combo->setCurrentIndex(m_ir_combo->count() - 1); + } + + m_ir_combo->setMaxVisibleItems(m_ir_combo->count()); + + m_aa_combo = new QComboBox(); + m_af_combo = new GraphicsChoice({tr("1x"), tr("2x"), tr("4x"), tr("8x"), tr("16x")}, + Config::GFX_ENHANCE_MAX_ANISOTROPY); + m_pp_effect = new QComboBox(); + m_configure_pp_effect = new QPushButton(tr("Configure")); + m_scaled_efb_copy = new GraphicsBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_ENABLED); + m_per_pixel_lighting = + new GraphicsBool(tr("Per-Pixel Lighting"), Config::GFX_ENABLE_PIXEL_LIGHTING); + m_force_texture_filtering = + new GraphicsBool(tr("Force Texture Filtering"), Config::GFX_ENHANCE_FORCE_FILTERING); + m_widescreen_hack = new GraphicsBool(tr("Widescreen Hack"), Config::GFX_WIDESCREEN_HACK); + m_disable_fog = new GraphicsBool(tr("Disable Fog"), Config::GFX_DISABLE_FOG); + m_force_24bit_color = + new GraphicsBool(tr("Force 24-bit Color"), Config::GFX_ENHANCE_FORCE_TRUE_COLOR); + + enhancements_layout->addWidget(new QLabel(tr("Internal Resolution:")), 0, 0); + enhancements_layout->addWidget(m_ir_combo, 0, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Anti-Aliasing")), 1, 0); + enhancements_layout->addWidget(m_aa_combo, 1, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Antisotrophic Filtering:")), 2, 0); + enhancements_layout->addWidget(m_af_combo, 2, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Post-Processing Effect:")), 3, 0); + enhancements_layout->addWidget(m_pp_effect, 3, 1); + enhancements_layout->addWidget(m_configure_pp_effect, 3, 2); + + enhancements_layout->addWidget(m_scaled_efb_copy, 4, 0); + enhancements_layout->addWidget(m_per_pixel_lighting, 4, 1); + enhancements_layout->addWidget(m_force_texture_filtering, 5, 0); + enhancements_layout->addWidget(m_widescreen_hack, 5, 1); + enhancements_layout->addWidget(m_disable_fog, 6, 0); + enhancements_layout->addWidget(m_force_24bit_color, 6, 1); + + // Stereoscopy + auto* stereoscopy_box = new QGroupBox(tr("Stereoscopy")); + auto* stereoscopy_layout = new QGridLayout(); + stereoscopy_box->setLayout(stereoscopy_layout); + + m_3d_mode = + new GraphicsChoice({tr("Off"), tr("Side-by-Side"), tr("Top-and-Bottom"), tr("Anaglyph")}, + Config::GFX_STEREO_MODE); + m_3d_depth = new GraphicsSlider(0, 100, Config::GFX_STEREO_DEPTH); + m_3d_convergence = new GraphicsSlider(0, 200, Config::GFX_STEREO_CONVERGENCE, 100); + m_3d_swap_eyes = new GraphicsBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES); + + stereoscopy_layout->addWidget(new QLabel(tr("Stereoscopic 3D Mode:")), 0, 0); + stereoscopy_layout->addWidget(m_3d_mode, 0, 1); + stereoscopy_layout->addWidget(new QLabel(tr("Depth:")), 1, 0); + stereoscopy_layout->addWidget(m_3d_depth, 1, 1); + stereoscopy_layout->addWidget(new QLabel(tr("Convergence:")), 2, 0); + stereoscopy_layout->addWidget(m_3d_convergence, 2, 1); + stereoscopy_layout->addWidget(m_3d_swap_eyes, 3, 0); + + main_layout->addWidget(enhancements_box); + main_layout->addWidget(stereoscopy_box); + + setLayout(main_layout); +} + +void EnhancementsWidget::ConnectWidgets() +{ + connect(m_aa_combo, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + connect(m_pp_effect, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + connect(m_3d_mode, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); +} + +void EnhancementsWidget::LoadSettings() +{ + m_block_save = true; + // Anti-Aliasing + + int aa_selection = Config::Get(Config::GFX_MSAA); + bool ssaa = Config::Get(Config::GFX_SSAA); + + m_aa_combo->clear(); + for (const auto& option : VideoUtils::GetAvailableAntialiasingModes(m_msaa_modes)) + m_aa_combo->addItem(option == "None" ? tr("None") : QString::fromStdString(option)); + + m_aa_combo->setCurrentText( + QString::fromStdString(std::to_string(aa_selection) + "x " + (ssaa ? "SSAA" : "MSAA"))); + m_aa_combo->setEnabled(m_aa_combo->count() > 1); + + // Post Processing Shader + std::vector shaders = + g_Config.iStereoMode == STEREO_ANAGLYPH ? + PostProcessingShaderImplementation::GetAnaglyphShaderList( + g_Config.backend_info.api_type) : + PostProcessingShaderImplementation::GetShaderList(g_Config.backend_info.api_type); + + m_pp_effect->clear(); + m_pp_effect->addItem(tr("(off)")); + + const auto selected_shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER); + + for (const auto& shader : shaders) + { + m_pp_effect->addItem(QString::fromStdString(shader)); + if (selected_shader == shader) + m_pp_effect->setCurrentIndex(m_pp_effect->count() - 1); + } + + PostProcessingShaderConfiguration pp_shader; + if (selected_shader != "(off)") + { + pp_shader.LoadShader(selected_shader); + m_configure_pp_effect->setEnabled(pp_shader.HasOptions()); + } + bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders; + + m_3d_mode->setEnabled(supports_stereoscopy); + m_3d_convergence->setEnabled(supports_stereoscopy); + m_3d_depth->setEnabled(supports_stereoscopy); + m_3d_swap_eyes->setEnabled(supports_stereoscopy); + m_block_save = false; +} + +void EnhancementsWidget::SaveSettings() +{ + if (m_block_save) + return; + + bool is_ssaa = m_aa_combo->currentText().endsWith(QStringLiteral("SSAA")); + + int aa_value = m_aa_combo->currentIndex(); + + if (aa_value == 0) + { + aa_value = 1; + } + else + { + if (aa_value > m_msaa_modes) + aa_value -= m_msaa_modes; + aa_value = std::pow(2, aa_value); + } + Config::SetBaseOrCurrent(Config::GFX_MSAA, static_cast(aa_value)); + + Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa); + + Config::SetBaseOrCurrent(Config::GFX_ENHANCE_POST_SHADER, + m_pp_effect->currentText().toStdString()); + + PostProcessingShaderConfiguration pp_shader; + if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) != "(off)") + { + pp_shader.LoadShader(Config::Get(Config::GFX_ENHANCE_POST_SHADER)); + m_configure_pp_effect->setEnabled(pp_shader.HasOptions()); + } + else + { + m_configure_pp_effect->setEnabled(false); + } +} + +void EnhancementsWidget::AddDescriptions() +{ + static const char* TR_INTERNAL_RESOLUTION_DESCRIPTION = + QT_TR_NOOP("Specifies the resolution used to render at. A high resolution greatly improves " + "visual quality, but also greatly increases GPU load and can cause issues in " + "certain games.\n\"Multiple of 640x528\" will result in a size slightly larger " + "than \"Window Size\" but yield fewer issues. Generally speaking, the lower the " + "internal resolution is, the better your performance will be. Auto (Window Size), " + "1.5x, and 2.5x may cause issues in some games.\n\nIf unsure, select Native."); + + static const char* TR_ANTIALIAS_DESCRIPTION = + QT_TR_NOOP("Reduces the amount of aliasing caused by rasterizing 3D graphics. This smooths " + "out jagged edges on objects.\nIncreases GPU load and sometimes causes graphical " + "issues. SSAA is significantly more demanding than MSAA, but provides top quality " + "geometry anti-aliasing and also applies anti-aliasing to lighting, shader " + "effects, and textures.\n\nIf unsure, select None."); + + static const char* TR_ANTISTROPIC_FILTERING_DESCRIPTION = QT_TR_NOOP( + "Enable anisotropic filtering.\nEnhances visual quality of textures that are at oblique " + "viewing angles.\nMight cause issues in a small number of games.\n\nIf unsure, select 1x."); + + static const char* TR_POSTPROCESSING_DESCRIPTION = QT_TR_NOOP( + "Apply a post-processing effect after finishing a frame.\n\nIf unsure, select (off)."); + + static const char* TR_SCALED_EFB_COPY_DESCRIPTION = QT_TR_NOOP( + "Greatly increases quality of textures generated using render-to-texture " + "effects.\nRaising the " + "internal resolution will improve the effect of this setting.\nSlightly increases GPU " + "load and " + "causes relatively few graphical issues.\n\nIf unsure, leave this checked."); + static const char* TR_PER_PIXEL_LIGHTING_DESCRIPTION = QT_TR_NOOP( + "Calculates lighting of 3D objects per-pixel rather than per-vertex, smoothing out the " + "appearance of lit polygons and making individual triangles less noticeable.\nRarely causes " + "slowdowns or graphical issues.\n\nIf unsure, leave this unchecked."); + static const char* TR_WIDESCREEN_HACK_DESCRIPTION = QT_TR_NOOP( + "Forces the game to output graphics for any aspect ratio.\nUse with \"Aspect Ratio\" set to " + "\"Force 16:9\" to force 4:3-only games to run at 16:9.\nRarely produces good results and " + "often partially breaks graphics and game UIs.\nUnnecessary (and detrimental) if using any " + "AR/Gecko-code widescreen patches.\n\nIf unsure, leave this unchecked."); + static const char* TR_REMOVE_FOG_DESCRIPTION = + QT_TR_NOOP("Makes distant objects more visible by removing fog, thus increasing the overall " + "detail.\nDisabling fog will break some games which rely on proper fog " + "emulation.\n\nIf unsure, leave this unchecked."); + + static const char* TR_3D_MODE_DESCRIPTION = QT_TR_NOOP( + "Selects the stereoscopic 3D mode. Stereoscopy allows you to get a better feeling " + "of depth if you have the necessary hardware.\nSide-by-Side and Top-and-Bottom are " + "used by most 3D TVs.\nAnaglyph is used for Red-Cyan colored glasses.\nHeavily " + "decreases emulation speed and sometimes causes issues.\n\nIf unsure, select Off."); + static const char* TR_3D_DEPTH_DESCRIPTION = + QT_TR_NOOP("Controls the separation distance between the virtual cameras.\nA higher value " + "creates a stronger feeling of depth while a lower value is more comfortable."); + static const char* TR_3D_CONVERGENCE_DESCRIPTION = QT_TR_NOOP( + "Controls the distance of the convergence plane. This is the distance at which " + "virtual objects will appear to be in front of the screen.\nA higher value creates " + "stronger out-of-screen effects while a lower value is more comfortable."); + static const char* TR_3D_SWAP_EYES_DESCRIPTION = + QT_TR_NOOP("Swaps the left and right eye. Mostly useful if you want to view side-by-side " + "cross-eyed.\n\nIf unsure, leave this unchecked."); + static const char* TR_FORCE_24BIT_DESCRIPTION = + QT_TR_NOOP("Forces the game to render the RGB color channels in 24-bit, thereby increasing " + "quality by reducing color banding.\nIt has no impact on performance and causes " + "few graphical issues.\n\n\nIf unsure, leave this checked."); + static const char* TR_FORCE_TEXTURE_FILTERING_DESCRIPTION = + QT_TR_NOOP("Filter all textures, including any that the game explicitly set as " + "unfiltered.\nMay improve quality of certain textures in some games, but will " + "cause issues in others.\n\nIf unsure, leave this unchecked."); + + AddDescription(m_ir_combo, TR_INTERNAL_RESOLUTION_DESCRIPTION); + AddDescription(m_aa_combo, TR_ANTIALIAS_DESCRIPTION); + AddDescription(m_af_combo, TR_ANTISTROPIC_FILTERING_DESCRIPTION); + AddDescription(m_pp_effect, TR_POSTPROCESSING_DESCRIPTION); + AddDescription(m_scaled_efb_copy, TR_SCALED_EFB_COPY_DESCRIPTION); + AddDescription(m_per_pixel_lighting, TR_PER_PIXEL_LIGHTING_DESCRIPTION); + AddDescription(m_widescreen_hack, TR_WIDESCREEN_HACK_DESCRIPTION); + AddDescription(m_disable_fog, TR_REMOVE_FOG_DESCRIPTION); + AddDescription(m_force_24bit_color, TR_FORCE_24BIT_DESCRIPTION); + AddDescription(m_force_texture_filtering, TR_FORCE_TEXTURE_FILTERING_DESCRIPTION); + AddDescription(m_3d_mode, TR_3D_MODE_DESCRIPTION); + AddDescription(m_3d_depth, TR_3D_DEPTH_DESCRIPTION); + AddDescription(m_3d_convergence, TR_3D_CONVERGENCE_DESCRIPTION); + AddDescription(m_3d_swap_eyes, TR_3D_SWAP_EYES_DESCRIPTION); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h new file mode 100644 index 0000000000..ac23ed84e9 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h @@ -0,0 +1,50 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; +class QComboBox; +class QPushButton; +class QSlider; + +class EnhancementsWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit EnhancementsWidget(GraphicsWindow* parent); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); + + // Enhancements + QComboBox* m_ir_combo; + QComboBox* m_aa_combo; + QComboBox* m_af_combo; + QComboBox* m_pp_effect; + QPushButton* m_configure_pp_effect; + QCheckBox* m_scaled_efb_copy; + QCheckBox* m_per_pixel_lighting; + QCheckBox* m_force_texture_filtering; + QCheckBox* m_widescreen_hack; + QCheckBox* m_disable_fog; + QCheckBox* m_force_24bit_color; + + // Stereoscopy + QComboBox* m_3d_mode; + QSlider* m_3d_depth; + QSlider* m_3d_convergence; + QCheckBox* m_3d_swap_eyes; + + int m_msaa_modes; + bool m_block_save; +}; From 6598c23d0e5fa201bb1b8d86a39205b8d0f16e15 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:43:14 +0200 Subject: [PATCH 6/9] Qt/GraphicsSettings: Implement general tab --- Source/Core/DolphinQt2/CMakeLists.txt | 1 + .../Config/Graphics/GeneralWidget.cpp | 335 ++++++++++++++++++ .../Config/Graphics/GeneralWidget.h | 58 +++ .../Config/Graphics/GraphicsWindow.cpp | 46 ++- .../Config/Graphics/GraphicsWindow.h | 11 + 5 files changed, 442 insertions(+), 9 deletions(-) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt index 8227cf5f6f..6ddffd597f 100644 --- a/Source/Core/DolphinQt2/CMakeLists.txt +++ b/Source/Core/DolphinQt2/CMakeLists.txt @@ -35,6 +35,7 @@ set(SRCS Config/Graphics/GraphicsSlider.cpp Config/Graphics/GraphicsWidget.cpp Config/Graphics/GraphicsWindow.cpp + Config/Graphics/SoftwareRendererWidget.cpp Config/InfoWidget.cpp Config/Mapping/GCKeyboardEmu.cpp Config/Mapping/GCPadEmu.cpp diff --git a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp new file mode 100644 index 0000000000..c9b29e103b --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp @@ -0,0 +1,335 @@ +// Copyright 2017 Dolphin Emulator Project5~5~5~ +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GeneralWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "UICommon/VideoUtils.h" +#include "VideoCommon/VideoBackendBase.h" +#include "VideoCommon/VideoConfig.h" + +GeneralWidget::GeneralWidget(X11Utils::XRRConfiguration* xrr_config, GraphicsWindow* parent) + : GraphicsWidget(parent), m_xrr_config(xrr_config) +{ + CreateWidgets(); + LoadSettings(); + ConnectWidgets(); + AddDescriptions(); + emit BackendChanged(QString::fromStdString(SConfig::GetInstance().m_strVideoBackend)); + + connect(parent, &GraphicsWindow::BackendChanged, this, &GeneralWidget::OnBackendChanged); + connect(parent, &GraphicsWindow::EmulationStarted, [this] { OnEmulationStateChanged(true); }); + connect(parent, &GraphicsWindow::EmulationStopped, [this] { OnEmulationStateChanged(false); }); +} + +void GeneralWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + // Video Section + auto* m_video_box = new QGroupBox(tr("Video")); + m_video_layout = new QGridLayout(); + + m_backend_combo = new QComboBox(); + m_resolution_combo = new QComboBox(); + m_aspect_combo = + new GraphicsChoice({tr("Auto"), tr("Force 16:9"), tr("Force 4:3"), tr("Stretch to Window")}, + Config::GFX_ASPECT_RATIO); + m_adapter_combo = new GraphicsChoice({}, Config::GFX_ADAPTER); + m_enable_vsync = new GraphicsBool(tr("V-Sync"), Config::GFX_VSYNC); + m_enable_fullscreen = new QCheckBox(tr("Use Fullscreen")); + + m_video_box->setLayout(m_video_layout); + + for (auto& backend : g_available_video_backends) + m_backend_combo->addItem(tr(backend->GetDisplayName().c_str())); + +#ifndef __APPLE__ + m_resolution_combo->addItem(tr("Auto")); + + for (const auto& res : VideoUtils::GetAvailableResolutions(m_xrr_config)) + m_resolution_combo->addItem(QString::fromStdString(res)); +#endif + + m_video_layout->addWidget(new QLabel(tr("Backend:")), 0, 0); + m_video_layout->addWidget(m_backend_combo, 0, 1); +#ifdef _WIN32 + m_video_layout->addWidget(new QLabel(tr("Adapter:")), 1, 0); + m_video_layout->addWidget(m_adapter_combo, 1, 1); +#endif + +#ifndef __APPLE__ + m_video_layout->addWidget(new QLabel(tr("Fullscreen Resolution:")), 2, 0); + m_video_layout->addWidget(m_resolution_combo, 2, 1); +#endif + + m_video_layout->addWidget(new QLabel(tr("Aspect Ratio:")), 3, 0); + m_video_layout->addWidget(m_aspect_combo, 3, 1); + + m_video_layout->addWidget(m_enable_vsync, 4, 0); + m_video_layout->addWidget(m_enable_fullscreen, 4, 1); + + // Options + auto* m_options_box = new QGroupBox(tr("Options")); + auto* m_options_layout = new QGridLayout(); + + m_show_fps = new GraphicsBool(tr("Show FPS"), Config::GFX_SHOW_FPS); + m_show_ping = new GraphicsBool(tr("Show NetPlay Ping"), Config::GFX_SHOW_NETPLAY_PING); + m_log_render_time = new GraphicsBool(tr("Log Rendertime"), Config::GFX_LOG_RENDER_TIME_TO_FILE); + m_autoadjust_window_size = new QCheckBox(tr("Auto-adjust Window size")); + m_show_messages = + new GraphicsBool(tr("Show NetPlay Messages"), Config::GFX_SHOW_NETPLAY_MESSAGES); + m_keep_window_top = new QCheckBox(tr("Keep Window on Top")); + m_hide_cursor = new QCheckBox(tr("Hide Mouse Cursor")); + m_render_main_window = new QCheckBox(tr("Render to Main Window")); + + m_options_box->setLayout(m_options_layout); + + m_options_layout->addWidget(m_show_fps, 0, 0); + m_options_layout->addWidget(m_show_ping, 0, 1); + + m_options_layout->addWidget(m_log_render_time, 1, 0); + m_options_layout->addWidget(m_autoadjust_window_size, 1, 1); + + m_options_layout->addWidget(m_show_messages, 2, 0); + m_options_layout->addWidget(m_keep_window_top, 2, 1); + + m_options_layout->addWidget(m_hide_cursor, 3, 0); + m_options_layout->addWidget(m_render_main_window, 3, 1); + + main_layout->addWidget(m_video_box); + main_layout->addWidget(m_options_box); + + setLayout(main_layout); +} + +void GeneralWidget::ConnectWidgets() +{ + // Video Backend + connect(m_backend_combo, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + // Fullscreen Resolution + connect(m_resolution_combo, + static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + // Enable Fullscreen + for (QCheckBox* checkbox : {m_enable_fullscreen, m_hide_cursor, m_render_main_window}) + connect(checkbox, &QCheckBox::toggled, this, &GeneralWidget::SaveSettings); +} + +void GeneralWidget::LoadSettings() +{ + // Video Backend + for (const auto& backend : g_available_video_backends) + { + if (backend->GetName() == SConfig::GetInstance().m_strVideoBackend) + { + backend->InitBackendInfo(); + m_backend_combo->setCurrentIndex( + m_backend_combo->findText(tr(backend->GetDisplayName().c_str()))); + break; + } + } + + // Fullscreen Resolution + auto resolution = SConfig::GetInstance().strFullscreenResolution; + m_resolution_combo->setCurrentIndex( + resolution == "Auto" ? 0 : m_resolution_combo->findText(QString::fromStdString(resolution))); + // Enable Fullscreen + m_enable_fullscreen->setChecked(SConfig::GetInstance().bFullscreen); + // Hide Cursor + m_hide_cursor->setChecked(SConfig::GetInstance().bHideCursor); + // Render to Main Window + m_render_main_window->setChecked(SConfig::GetInstance().bRenderToMain); + // Keep Window on Top + m_keep_window_top->setChecked(SConfig::GetInstance().bKeepWindowOnTop); + // Autoadjust Window size + m_autoadjust_window_size->setChecked(SConfig::GetInstance().bRenderWindowAutoSize); +} + +void GeneralWidget::SaveSettings() +{ + // Video Backend + for (const auto& backend : g_available_video_backends) + { + if (backend->GetDisplayName() == m_backend_combo->currentText().toStdString()) + { + const auto current_backend = backend->GetName(); + if (SConfig::GetInstance().m_strVideoBackend != current_backend) + { + SConfig::GetInstance().m_strVideoBackend = current_backend; + + if (backend->GetName() == "Software Renderer") + { + QMessageBox confirm_sw; + + confirm_sw.setIcon(QMessageBox::Warning); + confirm_sw.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + confirm_sw.setText( + tr("Software rendering is an order of magnitude slower than using the " + "other backends.\nIt's only useful for debugging purposes.\nDo you " + "really want to enable software rendering? If unsure, select 'No'.")); + + if (confirm_sw.exec() != QMessageBox::Yes) + { + for (const auto& prv_backend : g_available_video_backends) + { + if (prv_backend->GetName() == SConfig::GetInstance().m_strVideoBackend) + { + m_backend_combo->setCurrentIndex( + m_backend_combo->findText(tr(prv_backend->GetDisplayName().c_str()))); + break; + } + } + return; + } + } + SConfig::GetInstance().m_strVideoBackend = current_backend; + backend->InitBackendInfo(); + emit BackendChanged(QString::fromStdString(current_backend)); + break; + } + } + } + + // Fullscreen Resolution + SConfig::GetInstance().strFullscreenResolution = + m_resolution_combo->currentIndex() == 0 ? "Auto" : + m_resolution_combo->currentText().toStdString(); + // Enable Fullscreen + SConfig::GetInstance().bFullscreen = m_enable_fullscreen->isChecked(); + // Hide Cursor + SConfig::GetInstance().bHideCursor = m_hide_cursor->isChecked(); + // Render to Main Window + SConfig::GetInstance().bRenderToMain = m_render_main_window->isChecked(); + // Keep Window on Top + SConfig::GetInstance().bKeepWindowOnTop = m_keep_window_top->isChecked(); + // Autoadjust windowsize + SConfig::GetInstance().bRenderWindowAutoSize = m_autoadjust_window_size->isChecked(); +} + +void GeneralWidget::OnEmulationStateChanged(bool running) +{ + m_backend_combo->setEnabled(!running); + m_render_main_window->setEnabled(!running); +#ifndef __APPLE__ + m_resolution_combo->setEnabled(!running); +#endif + +#ifdef _WIN32 + m_adapter_combo->setEnabled(!running); +#endif +} + +void GeneralWidget::AddDescriptions() +{ +// We need QObject::tr +#if defined(_WIN32) + static const char* TR_BACKEND_DESCRIPTION = + QT_TR_NOOP("Selects what graphics API to use internally.\nThe software renderer is extremely " + "slow and only useful for debugging, so you'll want to use either Direct3D or " + "OpenGL. Different games and different GPUs will behave differently on each " + "backend, so for the best emulation experience it's recommended to try both and " + "choose the one that's less problematic.\n\nIf unsure, select OpenGL."); + static const char* TR_ADAPTER_DESCRIPTION = + QT_TR_NOOP("Selects a hardware adapter to use.\n\nIf unsure, use the first one."); +#else + static const char* TR_BACKEND_DESCRIPTION = + QT_TR_NOOP("Selects what graphics API to use internally.\nThe software renderer is extremely " + "slow and only useful for debugging, so unless you have a reason to use it you'll " + "want to select OpenGL here.\n\nIf unsure, select OpenGL."); +#endif + static const char* TR_RESOLUTION_DESCRIPTION = + QT_TR_NOOP("Selects the display resolution used in fullscreen mode.\nThis should always be " + "bigger than or equal to the internal resolution. Performance impact is " + "negligible.\n\nIf unsure, select auto."); + static const char* TR_FULLSCREEN_DESCRIPTION = QT_TR_NOOP( + "Enable this if you want the whole screen to be used for rendering.\nIf this is disabled, a " + "render window will be created instead.\n\nIf unsure, leave this unchecked."); + static const char* TR_AUTOSIZE_DESCRIPTION = + QT_TR_NOOP("Automatically adjusts the window size to your internal resolution.\n\nIf unsure, " + "leave this unchecked."); + static const char* TR_KEEP_WINDOW_ON_TOP_DESCRIPTION = QT_TR_NOOP( + "Keep the game window on top of all other windows.\n\nIf unsure, leave this unchecked."); + static const char* TR_HIDE_MOUSE_CURSOR_DESCRIPTION = + QT_TR_NOOP("Hides the mouse cursor if it's on top of the emulation window.\n\nIf unsure, " + "leave this unchecked."); + static const char* TR_RENDER_TO_MAINWINDOW_DESCRIPTION = + QT_TR_NOOP("Enable this if you want to use the main Dolphin window for rendering rather than " + "a separate render window.\n\nIf unsure, leave this unchecked."); + static const char* TR_ASPECT_RATIO_DESCRIPTION = QT_TR_NOOP( + "Select what aspect ratio to use when rendering:\nAuto: Use the native aspect " + "ratio\nForce 16:9: Mimic an analog TV with a widescreen aspect ratio.\nForce 4:3: " + "Mimic a standard 4:3 analog TV.\nStretch to Window: Stretch the picture to the " + "window size.\n\nIf unsure, select Auto."); + static const char* TR_VSYNC_DESCRIPTION = + QT_TR_NOOP("Wait for vertical blanks in order to reduce tearing.\nDecreases performance if " + "emulation speed is below 100%.\n\nIf unsure, leave this unchecked."); + static const char* TR_SHOW_FPS_DESCRIPTION = + QT_TR_NOOP("Show the number of frames rendered per second as a measure of " + "emulation speed.\n\nIf unsure, leave this unchecked."); + static const char* TR_SHOW_NETPLAY_PING_DESCRIPTION = + QT_TR_NOOP("Show the players' maximum Ping while playing on " + "NetPlay.\n\nIf unsure, leave this unchecked."); + static const char* TR_LOG_RENDERTIME_DESCRIPTION = + QT_TR_NOOP("Log the render time of every frame to User/Logs/render_time.txt. Use this " + "feature when you want to measure the performance of Dolphin.\n\nIf " + "unsure, leave this unchecked."); + static const char* TR_SHOW_NETPLAY_MESSAGES_DESCRIPTION = + QT_TR_NOOP("When playing on NetPlay, show chat messages, buffer changes and " + "desync alerts.\n\nIf unsure, leave this unchecked."); + + AddDescription(m_backend_combo, TR_BACKEND_DESCRIPTION); +#ifdef _WIN32 + AddDescription(m_adapter_combo, TR_ADAPTER_DESCRIPTION); +#endif + AddDescription(m_resolution_combo, TR_RESOLUTION_DESCRIPTION); + AddDescription(m_enable_fullscreen, TR_FULLSCREEN_DESCRIPTION); + AddDescription(m_autoadjust_window_size, TR_AUTOSIZE_DESCRIPTION); + AddDescription(m_hide_cursor, TR_HIDE_MOUSE_CURSOR_DESCRIPTION); + AddDescription(m_render_main_window, TR_RENDER_TO_MAINWINDOW_DESCRIPTION); + AddDescription(m_aspect_combo, TR_ASPECT_RATIO_DESCRIPTION); + AddDescription(m_enable_vsync, TR_VSYNC_DESCRIPTION); + AddDescription(m_show_fps, TR_SHOW_FPS_DESCRIPTION); + AddDescription(m_show_ping, TR_SHOW_NETPLAY_PING_DESCRIPTION); + AddDescription(m_log_render_time, TR_LOG_RENDERTIME_DESCRIPTION); + AddDescription(m_show_messages, TR_SHOW_FPS_DESCRIPTION); + AddDescription(m_keep_window_top, TR_KEEP_WINDOW_ON_TOP_DESCRIPTION); + AddDescription(m_show_messages, TR_SHOW_NETPLAY_MESSAGES_DESCRIPTION); +} +void GeneralWidget::OnBackendChanged(const QString& backend_name) +{ + for (const auto& backend : g_available_video_backends) + { + if (QString::fromStdString(backend->GetName()) == backend_name) + { + m_backend_combo->setCurrentIndex( + m_backend_combo->findText(tr(backend->GetDisplayName().c_str()))); + break; + } + } + +#ifdef _WIN32 + m_adapter_combo->clear(); + + for (const auto& adapter : g_Config.backend_info.Adapters) + m_adapter_combo->addItem(QString::fromStdString(adapter)); + + m_adapter_combo->setCurrentIndex(g_Config.iAdapter); + m_adapter_combo->setEnabled(g_Config.backend_info.Adapters.size()); +#endif +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h new file mode 100644 index 0000000000..76b0530179 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h @@ -0,0 +1,58 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; +class QComboBox; +class QGridLayout; + +namespace X11Utils +{ +class XRRConfiguration; +} + +class GeneralWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit GeneralWidget(X11Utils::XRRConfiguration* xrr_config, GraphicsWindow* parent); +signals: + void BackendChanged(const QString& backend); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); + + void OnBackendChanged(const QString& backend_name); + void OnEmulationStateChanged(bool running); + + // Video + QGridLayout* m_video_layout; + QComboBox* m_backend_combo; + QComboBox* m_resolution_combo; + QComboBox* m_adapter_combo; + QComboBox* m_aspect_combo; + QCheckBox* m_enable_vsync; + QCheckBox* m_enable_fullscreen; + + // Options + QCheckBox* m_show_fps; + QCheckBox* m_show_ping; + QCheckBox* m_log_render_time; + QCheckBox* m_autoadjust_window_size; + QCheckBox* m_show_messages; + QCheckBox* m_keep_window_top; + QCheckBox* m_hide_cursor; + QCheckBox* m_render_main_window; + + X11Utils::XRRConfiguration* m_xrr_config; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp index f32623f22e..2ada29ac81 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp @@ -16,6 +16,7 @@ #include "DolphinQt2/Config/Graphics/EnhancementsWidget.h" #include "DolphinQt2/Config/Graphics/GeneralWidget.h" #include "DolphinQt2/Config/Graphics/HacksWidget.h" +#include "DolphinQt2/Config/Graphics/SoftwareRendererWidget.h" #include "DolphinQt2/MainWindow.h" GraphicsWindow::GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindow* parent) @@ -56,17 +57,28 @@ void GraphicsWindow::CreateMainLayout() main_layout->addWidget(description_box); main_layout->addWidget(m_button_box); - auto* general_widget = new GeneralWidget(m_xrr_config, this); - auto* enhancements_widget = new EnhancementsWidget(this); - auto* hacks_widget = new HacksWidget(this); - auto* advanced_widget = new AdvancedWidget(this); + m_general_widget = new GeneralWidget(m_xrr_config, this); + m_enhancements_widget = new EnhancementsWidget(this); + m_hacks_widget = new HacksWidget(this); + m_advanced_widget = new AdvancedWidget(this); + m_software_renderer = new SoftwareRendererWidget(this); - connect(general_widget, &GeneralWidget::BackendChanged, this, &GraphicsWindow::OnBackendChanged); + connect(m_general_widget, &GeneralWidget::BackendChanged, this, + &GraphicsWindow::OnBackendChanged); + connect(m_software_renderer, &SoftwareRendererWidget::BackendChanged, this, + &GraphicsWindow::OnBackendChanged); - m_tab_widget->addTab(general_widget, tr("General")); - m_tab_widget->addTab(enhancements_widget, tr("Enhancements")); - m_tab_widget->addTab(hacks_widget, tr("Hacks")); - m_tab_widget->addTab(advanced_widget, tr("Advanced")); + if (SConfig::GetInstance().m_strVideoBackend != "Software Renderer") + { + m_tab_widget->addTab(m_general_widget, tr("General")); + m_tab_widget->addTab(m_enhancements_widget, tr("Enhancements")); + m_tab_widget->addTab(m_hacks_widget, tr("Hacks")); + m_tab_widget->addTab(m_advanced_widget, tr("Advanced")); + } + else + { + m_tab_widget->addTab(m_software_renderer, tr("Software Renderer")); + } setLayout(main_layout); } @@ -79,6 +91,21 @@ void GraphicsWindow::ConnectWidgets() void GraphicsWindow::OnBackendChanged(const QString& backend) { setWindowTitle(tr("Dolphin %1 Graphics Configuration").arg(backend)); + if (backend == QStringLiteral("Software Renderer") && m_tab_widget->count() > 1) + { + m_tab_widget->clear(); + m_tab_widget->addTab(m_software_renderer, tr("Software Renderer")); + } + + if (backend != QStringLiteral("Software Renderer") && m_tab_widget->count() == 1) + { + m_tab_widget->clear(); + m_tab_widget->addTab(m_general_widget, tr("General")); + m_tab_widget->addTab(m_enhancements_widget, tr("Enhancements")); + m_tab_widget->addTab(m_hacks_widget, tr("Hacks")); + m_tab_widget->addTab(m_advanced_widget, tr("Advanced")); + } + emit BackendChanged(backend); } @@ -97,6 +124,7 @@ bool GraphicsWindow::eventFilter(QObject* object, QEvent* event) { if (!m_widget_descriptions.contains(object)) return false; + if (event->type() == QEvent::Enter) { m_description->setText(tr(m_widget_descriptions[object])); diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h index 1d3748e62d..c78d8663fd 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h @@ -7,11 +7,16 @@ #include #include +class AdvancedWidget; +class EnhancementsWidget; +class HacksWidget; +class GeneralWidget; class GraphicsWidget; class MainWindow; class QLabel; class QTabWidget; class QDialogButtonBox; +class SoftwareRendererWidget; namespace X11Utils { @@ -41,6 +46,12 @@ private: QLabel* m_description; QDialogButtonBox* m_button_box; + AdvancedWidget* m_advanced_widget; + EnhancementsWidget* m_enhancements_widget; + HacksWidget* m_hacks_widget; + GeneralWidget* m_general_widget; + SoftwareRendererWidget* m_software_renderer; + X11Utils::XRRConfiguration* m_xrr_config; QHash m_widget_descriptions; From 0b9f0d44e6c36aedc9534d6cb7bb329f73b9fca1 Mon Sep 17 00:00:00 2001 From: spycrab Date: Tue, 27 Jun 2017 18:00:23 +0200 Subject: [PATCH 7/9] Qt/GraphicsSettings: Implement software rendering tab --- .../Graphics/SoftwareRendererWidget.cpp | 174 ++++++++++++++++++ .../Config/Graphics/SoftwareRendererWidget.h | 41 +++++ 2 files changed, 215 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.h diff --git a/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.cpp new file mode 100644 index 0000000000..1cada915cd --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.cpp @@ -0,0 +1,174 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/SoftwareRendererWidget.h" + +#include +#include +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "DolphinQt2/Settings.h" +#include "UICommon/VideoUtils.h" +#include "VideoCommon/VideoBackendBase.h" +#include "VideoCommon/VideoConfig.h" + +SoftwareRendererWidget::SoftwareRendererWidget(GraphicsWindow* parent) : GraphicsWidget(parent) +{ + CreateWidgets(); + + connect(parent, &GraphicsWindow::BackendChanged, [this] { LoadSettings(); }); + + LoadSettings(); + ConnectWidgets(); + AddDescriptions(); +} + +void SoftwareRendererWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + auto* rendering_box = new QGroupBox(tr("Rendering")); + auto* rendering_layout = new QGridLayout(); + m_backend_combo = new QComboBox(); + m_disable_xfb = new GraphicsBool(tr("Disable XFB"), Config::GFX_USE_XFB, true); + + rendering_box->setLayout(rendering_layout); + rendering_layout->addWidget(new QLabel(tr("Backend:")), 1, 1); + rendering_layout->addWidget(m_backend_combo, 1, 2); + rendering_layout->addWidget(m_disable_xfb, 2, 1); + + for (const auto& backend : g_available_video_backends) + m_backend_combo->addItem(tr(backend->GetDisplayName().c_str())); + + auto* overlay_box = new QGroupBox(tr("Overlay Information")); + auto* overlay_layout = new QGridLayout(); + overlay_box->setLayout(overlay_layout); + m_enable_statistics = new GraphicsBool(tr("Various Statistics"), Config::GFX_OVERLAY_STATS); + + overlay_layout->addWidget(m_enable_statistics); + + auto* utility_box = new QGroupBox(tr("Utility")); + auto* utility_layout = new QGridLayout(); + m_dump_textures = new GraphicsBool(tr("Dump Textures"), Config::GFX_DUMP_TEXTURES); + m_dump_objects = new GraphicsBool(tr("Dump Objects"), Config::GFX_SW_DUMP_OBJECTS); + utility_box->setLayout(utility_layout); + + utility_layout->addWidget(m_dump_textures, 1, 1); + utility_layout->addWidget(m_dump_objects, 1, 2); + + auto* debug_box = new QGroupBox(tr("Debug Only")); + auto* debug_layout = new QGridLayout(); + m_dump_tev_stages = new GraphicsBool(tr("Dump TEV stages"), Config::GFX_SW_DUMP_TEV_STAGES); + m_dump_tev_fetches = + new GraphicsBool(tr("Dump Texture Fetches"), Config::GFX_SW_DUMP_TEV_TEX_FETCHES); + + debug_layout->addWidget(m_dump_tev_stages, 1, 1); + debug_layout->addWidget(m_dump_tev_fetches, 1, 2); + + debug_box->setLayout(debug_layout); + +#ifdef _DEBUG + utility_layout->addWidget(debug_box, 2, 1, 1, 2); +#endif + + auto* object_range_box = new QGroupBox(tr("Drawn Object Range")); + auto* object_range_layout = new QGridLayout(); + m_object_range_min = new QSpinBox(); + m_object_range_max = new QSpinBox(); + + for (auto* spin : {m_object_range_min, m_object_range_max}) + { + spin->setMinimum(0); + spin->setMaximum(100000); + } + + object_range_box->setLayout(object_range_layout); + + object_range_layout->addWidget(m_object_range_min, 1, 1); + object_range_layout->addWidget(m_object_range_max, 1, 2); + + main_layout->addWidget(rendering_box); + main_layout->addWidget(overlay_box); + main_layout->addWidget(utility_box); + main_layout->addWidget(object_range_box); + + setLayout(main_layout); +} + +void SoftwareRendererWidget::ConnectWidgets() +{ + connect(m_backend_combo, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + connect(m_object_range_min, static_cast(&QSpinBox::valueChanged), + [this](int) { SaveSettings(); }); + connect(m_object_range_max, static_cast(&QSpinBox::valueChanged), + [this](int) { SaveSettings(); }); +} + +void SoftwareRendererWidget::LoadSettings() +{ + for (const auto& backend : g_available_video_backends) + { + if (backend->GetName() == SConfig::GetInstance().m_strVideoBackend) + m_backend_combo->setCurrentIndex( + m_backend_combo->findText(tr(backend->GetDisplayName().c_str()))); + } + + m_object_range_min->setValue(Config::Get(Config::GFX_SW_DRAW_START)); + m_object_range_max->setValue(Config::Get(Config::GFX_SW_DRAW_END)); +} + +void SoftwareRendererWidget::SaveSettings() +{ + for (const auto& backend : g_available_video_backends) + { + if (tr(backend->GetDisplayName().c_str()) == m_backend_combo->currentText()) + { + const auto backend_name = backend->GetName(); + if (backend_name != SConfig::GetInstance().m_strVideoBackend) + { + SConfig::GetInstance().m_strVideoBackend = backend_name; + emit BackendChanged(QString::fromStdString(backend_name)); + } + break; + } + } + + Config::SetBaseOrCurrent(Config::GFX_SW_DRAW_START, m_object_range_min->value()); + Config::SetBaseOrCurrent(Config::GFX_SW_DRAW_END, m_object_range_max->value()); +} + +void SoftwareRendererWidget::AddDescriptions() +{ + static const char* TR_BACKEND_DESCRIPTION = + QT_TR_NOOP("Selects what graphics API to use internally.\nThe software renderer is extremely " + "slow and only useful for debugging, so you'll want to use either Direct3D or " + "OpenGL. Different games and different GPUs will behave differently on each " + "backend, so for the best emulation experience it's recommended to try both and " + "choose the one that's less problematic.\n\nIf unsure, select OpenGL."); + + static const char* TR_DISABLE_XFB_DESCRIPTION = QT_TR_NOOP( + "Disable any XFB emulation.\nSpeeds up emulation a lot but causes heavy glitches in many " + "games " + "which rely on them (especially homebrew applications).\n\nIf unsure, leave this checked."); + + static const char* TR_SHOW_STATISTICS_DESCRIPTION = + QT_TR_NOOP("Show various rendering statistics.\n\nIf unsure, leave this unchecked."); + + static const char* TR_DUMP_TEXTURES_DESCRIPTION = + QT_TR_NOOP("Dump decoded game textures to User/Dump/Textures//.\n\nIf unsure, leave " + "this unchecked."); + + AddDescription(m_backend_combo, TR_BACKEND_DESCRIPTION); + AddDescription(m_disable_xfb, TR_DISABLE_XFB_DESCRIPTION); + AddDescription(m_enable_statistics, TR_SHOW_STATISTICS_DESCRIPTION); + AddDescription(m_dump_textures, TR_DUMP_TEXTURES_DESCRIPTION); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.h b/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.h new file mode 100644 index 0000000000..b9bf586b0e --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/SoftwareRendererWidget.h @@ -0,0 +1,41 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; +class QComboBox; +class QSpinBox; + +class SoftwareRendererWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit SoftwareRendererWidget(GraphicsWindow* parent); + +signals: + void BackendChanged(const QString& backend); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); + + QComboBox* m_backend_combo; + QCheckBox* m_disable_xfb; + QCheckBox* m_enable_statistics; + QCheckBox* m_dump_textures; + QCheckBox* m_dump_objects; + QCheckBox* m_dump_tev_stages; + QCheckBox* m_dump_tev_fetches; + + QSpinBox* m_object_range_min; + QSpinBox* m_object_range_max; +}; From 04bb6b3d59bc09c54d97767674421ee2db0c2b8b Mon Sep 17 00:00:00 2001 From: spycrab Date: Tue, 27 Jun 2017 18:00:41 +0200 Subject: [PATCH 8/9] Qt/GraphicsSettings: Implement hacks tab --- .../Config/Graphics/HacksWidget.cpp | 226 ++++++++++++++++++ .../DolphinQt2/Config/Graphics/HacksWidget.h | 48 ++++ 2 files changed, 274 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h diff --git a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp new file mode 100644 index 0000000000..93b686fd26 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp @@ -0,0 +1,226 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/HacksWidget.h" + +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsSlider.h" +#include "VideoCommon/VideoConfig.h" + +HacksWidget::HacksWidget(GraphicsWindow* parent) : GraphicsWidget(parent) +{ + CreateWidgets(); + LoadSettings(); + ConnectWidgets(); + OnXFBToggled(); + AddDescriptions(); +} + +void HacksWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + // EFB + 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 GraphicsBool(tr("Skip EFB Access from CPU"), Config::GFX_HACK_EFB_ACCESS_ENABLE, true); + m_ignore_format_changes = new GraphicsBool(tr("Ignore Format Changes"), + Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, true); + m_store_efb_copies = new GraphicsBool(tr("Store EFB Copies to Texture Only"), + Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); + + efb_layout->addWidget(m_skip_efb_cpu, 0, 0); + efb_layout->addWidget(m_ignore_format_changes, 0, 1); + efb_layout->addWidget(m_store_efb_copies, 1, 0); + + // Texture Cache + auto* texture_cache_box = new QGroupBox(tr("Texture Cache")); + auto* texture_cache_layout = new QGridLayout(); + texture_cache_box->setLayout(texture_cache_layout); + + m_accuracy = new QSlider(Qt::Horizontal); + m_accuracy->setMinimum(0); + m_accuracy->setMaximum(2); + m_gpu_texture_decoding = + new GraphicsBool(tr("GPU Texture Decoding"), Config::GFX_ENABLE_GPU_TEXTURE_DECODING); + + auto* safe_label = new QLabel(tr("Safe")); + safe_label->setAlignment(Qt::AlignRight); + + texture_cache_layout->addWidget(new QLabel(tr("Accuracy:")), 0, 0); + texture_cache_layout->addWidget(safe_label, 0, 1); + texture_cache_layout->addWidget(m_accuracy, 0, 2); + texture_cache_layout->addWidget(new QLabel(tr("Fast")), 0, 3); + texture_cache_layout->addWidget(m_gpu_texture_decoding, 1, 0); + + // XFB + auto* xfb_box = new QGroupBox(tr("External Frame Buffer (XFB)")); + auto* xfb_layout = new QGridLayout(); + xfb_box->setLayout(xfb_layout); + + m_disable_xfb = new GraphicsBool(tr("Disable"), Config::GFX_USE_XFB, true); + m_real_xfb = new GraphicsBoolEx(tr("Real"), Config::GFX_USE_REAL_XFB, false); + m_virtual_xfb = new GraphicsBoolEx(tr("Virtual"), Config::GFX_USE_REAL_XFB, true); + + xfb_layout->addWidget(m_disable_xfb, 0, 0); + xfb_layout->addWidget(m_virtual_xfb, 0, 1); + xfb_layout->addWidget(m_real_xfb, 0, 2); + // Other + auto* other_box = new QGroupBox(tr("Other")); + auto* other_layout = new QGridLayout(); + other_box->setLayout(other_layout); + + m_fast_depth_calculation = + new GraphicsBool(tr("Fast Depth Calculation"), Config::GFX_FAST_DEPTH_CALC); + m_disable_bounding_box = + new GraphicsBool(tr("Disable Bounding Box"), Config::GFX_HACK_BBOX_ENABLE, true); + m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUDING); + + other_layout->addWidget(m_fast_depth_calculation, 0, 0); + other_layout->addWidget(m_disable_bounding_box, 0, 1); + other_layout->addWidget(m_vertex_rounding, 1, 0); + + main_layout->addWidget(efb_box); + main_layout->addWidget(texture_cache_box); + main_layout->addWidget(xfb_box); + main_layout->addWidget(other_box); + + setLayout(main_layout); +} + +void HacksWidget::ConnectWidgets() +{ + connect(m_disable_xfb, &QCheckBox::toggled, this, &HacksWidget::OnXFBToggled); + connect(m_accuracy, &QSlider::valueChanged, [this](int) { SaveSettings(); }); +} + +void HacksWidget::OnXFBToggled() +{ + m_real_xfb->setEnabled(!m_disable_xfb->isChecked()); + m_virtual_xfb->setEnabled(!m_disable_xfb->isChecked()); +} + +void HacksWidget::LoadSettings() +{ + auto samples = Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES); + + int slider_pos = 0; + + switch (samples) + { + case 512: + slider_pos = 1; + break; + case 128: + slider_pos = 2; + break; + case 0: + slider_pos = 0; + break; + // Custom values, ought not to be touched + default: + m_accuracy->setEnabled(false); + } + + m_accuracy->setValue(slider_pos); +} + +void HacksWidget::SaveSettings() +{ + int slider_pos = m_accuracy->value(); + + if (m_accuracy->isEnabled()) + { + int samples = 0; + switch (slider_pos) + { + case 0: + samples = 0; + break; + case 1: + samples = 512; + break; + case 2: + samples = 128; + } + + Config::SetBaseOrCurrent(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES, samples); + } +} + +void HacksWidget::AddDescriptions() +{ + static const char* TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION = + QT_TR_NOOP("Ignore any requests from the CPU to read from or write to the EFB.\nImproves " + "performance in some games, but might disable some gameplay-related features or " + "graphical effects.\n\nIf unsure, leave this unchecked."); + static const char* TR_IGNORE_FORMAT_CHANGE_DESCRIPTION = QT_TR_NOOP( + "Ignore any changes to the EFB format.\nImproves performance in many games without " + "any negative effect. Causes graphical defects in a small number of other " + "games.\n\nIf unsure, leave this checked."); + static const char* TR_STORE_EFB_TO_TEXTURE_DESCRIPTION = QT_TR_NOOP( + "Stores EFB Copies exclusively on the GPU, bypassing system memory. Causes graphical defects " + "in a small number of games.\n\nEnabled = EFB Copies to Texture\nDisabled = EFB Copies to " + "RAM " + "(and Texture)\n\nIf unsure, leave this checked."); + static const char* TR_ACCUARCY_DESCRIPTION = QT_TR_NOOP( + "The \"Safe\" setting eliminates the likelihood of the GPU missing texture updates " + "from RAM.\nLower accuracies cause in-game text to appear garbled in certain " + "games.\n\nIf unsure, use the rightmost value."); + + static const char* TR_DISABLE_XFB_DESCRIPTION = QT_TR_NOOP( + "Disable any XFB emulation.\nSpeeds up emulation a lot but causes heavy glitches in many " + "games " + "which rely on them (especially homebrew applications).\n\nIf unsure, leave this checked."); + static const char* TR_VIRTUAL_XFB_DESCRIPTION = QT_TR_NOOP( + "Emulate XFBs using GPU texture objects.\nFixes many games which don't work without XFB " + "emulation while not being as slow as real XFB emulation. However, it may still fail for " + "a lot " + "of other games (especially homebrew applications).\n\nIf unsure, leave this checked."); + + static const char* TR_REAL_XFB_DESCRIPTION = + QT_TR_NOOP("Emulate XFBs accurately.\nSlows down emulation a lot and prohibits " + "high-resolution rendering but is necessary to emulate a number of games " + "properly.\n\nIf unsure, check virtual XFB emulation instead."); + + static const char* TR_GPU_DECODING_DESCRIPTION = + QT_TR_NOOP("Enables texture decoding using the GPU instead of the CPU. This may result in " + "performance gains in some scenarios, or on systems where the CPU is the " + "bottleneck.\n\nIf unsure, leave this unchecked."); + + static const char* TR_FAST_DEPTH_CALC_DESCRIPTION = QT_TR_NOOP( + "Use a less accurate algorithm to calculate depth values.\nCauses issues in a few " + "games, but can give a decent speedup depending on the game and/or your GPU.\n\nIf " + "unsure, leave this checked."); + static const char* TR_DISABLE_BOUNDINGBOX_DESCRIPTION = + QT_TR_NOOP("Disable the bounding box emulation.\nThis may improve the GPU performance a lot, " + "but some games will break.\n\nIf unsure, leave this checked."); + static const char* TR_VERTEX_ROUNDING_DESCRIPTION = + QT_TR_NOOP("Rounds 2D vertices to whole pixels. Fixes graphical problems in some games at " + "higher internal resolutions. This setting has no effect when native internal " + "resolution is used.\n\nIf unsure, leave this unchecked."); + + AddDescription(m_skip_efb_cpu, TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION); + AddDescription(m_ignore_format_changes, TR_IGNORE_FORMAT_CHANGE_DESCRIPTION); + AddDescription(m_store_efb_copies, TR_STORE_EFB_TO_TEXTURE_DESCRIPTION); + AddDescription(m_accuracy, TR_ACCUARCY_DESCRIPTION); + AddDescription(m_disable_xfb, TR_DISABLE_XFB_DESCRIPTION); + AddDescription(m_virtual_xfb, TR_VIRTUAL_XFB_DESCRIPTION); + AddDescription(m_real_xfb, TR_REAL_XFB_DESCRIPTION); + AddDescription(m_gpu_texture_decoding, TR_GPU_DECODING_DESCRIPTION); + AddDescription(m_fast_depth_calculation, TR_FAST_DEPTH_CALC_DESCRIPTION); + AddDescription(m_disable_bounding_box, TR_DISABLE_BOUNDINGBOX_DESCRIPTION); + AddDescription(m_fast_depth_calculation, TR_FAST_DEPTH_CALC_DESCRIPTION); + AddDescription(m_disable_bounding_box, TR_DISABLE_BOUNDINGBOX_DESCRIPTION); + AddDescription(m_vertex_rounding, TR_VERTEX_ROUNDING_DESCRIPTION); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h new file mode 100644 index 0000000000..d652a10b3f --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h @@ -0,0 +1,48 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; +class QRadioButton; +class QSlider; + +class HacksWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit HacksWidget(GraphicsWindow* parent); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void OnXFBToggled(); + + // EFB + QCheckBox* m_skip_efb_cpu; + QCheckBox* m_ignore_format_changes; + QCheckBox* m_store_efb_copies; + + // Texture Cache + QSlider* m_accuracy; + QCheckBox* m_gpu_texture_decoding; + + // External Framebuffer + QCheckBox* m_disable_xfb; + QRadioButton* m_virtual_xfb; + QRadioButton* m_real_xfb; + + // Other + QCheckBox* m_fast_depth_calculation; + QCheckBox* m_disable_bounding_box; + QCheckBox* m_vertex_rounding; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); +}; From 4d37190327366a152951306fadfffa6c24893759 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 02:58:56 +0200 Subject: [PATCH 9/9] Make Visual Studio happy --- Source/Core/DolphinQt2/DolphinQt2.vcxproj | 34 +++++++++++++++++++++-- Source/Core/UICommon/UICommon.vcxproj | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj index 20e251a3b0..1a51b5e633 100644 --- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj +++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj @@ -47,7 +47,7 @@ avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) - $(ProjectDir)VideoInterface;$(ProjectDir)GameList;$(ProjectDir)Settings;$(ProjectDir)Config;$(ProjectDir)Config\Mapping;$(ProjectDir)QtUtils;%(AdditionalIncludeDirectories) + $(ProjectDir)VideoInterface;$(ProjectDir)GameList;$(ProjectDir)Settings;$(ProjectDir)Config;$(ProjectDir)Config\Mapping;$(ProjectDir)Config\Graphics;$(ProjectDir)QtUtils;%(AdditionalIncludeDirectories) DolphinQt2.manifest;%(AdditionalManifestFiles) @@ -66,6 +66,16 @@ + + + + + + + + + + @@ -92,6 +102,8 @@ + + @@ -99,6 +111,13 @@ + + + + + + + @@ -116,10 +135,21 @@ + + + + + + + + + + + @@ -268,4 +298,4 @@ - + \ No newline at end of file diff --git a/Source/Core/UICommon/UICommon.vcxproj b/Source/Core/UICommon/UICommon.vcxproj index 1b5f3521d4..643a5e9829 100644 --- a/Source/Core/UICommon/UICommon.vcxproj +++ b/Source/Core/UICommon/UICommon.vcxproj @@ -50,6 +50,7 @@ 4200;%(DisableSpecificWarnings) +