2017-06-27 16:00:23 +00:00
|
|
|
// Copyright 2017 Dolphin Emulator Project
|
2021-07-05 01:22:19 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2017-06-27 16:00:23 +00:00
|
|
|
|
2018-07-06 22:40:15 +00:00
|
|
|
#include "DolphinQt/Config/Graphics/SoftwareRendererWidget.h"
|
2017-06-27 16:00:23 +00:00
|
|
|
|
|
|
|
#include <QComboBox>
|
|
|
|
#include <QGridLayout>
|
|
|
|
#include <QGroupBox>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QSpinBox>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
|
|
#include "Core/Config/GraphicsSettings.h"
|
2020-05-03 23:21:51 +00:00
|
|
|
#include "Core/Config/MainSettings.h"
|
2017-06-27 16:00:23 +00:00
|
|
|
#include "Core/ConfigManager.h"
|
2019-06-08 23:02:01 +00:00
|
|
|
#include "Core/Core.h"
|
2018-05-28 01:48:04 +00:00
|
|
|
|
2018-07-06 22:40:15 +00:00
|
|
|
#include "DolphinQt/Config/Graphics/GraphicsBool.h"
|
|
|
|
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
|
2020-10-21 01:03:15 +00:00
|
|
|
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
|
2018-07-06 22:40:15 +00:00
|
|
|
#include "DolphinQt/Settings.h"
|
2018-05-28 01:48:04 +00:00
|
|
|
|
2017-06-27 16:00:23 +00:00
|
|
|
#include "UICommon/VideoUtils.h"
|
2018-05-28 01:48:04 +00:00
|
|
|
|
2017-06-27 16:00:23 +00:00
|
|
|
#include "VideoCommon/VideoBackendBase.h"
|
|
|
|
#include "VideoCommon/VideoConfig.h"
|
|
|
|
|
2020-10-21 01:03:15 +00:00
|
|
|
SoftwareRendererWidget::SoftwareRendererWidget(GraphicsWindow* parent)
|
2017-06-27 16:00:23 +00:00
|
|
|
{
|
|
|
|
CreateWidgets();
|
|
|
|
LoadSettings();
|
|
|
|
ConnectWidgets();
|
|
|
|
AddDescriptions();
|
2020-05-03 23:21:51 +00:00
|
|
|
emit BackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
|
2019-06-08 23:02:01 +00:00
|
|
|
|
|
|
|
connect(parent, &GraphicsWindow::BackendChanged, [this] { LoadSettings(); });
|
|
|
|
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
|
|
|
[=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); });
|
|
|
|
OnEmulationStateChanged(Core::GetState() != Core::State::Uninitialized);
|
2017-06-27 16:00:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoftwareRendererWidget::CreateWidgets()
|
|
|
|
{
|
|
|
|
auto* main_layout = new QVBoxLayout;
|
|
|
|
|
|
|
|
auto* rendering_box = new QGroupBox(tr("Rendering"));
|
|
|
|
auto* rendering_layout = new QGridLayout();
|
2020-10-21 01:03:15 +00:00
|
|
|
m_backend_combo = new ToolTipComboBox();
|
2017-06-27 16:00:23 +00:00
|
|
|
|
|
|
|
rendering_box->setLayout(rendering_layout);
|
|
|
|
rendering_layout->addWidget(new QLabel(tr("Backend:")), 1, 1);
|
|
|
|
rendering_layout->addWidget(m_backend_combo, 1, 2);
|
|
|
|
|
2020-10-21 19:34:38 +00:00
|
|
|
for (const auto& backend : VideoBackendBase::GetAvailableBackends())
|
2017-06-27 16:00:23 +00:00
|
|
|
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);
|
2017-11-19 21:11:33 +00:00
|
|
|
m_show_statistics = new GraphicsBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS);
|
2017-06-27 16:00:23 +00:00
|
|
|
|
2017-11-19 21:11:33 +00:00
|
|
|
overlay_layout->addWidget(m_show_statistics);
|
2017-06-27 16:00:23 +00:00
|
|
|
|
|
|
|
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();
|
2017-07-23 10:58:32 +00:00
|
|
|
m_dump_tev_stages = new GraphicsBool(tr("Dump TEV Stages"), Config::GFX_SW_DUMP_TEV_STAGES);
|
2017-06-27 16:00:23 +00:00
|
|
|
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);
|
2017-09-14 16:48:20 +00:00
|
|
|
main_layout->addStretch();
|
2017-06-27 16:00:23 +00:00
|
|
|
|
|
|
|
setLayout(main_layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoftwareRendererWidget::ConnectWidgets()
|
|
|
|
{
|
2019-07-30 13:35:46 +00:00
|
|
|
connect(m_backend_combo, qOverload<int>(&QComboBox::currentIndexChanged),
|
2017-06-27 16:00:23 +00:00
|
|
|
[this](int) { SaveSettings(); });
|
2019-07-30 13:35:46 +00:00
|
|
|
connect(m_object_range_min, qOverload<int>(&QSpinBox::valueChanged),
|
2017-06-27 16:00:23 +00:00
|
|
|
[this](int) { SaveSettings(); });
|
2019-07-30 13:35:46 +00:00
|
|
|
connect(m_object_range_max, qOverload<int>(&QSpinBox::valueChanged),
|
2017-06-27 16:00:23 +00:00
|
|
|
[this](int) { SaveSettings(); });
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoftwareRendererWidget::LoadSettings()
|
|
|
|
{
|
2020-10-21 19:34:38 +00:00
|
|
|
for (const auto& backend : VideoBackendBase::GetAvailableBackends())
|
2017-06-27 16:00:23 +00:00
|
|
|
{
|
2020-05-03 23:21:51 +00:00
|
|
|
if (backend->GetName() == Config::Get(Config::MAIN_GFX_BACKEND))
|
|
|
|
{
|
2017-06-27 16:00:23 +00:00
|
|
|
m_backend_combo->setCurrentIndex(
|
|
|
|
m_backend_combo->findText(tr(backend->GetDisplayName().c_str())));
|
2020-05-03 23:21:51 +00:00
|
|
|
}
|
2017-06-27 16:00:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
2020-10-21 19:34:38 +00:00
|
|
|
for (const auto& backend : VideoBackendBase::GetAvailableBackends())
|
2017-06-27 16:00:23 +00:00
|
|
|
{
|
|
|
|
if (tr(backend->GetDisplayName().c_str()) == m_backend_combo->currentText())
|
|
|
|
{
|
|
|
|
const auto backend_name = backend->GetName();
|
2020-05-03 23:21:51 +00:00
|
|
|
if (backend_name != Config::Get(Config::MAIN_GFX_BACKEND))
|
2017-06-27 16:00:23 +00:00
|
|
|
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()
|
|
|
|
{
|
2020-10-21 01:03:15 +00:00
|
|
|
static const char TR_BACKEND_DESCRIPTION[] = QT_TR_NOOP(
|
|
|
|
"Selects what graphics API to use internally.<br>The 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.<br><br><dolphin_emphasis>If unsure, select "
|
|
|
|
"OpenGL.</dolphin_emphasis>");
|
2018-06-06 13:05:18 +00:00
|
|
|
static const char TR_SHOW_STATISTICS_DESCRIPTION[] =
|
2020-10-21 01:03:15 +00:00
|
|
|
QT_TR_NOOP("Show various rendering statistics.<br><br><dolphin_emphasis>If unsure, leave "
|
|
|
|
"this unchecked.</dolphin_emphasis>");
|
2018-06-06 13:05:18 +00:00
|
|
|
static const char TR_DUMP_TEXTURES_DESCRIPTION[] =
|
2021-02-27 19:17:28 +00:00
|
|
|
QT_TR_NOOP("Dump decoded game textures to "
|
|
|
|
"User/Dump/Textures/<game_id>/.<br><br><dolphin_emphasis>If unsure, leave "
|
2020-10-21 01:03:15 +00:00
|
|
|
"this unchecked.</dolphin_emphasis>");
|
2018-06-06 13:05:18 +00:00
|
|
|
static const char TR_DUMP_OBJECTS_DESCRIPTION[] =
|
2020-10-21 01:03:15 +00:00
|
|
|
QT_TR_NOOP("Dump objects to User/Dump/Objects/.<br><br><dolphin_emphasis>If unsure, leave "
|
|
|
|
"this unchecked.</dolphin_emphasis>");
|
2018-06-06 15:59:29 +00:00
|
|
|
static const char TR_DUMP_TEV_STAGES_DESCRIPTION[] =
|
2020-10-21 01:03:15 +00:00
|
|
|
QT_TR_NOOP("Dump TEV Stages to User/Dump/Objects/.<br><br><dolphin_emphasis>If unsure, leave "
|
|
|
|
"this unchecked.</dolphin_emphasis>");
|
|
|
|
static const char TR_DUMP_TEV_FETCHES_DESCRIPTION[] = QT_TR_NOOP(
|
|
|
|
"Dump Texture Fetches to User/Dump/Objects/.<br><br><dolphin_emphasis>If unsure, leave "
|
|
|
|
"this unchecked.</dolphin_emphasis>");
|
|
|
|
|
|
|
|
m_backend_combo->SetTitle(tr("Backend"));
|
2020-11-30 13:04:08 +00:00
|
|
|
m_backend_combo->SetDescription(tr(TR_BACKEND_DESCRIPTION));
|
|
|
|
m_show_statistics->SetDescription(tr(TR_SHOW_STATISTICS_DESCRIPTION));
|
|
|
|
m_dump_textures->SetDescription(tr(TR_DUMP_TEXTURES_DESCRIPTION));
|
|
|
|
m_dump_objects->SetDescription(tr(TR_DUMP_OBJECTS_DESCRIPTION));
|
|
|
|
m_dump_tev_stages->SetDescription(tr(TR_DUMP_TEV_STAGES_DESCRIPTION));
|
|
|
|
m_dump_tev_fetches->SetDescription(tr(TR_DUMP_TEV_FETCHES_DESCRIPTION));
|
2017-06-27 16:00:23 +00:00
|
|
|
}
|
2019-06-08 23:02:01 +00:00
|
|
|
|
|
|
|
void SoftwareRendererWidget::OnEmulationStateChanged(bool running)
|
|
|
|
{
|
|
|
|
m_backend_combo->setEnabled(!running);
|
|
|
|
}
|