mirror of https://github.com/mgba-emu/mgba.git
GBA: Add bilinear resampling option
This commit is contained in:
parent
7c8f1d9726
commit
f53f9555a2
1
CHANGES
1
CHANGES
|
@ -5,6 +5,7 @@ Features:
|
||||||
- Debugger: Add CLI "frame", frame advance command
|
- Debugger: Add CLI "frame", frame advance command
|
||||||
- Better audio resampling via FFmpeg
|
- Better audio resampling via FFmpeg
|
||||||
- Settings window
|
- Settings window
|
||||||
|
- Bilinear resampling option
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Qt: Fix issue with set frame sizes being the wrong height
|
- Qt: Fix issue with set frame sizes being the wrong height
|
||||||
- Qt: Fix emulator crashing when full screen if a game is not running
|
- Qt: Fix emulator crashing when full screen if a game is not running
|
||||||
|
|
|
@ -199,6 +199,9 @@ void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) {
|
||||||
if (_lookupIntValue(config, "lockAspectRatio", &fakeBool)) {
|
if (_lookupIntValue(config, "lockAspectRatio", &fakeBool)) {
|
||||||
opts->lockAspectRatio = fakeBool;
|
opts->lockAspectRatio = fakeBool;
|
||||||
}
|
}
|
||||||
|
if (_lookupIntValue(config, "resampleVideo", &fakeBool)) {
|
||||||
|
opts->resampleVideo = fakeBool;
|
||||||
|
}
|
||||||
|
|
||||||
_lookupIntValue(config, "fullscreen", &opts->fullscreen);
|
_lookupIntValue(config, "fullscreen", &opts->fullscreen);
|
||||||
_lookupIntValue(config, "width", &opts->width);
|
_lookupIntValue(config, "width", &opts->width);
|
||||||
|
@ -219,6 +222,7 @@ void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* op
|
||||||
ConfigurationSetIntValue(&config->defaultsTable, 0, "width", opts->width);
|
ConfigurationSetIntValue(&config->defaultsTable, 0, "width", opts->width);
|
||||||
ConfigurationSetIntValue(&config->defaultsTable, 0, "height", opts->height);
|
ConfigurationSetIntValue(&config->defaultsTable, 0, "height", opts->height);
|
||||||
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio);
|
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio);
|
||||||
|
ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAConfigFreeOpts(struct GBAOptions* opts) {
|
void GBAConfigFreeOpts(struct GBAOptions* opts) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct GBAOptions {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
bool lockAspectRatio;
|
bool lockAspectRatio;
|
||||||
|
bool resampleVideo;
|
||||||
|
|
||||||
bool videoSync;
|
bool videoSync;
|
||||||
bool audioSync;
|
bool audioSync;
|
||||||
|
|
|
@ -55,6 +55,7 @@ void Display::startDrawing(const uint32_t* buffer, GBAThread* thread) {
|
||||||
m_drawThread->start(QThread::TimeCriticalPriority);
|
m_drawThread->start(QThread::TimeCriticalPriority);
|
||||||
|
|
||||||
lockAspectRatio(m_lockAspectRatio);
|
lockAspectRatio(m_lockAspectRatio);
|
||||||
|
filter(m_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::stopDrawing() {
|
void Display::stopDrawing() {
|
||||||
|
@ -114,6 +115,13 @@ void Display::lockAspectRatio(bool lock) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::filter(bool filter) {
|
||||||
|
m_filter = filter;
|
||||||
|
if (m_drawThread) {
|
||||||
|
QMetaObject::invokeMethod(m_painter, "filter", Qt::QueuedConnection, Q_ARG(bool, filter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_PNG
|
#ifdef USE_PNG
|
||||||
void Display::screenshot() {
|
void Display::screenshot() {
|
||||||
GBAThreadInterrupt(m_context);
|
GBAThreadInterrupt(m_context);
|
||||||
|
@ -163,6 +171,18 @@ void Painter::lockAspectRatio(bool lock) {
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Painter::filter(bool filter) {
|
||||||
|
m_filter = filter;
|
||||||
|
m_gl->makeCurrent();
|
||||||
|
if (m_filter) {
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
m_gl->doneCurrent();
|
||||||
|
forceDraw();
|
||||||
|
}
|
||||||
|
|
||||||
void Painter::start() {
|
void Painter::start() {
|
||||||
m_gl->makeCurrent();
|
m_gl->makeCurrent();
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
@ -170,7 +190,11 @@ void Painter::start() {
|
||||||
glBindTexture(GL_TEXTURE_2D, m_tex);
|
glBindTexture(GL_TEXTURE_2D, m_tex);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
if (m_filter) {
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertexPointer(2, GL_INT, 0, _glVertices);
|
glVertexPointer(2, GL_INT, 0, _glVertices);
|
||||||
|
|
|
@ -28,6 +28,7 @@ public slots:
|
||||||
void unpauseDrawing();
|
void unpauseDrawing();
|
||||||
void forceDraw();
|
void forceDraw();
|
||||||
void lockAspectRatio(bool lock);
|
void lockAspectRatio(bool lock);
|
||||||
|
void filter(bool filter);
|
||||||
#ifdef USE_PNG
|
#ifdef USE_PNG
|
||||||
void screenshot();
|
void screenshot();
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,6 +43,7 @@ private:
|
||||||
QThread* m_drawThread;
|
QThread* m_drawThread;
|
||||||
GBAThread* m_context;
|
GBAThread* m_context;
|
||||||
bool m_lockAspectRatio;
|
bool m_lockAspectRatio;
|
||||||
|
bool m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Painter : public QObject {
|
class Painter : public QObject {
|
||||||
|
@ -62,6 +64,7 @@ public slots:
|
||||||
void unpause();
|
void unpause();
|
||||||
void resize(const QSize& size);
|
void resize(const QSize& size);
|
||||||
void lockAspectRatio(bool lock);
|
void lockAspectRatio(bool lock);
|
||||||
|
void filter(bool filter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void performDraw();
|
void performDraw();
|
||||||
|
@ -73,6 +76,7 @@ private:
|
||||||
QGLWidget* m_gl;
|
QGLWidget* m_gl;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
bool m_lockAspectRatio;
|
bool m_lockAspectRatio;
|
||||||
|
bool m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ SettingsView::SettingsView(ConfigController* controller, QWidget* parent)
|
||||||
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
||||||
loadSetting("rewindBufferInterval", m_ui.rewindInterval);
|
loadSetting("rewindBufferInterval", m_ui.rewindInterval);
|
||||||
loadSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
loadSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
||||||
|
loadSetting("resampleVideo", m_ui.resampleVideo);
|
||||||
|
|
||||||
connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios()));
|
connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios()));
|
||||||
connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
|
connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
|
||||||
|
@ -46,6 +47,7 @@ void SettingsView::updateConfig() {
|
||||||
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
|
||||||
saveSetting("rewindBufferInterval", m_ui.rewindInterval);
|
saveSetting("rewindBufferInterval", m_ui.rewindInterval);
|
||||||
saveSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
saveSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
||||||
|
saveSetting("resampleVideo", m_ui.resampleVideo);
|
||||||
m_controller->write();
|
m_controller->write();
|
||||||
|
|
||||||
emit biosLoaded(m_ui.bios->text());
|
emit biosLoaded(m_ui.bios->text());
|
||||||
|
|
|
@ -224,9 +224,6 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="QCheckBox" name="resampleVideo">
|
<widget class="QCheckBox" name="resampleVideo">
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Resample video</string>
|
<string>Resample video</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -138,6 +138,7 @@ void Window::loadConfig() {
|
||||||
m_controller->setAudioSync(opts->audioSync);
|
m_controller->setAudioSync(opts->audioSync);
|
||||||
m_controller->setVideoSync(opts->videoSync);
|
m_controller->setVideoSync(opts->videoSync);
|
||||||
m_display->lockAspectRatio(opts->lockAspectRatio);
|
m_display->lockAspectRatio(opts->lockAspectRatio);
|
||||||
|
m_display->filter(opts->resampleVideo);
|
||||||
|
|
||||||
if (opts->bios) {
|
if (opts->bios) {
|
||||||
m_controller->loadBIOS(opts->bios);
|
m_controller->loadBIOS(opts->bios);
|
||||||
|
@ -532,6 +533,11 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
lockAspectRatio->connect([this](const QVariant& value) { m_display->lockAspectRatio(value.toBool()); });
|
lockAspectRatio->connect([this](const QVariant& value) { m_display->lockAspectRatio(value.toBool()); });
|
||||||
m_config->updateOption("lockAspectRatio");
|
m_config->updateOption("lockAspectRatio");
|
||||||
|
|
||||||
|
ConfigOption* resampleVideo = m_config->addOption("resampleVideo");
|
||||||
|
resampleVideo->addBoolean(tr("Resample video"), avMenu);
|
||||||
|
resampleVideo->connect([this](const QVariant& value) { m_display->filter(value.toBool()); });
|
||||||
|
m_config->updateOption("resampleVideo");
|
||||||
|
|
||||||
QMenu* skipMenu = avMenu->addMenu(tr("Frame&skip"));
|
QMenu* skipMenu = avMenu->addMenu(tr("Frame&skip"));
|
||||||
ConfigOption* skip = m_config->addOption("frameskip");
|
ConfigOption* skip = m_config->addOption("frameskip");
|
||||||
skip->connect([this](const QVariant& value) { m_controller->setFrameskip(value.toInt()); });
|
skip->connect([this](const QVariant& value) { m_controller->setFrameskip(value.toInt()); });
|
||||||
|
|
|
@ -64,8 +64,13 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||||
glGenTextures(1, &renderer->tex);
|
glGenTextures(1, &renderer->tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, renderer->tex);
|
glBindTexture(GL_TEXTURE_2D, renderer->tex);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
if (renderer->filter) {
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
|
@ -75,6 +75,9 @@ int main(int argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
renderer.ratio = graphicsOpts.multiplier;
|
renderer.ratio = graphicsOpts.multiplier;
|
||||||
|
|
||||||
|
renderer.lockAspectRatio = opts.lockAspectRatio;
|
||||||
|
renderer.filter = opts.resampleVideo;
|
||||||
|
|
||||||
if (!_GBASDLInit(&renderer)) {
|
if (!_GBASDLInit(&renderer)) {
|
||||||
freeArguments(&args);
|
freeArguments(&args);
|
||||||
GBAConfigFreeOpts(&opts);
|
GBAConfigFreeOpts(&opts);
|
||||||
|
|
|
@ -48,6 +48,9 @@ struct SDLSoftwareRenderer {
|
||||||
int viewportHeight;
|
int viewportHeight;
|
||||||
int ratio;
|
int ratio;
|
||||||
|
|
||||||
|
bool lockAspectRatio;
|
||||||
|
bool filter;
|
||||||
|
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue