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}