1 /* Tower Toppler - Nebulus
2 * Copyright (C) 2000-2012 Andreas R�ver
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "keyb.h"
20 #include "decl.h"
21
22 #include <SDL.h>
23
24 static ttkey keydown, keytyped;
25 static char chartyped;
26 static SDLKey sdlkeytyped;
27 static Uint16 mouse_x, mouse_y;
28 static bool mouse_moved;
29 static Uint16 mouse_button;
30 static int joy_inited = 0;
31 SDL_Joystick *joy;
32
33 class quit_action_class {};
34
35 #define JOYSTICK_DEADZONE 6000
36
37 bool tt_has_focus;
38
39 struct _ttkeyconv {
40 ttkey outval;
41 SDLKey key;
42 } static ttkeyconv[] = {
43 {up_key, SDLK_UP},
44 {down_key, SDLK_DOWN},
45 {left_key, SDLK_LEFT},
46 {right_key, SDLK_RIGHT},
47 {fire_key, SDLK_SPACE},
48 {fire_key, SDLK_RETURN},
49 {break_key, SDLK_ESCAPE},
50 {pause_key, SDLK_p},
51 {up_key, SDLK_UP},
52 {down_key, SDLK_DOWN},
53 {left_key, SDLK_LEFT},
54 {right_key, SDLK_RIGHT},
55 {fire_key, SDLK_SPACE},
56 {break_key, SDLK_ESCAPE},
57 {pause_key, SDLK_p},
58 };
59
key_redefine(ttkey code,SDLKey key)60 void key_redefine(ttkey code, SDLKey key) {
61 int i;
62
63 for (i = SIZE(ttkeyconv) - 1; i >= 0; i--)
64 if (ttkeyconv[i].outval == code) {
65 ttkeyconv[i].key = key;
66 break;
67 }
68 }
69
key_init(void)70 void key_init(void) {
71 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
72 SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
73 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
74
75 SDL_EnableUNICODE(1);
76
77 if (joy_inited == 0) {
78 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
79 joy_inited = 2;
80 } else {
81 joy = SDL_JoystickOpen(0);
82 if (!joy) {
83 joy_inited = 2;
84 } else {
85 SDL_JoystickEventState(SDL_ENABLE);
86 printf("Joystick enabled\n");
87 joy_inited = 1;
88 }
89 }
90 }
91
92 chartyped = 0;
93 keytyped = keydown = no_key;
94 sdlkeytyped = SDLK_UNKNOWN;
95 mouse_button = mouse_x = mouse_y = 0;
96 mouse_moved = false;
97 }
98
handleEvents(void)99 static void handleEvents(void) {
100 SDL_Event e;
101
102 while (SDL_PollEvent(&e)) {
103
104 switch (e.type) {
105 case SDL_ACTIVEEVENT:
106 if ((e.active.state & SDL_APPINPUTFOCUS) || (e.active.state & SDL_APPACTIVE))
107 tt_has_focus = (e.active.gain == 1);
108 break;
109 case SDL_MOUSEMOTION:
110 mouse_x = e.motion.x;
111 mouse_y = e.motion.y;
112 mouse_moved = true;
113 break;
114 case SDL_JOYAXISMOTION:
115 if (e.jaxis.axis == 0) {
116 if (e.jaxis.value < -JOYSTICK_DEADZONE) {
117 keydown = (ttkey) (keydown | left_key);
118 } else
119 if (e.jaxis.value > JOYSTICK_DEADZONE) {
120 keydown = (ttkey) (keydown | right_key);
121 } else
122 keydown = (ttkey) (keydown & ~(right_key|left_key));
123 }
124 if (e.jaxis.axis == 1) {
125 if (e.jaxis.value < -JOYSTICK_DEADZONE) {
126 keydown = (ttkey) (keydown | up_key);
127 } else
128 if (e.jaxis.value > JOYSTICK_DEADZONE) {
129 keydown = (ttkey) (keydown | down_key);
130 } else
131 keydown = (ttkey) (keydown & ~(up_key|down_key));
132 }
133 keytyped = keydown;
134 break;
135 case SDL_JOYBUTTONDOWN:
136 keydown = (ttkey)(keydown | fire_key);
137 keytyped = keydown;
138 break;
139 case SDL_JOYBUTTONUP:
140 keydown = (ttkey)(keydown & ~fire_key);
141 keytyped = keydown;
142 break;
143 case SDL_MOUSEBUTTONDOWN:
144 case SDL_MOUSEBUTTONUP:
145 mouse_x = e.button.x;
146 mouse_y = e.button.y;
147 mouse_button = e.button.button;
148 break;
149 case SDL_QUIT:
150 fprintf(stderr, _("Wheee!!\n"));
151 exit(0);
152 break;
153 case SDL_KEYDOWN:
154 case SDL_KEYUP:
155
156 ttkey key = no_key;
157 for (int tmpk = 0; tmpk < SIZE(ttkeyconv); tmpk++)
158 if (ttkeyconv[tmpk].key == e.key.keysym.sym) {
159 key = ttkeyconv[tmpk].outval;
160 break;
161 }
162
163 if (e.key.state == SDL_PRESSED) {
164
165 if ((e.key.keysym.unicode & 0xff80) == 0) {
166 chartyped = e.key.keysym.unicode & 0x7f;
167 } else
168 chartyped = 0;
169
170 sdlkeytyped = e.key.keysym.sym;
171
172 keydown = (ttkey)(keydown | key);
173 keytyped = (ttkey)(keytyped | key);
174
175 } else {
176 keydown = (ttkey)(keydown & ~key);
177 }
178 break;
179 }
180 }
181 }
182
key_done(void)183 void key_done(void) {
184 SDL_JoystickClose(joy);
185 }
186
key_keystat(void)187 Uint16 key_keystat(void) {
188 handleEvents();
189 return keydown;
190 }
191
key_keypressed(ttkey key)192 bool key_keypressed(ttkey key) {
193 handleEvents();
194 return (keytyped & key) != 0;
195 }
196
key_sdlkey(void)197 SDLKey key_sdlkey(void) {
198 handleEvents();
199 SDLKey tmp = sdlkeytyped;
200 sdlkeytyped = SDLK_UNKNOWN;
201 keytyped = no_key;
202 chartyped = 0;
203 return tmp;
204 }
205
key_keydatas(SDLKey & sdlkey,ttkey & tkey,char & ch)206 void key_keydatas(SDLKey &sdlkey, ttkey &tkey, char &ch) {
207 handleEvents();
208 sdlkey = sdlkeytyped;
209 tkey = keytyped;
210 ch = chartyped;
211 sdlkeytyped = SDLK_UNKNOWN;
212 keytyped = no_key;
213 chartyped = 0;
214 }
215
216
key_conv2sdlkey(ttkey k,bool game)217 SDLKey key_conv2sdlkey(ttkey k, bool game) {
218 register int i;
219
220 if (game) {
221 for (i = SIZE(ttkeyconv) - 1; i >= 0; i--)
222 if (ttkeyconv[i].outval == k)
223 return ttkeyconv[i].key;
224 } else {
225 for (i = 0; i < SIZE(ttkeyconv); i++)
226 if (ttkeyconv[i].outval == k)
227 return ttkeyconv[i].key;
228 }
229
230 return SDLK_UNKNOWN;
231 }
232
key_sdlkey2conv(SDLKey k,bool game)233 ttkey key_sdlkey2conv(SDLKey k, bool game) {
234 register int i;
235
236 if (k != SDLK_UNKNOWN) {
237 if (game) {
238 for (i = SIZE(ttkeyconv) - 1; i >= 0; i--)
239 if (ttkeyconv[i].key == k)
240 return ttkeyconv[i].outval;
241 } else {
242 for (i = 0; i < SIZE(ttkeyconv); i++)
243 if (ttkeyconv[i].key == k)
244 return ttkeyconv[i].outval;
245 }
246 }
247
248 return no_key;
249 }
250
key_readkey(void)251 ttkey key_readkey(void) {
252 handleEvents();
253
254 ttkey i = keytyped;
255
256 keytyped = no_key;
257 chartyped = 0;
258 sdlkeytyped = SDLK_UNKNOWN;
259
260 return i;
261 }
262
wait_for_focus(void)263 void wait_for_focus(void) {
264
265 while (!tt_has_focus) {
266 SDL_Delay(200);
267 handleEvents();
268 }
269
270 keytyped = no_key;
271 chartyped = 0;
272 sdlkeytyped = SDLK_UNKNOWN;
273 }
274
key_chartyped(void)275 char key_chartyped(void) {
276 handleEvents();
277 int erg = chartyped;
278 chartyped = 0;
279 return erg;
280 }
281
key_wait_for_none(keyb_wait_proc bg)282 void key_wait_for_none(keyb_wait_proc bg) {
283
284 do {
285 handleEvents();
286 if (bg) (*bg)();
287 } while (keydown);
288
289 keytyped = no_key;
290 chartyped = 0;
291 sdlkeytyped = SDLK_UNKNOWN;
292 }
293
key_mouse(Uint16 * x,Uint16 * y,ttkey * bttn)294 bool key_mouse(Uint16 *x, Uint16 *y, ttkey *bttn) {
295 bool tmp = mouse_moved;
296 handleEvents();
297 switch (mouse_button) {
298 default: *bttn = no_key; break;
299 }
300 mouse_moved = false;
301 mouse_button = 0;
302 if (tmp) {
303 *x = mouse_x;
304 *y = mouse_y;
305 } else {
306 *x = *y = 0;
307 }
308 return tmp;
309 }
310