all repos — mgba @ 3837213f941a150bc7a3c26c9e38b75f4ef12952

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	case SDLK_TAB:
 55		context->sync.audioWait = !context->sync.audioWait;
 56		return;
 57	default:
 58		if (event->keysym.mod & KMOD_CTRL && event->type == SDL_KEYDOWN) {
 59			switch (event->keysym.sym) {
 60			case SDLK_p:
 61				GBAThreadTogglePause(context);
 62			default:
 63				break;
 64			}
 65		}
 66		return;
 67	}
 68
 69	if (event->type == SDL_KEYDOWN) {
 70		context->activeKeys |= 1 << key;
 71	} else {
 72		context->activeKeys &= ~(1 << key);
 73	}
 74}
 75
 76static void _GBASDLHandleJoyButton(struct GBAThread* context, const struct SDL_JoyButtonEvent* event) {
 77	enum GBAKey key = 0;
 78	// Sorry, hardcoded to my gamepad for now
 79	switch (event->button) {
 80	case 2:
 81		key = GBA_KEY_A;
 82		break;
 83	case 1:
 84		key = GBA_KEY_B;
 85		break;
 86	case 6:
 87		key = GBA_KEY_L;
 88		break;
 89	case 7:
 90		key = GBA_KEY_R;
 91		break;
 92	case 8:
 93		key = GBA_KEY_START;
 94		break;
 95	case 9:
 96		key = GBA_KEY_SELECT;
 97		break;
 98	default:
 99		return;
100	}
101
102	if (event->type == SDL_JOYBUTTONDOWN) {
103		context->activeKeys |= 1 << key;
104	} else {
105		context->activeKeys &= ~(1 << key);
106	}
107}
108
109static void _GBASDLHandleJoyHat(struct GBAThread* context, const struct SDL_JoyHatEvent* event) {
110	enum GBAKey key = 0;
111
112	if (event->value & SDL_HAT_UP) {
113		key |= 1 << GBA_KEY_UP;
114	}
115	if (event->value & SDL_HAT_LEFT) {
116		key |= 1 << GBA_KEY_LEFT;
117	}
118	if (event->value & SDL_HAT_DOWN) {
119		key |= 1 << GBA_KEY_DOWN;
120	}
121	if (event->value & SDL_HAT_RIGHT) {
122		key |= 1 << GBA_KEY_RIGHT;
123	}
124
125	context->activeKeys &= ~((1 << GBA_KEY_UP) | (1 << GBA_KEY_LEFT) | (1 << GBA_KEY_DOWN) | (1 << GBA_KEY_RIGHT));
126	context->activeKeys |= key;
127}
128
129void GBASDLHandleEvent(struct GBAThread* context, const union SDL_Event* event) {
130	switch (event->type) {
131	case SDL_QUIT:
132		// FIXME: this isn't thread-safe
133		if (context->debugger) {
134			context->debugger->state = DEBUGGER_EXITING;
135		}
136		MutexLock(&context->stateMutex);
137		context->state = THREAD_EXITING;
138		ConditionWake(&context->stateCond);
139		MutexUnlock(&context->stateMutex);
140		break;
141	case SDL_KEYDOWN:
142	case SDL_KEYUP:
143		_GBASDLHandleKeypress(context, &event->key);
144		break;
145	case SDL_JOYBUTTONDOWN:
146	case SDL_JOYBUTTONUP:
147		_GBASDLHandleJoyButton(context, &event->jbutton);
148		break;
149	case SDL_JOYHATMOTION:
150		_GBASDLHandleJoyHat(context, &event->jhat);
151	}
152}