all repos — mgba @ 71ec6162f11ab51bb159af78a9a3a84538189cb6

mGBA Game Boy Advance Emulator

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}