All: Add option to lock video to integer scaling

This commit is contained in:
Vicki Pfau 2017-04-21 18:13:16 -07:00
parent 69a30f9501
commit 2d930cbc61
16 changed files with 81 additions and 4 deletions

View File

@ -15,6 +15,7 @@ Features:
- Command line ability to override configuration values
- Add option to allow preloading the entire ROM before running
- GB: Video/audio channel enabling/disabling
- Add option to lock video to integer scaling
Bugfixes:
- LR35902: Fix core never exiting with certain event patterns
- GB Timer: Improve DIV reset behavior

View File

@ -42,6 +42,7 @@ struct mCoreOptions {
int width;
int height;
bool lockAspectRatio;
bool lockIntegerScaling;
bool resampleVideo;
bool suspendScreensaver;
char* shader;

View File

@ -349,6 +349,9 @@ void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts)
if (_lookupIntValue(config, "lockAspectRatio", &fakeBool)) {
opts->lockAspectRatio = fakeBool;
}
if (_lookupIntValue(config, "lockIntegerScaling", &fakeBool)) {
opts->lockIntegerScaling = fakeBool;
}
if (_lookupIntValue(config, "resampleVideo", &fakeBool)) {
opts->resampleVideo = fakeBool;
}
@ -396,6 +399,7 @@ void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptio
ConfigurationSetIntValue(&config->defaultsTable, 0, "volume", opts->volume);
ConfigurationSetIntValue(&config->defaultsTable, 0, "mute", opts->mute);
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio);
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockIntegerScaling", opts->lockIntegerScaling);
ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo);
ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver);
}

View File

@ -65,6 +65,10 @@ static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h) {
drawH = w * v->height / v->width;
}
}
if (v->lockIntegerScaling) {
drawW -= drawW % v->width;
drawH -= drawH % v->height;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);

View File

@ -171,6 +171,10 @@ static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h)
drawH = w * v->height / v->width;
}
}
if (v->lockIntegerScaling) {
drawW -= drawW % v->width;
drawH -= drawH % v->height;
}
glViewport(0, 0, v->width, v->height);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);

View File

@ -54,6 +54,7 @@ Display* Display::create(QWidget* parent) {
Display::Display(QWidget* parent)
: QWidget(parent)
, m_lockAspectRatio(false)
, m_lockIntegerScaling(false)
, m_filter(false)
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
@ -77,6 +78,10 @@ void Display::lockAspectRatio(bool lock) {
m_messagePainter.resize(size(), m_lockAspectRatio, devicePixelRatio());
}
void Display::lockIntegerScaling(bool lock) {
m_lockIntegerScaling = lock;
}
void Display::filter(bool filter) {
m_filter = filter;
}

View File

@ -38,6 +38,7 @@ public:
static void setDriver(Driver driver) { s_driver = driver; }
bool isAspectRatioLocked() const { return m_lockAspectRatio; }
bool isIntegerScalingLocked() const { return m_lockIntegerScaling; }
bool isFiltered() const { return m_filter; }
virtual bool isDrawing() const = 0;
@ -55,6 +56,7 @@ public slots:
virtual void unpauseDrawing() = 0;
virtual void forceDraw() = 0;
virtual void lockAspectRatio(bool lock);
virtual void lockIntegerScaling(bool lock);
virtual void filter(bool filter);
virtual void framePosted(const uint32_t*) = 0;
virtual void setShaders(struct VDir*) = 0;
@ -74,6 +76,7 @@ private:
MessagePainter m_messagePainter;
bool m_lockAspectRatio;
bool m_lockIntegerScaling;
bool m_filter;
QTimer m_mouseTimer;
};

View File

