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.
23 #include "joystickkeyboardcontroller.hpp"
28 #include "gui/menu.hpp"
29 #include "gettext.hpp"
30 #include "lisp/writer.hpp"
31 #include "lisp/lisp.hpp"
32 #include "lisp/list_iterator.hpp"
33 #include "game_session.hpp"
34 #include "console.hpp"
35 #include "gameconfig.hpp"
38 const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
41 class JoystickKeyboardController::JoystickMenu : public Menu
44 JoystickMenu(JoystickKeyboardController* controller);
45 virtual ~JoystickMenu();
48 std::string get_button_name(int button);
49 void update_menu_item(Control id);
50 virtual void menu_action(MenuItem* item);
51 JoystickKeyboardController* controller;
56 class JoystickKeyboardController::KeyboardMenu : public Menu
59 KeyboardMenu(JoystickKeyboardController* controller);
63 std::string get_key_name(SDLKey key);
64 virtual void menu_action(MenuItem* item);
65 JoystickKeyboardController* controller;
68 JoystickKeyboardController::JoystickKeyboardController()
70 wait_for_key(-1), wait_for_joystick(-1),
71 key_options_menu(0), joystick_options_menu(0)
73 // initialize default keyboard map
74 keymap[SDLK_LEFT] = LEFT;
75 keymap[SDLK_RIGHT] = RIGHT;
77 keymap[SDLK_DOWN] = DOWN;
78 keymap[SDLK_SPACE] = JUMP;
79 keymap[SDLK_LCTRL] = ACTION;
80 keymap[SDLK_LALT] = ACTION;
81 keymap[SDLK_ESCAPE] = PAUSE_MENU;
82 keymap[SDLK_p] = PAUSE_MENU;
83 keymap[SDLK_PAUSE] = PAUSE_MENU;
84 keymap[SDLK_RETURN] = MENU_SELECT;
85 keymap[SDLK_KP_ENTER] = MENU_SELECT;
86 keymap[SDLK_CARET] = CONSOLE;
87 keymap[SDLK_DELETE] = PEEK_LEFT;
88 keymap[SDLK_PAGEDOWN] = PEEK_RIGHT;
89 keymap[SDLK_HOME] = PEEK_UP;
90 keymap[SDLK_END] = PEEK_DOWN;
92 jump_with_up_joy = false;
93 jump_with_up_kbd = false;
95 updateAvailableJoysticks();
99 // Default joystick button configuration
100 joy_button_map[0] = JUMP;
101 joy_button_map[1] = ACTION;
103 if( min_joybuttons > 5 ){
104 joy_button_map[4] = PEEK_LEFT;
105 joy_button_map[5] = PEEK_RIGHT;
107 if(min_joybuttons > 7)
108 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
110 // map the last 2 buttons to menu and pause
111 if(min_joybuttons > 2)
112 joy_button_map[min_joybuttons-1] = PAUSE_MENU;
113 // map all remaining joystick buttons to MENU_SELECT
114 for(int i = 2; i < max_joybuttons; ++i) {
115 if(i != min_joybuttons-1)
116 joy_button_map[i] = MENU_SELECT;
120 // Default joystick axis configuration
121 joy_axis_map[-1] = LEFT;
122 joy_axis_map[ 1] = RIGHT;
123 joy_axis_map[-2] = UP;
124 joy_axis_map[ 2] = DOWN;
127 JoystickKeyboardController::~JoystickKeyboardController()
129 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
130 i != joysticks.end(); ++i) {
132 SDL_JoystickClose(*i);
135 delete key_options_menu;
136 delete joystick_options_menu;
140 JoystickKeyboardController::updateAvailableJoysticks()
142 for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
143 i != joysticks.end(); ++i) {
145 SDL_JoystickClose(*i);
149 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
150 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
152 int joystick_count = SDL_NumJoysticks();
158 if( joystick_count > 0 ){
159 for(int i = 0; i < joystick_count; ++i) {
160 SDL_Joystick* joystick = SDL_JoystickOpen(i);
162 if(SDL_JoystickNumButtons(joystick) < 2) {
163 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 buttons" << std::endl;
166 if(SDL_JoystickNumAxes(joystick) < 2
167 && SDL_JoystickNumHats(joystick) == 0) {
168 log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 axes and no hat" << std::endl;
172 SDL_JoystickClose(joystick);
176 if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
177 min_joybuttons = SDL_JoystickNumButtons(joystick);
179 if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
180 max_joybuttons = SDL_JoystickNumButtons(joystick);
182 if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
183 max_joyaxis = SDL_JoystickNumAxes(joystick);
185 if(SDL_JoystickNumHats(joystick) > max_joyhats)
186 max_joyhats = SDL_JoystickNumHats(joystick);
188 joysticks.push_back(joystick);
192 // some joysticks or SDL seem to produce some bogus events after being opened
193 Uint32 ticks = SDL_GetTicks();
194 while(SDL_GetTicks() - ticks < 200) {
196 SDL_PollEvent(&event);
201 JoystickKeyboardController::read(const lisp::Lisp& lisp)
203 const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
206 keymap_lisp->get("jump-with-up", jump_with_up_kbd);
207 lisp::ListIterator iter(keymap_lisp);
209 if(iter.item() == "map") {
212 const lisp::Lisp* map = iter.lisp();
213 map->get("key", key);
214 map->get("control", control);
215 if(key < SDLK_FIRST || key >= SDLK_LAST) {
216 log_info << "Invalid key '" << key << "' in keymap" << std::endl;
221 for(i = 0; controlNames[i] != 0; ++i) {
222 if(control == controlNames[i])
225 if(controlNames[i] == 0) {
226 log_info << "Invalid control '" << control << "' in keymap" << std::endl;
229 keymap[(SDLKey) key] = (Control)i;
234 const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
236 joystick_lisp->get("dead-zone", dead_zone);
237 joystick_lisp->get("jump-with-up", jump_with_up_joy);
238 lisp::ListIterator iter(joystick_lisp);
240 if(iter.item() == "map") {
245 const lisp::Lisp* map = iter.lisp();
247 map->get("control", control);
249 for(i = 0; controlNames[i] != 0; ++i) {
250 if(control == controlNames[i])
253 if(controlNames[i] == 0) {
254 log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
258 if (map->get("button", button)) {
259 if(button < 0 || button >= max_joybuttons) {
260 log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
263 bind_joybutton(button, (Control) i);
266 if (map->get("axis", axis)) {
267 if (axis == 0 || abs(axis) > max_joyaxis) {
268 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
271 bind_joyaxis(axis, (Control) i);
274 if (map->get("hat", hat)) {
275 if (hat != SDL_HAT_UP &&
276 hat != SDL_HAT_DOWN &&
277 hat != SDL_HAT_LEFT &&
278 hat != SDL_HAT_RIGHT) {
279 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
282 bind_joyhat(hat, (Control) i);
291 JoystickKeyboardController::write(lisp::Writer& writer)
293 writer.start_list("keymap");
294 writer.write_bool("jump-with-up", jump_with_up_kbd);
295 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
296 writer.start_list("map");
297 writer.write_int("key", (int) i->first);
298 writer.write_string("control", controlNames[i->second]);
299 writer.end_list("map");
301 writer.end_list("keymap");
303 writer.start_list("joystick");
304 writer.write_int("dead-zone", dead_zone);
305 writer.write_bool("jump-with-up", jump_with_up_joy);
307 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
309 writer.start_list("map");
310 writer.write_int("button", i->first);
311 writer.write_string("control", controlNames[i->second]);
312 writer.end_list("map");
315 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
316 writer.start_list("map");
317 writer.write_int("hat", i->first);
318 writer.write_string("control", controlNames[i->second]);
319 writer.end_list("map");
322 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
323 writer.start_list("map");
324 writer.write_int("axis", i->first);
325 writer.write_string("control", controlNames[i->second]);
326 writer.end_list("map");
329 writer.end_list("joystick");
333 JoystickKeyboardController::reset()
339 JoystickKeyboardController::set_joy_controls(Control id, bool value)
341 if (jump_with_up_joy && id == Controller::UP)
342 controls[Controller::JUMP] = value;
344 controls[(Control)id] = value;
348 JoystickKeyboardController::process_event(const SDL_Event& event)
353 process_key_event(event);
356 case SDL_JOYAXISMOTION:
357 process_axis_event(event.jaxis);
360 case SDL_JOYHATMOTION:
361 process_hat_event(event.jhat);
364 case SDL_JOYBUTTONDOWN:
365 case SDL_JOYBUTTONUP:
366 process_button_event(event.jbutton);
375 JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
377 if(wait_for_joystick >= 0)
379 if(jbutton.state == SDL_PRESSED)
381 bind_joybutton(jbutton.button, (Control)wait_for_joystick);
382 joystick_options_menu->update();
384 wait_for_joystick = -1;
389 ButtonMap::iterator i = joy_button_map.find(jbutton.button);
390 if(i == joy_button_map.end()) {
391 log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
393 set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
399 JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
401 if (wait_for_joystick >= 0)
403 if (abs(jaxis.value) > dead_zone) {
405 bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
407 bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
409 joystick_options_menu->update();
410 wait_for_joystick = -1;
415 // Split the axis into left and right, so that both can be
416 // mapped separately (needed for jump/down vs up/down)
417 int axis = jaxis.axis + 1;
419 AxisMap::iterator left = joy_axis_map.find(-axis);
420 AxisMap::iterator right = joy_axis_map.find(axis);
422 if(left == joy_axis_map.end()) {
423 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
425 if (jaxis.value < -dead_zone)
426 set_joy_controls(left->second, true);
427 else if (jaxis.value > dead_zone)
428 set_joy_controls(left->second, false);
430 set_joy_controls(left->second, false);
433 if(right == joy_axis_map.end()) {
434 std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
436 if (jaxis.value < -dead_zone)
437 set_joy_controls(right->second, false);
438 else if (jaxis.value > dead_zone)
439 set_joy_controls(right->second, true);
441 set_joy_controls(right->second, false);
447 JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
449 Uint8 changed = hat_state ^ jhat.value;
451 if (wait_for_joystick >= 0)
453 if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
454 bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
456 if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
457 bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
459 if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
460 bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
462 if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
463 bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
465 joystick_options_menu->update();
466 wait_for_joystick = -1;
470 if (changed & SDL_HAT_UP)
472 HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
473 if (it != joy_hat_map.end())
474 set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
477 if (changed & SDL_HAT_DOWN)
479 HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
480 if (it != joy_hat_map.end())
481 set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
484 if (changed & SDL_HAT_LEFT)
486 HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
487 if (it != joy_hat_map.end())
488 set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
491 if (changed & SDL_HAT_RIGHT)
493 HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
494 if (it != joy_hat_map.end())
495 set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
499 hat_state = jhat.value;
503 JoystickKeyboardController::process_key_event(const SDL_Event& event)
505 KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
507 // if console key was pressed: toggle console
508 if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
509 if (event.type == SDL_KEYDOWN)
510 Console::instance->toggle();
512 if (Console::instance->hasFocus()) {
513 // if console is open: send key there
514 process_console_key_event(event);
515 } else if (Menu::current()) {
516 // if menu mode: send key there
517 process_menu_key_event(event);
518 } else if(key_mapping == keymap.end()) {
519 // default action: update controls
520 //log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
522 Control control = key_mapping->second;
523 controls[control] = (event.type == SDL_KEYDOWN);
524 if (jump_with_up_kbd && control == UP){
525 controls[JUMP] = (event.type == SDL_KEYDOWN);
532 JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
534 if (event.type != SDL_KEYDOWN) return;
536 switch (event.key.keysym.sym) {
538 Console::instance->enter();
541 Console::instance->backspace();
544 Console::instance->autocomplete();
547 Console::instance->scroll(-1);
550 Console::instance->scroll(+1);
553 Console::instance->move_cursor(-65535);
556 Console::instance->move_cursor(+65535);
559 Console::instance->show_history(-1);
562 Console::instance->show_history(+1);
565 Console::instance->move_cursor(-1);
568 Console::instance->move_cursor(+1);
571 int c = event.key.keysym.unicode;
572 if ((c >= 32) && (c <= 126)) {
573 Console::instance->input((char)c);
580 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
582 // wait for key mode?
583 if(wait_for_key >= 0) {
584 if(event.type == SDL_KEYUP)
587 if(event.key.keysym.sym != SDLK_ESCAPE
588 && event.key.keysym.sym != SDLK_PAUSE) {
589 bind_key(event.key.keysym.sym, (Control) wait_for_key);
592 key_options_menu->update();
596 if(wait_for_joystick >= 0) {
597 if(event.key.keysym.sym == SDLK_ESCAPE) {
599 joystick_options_menu->update();
600 wait_for_joystick = -1;
606 /* we use default keys when the menu is open (to avoid problems when
607 * redefining keys to invalid settings
609 switch(event.key.keysym.sym) {
625 control = MENU_SELECT;
629 control = PAUSE_MENU;
636 controls[control] = (event.type == SDL_KEYDOWN);
640 JoystickKeyboardController::unbind_joystick_control(Control control)
642 // remove all previous mappings for that control
643 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
644 if(i->second == control)
645 joy_axis_map.erase(i++);
650 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
651 if(i->second == control)
652 joy_button_map.erase(i++);
657 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
658 if(i->second == control)
659 joy_hat_map.erase(i++);
666 JoystickKeyboardController::bind_joyaxis(int axis, Control control)
668 // axis isn't the SDL axis number, but axisnumber + 1 with sign
669 // changed depending on if the positive or negative end is to be
670 // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
673 unbind_joystick_control(control);
676 joy_axis_map[axis] = control;
680 JoystickKeyboardController::bind_joyhat(int dir, Control c)
682 unbind_joystick_control(c);
685 joy_hat_map[dir] = c;
689 JoystickKeyboardController::bind_joybutton(int button, Control control)
691 unbind_joystick_control(control);
694 joy_button_map[button] = control;
698 JoystickKeyboardController::bind_key(SDLKey key, Control control)
700 // remove all previous mappings for that control and for that key
701 for(KeyMap::iterator i = keymap.begin();
702 i != keymap.end(); /* no ++i */) {
703 if(i->second == control) {
704 KeyMap::iterator e = i;
712 KeyMap::iterator i = keymap.find(key);
713 if(i != keymap.end())
717 keymap[key]= control;
721 JoystickKeyboardController::print_joystick_mappings()
723 std::cout << "Joystick Mappings" << std::endl;
724 std::cout << "-----------------" << std::endl;
725 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
726 std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
729 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
730 std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
733 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
734 std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
736 std::cout << std::endl;
740 JoystickKeyboardController::reversemap_key(Control c)
742 for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
751 JoystickKeyboardController::reversemap_joyaxis(Control c)
753 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
762 JoystickKeyboardController::reversemap_joybutton(Control c)
764 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
773 JoystickKeyboardController::reversemap_joyhat(Control c)
775 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
784 JoystickKeyboardController::get_key_options_menu()
786 if(key_options_menu == 0) {
787 key_options_menu = new KeyboardMenu(this);
790 return key_options_menu;
794 JoystickKeyboardController::get_joystick_options_menu()
796 if(joystick_options_menu == 0) {
797 joystick_options_menu = new JoystickMenu(this);
800 return joystick_options_menu;
803 //----------------------------------------------------------------------------
805 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
806 JoystickKeyboardController* _controller)
807 : controller(_controller)
809 add_label(_("Setup Keyboard"));
811 add_controlfield(Controller::UP, _("Up"));
812 add_controlfield(Controller::DOWN, _("Down"));
813 add_controlfield(Controller::LEFT, _("Left"));
814 add_controlfield(Controller::RIGHT, _("Right"));
815 add_controlfield(Controller::JUMP, _("Jump"));
816 add_controlfield(Controller::ACTION, _("Action"));
817 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
818 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
819 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
820 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
821 if (config->console_enabled) {
822 add_controlfield(Controller::CONSOLE, _("Console"));
824 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
830 JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
834 JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
840 return _("Up cursor");
842 return _("Down cursor");
844 return _("Left cursor");
846 return _("Right cursor");
852 return _("Right Shift");
854 return _("Left Shift");
856 return _("Right Control");
858 return _("Left Control");
860 return _("Right Alt");
862 return _("Left Alt");
864 return SDL_GetKeyName((SDLKey) key);
869 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
871 if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
872 item->change_input(_("Press Key"));
873 controller->wait_for_key = item->id;
874 } else if( item->id == Controller::CONTROLCOUNT) {
875 controller->jump_with_up_kbd = item->toggled;
880 JoystickKeyboardController::KeyboardMenu::update()
883 get_item_by_id((int) Controller::UP).change_input(get_key_name(
884 controller->reversemap_key(Controller::UP)));
885 get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
886 controller->reversemap_key(Controller::DOWN)));
887 get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
888 controller->reversemap_key(Controller::LEFT)));
889 get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
890 controller->reversemap_key(Controller::RIGHT)));
891 get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
892 controller->reversemap_key(Controller::JUMP)));
893 get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
894 controller->reversemap_key(Controller::ACTION)));
895 get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
896 controller->reversemap_key(Controller::PEEK_LEFT)));
897 get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
898 controller->reversemap_key(Controller::PEEK_RIGHT)));
899 get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
900 controller->reversemap_key(Controller::PEEK_UP)));
901 get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
902 controller->reversemap_key(Controller::PEEK_DOWN)));
903 if (config->console_enabled) {
904 get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
905 controller->reversemap_key(Controller::CONSOLE)));
907 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
910 //---------------------------------------------------------------------------
912 JoystickKeyboardController::JoystickMenu::JoystickMenu(
913 JoystickKeyboardController* _controller)
914 : controller(_controller)
919 JoystickKeyboardController::JoystickMenu::~JoystickMenu()
923 JoystickKeyboardController::JoystickMenu::recreateMenu()
926 add_label(_("Setup Joystick"));
928 if(controller->joysticks.size() > 0) {
929 add_controlfield(Controller::UP, _("Up"));
930 add_controlfield(Controller::DOWN, _("Down"));
931 add_controlfield(Controller::LEFT, _("Left"));
932 add_controlfield(Controller::RIGHT, _("Right"));
933 add_controlfield(Controller::JUMP, _("Jump"));
934 add_controlfield(Controller::ACTION, _("Action"));
935 add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
936 add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
937 add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
938 add_controlfield(Controller::PEEK_UP, _("Peek Up"));
939 add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
941 add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
943 add_inactive(-1, _("No Joysticks found"));
946 add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
948 //Show Joysticks currently activated:
949 for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
950 i != controller->joysticks.end(); ++i) {
952 add_inactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
961 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
966 std::ostringstream name;
967 name << "Button " << button;
972 JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
974 if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
975 item->change_input(_("Press Button"));
976 controller->wait_for_joystick = item->id;
977 } else if (item->id == Controller::CONTROLCOUNT) {
978 controller->jump_with_up_joy = item->toggled;
979 } else if( item->id == SCAN_JOYSTICKS) {
980 controller->updateAvailableJoysticks();
986 JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
988 int button = controller->reversemap_joybutton(id);
989 int axis = controller->reversemap_joyaxis(id);
990 int hat_dir = controller->reversemap_joyhat(id);
993 get_item_by_id((int)id).change_input(get_button_name(button));
994 } else if (axis != 0) {
995 std::ostringstream name;
1006 else if (abs(axis) == 2)
1008 else if (abs(axis) == 2)
1010 else if (abs(axis) == 3)
1015 get_item_by_id((int)id).change_input(name.str());
1016 } else if (hat_dir != -1) {
1038 name = "Unknown hat_dir";
1042 get_item_by_id((int)id).change_input(name);
1044 get_item_by_id((int)id).change_input("None");
1049 JoystickKeyboardController::JoystickMenu::update()
1051 if(controller->joysticks.size() == 0)
1054 update_menu_item(Controller::UP);
1055 update_menu_item(Controller::DOWN);
1056 update_menu_item(Controller::LEFT);
1057 update_menu_item(Controller::RIGHT);
1059 update_menu_item(Controller::JUMP);
1060 update_menu_item(Controller::ACTION);
1061 update_menu_item(Controller::PAUSE_MENU);
1062 update_menu_item(Controller::PEEK_LEFT);
1063 update_menu_item(Controller::PEEK_RIGHT);
1064 update_menu_item(Controller::PEEK_UP);
1065 update_menu_item(Controller::PEEK_DOWN);
1067 get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;