1 /**
2  * @file handler_keyboard.cc
3  * @brief Handler of the keyboard and mouse
4  * @date 2012-09-04
5  * @copyright 1991-2014 TLK Games
6  * @author Bruno Ethvignot
7  * @version $Revision: 24 $
8  */
9 /*
10  * copyright (c) 1991-2014 TLK Games all rights reserved
11  * $Id: handler_keyboard.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
12  *
13  * TecnoballZ is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * TecnoballZ is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26  * MA  02110-1301, USA.
27  */
28 #include "../include/handler_keyboard.h"
29 #include "../include/handler_display.h"
30 
31 bool
32 handler_keyboard::command_keys[NUMOF_COMMAND_KEYS];
33 bool
34 handler_keyboard::last_command_keys[NUMOF_COMMAND_KEYS];
35 Uint32
36 handler_keyboard::key_codes[K_MAXOF] =
37 {
38   SDLK_LEFT,
39   SDLK_RIGHT,
40   SDLK_UP,
41   SDLK_DOWN,
42   SDLK_SPACE,
43   SDLK_LCTRL,
44   SDLK_LALT,
45   SDLK_PAGEUP,
46   SDLK_PAGEDOWN
47 };
48 handler_keyboard *
49 handler_keyboard::keyboard_singleton = NULL;
50 
51 #ifdef TECNOBALLZ_GP2X
52 bool
53 handler_keyboard::gp2x_buttons[GP2X_NUM_BUTTONS];
54 #endif
55 #ifdef TECNOBALLZ_PSP
56 bool
57 handler_keyboard::psp_buttons[PSP_NUM_BUTTONS];
58 #endif
59 
60 /**
61  * Create the handler_keyboard singleton object, and clear members
62  */
handler_keyboard()63 handler_keyboard::handler_keyboard ()
64 {
65   object_init ();
66   is_grab_input = false;
67   mouse_x_offset = 0;
68   mouse_y_offset = 0;
69   /* x and y coordinates of the mouse */
70   mouse_x_coord = 0;
71   mouse_y_coord = 0;
72   is_left_button_down = false;
73   is_right_button_down = false;
74   is_middle_button_down = false;
75   is_left_button_released = 0;
76   is_right_button_released = 0;
77   key_delay = 0;
78   key_code_down = 0;
79   previous_key_code_down = 0;
80   string_cursor_pos = 0;
81   string_input_size = 0;
82   code_keyup = 0;
83   current_input_string = NULL;
84   for (Uint32 i = 0; i < NUMOF_COMMAND_KEYS; i++)
85     {
86       command_keys[i] = false;
87       last_command_keys[i] = false;
88     }
89   init_joysticks ();
90   is_key_waiting = true;
91   wait_key_pressed = false;
92   joy_code_down = 0;
93   joy_code_down_prev = 0;
94   joy_up = 0;
95   input_joy_tempo = 0;
96 #ifdef TECNOBALLZ_GP2X
97   for (Uint32 i = 0; i < GP2X_NUM_BUTTONS; i++)
98     {
99       gp2x_buttons[i] = false;
100     }
101 #endif
102 #ifdef TECNOBALLZ_PSP
103   for (Uint32 i = 0; i < PSP_NUM_BUTTONS; i++)
104     {
105       psp_buttons[i] = false;
106     }
107 #endif
108 }
109 
110 /**
111  * Release the handler_keyboard singleton object
112  */
~handler_keyboard()113 handler_keyboard::~handler_keyboard ()
114 {
115   object_free ();
116   keyboard_singleton = NULL;
117   if (numof_joysticks > 0)
118     {
119       for (Uint32 i = 0; i < numof_joysticks; i++)
120         {
121           if (sdl_joysticks[i] != NULL)
122             {
123               SDL_JoystickClose (sdl_joysticks[i]);
124               sdl_joysticks[i] = NULL;
125             }
126         }
127       delete[]sdl_joysticks;
128       numof_joysticks = 0;
129     }
130 }
131 
132 /**
133  * Open joystick(s) if available
134  */
135 void
init_joysticks()136 handler_keyboard::init_joysticks ()
137 {
138   joy_fire = false;
139   joy_release = false;
140   joy_gigablitz = false;
141   joy_option = false;
142   joy_left = false;
143   joy_right = false;
144   joy_top = false;
145   joy_down = false;
146   numof_joysticks = SDL_NumJoysticks ();
147   if (is_verbose)
148     {
149       std::cout << "handler_keyboard::init_joysticks()" <<
150       " number of joysticks available: " << numof_joysticks << std::endl;
151     }
152   if (numof_joysticks > 0)
153     {
154       sdl_joysticks = new SDL_Joystick *[numof_joysticks];
155       for (Uint32 i = 0; i < numof_joysticks; i++)
156         {
157 
158           sdl_joysticks[i] = SDL_JoystickOpen (i);
159           if (sdl_joysticks[i] == NULL)
160             {
161               std::cerr << "(!)handler_keyboard::init_joysticks()" <<
162               " couldn't open joystick " << i << ": "
163               << SDL_GetError () << std::endl;
164             }
165           else
166             {
167               if (is_verbose)
168                 {
169                   std::
170                   cout << "- joystick  : " << SDL_JoystickName (i) << std::
171                   endl;
172                   std::
173                   cout << "- axes      : " <<
174                   SDL_JoystickNumAxes (sdl_joysticks[i]) << std::endl;
175                   std::
176                   cout << "- buttons   : " <<
177                   SDL_JoystickNumButtons (sdl_joysticks[i]) << std::endl;
178                   std::
179                   cout << "- trackballs: " <<
180                   SDL_JoystickNumButtons (sdl_joysticks[i]) << std::endl;
181                   std::
182                   cout << "- hats      : " <<
183                   SDL_JoystickNumHats (sdl_joysticks[i]) << std::endl;
184                 }
185             }
186         }
187     }
188 }
189 
190 /**
191  * Get the object instance
192  * handler_keyboard is a singleton
193  * @return the handler_keyboard object
194  */
195 handler_keyboard *
get_instance()196 handler_keyboard::get_instance ()
197 {
198   if (NULL == keyboard_singleton)
199     {
200       keyboard_singleton = new handler_keyboard ();
201     }
202   return keyboard_singleton;
203 }
204 
205 /**
206  * Grabs mouse and keyboard input, the mouse is confined to the
207  * application window, and nearly all keyboard input is passed
208  * directly to the application
209  * @param mode true to enable grab input, false to disable it
210  */
211 #ifdef UNDER_DEVELOPMENT
212 void
set_grab_input(bool)213 handler_keyboard::set_grab_input (bool)
214 {
215   return;
216 }
217 #else
218 void
set_grab_input(bool mode)219 handler_keyboard::set_grab_input (bool mode)
220 {
221   if (mode)
222     {
223       is_grab_input = true;
224       SDL_WM_GrabInput (SDL_GRAB_ON);
225       SDL_EventState (SDL_MOUSEMOTION, SDL_IGNORE);
226       SDL_WarpMouse (display->get_width () >> 1, display->get_height () >> 1);
227       SDL_EventState (SDL_MOUSEMOTION, SDL_ENABLE);
228     }
229   else
230     {
231       is_grab_input = false;
232       SDL_WM_GrabInput (SDL_GRAB_OFF);
233     }
234 }
235 #endif
236 
237 /**
238  * Handle buttons of handheld video game console
239  * @param event Pointer to a SDL_Event structure
240  */
241 #ifdef TECNOBALLZ_HANDHELD_CONSOLE
242 void
handle_console_buttons(SDL_Event * event)243 handler_keyboard::handle_console_buttons (SDL_Event * event)
244 {
245 #ifdef TECNOBALLZ_GP2X
246   if (event->jbutton.button >= GP2X_NUM_BUTTONS)
247     {
248       return;
249     }
250   if (event->type == SDL_JOYBUTTONDOWN)
251     {
252       gp2x_buttons[event->jbutton.button] = true;
253       if (event->jbutton.button == GP2X_BUTTON_UP
254           || event->jbutton.button == GP2X_BUTTON_UPRIGHT
255           || event->jbutton.button == GP2X_BUTTON_UPRIGHT)
256         {
257           set_joy (IJOY_TOP);
258         }
259       if (event->jbutton.button == GP2X_BUTTON_DOWN
260           || event->jbutton.button == GP2X_BUTTON_DOWNLEFT
261           || event->jbutton.button == GP2X_BUTTON_DOWNRIGHT)
262         {
263           set_joy (IJOY_DOWN);
264         }
265 
266       if (event->jbutton.button == GP2X_BUTTON_LEFT
267           || event->jbutton.button == GP2X_BUTTON_UPLEFT
268           || event->jbutton.button == GP2X_BUTTON_DOWNLEFT
269           || event->jbutton.button == GP2X_BUTTON_L)
270         {
271           set_joy (IJOY_LEFT);
272         }
273 
274       if (event->jbutton.button == GP2X_BUTTON_RIGHT
275           || event->jbutton.button == GP2X_BUTTON_UPRIGHT
276           || event->jbutton.button == GP2X_BUTTON_DOWNRIGHT
277           || event->jbutton.button == GP2X_BUTTON_R)
278         {
279           set_joy (IJOY_RIGHT);
280         }
281       if (event->jbutton.button == GP2X_BUTTON_A
282           || event->jbutton.button == GP2X_BUTTON_B
283           || event->jbutton.button == GP2X_BUTTON_CLICK)
284         {
285           set_joy (IJOY_FIRE);
286         }
287       if (event->jbutton.button == GP2X_BUTTON_X
288           || event->jbutton.button == GP2X_BUTTON_Y)
289         {
290           set_joy (IJOY_OPTION);
291         }
292       if (event->jbutton.button == GP2X_BUTTON_SELECT)
293         {
294           last_command_keys[TOGGLE_POPUP_MENU] = true;
295         }
296       if (event->jbutton.button == GP2X_BUTTON_START)
297         {
298           last_command_keys[COMMAND_KEY_PAUSE] = true;
299         }
300       if (event->jbutton.button == GP2X_BUTTON_VOLUP)
301         {
302           last_command_keys[VOLUME_UP] = true;
303         }
304       if (event->jbutton.button == GP2X_BUTTON_VOLDOWN)
305         {
306           last_command_keys[VOLUME_DOWN] = true;
307         }
308     }
309   else
310     {
311       gp2x_buttons[event->jbutton.button] = false;
312       if (event->jbutton.button == GP2X_BUTTON_UP
313           || event->jbutton.button == GP2X_BUTTON_UPRIGHT
314           || event->jbutton.button == GP2X_BUTTON_UPRIGHT)
315         {
316           clr_joy (IJOY_TOP);
317         }
318       if (event->jbutton.button == GP2X_BUTTON_DOWN
319           || event->jbutton.button == GP2X_BUTTON_DOWNLEFT
320           || event->jbutton.button == GP2X_BUTTON_DOWNRIGHT)
321         {
322           clr_joy (IJOY_DOWN);
323         }
324       if (event->jbutton.button == GP2X_BUTTON_LEFT
325           || event->jbutton.button == GP2X_BUTTON_UPLEFT
326           || event->jbutton.button == GP2X_BUTTON_DOWNLEFT
327           || event->jbutton.button == GP2X_BUTTON_L)
328         {
329           clr_joy (IJOY_LEFT);
330         }
331       if (event->jbutton.button == GP2X_BUTTON_RIGHT
332           || event->jbutton.button == GP2X_BUTTON_UPRIGHT
333           || event->jbutton.button == GP2X_BUTTON_DOWNRIGHT
334           || event->jbutton.button == GP2X_BUTTON_R)
335         {
336           clr_joy (IJOY_RIGHT);
337         }
338       if (event->jbutton.button == GP2X_BUTTON_A
339           || event->jbutton.button == GP2X_BUTTON_B
340           || event->jbutton.button == GP2X_BUTTON_CLICK)
341         {
342           clr_joy (IJOY_FIRE);
343         }
344       if (event->jbutton.button == GP2X_BUTTON_X
345           || event->jbutton.button == GP2X_BUTTON_Y)
346         {
347           clr_joy (IJOY_OPTION);
348         }
349       if (event->jbutton.button == GP2X_BUTTON_SELECT
350           && last_command_keys[TOGGLE_POPUP_MENU])
351         {
352           toggle_popup_menu ();
353         }
354       if (event->jbutton.button == GP2X_BUTTON_START
355           && last_command_keys[COMMAND_KEY_PAUSE])
356         {
357           toggle_pause ();
358         }
359       if (event->jbutton.button == GP2X_BUTTON_VOLUP
360           && last_command_keys[VOLUME_UP])
361         {
362           last_command_keys[VOLUME_UP] = false;
363           command_keys[VOLUME_UP] = true;
364         }
365       if (event->jbutton.button == GP2X_BUTTON_VOLDOWN
366           && last_command_keys[VOLUME_DOWN])
367         {
368           last_command_keys[VOLUME_DOWN] = false;
369           command_keys[VOLUME_DOWN] = true;
370         }
371     }
372   /* This button mapping conforms to the GP2X Common User Interface
373      Recommendations, as of 2006-07-29, available from
374      http://wiki.gp2x.org/wiki/Common_User_Interface_Recommendations */
375 
376   /* Directions (UDLR) */
377   joy_top = gp2x_buttons[GP2X_BUTTON_UP]
378             | gp2x_buttons[GP2X_BUTTON_UPLEFT] | gp2x_buttons[GP2X_BUTTON_UPRIGHT];
379   joy_down = gp2x_buttons[GP2X_BUTTON_DOWN]
380              | gp2x_buttons[GP2X_BUTTON_DOWNLEFT]
381              | gp2x_buttons[GP2X_BUTTON_DOWNRIGHT];
382   joy_left = gp2x_buttons[GP2X_BUTTON_LEFT]
383              | gp2x_buttons[GP2X_BUTTON_UPLEFT]
384              | gp2x_buttons[GP2X_BUTTON_DOWNLEFT] | gp2x_buttons[GP2X_BUTTON_L];
385   joy_right = gp2x_buttons[GP2X_BUTTON_RIGHT]
386               | gp2x_buttons[GP2X_BUTTON_UPRIGHT]
387               | gp2x_buttons[GP2X_BUTTON_DOWNRIGHT] | gp2x_buttons[GP2X_BUTTON_R];
388 
389   /* volume ctrl */
390   joy_fire = gp2x_buttons[GP2X_BUTTON_A] | gp2x_buttons[GP2X_BUTTON_CLICK];
391   joy_release = gp2x_buttons[GP2X_BUTTON_B];
392   joy_gigablitz = gp2x_buttons[GP2X_BUTTON_X];
393   joy_option = gp2x_buttons[GP2X_BUTTON_Y];
394 
395   /* Quit */
396   command_keys[QUIT_TECNOBALLZ] = gp2x_buttons[GP2X_BUTTON_CLICK]
397                                   & gp2x_buttons[GP2X_BUTTON_START];
398 #endif
399 #ifdef TECNOBALLZ_PSP
400   if (event->jbutton.button >= PSP_NUM_BUTTONS)
401     {
402       return;
403     }
404   if (event->type == SDL_JOYBUTTONDOWN)
405     {
406       psp_buttons[event->jbutton.button] = true;
407       if (event->jbutton.button == PSP_BUTTON_UP)
408         {
409           set_joy (IJOY_TOP);
410         }
411       if (event->jbutton.button == PSP_BUTTON_DOWN)
412         {
413           set_joy (IJOY_DOWN);
414         }
415       if (event->jbutton.button == PSP_BUTTON_LEFT)
416         {
417           set_joy (IJOY_LEFT);
418         }
419       if (event->jbutton.button == PSP_BUTTON_RIGHT)
420         {
421           set_joy (IJOY_RIGHT);
422         }
423       if (event->jbutton.button == PSP_BUTTON_A)
424         {
425           set_joy (IJOY_FIRE);
426         }
427       if (event->jbutton.button == PSP_BUTTON_X)
428         {
429           set_joy (IJOY_OPTION);
430         }
431       if (event->jbutton.button == PSP_BUTTON_SELECT)
432         {
433           last_command_keys[TOGGLE_POPUP_MENU] = true;
434         }
435       if (event->jbutton.button == PSP_BUTTON_START)
436         {
437           last_command_keys[COMMAND_KEY_PAUSE] = true;
438         }
439     }
440   else
441     {
442       psp_buttons[event->jbutton.button] = false;
443       if (event->jbutton.button == PSP_BUTTON_UP)
444         {
445           clr_joy (IJOY_TOP);
446         }
447       if (event->jbutton.button == PSP_BUTTON_DOWN)
448         {
449           clr_joy (IJOY_DOWN);
450         }
451       if (event->jbutton.button == PSP_BUTTON_LEFT)
452         {
453           clr_joy (IJOY_LEFT);
454         }
455       if (event->jbutton.button == PSP_BUTTON_RIGHT)
456         {
457           clr_joy (IJOY_RIGHT);
458         }
459       if (event->jbutton.button == PSP_BUTTON_A)
460         {
461           clr_joy (IJOY_FIRE);
462         }
463       if (event->jbutton.button == PSP_BUTTON_X)
464         {
465           clr_joy (IJOY_OPTION);
466         }
467       if (event->jbutton.button == PSP_BUTTON_SELECT
468           && last_command_keys[TOGGLE_POPUP_MENU])
469         {
470           toggle_popup_menu ();
471         }
472       if (event->jbutton.button == PSP_BUTTON_START
473           && last_command_keys[COMMAND_KEY_PAUSE])
474         {
475           toggle_pause ();
476         }
477     }
478 
479   /* Directions (UDLR) */
480   joy_top = psp_buttons[PSP_BUTTON_UP];
481   joy_down = psp_buttons[PSP_BUTTON_DOWN];
482   joy_left = psp_buttons[PSP_BUTTON_LEFT];
483   joy_right = psp_buttons[PSP_BUTTON_RIGHT];
484   joy_fire = psp_buttons[PSP_BUTTON_A];
485   joy_release = psp_buttons[PSP_BUTTON_B];
486   joy_gigablitz = psp_buttons[PSP_BUTTON_X];
487   joy_option = psp_buttons[PSP_BUTTON_Y];
488 #endif
489 }
490 #endif
491 
492 /**
493  * Request to enable or disable popup menu
494  */
495 void
toggle_popup_menu()496 handler_keyboard::toggle_popup_menu ()
497 {
498   last_command_keys[TOGGLE_POPUP_MENU] = false;
499   command_keys[TOGGLE_POPUP_MENU] =
500     command_keys[TOGGLE_POPUP_MENU] ? false : true;
501   command_keys[COMMAND_KEY_PAUSE] = command_keys[TOGGLE_POPUP_MENU];
502   if (is_grab_input && command_keys[COMMAND_KEY_PAUSE])
503     {
504       SDL_WM_GrabInput (SDL_GRAB_OFF);
505     }
506   if (is_grab_input && !command_keys[COMMAND_KEY_PAUSE])
507     {
508       SDL_WM_GrabInput (SDL_GRAB_ON);
509     }
510 
511   if (!command_keys[TOGGLE_POPUP_MENU])
512     {
513       SDL_ShowCursor (SDL_DISABLE);
514     }
515   if (command_keys[TOGGLE_POPUP_MENU])
516     {
517       SDL_ShowCursor (SDL_ENABLE);
518     }
519 }
520 
521 /**
522  * Request to enable or disable pause mode
523  */
524 void
toggle_pause()525 handler_keyboard::toggle_pause ()
526 {
527   last_command_keys[COMMAND_KEY_PAUSE] = false;
528   if (!command_keys[TOGGLE_POPUP_MENU])
529     {
530       command_keys[COMMAND_KEY_PAUSE] =
531         command_keys[COMMAND_KEY_PAUSE] ? false : true;
532       if (is_grab_input && command_keys[COMMAND_KEY_PAUSE])
533         {
534           SDL_WM_GrabInput (SDL_GRAB_OFF);
535         }
536       if (is_grab_input && !command_keys[COMMAND_KEY_PAUSE])
537         {
538           SDL_WM_GrabInput (SDL_GRAB_ON);
539         }
540     }
541 }
542 
543 /**
544  * Read keyboard mouse and exit events
545  */
546 void
read_events()547 handler_keyboard::read_events ()
548 {
549   command_keys[TOGGLE_FULLSCREEN] = false;
550   command_keys[DISABLE_TIMER] = false;
551   command_keys[VOLUME_DOWN] = false;
552   command_keys[VOLUME_UP] = false;
553   is_left_button_released = 0;
554   is_right_button_released = 0;
555   SDL_Event event;
556   SDL_KeyboardEvent *kbEvt;
557 
558   while (SDL_PollEvent (&event) > 0)
559     {
560       switch (event.type)
561         {
562           /* mouse motion event */
563         case SDL_MOUSEMOTION:
564         {
565           /* read the x and y coordinates of the mouse */
566           mouse_x_coord = event.motion.x;
567           mouse_y_coord = event.motion.y;
568           mouse_x_offset += event.motion.xrel;
569           mouse_y_offset += event.motion.yrel;
570         }
571         break;
572 
573         /* a key is pressed */
574         case SDL_KEYDOWN:
575         {
576           kbEvt = (SDL_KeyboardEvent *) & event;
577           Uint8 *keys = SDL_GetKeyState (NULL);
578 
579           if (keys[SDLK_RALT] == SDL_RELEASED &&
580               keys[SDLK_LALT] == SDL_RELEASED &&
581               keys[SDLK_LSHIFT] == SDL_RELEASED &&
582               keys[SDLK_RSHIFT] == SDL_RELEASED)
583             {
584 
585               if (keys[SDLK_RCTRL] == SDL_RELEASED &&
586                   keys[SDLK_LCTRL] == SDL_RELEASED)
587                 {
588                   if (keys[SDLK_p] == SDL_PRESSED)
589                     {
590                       last_command_keys[COMMAND_KEY_PAUSE] = true;
591                     }
592                   if (keys[SDLK_f] == SDL_PRESSED)
593                     {
594                       last_command_keys[TOGGLE_FULLSCREEN] = true;
595                     }
596                   if (keys[SDLK_ESCAPE] == SDL_PRESSED)
597                     {
598                       last_command_keys[TOGGLE_POPUP_MENU] = true;
599                     }
600                   if (keys[SDLK_l] == SDL_PRESSED)
601                     {
602                       last_command_keys[DISABLE_TIMER] = true;
603                     }
604                   if (keys[SDLK_PAGEDOWN] == SDL_PRESSED)
605                     {
606                       last_command_keys[VOLUME_DOWN] = true;
607                     }
608                   if (keys[SDLK_PAGEUP] == SDL_PRESSED)
609                     {
610                       last_command_keys[VOLUME_UP] = true;
611                     }
612                 }
613               else
614                 {
615                   if (keys[SDLK_ESCAPE] == SDL_PRESSED)
616                     {
617                       last_command_keys[QUIT_TECNOBALLZ] = true;
618                     }
619                   if (keys[SDLK_x] == SDL_PRESSED)
620                     {
621                       last_command_keys[CAUSE_GAME_OVER] = true;
622                     }
623                   if (keys[SDLK_q] == SDL_PRESSED)
624                     {
625                       last_command_keys[QUIT_TO_MAIN_MENU] = true;
626                     }
627                   if (keys[SDLK_f] == SDL_PRESSED)
628                     {
629                       last_command_keys[TOGGLE_SOUND] = true;
630                     }
631                   if (keys[SDLK_s] == SDL_PRESSED)
632                     {
633                       last_command_keys[TOGGLE_AUDIO] = true;
634                     }
635                   if (keys[SDLK_d] == SDL_PRESSED)
636                     {
637                       last_command_keys[TOGGLE_MUSIC] = true;
638                     }
639                 }
640             }
641 
642           if (kbEvt->keysym.unicode > 0)
643             {
644               set_key_code_down (kbEvt->keysym.unicode);
645             }
646           else
647             {
648               set_key_code_down (kbEvt->keysym.sym);
649             }
650         }
651         break;
652 
653         /* a key is released */
654         case SDL_KEYUP:
655         {
656           kbEvt = (SDL_KeyboardEvent *) & event;
657           Uint8 *keys = SDL_GetKeyState (NULL);
658 
659 
660           /* enable pause [P] key */
661           if (keys[SDLK_p] == SDL_RELEASED
662               && last_command_keys[COMMAND_KEY_PAUSE])
663             {
664               toggle_pause ();
665             }
666 
667           /* enable context menu [ESC] key */
668           if (keys[TOGGLE_POPUP_MENU] == SDL_RELEASED
669               && last_command_keys[TOGGLE_POPUP_MENU])
670             {
671               toggle_popup_menu ();
672             }
673 
674           if (keys[SDLK_f] == SDL_RELEASED
675               && last_command_keys[TOGGLE_FULLSCREEN])
676             {
677               last_command_keys[TOGGLE_FULLSCREEN] = false;
678               command_keys[TOGGLE_FULLSCREEN] = true;
679             }
680           {
681             if (keys[SDLK_ESCAPE] == SDL_RELEASED
682                 && last_command_keys[QUIT_TECNOBALLZ])
683               {
684                 last_command_keys[QUIT_TECNOBALLZ] = false;
685                 command_keys[QUIT_TECNOBALLZ] = true;
686               }
687             if (keys[SDLK_x] == SDL_RELEASED
688                 && last_command_keys[CAUSE_GAME_OVER])
689               {
690                 last_command_keys[CAUSE_GAME_OVER] = false;
691                 command_keys[CAUSE_GAME_OVER] = true;
692               }
693             if (keys[SDLK_q] == SDL_RELEASED
694                 && last_command_keys[QUIT_TO_MAIN_MENU])
695               {
696                 last_command_keys[QUIT_TO_MAIN_MENU] = false;
697                 command_keys[QUIT_TO_MAIN_MENU] = true;
698               }
699             if (keys[SDLK_f] == SDL_RELEASED
700                 && last_command_keys[TOGGLE_SOUND])
701               {
702                 last_command_keys[TOGGLE_SOUND] = false;
703                 command_keys[TOGGLE_SOUND] = true;
704               }
705             if (keys[SDLK_s] == SDL_RELEASED
706                 && last_command_keys[TOGGLE_AUDIO])
707               {
708                 last_command_keys[TOGGLE_AUDIO] = false;
709                 command_keys[TOGGLE_AUDIO] = true;
710               }
711             if (keys[SDLK_d] == SDL_RELEASED
712                 && last_command_keys[TOGGLE_MUSIC])
713               {
714                 last_command_keys[TOGGLE_MUSIC] = false;
715                 command_keys[TOGGLE_MUSIC] = true;
716               }
717             if (keys[SDLK_l] == SDL_RELEASED
718                 && last_command_keys[DISABLE_TIMER])
719               {
720                 last_command_keys[DISABLE_TIMER] = false;
721                 command_keys[DISABLE_TIMER] = true;
722               }
723             if (keys[SDLK_PAGEDOWN] == SDL_RELEASED
724                 && last_command_keys[VOLUME_DOWN])
725               {
726                 last_command_keys[VOLUME_DOWN] = false;
727                 command_keys[VOLUME_DOWN] = true;
728               }
729             if (keys[SDLK_PAGEUP] == SDL_RELEASED
730                 && last_command_keys[VOLUME_UP])
731               {
732                 last_command_keys[VOLUME_UP] = false;
733                 command_keys[VOLUME_UP] = true;
734               }
735 
736           }
737 
738           if (kbEvt->keysym.unicode > 0)
739             {
740               set_keycode_up (kbEvt->keysym.unicode);
741             }
742           else
743             {
744               set_keycode_up (kbEvt->keysym.sym);
745             }
746         }
747         break;
748 
749         /* a mouse button is pressed */
750         case SDL_MOUSEBUTTONDOWN:
751         {
752           switch (event.button.button)
753             {
754             case SDL_BUTTON_LEFT:
755               is_left_button_down = true;
756               break;
757             case SDL_BUTTON_RIGHT:
758               is_right_button_down = true;
759               break;
760             case SDL_BUTTON_MIDDLE:
761               is_middle_button_down = true;
762               break;
763             }
764         }
765         break;
766 
767         /* a mouse button is relased */
768         case SDL_MOUSEBUTTONUP:
769         {
770           switch (event.button.button)
771             {
772             case SDL_BUTTON_LEFT:
773               if (is_left_button_down)
774                 {
775                   is_left_button_released = true;
776                 }
777               is_left_button_down = false;
778               break;
779             case SDL_BUTTON_RIGHT:
780               if (is_right_button_down)
781                 {
782                   is_right_button_released = true;
783                 }
784               is_right_button_down = false;
785               break;
786             case SDL_BUTTON_MIDDLE:
787               is_middle_button_down = false;
788               break;
789             }
790         }
791         break;
792 
793         case SDL_JOYAXISMOTION:
794         {
795           Sint32 deadzone = 4096;
796           /* x axis */
797           if (event.jaxis.axis == 0)
798             {
799               if (event.jaxis.value < -deadzone)
800                 {
801                   joy_left = true;
802                   set_joy (IJOY_LEFT);
803                   joy_right = false;
804                 }
805               else if (event.jaxis.value > deadzone)
806                 {
807                   joy_left = false;
808                   joy_right = true;
809                   set_joy (IJOY_RIGHT);
810                 }
811               else
812                 {
813                   joy_left = false;
814                   joy_right = false;
815                   clr_joy (IJOY_RIGHT);
816                   clr_joy (IJOY_LEFT);
817                 }
818             }
819           /* y axis */
820           else if (event.jaxis.axis == 1)
821             {
822               if (event.jaxis.value < -deadzone)
823                 {
824                   joy_down = false;
825                   joy_top = true;
826                   set_joy (IJOY_TOP);
827                 }
828               else if (event.jaxis.value > deadzone)
829                 {
830                   joy_down = true;
831                   joy_top = false;
832                   set_joy (IJOY_DOWN);
833                 }
834               else
835                 {
836                   joy_down = false;
837                   joy_top = false;
838                   clr_joy (IJOY_TOP);
839                   clr_joy (IJOY_DOWN);
840                 }
841             }
842         }
843         break;
844         case SDL_JOYBUTTONDOWN:
845 #ifdef TECNOBALLZ_HANDHELD_CONSOLE
846           handle_console_buttons (&event);
847 #else
848           if (event.jbutton.button == 2)
849             {
850               joy_gigablitz = true;
851               set_joy (IJOY_GIGABLITZ);
852             }
853           else if (event.jbutton.button == 0)
854             {
855               joy_fire = true;
856               set_joy (IJOY_FIRE);
857             }
858           else if (event.jbutton.button == 1)
859             {
860               joy_release = true;
861               set_joy (IJOY_RELEASE);
862             }
863           else if (event.jbutton.button > 2)
864             {
865               joy_option = true;
866               last_command_keys[TOGGLE_POPUP_MENU] = true;
867               set_joy (IJOY_OPTION);
868             }
869           break;
870 #endif
871         case SDL_JOYBUTTONUP:
872 #ifdef TECNOBALLZ_HANDHELD_CONSOLE
873           handle_console_buttons (&event);
874 #else
875           if (event.jbutton.button == 2)
876             {
877               joy_gigablitz = false;
878               clr_joy (IJOY_GIGABLITZ);
879             }
880           else if (event.jbutton.button == 0)
881             {
882               joy_fire = false;
883               clr_joy (IJOY_FIRE);
884             }
885           else if (event.jbutton.button == 1)
886             {
887               joy_release = false;
888               clr_joy (IJOY_RELEASE);
889             }
890           else if (event.jbutton.button > 2)
891             {
892               joy_option = false;
893               clr_joy (IJOY_OPTION);
894               if (last_command_keys[TOGGLE_POPUP_MENU])
895                 {
896                   last_command_keys[TOGGLE_POPUP_MENU] = false;
897                   command_keys[TOGGLE_POPUP_MENU] =
898                     command_keys[TOGGLE_POPUP_MENU] ? false : true;
899                   command_keys[COMMAND_KEY_PAUSE] =
900                     command_keys[TOGGLE_POPUP_MENU];
901                 }
902             }
903 #endif
904           break;
905 
906           /* quit the game */
907         case SDL_QUIT:
908         {
909           command_keys[QUIT_TECNOBALLZ] = true;
910         }
911         break;
912         }
913     }
914   random_counter += mouse_x_coord;
915   random_counter += mouse_y_coord;
916   input_string ();
917 }
918 
919 /**
920  * Check if a key is pressed
921  * @param code a SDL Keysym definition
922  * @return true if the key is pressed
923  */
924 bool
key_is_pressed(Sint32 code)925 handler_keyboard::key_is_pressed (Sint32 code)
926 {
927   Uint8 *keys;
928   keys = SDL_GetKeyState (NULL);
929   if (keys[code] == SDL_PRESSED)
930     {
931       return true;
932     }
933   else
934     {
935       return false;
936     }
937 }
938 
939 /**
940  * Check if a key is released
941  * @param code a SDL Keysym definition
942  * @return true if the key is released
943  */
944 bool
key_is_released(Sint32 code)945 handler_keyboard::key_is_released (Sint32 code)
946 {
947   Uint8 *keys;
948   keys = SDL_GetKeyState (NULL);
949   if (keys[code] == SDL_RELEASED)
950     {
951       return true;
952     }
953   else
954     {
955       return false;
956     }
957 }
958 
959 /**
960  * Check if a control key is pressed
961  * @param code A code of key
962  * @return true if the key is pressed
963  */
control_is_pressed(Uint32 code)964 bool handler_keyboard::control_is_pressed (Uint32 code)
965 {
966   /*
967      if(code >= K_MAXOF)
968      {
969      std::cerr << "(!)handler_keyboard::control_is_pressed() " <<
970      code << " is greated or equal to " << K_MAXOF << std::endl;
971      return false;
972      }
973    */
974   Uint8 *
975   keys;
976   keys = SDL_GetKeyState (NULL);
977   if (keys[key_codes[code]] == SDL_PRESSED)
978     {
979       return true;
980     }
981   else
982     {
983       switch (code)
984         {
985         case K_LEFT:
986           return joy_left ? true : false;
987           break;
988         case K_RIGHT:
989           return joy_right ? true : false;
990           break;
991         case K_UP:
992           return joy_top ? true : false;
993           break;
994         case K_DOWN:
995           return joy_down ? true : false;
996           break;
997         case K_FIRE:
998           return joy_fire ? true : false;
999           break;
1000         case K_RELEASE_BALL:
1001           return joy_release ? true : false;
1002           break;
1003         case K_GIGABLITZ:
1004           return joy_gigablitz ? true : false;
1005           break;
1006         }
1007       return false;
1008     }
1009 }
1010 
1011 /**
1012  * Clear some command keys and set grab input
1013  */
1014 void
clear_command_keys()1015 handler_keyboard::clear_command_keys ()
1016 {
1017   command_keys[COMMAND_KEY_PAUSE] = false;
1018   command_keys[QUIT_TO_MAIN_MENU] = false;
1019   command_keys[CAUSE_GAME_OVER] = false;
1020   command_keys[TOGGLE_AUDIO] = false;
1021   command_keys[TOGGLE_SOUND] = false;
1022   command_keys[TOGGLE_MUSIC] = false;
1023   command_keys[TOGGLE_POPUP_MENU] = false;
1024   last_command_keys[COMMAND_KEY_PAUSE] = false;
1025   last_command_keys[QUIT_TO_MAIN_MENU] = false;
1026   last_command_keys[CAUSE_GAME_OVER] = false;
1027   last_command_keys[TOGGLE_AUDIO] = false;
1028   last_command_keys[TOGGLE_SOUND] = false;
1029   last_command_keys[TOGGLE_MUSIC] = false;
1030   last_command_keys[TOGGLE_POPUP_MENU] = false;
1031   if (is_grab_input)
1032     {
1033       SDL_WM_GrabInput (SDL_GRAB_ON);
1034     }
1035   mouse_x_offset = 0;
1036   mouse_y_offset = 0;
1037   is_key_waiting = true;
1038   wait_key_pressed = false;
1039 }
1040 
1041 /**
1042  * Check if a command key is pressed
1043  * @param code of the command key
1044  * @param clear true if clear flag after read
1045  * @return true if the command key is pressed
1046  */
1047 bool
command_is_pressed(Uint32 code,bool clear)1048 handler_keyboard::command_is_pressed (Uint32 code, bool clear)
1049 {
1050   bool is_pressed = command_keys[code];
1051   if (clear)
1052     {
1053       command_keys[code] = false;
1054     }
1055   return is_pressed;
1056 }
1057 
1058 /**
1059  * Test if mouse left button is pressed
1060  * @return true if mouse left button is down
1061  */
1062 bool
is_left_button()1063 handler_keyboard::is_left_button ()
1064 {
1065   return is_left_button_down;
1066 }
1067 
1068 /**
1069  * Test if mouse right button is pressed
1070  * @return true if mouse right button is down
1071  */
1072 bool
is_right_button()1073 handler_keyboard::is_right_button ()
1074 {
1075   return is_right_button_down;
1076 }
1077 
1078 
1079 /**
1080  * Check if player want send a gigablitz or enable tilt
1081  * @return true if want send a gigablitz or enable tilt
1082  */
is_gigablitz_or_tilt()1083 bool handler_keyboard::is_gigablitz_or_tilt ()
1084 {
1085   if (is_middle_button_down || control_is_pressed (K_GIGABLITZ))
1086     {
1087       return true;
1088     }
1089   else
1090     {
1091       return false;
1092     }
1093 }
1094 
1095 /**
1096  * Test if mouse right and left button are pressed (start gigablitz)
1097  * @return true if mouse right and left buttons are down
1098  */
1099 /*
1100 bool handler_keyboard::is_right_left_buttons ()
1101 {
1102   if (is_right_button_down && is_left_button_down)
1103     {
1104       return true;
1105     }
1106   else
1107     {
1108       return false;
1109     }
1110 }
1111 */
1112 
1113 /**
1114  * Test if the left mouse button were released
1115  * @param x_coord pointer to integer in which to return x mouse
1116  * @param y_coord pointer to integer in which to return y mouse
1117  * @return true if the left mouse button is released
1118  */
1119 bool
is_left_button_up(Sint32 * x_coord,Sint32 * y_coord)1120 handler_keyboard::is_left_button_up (Sint32 * x_coord, Sint32 * y_coord)
1121 {
1122   *x_coord = mouse_x_coord;
1123   *y_coord = mouse_y_coord;
1124   return is_left_button_released;
1125 }
1126 
1127 /**
1128  * Test if the right mouse button were released
1129  * @param x_coord pointer to integer in which to return x mouse
1130  * @param y_coord pointer to integer in which to return y mouse
1131  * @return true if the right mouse button is released
1132  */
1133 bool
is_right_button_up(Sint32 * x_coord,Sint32 * y_coord)1134 handler_keyboard::is_right_button_up (Sint32 * x_coord, Sint32 * y_coord)
1135 {
1136   *x_coord = mouse_x_coord;
1137   *y_coord = mouse_y_coord;
1138   return is_right_button_released;
1139 }
1140 
1141 /**
1142  * Caculate and return offset of horizontal displacement of the mouse
1143  * @return the mouse horizonal offset
1144  */
1145 Sint32
get_mouse_x_offset()1146 handler_keyboard::get_mouse_x_offset ()
1147 {
1148   Sint32 retval = mouse_x_offset;
1149   random_counter += mouse_x_coord + mouse_x_offset;
1150   mouse_x_offset = 0;
1151   return retval;
1152 }
1153 
1154 /**
1155 * Caculate and return offset of vertical displacement of the mouse
1156 * @return the mouse vertical offset
1157 */
1158 Sint32
get_mouse_y_offset()1159 handler_keyboard::get_mouse_y_offset ()
1160 {
1161   Sint32 retval = mouse_y_offset;
1162   random_counter += mouse_y_coord + mouse_y_offset;
1163   mouse_y_offset = 0;
1164   return retval;
1165 }
1166 
1167 
1168 /**
1169  * Return absolute mouse y coordinate
1170  * @return the mouse pointer y coordinate
1171  */
1172 Sint32
get_mouse_y()1173 handler_keyboard::get_mouse_y ()
1174 {
1175   return mouse_y_coord;
1176 }
1177 
1178 /**
1179  * Return absolute mouse x coordinate
1180  * @return the mouse pointer x coordinate
1181  */
1182 Sint32
get_mouse_x()1183 handler_keyboard::get_mouse_x ()
1184 {
1185   return mouse_x_coord;
1186 }
1187 
1188 /**
1189  * Set new pressed key for handle string input
1190  * @param kcode key code of the pressed key
1191  */
1192 void
set_key_code_down(Uint32 kcode)1193 handler_keyboard::set_key_code_down (Uint32 kcode)
1194 {
1195   if (kcode != SDLK_LSHIFT && kcode != SDLK_RSHIFT && kcode != SDLK_LCTRL &&
1196       kcode != SDLK_RCTRL)
1197     key_code_down = kcode;
1198 }
1199 
1200 /**
1201  * Set new relased key for handle string input
1202  * @param kcode key code of the pressed key
1203  */
1204 void
set_keycode_up(Uint32 kcode)1205 handler_keyboard::set_keycode_up (Uint32 kcode)
1206 {
1207   if (kcode != SDLK_LSHIFT && kcode != SDLK_RSHIFT && kcode != SDLK_LCTRL &&
1208       kcode != SDLK_RCTRL)
1209     {
1210       code_keyup = kcode;
1211       if (code_keyup == key_code_down)
1212         {
1213           key_code_down = 0;
1214         }
1215       key_delay = 0;
1216       previous_key_code_down = 0;
1217     }
1218 }
1219 
1220 
1221 /**
1222  * Set a joystick code
1223  * @param code A joystick code, a buttom is down
1224  */
1225 void
set_joy(Uint32 code)1226 handler_keyboard::set_joy (Uint32 code)
1227 {
1228   joy_code_down = code;
1229   input_joy_tempo = 0;
1230 }
1231 
1232 /**
1233  * Clear a joystick code, a button is up
1234  * @param code A joystick code
1235  */
1236 void
clr_joy(Uint32 code)1237 handler_keyboard::clr_joy (Uint32 code)
1238 {
1239   joy_up = code;
1240   if (joy_up == joy_code_down)
1241     {
1242       joy_code_down = 0;
1243       input_joy_tempo = 0;
1244       key_delay = 0;
1245       joy_code_down_prev = 0;
1246     }
1247 }
1248 
1249 /**
1250  * Handle string input
1251  */
1252 void
input_string()1253 handler_keyboard::input_string ()
1254 {
1255   Sint32 kcode = 0;
1256   if (key_delay < 1)
1257     {
1258       kcode = key_code_down;
1259       if (key_code_down > 0)
1260         {
1261           /* it is key pressed for the first time? */
1262           if (previous_key_code_down != key_code_down)
1263             {
1264               previous_key_code_down = key_code_down;
1265               key_delay = 30;
1266             }
1267           else
1268             {
1269               /* repeat key press delay */
1270               key_delay = 10;
1271             }
1272         }
1273     }
1274   else
1275     {
1276       kcode = 0;
1277       key_delay--;
1278     }
1279   if (current_input_string == NULL)
1280     {
1281       return;
1282     }
1283   input_string (kcode);
1284 
1285   /* input string with the joystick */
1286   Sint32 joycode = 0;
1287   if (input_joy_tempo < 1)
1288     {
1289       joycode = joy_code_down;
1290       if (joy_code_down > 0)
1291         {
1292           /* button pressed for the first time? */
1293           if (joy_code_down_prev != joy_code_down)
1294             {
1295               joy_code_down_prev = joy_code_down;
1296               input_joy_tempo = 40;
1297             }
1298           else
1299             {
1300               input_joy_tempo = 5;
1301             }
1302         }
1303     }
1304   else
1305     {
1306       joycode = 0;
1307       input_joy_tempo--;
1308     }
1309   if (joycode > 0)
1310     {
1311       switch (joycode)
1312         {
1313         case IJOY_FIRE:
1314         case IJOY_RELEASE:
1315           current_input_string[string_cursor_pos] = ' ';
1316           break;
1317         case IJOY_OPTION:
1318         case IJOY_GIGABLITZ:
1319           input_string (SDLK_RETURN);
1320           break;
1321         case IJOY_LEFT:
1322           input_string (SDLK_LEFT);
1323           break;
1324         case IJOY_RIGHT:
1325           input_string (SDLK_RIGHT);
1326           break;
1327         case IJOY_TOP:
1328         {
1329           char c = current_input_string[string_cursor_pos] + 1;
1330 
1331           /* space (32) / ! (33)
1332            * , (44) /  - (45) / . (46) /
1333            * 0-9 (48-57) : (58)
1334            * A-Z (65 to 90)
1335            */
1336           if (c > 90)
1337             {
1338               c = 32;
1339             }
1340           else if (c > 58 && c < 65)
1341             {
1342               c = 65;
1343             }
1344           else if (c > 46 && c < 48)
1345             {
1346               c = 48;
1347             }
1348           else if (c > 33 && c < 44)
1349             {
1350               c = 44;
1351             }
1352           current_input_string[string_cursor_pos] = c;
1353         }
1354         break;
1355         case IJOY_DOWN:
1356           char c = current_input_string[string_cursor_pos] - 1;
1357           if (c < 32)
1358             {
1359               c = 90;
1360             }
1361           else if (c < 44 && c > 33)
1362             {
1363               c = 33;
1364             }
1365           else if (c < 48 && c > 46)
1366             {
1367               c = 46;
1368             }
1369           else if (c < 65 && c > 58)
1370             {
1371               c = 58;
1372             }
1373           current_input_string[string_cursor_pos] = c;
1374           break;
1375         }
1376     }
1377 }
1378 
1379 /**
1380  * Handle input string
1381  * @param kcode Key code enter
1382  */
1383 void
input_string(Uint32 kcode)1384 handler_keyboard::input_string (Uint32 kcode)
1385 {
1386   Sint32 j, i;
1387   if (0 == kcode)
1388     {
1389       return;
1390     }
1391 
1392   /* check pressed key */
1393   switch (kcode)
1394     {
1395     case SDLK_LEFT:
1396       string_cursor_pos--;
1397       break;
1398     case SDLK_RIGHT:
1399       string_cursor_pos++;
1400       break;
1401 
1402       /* backspace key pressed */
1403     case SDLK_BACKSPACE:
1404       if (string_cursor_pos > 0)
1405         {
1406           j = string_cursor_pos;
1407         }
1408       else
1409         {
1410           j = 1;
1411         }
1412       for (i = j; i < string_input_size; i++)
1413         {
1414           current_input_string[i - 1] = current_input_string[i];
1415         }
1416       current_input_string[string_input_size - 1] = ' ';
1417       string_cursor_pos--;
1418       break;
1419 
1420       /* [Suppr] key pressed? */
1421     case SDLK_DELETE:
1422       for (i = string_cursor_pos; i < string_input_size - 1; i++)
1423         {
1424           current_input_string[i] = current_input_string[i + 1];
1425         }
1426       current_input_string[string_input_size - 1] = ' ';
1427       break;
1428 
1429       /* [Return] or [Enter] pressed, stop string input */
1430     case SDLK_RETURN:
1431       stop_string_input ();
1432       return;
1433       break;
1434 
1435     default:
1436       kcode = kcode & 127;
1437       if (kcode >= 'a' && kcode <= 'z')
1438         {
1439           kcode = kcode - 32;
1440         }
1441 
1442       /* space (32) / ! (33)
1443        * , (44) /  - (45) / . (46) /
1444        * : (58) / 0-9 (48-57)
1445        * A-Z (65 to 90)
1446        */
1447       if ((kcode >= ' ' && kcode <= '!') ||
1448           (kcode >= '-' && kcode <= '.') ||
1449           (kcode >= '0' && kcode <= ':') ||
1450           (kcode >= 'A' && kcode <= 'Z') || kcode == '\'')
1451         {
1452           for (i = string_input_size - 1; i > string_cursor_pos; i--)
1453             {
1454               current_input_string[i] = current_input_string[i - 1];
1455             }
1456           current_input_string[string_cursor_pos] = kcode;
1457           string_cursor_pos++;
1458         }
1459     }
1460 
1461   /* verify overflow position cursor */
1462   if (string_cursor_pos < 0)
1463     {
1464       string_cursor_pos = 0;
1465     }
1466   if (string_cursor_pos > string_input_size - 1)
1467     {
1468       string_cursor_pos = string_input_size - 1;
1469     }
1470 }
1471 
1472 /**
1473  * Initializes a string input
1474  * @param strng pointer to a string
1475  * @param ssize size of the string
1476  */
1477 void
set_input_string(char * strng,Uint32 ssize)1478 handler_keyboard::set_input_string (char *strng, Uint32 ssize)
1479 {
1480   string_cursor_pos = 0;
1481   string_input_size = ssize;
1482   current_input_string = strng;
1483 }
1484 
1485 /**
1486  * Return the current cursor position in the input string
1487  * @return current cursor position 0 to n
1488  */
1489 Sint32
get_input_cursor_pos()1490 handler_keyboard::get_input_cursor_pos ()
1491 {
1492   if (NULL == current_input_string)
1493     {
1494       /* not current input string */
1495       return -1;
1496     }
1497   return string_cursor_pos;
1498 }
1499 
1500 /**
1501  * Stop using string input
1502  */
1503 void
stop_string_input()1504 handler_keyboard::stop_string_input ()
1505 {
1506   string_cursor_pos = 0;
1507   string_input_size = 0;
1508   current_input_string = NULL;
1509 }
1510 
1511 
1512 /**
1513  * Set the code of the last key down
1514  * @return last pressed key code
1515  */
get_key_down_code()1516 Uint32 handler_keyboard::get_key_down_code ()
1517 {
1518   return key_code_down;
1519 }
1520 
1521 
1522 /**
1523  * Wait a key (used for press an key to continue)
1524  * @return true if a key is pressed and released
1525  */
wait_key()1526 bool handler_keyboard::wait_key ()
1527 {
1528   if (is_key_waiting)
1529     {
1530       if (!control_is_pressed (K_FIRE) &&
1531           !control_is_pressed (K_RELEASE_BALL) &&
1532           !control_is_pressed (K_GIGABLITZ) && !is_left_button_down)
1533         {
1534           is_key_waiting = false;
1535         }
1536       wait_key_pressed = false;
1537       return false;
1538     }
1539   if (control_is_pressed (K_FIRE) ||
1540       control_is_pressed (K_RELEASE_BALL) ||
1541       control_is_pressed (K_GIGABLITZ) || is_left_button_down)
1542     {
1543       wait_key_pressed = true;
1544       return false;
1545     }
1546   if (wait_key_pressed)
1547     {
1548       return true;
1549     }
1550   return false;
1551 }
1552