src/sdl-main.c (view raw)
1#include "debugger.h"
2#include "gba-thread.h"
3#include "gba.h"
4#include "renderers/video-software.h"
5#include "sdl-events.h"
6
7#include <SDL.h>
8
9#include <fcntl.h>
10#include <errno.h>
11#include <signal.h>
12#include <sys/time.h>
13#include <unistd.h>
14
15static int _GBASDLInit(void);
16static void _GBASDLDeinit(void);
17static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer);
18
19int main(int argc, char** argv) {
20 const char* fname = "test.rom";
21 if (argc > 1) {
22 fname = argv[1];
23 }
24 int fd = open(fname, O_RDONLY);
25 if (fd < 0) {
26 return 1;
27 }
28
29 struct GBAThread context;
30 struct GBAVideoSoftwareRenderer renderer;
31
32 if (!_GBASDLInit()) {
33 return 1;
34 }
35 GBAVideoSoftwareRendererCreate(&renderer);
36 SDL_Surface* surface = SDL_GetVideoSurface();
37 SDL_LockSurface(surface);
38 renderer.outputBuffer = surface->pixels;
39 renderer.outputBufferStride = surface->pitch / 4;
40
41 context.fd = fd;
42 context.renderer = &renderer.d;
43 GBAThreadStart(&context);
44
45 _GBASDLRunloop(&context, &renderer);
46
47 SDL_UnlockSurface(surface);
48 GBAThreadJoin(&context);
49 close(fd);
50
51 _GBASDLDeinit();
52
53 return 0;
54}
55
56static int _GBASDLInit() {
57 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
58 return 0;
59 }
60
61 GBASDLInitEvents();
62
63 SDL_SetVideoMode(240, 160, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
64
65 return 1;
66}
67
68static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer) {
69 SDL_Event event;
70 SDL_Surface* surface = SDL_GetVideoSurface();
71
72 while (context->started && context->debugger->state != DEBUGGER_EXITING) {
73 pthread_mutex_lock(&renderer->mutex);
74 if (renderer->d.framesPending) {
75 renderer->d.framesPending = 0;
76 pthread_mutex_unlock(&renderer->mutex);
77
78 SDL_UnlockSurface(surface);
79 SDL_Flip(surface);
80 SDL_LockSurface(surface);
81
82 while (SDL_PollEvent(&event)) {
83 GBASDLHandleEvent(context, &event);
84 }
85 pthread_mutex_lock(&renderer->mutex);
86 pthread_cond_broadcast(&renderer->downCond);
87 } else {
88 pthread_cond_broadcast(&renderer->downCond);
89 pthread_cond_wait(&renderer->upCond, &renderer->mutex);
90 }
91 pthread_mutex_unlock(&renderer->mutex);
92 }
93}
94
95static void _GBASDLDeinit() {
96 GBASDLDeinitEvents();
97 SDL_Quit();
98}