src/main.c (view raw)
1#include "debugger.h"
2#include "gba-thread.h"
3#include "renderers/video-software.h"
4
5#include <sdl.h>
6#include <OpenGL/gl.h>
7
8#include <fcntl.h>
9#include <errno.h>
10#include <signal.h>
11#include <unistd.h>
12
13struct GLSoftwareRenderer {
14 struct GBAVideoSoftwareRenderer d;
15
16 GLuint tex;
17};
18
19static int _GBASDLInit(struct GLSoftwareRenderer* renderer);
20static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer);
21static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer);
22
23static const GLint _glVertices[] = {
24 0, 0,
25 256, 0,
26 256, 256,
27 0, 256
28};
29
30static const GLint _glTexCoords[] = {
31 0, 0,
32 1, 0,
33 1, 1,
34 0, 1
35};
36
37int main(int argc, char** argv) {
38 int fd = open("test.rom", O_RDONLY);
39
40 sigset_t signals;
41 sigaddset(&signals, SIGINT);
42 sigaddset(&signals, SIGTRAP);
43 pthread_sigmask(SIG_BLOCK, &signals, 0);
44
45 struct GBAThread context;
46 struct GLSoftwareRenderer renderer;
47 GBAVideoSoftwareRendererCreate(&renderer.d);
48
49 if (!_GBASDLInit(&renderer)) {
50 return 1;
51 }
52
53 context.fd = fd;
54 context.renderer = &renderer.d.d;
55 GBAThreadStart(&context);
56
57 _GBASDLRunloop(&context, &renderer);
58
59 GBAThreadJoin(&context);
60 close(fd);
61
62 _GBASDLDeinit(&renderer);
63
64 return 0;
65}
66
67static int _GBASDLInit(struct GLSoftwareRenderer* renderer) {
68 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
69 return 0;
70 }
71
72 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
73 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
74 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
75 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
76 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
77 SDL_SetVideoMode(240, 160, 16, SDL_OPENGL);
78
79 renderer->d.outputBuffer = malloc(256 * 256 * 2);
80 renderer->d.outputBufferStride = 256;
81 glGenTextures(1, &renderer->tex);
82 glBindTexture(GL_TEXTURE_2D, renderer->tex);
83 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
84 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
85 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
86 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
87 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
88
89 glViewport(0, 0, 240, 160);
90
91 return 1;
92}
93
94static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer) {
95 SDL_Event event;
96
97 int err;
98 glEnable(GL_TEXTURE_2D);
99 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
100 glEnableClientState(GL_VERTEX_ARRAY);
101 glVertexPointer(2, GL_INT, 0, _glVertices);
102 glTexCoordPointer(2, GL_INT, 0, _glTexCoords);
103 glMatrixMode (GL_PROJECTION);
104 glLoadIdentity();
105 glOrtho(0, 240, 160, 0, 0, 1);
106 while (context->started) {
107 glBindTexture(GL_TEXTURE_2D, renderer->tex);
108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer);
109 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
110
111 SDL_GL_SwapBuffers();
112 pthread_mutex_lock(&renderer->d.mutex);
113 pthread_cond_broadcast(&renderer->d.cond);
114 pthread_mutex_unlock(&renderer->d.mutex);
115 while(SDL_PollEvent(&event)) {
116
117 }
118 }
119}
120
121static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer) {
122 free(renderer->d.outputBuffer);
123
124 SDL_Quit();
125}