mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-25 23:29:55 -06:00
305 lines
9.0 KiB
C++
305 lines
9.0 KiB
C++
/*
|
|
Copyright 2016-2024 melonDS team
|
|
|
|
This file is part of melonDS.
|
|
|
|
melonDS is free software: you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation, either version 3 of the License, or (at your option)
|
|
any later version.
|
|
|
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
#include <QFileDialog>
|
|
#include <QtGlobal>
|
|
|
|
#include "types.h"
|
|
#include "Platform.h"
|
|
#include "Config.h"
|
|
#include "GPU.h"
|
|
#include "main.h"
|
|
|
|
#include "VideoSettingsDialog.h"
|
|
#include "ui_VideoSettingsDialog.h"
|
|
|
|
|
|
inline bool VideoSettingsDialog::UsesGL()
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
return cfg.GetBool("Screen.UseGL") || (cfg.GetInt("3D.Renderer") != renderer3D_Software);
|
|
}
|
|
|
|
VideoSettingsDialog* VideoSettingsDialog::currentDlg = nullptr;
|
|
|
|
void VideoSettingsDialog::setEnabled()
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
int renderer = cfg.GetInt("3D.Renderer");
|
|
int oglDisplay = cfg.GetBool("Screen.UseGL");
|
|
|
|
if (!computeGl)
|
|
{
|
|
ui->rb3DCompute->setEnabled(false);
|
|
if (renderer == renderer3D_OpenGLCompute) // fallback to software renderer
|
|
{
|
|
ui->rb3DSoftware->setChecked(true);
|
|
renderer = renderer3D_Software;
|
|
}
|
|
}
|
|
|
|
if (!baseGl) // fallback to software renderer
|
|
{
|
|
renderer = renderer3D_Software;
|
|
oglDisplay = false;
|
|
|
|
ui->rb3DOpenGL->setEnabled(false);
|
|
ui->cbGLDisplay->setChecked(false);
|
|
ui->rb3DSoftware->setChecked(true);
|
|
}
|
|
|
|
cfg.SetInt("3D.Renderer", renderer);
|
|
cfg.SetBool("Screen.UseGL", oglDisplay);
|
|
bool softwareRenderer = renderer == renderer3D_Software;
|
|
|
|
ui->cbGLDisplay->setEnabled(softwareRenderer && baseGl);
|
|
setVsyncControlEnable(oglDisplay || !softwareRenderer);
|
|
ui->cbSoftwareThreaded->setEnabled(softwareRenderer);
|
|
ui->cbxGLResolution->setEnabled(!softwareRenderer);
|
|
ui->cbBetterPolygons->setEnabled(renderer == renderer3D_OpenGL);
|
|
ui->cbxComputeHiResCoords->setEnabled(renderer == renderer3D_OpenGLCompute);
|
|
}
|
|
|
|
int VideoSettingsDialog::getsupportedRenderers()
|
|
{
|
|
ScreenPanelGL *glPanel = new ScreenPanelGL(this);
|
|
std::optional<WindowInfo> windowInfo = glPanel->getWindowInfo();
|
|
|
|
int renderer = renderer3D_Software;
|
|
|
|
if (windowInfo.has_value())
|
|
{
|
|
std::array<GL::Context::Version, 2> versionsToTry = {
|
|
GL::Context::Version{GL::Context::Profile::Core, 4, 3},
|
|
GL::Context::Version{GL::Context::Profile::Core, 3, 2}
|
|
};
|
|
|
|
std::unique_ptr<GL::Context> glContext = GL::Context::Create(*windowInfo, versionsToTry);
|
|
|
|
if (glContext)
|
|
{
|
|
const char* glVersionStr = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
|
|
|
if (glVersionStr)
|
|
{
|
|
int gl_version = 0;
|
|
|
|
// A proper version string or object isn't provided, so we have to parse it ourselves
|
|
if (isdigit(glVersionStr[0]) && isdigit(glVersionStr[2]))
|
|
gl_version = (glVersionStr[0] - '0') * 100 +
|
|
(glVersionStr[2] - '0') * 10;
|
|
|
|
// OpenGL 4.3 is required for Compute Shaders while 3.2 is the base requirement
|
|
if (gl_version >= 430)
|
|
renderer = renderer3D_OpenGLCompute;
|
|
else if (gl_version >= 320)
|
|
renderer = renderer3D_OpenGL;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete glPanel;
|
|
|
|
return renderer;
|
|
}
|
|
|
|
VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::VideoSettingsDialog)
|
|
{
|
|
ui->setupUi(this);
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
emuInstance = ((MainWindow*)parent)->getEmuInstance();
|
|
int supportedRenderers = getsupportedRenderers();
|
|
|
|
baseGl = supportedRenderers > renderer3D_Software;
|
|
computeGl = supportedRenderers == renderer3D_OpenGLCompute;
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
oldRenderer = cfg.GetInt("3D.Renderer");
|
|
oldGLDisplay = cfg.GetBool("Screen.UseGL");
|
|
oldVSync = cfg.GetBool("Screen.VSync");
|
|
oldVSyncInterval = cfg.GetInt("Screen.VSyncInterval");
|
|
oldSoftThreaded = cfg.GetBool("3D.Soft.Threaded");
|
|
oldGLScale = cfg.GetInt("3D.GL.ScaleFactor");
|
|
oldGLBetterPolygons = cfg.GetBool("3D.GL.BetterPolygons");
|
|
oldHiresCoordinates = cfg.GetBool("3D.GL.HiresCoordinates");
|
|
|
|
grp3DRenderer = new QButtonGroup(this);
|
|
grp3DRenderer->addButton(ui->rb3DSoftware, renderer3D_Software);
|
|
grp3DRenderer->addButton(ui->rb3DOpenGL, renderer3D_OpenGL);
|
|
grp3DRenderer->addButton(ui->rb3DCompute, renderer3D_OpenGLCompute);
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
|
connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int)));
|
|
#else
|
|
connect(grp3DRenderer, SIGNAL(idClicked(int)), this, SLOT(onChange3DRenderer(int)));
|
|
#endif
|
|
grp3DRenderer->button(oldRenderer)->setChecked(true);
|
|
|
|
#ifndef OGLRENDERER_ENABLED
|
|
ui->rb3DOpenGL->setEnabled(false);
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
ui->rb3DCompute->setEnabled(false);
|
|
#endif
|
|
|
|
ui->cbGLDisplay->setChecked(oldGLDisplay != 0);
|
|
|
|
ui->cbVSync->setChecked(oldVSync != 0);
|
|
ui->sbVSyncInterval->setValue(oldVSyncInterval);
|
|
|
|
ui->cbSoftwareThreaded->setChecked(oldSoftThreaded);
|
|
|
|
for (int i = 1; i <= 16; i++)
|
|
ui->cbxGLResolution->addItem(QString("%1x native (%2x%3)").arg(i).arg(256*i).arg(192*i));
|
|
ui->cbxGLResolution->setCurrentIndex(oldGLScale-1);
|
|
|
|
ui->cbBetterPolygons->setChecked(oldGLBetterPolygons != 0);
|
|
ui->cbxComputeHiResCoords->setChecked(oldHiresCoordinates != 0);
|
|
|
|
if (!oldVSync)
|
|
ui->sbVSyncInterval->setEnabled(false);
|
|
setVsyncControlEnable(UsesGL());
|
|
|
|
setEnabled();
|
|
}
|
|
|
|
VideoSettingsDialog::~VideoSettingsDialog()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void VideoSettingsDialog::on_VideoSettingsDialog_accepted()
|
|
{
|
|
Config::Save();
|
|
|
|
closeDlg();
|
|
}
|
|
|
|
void VideoSettingsDialog::on_VideoSettingsDialog_rejected()
|
|
{
|
|
if (!((MainWindow*)parent())->getEmuInstance())
|
|
{
|
|
closeDlg();
|
|
return;
|
|
}
|
|
|
|
bool old_gl = UsesGL();
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetInt("3D.Renderer", oldRenderer);
|
|
cfg.SetBool("Screen.UseGL", oldGLDisplay);
|
|
cfg.SetBool("Screen.VSync", oldVSync);
|
|
cfg.SetInt("Screen.VSyncInterval", oldVSyncInterval);
|
|
cfg.SetBool("3D.Soft.Threaded", oldSoftThreaded);
|
|
cfg.SetInt("3D.GL.ScaleFactor", oldGLScale);
|
|
cfg.SetBool("3D.GL.BetterPolygons", oldGLBetterPolygons);
|
|
cfg.SetBool("3D.GL.HiresCoordinates", oldHiresCoordinates);
|
|
|
|
emit updateVideoSettings(old_gl != UsesGL());
|
|
|
|
closeDlg();
|
|
}
|
|
|
|
void VideoSettingsDialog::setVsyncControlEnable(bool hasOGL)
|
|
{
|
|
ui->label_2->setEnabled(hasOGL);
|
|
ui->cbVSync->setEnabled(hasOGL);
|
|
ui->sbVSyncInterval->setEnabled(hasOGL);
|
|
}
|
|
|
|
void VideoSettingsDialog::onChange3DRenderer(int renderer)
|
|
{
|
|
bool old_gl = UsesGL();
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetInt("3D.Renderer", renderer);
|
|
|
|
setEnabled();
|
|
|
|
emit updateVideoSettings(old_gl != UsesGL());
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbGLDisplay_stateChanged(int state)
|
|
{
|
|
bool old_gl = UsesGL();
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetBool("Screen.UseGL", (state != 0));
|
|
|
|
setVsyncControlEnable(UsesGL());
|
|
|
|
emit updateVideoSettings(old_gl != UsesGL());
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbVSync_stateChanged(int state)
|
|
{
|
|
bool vsync = (state != 0);
|
|
ui->sbVSyncInterval->setEnabled(vsync);
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetBool("Screen.VSync", vsync);
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|
|
|
|
void VideoSettingsDialog::on_sbVSyncInterval_valueChanged(int val)
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetInt("Screen.VSyncInterval", val);
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbSoftwareThreaded_stateChanged(int state)
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetBool("3D.Soft.Threaded", (state != 0));
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbxGLResolution_currentIndexChanged(int idx)
|
|
{
|
|
// prevent a spurious change
|
|
if (ui->cbxGLResolution->count() < 16) return;
|
|
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetInt("3D.GL.ScaleFactor", idx+1);
|
|
|
|
setVsyncControlEnable(UsesGL());
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbBetterPolygons_stateChanged(int state)
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetBool("3D.GL.BetterPolygons", (state != 0));
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|
|
|
|
void VideoSettingsDialog::on_cbxComputeHiResCoords_stateChanged(int state)
|
|
{
|
|
auto& cfg = emuInstance->getGlobalConfig();
|
|
cfg.SetBool("3D.GL.HiresCoordinates", (state != 0));
|
|
|
|
emit updateVideoSettings(false);
|
|
}
|