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;
49 JoystickMenu(const JoystickMenu&);
50 JoystickMenu& operator=(const JoystickMenu&);
53 class JoystickKeyboardController::KeyboardMenu : public Menu
56 KeyboardMenu(JoystickKeyboardController* controller);
60 std::string get_key_name(SDLKey key);
61 virtual void menu_action(MenuItem* item);
62 JoystickKeyboardController* controller;
65 KeyboardMenu(const KeyboardMenu&);
66 KeyboardMenu& operator=(const KeyboardMenu&);
69 JoystickKeyboardController::JoystickKeyboardController() :
85 wait_for_joystick(-1),
87 joystick_options_menu(0)
89 // initialize default keyboard map
90 keymap[SDLK_LEFT] = LEFT;
91 keymap[SDLK_RIGHT] = RIGHT;
93 keymap[SDLK_DOWN] = DOWN;
94 keymap[SDLK_SPACE] = JUMP;
95 keymap[SDLK_LCTRL] = ACTION;
96 keymap[SDLK_LALT] = ACTION;
97 keymap[SDLK_ESCAPE] = PAUSE_MENU;
98 keymap[SDLK_p] = PAUSE_MENU;
99 keymap[SDLK_PAUSE] = PAUSE_MENU;
100 keymap[SDLK_RETURN] = MENU_SELECT;
101 keymap[SDLK_KP_ENTER] = MENU_SELECT;
102 keymap[SDLK_CARET] = CONSOLE;
103 keymap[SDLK_DELETE] = PEEK_LEFT;
104 keymap[SDLK_PAGEDOWN] = PEEK_RIGHT;
105 keymap[SDLK_HOME] = PEEK_UP;
106 keymap[SDLK_END] = PEEK_DOWN;
108 jump_with_up_joy = false;
109 jump_with_up_kbd = false;
111 updateAvailableJoysticks();
115 // Default joystick button configuration
116 joy_button_map[0] = JUMP;
117 joy_button_map[1] = ACTION;
119 if( min_joybuttons > 5 ){
120 joy_button_map[4] = PEEK_LEFT;
121 joy_button_map[5] = PEEK_RIGHT;
123 if(min_joybuttons > 7)
124 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
126 // map the last 2 buttons to menu and pause
127 if(min_joybuttons > 2)
128 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
129 // map all remaining joystick buttons to MENU_SELECT
130 for(int i = 2; i < max_joybuttons; ++i) {
131 if(i != min_joybuttons-1)
132 joy_button_map[i] = MENU_SELECT;
136 // Default joystick axis configuration
137 joy_axis_map[-1] = LEFT;
138 joy_axis_map[ 1] = RIGHT;
139 joy_axis_map[-2] = UP;
140 joy_axis_map[ 2] = DOWN;
143 JoystickKeyboardController::~JoystickKeyboardController()
145 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
146 i != joysticks.end(); ++i) {
148 SDL_JoystickClose(*i);
151 delete key_options_menu;
152 delete joystick_options_menu;
156 JoystickKeyboardController::updateAvailableJoysticks()
158 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
159 i != joysticks.end(); ++i) {
161 SDL_JoystickClose(*i);
165 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
166 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
168 int joystick_count = SDL_NumJoysticks();
174 if( joystick_count > 0 ){
175 for(int i = 0; i < joystick_count; ++i) {
176 SDL_Joystick* joystick = SDL_JoystickOpen(i);
178 if(SDL_JoystickNumButtons(joystick) < 2) {
179 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 buttons" << std::endl;
182 if(SDL_JoystickNumAxes(joystick) < 2
183 && SDL_JoystickNumHats(joystick) == 0) {
184 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 axes and no hat" << std::endl;
188 SDL_JoystickClose(joystick);
192 if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
193 min_joybuttons = SDL_JoystickNumButtons(joystick);
195 if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
196 max_joybuttons = SDL_JoystickNumButtons(joystick);
198 if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
199 max_joyaxis = SDL_JoystickNumAxes(joystick);
201 if(SDL_JoystickNumHats(joystick) > max_joyhats)
202 max_joyhats = SDL_JoystickNumHats(joystick);
204 joysticks.push_back(joystick);
208 // some joysticks or SDL seem to produce some bogus events after being opened
209 Uint32 ticks = SDL_GetTicks();
210 while(SDL_GetTicks() - ticks < 200) {
212 SDL_PollEvent(&event);
217 JoystickKeyboardController::read(const Reader& lisp)
219 const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
222 keymap_lisp->get("jump-with-up", jump_with_up_kbd);
223 lisp::ListIterator iter(keymap_lisp);
225 if(iter.item() == "map") {
228 const lisp::Lisp* map = iter.lisp();
229 map->get("key", key);
230 map->get("control", control);
231 if(key < SDLK_FIRST || key >= SDLK_LAST) {
232 log_info << "Invalid key '" << key << "' in keymap" << std::endl;
237 for(i = 0; controlNames[i] != 0; ++i) {
238 if(control == controlNames[i])
241 if(controlNames[i] == 0) {
242 log_info << "Invalid control '" << control << "' in keymap" << std::endl;
245 keymap[(SDLKey) key] = (Control)i;
250 const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
252 joystick_lisp->get("dead-zone", dead_zone);
253 joystick_lisp->get("jump-with-up", jump_with_up_joy);
254 lisp::ListIterator iter(joystick_lisp);
256 if(iter.item() == "map") {
261 const lisp::Lisp* map = iter.lisp();
263 map->get("control", control);
265 for(i = 0; controlNames[i] != 0; ++i) {
266 if(control == controlNames[i])
269 if(controlNames[i] == 0) {
270 log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
274 if (map->get("button", button)) {
275 if(button < 0 || button >= max_joybuttons) {
276 log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
279 bind_joybutton(button, (Control) i);
282 if (map->get("axis", axis)) {
283 if (axis == 0 || abs(axis) > max_joyaxis) {
284 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
287 bind_joyaxis(axis, (Control) i);
290 if (map->get("hat", hat)) {
291 if (hat != SDL_HAT_UP &&
292 hat != SDL_HAT_DOWN &&
293 hat != SDL_HAT_LEFT &&
294 hat != SDL_HAT_RIGHT) {
295 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
298 bind_joyhat(hat, (Control) i);
307 JoystickKeyboardController::write(Writer& writer)
309 writer.start_list("keymap");
310 writer.write("jump-with-up", jump_with_up_kbd);
311 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
312 writer.start_list("map");
313 writer.write("key", (int) i->first);
314 writer.write("control", controlNames[i->second]);
315 writer.end_list("map");
317 writer.end_list("keymap");
319 writer.start_list("joystick");
320 writer.write("dead-zone", dead_zone);
321 writer.write("jump-with-up", jump_with_up_joy);
323 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
325 writer.start_list("map");
326 writer.write("button", i->first);
327 writer.write("control", controlNames[i->second]);
328 writer.end_list("map");
331 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
332 writer.start_list("map");
333 writer.write("hat", i->first);
334 writer.write("control", controlNames[i->second]);
335 writer.end_list("map");
338 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
339 writer.start_list("map");
340 writer.write("axis", i->first);
341 writer.write("control", controlNames[i->second]);
342 writer.end_list("map");
345 writer.end_list("joystick");
349 JoystickKeyboardController::reset()
355 JoystickKeyboardController::set_joy_controls(Control id, bool value)
357 if (jump_with_up_joy && id == Controller::UP)
358 controls[Controller::JUMP] = value;
360 controls[(Control)id] = value;
364 JoystickKeyboardController::process_event(const SDL_Event& event)
369 process_key_event(event);
372 case SDL_JOYAXISMOTION:
373 process_axis_event(event.jaxis);
376 case SDL_JOYHATMOTION:
377 process_hat_event(event.jhat);
380 case SDL_JOYBUTTONDOWN:
381 case SDL_JOYBUTTONUP:
382 process_button_event(event.jbutton);
391 JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
393 if(wait_for_joystick >= 0)
395 if(jbutton.state == SDL_PRESSED)
397 bind_joybutton(jbutton.button, (Control)wait_for_joystick);
398 joystick_options_menu->update();
400 wait_for_joystick = -1;
405 ButtonMap::iterator i = joy_button_map.find(jbutton.button);
406 if(i == joy_button_map.end()) {
407 log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
409 set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
415 JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
417 if (wait_for_joystick >= 0)
419 if (abs(jaxis.value) > dead_zone) {
421 bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
423 bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
425 joystick_options_menu->update();
426 wait_for_joystick = -1;
431 // Split the axis into left and right, so that both can be
432 // mapped separately (needed for jump/down vs up/down)
433 int axis = jaxis.axis + 1;
435 AxisMap::iterator left = joy_axis_map.find(-axis);
436 AxisMap::iterator right = joy_axis_map.find(axis);
438 if(left == joy_axis_map.end()) {
439 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
441 if (jaxis.value < -dead_zone)
442 set_joy_controls(left->second, true);
443 else if (jaxis.value > dead_zone)
444 set_joy_controls(left->second, false);
446 set_joy_controls(left->second, false);
449 if(right == joy_axis_map.end()) {
450 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
452 if (jaxis.value < -dead_zone)
453 set_joy_controls(right->second, false);
454 else if (jaxis.value > dead_zone)
455 set_joy_controls(right->second, true);
457 set_joy_controls(right->second, false);
463 JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
465 Uint8 changed = hat_state ^ jhat.value;
467 if (wait_for_joystick >= 0)
469 if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
470 bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
472 if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
473 bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
475 if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
476 bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
478 if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
479 bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
481 joystick_options_menu->update();
482 wait_for_joystick = -1;
486 if (changed & SDL_HAT_UP)
488 HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
489 if (it != joy_hat_map.end())
490 set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
493 if (changed & SDL_HAT_DOWN)
495 HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
496 if (it != joy_hat_map.end())
497 set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
500 if (changed & SDL_HAT_LEFT)
502 HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
503 if (it != joy_hat_map.end())
504 set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
507 if (changed & SDL_HAT_RIGHT)
509 HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
510 if (it != joy_hat_map.end())
511 set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
515 hat_state = jhat.value;
519 JoystickKeyboardController::process_key_event(const SDL_Event& event)
521 KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
523 // if console key was pressed: toggle console
524 if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
525 if (event.type == SDL_KEYDOWN)
526 Console::instance->toggle();
528 if (Console::instance->hasFocus()) {
529 // if console is open: send key there
530 process_console_key_event(event);
531 } else if (Menu::current()) {
532 // if menu mode: send key there
533 process_menu_key_event(event);
534 } else if(key_mapping == keymap.end()) {
535 // default action: update controls
536 //log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
538 Control control = key_mapping->second;
539 controls[control] = (event.type == SDL_KEYDOWN);
540 if (jump_with_up_kbd && control == UP){
541 controls[JUMP] = (event.type == SDL_KEYDOWN);
548 JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
550 if (event.type != SDL_KEYDOWN) return;
552 switch (event.key.keysym.sym) {
554 Console::instance->enter();
557 Console::instance->backspace();
560 Console::instance->autocomplete();
563 Console::instance->scroll(-1);
566 Console::instance->scroll(+1);
569 Console::instance->move_cursor(-65535);
572 Console::instance->move_cursor(+65535);
575 Console::instance->show_history(-1);
578 Console::instance->show_history(+1);
581 Console::instance->move_cursor(-1);
584 Console::instance->move_cursor(+1);
587 int c = event.key.keysym.unicode;
588 if ((c >= 32) && (c <= 126)) {
589 Console::instance->input((char)c);
596 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
598 // wait for key mode?
599 if(wait_for_key >= 0) {
600 if(event.type == SDL_KEYUP)
603 if(event.key.keysym.sym != SDLK_ESCAPE
604 && event.key.keysym.sym != SDLK_PAUSE) {
605 bind_key(event.key.keysym.sym, (Control) wait_for_key);
608 key_options_menu->update();
612 if(wait_for_joystick >= 0) {
613 if(event.key.keysym.sym == SDLK_ESCAPE) {
615 joystick_options_menu->update();
616 wait_for_joystick = -1;
622 /* we use default keys when the menu is open (to avoid problems when
623 * redefining keys to invalid settings
625 switch(event.key.keysym.sym) {
641 control = MENU_SELECT;
645 control = PAUSE_MENU;
652 controls[control] = (event.type == SDL_KEYDOWN);
656 JoystickKeyboardController::unbind_joystick_control(Control control)
658 // remove all previous mappings for that control
659 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
660 if(i->second == control)
661 joy_axis_map.erase(i++);
666 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
667 if(i->second == control)
668 joy_button_map.erase(i++);
673 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
674 if(i->second == control)
675 joy_hat_map.erase(i++);
682 JoystickKeyboardController::bind_joyaxis(int axis, Control control)
684 // axis isn't the SDL axis number, but axisnumber + 1 with sign
685 // changed depending on if the positive or negative end is to be
686 // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
689 unbind_joystick_control(control);
692 joy_axis_map[axis] = control;
696 JoystickKeyboardController::bind_joyhat(int dir, Control c)
698 unbind_joystick_control(c);
701 joy_hat_map[dir] = c;
705 JoystickKeyboardController::bind_joybutton(int button, Control control)
707 unbind_joystick_control(control);
710 joy_button_map[button] = control;
714 JoystickKeyboardController::bind_key(SDLKey key, Control control)
716 // remove all previous mappings for that control and for that key
717 for(KeyMap::iterator i = keymap.begin();
718 i != keymap.end(); /* no ++i */) {
719 if(i->second == control) {
720 KeyMap::iterator e = i;
728 KeyMap::iterator i = keymap.find(key);
729 if(i != keymap.end())
733 keymap[key]= control;
737 JoystickKeyboardController::print_joystick_mappings()
739 std::cout << "Joystick Mappings" << std::endl;
740 std::cout << "-----------------" << std::endl;
741 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
742 std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
745 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
746 std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
749 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
750 std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
752 std::cout << std::endl;
756 JoystickKeyboardController::reversemap_key(Control c)
758 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
767 JoystickKeyboardController::reversemap_joyaxis(Control c)
769 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
778 JoystickKeyboardController::reversemap_joybutton(Control c)
780 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
789 JoystickKeyboardController::reversemap_joyhat(Control c)
791 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
800 JoystickKeyboardController::get_key_options_menu()
802 if(key_options_menu == 0) {
803 key_options_menu = new KeyboardMenu(this);
806 return key_options_menu;
810 JoystickKeyboardController::get_joystick_options_menu()
812 if(joystick_options_menu == 0) {
813 joystick_options_menu = new JoystickMenu(this);
816 return joystick_options_menu;
819 //----------------------------------------------------------------------------
821 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
822 JoystickKeyboardController* _controller)
823 : controller(_controller)
825 add_label(_("Setup Keyboard"));
827 add_controlfield(Controller::UP, _("Up"));
828 add_controlfield(Controller::DOWN, _("Down"));
829 add_controlfield(Controller::LEFT, _("Left"));
830 add_controlfield(Controller::RIGHT, _("Right"));
831 add_controlfield(Controller::JUMP, _("Jump"));
832 add_controlfield(Controller::ACTION, _("Action"));
833 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
834 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
835 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
836 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
837 if (g_config->console_enabled) {
838 add_controlfield(Controller::CONSOLE, _("Console"));
840 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
846 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
850 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
856 return _("Up cursor");
858 return _("Down cursor");
860 return _("Left cursor");
862 return _("Right cursor");
868 return _("Right Shift");
870 return _("Left Shift");
872 return _("Right Control");
874 return _("Left Control");
876 return _("Right Alt");
878 return _("Left Alt");
880 return SDL_GetKeyName((SDLKey) key);
885 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
887 if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
888 item->change_input(_("Press Key"));
889 controller->wait_for_key = item->id;
890 } else if( item->id == Controller::CONTROLCOUNT) {
891 controller->jump_with_up_kbd = item->toggled;
896 JoystickKeyboardController::KeyboardMenu::update()
899 get_item_by_id((int) Controller::UP).change_input(get_key_name(
900 controller->reversemap_key(Controller::UP)));
901 get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
902 controller->reversemap_key(Controller::DOWN)));
903 get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
904 controller->reversemap_key(Controller::LEFT)));
905 get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
906 controller->reversemap_key(Controller::RIGHT)));
907 get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
908 controller->reversemap_key(Controller::JUMP)));
909 get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
910 controller->reversemap_key(Controller::ACTION)));
911 get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
912 controller->reversemap_key(Controller::PEEK_LEFT)));
913 get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
914 controller->reversemap_key(Controller::PEEK_RIGHT)));
915 get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
916 controller->reversemap_key(Controller::PEEK_UP)));
917 get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
918 controller->reversemap_key(Controller::PEEK_DOWN)));
919 if (g_config->console_enabled) {
920 get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
921 controller->reversemap_key(Controller::CONSOLE)));
923 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
926 //---------------------------------------------------------------------------
928 JoystickKeyboardController::JoystickMenu::JoystickMenu(
929 JoystickKeyboardController* _controller)
930 : controller(_controller)
935 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
939 JoystickKeyboardController::JoystickMenu::recreateMenu()
942 add_label(_("Setup Joystick"));
944 if(controller->joysticks.size() > 0) {
945 add_controlfield(Controller::UP, _("Up"));
946 add_controlfield(Controller::DOWN, _("Down"));
947 add_controlfield(Controller::LEFT, _("Left"));
948 add_controlfield(Controller::RIGHT, _("Right"));
949 add_controlfield(Controller::JUMP, _("Jump"));
950 add_controlfield(Controller::ACTION, _("Action"));
951 add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
952 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
953 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
954 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
955 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
957 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
959 add_inactive(-1, _("No Joysticks found"));
962 add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
964 //Show Joysticks currently activated:
965 for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
966 i != controller->joysticks.end(); ++i) {
968 add_inactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
977 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
982 std::ostringstream name;
983 name << "Button " << button;
988 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
990 if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
991 item->change_input(_("Press Button"));
992 controller->wait_for_joystick = item->id;
993 } else if (item->id == Controller::CONTROLCOUNT) {
994 controller->jump_with_up_joy = item->toggled;
995 } else if( item->id == SCAN_JOYSTICKS) {
996 controller->updateAvailableJoysticks();
1002 JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
1004 int button = controller->reversemap_joybutton(id);
1005 int axis = controller->reversemap_joyaxis(id);
1006 int hat_dir = controller->reversemap_joyhat(id);
1009 get_item_by_id((int)id).change_input(get_button_name(button));
1010 } else if (axis != 0) {
1011 std::ostringstream name;
1022 else if (abs(axis) == 2)
1024 else if (abs(axis) == 2)
1026 else if (abs(axis) == 3)
1031 get_item_by_id((int)id).change_input(name.str());
1032 } else if (hat_dir != -1) {
1054 name = "Unknown hat_dir";
1058 get_item_by_id((int)id).change_input(name);
1060 get_item_by_id((int)id).change_input("None");
1065 JoystickKeyboardController::JoystickMenu::update()
1067 if(controller->joysticks.size() == 0)
1070 update_menu_item(Controller::UP);
1071 update_menu_item(Controller::DOWN);
1072 update_menu_item(Controller::LEFT);
1073 update_menu_item(Controller::RIGHT);
1075 update_menu_item(Controller::JUMP);
1076 update_menu_item(Controller::ACTION);
1077 update_menu_item(Controller::PAUSE_MENU);
1078 update_menu_item(Controller::PEEK_LEFT);
1079 update_menu_item(Controller::PEEK_RIGHT);
1080 update_menu_item(Controller::PEEK_UP);
1081 update_menu_item(Controller::PEEK_DOWN);
1083 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;