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