all repos — mgba @ fae8ef7f422184be05a3567e8caa4a10aec801f4

mGBA Game Boy Advance Emulator

OpenGL: Make video dimensions customizable
Jeffrey Pfau jeffrey@endrift.com
Mon, 08 Feb 2016 20:48:01 -0800
commit

fae8ef7f422184be05a3567e8caa4a10aec801f4

parent

73b58ec7c43f70f899147bbc1ef83e0ea2a4f0a6

M src/platform/opengl/gl.csrc/platform/opengl/gl.c

@@ -21,7 +21,7 @@ 1, 1,

0, 1 }; -static void GBAGLContextInit(struct VideoBackend* v, unsigned width, unsigned height, WHandle handle) { +static void GBAGLContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct GBAGLContext* context = (struct GBAGLContext*) v; glGenTextures(1, &context->tex);

@@ -31,9 +31,14 @@ #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); #endif +} + +static void GBAGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { + struct GBAGLContext* context = (struct GBAGLContext*) v; v->width = width; v->height = height; + glBindTexture(GL_TEXTURE_2D, context->tex); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);

@@ -113,6 +118,7 @@

void GBAGLContextCreate(struct GBAGLContext* context) { context->d.init = GBAGLContextInit; context->d.deinit = GBAGLContextDeinit; + context->d.setDimensions = GBAGLContextSetDimensions; context->d.resized = GBAGLContextResized; context->d.swap = 0; context->d.clear = GBAGLContextClear;
M src/platform/opengl/gles2.csrc/platform/opengl/gles2.c

@@ -71,25 +71,13 @@ 1.f, 1.f,

1.f, -1.f, }; -static void GBAGLES2ContextInit(struct VideoBackend* v, unsigned width, unsigned height, WHandle handle) { +static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct GBAGLES2Context* context = (struct GBAGLES2Context*) v; glGenTextures(1, &context->tex); glBindTexture(GL_TEXTURE_2D, context->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - v->width = width; - v->height = height; - -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); -#endif glClearColor(0.f, 0.f, 0.f, 1.f);

@@ -142,6 +130,23 @@ glDeleteFramebuffers(1, &context->finalShader.fbo);

glDeleteTextures(1, &context->finalShader.tex); context->finalShader.fbo = 0; context->finalShader.tex = 0; +} + +static void GBAGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { + struct GBAGLES2Context* context = (struct GBAGLES2Context*) v; + v->width = width; + v->height = height; + + glBindTexture(GL_TEXTURE_2D, context->tex); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +#endif } static void GBAGLES2ContextDeinit(struct VideoBackend* v) {

@@ -312,6 +317,7 @@

void GBAGLES2ContextCreate(struct GBAGLES2Context* context) { context->d.init = GBAGLES2ContextInit; context->d.deinit = GBAGLES2ContextDeinit; + context->d.setDimensions = GBAGLES2ContextSetDimensions; context->d.resized = GBAGLES2ContextResized; context->d.swap = 0; context->d.clear = GBAGLES2ContextClear;
M src/platform/qt/DisplayGL.cppsrc/platform/qt/DisplayGL.cpp

@@ -221,7 +221,7 @@ m_gl->makeCurrent();

#if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif - m_backend->init(m_backend, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, reinterpret_cast<WHandle>(m_gl->winId())); + m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId())); #if !defined(_WIN32) || defined(USE_EPOXY) if (m_supportsShaders) { m_shader.preprocessShader = static_cast<void*>(&reinterpret_cast<GBAGLES2Context*>(m_backend)->initialShader);

@@ -262,6 +262,19 @@ }

void PainterGL::setContext(mCoreThread* context) { m_context = context; + + if (!context) { + return; + } + + m_gl->makeCurrent(); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif + unsigned width, height; + context->core->desiredVideoDimensions(context->core, &width, &height); + m_backend->setDimensions(m_backend, width, height); + m_gl->doneCurrent(); } void PainterGL::setMessagePainter(MessagePainter* messagePainter) {

@@ -374,7 +387,9 @@ buffer = m_queue.dequeue();

} else { buffer = m_free.takeLast(); } - memcpy(buffer, backing, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); + unsigned width, height; + m_context->core->desiredVideoDimensions(m_context->core, &width, &height); + memcpy(buffer, backing, width * height * BYTES_PER_PIXEL); m_queue.enqueue(buffer); m_mutex.unlock(); }
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -34,8 +34,8 @@ using namespace std;

GameController::GameController(QObject* parent) : QObject(parent) - , m_drawContext(new uint32_t[VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS]) - , m_frontBuffer(new uint32_t[VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS]) + , m_drawContext(nullptr) + , m_frontBuffer(nullptr) , m_threadContext() , m_activeKeys(0) , m_inactiveKeys(0)

@@ -116,7 +116,9 @@ };

