mirror of https://github.com/mgba-emu/mgba.git
Qt: Begin work on shader selector
This commit is contained in:
parent
ded463ea25
commit
64901c0afe
|
@ -94,6 +94,7 @@ set(SOURCE_FILES
|
||||||
SavestateButton.cpp
|
SavestateButton.cpp
|
||||||
SensorView.cpp
|
SensorView.cpp
|
||||||
SettingsView.cpp
|
SettingsView.cpp
|
||||||
|
ShaderSelector.cpp
|
||||||
ShortcutController.cpp
|
ShortcutController.cpp
|
||||||
ShortcutView.cpp
|
ShortcutView.cpp
|
||||||
Swatch.cpp
|
Swatch.cpp
|
||||||
|
@ -113,6 +114,7 @@ qt5_wrap_ui(UI_FILES
|
||||||
PaletteView.ui
|
PaletteView.ui
|
||||||
SensorView.ui
|
SensorView.ui
|
||||||
SettingsView.ui
|
SettingsView.ui
|
||||||
|
ShaderSelector.ui
|
||||||
ShortcutView.ui
|
ShortcutView.ui
|
||||||
VideoView.ui)
|
VideoView.ui)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
struct GBAThread;
|
struct GBAThread;
|
||||||
struct VDir;
|
struct VDir;
|
||||||
|
struct VideoShader;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ public:
|
||||||
|
|
||||||
virtual bool isDrawing() const = 0;
|
virtual bool isDrawing() const = 0;
|
||||||
virtual bool supportsShaders() const = 0;
|
virtual bool supportsShaders() const = 0;
|
||||||
|
virtual VideoShader* shaders() = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showCursor();
|
void showCursor();
|
||||||
|
|
|
@ -44,6 +44,16 @@ bool DisplayGL::supportsShaders() const {
|
||||||
return m_painter->supportsShaders();
|
return m_painter->supportsShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoShader* DisplayGL::shaders() {
|
||||||
|
VideoShader* shaders = nullptr;
|
||||||
|
if (m_drawThread) {
|
||||||
|
QMetaObject::invokeMethod(m_painter, "shaders", Qt::BlockingQueuedConnection, Q_RETURN_ARG(VideoShader*, shaders));
|
||||||
|
} else {
|
||||||
|
shaders = m_painter->shaders();
|
||||||
|
}
|
||||||
|
return shaders;
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayGL::startDrawing(GBAThread* thread) {
|
void DisplayGL::startDrawing(GBAThread* thread) {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
return;
|
return;
|
||||||
|
@ -158,8 +168,7 @@ PainterGL::PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlags glVersion)
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_started(false)
|
, m_started(false)
|
||||||
, m_context(nullptr)
|
, m_context(nullptr)
|
||||||
, m_shaders(nullptr)
|
, m_shader{}
|
||||||
, m_nShaders(0)
|
|
||||||
, m_backend(nullptr)
|
, m_backend(nullptr)
|
||||||
, m_messagePainter(nullptr)
|
, m_messagePainter(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +218,9 @@ PainterGL::~PainterGL() {
|
||||||
}
|
}
|
||||||
delete m_backend;
|
delete m_backend;
|
||||||
m_backend = nullptr;
|
m_backend = nullptr;
|
||||||
|
if (m_shader.passes) {
|
||||||
|
GBAGLES2ShaderFree(&m_shader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::setContext(GBAThread* context) {
|
void PainterGL::setContext(GBAThread* context) {
|
||||||
|
@ -248,8 +260,8 @@ void PainterGL::start() {
|
||||||
m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId()));
|
m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId()));
|
||||||
|
|
||||||
#if !defined(_WIN32) || defined(USE_EPOXY)
|
#if !defined(_WIN32) || defined(USE_EPOXY)
|
||||||
if (m_shaders) {
|
if (m_shader.passes) {
|
||||||
GBAGLES2ShaderAttach(reinterpret_cast<GBAGLES2Context*>(m_backend), m_shaders, m_nShaders);
|
GBAGLES2ShaderAttach(reinterpret_cast<GBAGLES2Context*>(m_backend), static_cast<GBAGLES2Shader*>(m_shader.passes), m_shader.nPasses);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -366,13 +378,18 @@ void PainterGL::setShaders(struct VDir* dir) {
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
#if defined(_WIN32) && defined(USE_EPOXY)
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
epoxy_handle_external_wglMakeCurrent();
|
||||||
#endif
|
#endif
|
||||||
if (m_shaders) {
|
if (m_shader.passes) {
|
||||||
GBAGLES2ShaderDetach(reinterpret_cast<GBAGLES2Context*>(m_backend));
|
GBAGLES2ShaderDetach(reinterpret_cast<GBAGLES2Context*>(m_backend));
|
||||||
|
GBAGLES2ShaderFree(&m_shader);
|
||||||
}
|
}
|
||||||
GBAGLES2ShaderLoad(&m_shaders, &m_nShaders, nullptr, dir);
|
GBAGLES2ShaderLoad(&m_shader, dir);
|
||||||
if (m_started) {
|
if (m_started) {
|
||||||
GBAGLES2ShaderAttach(reinterpret_cast<GBAGLES2Context*>(m_backend), m_shaders, m_nShaders);
|
GBAGLES2ShaderAttach(reinterpret_cast<GBAGLES2Context*>(m_backend), static_cast<GBAGLES2Shader*>(m_shader.passes), m_shader.nPasses);
|
||||||
}
|
}
|
||||||
m_gl->doneCurrent();
|
m_gl->doneCurrent();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoShader* PainterGL::shaders() {
|
||||||
|
return &m_shader;
|
||||||
|
}
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "platform/video-backend.h"
|
||||||
|
}
|
||||||
|
|
||||||
struct GBAThread;
|
struct GBAThread;
|
||||||
struct VideoBackend;
|
|
||||||
struct GBAGLES2Shader;
|
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ public:
|
||||||
|
|
||||||
bool isDrawing() const override { return m_isDrawing; }
|
bool isDrawing() const override { return m_isDrawing; }
|
||||||
bool supportsShaders() const override;
|
bool supportsShaders() const override;
|
||||||
|
VideoShader* shaders() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startDrawing(GBAThread* context) override;
|
void startDrawing(GBAThread* context) override;
|
||||||
|
@ -96,6 +99,7 @@ public slots:
|
||||||
void filter(bool filter);
|
void filter(bool filter);
|
||||||
|
|
||||||
void setShaders(struct VDir*);
|
void setShaders(struct VDir*);
|
||||||
|
VideoShader* shaders();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void performDraw();
|
void performDraw();
|
||||||
|
@ -111,8 +115,7 @@ private:
|
||||||
bool m_started;
|
bool m_started;
|
||||||
GBAThread* m_context;
|
GBAThread* m_context;
|
||||||
bool m_supportsShaders;
|
bool m_supportsShaders;
|
||||||
GBAGLES2Shader* m_shaders;
|
VideoShader m_shader;
|
||||||
size_t m_nShaders;
|
|
||||||
VideoBackend* m_backend;
|
VideoBackend* m_backend;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
MessagePainter* m_messagePainter;
|
MessagePainter* m_messagePainter;
|
||||||
|
|
|
@ -22,7 +22,8 @@ public:
|
||||||
DisplayQt(QWidget* parent = nullptr);
|
DisplayQt(QWidget* parent = nullptr);
|
||||||
|
|
||||||
bool isDrawing() const override { return m_isDrawing; }
|
bool isDrawing() const override { return m_isDrawing; }
|
||||||
bool supportsShaders() const override { return 0; }
|
bool supportsShaders() const override { return false; }
|
||||||
|
VideoShader* shaders() override { return nullptr; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startDrawing(GBAThread* context) override;
|
void startDrawing(GBAThread* context) override;
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "ShaderSelector.h"
|
||||||
|
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "platform/video-backend.h"
|
||||||
|
|
||||||
|
#if !defined(_WIN32) || defined(USE_EPOXY)
|
||||||
|
#include "platform/opengl/gles2.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace QGBA;
|
||||||
|
|
||||||
|
ShaderSelector::ShaderSelector(Display* display, QWidget* parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_display(display)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
refreshShaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderSelector::~ShaderSelector() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderSelector::clear() {
|
||||||
|
m_ui.shaderName->setText(tr("No shader active"));
|
||||||
|
m_ui.description->clear();
|
||||||
|
m_ui.author->clear();
|
||||||
|
|
||||||
|
while (QWidget* page = m_ui.passes->widget(0)) {
|
||||||
|
m_ui.passes->removeTab(0);
|
||||||
|
delete page;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderSelector::refreshShaders() {
|
||||||
|
clear();
|
||||||
|
m_shaders = m_display->shaders();
|
||||||
|
if (!m_shaders) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ui.shaderName->setText(m_shaders->name);
|
||||||
|
m_ui.description->setText(m_shaders->description);
|
||||||
|
m_ui.author->setText(tr("by %1").arg(m_shaders->author));
|
||||||
|
|
||||||
|
#if !defined(_WIN32) || defined(USE_EPOXY)
|
||||||
|
GBAGLES2Shader* shaders = static_cast<GBAGLES2Shader*>(m_shaders->passes);
|
||||||
|
for (size_t p = 0; p < m_shaders->nPasses; ++p) {
|
||||||
|
QWidget* page = new QWidget;
|
||||||
|
QFormLayout* layout = new QFormLayout;
|
||||||
|
page->setLayout(layout);
|
||||||
|
for (size_t u = 0 ; u < shaders[p].nUniforms; ++u) {
|
||||||
|
QGridLayout* settings = new QGridLayout;
|
||||||
|
std::function<void (size_t, size_t)> bind;
|
||||||
|
GBAGLES2Uniform* uniform = &shaders[p].uniforms[u];
|
||||||
|
switch (uniform->type) {
|
||||||
|
case GL_FLOAT:
|
||||||
|
addUniform(settings, &uniform->value.f, uniform->min.f, uniform->max.f, 0, 0);
|
||||||
|
break;
|
||||||
|
case GL_FLOAT_VEC2:
|
||||||
|
addUniform(settings, &uniform->value.fvec2[0], uniform->min.fvec2[0], uniform->max.fvec2[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.fvec2[1], uniform->min.fvec2[1], uniform->max.fvec2[1], 0, 1);
|
||||||
|
break;
|
||||||
|
case GL_FLOAT_VEC3:
|
||||||
|
addUniform(settings, &uniform->value.fvec3[0], uniform->min.fvec3[0], uniform->max.fvec3[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.fvec3[1], uniform->min.fvec3[1], uniform->max.fvec3[1], 0, 1);
|
||||||
|
addUniform(settings, &uniform->value.fvec3[2], uniform->min.fvec3[2], uniform->max.fvec3[2], 0, 2);
|
||||||
|
break;
|
||||||
|
case GL_FLOAT_VEC4:
|
||||||
|
addUniform(settings, &uniform->value.fvec4[0], uniform->min.fvec4[0], uniform->max.fvec4[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.fvec4[1], uniform->min.fvec4[1], uniform->max.fvec4[1], 0, 1);
|
||||||
|
addUniform(settings, &uniform->value.fvec4[2], uniform->min.fvec4[2], uniform->max.fvec4[2], 0, 2);
|
||||||
|
addUniform(settings, &uniform->value.fvec4[3], uniform->min.fvec4[3], uniform->max.fvec4[3], 0, 3);
|
||||||
|
break;
|
||||||
|
case GL_INT:
|
||||||
|
addUniform(settings, &uniform->value.i, uniform->min.i, uniform->max.i, 0, 0);
|
||||||
|
break;
|
||||||
|
case GL_INT_VEC2:
|
||||||
|
addUniform(settings, &uniform->value.ivec2[0], uniform->min.ivec2[0], uniform->max.ivec2[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.ivec2[1], uniform->min.ivec2[1], uniform->max.ivec2[1], 0, 1);
|
||||||
|
break;
|
||||||
|
case GL_INT_VEC3:
|
||||||
|
addUniform(settings, &uniform->value.ivec3[0], uniform->min.ivec3[0], uniform->max.ivec3[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.ivec3[1], uniform->min.ivec3[1], uniform->max.ivec3[1], 0, 1);
|
||||||
|
addUniform(settings, &uniform->value.ivec3[2], uniform->min.ivec3[2], uniform->max.ivec3[2], 0, 2);
|
||||||
|
break;
|
||||||
|
case GL_INT_VEC4:
|
||||||
|
addUniform(settings, &uniform->value.ivec4[0], uniform->min.ivec4[0], uniform->max.ivec4[0], 0, 0);
|
||||||
|
addUniform(settings, &uniform->value.ivec4[1], uniform->min.ivec4[1], uniform->max.ivec4[1], 0, 1);
|
||||||
|
addUniform(settings, &uniform->value.ivec4[2], uniform->min.ivec4[2], uniform->max.ivec4[2], 0, 2);
|
||||||
|
addUniform(settings, &uniform->value.ivec4[3], uniform->min.ivec4[3], uniform->max.ivec4[3], 0, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
layout->addRow(shaders[p].uniforms[u].readableName, settings);
|
||||||
|
}
|
||||||
|
m_ui.passes->addTab(page, tr("Pass %1").arg(p + 1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderSelector::addUniform(QGridLayout* settings, float* value, float min, float max, int y, int x) {
|
||||||
|
QDoubleSpinBox* f = new QDoubleSpinBox;
|
||||||
|
f->setDecimals(3);
|
||||||
|
if (min < max) {
|
||||||
|
f->setMinimum(min);
|
||||||
|
f->setMaximum(max);
|
||||||
|
}
|
||||||
|
f->setValue(*value);
|
||||||
|
f->setSingleStep(0.001);
|
||||||
|
f->setAccelerated(true);
|
||||||
|
settings->addWidget(f, y, x);
|
||||||
|
connect(f, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [value](double v) {
|
||||||
|
*value = v;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderSelector::addUniform(QGridLayout* settings, int* value, int min, int max, int y, int x) {
|
||||||
|
QSpinBox* i = new QSpinBox;
|
||||||
|
if (min < max) {
|
||||||
|
i->setMinimum(min);
|
||||||
|
i->setMaximum(max);
|
||||||
|
}
|
||||||
|
i->setValue(*value);
|
||||||
|
i->setSingleStep(1);
|
||||||
|
i->setAccelerated(true);
|
||||||
|
settings->addWidget(i, y, x);
|
||||||
|
connect(i, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [value](int v) {
|
||||||
|
*value = v;
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef QGBA_SHADER_SELECTOR_H
|
||||||
|
#define QGBA_SHADER_SELECTOR_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "ui_ShaderSelector.h"
|
||||||
|
|
||||||
|
class QGridLayout;
|
||||||
|
struct VideoShader;
|
||||||
|
|
||||||
|
namespace QGBA {
|
||||||
|
|
||||||
|
class Display;
|
||||||
|
|
||||||
|
class ShaderSelector : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShaderSelector(Display* display, QWidget* parent = nullptr);
|
||||||
|
~ShaderSelector();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void refreshShaders();
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addUniform(QGridLayout*, float* value, float min, float max, int y, int x);
|
||||||
|
void addUniform(QGridLayout*, int* value, int min, int max, int y, int x);
|
||||||
|
|
||||||
|
Ui::ShaderSelector m_ui;
|
||||||
|
Display* m_display;
|
||||||
|
VideoShader* m_shaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ShaderSelector</class>
|
||||||
|
<widget class="QDialog" name="ShaderSelector">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Shaders</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Active Shader:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="shaderName">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="author">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="description">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="passes">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ShaderSelector</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -33,6 +33,7 @@
|
||||||
#include "PaletteView.h"
|
#include "PaletteView.h"
|
||||||
#include "SensorView.h"
|
#include "SensorView.h"
|
||||||
#include "SettingsView.h"
|
#include "SettingsView.h"
|
||||||
|
#include "ShaderSelector.h"
|
||||||
#include "ShortcutController.h"
|
#include "ShortcutController.h"
|
||||||
#include "ShortcutView.h"
|
#include "ShortcutView.h"
|
||||||
#include "VideoView.h"
|
#include "VideoView.h"
|
||||||
|
@ -395,6 +396,11 @@ void Window::openAboutScreen() {
|
||||||
openView(about);
|
openView(about);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::openShaderWindow() {
|
||||||
|
ShaderSelector* shaderView = new ShaderSelector(m_display);
|
||||||
|
openView(shaderView);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
void Window::openGamepadWindow() {
|
void Window::openGamepadWindow() {
|
||||||
const char* profile = m_inputController.profileForType(SDL_BINDING_BUTTON);
|
const char* profile = m_inputController.profileForType(SDL_BINDING_BUTTON);
|
||||||
|
@ -1048,6 +1054,13 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
}
|
}
|
||||||
m_config->updateOption("frameskip");
|
m_config->updateOption("frameskip");
|
||||||
|
|
||||||
|
QAction* shaderView = new QAction(tr("Shader options..."), avMenu);
|
||||||
|
connect(shaderView, SIGNAL(triggered()), this, SLOT(openShaderWindow()));
|
||||||
|
if (!m_display->supportsShaders()) {
|
||||||
|
shaderView->setEnabled(false);
|
||||||
|
}
|
||||||
|
addControlledAction(avMenu, shaderView, "shaderSelector");
|
||||||
|
|
||||||
avMenu->addSeparator();
|
avMenu->addSeparator();
|
||||||
|
|
||||||
QMenu* target = avMenu->addMenu(tr("FPS target"));
|
QMenu* target = avMenu->addMenu(tr("FPS target"));
|
||||||
|
|
|
@ -88,6 +88,8 @@ public slots:
|
||||||
|
|
||||||
void openAboutScreen();
|
void openAboutScreen();
|
||||||
|
|
||||||
|
void openShaderWindow();
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
void openGamepadWindow();
|
void openGamepadWindow();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue