all repos — mgba @ a8731d280f1cb73d462e9c278cbf2bddc480ef58

mGBA Game Boy Advance Emulator

src/platform/sdl/main.c (view raw)

  1#include "main.h"
  2
  3#ifdef USE_CLI_DEBUGGER
  4#include "debugger/cli-debugger.h"
  5#endif
  6
  7#ifdef USE_GDB_STUB
  8#include "debugger/gdb-stub.h"
  9#endif
 10
 11#include "gba-thread.h"
 12#include "gba.h"
 13#include "gba-config.h"
 14#include "gba-video.h"
 15#include "platform/commandline.h"
 16#include "util/configuration.h"
 17
 18#include <SDL.h>
 19
 20#include <errno.h>
 21#include <signal.h>
 22#include <sys/time.h>
 23
 24#define PORT "sdl"
 25
 26static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer);
 27static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
 28
 29int main(int argc, char** argv) {
 30	struct SDLSoftwareRenderer renderer;
 31	GBAVideoSoftwareRendererCreate(&renderer.d);
 32
 33	struct GBAInputMap inputMap;
 34	GBAInputMapInit(&inputMap);
 35
 36	struct GBAConfig config;
 37	GBAConfigInit(&config, PORT);
 38	GBAConfigLoad(&config);
 39
 40	struct GBAOptions opts = {
 41		.width = VIDEO_HORIZONTAL_PIXELS,
 42		.height = VIDEO_VERTICAL_PIXELS,
 43		.audioBuffers = 512,
 44		.videoSync = false,
 45		.audioSync = true,
 46	};
 47	GBAConfigLoadDefaults(&config, &opts);
 48
 49	struct GBAArguments args = {};
 50	struct GraphicsOpts graphicsOpts = {};
 51
 52	struct SubParser subparser;
 53
 54	initParserForGraphics(&subparser, &graphicsOpts);
 55	if (!parseArguments(&args, &config, argc, argv, &subparser)) {
 56		usage(argv[0], subparser.usage);
 57		freeArguments(&args);
 58		GBAConfigFreeOpts(&opts);
 59		GBAConfigDeinit(&config);
 60		return 1;
 61	}
 62
 63	GBAConfigMap(&config, &opts);
 64
 65	renderer.viewportWidth = opts.width;
 66	renderer.viewportHeight = opts.height;
 67#if SDL_VERSION_ATLEAST(2, 0, 0)
 68	renderer.events.fullscreen = opts.fullscreen;
 69	renderer.events.windowUpdated = 0;
 70#endif
 71	renderer.ratio = graphicsOpts.multiplier;
 72
 73	if (!_GBASDLInit(&renderer)) {
 74		freeArguments(&args);
 75		GBAConfigFreeOpts(&opts);
 76		GBAConfigDeinit(&config);
 77		return 1;
 78	}
 79
 80	struct GBAThread context = {
 81		.renderer = &renderer.d.d,
 82		.userData = &renderer
 83	};
 84
 85	context.debugger = createDebugger(&args, &context);
 86
 87	GBAMapOptionsToContext(&opts, &context);
 88	GBAMapArgumentsToContext(&args, &context);
 89
 90	renderer.audio.samples = context.audioBuffers;
 91	GBASDLInitAudio(&renderer.audio, &context);
 92
 93	renderer.events.bindings = &inputMap;
 94	GBASDLInitBindings(&inputMap);
 95	GBASDLInitEvents(&renderer.events);
 96	GBASDLEventsLoadConfig(&renderer.events, &config.configTable); // TODO: Don't use this directly
 97
 98	GBAThreadStart(&context);
 99
100	GBASDLRunloop(&context, &renderer);
101
102	GBAThreadJoin(&context);
103	freeArguments(&args);
104	GBAConfigFreeOpts(&opts);
105	GBAConfigDeinit(&config);
106	free(context.debugger);
107	GBAInputMapDeinit(&inputMap);
108
109	_GBASDLDeinit(&renderer);
110
111	return 0;
112}
113
114static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer) {
115	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
116		return false;
117	}
118
119	return GBASDLInit(renderer);
120}
121
122static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
123	free(renderer->d.outputBuffer);
124
125	GBASDLDeinitEvents(&renderer->events);
126	GBASDLDeinitAudio(&renderer->audio);
127#if SDL_VERSION_ATLEAST(2, 0, 0)
128	SDL_DestroyWindow(renderer->window);
129#endif
130
131	GBASDLDeinit(renderer);
132
133	SDL_Quit();
134
135}