GBA: Add bilinear resampling option

This commit is contained in:
Jeffrey Pfau 2014-12-21 16:50:55 -08:00
parent 7c8f1d9726
commit f53f9555a2
11 changed files with 56 additions and 6 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;
}; };
} }

View File

@ -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());

View File

@ -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>

View File

@ -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()); });

View File

@ -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);

View File

@ -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);

View File

@ -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