comparison ext/guichan-0.8.2/src/openlayer/openlayerinput.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/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 }