comparison ext/guichan-0.8.1/src/allegro/allegroinput.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
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 }