diff --git a/CMakeLists.txt b/CMakeLists.txt index 4540bdda4..9fc89fbc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.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}) diff --git a/src/main.c b/src/main.c index 1bf41f50c..91366c6af 100644 --- a/src/main.c +++ b/src/main.c @@ -3,14 +3,36 @@ #include "renderers/video-software.h" #include +#include #include #include #include #include -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 @@ int main(int argc, char** argv) { 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 @@ int main(int argc, char** argv) { 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 @@ static int _GBASDLInit() { 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(); +}