comparison ext/guichan-0.8.2/src/allegro/allegroinput.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/allegro/allegroinput.hpp"
49
50 #include <allegro.h>
51
52 #include "guichan/exception.hpp"
53
54 namespace gcn
55 {
56 AllegroInput::AllegroInput()
57 {
58 mMouseButton1 = mMouseButton2 = mMouseButton3 = false;
59 mLastMouseZ = 0;
60 mLastMouseX = 0;
61 mLastMouseY = 0;
62 }
63
64 bool AllegroInput::isKeyQueueEmpty()
65 {
66 return mKeyQueue.empty();
67 }
68
69 KeyInput AllegroInput::dequeueKeyInput()
70 {
71 if (isKeyQueueEmpty())
72 {
73 throw GCN_EXCEPTION("Key queue is empty.");
74 }
75
76 KeyInput ki = mKeyQueue.front();
77 mKeyQueue.pop();
78
79 return ki;
80 }
81
82 bool AllegroInput::isMouseQueueEmpty()
83 {
84 return mMouseQueue.empty();
85 }
86
87 MouseInput AllegroInput::dequeueMouseInput()
88 {
89 if (isMouseQueueEmpty())
90 {
91 throw GCN_EXCEPTION("Mouse queue is empty.");
92 }
93
94 MouseInput mi = mMouseQueue.front();
95 mMouseQueue.pop();
96
97 return mi;
98 }
99
100 void AllegroInput::_pollInput()
101 {
102 pollMouseInput();
103 pollKeyInput();
104 }
105
106 void AllegroInput::pollMouseInput()
107 {
108 if (mouse_needs_poll())
109 {
110 poll_mouse();
111 }
112 int mouseX = mouse_x;
113 int mouseY = mouse_y;
114 int mouseZ = mouse_z;
115 int mouseB1 = mouse_b & 1;
116 int mouseB2 = mouse_b & 2;
117 int mouseB3 = mouse_b & 4;
118
119 // Check mouse movement
120 if (mouseX != mLastMouseX || mouseY != mLastMouseY)
121 {
122 mMouseQueue.push(MouseInput(MouseInput::EMPTY,
123 MouseInput::MOVED,
124 mouseX,
125 mouseY,
126 0));
127 mLastMouseX = mouseX;
128 mLastMouseY = mouseY;
129 }
130
131 // Check mouse Wheel
132 while (mLastMouseZ < mouseZ)
133 {
134 mMouseQueue.push(MouseInput(MouseInput::EMPTY,
135 MouseInput::WHEEL_MOVED_UP,
136 mouseX,
137 mouseY,
138 0));
139 mLastMouseZ++;
140 }
141
142 while (mLastMouseZ > mouseZ)
143 {
144 mMouseQueue.push(MouseInput(MouseInput::EMPTY,
145 MouseInput::WHEEL_MOVED_DOWN,
146 mouseX,
147 mouseY,
148 0));
149 mLastMouseZ--;
150 }
151
152 // Check mouse buttons
153 if (!mMouseButton1 && mouseB1)
154 {
155 mMouseQueue.push(MouseInput(MouseInput::LEFT,
156 MouseInput::PRESSED,
157 mouseX,
158 mouseY,
159 0));
160 }
161
162 if (mMouseButton1 && !mouseB1)
163 {
164 mMouseQueue.push(MouseInput(MouseInput::LEFT,
165 MouseInput::RELEASED,
166 mouseX,
167 mouseY,
168 0));
169 }
170
171
172 if (!mMouseButton2 && mouseB2)
173 {
174 mMouseQueue.push(MouseInput(MouseInput::RIGHT,
175 MouseInput::PRESSED,
176 mouseX,
177 mouseY,
178 0));
179 }
180
181 if (mMouseButton2 && !mouseB2)
182 {
183 mMouseQueue.push(MouseInput(MouseInput::RIGHT,
184 MouseInput::RELEASED,
185 mouseX,
186 mouseY,
187 0));
188 }
189
190
191 if (!mMouseButton3 && mouseB3)
192 {
193 mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
194 MouseInput::PRESSED,
195 mouseX,
196 mouseY,
197 0));
198 }
199
200 if (mMouseButton3 && !mouseB3)
201 {
202 mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
203 MouseInput::RELEASED,
204 mouseX,
205 mouseY,
206 0));
207 }
208
209 mMouseButton1 = mouseB1;
210 mMouseButton2 = mouseB2;
211 mMouseButton3 = mouseB3;
212 }
213
214 void AllegroInput::pollKeyInput()
215 {
216 int unicode, scancode;
217
218 if (keyboard_needs_poll())
219 {
220 poll_keyboard();
221 }
222
223 while (keypressed())
224 {
225 unicode = ureadkey(&scancode);
226 Key keyObj = convertToKey(scancode, unicode);
227
228 KeyInput keyInput(keyObj, KeyInput::PRESSED);
229
230 keyInput.setNumericPad(isNumericPad(scancode));
231 keyInput.setShiftPressed(key_shifts & KB_SHIFT_FLAG);
232 keyInput.setAltPressed(key_shifts & KB_ALT_FLAG);
233 keyInput.setControlPressed(key_shifts & KB_CTRL_FLAG);
234 #ifdef KB_COMMAND_FLAG
235 keyInput.setMetaPressed(key_shifts & (KB_COMMAND_FLAG |
236 KB_LWIN_FLAG |
237 KB_RWIN_FLAG));
238 #else
239 keyInput.setMetaPressed(key_shifts & (KB_LWIN_FLAG |
240 KB_RWIN_FLAG));
241 #endif
242
243
244 mKeyQueue.push(keyInput);
245
246 mPressedKeys[scancode] = keyInput;
247 }
248
249 if (key[KEY_ALT] && mPressedKeys.find(KEY_ALT) == mPressedKeys.end())
250 {
251 KeyInput keyInput(convertToKey(KEY_ALT, 0), KeyInput::PRESSED);
252 mKeyQueue.push(keyInput);
253 mPressedKeys[KEY_ALT] = keyInput;
254 }
255
256 if (key[KEY_ALTGR] && mPressedKeys.find(KEY_ALTGR) == mPressedKeys.end())
257 {
258 KeyInput keyInput(convertToKey(KEY_ALTGR, 0), KeyInput::PRESSED);
259 mKeyQueue.push(keyInput);
260 mPressedKeys[KEY_ALTGR] = keyInput;
261 }
262
263 if (key[KEY_LSHIFT] && mPressedKeys.find(KEY_LSHIFT) == mPressedKeys.end())
264 {
265 KeyInput keyInput(convertToKey(KEY_LSHIFT, 0), KeyInput::PRESSED);
266 mKeyQueue.push(keyInput);
267 mPressedKeys[KEY_LSHIFT] = keyInput;
268 }
269
270 if (key[KEY_RSHIFT] && mPressedKeys.find(KEY_RSHIFT) == mPressedKeys.end())
271 {
272 KeyInput keyInput(convertToKey(KEY_RSHIFT, 0), KeyInput::PRESSED);
273 mKeyQueue.push(keyInput);
274 mPressedKeys[KEY_RSHIFT] = keyInput;
275 }
276
277 if (key[KEY_LCONTROL] && mPressedKeys.find(KEY_LCONTROL) == mPressedKeys.end())
278 {
279 KeyInput keyInput(convertToKey(KEY_LCONTROL, 0), KeyInput::PRESSED);
280 mKeyQueue.push(keyInput);
281 mPressedKeys[KEY_LCONTROL] = keyInput;
282 }
283
284 if (key[KEY_RCONTROL] && mPressedKeys.find(KEY_RCONTROL) == mPressedKeys.end())
285 {
286 KeyInput keyInput(convertToKey(KEY_RCONTROL, 0), KeyInput::PRESSED);
287 mKeyQueue.push(keyInput);
288 mPressedKeys[KEY_RCONTROL] = keyInput;
289 }
290
291 // Check for released keys
292 std::map<int, KeyInput>::iterator iter, tempIter;
293 for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); )
294 {
295 if (!key[iter->first])
296 {
297 KeyInput keyInput(iter->second.getKey(), KeyInput::RELEASED);
298 keyInput.setNumericPad(iter->second.isNumericPad());
299 keyInput.setShiftPressed(iter->second.isShiftPressed());
300 keyInput.setAltPressed(iter->second.isAltPressed());
301 keyInput.setControlPressed(iter->second.isControlPressed());
302
303 mKeyQueue.push(keyInput);
304
305 tempIter = iter;
306 iter++;
307 mPressedKeys.erase(tempIter);
308 }
309 else
310 {
311 iter++;
312 }
313 }
314 }
315
316 Key AllegroInput::convertToKey(int scancode, int unicode)
317 {
318 int keysym;
319 bool pad = false;
320
321 switch(scancode)
322 {
323 case KEY_ESC:
324 keysym = Key::ESCAPE;
325 break;
326
327 case KEY_ALT:
328 keysym = Key::LEFT_ALT;
329 break;
330
331 case KEY_ALTGR:
332 keysym = Key::RIGHT_ALT;
333 break;
334
335 case KEY_LSHIFT:
336 keysym = Key::LEFT_SHIFT;
337 break;
338
339 case KEY_RSHIFT:
340 keysym = Key::RIGHT_SHIFT;
341 break;
342
343 case KEY_LCONTROL:
344 keysym = Key::LEFT_CONTROL;
345 break;
346
347 case KEY_RCONTROL:
348 keysym = Key::RIGHT_CONTROL;
349 break;
350
351 case KEY_LWIN:
352 keysym = Key::LEFT_META;
353 break;
354
355 case KEY_RWIN:
356 keysym = Key::RIGHT_META;
357 break;
358
359 case KEY_INSERT:
360 keysym = Key::INSERT;
361 break;
362
363 case KEY_HOME:
364 keysym = Key::HOME;
365 break;
366
367 case KEY_PGUP:
368 keysym = Key::PAGE_UP;
369 break;
370
371 case KEY_PGDN:
372 keysym = Key::PAGE_DOWN;
373 break;
374
375 case KEY_DEL:
376 keysym = Key::DELETE;
377 break;
378
379 case KEY_DEL_PAD:
380 keysym = Key::DELETE;
381 pad = true;
382 break;
383
384 case KEY_END:
385 keysym = Key::END;
386 break;
387
388 case KEY_CAPSLOCK:
389 keysym = Key::CAPS_LOCK;
390 break;
391
392 case KEY_BACKSPACE:
393 keysym = Key::BACKSPACE;
394 break;
395
396 case KEY_F1:
397 keysym = Key::F1;
398 break;
399
400 case KEY_F2:
401 keysym = Key::F2;
402 break;
403
404 case KEY_F3:
405 keysym = Key::F3;
406 break;
407
408 case KEY_F4:
409 keysym = Key::F4;
410 break;
411
412 case KEY_F5:
413 keysym = Key::F5;
414 break;
415
416 case KEY_F6:
417 keysym = Key::F6;
418 break;
419
420 case KEY_F7:
421 keysym = Key::F7;
422 break;
423
424 case KEY_F8:
425 keysym = Key::F8;
426 break;
427
428 case KEY_F9:
429 keysym = Key::F9;
430 break;
431
432 case KEY_F10:
433 keysym = Key::F10;
434 break;
435
436 case KEY_F11:
437 keysym = Key::F11;
438 break;
439
440 case KEY_F12:
441 keysym = Key::F12;
442 break;
443
444 case KEY_PRTSCR:
445 keysym = Key::PRINT_SCREEN;
446 break;
447
448 case KEY_PAUSE:
449 keysym = Key::PAUSE;
450 break;
451
452 case KEY_SCRLOCK:
453 keysym = Key::SCROLL_LOCK;
454 break;
455
456 case KEY_NUMLOCK:
457 keysym = Key::NUM_LOCK;
458 break;
459
460 case KEY_LEFT:
461 keysym = Key::LEFT;
462 break;
463
464 case KEY_RIGHT:
465 keysym = Key::RIGHT;
466 break;
467
468 case KEY_UP:
469 keysym = Key::UP;
470 break;
471
472 case KEY_DOWN:
473 keysym = Key::DOWN;
474 break;
475
476 case KEY_ENTER_PAD:
477 pad = true;
478 case KEY_ENTER:
479 keysym = Key::ENTER;
480 break;
481 default:
482 keysym = unicode;
483 }
484
485 Key k = Key(keysym);
486
487 return k;
488
489 //Now, THAT was fun to code! =D =D =D
490 }
491
492 bool AllegroInput::isNumericPad(int scancode)
493 {
494 switch (scancode)
495 {
496 case KEY_0_PAD:
497 case KEY_1_PAD:
498 case KEY_2_PAD:
499 case KEY_3_PAD:
500 case KEY_4_PAD:
501 case KEY_5_PAD:
502 case KEY_6_PAD:
503 case KEY_7_PAD:
504 case KEY_8_PAD:
505 case KEY_9_PAD:
506 case KEY_SLASH_PAD:
507 case KEY_MINUS_PAD:
508 case KEY_PLUS_PAD:
509 return true;
510 default:
511 return false;
512 }
513 }
514 }