all repos — mgba @ 2860714714b1dd3307a4a50e8854b8eed18e43a6

mGBA Game Boy Advance Emulator

Draw output buffer
Jeffrey Pfau jeffrey@endrift.com
Sat, 20 Apr 2013 21:40:06 -0700
commit

2860714714b1dd3307a4a50e8854b8eed18e43a6

parent

eba5d547b94681d5a0adaf17985cfe935d4354ef

2 files changed, 71 insertions(+), 19 deletions(-)

jump to
M CMakeLists.txtCMakeLists.txt

@@ -12,7 +12,8 @@ include_directories(${CMAKE_SOURCE_DIR}/src/debugger)

include_directories(${CMAKE_SOURCE_DIR}/third-party/linenoise) find_package(SDL 1.2 REQUIRED) -include_directories(${SDL_INCLUDE_DIR}) +find_package(OpenGL REQUIRED) +include_directories(${SDL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) add_executable(gbac ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${THIRD_PARTY} ${CMAKE_SOURCE_DIR}/src/main.c) -target_link_libraries(gbac m pthread ${SDL_LIBRARY}) +target_link_libraries(gbac m pthread ${SDL_LIBRARY} ${OPENGL_LIBRARY})
M src/main.csrc/main.c

@@ -3,14 +3,36 @@ #include "gba-thread.h"

#include "renderers/video-software.h" #include <sdl.h> +#include <OpenGL/gl.h> #include <fcntl.h> #include <errno.h> #include <signal.h> #include <unistd.h> -static int _GBASDLInit(void); -static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* 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) { int fd = open("test.rom", O_RDONLY);

@@ -20,15 +42,16 @@ sigaddset(&signals, SIGINT);

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

@@ -36,12 +59,12 @@

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

@@ -53,22 +76,50 @@ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_SetVideoMode(240, 160, 16, SDL_OPENGL); + renderer->d.outputBuffer = malloc(256 * 256 * 2); + 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 GBAVideoSoftwareRenderer* renderer) { +static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer) { SDL_Event event; - while (1) { - if (!context->started) { - break; - } + int err; + 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) { + glBindTexture(GL_TEXTURE_2D, renderer->tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + SDL_GL_SwapBuffers(); - pthread_mutex_lock(&renderer->mutex); - pthread_cond_broadcast(&renderer->cond); - pthread_mutex_unlock(&renderer->mutex); + pthread_mutex_lock(&renderer->d.mutex); + pthread_cond_broadcast(&renderer->d.cond); + pthread_mutex_unlock(&renderer->d.mutex); while(SDL_PollEvent(&event)) { } } } + +static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer) { + free(renderer->d.outputBuffer); + + SDL_Quit(); +}