Merge pull request #5615 from spycrab/qt_graphics

Qt: Implement graphics window
This commit is contained in:
shuffle2 2017-06-28 12:05:00 -07:00 committed by GitHub
commit c29c1f92af
31 changed files with 2129 additions and 66 deletions

View File

@ -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,16 @@ 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/Graphics/SoftwareRendererWidget.cpp
Config/InfoWidget.cpp
Config/Mapping/GCKeyboardEmu.cpp
Config/Mapping/GCPadEmu.cpp

View File

@ -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 <QCheckBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QVBoxLayout>
#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/<game_id>/.\n\nIf unsure, leave "
"this unchecked.");
static const char* TR_LOAD_CUSTOM_TEXTURE_DESCRIPTION = QT_TR_NOOP(
"Load custom textures from User/Load/Textures/<game_id>/.\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
}

View File

@ -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;
};

View File

@ -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 <cmath>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[this](int) { SaveSettings(); });
connect(m_pp_effect, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[this](int) { SaveSettings(); });
connect(m_3d_mode, static_cast<void (QComboBox::*)(int)>(&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<std::string> 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<unsigned int>(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);
}

View File

@ -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;
};

View File

@ -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 <QCheckBox>
#include <QComboBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QVBoxLayout>
#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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[this](int) { SaveSettings(); });
// Fullscreen Resolution
connect(m_resolution_combo,
static_cast<void (QComboBox::*)(int)>(&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
}

View File

@ -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;
};

View File

@ -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 <QFont>
GraphicsBool::GraphicsBool(const QString& label, const Config::ConfigInfo<bool>& 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<bool>(isChecked() ^ m_reverse));
}
GraphicsBoolEx::GraphicsBoolEx(const QString& label, const Config::ConfigInfo<bool>& 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<bool>(isChecked() ^ m_reverse));
}

View File

@ -0,0 +1,41 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QCheckBox>
#include <QRadioButton>
namespace Config
{
template <typename T>
struct ConfigInfo;
};
class GraphicsBool : public QCheckBox
{
Q_OBJECT
public:
GraphicsBool(const QString& label, const Config::ConfigInfo<bool>& setting, bool reverse = false);
private:
void Update();
const Config::ConfigInfo<bool>& m_setting;
bool m_reverse;
};
class GraphicsBoolEx : public QRadioButton
{
Q_OBJECT
public:
GraphicsBoolEx(const QString& label, const Config::ConfigInfo<bool>& setting,
bool reverse = false);
private:
void Update();
const Config::ConfigInfo<bool>& m_setting;
bool m_reverse;
};

View File

@ -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<int>& setting)
: m_setting(setting)
{
addItems(options);
connect(this, static_cast<void (QComboBox::*)(int)>(&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);
}

View File

@ -0,0 +1,24 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QComboBox>
namespace Config
{
template <typename T>
struct ConfigInfo;
};
class GraphicsChoice : public QComboBox
{
public:
GraphicsChoice(const QStringList& options, const Config::ConfigInfo<int>& setting);
private:
void Update(int choice);
const Config::ConfigInfo<int>& m_setting;
};

View File

@ -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<int>& 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);
}

View File

@ -0,0 +1,23 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QSlider>
namespace Config
{
template <typename T>
struct ConfigInfo;
};
class GraphicsSlider : public QSlider
{
public:
GraphicsSlider(int minimum, int maximum, const Config::ConfigInfo<int>& setting, int tick = 0);
void Update(int value);
private:
const Config::ConfigInfo<int>& m_setting;
};

View File

@ -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 <QEvent>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QVBoxLayout>
#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);
}

View File

@ -0,0 +1,34 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QWidget>
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;
};

View File

@ -0,0 +1,141 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "DolphinQt2/Config/Graphics/GraphicsWindow.h"
#include <QDialogButtonBox>
#include <QEvent>
#include <QGroupBox>
#include <QLabel>
#include <QTabWidget>
#include <QVBoxLayout>
#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/Config/Graphics/SoftwareRendererWidget.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);
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(m_general_widget, &GeneralWidget::BackendChanged, this,
&GraphicsWindow::OnBackendChanged);
connect(m_software_renderer, &SoftwareRendererWidget::BackendChanged, this,
&GraphicsWindow::OnBackendChanged);
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);
}
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));
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);
}
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;
}

View File

@ -0,0 +1,58 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QDialog>
#include <QHash>
class AdvancedWidget;
class EnhancementsWidget;
class HacksWidget;
class GeneralWidget;
class GraphicsWidget;
class MainWindow;
class QLabel;
class QTabWidget;
class QDialogButtonBox;
class SoftwareRendererWidget;
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;
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<QObject*, const char*> m_widget_descriptions;
};

View File

@ -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 <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QVBoxLayout>
#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);
}

View File

@ -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();
};

View File

@ -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 <QComboBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QSpinBox>
#include <QVBoxLayout>
#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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[this](int) { SaveSettings(); });
connect(m_object_range_min, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
[this](int) { SaveSettings(); });
connect(m_object_range_max, static_cast<void (QSpinBox::*)(int)>(&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/<game_id>/.\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);
}

View File

@ -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;
};

View File

