all repos — mgba @ d0604c35af4e1540238fe4d7bfd71367163f5f4e

mGBA Game Boy Advance Emulator

Qt: Add ability to lock aspect ratio (fixes #147)
Jeffrey Pfau jeffrey@endrift.com
Tue, 16 Dec 2014 01:33:08 -0800
commit

d0604c35af4e1540238fe4d7bfd71367163f5f4e

parent

e58182c9522edf3d130d6f86aa0c45ec32cd5aee

M src/gba/gba-config.csrc/gba/gba-config.c

@@ -196,6 +196,9 @@ }

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

@@ -215,6 +218,7 @@ ConfigurationSetIntValue(&config->defaultsTable, 0, "videoSync", opts->videoSync);

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); } void GBAConfigFreeOpts(struct GBAOptions* opts) {
M src/gba/gba-config.hsrc/gba/gba-config.h

@@ -28,6 +28,7 @@

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

@@ -53,6 +53,8 @@ doneCurrent();

context()->moveToThread(m_drawThread); connect(m_drawThread, SIGNAL(started()), m_painter, SLOT(start())); m_drawThread->start(QThread::TimeCriticalPriority); + + lockAspectRatio(m_lockAspectRatio); } void Display::stopDrawing() {

@@ -105,6 +107,13 @@ QMetaObject::invokeMethod(m_painter, "forceDraw", Qt::QueuedConnection);

} } +void Display::lockAspectRatio(bool lock) { + m_lockAspectRatio = lock; + if (m_drawThread) { + QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Qt::QueuedConnection, Q_ARG(bool, lock)); + } +} + #ifdef USE_PNG void Display::screenshot() { GBAThreadInterrupt(m_context);

@@ -131,6 +140,7 @@ }

Painter::Painter(Display* parent) : m_gl(parent) + , m_lockAspectRatio(false) { m_size = parent->size(); }

@@ -145,11 +155,12 @@ }

void Painter::resize(const QSize& size) { m_size = size; - m_gl->makeCurrent(); - glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - m_gl->swapBuffers(); - m_gl->doneCurrent(); + forceDraw(); +} + +void Painter::lockAspectRatio(bool lock) { + m_lockAspectRatio = lock; + forceDraw(); } void Painter::start() {

@@ -181,12 +192,7 @@

void Painter::draw() { m_gl->makeCurrent(); if (GBASyncWaitFrameStart(&m_context->sync, m_context->frameskip)) { - glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_backing); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - if (m_context->sync.videoFrameWait) { - glFlush(); - } + performDraw(); } GBASyncWaitFrameEnd(&m_context->sync); m_gl->swapBuffers();

@@ -195,12 +201,7 @@ }

void Painter::forceDraw() { m_gl->makeCurrent(); - glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_backing); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - if (m_context->sync.videoFrameWait) { - glFlush(); - } + performDraw(); m_gl->swapBuffers(); m_gl->doneCurrent(); }

@@ -226,3 +227,25 @@

void Painter::unpause() { m_drawTimer->start(); } + +void Painter::performDraw() { + glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); + glClear(GL_COLOR_BUFFER_BIT); + int w = m_size.width() * m_gl->devicePixelRatio(); + int h = m_size.height() * m_gl->devicePixelRatio(); + int drawW = w; + int drawH = h; + if (m_lockAspectRatio) { + if (w * 2 > h * 3) { + drawW = h * 3 / 2; + } else if (w * 2 < h * 3) { + drawH = w * 2 / 3; + } + } + glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_backing); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + if (m_context->sync.videoFrameWait) { + glFlush(); + } +}
M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -27,6 +27,7 @@ void stopDrawing();

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

@@ -40,6 +41,7 @@ private:

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

@@ -59,14 +61,18 @@ void stop();

void pause(); void unpause(); void resize(const QSize& size); + void lockAspectRatio(bool lock); private: + void performDraw(); + QTimer* m_drawTimer; GBAThread* m_context; const uint32_t* m_backing; GLuint m_tex; QGLWidget* m_gl; QSize m_size; + bool m_lockAspectRatio; }; }
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -133,6 +133,7 @@

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

@@ -508,6 +509,11 @@ resizeFrame(VIDEO_HORIZONTAL_PIXELS * 4, VIDEO_VERTICAL_PIXELS * 4);

}); frameMenu->addAction(setSize); addAction(frameMenu->addAction(tr("Fullscreen"), this, SLOT(toggleFullScreen()), QKeySequence("Ctrl+F"))); + + 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"); QMenu* skipMenu = avMenu->addMenu(tr("Frame&skip")); ConfigOption* skip = m_config->addOption("frameskip");