4 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
5 // 2007 Ingo Ruhnke <grumbel@gmx.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "joystickkeyboardcontroller.hpp"
26 #include "gui/menu.hpp"
27 #include "gettext.hpp"
28 #include "lisp/lisp.hpp"
29 #include "lisp/list_iterator.hpp"
30 #include "game_session.hpp"
31 #include "console.hpp"
32 #include "gameconfig.hpp"
35 const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
38 class JoystickKeyboardController::JoystickMenu : public Menu
41 JoystickMenu(JoystickKeyboardController* controller);
42 virtual ~JoystickMenu();
45 std::string get_button_name(int button);
46 void update_menu_item(Control id);
47 virtual void menu_action(MenuItem* item);
48 JoystickKeyboardController* controller;
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 JoystickKeyboardController::JoystickKeyboardController()
67 wait_for_key(-1), wait_for_joystick(-1),
68 key_options_menu(0), joystick_options_menu(0)
70 // initialize default keyboard map
71 keymap[SDLK_LEFT] = LEFT;
72 keymap[SDLK_RIGHT] = RIGHT;
74 keymap[SDLK_DOWN] = DOWN;
75 keymap[SDLK_SPACE] = JUMP;
76 keymap[SDLK_LCTRL] = ACTION;
77 keymap[SDLK_LALT] = ACTION;
78 keymap[SDLK_ESCAPE] = PAUSE_MENU;
79 keymap[SDLK_p] = PAUSE_MENU;
80 keymap[SDLK_PAUSE] = PAUSE_MENU;
81 keymap[SDLK_RETURN] = MENU_SELECT;
82 keymap[SDLK_KP_ENTER] = MENU_SELECT;
83 keymap[SDLK_CARET] = CONSOLE;
84 keymap[SDLK_DELETE] = PEEK_LEFT;
85 keymap[SDLK_END] = PEEK_RIGHT;
86 keymap[SDLK_PAGEUP] = PEEK_UP;
87 keymap[SDLK_PAGEDOWN] = PEEK_DOWN;
89 jump_with_up_joy = false;
90 jump_with_up_kbd = false;
92 updateAvailableJoysticks();
96 // Default joystick button configuration
97 joy_button_map[0] = JUMP;
98 joy_button_map[1] = ACTION;
100 if( min_joybuttons > 5 ){
101 joy_button_map[4] = PEEK_LEFT;
102 joy_button_map[5] = PEEK_RIGHT;
104 if(min_joybuttons > 7)
105 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
107 // map the last 2 buttons to menu and pause
108 if(min_joybuttons > 2)
109 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
110 // map all remaining joystick buttons to MENU_SELECT
111 for(int i = 2; i < max_joybuttons; ++i) {
112 if(i != min_joybuttons-1)
113 joy_button_map[i] = MENU_SELECT;
117 // Default joystick axis configuration
118 joy_axis_map[-1] = LEFT;
119 joy_axis_map[ 1] = RIGHT;
120 joy_axis_map[-2] = UP;
121 joy_axis_map[ 2] = DOWN;
124 JoystickKeyboardController::~JoystickKeyboardController()
126 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
127 i != joysticks.end(); ++i) {
129 SDL_JoystickClose(*i);
132 delete key_options_menu;
133 delete joystick_options_menu;
137 JoystickKeyboardController::updateAvailableJoysticks()
139 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
140 i != joysticks.end(); ++i) {
142 SDL_JoystickClose(*i);
146 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
147 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
149 int joystick_count = SDL_NumJoysticks();
155 if( joystick_count > 0 ){
156 for(int i = 0; i < joystick_count; ++i) {
157 SDL_Joystick* joystick = SDL_JoystickOpen(i);
159 if(SDL_JoystickNumButtons(joystick) < 2) {
160 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 buttons" << std::endl;
163 if(SDL_JoystickNumAxes(joystick) < 2
164 && SDL_JoystickNumHats(joystick) == 0) {
165 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 axes and no hat" << std::endl;
169 SDL_JoystickClose(joystick);
173 if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
174 min_joybuttons = SDL_JoystickNumButtons(joystick);
176 if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
177 max_joybuttons = SDL_JoystickNumButtons(joystick);
179 if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
180 max_joyaxis = SDL_JoystickNumAxes(joystick);
182 if(SDL_JoystickNumHats(joystick) > max_joyhats)
183 max_joyhats = SDL_JoystickNumHats(joystick);
185 joysticks.push_back(joystick);
189 // some joysticks or SDL seem to produce some bogus events after being opened
190 Uint32 ticks = SDL_GetTicks();
191 while(SDL_GetTicks() - ticks < 200) {
193 SDL_PollEvent(&event);
198 JoystickKeyboardController::read(const lisp::Lisp& lisp)
200 const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
203 keymap_lisp->get("jump-with-up", jump_with_up_kbd);
204 lisp::ListIterator iter(keymap_lisp);
206 if(iter.item() == "map") {
209 const lisp::Lisp* map = iter.lisp();
210 map->get("key", key);
211 map->get("control", control);
212 if(key < SDLK_FIRST || key >= SDLK_LAST) {
213 log_info << "Invalid key '" << key << "' in keymap" << std::endl;
218 for(i = 0; controlNames[i] != 0; ++i) {
219 if(control == controlNames[i])
222 if(controlNames[i] == 0) {
223 log_info << "Invalid control '" << control << "' in keymap" << std::endl;
226 keymap[(SDLKey) key] = (Control)i;
231 const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
233 joystick_lisp->get("dead-zone", dead_zone);
234 joystick_lisp->get("jump-with-up", jump_with_up_joy);
235 lisp::ListIterator iter(joystick_lisp);
237 if(iter.item() == "map") {
242 const lisp::Lisp* map = iter.lisp();
244 map->get("control", control);
246 for(i = 0; controlNames[i] != 0; ++i) {
247 if(control == controlNames[i])
250 if(controlNames[i] == 0) {
251 log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
255 if (map->get("button", button)) {
256 if(button < 0 || button >= max_joybuttons) {
257 log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
260 bind_joybutton(button, (Control) i);
263 if (map->get("axis", axis)) {
264 if (axis == 0 || abs(axis) > max_joyaxis) {
265 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
268 bind_joyaxis(axis, (Control) i);
271 if (map->get("hat", hat)) {
272 if (hat != SDL_HAT_UP &&
273 hat != SDL_HAT_DOWN &&
274 hat != SDL_HAT_LEFT &&
275 hat != SDL_HAT_RIGHT) {
276 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
279 bind_joyhat(hat, (Control) i);
288 JoystickKeyboardController::write(lisp::Writer& writer)
290 writer.start_list("keymap");
291 writer.write_bool("jump-with-up", jump_with_up_kbd);
292 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
293 writer.start_list("map");
294 writer.write_int("key", (int) i->first);
295 writer.write_string("control", controlNames[i->second]);
296 writer.end_list("map");
298 writer.end_list("keymap");
300 writer.start_list("joystick");
301 writer.write_int("dead-zone", dead_zone);
302 writer.write_bool("jump-with-up", jump_with_up_joy);
304 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
306 writer.start_list("map");
307 writer.write_int("button", i->first);
308 writer.write_string("control", controlNames[i->second]);
309 writer.end_list("map");
312 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
313 writer.start_list("map");
314 writer.write_int("hat", i->first);
315 writer.write_string("control", controlNames[i->second]);
316 writer.end_list("map");
319 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
320 writer.start_list("map");
321 writer.write_int("axis", i->first);
322 writer.write_string("control", controlNames[i->second]);
323 writer.end_list("map");
326 writer.end_list("joystick");
330 JoystickKeyboardController::reset()
336 JoystickKeyboardController::set_joy_controls(Control id, bool value)
338 if (jump_with_up_joy && id == Controller::UP)
339 controls[Controller::JUMP] = value;
341 controls[(Control)id] = value;
345 JoystickKeyboardController::process_event(const SDL_Event& event)
350 process_key_event(event);
353 case SDL_JOYAXISMOTION:
354 process_axis_event(event.jaxis);
357 case SDL_JOYHATMOTION:
358 process_hat_event(event.jhat);
361 case SDL_JOYBUTTONDOWN:
362 case SDL_JOYBUTTONUP:
363 process_button_event(event.jbutton);
372 JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
374 if(wait_for_joystick >= 0)
376 if(jbutton.state == SDL_PRESSED)
378 bind_joybutton(jbutton.button, (Control)wait_for_joystick);
379 joystick_options_menu->update();
381 wait_for_joystick = -1;
386 ButtonMap::iterator i = joy_button_map.find(jbutton.button);
387 if(i == joy_button_map.end()) {
388 log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
390 set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
396 JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
398 if (wait_for_joystick >= 0)
400 if (abs(jaxis.value) > dead_zone) {
402 bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
404 bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
406 joystick_options_menu->update();
407 wait_for_joystick = -1;
412 // Split the axis into left and right, so that both can be
413 // mapped seperatly (needed for jump/down vs up/down)
414 int axis = jaxis.axis + 1;
416 AxisMap::iterator left = joy_axis_map.find(-axis);
417 AxisMap::iterator right = joy_axis_map.find(axis);
419 if(left == joy_axis_map.end()) {
420 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
422 if (jaxis.value < -dead_zone)
423 set_joy_controls(left->second, true);
424 else if (jaxis.value > dead_zone)
425 set_joy_controls(left->second, false);
427 set_joy_controls(left->second, false);
430 if(right == joy_axis_map.end()) {
431 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
433 if (jaxis.value < -dead_zone)
434 set_joy_controls(right->second, false);
435 else if (jaxis.value > dead_zone)
436 set_joy_controls(right->second, true);
438 set_joy_controls(right->second, false);
444 JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
446 Uint8 changed = hat_state ^ jhat.value;
448 if (wait_for_joystick >= 0)
450 if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
451 bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
453 if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
454 bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
456 if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
457 bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
459 if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
460 bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
462 joystick_options_menu->update();
463 wait_for_joystick = -1;
467 if (changed & SDL_HAT_UP)
469 HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
470 if (it != joy_hat_map.end())
471 set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
474 if (changed & SDL_HAT_DOWN)
476 HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
477 if (it != joy_hat_map.end())
478 set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
481 if (changed & SDL_HAT_LEFT)
483 HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
484 if (it != joy_hat_map.end())
485 set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
488 if (changed & SDL_HAT_RIGHT)
490 HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
491 if (it != joy_hat_map.end())
492 set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
496 hat_state = jhat.value;
500 JoystickKeyboardController::process_key_event(const SDL_Event& event)
502 KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
504 // if console key was pressed: toggle console
505 if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
506 if (event.type == SDL_KEYDOWN)
507 Console::instance->toggle();
509 if (Console::instance->hasFocus()) {
510 // if console is open: send key there
511 process_console_key_event(event);
512 } else if (Menu::current()) {
513 // if menu mode: send key there
514 process_menu_key_event(event);
515 } else if(key_mapping == keymap.end()) {
516 // default action: update controls
517 log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
519 Control control = key_mapping->second;
520 controls[control] = (event.type == SDL_KEYDOWN);
521 if (jump_with_up_kbd && control == UP){
522 controls[JUMP] = (event.type == SDL_KEYDOWN);
529 JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
531 if (event.type != SDL_KEYDOWN) return;
533 switch (event.key.keysym.sym) {
535 Console::instance->enter();
538 Console::instance->backspace();
541 Console::instance->autocomplete();
544 Console::instance->scroll(-1);
547 Console::instance->scroll(+1);
550 Console::instance->move_cursor(-65535);
553 Console::instance->move_cursor(+65535);
556 Console::instance->show_history(-1);
559 Console::instance->show_history(+1);
562 Console::instance->move_cursor(-1);
565 Console::instance->move_cursor(+1);
568 int c = event.key.keysym.unicode;
569 if ((c >= 32) && (c <= 126)) {
570 Console::instance->input((char)c);
577 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
579 // wait for key mode?
580 if(wait_for_key >= 0) {
581 if(event.type == SDL_KEYUP)
584 if(event.key.keysym.sym != SDLK_ESCAPE
585 && event.key.keysym.sym != SDLK_PAUSE) {
586 bind_key(event.key.keysym.sym, (Control) wait_for_key);
589 key_options_menu->update();
593 if(wait_for_joystick >= 0) {
594 if(event.key.keysym.sym == SDLK_ESCAPE) {
596 joystick_options_menu->update();
597 wait_for_joystick = -1;
603 /* we use default keys when the menu is open (to avoid problems when
604 * redefining keys to invalid settings
606 switch(event.key.keysym.sym) {
622 control = MENU_SELECT;
626 control = PAUSE_MENU;
633 controls[control] = (event.type == SDL_KEYDOWN);
637 JoystickKeyboardController::unbind_joystick_control(Control control)
639 // remove all previous mappings for that control
640 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
641 if(i->second == control)
642 joy_axis_map.erase(i++);
647 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
648 if(i->second == control)
649 joy_button_map.erase(i++);
654 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
655 if(i->second == control)
656 joy_hat_map.erase(i++);
663 JoystickKeyboardController::bind_joyaxis(int axis, Control control)
665 // axis isn't the SDL axis number, but axisnumber + 1 with sign
666 // changed depending on if the positive or negative end is to be
667 // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
670 unbind_joystick_control(control);
673 joy_axis_map[axis] = control;
677 JoystickKeyboardController::bind_joyhat(int dir, Control c)
679 unbind_joystick_control(c);
682 joy_hat_map[dir] = c;
686 JoystickKeyboardController::bind_joybutton(int button, Control control)
688 unbind_joystick_control(control);
691 joy_button_map[button] = control;
695 JoystickKeyboardController::bind_key(SDLKey key, Control control)
697 // remove all previous mappings for that control and for that key
698 for(KeyMap::iterator i = keymap.begin();
699 i != keymap.end(); /* no ++i */) {
700 if(i->second == control) {
701 KeyMap::iterator e = i;
709 KeyMap::iterator i = keymap.find(key);
710 if(i != keymap.end())
714 keymap[key]= control;
718 JoystickKeyboardController::print_joystick_mappings()
720 std::cout << "Joystick Mappings" << std::endl;
721 std::cout << "-----------------" << std::endl;
722 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
723 std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
726 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
727 std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
730 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
731 std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
733 std::cout << std::endl;
737 JoystickKeyboardController::reversemap_key(Control c)
739 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
748 JoystickKeyboardController::reversemap_joyaxis(Control c)
750 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
759 JoystickKeyboardController::reversemap_joybutton(Control c)
761 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
770 JoystickKeyboardController::reversemap_joyhat(Control c)
772 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
781 JoystickKeyboardController::get_key_options_menu()
783 if(key_options_menu == 0) {
784 key_options_menu = new KeyboardMenu(this);
787 return key_options_menu;
791 JoystickKeyboardController::get_joystick_options_menu()
793 if(joystick_options_menu == 0) {
794 joystick_options_menu = new JoystickMenu(this);
797 return joystick_options_menu;
800 //----------------------------------------------------------------------------
802 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
803 JoystickKeyboardController* _controller)
804 : controller(_controller)
806 add_label(_("Setup Keyboard"));
808 add_controlfield(Controller::UP, _("Up"));
809 add_controlfield(Controller::DOWN, _("Down"));
810 add_controlfield(Controller::LEFT, _("Left"));
811 add_controlfield(Controller::RIGHT, _("Right"));
812 add_controlfield(Controller::JUMP, _("Jump"));
813 add_controlfield(Controller::ACTION, _("Action"));
814 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
815 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
816 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
817 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
818 if (config->console_enabled) {
819 add_controlfield(Controller::CONSOLE, _("Console"));
821 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
827 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
831 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
837 return _("Up cursor");
839 return _("Down cursor");
841 return _("Left cursor");
843 return _("Right cursor");
849 return _("Right Shift");
851 return _("Left Shift");
853 return _("Right Control");
855 return _("Left Control");
857 return _("Right Alt");
859 return _("Left Alt");
861 return SDL_GetKeyName((SDLKey) key);
866 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
868 if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
869 item->change_input(_("Press Key"));
870 controller->wait_for_key = item->id;
871 } else if( item->id == Controller::CONTROLCOUNT) {
872 controller->jump_with_up_kbd = item->toggled;
877 JoystickKeyboardController::KeyboardMenu::update()
880 get_item_by_id((int) Controller::UP).change_input(get_key_name(
881 controller->reversemap_key(Controller::UP)));
882 get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
883 controller->reversemap_key(Controller::DOWN)));
884 get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
885 controller->reversemap_key(Controller::LEFT)));
886 get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
887 controller->reversemap_key(Controller::RIGHT)));
888 get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
889 controller->reversemap_key(Controller::JUMP)));
890 get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
891 controller->reversemap_key(Controller::ACTION)));
892 get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
893 controller->reversemap_key(Controller::PEEK_LEFT)));
894 get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
895 controller->reversemap_key(Controller::PEEK_RIGHT)));
896 get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
897 controller->reversemap_key(Controller::PEEK_UP)));
898 get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
899 controller->reversemap_key(Controller::PEEK_DOWN)));
900 if (config->console_enabled) {
901 get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
902 controller->reversemap_key(Controller::CONSOLE)));
904 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
907 //---------------------------------------------------------------------------
909 JoystickKeyboardController::JoystickMenu::JoystickMenu(
910 JoystickKeyboardController* _controller)
911 : controller(_controller)
916 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
920 JoystickKeyboardController::JoystickMenu::recreateMenu()
923 add_label(_("Setup Joystick"));
925 if(controller->joysticks.size() > 0) {
926 add_controlfield(Controller::UP, _("Up"));
927 add_controlfield(Controller::DOWN, _("Down"));
928 add_controlfield(Controller::LEFT, _("Left"));
929 add_controlfield(Controller::RIGHT, _("Right"));
930 add_controlfield(Controller::JUMP, _("Jump"));
931 add_controlfield(Controller::ACTION, _("Action"));
932 add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
933 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
934 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
935 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
936 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
938 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
940 add_deactive(-1, _("No Joysticks found"));
943 add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
945 //Show Joysticks currently activated:
946 for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
947 i != controller->joysticks.end(); ++i) {
949 add_deactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
958 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
963 std::ostringstream name;
964 name << "Button " << button;
969 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
971 if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
972 item->change_input(_("Press Button"));
973 controller->wait_for_joystick = item->id;
974 } else if (item->id == Controller::CONTROLCOUNT) {
975 controller->jump_with_up_joy = item->toggled;
976 } else if( item->id == SCAN_JOYSTICKS) {
977 controller->updateAvailableJoysticks();
983 JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
985 int button = controller->reversemap_joybutton(id);
986 int axis = controller->reversemap_joyaxis(id);
987 int hat_dir = controller->reversemap_joyhat(id);
990 get_item_by_id((int)id).change_input(get_button_name(button));
991 } else if (axis != 0) {
992 std::ostringstream name;
1003 else if (abs(axis) == 2)
1005 else if (abs(axis) == 2)
1007 else if (abs(axis) == 3)
1012 get_item_by_id((int)id).change_input(name.str());
1013 } else if (hat_dir != -1) {
1035 name = "Unknown hat_dir";
1039 get_item_by_id((int)id).change_input(name);
1041 get_item_by_id((int)id).change_input("None");
1046 JoystickKeyboardController::JoystickMenu::update()
1048 if(controller->joysticks.size() == 0)
1051 update_menu_item(Controller::UP);
1052 update_menu_item(Controller::DOWN);
1053 update_menu_item(Controller::LEFT);
1054 update_menu_item(Controller::RIGHT);
1056 update_menu_item(Controller::JUMP);
1057 update_menu_item(Controller::ACTION);
1058 update_menu_item(Controller::PAUSE_MENU);
1059 update_menu_item(Controller::PEEK_LEFT);
1060 update_menu_item(Controller::PEEK_RIGHT);
1061 update_menu_item(Controller::PEEK_UP);
1062 update_menu_item(Controller::PEEK_DOWN);
1064 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;