@ -47,7 +47,7 @@
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)VideoInterface;$(ProjectDir)GameList;$(ProjectDir)Settings;$(ProjectDir)Config;$(ProjectDir)Config\Mapping;$(ProjectDir)QtUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)VideoInterface;$(ProjectDir)GameList;$(ProjectDir)Settings;$(ProjectDir)Config;$(ProjectDir)Config\Mapping;$(ProjectDir)Config\Graphics;$(ProjectDir)QtUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Manifest>
<AdditionalManifestFiles>DolphinQt2.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
@ -66,6 +66,16 @@
<QtMoc Include="Config\Mapping\MappingButton.h" />
<QtMoc Include="Config\Mapping\MappingWidget.h" />
<QtMoc Include="Config\Mapping\MappingWindow.h" />
<QtMoc Include="Config\Graphics\AdvancedWidget.h" />
<QtMoc Include="Config\Graphics\EnhancementsWidget.h" />
<QtMoc Include="Config\Graphics\GeneralWidget.h" />
<QtMoc Include="Config\Graphics\GraphicsBool.h" />
<QtMoc Include="Config\Graphics\GraphicsChoice.h" />
<QtMoc Include="Config\Graphics\GraphicsSlider.h" />
<QtMoc Include="Config\Graphics\GraphicsWidget.h" />
<QtMoc Include="Config\Graphics\GraphicsWindow.h" />
<QtMoc Include="Config\Graphics\HacksWidget.h" />
<QtMoc Include="Config\Graphics\SoftwareRendererWidget.h" />
<QtMoc Include="Config\InfoWidget.h" />
<QtMoc Include="Config\PropertiesDialog.h" />
<QtMoc Include="Config\SettingsWindow.h" />
@ -92,6 +102,8 @@
<ItemGroup>
<ClCompile Include="$(QtMocOutPrefix)AboutDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)AudioPane.cpp" />
<ClCompile Include="$(QtMocOutPrefix)AdvancedWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)EnhancementsWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ControllersWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)FilesystemWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)WindowActivationEventFilter.cpp" />
@ -99,6 +111,13 @@
<ClCompile Include="$(QtMocOutPrefix)GameListModel.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GameTracker.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GeneralPane.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GeneralWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsBool.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsChoice.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsSlider.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)HacksWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)Host.cpp" />
<ClCompile Include="$(QtMocOutPrefix)HotkeyScheduler.cpp" />
<ClCompile Include="$(QtMocOutPrefix)InDevelopmentWarning.cpp" />
@ -116,10 +135,21 @@
<ClCompile Include="$(QtMocOutPrefix)RenderWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)Settings.cpp" />
<ClCompile Include="$(QtMocOutPrefix)SettingsWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)SoftwareRendererWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ToolBar.cpp" />
<ClCompile Include="AboutDialog.cpp" />
<ClCompile Include="Config\ControllersWindow.cpp" />
<ClCompile Include="Config\FilesystemWidget.cpp" />
<ClCompile Include="Config\Graphics\AdvancedWidget.cpp" />
<ClCompile Include="Config\Graphics\EnhancementsWidget.cpp" />
<ClCompile Include="Config\Graphics\HacksWidget.cpp" />
<ClCompile Include="Config\Graphics\GeneralWidget.cpp" />
<ClCompile Include="Config\Graphics\GraphicsBool.cpp" />
<ClCompile Include="Config\Graphics\GraphicsChoice.cpp" />
<ClCompile Include="Config\Graphics\GraphicsSlider.cpp" />
<ClCompile Include="Config\Graphics\GraphicsWidget.cpp" />
<ClCompile Include="Config\Graphics\GraphicsWindow.cpp" />
<ClCompile Include="Config\Graphics\SoftwareRendererWidget.cpp" />
<ClCompile Include="Config\InfoWidget.cpp" />
<ClCompile Include="Config\Mapping\GCKeyboardEmu.cpp" />
<ClCompile Include="Config\Mapping\GCPadEmu.cpp" />
@ -268,4 +298,4 @@
<Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
</Target>
</Project>
</Project>

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <QApplication>
#include <QCloseEvent>
#include <QDir>
#include <QDragEnterEvent>
@ -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 <qpa/qplatformnativeinterface.h>
#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<Display*>(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(),

View File

@ -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;
};

View File

@ -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"));
}

View File

@ -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;
};

View File

@ -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<std::string> 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<std::string> 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(_("<No resolutions found>"));
label_display_resolution =

View File

@ -3,6 +3,7 @@ set(SRCS
Disassembler.cpp
UICommon.cpp
USBUtils.cpp
VideoUtils.cpp
)
if(USE_X11)

View File

@ -50,6 +50,7 @@
<ClCompile Include="USBUtils.cpp">
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="VideoUtils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CommandLineParse.h" />

View File

@ -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<std::string> GetAvailableResolutions(X11Utils::XRRConfiguration* xrr_config)
{
std::vector<std::string> 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<std::string> GetAvailableAntialiasingModes(int& msaa_modes)
{
std::vector<std::string> 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;
}
}

View File

@ -0,0 +1,22 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <string>
#include <vector>
namespace X11Utils
{
class XRRConfiguration;
}
namespace VideoUtils
{
#if !defined(__APPLE__)
std::vector<std::string> GetAvailableResolutions(X11Utils::XRRConfiguration* xrr_config);
#endif
std::vector<std::string> GetAvailableAntialiasingModes(int& m_msaa_modes);
}