all repos — mgba @ f53f9555a26461fee86ba676e4f04d8bdecf7c40

mGBA Game Boy Advance Emulator

GBA: Add bilinear resampling option
Jeffrey Pfau jeffrey@endrift.com
Sun, 21 Dec 2014 16:50:55 -0800
commit

f53f9555a26461fee86ba676e4f04d8bdecf7c40

parent

7c8f1d9726eb246aac895fe90297a0ecd1ebe13a

M CHANGESCHANGES

@@ -5,6 +5,7 @@ - Add scale presets for up to 6x

- Debugger: Add CLI "frame", frame advance command - Better audio resampling via FFmpeg - Settings window + - Bilinear resampling option Bugfixes: - Qt: Fix issue with set frame sizes being the wrong height - Qt: Fix emulator crashing when full screen if a game is not running
M src/gba/gba-config.csrc/gba/gba-config.c

@@ -199,6 +199,9 @@ }

if (_lookupIntValue(config, "lockAspectRatio", &fakeBool)) { opts->lockAspectRatio = fakeBool; } + if (_lookupIntValue(config, "resampleVideo", &fakeBool)) { + opts->resampleVideo = fakeBool; + } _lookupIntValue(config, "fullscreen", &opts->fullscreen); _lookupIntValue(config, "width", &opts->width);

@@ -219,6 +222,7 @@ ConfigurationSetIntValue(&config->defaultsTable, 0, "fullscreen", opts->fullscreen);

ConfigurationSetIntValue(&config->defaultsTable, 0, "width", opts->width); ConfigurationSetIntValue(&config->defaultsTable, 0, "height", opts->height); ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio); + ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo); } void GBAConfigFreeOpts(struct GBAOptions* opts) {
M src/gba/gba-config.hsrc/gba/gba-config.h

@@ -29,6 +29,7 @@ int fullscreen;

int width; int height; bool lockAspectRatio; + bool resampleVideo; bool videoSync; bool audioSync;
M src/platform/qt/Display.cppsrc/platform/qt/Display.cpp

@@ -55,6 +55,7 @@ connect(m_drawThread, SIGNAL(started()), m_painter, SLOT(start()));

m_drawThread->start(QThread::TimeCriticalPriority); lockAspectRatio(m_lockAspectRatio); + filter(m_filter); } void Display::stopDrawing() {

@@ -114,6 +115,13 @@ QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Qt::QueuedConnection, Q_ARG(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 void Display::screenshot() { GBAThreadInterrupt(m_context);

@@ -163,6 +171,18 @@ m_lockAspectRatio = lock;

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() { m_gl->makeCurrent(); glEnable(GL_TEXTURE_2D);

@@ -170,7 +190,11 @@ glGenTextures(1, &m_tex);

glBindTexture(GL_TEXTURE_2D, m_tex); 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_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_VERTEX_ARRAY); glVertexPointer(2, GL_INT, 0, _glVertices);
M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -28,6 +28,7 @@ void pauseDrawing();

void unpauseDrawing(); void forceDraw(); void lockAspectRatio(bool lock); + void filter(bool filter); #ifdef USE_PNG void screenshot(); #endif

@@ -42,6 +43,7 @@ Painter* m_painter;

QThread* m_drawThread; GBAThread* m_context; bool m_lockAspectRatio; + bool m_filter; }; class Painter : public QObject {

@@ -62,6 +64,7 @@ void pause();

void unpause(); void resize(const QSize& size); void lockAspectRatio(bool lock); + void filter(bool filter); private: void performDraw();

@@ -73,6 +76,7 @@ GLuint m_tex;

QGLWidget* m_gl; QSize m_size; bool m_lockAspectRatio; + bool m_filter; }; }
M src/platform/qt/SettingsView.cppsrc/platform/qt/SettingsView.cpp

@@ -25,6 +25,7 @@ loadSetting("frameskip", m_ui.frameskip);

loadSetting("lockAspectRatio", m_ui.lockAspectRatio); loadSetting("rewindBufferInterval", m_ui.rewindInterval); loadSetting("rewindBufferCapacity", m_ui.rewindCapacity); + loadSetting("resampleVideo", m_ui.resampleVideo); connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios())); connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));

@@ -46,6 +47,7 @@ saveSetting("frameskip", m_ui.frameskip);

saveSetting("lockAspectRatio", m_ui.lockAspectRatio); saveSetting("rewindBufferInterval", m_ui.rewindInterval); saveSetting("rewindBufferCapacity", m_ui.rewindCapacity); + saveSetting("resampleVideo", m_ui.resampleVideo); m_controller->write(); emit biosLoaded(m_ui.bios->text());
M src/platform/qt/SettingsView.uisrc/platform/qt/SettingsView.ui

@@ -224,9 +224,6 @@ </widget>

</item> <item row="10" column="1"> <widget class="QCheckBox" name="resampleVideo"> - <property name="enabled"> - <bool>false</bool> - </property> <property name="text"> <string>Resample video</string> </property>
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -138,6 +138,7 @@ m_controller->setFrameskip(opts->frameskip);

m_controller->setAudioSync(opts->audioSync); m_controller->setVideoSync(opts->videoSync); m_display->lockAspectRatio(opts->lockAspectRatio); + m_display->filter(opts->resampleVideo); if (opts->bios) { m_controller->loadBIOS(opts->bios);

@@ -531,6 +532,11 @@ ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio");

lockAspectRatio->addBoolean(tr("Lock aspect ratio"), avMenu); lockAspectRatio->connect([this](const QVariant& value) { m_display->lockAspectRatio(value.toBool()); }); 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")); ConfigOption* skip = m_config->addOption("frameskip");
M src/platform/sdl/gl-sdl.csrc/platform/sdl/gl-sdl.c

@@ -64,8 +64,13 @@ renderer->d.outputBufferStride = 256;

glGenTextures(1, &renderer->tex); glBindTexture(GL_TEXTURE_2D, renderer->tex); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + if (renderer->filter) { + 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 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
M src/platform/sdl/main.csrc/platform/sdl/main.c

@@ -75,6 +75,9 @@ renderer.events.windowUpdated = 0;

#endif renderer.ratio = graphicsOpts.multiplier; + renderer.lockAspectRatio = opts.lockAspectRatio; + renderer.filter = opts.resampleVideo; + if (!_GBASDLInit(&renderer)) { freeArguments(&args); GBAConfigFreeOpts(&opts);
M src/platform/sdl/main.hsrc/platform/sdl/main.h

@@ -48,6 +48,9 @@ int viewportWidth;

int viewportHeight; int ratio; + bool lockAspectRatio; + bool filter; + #ifdef BUILD_GL GLuint tex; #endif