2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
3 // 2007 Ingo Ruhnke <grumbel@gmx.de>
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "control/joystickkeyboardcontroller.hpp"
22 #include "gui/menu.hpp"
23 #include "util/writer.hpp"
24 #include "lisp/list_iterator.hpp"
25 #include "supertux/gameconfig.hpp"
26 #include "supertux/console.hpp"
27 #include "util/gettext.hpp"
30 const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
33 class JoystickKeyboardController::JoystickMenu : public Menu
36 JoystickMenu(JoystickKeyboardController* controller);
37 virtual ~JoystickMenu();
40 std::string get_button_name(int button);
41 void update_menu_item(Control id);
42 virtual void menu_action(MenuItem* item);
43 JoystickKeyboardController* controller;
48 class JoystickKeyboardController::KeyboardMenu : public Menu
51 KeyboardMenu(JoystickKeyboardController* controller);
55 std::string get_key_name(SDLKey key);
56 virtual void menu_action(MenuItem* item);
57 JoystickKeyboardController* controller;
60 JoystickKeyboardController::JoystickKeyboardController() :
63 wait_for_joystick(-1),
65 joystick_options_menu(0)
67 // initialize default keyboard map
68 keymap[SDLK_LEFT] = LEFT;
69 keymap[SDLK_RIGHT] = RIGHT;
71 keymap[SDLK_DOWN] = DOWN;
72 keymap[SDLK_SPACE] = JUMP;
73 keymap[SDLK_LCTRL] = ACTION;
74 keymap[SDLK_LALT] = ACTION;
75 keymap[SDLK_ESCAPE] = PAUSE_MENU;
76 keymap[SDLK_p] = PAUSE_MENU;
77 keymap[SDLK_PAUSE] = PAUSE_MENU;
78 keymap[SDLK_RETURN] = MENU_SELECT;
79 keymap[SDLK_KP_ENTER] = MENU_SELECT;
80 keymap[SDLK_CARET] = CONSOLE;
81 keymap[SDLK_DELETE] = PEEK_LEFT;
82 keymap[SDLK_PAGEDOWN] = PEEK_RIGHT;
83 keymap[SDLK_HOME] = PEEK_UP;
84 keymap[SDLK_END] = PEEK_DOWN;
86 jump_with_up_joy = false;
87 jump_with_up_kbd = false;
89 updateAvailableJoysticks();
93 // Default joystick button configuration
94 joy_button_map[0] = JUMP;
95 joy_button_map[1] = ACTION;
97 if( min_joybuttons > 5 ){
98 joy_button_map[4] = PEEK_LEFT;
99 joy_button_map[5] = PEEK_RIGHT;
101 if(min_joybuttons > 7)
102 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
104 // map the last 2 buttons to menu and pause
105 if(min_joybuttons > 2)
106 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
107 // map all remaining joystick buttons to MENU_SELECT
108 for(int i = 2; i < max_joybuttons; ++i) {
109 if(i != min_joybuttons-1)
110 joy_button_map[i] = MENU_SELECT;
114 // Default joystick axis configuration
115 joy_axis_map[-1] = LEFT;
116 joy_axis_map[ 1] = RIGHT;
117 joy_axis_map[-2] = UP;
118 joy_axis_map[ 2] = DOWN;
121 JoystickKeyboardController::~JoystickKeyboardController()
123 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
124 i != joysticks.end(); ++i) {
126 SDL_JoystickClose(*i);
129 delete key_options_menu;
130 delete joystick_options_menu;
134 JoystickKeyboardController::updateAvailableJoysticks()
136 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
137 i != joysticks.end(); ++i) {
139 SDL_JoystickClose(*i);
143 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
144 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
146 int joystick_count = SDL_NumJoysticks();
152 if( joystick_count > 0 ){
153 for(int i = 0; i < joystick_count; ++i) {
154 SDL_Joystick* joystick = SDL_JoystickOpen(i);
156 if(SDL_JoystickNumButtons(joystick) < 2) {
157 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 buttons" << std::endl;
160 if(SDL_JoystickNumAxes(joystick) < 2
161 && SDL_JoystickNumHats(joystick) == 0) {
162 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 axes and no hat" << std::endl;
166 SDL_JoystickClose(joystick);
170 if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
171 min_joybuttons = SDL_JoystickNumButtons(joystick);
173 if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
174 max_joybuttons = SDL_JoystickNumButtons(joystick);
176 if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
177 max_joyaxis = SDL_JoystickNumAxes(joystick);
179 if(SDL_JoystickNumHats(joystick) > max_joyhats)
180 max_joyhats = SDL_JoystickNumHats(joystick);
182 joysticks.push_back(joystick);
186 // some joysticks or SDL seem to produce some bogus events after being opened
187 Uint32 ticks = SDL_GetTicks();
188 while(SDL_GetTicks() - ticks < 200) {
190 SDL_PollEvent(&event);
195 JoystickKeyboardController::read(const Reader& lisp)
197 const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
200 keymap_lisp->get("jump-with-up", jump_with_up_kbd);
201 lisp::ListIterator iter(keymap_lisp);
203 if(iter.item() == "map") {
206 const lisp::Lisp* map = iter.lisp();
207 map->get("key", key);
208 map->get("control", control);
209 if(key < SDLK_FIRST || key >= SDLK_LAST) {
210 log_info << "Invalid key '" << key << "' in keymap" << std::endl;
215 for(i = 0; controlNames[i] != 0; ++i) {
216 if(control == controlNames[i])
219 if(controlNames[i] == 0) {
220 log_info << "Invalid control '" << control << "' in keymap" << std::endl;
223 keymap[(SDLKey) key] = (Control)i;
228 const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
230 joystick_lisp->get("dead-zone", dead_zone);
231 joystick_lisp->get("jump-with-up", jump_with_up_joy);
232 lisp::ListIterator iter(joystick_lisp);
234 if(iter.item() == "map") {
239 const lisp::Lisp* map = iter.lisp();
241 map->get("control", control);
243 for(i = 0; controlNames[i] != 0; ++i) {
244 if(control == controlNames[i])
247 if(controlNames[i] == 0) {
248 log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
252 if (map->get("button", button)) {
253 if(button < 0 || button >= max_joybuttons) {
254 log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
257 bind_joybutton(button, (Control) i);
260 if (map->get("axis", axis)) {
261 if (axis == 0 || abs(axis) > max_joyaxis) {
262 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
265 bind_joyaxis(axis, (Control) i);
268 if (map->get("hat", hat)) {
269 if (hat != SDL_HAT_UP &&
270 hat != SDL_HAT_DOWN &&
271 hat != SDL_HAT_LEFT &&
272 hat != SDL_HAT_RIGHT) {
273 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
276 bind_joyhat(hat, (Control) i);
285 JoystickKeyboardController::write(Writer& writer)
287 writer.start_list("keymap");
288 writer.write("jump-with-up", jump_with_up_kbd);
289 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
290 writer.start_list("map");
291 writer.write("key", (int) i->first);
292 writer.write("control", controlNames[i->second]);
293 writer.end_list("map");
295 writer.end_list("keymap");
297 writer.start_list("joystick");
298 writer.write("dead-zone", dead_zone);
299 writer.write("jump-with-up", jump_with_up_joy);
301 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
303 writer.start_list("map");
304 writer.write("button", i->first);
305 writer.write("control", controlNames[i->second]);
306 writer.end_list("map");
309 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
310 writer.start_list("map");
311 writer.write("hat", i->first);
312 writer.write("control", controlNames[i->second]);
313 writer.end_list("map");
316 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
317 writer.start_list("map");
318 writer.write("axis", i->first);
319 writer.write("control", controlNames[i->second]);
320 writer.end_list("map");
323 writer.end_list("joystick");
327 JoystickKeyboardController::reset()
333 JoystickKeyboardController::set_joy_controls(Control id, bool value)
335 if (jump_with_up_joy && id == Controller::UP)
336 controls[Controller::JUMP] = value;
338 controls[(Control)id] = value;
342 JoystickKeyboardController::process_event(const SDL_Event& event)
347 process_key_event(event);
350 case SDL_JOYAXISMOTION:
351 process_axis_event(event.jaxis);
354 case SDL_JOYHATMOTION:
355 process_hat_event(event.jhat);
358 case SDL_JOYBUTTONDOWN:
359 case SDL_JOYBUTTONUP:
360 process_button_event(event.jbutton);
369 JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
371 if(wait_for_joystick >= 0)
373 if(jbutton.state == SDL_PRESSED)
375 bind_joybutton(jbutton.button, (Control)wait_for_joystick);
376 joystick_options_menu->update();
378 wait_for_joystick = -1;
383 ButtonMap::iterator i = joy_button_map.find(jbutton.button);
384 if(i == joy_button_map.end()) {
385 log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
387 set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
393 JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
395 if (wait_for_joystick >= 0)
397 if (abs(jaxis.value) > dead_zone) {
399 bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
401 bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
403 joystick_options_menu->update();
404 wait_for_joystick = -1;
409 // Split the axis into left and right, so that both can be
410 // mapped separately (needed for jump/down vs up/down)
411 int axis = jaxis.axis + 1;
413 AxisMap::iterator left = joy_axis_map.find(-axis);
414 AxisMap::iterator right = joy_axis_map.find(axis);
416 if(left == joy_axis_map.end()) {
417 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
419 if (jaxis.value < -dead_zone)
420 set_joy_controls(left->second, true);
421 else if (jaxis.value > dead_zone)
422 set_joy_controls(left->second, false);
424 set_joy_controls(left->second, false);
427 if(right == joy_axis_map.end()) {
428 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
430 if (jaxis.value < -dead_zone)
431 set_joy_controls(right->second, false);
432 else if (jaxis.value > dead_zone)
433 set_joy_controls(right->second, true);
435 set_joy_controls(right->second, false);
441 JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
443 Uint8 changed = hat_state ^ jhat.value;
445 if (wait_for_joystick >= 0)
447 if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
448 bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
450 if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
451 bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
453 if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
454 bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
456 if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
457 bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
459 joystick_options_menu->update();
460 wait_for_joystick = -1;
464 if (changed & SDL_HAT_UP)
466 HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
467 if (it != joy_hat_map.end())
468 set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
471 if (changed & SDL_HAT_DOWN)
473 HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
474 if (it != joy_hat_map.end())
475 set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
478 if (changed & SDL_HAT_LEFT)
480 HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
481 if (it != joy_hat_map.end())
482 set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
485 if (changed & SDL_HAT_RIGHT)
487 HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
488 if (it != joy_hat_map.end())
489 set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
493 hat_state = jhat.value;
497 JoystickKeyboardController::process_key_event(const SDL_Event& event)
499 KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
501 // if console key was pressed: toggle console
502 if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
503 if (event.type == SDL_KEYDOWN)
504 Console::instance->toggle();
506 if (Console::instance->hasFocus()) {
507 // if console is open: send key there
508 process_console_key_event(event);
509 } else if (Menu::current()) {
510 // if menu mode: send key there
511 process_menu_key_event(event);
512 } else if(key_mapping == keymap.end()) {
513 // default action: update controls
514 //log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
516 Control control = key_mapping->second;
517 controls[control] = (event.type == SDL_KEYDOWN);
518 if (jump_with_up_kbd && control == UP){
519 controls[JUMP] = (event.type == SDL_KEYDOWN);
526 JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
528 if (event.type != SDL_KEYDOWN) return;
530 switch (event.key.keysym.sym) {
532 Console::instance->enter();
535 Console::instance->backspace();
538 Console::instance->autocomplete();
541 Console::instance->scroll(-1);
544 Console::instance->scroll(+1);
547 Console::instance->move_cursor(-65535);
550 Console::instance->move_cursor(+65535);
553 Console::instance->show_history(-1);
556 Console::instance->show_history(+1);
559 Console::instance->move_cursor(-1);
562 Console::instance->move_cursor(+1);
565 int c = event.key.keysym.unicode;
566 if ((c >= 32) && (c <= 126)) {
567 Console::instance->input((char)c);
574 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
576 // wait for key mode?
577 if(wait_for_key >= 0) {
578 if(event.type == SDL_KEYUP)
581 if(event.key.keysym.sym != SDLK_ESCAPE
582 && event.key.keysym.sym != SDLK_PAUSE) {
583 bind_key(event.key.keysym.sym, (Control) wait_for_key);
586 key_options_menu->update();
590 if(wait_for_joystick >= 0) {
591 if(event.key.keysym.sym == SDLK_ESCAPE) {
593 joystick_options_menu->update();
594 wait_for_joystick = -1;
600 /* we use default keys when the menu is open (to avoid problems when
601 * redefining keys to invalid settings
603 switch(event.key.keysym.sym) {
619 control = MENU_SELECT;
623 control = PAUSE_MENU;
630 controls[control] = (event.type == SDL_KEYDOWN);
634 JoystickKeyboardController::unbind_joystick_control(Control control)
636 // remove all previous mappings for that control
637 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
638 if(i->second == control)
639 joy_axis_map.erase(i++);
644 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
645 if(i->second == control)
646 joy_button_map.erase(i++);
651 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
652 if(i->second == control)
653 joy_hat_map.erase(i++);
660 JoystickKeyboardController::bind_joyaxis(int axis, Control control)
662 // axis isn't the SDL axis number, but axisnumber + 1 with sign
663 // changed depending on if the positive or negative end is to be
664 // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
667 unbind_joystick_control(control);
670 joy_axis_map[axis] = control;
674 JoystickKeyboardController::bind_joyhat(int dir, Control c)
676 unbind_joystick_control(c);
679 joy_hat_map[dir] = c;
683 JoystickKeyboardController::bind_joybutton(int button, Control control)
685 unbind_joystick_control(control);
688 joy_button_map[button] = control;
692 JoystickKeyboardController::bind_key(SDLKey key, Control control)
694 // remove all previous mappings for that control and for that key
695 for(KeyMap::iterator i = keymap.begin();
696 i != keymap.end(); /* no ++i */) {
697 if(i->second == control) {
698 KeyMap::iterator e = i;
706 KeyMap::iterator i = keymap.find(key);
707 if(i != keymap.end())
711 keymap[key]= control;
715 JoystickKeyboardController::print_joystick_mappings()
717 std::cout << "Joystick Mappings" << std::endl;
718 std::cout << "-----------------" << std::endl;
719 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
720 std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
723 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
724 std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
727 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
728 std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
730 std::cout << std::endl;
734 JoystickKeyboardController::reversemap_key(Control c)
736 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
745 JoystickKeyboardController::reversemap_joyaxis(Control c)
747 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
756 JoystickKeyboardController::reversemap_joybutton(Control c)
758 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
767 JoystickKeyboardController::reversemap_joyhat(Control c)
769 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
778 JoystickKeyboardController::get_key_options_menu()
780 if(key_options_menu == 0) {
781 key_options_menu = new KeyboardMenu(this);
784 return key_options_menu;
788 JoystickKeyboardController::get_joystick_options_menu()
790 if(joystick_options_menu == 0) {
791 joystick_options_menu = new JoystickMenu(this);
794 return joystick_options_menu;
797 //----------------------------------------------------------------------------
799 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
800 JoystickKeyboardController* _controller)
801 : controller(_controller)
803 add_label(_("Setup Keyboard"));
805 add_controlfield(Controller::UP, _("Up"));
806 add_controlfield(Controller::DOWN, _("Down"));
807 add_controlfield(Controller::LEFT, _("Left"));
808 add_controlfield(Controller::RIGHT, _("Right"));
809 add_controlfield(Controller::JUMP, _("Jump"));
810 add_controlfield(Controller::ACTION, _("Action"));
811 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
812 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
813 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
814 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
815 if (g_config->console_enabled) {
816 add_controlfield(Controller::CONSOLE, _("Console"));
818 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
824 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
828 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
834 return _("Up cursor");
836 return _("Down cursor");
838 return _("Left cursor");
840 return _("Right cursor");
846 return _("Right Shift");
848 return _("Left Shift");
850 return _("Right Control");
852 return _("Left Control");
854 return _("Right Alt");
856 return _("Left Alt");
858 return SDL_GetKeyName((SDLKey) key);
863 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
865 if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
866 item->change_input(_("Press Key"));
867 controller->wait_for_key = item->id;
868 } else if( item->id == Controller::CONTROLCOUNT) {
869 controller->jump_with_up_kbd = item->toggled;
874 JoystickKeyboardController::KeyboardMenu::update()
877 get_item_by_id((int) Controller::UP).change_input(get_key_name(
878 controller->reversemap_key(Controller::UP)));
879 get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
880 controller->reversemap_key(Controller::DOWN)));
881 get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
882 controller->reversemap_key(Controller::LEFT)));
883 get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
884 controller->reversemap_key(Controller::RIGHT)));
885 get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
886 controller->reversemap_key(Controller::JUMP)));
887 get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
888 controller->reversemap_key(Controller::ACTION)));
889 get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
890 controller->reversemap_key(Controller::PEEK_LEFT)));
891 get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
892 controller->reversemap_key(Controller::PEEK_RIGHT)));
893 get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
894 controller->reversemap_key(Controller::PEEK_UP)));
895 get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
896 controller->reversemap_key(Controller::PEEK_DOWN)));
897 if (g_config->console_enabled) {
898 get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
899 controller->reversemap_key(Controller::CONSOLE)));
901 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
904 //---------------------------------------------------------------------------
906 JoystickKeyboardController::JoystickMenu::JoystickMenu(
907 JoystickKeyboardController* _controller)
908 : controller(_controller)
913 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
917 JoystickKeyboardController::JoystickMenu::recreateMenu()
920 add_label(_("Setup Joystick"));
922 if(controller->joysticks.size() > 0) {
923 add_controlfield(Controller::UP, _("Up"));
924 add_controlfield(Controller::DOWN, _("Down"));
925 add_controlfield(Controller::LEFT, _("Left"));
926 add_controlfield(Controller::RIGHT, _("Right"));
927 add_controlfield(Controller::JUMP, _("Jump"));
928 add_controlfield(Controller::ACTION, _("Action"));
929 add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
930 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
931 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
932 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
933 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
935 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
937 add_inactive(-1, _("No Joysticks found"));
940 add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
942 //Show Joysticks currently activated:
943 for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
944 i != controller->joysticks.end(); ++i) {
946 add_inactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
955 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
960 std::ostringstream name;
961 name << "Button " << button;
966 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
968 if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
969 item->change_input(_("Press Button"));
970 controller->wait_for_joystick = item->id;
971 } else if (item->id == Controller::CONTROLCOUNT) {
972 controller->jump_with_up_joy = item->toggled;
973 } else if( item->id == SCAN_JOYSTICKS) {
974 controller->updateAvailableJoysticks();
980 JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
982 int button = controller->reversemap_joybutton(id);
983 int axis = controller->reversemap_joyaxis(id);
984 int hat_dir = controller->reversemap_joyhat(id);
987 get_item_by_id((int)id).change_input(get_button_name(button));
988 } else if (axis != 0) {
989 std::ostringstream name;
1000 else if (abs(axis) == 2)
1002 else if (abs(axis) == 2)
1004 else if (abs(axis) == 3)
1009 get_item_by_id((int)id).change_input(name.str());
1010 } else if (hat_dir != -1) {
1032 name = "Unknown hat_dir";
1036 get_item_by_id((int)id).change_input(name);
1038 get_item_by_id((int)id).change_input("None");
1043 JoystickKeyboardController::JoystickMenu::update()
1045 if(controller->joysticks.size() == 0)
1048 update_menu_item(Controller::UP);
1049 update_menu_item(Controller::DOWN);
1050 update_menu_item(Controller::LEFT);
1051 update_menu_item(Controller::RIGHT);
1053 update_menu_item(Controller::JUMP);
1054 update_menu_item(Controller::ACTION);
1055 update_menu_item(Controller::PAUSE_MENU);
1056 update_menu_item(Controller::PEEK_LEFT);
1057 update_menu_item(Controller::PEEK_RIGHT);
1058 update_menu_item(Controller::PEEK_UP);
1059 update_menu_item(Controller::PEEK_DOWN);
1061 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;