Added line-editing functionality to console (issue 111)
[supertux.git] / src / control / joystickkeyboardcontroller.cpp
1 //  $Id$
2 //
3 //  SuperTux
4 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include <sstream>
23 #include "joystickkeyboardcontroller.hpp"
24 #include "log.hpp"
25 #include "gui/menu.hpp"
26 #include "gettext.hpp"
27 #include "lisp/lisp.hpp"
28 #include "lisp/list_iterator.hpp"
29 #include "game_session.hpp"
30 #include "console.hpp"
31 #include "gameconfig.hpp"
32
33 class JoystickKeyboardController::JoystickMenu : public Menu
34 {
35 public:
36   JoystickMenu(JoystickKeyboardController* controller);
37   virtual ~JoystickMenu();
38
39   void update();
40   std::string get_button_name(int button);
41   virtual void menu_action(MenuItem* item);
42   JoystickKeyboardController* controller;
43 };
44
45 class JoystickKeyboardController::KeyboardMenu : public Menu
46 {
47 public:
48   KeyboardMenu(JoystickKeyboardController* controller);
49   ~KeyboardMenu();
50
51   void update();
52   std::string get_key_name(SDLKey key);
53   virtual void menu_action(MenuItem* item);
54   JoystickKeyboardController* controller;
55 };
56
57 JoystickKeyboardController::JoystickKeyboardController()
58   : wait_for_key(-1), wait_for_joybutton(-1), key_options_menu(0),
59     joystick_options_menu(0)
60 {
61   // initialize default keyboard map
62   keymap.insert(std::make_pair(SDLK_LEFT, LEFT));
63   keymap.insert(std::make_pair(SDLK_RIGHT, RIGHT));
64   keymap.insert(std::make_pair(SDLK_UP, UP));
65   keymap.insert(std::make_pair(SDLK_DOWN, DOWN));
66   keymap.insert(std::make_pair(SDLK_SPACE, JUMP));
67   keymap.insert(std::make_pair(SDLK_LCTRL, ACTION));
68   keymap.insert(std::make_pair(SDLK_LALT, ACTION));
69   keymap.insert(std::make_pair(SDLK_ESCAPE, PAUSE_MENU));
70   keymap.insert(std::make_pair(SDLK_p, PAUSE_MENU));
71   keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU));
72   keymap.insert(std::make_pair(SDLK_RETURN, MENU_SELECT));
73   keymap.insert(std::make_pair(SDLK_KP_ENTER, MENU_SELECT));
74   keymap.insert(std::make_pair(SDLK_CARET, CONSOLE));
75   keymap.insert(std::make_pair(SDLK_DELETE, PEEK_LEFT));
76   keymap.insert(std::make_pair(SDLK_END, PEEK_RIGHT));
77
78   int joystick_count = SDL_NumJoysticks();
79   min_joybuttons = -1;
80   max_joybuttons = -1;
81   for(int i = 0; i < joystick_count; ++i) {
82     SDL_Joystick* joystick = SDL_JoystickOpen(i);
83     bool good = true;
84     if(SDL_JoystickNumButtons(joystick) < 2) {
85       log_info << "Joystick " << i << " has less than 2 buttons" << std::endl;
86       good = false;
87     }
88     if(SDL_JoystickNumAxes(joystick) < 2
89        && SDL_JoystickNumHats(joystick) == 0) {
90       log_info << "Joystick " << i << " has less than 2 axes and no hat" << std::endl;
91       good = false;
92     }
93     if(!good) {
94       SDL_JoystickClose(joystick);
95       continue;
96     }
97
98     if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
99       min_joybuttons = SDL_JoystickNumButtons(joystick);
100     if(SDL_JoystickNumButtons(joystick) > max_joybuttons) {
101       max_joybuttons = SDL_JoystickNumButtons(joystick);
102     }
103
104     joysticks.push_back(joystick);
105   }
106
107   use_hat = true;
108   joyaxis_x = 0;
109   joyaxis_y = 1;
110   dead_zone_x = 1000;
111   dead_zone_y = 1000;
112
113   joy_button_map.insert(std::make_pair(0, JUMP));
114   joy_button_map.insert(std::make_pair(1, ACTION));
115   // 6 or more Buttons
116   if( min_joybuttons > 5 ){
117     joy_button_map.insert(std::make_pair( 4, PEEK_LEFT));
118     joy_button_map.insert(std::make_pair( 5, PEEK_RIGHT));
119     // 8 or more
120     if(min_joybuttons > 7)
121       joy_button_map.insert(std::make_pair(min_joybuttons-1, PAUSE_MENU));
122     // map all remaining joystick buttons to MENU_SELECT
123     for(int i = 2; i < max_joybuttons; ++i) {
124       if( i != min_joybuttons-1 && i !=4  && i!= 5 )
125         joy_button_map.insert(std::make_pair(i, MENU_SELECT));
126     }
127
128   } else {
129     // map the last 2 buttons to menu and pause
130     if(min_joybuttons > 2)
131       joy_button_map.insert(std::make_pair(min_joybuttons-1, PAUSE_MENU));
132     // map all remaining joystick buttons to MENU_SELECT
133     for(int i = 2; i < max_joybuttons; ++i) {
134       if(i != min_joybuttons-1)
135         joy_button_map.insert(std::make_pair(i, MENU_SELECT));
136     }
137   }
138
139   // some joysticks or SDL seem to produce some bogus events after being opened
140   Uint32 ticks = SDL_GetTicks();
141   while(SDL_GetTicks() - ticks < 200) {
142     SDL_Event event;
143     SDL_PollEvent(&event);
144   }
145 }
146
147 JoystickKeyboardController::~JoystickKeyboardController()
148 {
149   for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
150       i != joysticks.end(); ++i) {
151     if(*i != 0)
152       SDL_JoystickClose(*i);
153   }
154
155   delete key_options_menu;
156   delete joystick_options_menu;
157 }
158
159 void
160 JoystickKeyboardController::read(const lisp::Lisp& lisp)
161 {
162   const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
163   if(keymap_lisp) {
164     keymap.clear();
165     lisp::ListIterator iter(keymap_lisp);
166     while(iter.next()) {
167       if(iter.item() == "map") {
168         int key = -1;
169         std::string control;
170         const lisp::Lisp* map = iter.lisp();
171         map->get("key", key);
172         map->get("control", control);
173         if(key < SDLK_FIRST || key >= SDLK_LAST) {
174           log_info << "Invalid key '" << key << "' in keymap" << std::endl;
175           continue;
176         }
177
178         int i = 0;
179         for(i = 0; controlNames[i] != 0; ++i) {
180           if(control == controlNames[i])
181             break;
182         }
183         if(controlNames[i] == 0) {
184           log_info << "Invalid control '" << control << "' in keymap" << std::endl;
185           continue;
186         }
187         keymap.insert(std::make_pair((SDLKey) key, (Control) i));
188       } else {
189         log_info << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl;
190       }
191     }
192   }
193
194   const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
195   if(joystick_lisp) {
196     joystick_lisp->get("use_hat", use_hat);
197     joystick_lisp->get("axis_x", joyaxis_x);
198     joystick_lisp->get("axis_y", joyaxis_y);
199     joystick_lisp->get("dead_zone_x", dead_zone_x);
200     joystick_lisp->get("dead_zone_y", dead_zone_y);
201     lisp::ListIterator iter(joystick_lisp);
202     while(iter.next()) {
203       if(iter.item() == "map") {
204         int button = -1;
205         std::string control;
206         const lisp::Lisp* map = iter.lisp();
207         map->get("button", button);
208         map->get("control", control);
209         if(button < 0 || button >= max_joybuttons) {
210           log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
211           continue;
212         }
213
214         int i = 0;
215         for(i = 0; controlNames[i] != 0; ++i) {
216           if(control == controlNames[i])
217             break;
218         }
219         if(controlNames[i] == 0) {
220           log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
221           continue;
222         }
223         reset_joybutton(button, (Control) i);
224       }
225     }
226   }
227 }
228
229 void
230 JoystickKeyboardController::write(lisp::Writer& writer)
231 {
232   writer.start_list("keymap");
233   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
234     writer.start_list("map");
235     writer.write_int("key", (int) i->first);
236     writer.write_string("control", controlNames[i->second]);
237     writer.end_list("map");
238   }
239   writer.end_list("keymap");
240   writer.start_list("joystick");
241   writer.write_bool("use_hat", use_hat);
242   writer.write_int("axis_x", joyaxis_x);
243   writer.write_int("axis_y", joyaxis_y);
244   writer.write_int("dead_zone_x", dead_zone_x);
245   writer.write_int("dead_zone_y", dead_zone_y);
246   for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
247       ++i) {
248     writer.start_list("map");
249     writer.write_int("button", i->first);
250     writer.write_string("control", controlNames[i->second]);
251     writer.end_list("map");
252   }
253   writer.end_list("joystick");
254 }
255
256 void
257 JoystickKeyboardController::reset()
258 {
259   Controller::reset();
260 }
261
262 void
263 JoystickKeyboardController::process_event(const SDL_Event& event)
264 {
265   switch(event.type) {
266     case SDL_KEYUP:
267     case SDL_KEYDOWN:
268       process_key_event(event);
269       break;
270
271     case SDL_JOYAXISMOTION:
272       if(event.jaxis.axis == joyaxis_x) {
273         if(event.jaxis.value < -dead_zone_x) {
274           controls[LEFT] = true;
275           controls[RIGHT] = false;
276         } else if(event.jaxis.value > dead_zone_x) {
277           controls[LEFT] = false;
278           controls[RIGHT] = true;
279         } else {
280           controls[LEFT] = false;
281           controls[RIGHT] = false;
282         }
283       } else if(event.jaxis.axis == joyaxis_y) {
284         if(event.jaxis.value < -dead_zone_y) {
285           controls[UP] = true;
286           controls[DOWN] = false;
287         } else if(event.jaxis.value > dead_zone_y) {
288           controls[UP] = false;
289           controls[DOWN] = true;
290         } else {
291           controls[UP] = false;
292           controls[DOWN] = false;
293         }
294       }
295       break;
296
297     case SDL_JOYHATMOTION:
298       if(!use_hat)
299         break;
300
301       if(event.jhat.value & SDL_HAT_UP) {
302         controls[UP] = true;
303         controls[DOWN] = false;
304       }
305       if(event.jhat.value & SDL_HAT_DOWN) {
306         controls[UP] = false;
307         controls[DOWN] = true;
308       }
309       if(event.jhat.value & SDL_HAT_LEFT) {
310         controls[LEFT] = true;
311         controls[RIGHT] = false;
312       }
313       if(event.jhat.value & SDL_HAT_RIGHT) {
314         controls[LEFT] = false;
315         controls[RIGHT] = true;
316       }
317       if(event.jhat.value == SDL_HAT_CENTERED) {
318         controls[UP] = false;
319         controls[DOWN] = false;
320         controls[LEFT] = false;
321         controls[RIGHT] = false;
322       }
323       break;
324
325     case SDL_JOYBUTTONDOWN:
326     case SDL_JOYBUTTONUP:
327     {
328       if(wait_for_joybutton >= 0) {
329         if(event.type == SDL_JOYBUTTONUP)
330           return;
331
332         Control c = (Control) wait_for_joybutton;
333         reset_joybutton(event.jbutton.button, c);
334         reset();
335         joystick_options_menu->update();
336         wait_for_joybutton = -1;
337         return;
338       }
339
340       ButtonMap::iterator i = joy_button_map.find(event.jbutton.button);
341       if(i == joy_button_map.end()) {
342         log_debug << "Unmapped joybutton " << (int)event.jbutton.button << " pressed" << std::endl;
343         return;
344       }
345
346       controls[i->second] = (event.type == SDL_JOYBUTTONDOWN);
347       break;
348     }
349
350     default:
351       break;
352   }
353 }
354
355 void
356 JoystickKeyboardController::process_key_event(const SDL_Event& event)
357 {
358   KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
359
360   // if console key was pressed: toggle console
361   if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
362     if (event.type != SDL_KEYDOWN) return;
363     Console::instance->toggle();
364     return;
365   }
366
367   // if console is open: send key there
368   if (Console::instance->hasFocus()) {
369     process_console_key_event(event);
370     return;
371   }
372
373   // if menu mode: send key there
374   if (Menu::current()) {
375     process_menu_key_event(event);
376     return;
377   }
378
379   // default action: update controls
380   if(key_mapping == keymap.end()) {
381     log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
382     return;
383   }
384   Control control = key_mapping->second;
385   controls[control] = (event.type == SDL_KEYDOWN);
386 }
387
388 void
389 JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
390 {
391   if (event.type != SDL_KEYDOWN) return;
392
393   switch (event.key.keysym.sym) {
394     case SDLK_RETURN:
395       Console::instance->enter();
396       break;
397     case SDLK_BACKSPACE:
398       Console::instance->backspace();
399       break;
400     case SDLK_TAB:
401       Console::instance->autocomplete();
402       break;
403     case SDLK_PAGEUP:
404       Console::instance->scroll(-1);
405       break;
406     case SDLK_PAGEDOWN:
407       Console::instance->scroll(+1);
408       break;
409     case SDLK_HOME:
410       Console::instance->move_cursor(-65535);
411       break;
412     case SDLK_END:
413       Console::instance->move_cursor(+65535);
414       break;
415     case SDLK_UP:
416       Console::instance->show_history(-1);
417       break;
418     case SDLK_DOWN:
419       Console::instance->show_history(+1);
420       break;
421     case SDLK_LEFT:
422       Console::instance->move_cursor(-1);
423       break;
424     case SDLK_RIGHT:
425       Console::instance->move_cursor(+1);
426       break;
427     default:
428       int c = event.key.keysym.unicode;
429       if ((c >= 32) && (c <= 126)) {
430         Console::instance->input((char)c);
431       }
432       break;
433   }
434 }
435
436 void
437 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
438 {
439   // wait for key mode?
440   if(wait_for_key >= 0) {
441     if(event.type == SDL_KEYUP)
442       return;
443
444     if(event.key.keysym.sym != SDLK_ESCAPE
445         && event.key.keysym.sym != SDLK_PAUSE) {
446       reset_key(event.key.keysym.sym, (Control) wait_for_key);
447     }
448     reset();
449     key_options_menu->update();
450     wait_for_key = -1;
451     return;
452   }
453   if(wait_for_joybutton >= 0) {
454     if(event.key.keysym.sym == SDLK_ESCAPE) {
455       reset();
456       joystick_options_menu->update();
457       wait_for_joybutton = -1;
458     }
459     return;
460   }
461
462   Control control;
463   /* we use default keys when the menu is open (to avoid problems when
464    * redefining keys to invalid settings
465    */
466   switch(event.key.keysym.sym) {
467     case SDLK_UP:
468       control = UP;
469       break;
470     case SDLK_DOWN:
471       control = DOWN;
472       break;
473     case SDLK_LEFT:
474       control = LEFT;
475       break;
476     case SDLK_RIGHT:
477       control = RIGHT;
478       break;
479     case SDLK_SPACE:
480     case SDLK_RETURN:
481     case SDLK_KP_ENTER:
482       control = MENU_SELECT;
483       break;
484     case SDLK_ESCAPE:
485     case SDLK_PAUSE:
486       control = PAUSE_MENU;
487       break;
488     default:
489       return;
490       break;
491   }
492
493   controls[control] = (event.type == SDL_KEYDOWN);
494 }
495
496 void
497 JoystickKeyboardController::reset_joybutton(int button, Control control)
498 {
499   // remove all previous mappings for that control and for that key
500   for(ButtonMap::iterator i = joy_button_map.begin();
501       i != joy_button_map.end(); /* no ++i */) {
502     if(i->second == control) {
503       ButtonMap::iterator e = i;
504       ++i;
505       joy_button_map.erase(e);
506     } else {
507       ++i;
508     }
509   }
510   ButtonMap::iterator i = joy_button_map.find(button);
511   if(i != joy_button_map.end())
512     joy_button_map.erase(i);
513
514   // add new mapping
515   joy_button_map.insert(std::make_pair(button, control));
516
517   // map all unused buttons to MENU_SELECT
518   for(int b = 0; b < max_joybuttons; ++b) {
519     ButtonMap::iterator i = joy_button_map.find(b);
520     if(i != joy_button_map.end())
521       continue;
522
523     joy_button_map.insert(std::make_pair(b, MENU_SELECT));
524   }
525 }
526
527 void
528 JoystickKeyboardController::reset_key(SDLKey key, Control control)
529 {
530   // remove all previous mappings for that control and for that key
531   for(KeyMap::iterator i = keymap.begin();
532       i != keymap.end(); /* no ++i */) {
533     if(i->second == control) {
534       KeyMap::iterator e = i;
535       ++i;
536       keymap.erase(e);
537     } else {
538       ++i;
539     }
540   }
541   KeyMap::iterator i = keymap.find(key);
542   if(i != keymap.end())
543     keymap.erase(i);
544
545   // add new mapping
546   keymap.insert(std::make_pair(key, control));
547 }
548
549 SDLKey
550 JoystickKeyboardController::reversemap_key(Control c)
551 {
552   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
553     if(i->second == c)
554       return i->first;
555   }
556
557   return SDLK_UNKNOWN;
558 }
559
560 int
561 JoystickKeyboardController::reversemap_joybutton(Control c)
562 {
563   for(ButtonMap::iterator i = joy_button_map.begin();
564       i != joy_button_map.end(); ++i) {
565     if(i->second == c)
566       return i->first;
567   }
568
569   return -1;
570 }
571
572 Menu*
573 JoystickKeyboardController::get_key_options_menu()
574 {
575   if(key_options_menu == 0) {
576     key_options_menu = new KeyboardMenu(this);
577   }
578
579   return key_options_menu;
580 }
581
582 Menu*
583 JoystickKeyboardController::get_joystick_options_menu()
584 {
585   if(joystick_options_menu == 0) {
586     joystick_options_menu = new JoystickMenu(this);
587   }
588
589   return joystick_options_menu;
590 }
591
592 //----------------------------------------------------------------------------
593
594 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
595     JoystickKeyboardController* _controller)
596   : controller(_controller)
597 {
598     add_label(_("Setup Keyboard"));
599     add_hl();
600     add_controlfield(Controller::UP, _("Up"));
601     add_controlfield(Controller::DOWN, _("Down"));
602     add_controlfield(Controller::LEFT, _("Left"));
603     add_controlfield(Controller::RIGHT, _("Right"));
604     add_controlfield(Controller::JUMP, _("Jump"));
605     add_controlfield(Controller::ACTION, _("Action"));
606     add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
607     add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
608     if (config->console_enabled) {
609       add_controlfield(Controller::CONSOLE, _("Console"));
610     }
611     add_hl();
612     add_back(_("Back"));
613     update();
614 }
615
616 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
617 {}
618
619 std::string
620 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
621 {
622   switch(key) {
623     case SDLK_UNKNOWN:
624       return _("None");
625     case SDLK_UP:
626       return _("Up cursor");
627     case SDLK_DOWN:
628       return _("Down cursor");
629     case SDLK_LEFT:
630       return _("Left cursor");
631     case SDLK_RIGHT:
632       return _("Right cursor");
633     case SDLK_RETURN:
634       return _("Return");
635     case SDLK_SPACE:
636       return _("Space");
637     case SDLK_RSHIFT:
638       return _("Right Shift");
639     case SDLK_LSHIFT:
640       return _("Left Shift");
641     case SDLK_RCTRL:
642       return _("Right Control");
643     case SDLK_LCTRL:
644       return _("Left Control");
645     case SDLK_RALT:
646       return _("Right Alt");
647     case SDLK_LALT:
648       return _("Left Alt");
649     default:
650       return SDL_GetKeyName((SDLKey) key);
651   }
652 }
653
654 void
655 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
656 {
657   assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
658   item->change_input(_("Press Key"));
659   controller->wait_for_key = item->id;
660 }
661
662 void
663 JoystickKeyboardController::KeyboardMenu::update()
664 {
665   // update menu
666   get_item_by_id((int) Controller::UP).change_input(get_key_name(
667     controller->reversemap_key(Controller::UP)));
668   get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
669     controller->reversemap_key(Controller::DOWN)));
670   get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
671     controller->reversemap_key(Controller::LEFT)));
672   get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
673     controller->reversemap_key(Controller::RIGHT)));
674   get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
675     controller->reversemap_key(Controller::JUMP)));
676   get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
677     controller->reversemap_key(Controller::ACTION)));
678   get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
679     controller->reversemap_key(Controller::PEEK_LEFT)));
680   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
681     controller->reversemap_key(Controller::PEEK_RIGHT)));
682   if (config->console_enabled) {
683     get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
684       controller->reversemap_key(Controller::CONSOLE)));
685   }
686 }
687
688 //---------------------------------------------------------------------------
689
690 JoystickKeyboardController::JoystickMenu::JoystickMenu(
691   JoystickKeyboardController* _controller)
692   : controller(_controller)
693 {
694   add_label(_("Setup Joystick"));
695   add_hl();
696   if(controller->joysticks.size() > 0) {
697     add_controlfield(Controller::JUMP, _("Jump"));
698     add_controlfield(Controller::ACTION, _("Action"));
699     add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
700     add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
701     add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
702   } else {
703     add_deactive(-1, _("No Joysticks found"));
704   }
705   add_hl();
706   add_back(_("Back"));
707   update();
708 }
709
710 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
711 {}
712
713 std::string
714 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
715 {
716   if(button < 0)
717     return _("None");
718
719   std::ostringstream name;
720   name << "Button " << button;
721   return name.str();
722 }
723
724 void
725 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
726 {
727   assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
728   item->change_input(_("Press Button"));
729   controller->wait_for_joybutton = item->id;
730 }
731
732 void
733 JoystickKeyboardController::JoystickMenu::update()
734 {
735   if(controller->joysticks.size() == 0)
736     return;
737
738   // update menu
739   get_item_by_id((int) Controller::JUMP).change_input(get_button_name(
740     controller->reversemap_joybutton(Controller::JUMP)));
741   get_item_by_id((int) Controller::ACTION).change_input(get_button_name(
742     controller->reversemap_joybutton(Controller::ACTION)));
743   get_item_by_id((int) Controller::PAUSE_MENU).change_input(get_button_name(
744     controller->reversemap_joybutton(Controller::PAUSE_MENU)));
745   get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_button_name(
746     controller->reversemap_joybutton(Controller::PEEK_LEFT)));
747   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_button_name(
748     controller->reversemap_joybutton(Controller::PEEK_RIGHT)));
749 }