Merged back changes from 0.3.x branch
[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->input << std::endl;
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_END:
410       Console::instance->scroll(+65535);
411       break;
412     case SDLK_UP:
413       Console::instance->show_history(-1);
414       break;
415     case SDLK_DOWN:
416       Console::instance->show_history(+1);
417       break;
418     default:
419       int c = event.key.keysym.unicode;
420       if ((c >= 32) && (c <= 126)) {
421         Console::instance->input << (char)c;
422       }
423       break;
424   }
425 }
426
427 void
428 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
429 {
430   // wait for key mode?
431   if(wait_for_key >= 0) {
432     if(event.type == SDL_KEYUP)
433       return;
434
435     if(event.key.keysym.sym != SDLK_ESCAPE
436         && event.key.keysym.sym != SDLK_PAUSE) {
437       reset_key(event.key.keysym.sym, (Control) wait_for_key);
438     }
439     reset();
440     key_options_menu->update();
441     wait_for_key = -1;
442     return;
443   }
444   if(wait_for_joybutton >= 0) {
445     if(event.key.keysym.sym == SDLK_ESCAPE) {
446       reset();
447       joystick_options_menu->update();
448       wait_for_joybutton = -1;
449     }
450     return;
451   }
452
453   Control control;
454   /* we use default keys when the menu is open (to avoid problems when
455    * redefining keys to invalid settings
456    */
457   switch(event.key.keysym.sym) {
458     case SDLK_UP:
459       control = UP;
460       break;
461     case SDLK_DOWN:
462       control = DOWN;
463       break;
464     case SDLK_LEFT:
465       control = LEFT;
466       break;
467     case SDLK_RIGHT:
468       control = RIGHT;
469       break;
470     case SDLK_SPACE:
471     case SDLK_RETURN:
472     case SDLK_KP_ENTER:
473       control = MENU_SELECT;
474       break;
475     case SDLK_ESCAPE:
476     case SDLK_PAUSE:
477       control = PAUSE_MENU;
478       break;
479     default:
480       return;
481       break;
482   }
483
484   controls[control] = (event.type == SDL_KEYDOWN);
485 }
486
487 void
488 JoystickKeyboardController::reset_joybutton(int button, Control control)
489 {
490   // remove all previous mappings for that control and for that key
491   for(ButtonMap::iterator i = joy_button_map.begin();
492       i != joy_button_map.end(); /* no ++i */) {
493     if(i->second == control) {
494       ButtonMap::iterator e = i;
495       ++i;
496       joy_button_map.erase(e);
497     } else {
498       ++i;
499     }
500   }
501   ButtonMap::iterator i = joy_button_map.find(button);
502   if(i != joy_button_map.end())
503     joy_button_map.erase(i);
504
505   // add new mapping
506   joy_button_map.insert(std::make_pair(button, control));
507
508   // map all unused buttons to MENU_SELECT
509   for(int b = 0; b < max_joybuttons; ++b) {
510     ButtonMap::iterator i = joy_button_map.find(b);
511     if(i != joy_button_map.end())
512       continue;
513
514     joy_button_map.insert(std::make_pair(b, MENU_SELECT));
515   }
516 }
517
518 void
519 JoystickKeyboardController::reset_key(SDLKey key, Control control)
520 {
521   // remove all previous mappings for that control and for that key
522   for(KeyMap::iterator i = keymap.begin();
523       i != keymap.end(); /* no ++i */) {
524     if(i->second == control) {
525       KeyMap::iterator e = i;
526       ++i;
527       keymap.erase(e);
528     } else {
529       ++i;
530     }
531   }
532   KeyMap::iterator i = keymap.find(key);
533   if(i != keymap.end())
534     keymap.erase(i);
535
536   // add new mapping
537   keymap.insert(std::make_pair(key, control));
538 }
539
540 SDLKey
541 JoystickKeyboardController::reversemap_key(Control c)
542 {
543   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
544     if(i->second == c)
545       return i->first;
546   }
547
548   return SDLK_UNKNOWN;
549 }
550
551 int
552 JoystickKeyboardController::reversemap_joybutton(Control c)
553 {
554   for(ButtonMap::iterator i = joy_button_map.begin();
555       i != joy_button_map.end(); ++i) {
556     if(i->second == c)
557       return i->first;
558   }
559
560   return -1;
561 }
562
563 Menu*
564 JoystickKeyboardController::get_key_options_menu()
565 {
566   if(key_options_menu == 0) {
567     key_options_menu = new KeyboardMenu(this);
568   }
569
570   return key_options_menu;
571 }
572
573 Menu*
574 JoystickKeyboardController::get_joystick_options_menu()
575 {
576   if(joystick_options_menu == 0) {
577     joystick_options_menu = new JoystickMenu(this);
578   }
579
580   return joystick_options_menu;
581 }
582
583 //----------------------------------------------------------------------------
584
585 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
586     JoystickKeyboardController* _controller)
587   : controller(_controller)
588 {
589     add_label(_("Setup Keyboard"));
590     add_hl();
591     add_controlfield(Controller::UP, _("Up"));
592     add_controlfield(Controller::DOWN, _("Down"));
593     add_controlfield(Controller::LEFT, _("Left"));
594     add_controlfield(Controller::RIGHT, _("Right"));
595     add_controlfield(Controller::JUMP, _("Jump"));
596     add_controlfield(Controller::ACTION, _("Action"));
597     add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
598     add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
599     if (config->console_enabled) {
600       add_controlfield(Controller::CONSOLE, _("Console"));
601     }
602     add_hl();
603     add_back(_("Back"));
604     update();
605 }
606
607 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
608 {}
609
610 std::string
611 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
612 {
613   switch(key) {
614     case SDLK_UNKNOWN:
615       return _("None");
616     case SDLK_UP:
617       return _("Up cursor");
618     case SDLK_DOWN:
619       return _("Down cursor");
620     case SDLK_LEFT:
621       return _("Left cursor");
622     case SDLK_RIGHT:
623       return _("Right cursor");
624     case SDLK_RETURN:
625       return _("Return");
626     case SDLK_SPACE:
627       return _("Space");
628     case SDLK_RSHIFT:
629       return _("Right Shift");
630     case SDLK_LSHIFT:
631       return _("Left Shift");
632     case SDLK_RCTRL:
633       return _("Right Control");
634     case SDLK_LCTRL:
635       return _("Left Control");
636     case SDLK_RALT:
637       return _("Right Alt");
638     case SDLK_LALT:
639       return _("Left Alt");
640     default:
641       return SDL_GetKeyName((SDLKey) key);
642   }
643 }
644
645 void
646 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
647 {
648   assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
649   item->change_input(_("Press Key"));
650   controller->wait_for_key = item->id;
651 }
652
653 void
654 JoystickKeyboardController::KeyboardMenu::update()
655 {
656   // update menu
657   get_item_by_id((int) Controller::UP).change_input(get_key_name(
658     controller->reversemap_key(Controller::UP)));
659   get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
660     controller->reversemap_key(Controller::DOWN)));
661   get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
662     controller->reversemap_key(Controller::LEFT)));
663   get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
664     controller->reversemap_key(Controller::RIGHT)));
665   get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
666     controller->reversemap_key(Controller::JUMP)));
667   get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
668     controller->reversemap_key(Controller::ACTION)));
669   get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
670     controller->reversemap_key(Controller::PEEK_LEFT)));
671   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
672     controller->reversemap_key(Controller::PEEK_RIGHT)));
673   if (config->console_enabled) {
674     get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
675       controller->reversemap_key(Controller::CONSOLE)));
676   }
677 }
678
679 //---------------------------------------------------------------------------
680
681 JoystickKeyboardController::JoystickMenu::JoystickMenu(
682   JoystickKeyboardController* _controller)
683   : controller(_controller)
684 {
685   add_label(_("Setup Joystick"));
686   add_hl();
687   if(controller->joysticks.size() > 0) {
688     add_controlfield(Controller::JUMP, _("Jump"));
689     add_controlfield(Controller::ACTION, _("Action"));
690     add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
691     add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
692     add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
693   } else {
694     add_deactive(-1, _("No Joysticks found"));
695   }
696   add_hl();
697   add_back(_("Back"));
698   update();
699 }
700
701 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
702 {}
703
704 std::string
705 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
706 {
707   if(button < 0)
708     return _("None");
709
710   std::ostringstream name;
711   name << "Button " << button;
712   return name.str();
713 }
714
715 void
716 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
717 {
718   assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
719   item->change_input(_("Press Button"));
720   controller->wait_for_joybutton = item->id;
721 }
722
723 void
724 JoystickKeyboardController::JoystickMenu::update()
725 {
726   if(controller->joysticks.size() == 0)
727     return;
728
729   // update menu
730   get_item_by_id((int) Controller::JUMP).change_input(get_button_name(
731     controller->reversemap_joybutton(Controller::JUMP)));
732   get_item_by_id((int) Controller::ACTION).change_input(get_button_name(
733     controller->reversemap_joybutton(Controller::ACTION)));
734   get_item_by_id((int) Controller::PAUSE_MENU).change_input(get_button_name(
735     controller->reversemap_joybutton(Controller::PAUSE_MENU)));
736   get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_button_name(
737     controller->reversemap_joybutton(Controller::PEEK_LEFT)));
738   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_button_name(
739     controller->reversemap_joybutton(Controller::PEEK_RIGHT)));
740 }