m_threadContext.frameCallback = [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - memcpy(controller->m_frontBuffer, controller->m_drawContext, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); + unsigned width, height; + controller->m_threadContext.core->desiredVideoDimensions(controller->m_threadContext.core, &width, &height); + memcpy(controller->m_frontBuffer, controller->m_drawContext, width * height * BYTES_PER_PIXEL); QMetaObject::invokeMethod(controller, "frameAvailable", Q_ARG(const uint32_t*, controller->m_frontBuffer)); if (controller->m_pauseAfterFrame.testAndSetAcquire(true, false)) { mCoreThreadPauseFromThread(context);

@@ -208,8 +210,6 @@ disconnect();

clearMultiplayerController(); closeGame(); GBACheatDeviceDestroy(&m_cheatDevice); - delete[] m_drawContext; - delete[] m_frontBuffer; delete m_backupLoadState; }

@@ -300,12 +300,17 @@ m_threadContext.core = GBACoreCreate();

} m_threadContext.core->init(m_threadContext.core); + unsigned width, height; + m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); + m_drawContext = new uint32_t[width * height]; + m_frontBuffer = new uint32_t[width * height]; + if (!biosOnly) { mCoreLoadFile(m_threadContext.core, m_fname.toUtf8().constData()); mCoreAutoloadSave(m_threadContext.core); } - m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, VIDEO_HORIZONTAL_PIXELS); + m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, width); if (!m_bios.isNull() && m_useBios) { VFile* bios = VFileDevice::open(m_bios, O_RDONLY);

@@ -324,7 +329,7 @@ patch->close(patch);

} m_inputController->recalibrateAxes(); - memset(m_drawContext, 0xF8, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * 4); + memset(m_drawContext, 0xF8, width * height * 4); m_threadContext.core->setAVStream(m_threadContext.core, m_stream);

@@ -422,6 +427,9 @@ mCoreThreadEnd(&m_threadContext);

mCoreThreadJoin(&m_threadContext); // Make sure the event queue clears out before the thread is reused QCoreApplication::processEvents(); + + delete[] m_drawContext; + delete[] m_frontBuffer; m_patch = QString();
M src/platform/sdl/gl-sdl.csrc/platform/sdl/gl-sdl.c

@@ -42,7 +42,8 @@ renderer->gl.d.user = renderer;

renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio; renderer->gl.d.filter = renderer->filter; renderer->gl.d.swap = mSDLGLCommonSwap; - renderer->gl.d.init(&renderer->gl.d, renderer->width, renderer->height, 0); + renderer->gl.d.init(&renderer->gl.d, 0); + renderer->gl.d.setDimensions(&renderer->gl.d, renderer->width, renderer->height); _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d); return true;
M src/platform/sdl/gles2-sdl.csrc/platform/sdl/gles2-sdl.c

@@ -102,6 +102,7 @@ renderer->gl2.d.lockAspectRatio = renderer->lockAspectRatio;

renderer->gl2.d.filter = renderer->filter; renderer->gl2.d.swap = mSDLGLCommonSwap; renderer->gl2.d.init(&renderer->gl2.d, 0); + renderer->gl2.d.setDimensions(&renderer->gl2.d, renderer->width, renderer->height); return true; }
M src/platform/video-backend.hsrc/platform/video-backend.h

@@ -16,8 +16,9 @@ typedef void* WHandle;

#endif struct VideoBackend { - void (*init)(struct VideoBackend*, unsigned width, unsigned height, WHandle handle); + void (*init)(struct VideoBackend*, WHandle handle); void (*deinit)(struct VideoBackend*); + void (*setDimensions)(struct VideoBackend*, unsigned width, unsigned height); void (*swap)(struct VideoBackend*); void (*clear)(struct VideoBackend*); void (*resized)(struct VideoBackend*, unsigned w, unsigned h);