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}