mirror of https://github.com/mgba-emu/mgba.git
All: Add option to lock video to integer scaling
This commit is contained in:
parent
69a30f9501
commit
2d930cbc61
1
CHANGES
1
CHANGES
|
@ -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
|
||||
|
|
|
@ -42,6 +42,7 @@ struct mCoreOptions {
|
|||
int width;
|
||||
int height;
|
||||
bool lockAspectRatio;
|
||||
bool lockIntegerScaling;
|
||||
bool resampleVideo;
|
||||
bool suspendScreensaver;
|
||||
char* shader;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ struct VideoBackend {
|
|||
|
||||
bool filter;
|
||||
bool lockAspectRatio;
|
||||
bool lockIntegerScaling;
|
||||
};
|
||||
|
||||
struct VideoShader {
|
||||
|
|
Loading…
Reference in New Issue