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}