comparison ext/guichan-0.8.2/src/sdl/sdlinput.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/sdl/sdlinput.hpp"
49
50 #include "guichan/exception.hpp"
51
52 namespace gcn
53 {
54 SDLInput::SDLInput()
55 {
56 mMouseInWindow = true;
57 mMouseDown = false;
58 }
59
60 bool SDLInput::isKeyQueueEmpty()
61 {
62 return mKeyInputQueue.empty();
63 }
64
65 KeyInput SDLInput::dequeueKeyInput()
66 {
67 KeyInput keyInput;
68
69 if (mKeyInputQueue.empty())
70 {
71 throw GCN_EXCEPTION("The queue is empty.");
72 }
73
74 keyInput = mKeyInputQueue.front();
75 mKeyInputQueue.pop();
76
77 return keyInput;
78 }
79
80 bool SDLInput::isMouseQueueEmpty()
81 {
82 return mMouseInputQueue.empty();
83 }
84
85 MouseInput SDLInput::dequeueMouseInput()
86 {
87 MouseInput mouseInput;
88
89 if (mMouseInputQueue.empty())
90 {
91 throw GCN_EXCEPTION("The queue is empty.");
92 }
93
94 mouseInput = mMouseInputQueue.front();
95 mMouseInputQueue.pop();
96
97 return mouseInput;
98 }
99
100 void SDLInput::pushInput(SDL_Event event)
101 {
102 KeyInput keyInput;
103 MouseInput mouseInput;
104
105 switch (event.type)
106 {
107 case SDL_KEYDOWN:
108 {
109 int value = convertSDLEventToGuichanKeyValue(event);
110
111 if (value == -1)
112 {
113 value = (int)event.key.keysym.unicode;
114 }
115
116 keyInput.setKey(Key(value));
117 keyInput.setType(KeyInput::PRESSED);
118 keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
119 keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
120 keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
121 keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
122 keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
123 && event.key.keysym.sym <= SDLK_KP_EQUALS);
124
125 mKeyInputQueue.push(keyInput);
126 break;
127 }
128
129 case SDL_KEYUP:
130 {
131 int value = convertSDLEventToGuichanKeyValue(event);
132
133 if (value == -1)
134 {
135 value = (int)event.key.keysym.sym;
136 }
137
138 keyInput.setKey(Key(value));
139 keyInput.setType(KeyInput::RELEASED);
140 keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
141 keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
142 keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
143 keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
144 keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
145 && event.key.keysym.sym <= SDLK_KP_EQUALS);
146
147 mKeyInputQueue.push(keyInput);
148 break;
149 }
150
151 case SDL_MOUSEBUTTONDOWN:
152 mMouseDown = true;
153 mouseInput.setX(event.button.x);
154 mouseInput.setY(event.button.y);
155 mouseInput.setButton(convertMouseButton(event.button.button));
156
157 if (event.button.button == SDL_BUTTON_WHEELDOWN)
158 {
159 mouseInput.setType(MouseInput::WHEEL_MOVED_DOWN);
160 }
161 else if (event.button.button == SDL_BUTTON_WHEELUP)
162 {
163 mouseInput.setType(MouseInput::WHEEL_MOVED_UP);
164 }
165 else
166 {
167 mouseInput.setType(MouseInput::PRESSED);
168 }
169 mouseInput.setTimeStamp(SDL_GetTicks());
170 mMouseInputQueue.push(mouseInput);
171 break;
172
173 case SDL_MOUSEBUTTONUP:
174 mMouseDown = false;
175 mouseInput.setX(event.button.x);
176 mouseInput.setY(event.button.y);
177 mouseInput.setButton(convertMouseButton(event.button.button));
178 mouseInput.setType(MouseInput::RELEASED);
179 mouseInput.setTimeStamp(SDL_GetTicks());
180 mMouseInputQueue.push(mouseInput);
181 break;
182
183 case SDL_MOUSEMOTION:
184 mouseInput.setX(event.button.x);
185 mouseInput.setY(event.button.y);
186 mouseInput.setButton(MouseInput::EMPTY);
187 mouseInput.setType(MouseInput::MOVED);
188 mouseInput.setTimeStamp(SDL_GetTicks());
189 mMouseInputQueue.push(mouseInput);
190 break;
191
192 case SDL_ACTIVEEVENT:
193 /*
194 * This occurs when the mouse leaves the window and the Gui-chan
195 * application loses its mousefocus.
196 */
197 if ((event.active.state & SDL_APPMOUSEFOCUS)
198 && !event.active.gain)
199 {
200 mMouseInWindow = false;
201
202 if (!mMouseDown)
203 {
204 mouseInput.setX(-1);
205 mouseInput.setY(-1);
206 mouseInput.setButton(MouseInput::EMPTY);
207 mouseInput.setType(MouseInput::MOVED);
208 mMouseInputQueue.push(mouseInput);
209 }
210 }
211
212 if ((event.active.state & SDL_APPMOUSEFOCUS)
213 && event.active.gain)
214 {
215 mMouseInWindow = true;
216 }
217 break;
218
219 } // end switch
220 }
221
222 int SDLInput::convertMouseButton(int button)
223 {
224 switch (button)
225 {
226 case SDL_BUTTON_LEFT:
227 return MouseInput::LEFT;
228 break;
229 case SDL_BUTTON_RIGHT:
230 return MouseInput::RIGHT;
231 break;
232 case SDL_BUTTON_MIDDLE:
233 return MouseInput::MIDDLE;
234 break;
235 default:
236 // We have an unknown mouse type which is ignored.
237 return button;
238 }
239 }
240
241 int SDLInput::convertSDLEventToGuichanKeyValue(SDL_Event event)
242 {
243 int value = -1;
244
245 switch (event.key.keysym.sym)
246 {
247 case SDLK_TAB:
248 value = Key::TAB;
249 break;
250 case SDLK_LALT:
251 value = Key::LEFT_ALT;
252 break;
253 case SDLK_RALT:
254 value = Key::RIGHT_ALT;
255 break;
256 case SDLK_LSHIFT:
257 value = Key::LEFT_SHIFT;
258 break;
259 case SDLK_RSHIFT:
260 value = Key::RIGHT_SHIFT;
261 break;
262 case SDLK_LCTRL:
263 value = Key::LEFT_CONTROL;
264 break;
265 case SDLK_RCTRL:
266 value = Key::RIGHT_CONTROL;
267 break;
268 case SDLK_BACKSPACE:
269 value = Key::BACKSPACE;
270 break;
271 case SDLK_PAUSE:
272 value = Key::PAUSE;
273 break;
274 case SDLK_SPACE:
275 // Special characters like ~ (tilde) ends up
276 // with the keysym.sym SDLK_SPACE which
277 // without this check would be lost. The check
278 // is only valid on key down events in SDL.
279 if (event.type == SDL_KEYUP || event.key.keysym.unicode == ' ')
280 {
281 value = Key::SPACE;
282 }
283 break;
284 case SDLK_ESCAPE:
285 value = Key::ESCAPE;
286 break;
287 case SDLK_DELETE:
288 value = Key::DELETE;
289 break;
290 case SDLK_INSERT:
291 value = Key::INSERT;
292 break;
293 case SDLK_HOME:
294 value = Key::HOME;
295 break;
296 case SDLK_END:
297 value = Key::END;
298 break;
299 case SDLK_PAGEUP:
300 value = Key::PAGE_UP;
301 break;
302 case SDLK_PRINT:
303 value = Key::PRINT_SCREEN;
304 break;
305 case SDLK_PAGEDOWN:
306 value = Key::PAGE_DOWN;
307 break;
308 case SDLK_F1:
309 value = Key::F1;
310 break;
311 case SDLK_F2:
312 value = Key::F2;
313 break;
314 case SDLK_F3:
315 value = Key::F3;
316 break;
317 case SDLK_F4:
318 value = Key::F4;
319 break;
320 case SDLK_F5:
321 value = Key::F5;
322 break;
323 case SDLK_F6:
324 value = Key::F6;
325 break;
326 case SDLK_F7:
327 value = Key::F7;
328 break;
329 case SDLK_F8:
330 value = Key::F8;
331 break;
332 case SDLK_F9:
333 value = Key::F9;
334 break;
335 case SDLK_F10:
336 value = Key::F10;
337 break;
338 case SDLK_F11:
339 value = Key::F11;
340 break;
341 case SDLK_F12:
342 value = Key::F12;
343 break;
344 case SDLK_F13:
345 value = Key::F13;
346 break;
347 case SDLK_F14:
348 value = Key::F14;
349 break;
350 case SDLK_F15:
351 value = Key::F15;
352 break;
353 case SDLK_NUMLOCK:
354 value = Key::NUM_LOCK;
355 break;
356 case SDLK_CAPSLOCK:
357 value = Key::CAPS_LOCK;
358 break;
359 case SDLK_SCROLLOCK:
360 value = Key::SCROLL_LOCK;
361 break;
362 case SDLK_RMETA:
363 value = Key::RIGHT_META;
364 break;
365 case SDLK_LMETA:
366 value = Key::LEFT_META;
367 break;
368 case SDLK_LSUPER:
369 value = Key::LEFT_SUPER;
370 break;
371 case SDLK_RSUPER:
372 value = Key::RIGHT_SUPER;
373 break;
374 case SDLK_MODE:
375 value = Key::ALT_GR;
376 break;
377 case SDLK_UP:
378 value = Key::UP;
379 break;
380 case SDLK_DOWN:
381 value = Key::DOWN;
382 break;
383 case SDLK_LEFT:
384 value = Key::LEFT;
385 break;
386 case SDLK_RIGHT:
387 value = Key::RIGHT;
388 break;
389 case SDLK_RETURN:
390 value = Key::ENTER;
391 break;
392 case SDLK_KP_ENTER:
393 value = Key::ENTER;
394 break;
395
396 default:
397 break;
398 }
399
400 if (!(event.key.keysym.mod & KMOD_NUM))
401 {
402 switch (event.key.keysym.sym)
403 {
404 case SDLK_KP0:
405 value = Key::INSERT;
406 break;
407 case SDLK_KP1:
408 value = Key::END;
409 break;
410 case SDLK_KP2:
411 value = Key::DOWN;
412 break;
413 case SDLK_KP3:
414 value = Key::PAGE_DOWN;
415 break;
416 case SDLK_KP4:
417 value = Key::LEFT;
418 break;
419 case SDLK_KP5:
420 value = 0;
421 break;
422 case SDLK_KP6:
423 value = Key::RIGHT;
424 break;
425 case SDLK_KP7:
426 value = Key::HOME;
427 break;
428 case SDLK_KP8:
429 value = Key::UP;
430 break;
431 case SDLK_KP9:
432 value = Key::PAGE_UP;
433 break;
434 default:
435 break;
436 }
437 }
438
439 return value;
440 }
441 }