all repos — mgba @ a5d8be30d83e5ff9ed376dca74eb961bba5b4593

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