1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: in_alleg.cpp 3694 2008-06-15 00:09:53Z dj_jl $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 //**
26 //** Input modue for Allegro library. Used only in Linux (in Windows I
27 //** don't use Allegro, in DOS keyboard and mouse are handled directly).
28 //**
29 //**************************************************************************
30
31 // HEADER FILES ------------------------------------------------------------
32
33 #include <allegro.h>
34 #include "gamedefs.h"
35
36 // MACROS ------------------------------------------------------------------
37
38 #define KBDQUESIZE 32
39
40 // TYPES -------------------------------------------------------------------
41
42 class VAllegroInputDevice : public VInputDevice
43 {
44 public:
45 VAllegroInputDevice();
46 ~VAllegroInputDevice();
47
48 void ReadInput();
49
50 private:
51 bool keyboard_started;
52
53 bool mouse_started;
54 int old_mouse_x;
55 int old_mouse_y;
56 int old_mouse_z;
57 int old_z_delta;
58 int lastbuttons;
59
60 bool joystick_started;
61 int joy_oldx;
62 int joy_oldy;
63 int joy_oldb[MAX_JOYSTICK_BUTTONS];
64
65 static const vuint8 scantokey[KEY_MAX];
66
67 void StartupKeyboard();
68 void ReadKeyboard();
69 void ShutdownKeyboard();
70
71 void StartupMouse();
72 void ReadMouse();
73 void ShutdownMouse();
74
75 void StartupJoystick();
76 void ReadJoystick();
77 void ShutdownJoystick();
78 };
79
80 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
81
82 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
83
84 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
85
86 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
87
88 // PUBLIC DATA DEFINITIONS -------------------------------------------------
89
90 // PRIVATE DATA DEFINITIONS ------------------------------------------------
91
92 static vuint8 keyboardque[KBDQUESIZE];
93 static int kbdtail = 0;
94 static int kbdhead = 0;
95
96 const vuint8 VAllegroInputDevice::scantokey[KEY_MAX] =
97 {
98 0,
99 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
100 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
101 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
102 K_PAD0, K_PAD1, K_PAD2, K_PAD3, K_PAD4,
103 K_PAD5, K_PAD6, K_PAD7, K_PAD8, K_PAD9,
104 K_F1, K_F2, K_F3, K_F4, K_F5, K_F6,
105 K_F7, K_F8, K_F9, K_F10, K_F11, K_F12,
106 K_ESCAPE, '`', '-', '=', K_BACKSPACE, K_TAB,
107 '[', ']', K_ENTER, ';', '\'', '\\', '\\', ',', '.', '/', ' ',
108 K_INSERT, K_DELETE, K_HOME, K_END, K_PAGEUP, K_PAGEDOWN,
109 K_LEFTARROW, K_RIGHTARROW, K_UPARROW, K_DOWNARROW,
110 K_PADDIVIDE, K_PADMULTIPLE, K_PADMINUS, K_PADPLUS,
111 K_PADDOT, K_PADENTER, K_PRINTSCRN, K_PAUSE,
112 K_ABNT_C1, K_YEN, K_KANA, K_CONVERT, K_NOCONVERT,
113 K_AT, K_CIRCUMFLEX, K_COLON2, K_KANJI,
114 K_LSHIFT, K_RSHIFT, K_LCTRL, K_RCTRL, K_LALT, K_RALT,
115 K_LWIN, K_RWIN, K_MENU, K_SCROLLLOCK, K_NUMLOCK, K_CAPSLOCK
116 };
117
118 static VCvarI m_filter("m_filter", "1", CVAR_Archive);
119
120 // CODE --------------------------------------------------------------------
121
122 //==========================================================================
123 //
124 // VAllegroInputDevice::VAllegroInputDevice
125 //
126 //==========================================================================
127
VAllegroInputDevice()128 VAllegroInputDevice::VAllegroInputDevice()
129 : keyboard_started(false)
130 , mouse_started(false)
131 , old_mouse_x(0)
132 , old_mouse_y(0)
133 , old_mouse_z(0)
134 , old_z_delta(0)
135 , lastbuttons(0)
136 , joystick_started(false)
137 , joy_oldx(0)
138 , joy_oldy(0)
139 {
140 guard(VAllegroInputDevice::VAllegroInputDevice);
141 StartupKeyboard();
142 StartupMouse();
143 StartupJoystick();
144 unguard;
145 }
146
147 //==========================================================================
148 //
149 // VAllegroInputDevice::~VAllegroInputDevice
150 //
151 //==========================================================================
152
~VAllegroInputDevice()153 VAllegroInputDevice::~VAllegroInputDevice()
154 {
155 guard(VAllegroInputDevice::~VAllegroInputDevice);
156 ShutdownJoystick();
157 ShutdownMouse();
158 ShutdownKeyboard();
159 unguard;
160 }
161
162 //==========================================================================
163 //
164 // VAllegroInputDevice::ReadInput
165 //
166 // Reads input from the input devices.
167 //
168 //==========================================================================
169
ReadInput()170 void VAllegroInputDevice::ReadInput()
171 {
172 guard(VAllegroInputDevice::ReadInput);
173 ReadKeyboard();
174 ReadMouse();
175 ReadJoystick();
176 unguard;
177 }
178
179 //**************************************************************************
180 //**
181 //** KEYBOARD
182 //**
183 //**************************************************************************
184
185 //==========================================================================
186 //
187 // KeyboardHandler
188 //
189 // Keyboard interrupt handler
190 //
191 //==========================================================================
192
KeyboardHandler(int key)193 static void KeyboardHandler(int key)
194 {
195 keyboardque[kbdhead & (KBDQUESIZE - 1)] = key;
196 kbdhead++;
197 }
END_OF_FUNCTION(KeyboardHandler)198 END_OF_FUNCTION(KeyboardHandler)
199
200 //==========================================================================
201 //
202 // VAllegroInputDevice::StartupKeyboard
203 //
204 // Installs the keyboard handler.
205 //
206 //==========================================================================
207
208 void VAllegroInputDevice::StartupKeyboard()
209 {
210 guard(VAllegroInputDevice::StartupKeyboard);
211 LOCK_FUNCTION((void*)KeyboardHandler);
212 LOCK_DATA(keyboardque, sizeof(keyboardque));
213 LOCK_VARIABLE(kbdhead);
214
215 if (install_keyboard())
216 {
217 Sys_Error("Failed to initialise keyboard");
218 }
219 keyboard_lowlevel_callback = KeyboardHandler;
220 keyboard_started = true;
221 unguard;
222 }
223
224 //==========================================================================
225 //
226 // VAllegroInputDevice::ReadKeyboard
227 //
228 //==========================================================================
229
ReadKeyboard()230 void VAllegroInputDevice::ReadKeyboard()
231 {
232 guard(VAllegroInputDevice::ReadKeyboard);
233 unsigned char ch;
234
235 if (!keyboard_started)
236 return;
237
238 while (kbdtail < kbdhead)
239 {
240 ch = keyboardque[kbdtail & (KBDQUESIZE - 1)];
241 kbdtail++;
242
243 GInput->KeyEvent(scantokey[ch & 0x7f], !(ch & 0x80));
244 }
245 unguard;
246 }
247
248 //==========================================================================
249 //
250 // VAllegroInputDevice::ShutdownKeyboard
251 //
252 // Removes the keyboard handler.
253 //
254 //==========================================================================
255
ShutdownKeyboard()256 void VAllegroInputDevice::ShutdownKeyboard()
257 {
258 guard(VAllegroInputDevice::ShutdownKeyboard);
259 if (keyboard_started)
260 {
261 remove_keyboard();
262 }
263 unguard;
264 }
265
266 //**************************************************************************
267 //**
268 //** MOUSE
269 //**
270 //**************************************************************************
271
272 //==========================================================================
273 //
274 // VAllegroInputDevice::StartupMouse
275 //
276 // Initialises mouse
277 //
278 //==========================================================================
279
StartupMouse()280 void VAllegroInputDevice::StartupMouse()
281 {
282 guard(VAllegroInputDevice::StartupMouse);
283 int buts;
284
285 if (GArgs.CheckParm("-nomouse"))
286 return;
287
288 buts = install_mouse();
289 if (buts == -1)
290 {
291 return;
292 }
293 mouse_started = true;
294 unguard;
295 }
296
297 //==========================================================================
298 //
299 // VAllegroInputDevice::ReadMouse
300 //
301 // Reads mouse.
302 //
303 //==========================================================================
304
ReadMouse()305 void VAllegroInputDevice::ReadMouse()
306 {
307 guard(VAllegroInputDevice::ReadMouse);
308 int i;
309 event_t event;
310 int xmickeys;
311 int ymickeys;
312 int mouse_x;
313 int mouse_y;
314 int buttons;
315
316 if (!mouse_started)
317 return;
318
319 poll_mouse();
320 get_mouse_mickeys(&xmickeys, &ymickeys);
321 int Wheel = mouse_z;
322 buttons = mouse_b;
323
324 if (m_filter == 2)
325 {
326 mouse_x = (xmickeys + old_mouse_x) / 2;
327 mouse_y = (ymickeys + old_mouse_y) / 2;
328 old_mouse_x = mouse_x;
329 old_mouse_y = mouse_y;
330 }
331 else if (m_filter == 1)
332 {
333 mouse_x = (xmickeys + old_mouse_x) / 2;
334 mouse_y = (ymickeys + old_mouse_y) / 2;
335 old_mouse_x = xmickeys;
336 old_mouse_y = ymickeys;
337 }
338 else
339 {
340 mouse_x = xmickeys;
341 mouse_y = ymickeys;
342 old_mouse_x = 0;
343 old_mouse_y = 0;
344 }
345
346 if (mouse_x || mouse_y)
347 {
348 event.type = ev_mouse;
349 event.data1 = 0;
350 event.data2 = mouse_x;
351 event.data3 = -mouse_y;
352
353 GInput->PostEvent(&event);
354 }
355 for (i = 0; i < 3; i++)
356 {
357 if ((buttons ^ lastbuttons) & (1 << i))
358 {
359 GInput->KeyEvent(K_MOUSE1 + i, buttons & (1 << i));
360 }
361 }
362 lastbuttons = buttons;
363
364 // Handle mouse wheel.
365 int ZDelta = Wheel - old_mouse_z;
366 if (ZDelta > 0 || old_mouse_z > 0)
367 {
368 GInput->KeyEvent(K_MWHEELUP, ZDelta > 0);
369 }
370 if (ZDelta < 0 || old_mouse_z < 0)
371 {
372 GInput->KeyEvent(K_MWHEELDOWN, ZDelta < 0);
373 }
374 old_mouse_z = Wheel;
375 old_z_delta = ZDelta;
376 unguard;
377 }
378
379 //==========================================================================
380 //
381 // VAllegroInputDevice::ShutdownMouse
382 //
383 //==========================================================================
384
ShutdownMouse()385 void VAllegroInputDevice::ShutdownMouse()
386 {
387 guard(VAllegroInputDevice::ShutdownMouse);
388 if (!mouse_started)
389 return;
390 remove_mouse();
391 unguard;
392 }
393
394 //**************************************************************************
395 //**
396 //** JOYSTICK
397 //**
398 //**************************************************************************
399
400 //==========================================================================
401 //
402 // VAllegroInputDevice::StartupJoystick
403 //
404 // Initialises joystick
405 //
406 //==========================================================================
407
StartupJoystick()408 void VAllegroInputDevice::StartupJoystick()
409 {
410 guard(VAllegroInputDevice::StartupJoystick);
411 if (GArgs.CheckParm("-nojoy"))
412 return;
413
414 // Detect the joystick type
415 if (install_joystick(JOY_TYPE_AUTODETECT))
416 {
417 Sys_Error("Error initialising joystick\n%s\n", allegro_error);
418 }
419
420 // Make sure that we really do have a joystick
421 if (!num_joysticks)
422 {
423 return;
424 }
425
426 // When initialising joystick, it must be centred, so we have to remove
427 // it, give a message to centre joystick, wait for keypress and then
428 // reinitialise it.
429 if (joy[0].flags & JOYFLAG_CALIBRATE)
430 {
431 remove_joystick();
432
433 printf("CENTRE the joystick and press a key:\n");
434 GInput->ReadKey();
435
436 // Initialise the joystick driver
437 if (install_joystick(JOY_TYPE_AUTODETECT))
438 {
439 Sys_Error("Error initialising joystick\n%s\n", allegro_error);
440 }
441 }
442
443 // Calibrate joystick
444 while (joy[0].flags & JOYFLAG_CALIBRATE)
445 {
446 printf("%s and press a key:\n", calibrate_joystick_name(0));
447 GInput->ReadKey();
448
449 if (calibrate_joystick(0))
450 {
451 Sys_Error("Error calibrating joystick!\n");
452 }
453 }
454
455 joystick_started = true;
456 memset(joy_oldb, 0, sizeof(joy_oldb));
457 unguard;
458 }
459
460 //==========================================================================
461 //
462 // VAllegroInputDevice::ReadJoystick
463 //
464 //==========================================================================
465
ReadJoystick()466 void VAllegroInputDevice::ReadJoystick()
467 {
468 guard(VAllegroInputDevice::ReadJoystick);
469 int i;
470 event_t event;
471
472 if (!joystick_started)
473 return;
474
475 poll_joystick();
476
477 if ((joy_oldx != joy_x) || (joy_oldy != joy_y))
478 {
479 event.type = ev_joystick;
480 event.data1 = 0;
481 event.data2 = (abs(joy_x) < 4)? 0 : joy_x;
482 event.data3 = (abs(joy_y) < 4)? 0 : joy_y;
483 GInput->PostEvent(&event);
484
485 joy_oldx = joy_x;
486 joy_oldy = joy_y;
487 }
488 for (i = 0; i < joy[0].num_buttons; i++)
489 {
490 if (joy[0].button[i].b != joy_oldb[i])
491 {
492 GInput->KeyEvent(K_JOY1 + i, joy[0].button[i].b);
493 joy_oldb[i] = joy[0].button[i].b;
494 }
495 }
496 unguard;
497 }
498
499 //==========================================================================
500 //
501 // VAllegroInputDevice::ShutdownJoystick
502 //
503 //==========================================================================
504
ShutdownJoystick()505 void VAllegroInputDevice::ShutdownJoystick()
506 {
507 guard(VAllegroInputDevice::ShutdownJoystick);
508 if (joystick_started)
509 {
510 remove_joystick();
511 }
512 unguard;
513 }
514
515 //==========================================================================
516 //
517 // VInputDevice::CreateDevice
518 //
519 //==========================================================================
520
CreateDevice()521 VInputDevice* VInputDevice::CreateDevice()
522 {
523 return new VAllegroInputDevice();
524 }
525