@ -73,6 +73,7 @@ void DisplayGL::startDrawing(mCoreThread* thread) {
mCoreSyncSetVideoSync(&m_context->sync, false);
lockAspectRatio(isAspectRatioLocked());
lockIntegerScaling(isIntegerScalingLocked());
filter(isFiltered());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatioF());
@ -136,6 +137,13 @@ void DisplayGL::lockAspectRatio(bool lock) {
}
}
void DisplayGL::lockIntegerScaling(bool lock) {
Display::lockIntegerScaling(lock);
if (m_drawThread) {
QMetaObject::invokeMethod(m_painter, "lockIntegerScaling", Q_ARG(bool, lock));
}
}
void DisplayGL::filter(bool filter) {
Display::filter(filter);
if (m_drawThread) {
@ -290,6 +298,13 @@ void PainterGL::lockAspectRatio(bool lock) {
}
}
void PainterGL::lockIntegerScaling(bool lock) {
m_backend->lockIntegerScaling = lock;
if (m_started && !m_active) {
forceDraw();
}
}
void PainterGL::filter(bool filter) {
m_backend->filter = filter;
if (m_started && !m_active) {

View File

@ -55,6 +55,7 @@ public slots:
void unpauseDrawing() override;
void forceDraw() override;
void lockAspectRatio(bool lock) override;
void lockIntegerScaling(bool lock) override;
void filter(bool filter) override;
void framePosted(const uint32_t*) override;
void setShaders(struct VDir*) override;
@ -96,6 +97,7 @@ public slots:
void unpause();
void resize(const QSize& size);
void lockAspectRatio(bool lock);
void lockIntegerScaling(bool lock);
void filter(bool filter);
void setShaders(struct VDir*);

View File

@ -30,6 +30,11 @@ void DisplayQt::lockAspectRatio(bool lock) {
update();
}
void DisplayQt::lockIntegerScaling(bool lock) {
Display::lockIntegerScaling(lock);
update();
}
void DisplayQt::filter(bool filter) {
Display::filter(filter);
update();
@ -66,6 +71,10 @@ void DisplayQt::paintEvent(QPaintEvent*) {
ds.setHeight(s.width() * m_height / m_width);
}
}
if (isIntegerScalingLocked()) {
ds.setWidth(ds.width() - ds.width() % m_width);
ds.setHeight(ds.height() - ds.height() % m_height);
}
QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2);
QRect full(origin, ds);

View File

@ -30,6 +30,7 @@ public slots:
void unpauseDrawing() override { m_isDrawing = true; }
void forceDraw() override { update(); }
void lockAspectRatio(bool lock) override;
void lockIntegerScaling(bool lock) override;
void filter(bool filter) override;
void framePosted(const uint32_t*) override;
void setShaders(struct VDir*) override {}

View File

@ -190,6 +190,7 @@ void SettingsView::updateConfig() {
saveSetting("frameskip", m_ui.frameskip);
saveSetting("fpsTarget", m_ui.fpsTarget);
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
saveSetting("volume", m_ui.volume);
saveSetting("mute", m_ui.mute);
saveSetting("rewindEnable", m_ui.rewind);
@ -270,6 +271,7 @@ void SettingsView::reloadConfig() {
loadSetting("frameskip", m_ui.frameskip);
loadSetting("fpsTarget", m_ui.fpsTarget);
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
loadSetting("lockIntegerScaling", m_ui.lockIntegerScaling);
loadSetting("volume", m_ui.volume);
loadSetting("mute", m_ui.mute);
loadSetting("rewindEnable", m_ui.rewind);

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>650</width>
<height>450</height>
<height>454</height>
</rect>
</property>
<property name="sizePolicy">
@ -115,7 +115,7 @@
<property name="editable">
<bool>true</bool>
</property>
<property name="currentText" stdset="0">
<property name="currentText">
<string>1536</string>
</property>
<property name="currentIndex">
@ -181,7 +181,7 @@
<property name="editable">
<bool>true</bool>
</property>
<property name="currentText" stdset="0">
<property name="currentText">
<string>44100</string>
</property>
<property name="currentIndex">
@ -380,13 +380,20 @@
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QCheckBox" name="resampleVideo">
<property name="text">
<string>Bilinear filtering</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="lockIntegerScaling">
<property name="text">
<string>Force integer scaling</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="interface_2">

View File

@ -1263,6 +1263,14 @@ void Window::setupMenu(QMenuBar* menubar) {
}, this);
m_config->updateOption("lockAspectRatio");
ConfigOption* lockIntegerScaling = m_config->addOption("lockIntegerScaling");
lockIntegerScaling->addBoolean(tr("Force integer scaling"), avMenu);
lockIntegerScaling->connect([this](const QVariant& value) {
m_display->lockIntegerScaling(value.toBool());
m_screenWidget->setLockIntegerScaling(value.toBool());
}, this);
m_config->updateOption("lockIntegerScaling");
ConfigOption* resampleVideo = m_config->addOption("resampleVideo");
resampleVideo->addBoolean(tr("Bilinear filtering"), avMenu);
resampleVideo->connect([this](const QVariant& value) {
@ -1637,6 +1645,10 @@ void WindowBackground::setLockAspectRatio(int width, int height) {
m_aspectHeight = height;
}
void WindowBackground::setLockIntegerScaling(bool lock) {
m_lockIntegerScaling = lock;
}
void WindowBackground::paintEvent(QPaintEvent*) {
const QPixmap* logo = pixmap();
if (!logo) {
@ -1652,6 +1664,10 @@ void WindowBackground::paintEvent(QPaintEvent*) {
} else if (ds.width() * m_aspectHeight < ds.height() * m_aspectWidth) {
ds.setHeight(ds.width() * m_aspectHeight / m_aspectWidth);
}
if (m_lockIntegerScaling) {
ds.setWidth(ds.width() - ds.width() % m_aspectWidth);
ds.setHeight(ds.height() - ds.height() % m_aspectHeight);
}
QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2);
QRect full(origin, ds);
painter.drawPixmap(full, *logo);

View File

@ -210,6 +210,7 @@ public:
void setSizeHint(const QSize& size);
virtual QSize sizeHint() const override;
void setLockAspectRatio(int width, int height);
void setLockIntegerScaling(bool lock);
protected:
virtual void paintEvent(QPaintEvent*) override;
@ -218,6 +219,7 @@ private:
QSize m_sizeHint;
int m_aspectWidth;
int m_aspectHeight;
bool m_lockIntegerScaling;
};
}

View File

@ -35,6 +35,7 @@ struct VideoBackend {
bool filter;
bool lockAspectRatio;
bool lockIntegerScaling;
};
struct VideoShader {