all repos — mgba @ f2b031467f1a5b1d573e7e6a38cc9b154b1c3809

mGBA Game Boy Advance Emulator

src/platform/sdl/sdl-events.c (view raw)

  1#include "sdl-events.h"
  2
  3#include "debugger.h"
  4#include "gba-io.h"
  5#include "gba-video.h"
  6
  7int GBASDLInitEvents(struct GBASDLEvents* context) {
  8	if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
  9		return 0;
 10	}
 11	SDL_JoystickEventState(SDL_ENABLE);
 12	context->joystick = SDL_JoystickOpen(0);
 13	return 1;
 14}
 15
 16void GBASDLDeinitEvents(struct GBASDLEvents* context) {
 17	SDL_JoystickClose(context->joystick);
 18	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
 19}
 20
 21static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event) {
 22	enum GBAKey key = 0;
 23	switch (event->keysym.sym) {
 24	case SDLK_z:
 25		key = GBA_KEY_A;
 26		break;
 27	case SDLK_x:
 28		key = GBA_KEY_B;
 29		break;
 30	case SDLK_a:
 31		key = GBA_KEY_L;
 32		break;
 33	case SDLK_s:
 34		key = GBA_KEY_R;
 35		break;
 36	case SDLK_RETURN:
 37		key = GBA_KEY_START;
 38		break;
 39	case SDLK_BACKSPACE:
 40		key = GBA_KEY_SELECT;
 41		break;
 42	case SDLK_UP:
 43		key = GBA_KEY_UP;
 44		break;
 45	case SDLK_DOWN:
 46		key = GBA_KEY_DOWN;
 47		break;
 48	case SDLK_LEFT:
 49		key = GBA_KEY_LEFT;
 50		break;
 51	case SDLK_RIGHT:
 52		key = GBA_KEY_RIGHT;
 53		break;
 54#ifdef USE_DEBUGGER
 55	case SDLK_F11:
 56		if (event->type == SDL_KEYDOWN && context->debugger) {
 57			ARMDebuggerEnter(context->debugger);
 58		}
 59		break;
 60#endif
 61	case SDLK_TAB:
 62		context->sync.audioWait = !context->sync.audioWait;
 63		return;
 64	default:
 65		if (event->keysym.mod & KMOD_CTRL && event->type == SDL_KEYDOWN) {
 66			switch (event->keysym.sym) {
 67			case SDLK_p:
 68				GBAThreadTogglePause(context);
 69			default:
 70				break;
 71			}
 72		}
 73		return;
 74	}
 75
 76	if (event->type == SDL_KEYDOWN) {
 77		context->activeKeys |= 1 << key;
 78	} else {
 79		context->activeKeys &= ~(1 << key);
 80	}
 81}
 82
 83static void _GBASDLHandleJoyButton(struct GBAThread* context, const struct SDL_JoyButtonEvent* event) {
 84	enum GBAKey key = 0;
 85	// Sorry, hardcoded to my gamepad for now
 86	switch (event->button) {
 87	case 2:
 88		key = GBA_KEY_A;
 89		break;
 90	case 1:
 91		key = GBA_KEY_B;
 92		break;
 93	case 6:
 94		key = GBA_KEY_L;
 95		break;
 96	case 7:
 97		key = GBA_KEY_R;
 98		break;
 99	case 8:
100		key = GBA_KEY_START;
101		break;
102	case 9:
103		key = GBA_KEY_SELECT;
104		break;
105	default:
106		return;
107	}
108
109	if (event->type == SDL_JOYBUTTONDOWN) {
110		context->activeKeys |= 1 << key;
111	} else {
112		context->activeKeys &= ~(1 << key);
113	}
114}
115
116static void _GBASDLHandleJoyHat(struct GBAThread* context, const struct SDL_JoyHatEvent* event) {
117	enum GBAKey key = 0;
118
119	if (event->value & SDL_HAT_UP) {
120		key |= 1 << GBA_KEY_UP;
121	}
122	if (event->value & SDL_HAT_LEFT) {
123		key |= 1 << GBA_KEY_LEFT;
124	}
125	if (event->value & SDL_HAT_DOWN) {
126		key |= 1 << GBA_KEY_DOWN;
127	}
128	if (event->value & SDL_HAT_RIGHT) {
129		key |= 1 << GBA_KEY_RIGHT;
130	}
131
132	context->activeKeys &= ~((1 << GBA_KEY_UP) | (1 << GBA_KEY_LEFT) | (1 << GBA_KEY_DOWN) | (1 << GBA_KEY_RIGHT));
133	context->activeKeys |= key;
134}
135
136void GBASDLHandleEvent(struct GBAThread* context, const union SDL_Event* event) {
137	switch (event->type) {
138	case SDL_QUIT:
139		// FIXME: this isn't thread-safe
140		if (context->debugger) {
141			context->debugger->state = DEBUGGER_EXITING;
142		}
143		MutexLock(&context->stateMutex);
144		context->state = THREAD_EXITING;
145		ConditionWake(&context->stateCond);
146		MutexUnlock(&context->stateMutex);
147		break;
148	case SDL_KEYDOWN:
149	case SDL_KEYUP:
150		_GBASDLHandleKeypress(context, &event->key);
151		break;
152	case SDL_JOYBUTTONDOWN:
153	case SDL_JOYBUTTONUP:
154		_GBASDLHandleJoyButton(context, &event->jbutton);
155		break;
156	case SDL_JOYHATMOTION:
157		_GBASDLHandleJoyHat(context, &event->jhat);
158	}
159}