all repos — mgba @ 8215afcee6baaad0f05926a46702a27ce631e33d

mGBA Game Boy Advance Emulator

Decouple GLSL and GL mains
Jeffrey Pfau jeffrey@endrift.com
Wed, 17 Jul 2013 23:31:19 -0700
commit

8215afcee6baaad0f05926a46702a27ce631e33d

parent

49de0fb52e8da117efe0cd076d1bd097844b1f54

2 files changed, 172 insertions(+), 22 deletions(-)

jump to
M src/gl-main.csrc/gl-main.c

@@ -1,8 +1,8 @@

#include "debugger.h" #include "gba-thread.h" #include "gba.h" -#include "renderers/video-glsl.h" #include "sdl-events.h" +#include "renderers/video-software.h" #include <SDL.h> #ifdef __APPLE__

@@ -17,9 +17,29 @@ #include <signal.h>

#include <sys/time.h> #include <unistd.h> -static int _GBASDLInit(void); -static void _GBASDLDeinit(void); -static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRenderer* renderer); +struct GLSoftwareRenderer { + struct GBAVideoSoftwareRenderer d; + + GLuint tex; +}; + +static int _GBASDLInit(struct GLSoftwareRenderer* renderer); +static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer); +static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer); + +static const GLint _glVertices[] = { + 0, 0, + 256, 0, + 256, 256, + 0, 256 +}; + +static const GLint _glTexCoords[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 +}; int main(int argc, char** argv) { const char* fname = "test.rom";

@@ -31,16 +51,21 @@ if (fd < 0) {

return 1; } + sigset_t signals; + sigaddset(&signals, SIGINT); + sigaddset(&signals, SIGTRAP); + pthread_sigmask(SIG_BLOCK, &signals, 0); + struct GBAThread context; - struct GBAVideoGLSLRenderer renderer; + struct GLSoftwareRenderer renderer; + GBAVideoSoftwareRendererCreate(&renderer.d); - if (!_GBASDLInit()) { + if (!_GBASDLInit(&renderer)) { return 1; } - GBAVideoGLSLRendererCreate(&renderer); context.fd = fd; - context.renderer = &renderer.d; + context.renderer = &renderer.d.d; GBAThreadStart(&context); _GBASDLRunloop(&context, &renderer);

@@ -48,12 +73,12 @@

GBAThreadJoin(&context); close(fd); - _GBASDLDeinit(); + _GBASDLDeinit(&renderer); return 0; } -static int _GBASDLInit() { +static int _GBASDLInit(struct GLSoftwareRenderer* renderer) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 0; }

@@ -67,38 +92,59 @@ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_SetVideoMode(240, 160, 32, SDL_OPENGL); + renderer->d.outputBuffer = malloc(256 * 256 * 4); + 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); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glViewport(0, 0, 240, 160); return 1; } -static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRenderer* renderer) { +static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer) { SDL_Event event; glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, _glVertices); + glTexCoordPointer(2, GL_INT, 0, _glTexCoords); + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 240, 160, 0, 0, 1); while (context->started && context->debugger->state != DEBUGGER_EXITING) { - GBAVideoGLSLRendererProcessEvents(renderer); - pthread_mutex_lock(&renderer->mutex); - if (renderer->d.framesPending) { - renderer->d.framesPending = 0; - pthread_mutex_unlock(&renderer->mutex); + pthread_mutex_lock(&renderer->d.mutex); + if (renderer->d.d.framesPending) { + renderer->d.d.framesPending = 0; + pthread_mutex_unlock(&renderer->d.mutex); + glBindTexture(GL_TEXTURE_2D, renderer->tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); SDL_GL_SwapBuffers(); while (SDL_PollEvent(&event)) { GBASDLHandleEvent(context, &event); } - pthread_mutex_lock(&renderer->mutex); - pthread_cond_broadcast(&renderer->downCond); + pthread_mutex_lock(&renderer->d.mutex); + pthread_cond_broadcast(&renderer->d.downCond); } else { - pthread_cond_broadcast(&renderer->downCond); - pthread_cond_wait(&renderer->upCond, &renderer->mutex); + pthread_cond_broadcast(&renderer->d.downCond); + pthread_cond_wait(&renderer->d.upCond, &renderer->d.mutex); } - pthread_mutex_unlock(&renderer->mutex); + pthread_mutex_unlock(&renderer->d.mutex); } } -static void _GBASDLDeinit() { +static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer) { + free(renderer->d.outputBuffer); + GBASDLDeinitEvents(); SDL_Quit(); }
A src/glsl-main.c

@@ -0,0 +1,104 @@

+#include "debugger.h" +#include "gba-thread.h" +#include "gba.h" +#include "renderers/video-glsl.h" +#include "sdl-events.h" + +#include <SDL.h> +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#else +#include <GL/gl.h> +#endif + +#include <fcntl.h> +#include <errno.h> +#include <signal.h> +#include <sys/time.h> +#include <unistd.h> + +static int _GBASDLInit(void); +static void _GBASDLDeinit(void); +static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRenderer* renderer); + +int main(int argc, char** argv) { + const char* fname = "test.rom"; + if (argc > 1) { + fname = argv[1]; + } + int fd = open(fname, O_RDONLY); + if (fd < 0) { + return 1; + } + + struct GBAThread context; + struct GBAVideoGLSLRenderer renderer; + + if (!_GBASDLInit()) { + return 1; + } + GBAVideoGLSLRendererCreate(&renderer); + + context.fd = fd; + context.renderer = &renderer.d; + GBAThreadStart(&context); + + _GBASDLRunloop(&context, &renderer); + + GBAThreadJoin(&context); + close(fd); + + _GBASDLDeinit(); + + return 0; +} + +static int _GBASDLInit() { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + return 0; + } + + GBASDLInitEvents(); + + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_SetVideoMode(240, 160, 32, SDL_OPENGL); + + glViewport(0, 0, 240, 160); + + return 1; +} + +static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRenderer* renderer) { + SDL_Event event; + + glEnable(GL_TEXTURE_2D); + while (context->started && context->debugger->state != DEBUGGER_EXITING) { + GBAVideoGLSLRendererProcessEvents(renderer); + pthread_mutex_lock(&renderer->mutex); + if (renderer->d.framesPending) { + renderer->d.framesPending = 0; + pthread_mutex_unlock(&renderer->mutex); + + SDL_GL_SwapBuffers(); + + while (SDL_PollEvent(&event)) { + GBASDLHandleEvent(context, &event); + } + pthread_mutex_lock(&renderer->mutex); + pthread_cond_broadcast(&renderer->downCond); + } else { + pthread_cond_broadcast(&renderer->downCond); + pthread_cond_wait(&renderer->upCond, &renderer->mutex); + } + pthread_mutex_unlock(&renderer->mutex); + } +} + +static void _GBASDLDeinit() { + GBASDLDeinitEvents(); + SDL_Quit(); +}