X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fcontrol%2Fjoystickkeyboardcontroller.cpp;h=c62153dcf18227e5e4fd590415531a291461de66;hb=8f4e4099494b925d893d94d3d4647d1ca29b09f6;hp=83cbdbced4edbddf8019054aef9bf74211b1e241;hpb=7ad6b7ed9d8d7c76ec7b70e4c27f47bd424b176e;p=supertux.git diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp index 83cbdbced..c62153dcf 100644 --- a/src/control/joystickkeyboardcontroller.cpp +++ b/src/control/joystickkeyboardcontroller.cpp @@ -1,7 +1,7 @@ // $Id$ -// +// // SuperTux -// Copyright (C) 2005 Matthias Braun +// Copyright (C) 2006 Matthias Braun // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -12,21 +12,22 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -#include "joystickkeyboardcontroller.h" -#include "gui/menu.h" -#include "app/gettext.h" -#include "lisp/lisp.h" -#include "lisp/list_iterator.h" -#include "game_session.h" +#include "joystickkeyboardcontroller.hpp" +#include "log.hpp" +#include "gui/menu.hpp" +#include "gettext.hpp" +#include "lisp/lisp.hpp" +#include "lisp/list_iterator.hpp" +#include "game_session.hpp" +#include "console.hpp" class JoystickKeyboardController::JoystickMenu : public Menu { @@ -53,10 +54,9 @@ public: }; JoystickKeyboardController::JoystickKeyboardController() - : wait_for_key(-1), wait_for_joybutton(-1) + : wait_for_key(-1), wait_for_joybutton(-1), key_options_menu(0), + joystick_options_menu(0) { - memset(last_keys, 0, sizeof(last_keys)); - // initialize default keyboard map keymap.insert(std::make_pair(SDLK_LEFT, LEFT)); keymap.insert(std::make_pair(SDLK_RIGHT, RIGHT)); @@ -70,29 +70,27 @@ JoystickKeyboardController::JoystickKeyboardController() keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU)); keymap.insert(std::make_pair(SDLK_RETURN, MENU_SELECT)); keymap.insert(std::make_pair(SDLK_KP_ENTER, MENU_SELECT)); + keymap.insert(std::make_pair(SDLK_CARET, CONSOLE)); + keymap.insert(std::make_pair(SDLK_DELETE, PEEK_LEFT)); + keymap.insert(std::make_pair(SDLK_END, PEEK_RIGHT)); - joystick_count = SDL_NumJoysticks(); + int joystick_count = SDL_NumJoysticks(); min_joybuttons = -1; max_joybuttons = -1; -#ifdef DEBUG - std::cout << "Found " << joystick_count << " joysticks.\n"; -#endif for(int i = 0; i < joystick_count; ++i) { SDL_Joystick* joystick = SDL_JoystickOpen(i); bool good = true; if(SDL_JoystickNumButtons(joystick) < 2) { - std::cerr << "Joystick " << i << " has less than 2 buttons.\n"; + log_warning << "Joystick " << i << " has less than 2 buttons" << std::endl; good = false; } if(SDL_JoystickNumAxes(joystick) < 2 && SDL_JoystickNumHats(joystick) == 0) { - std::cerr << "Joystick " << i << " has less than 2 axes and no hat.\n"; + log_warning << "Joystick " << i << " has less than 2 axes and no hat" << std::endl; good = false; } if(!good) { SDL_JoystickClose(joystick); - joysticks.push_back(0); - joystick_names.push_back(""); continue; } @@ -102,7 +100,6 @@ JoystickKeyboardController::JoystickKeyboardController() max_joybuttons = SDL_JoystickNumButtons(joystick); } - joystick_names.push_back(SDL_JoystickName(i)); joysticks.push_back(joystick); } @@ -114,13 +111,35 @@ JoystickKeyboardController::JoystickKeyboardController() joy_button_map.insert(std::make_pair(0, JUMP)); joy_button_map.insert(std::make_pair(1, ACTION)); - // map the last 2 buttons to menu and pause - if(min_joybuttons > 2) - joy_button_map.insert(std::make_pair(min_joybuttons-1, PAUSE_MENU)); - // map all remaining joystick buttons to MENU_SELECT - for(int i = 2; i < max_joybuttons; ++i) { - if(i != min_joybuttons-1) - joy_button_map.insert(std::make_pair(i, MENU_SELECT)); + // 6 or more Buttons + if( min_joybuttons > 5 ){ + joy_button_map.insert(std::make_pair( 4, PEEK_LEFT)); + joy_button_map.insert(std::make_pair( 5, PEEK_RIGHT)); + // 8 or more + if(min_joybuttons > 7) + joy_button_map.insert(std::make_pair(min_joybuttons-1, PAUSE_MENU)); + // map all remaining joystick buttons to MENU_SELECT + for(int i = 2; i < max_joybuttons; ++i) { + if( i != min_joybuttons-1 && i !=4 && i!= 5 ) + joy_button_map.insert(std::make_pair(i, MENU_SELECT)); + } + + } else { + // map the last 2 buttons to menu and pause + if(min_joybuttons > 2) + joy_button_map.insert(std::make_pair(min_joybuttons-1, PAUSE_MENU)); + // map all remaining joystick buttons to MENU_SELECT + for(int i = 2; i < max_joybuttons; ++i) { + if(i != min_joybuttons-1) + joy_button_map.insert(std::make_pair(i, MENU_SELECT)); + } + } + + // some joysticks or SDL seem to produce some bogus events after being opened + Uint32 ticks = SDL_GetTicks(); + while(SDL_GetTicks() - ticks < 200) { + SDL_Event event; + SDL_PollEvent(&event); } } @@ -151,7 +170,7 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp) map->get("key", key); map->get("control", control); if(key < SDLK_FIRST || key >= SDLK_LAST) { - std::cerr << "Invalid key '" << key << "' in keymap.\n"; + log_warning << "Invalid key '" << key << "' in keymap" << std::endl; continue; } @@ -161,12 +180,12 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp) break; } if(controlNames[i] == 0) { - std::cerr << "Invalid control '" << control << "' in keymap.\n"; + log_warning << "Invalid control '" << control << "' in keymap" << std::endl; continue; } keymap.insert(std::make_pair((SDLKey) key, (Control) i)); } else { - std::cerr << "Invalid lisp element '" << iter.item() << "' in keymap.\n"; + log_warning << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl; } } } @@ -187,7 +206,7 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp) map->get("button", button); map->get("control", control); if(button < 0 || button >= max_joybuttons) { - std::cerr << "Invalid button '" << button << "' in buttonmap.\n"; + log_warning << "Invalid button '" << button << "' in buttonmap" << std::endl; continue; } @@ -197,7 +216,7 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp) break; } if(controlNames[i] == 0) { - std::cerr << "Invalid control '" << control << "' in buttonmap.\n"; + log_warning << "Invalid control '" << control << "' in buttonmap" << std::endl; continue; } reset_joybutton(button, (Control) i); @@ -234,36 +253,18 @@ JoystickKeyboardController::write(lisp::Writer& writer) } void +JoystickKeyboardController::reset() +{ + Controller::reset(); +} + +void JoystickKeyboardController::process_event(const SDL_Event& event) { switch(event.type) { case SDL_KEYUP: case SDL_KEYDOWN: - // remember ascii keys for cheat codes... - if(event.type == SDL_KEYDOWN && - (event.key.keysym.unicode & 0xFF80) == 0) { - memmove(last_keys, last_keys+1, sizeof(last_keys)-1); - last_keys[sizeof(last_keys)-1] = event.key.keysym.unicode; - if(GameSession::current()) - GameSession::current()->try_cheats(); - } - - // menu mode? - if(Menu::current()) { // menu mode - process_menu_key_event(event); - return; - } else { - // normal mode, find key in keymap - KeyMap::iterator i = keymap.find(event.key.keysym.sym); - if(i == keymap.end()) { -#ifdef DEBUG - std::cerr << "Pressed key without mapping.\n"; -#endif - return; - } - Control control = i->second; - controls[control] = event.type == SDL_KEYDOWN ? true : false; - } + process_key_event(event); break; case SDL_JOYAXISMOTION: @@ -337,10 +338,7 @@ JoystickKeyboardController::process_event(const SDL_Event& event) ButtonMap::iterator i = joy_button_map.find(event.jbutton.button); if(i == joy_button_map.end()) { -#ifdef DEBUG - std::cerr << "Unmapped joybutton " << (int) event.jbutton.button - << " pressed.\n"; -#endif + log_debug << "Unmapped joybutton " << (int)event.jbutton.button << " pressed" << std::endl; return; } @@ -355,6 +353,78 @@ JoystickKeyboardController::process_event(const SDL_Event& event) } void +JoystickKeyboardController::process_key_event(const SDL_Event& event) +{ + KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym); + + // if console key was pressed: toggle console + if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) { + if (event.type != SDL_KEYDOWN) return; + Console::instance->toggle(); + return; + } + + // if console is open: send key there + if (Console::instance->hasFocus()) { + process_console_key_event(event); + return; + } + + // if menu mode: send key there + if (Menu::current()) { + process_menu_key_event(event); + return; + } + + // default action: update controls + if(key_mapping == keymap.end()) { + log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl; + return; + } + Control control = key_mapping->second; + controls[control] = event.type == SDL_KEYDOWN ? true : false; +} + +void +JoystickKeyboardController::process_console_key_event(const SDL_Event& event) +{ + if (event.type != SDL_KEYDOWN) return; + + switch (event.key.keysym.sym) { + case SDLK_RETURN: + Console::instance->input << std::endl; + break; + case SDLK_BACKSPACE: + Console::instance->backspace(); + break; + case SDLK_TAB: + Console::instance->autocomplete(); + break; + case SDLK_PAGEUP: + Console::instance->scroll(-1); + break; + case SDLK_PAGEDOWN: + Console::instance->scroll(+1); + break; + case SDLK_END: + Console::instance->scroll(+65535); + break; + case SDLK_UP: + Console::instance->show_history(-1); + break; + case SDLK_DOWN: + Console::instance->show_history(+1); + break; + default: + int c = event.key.keysym.unicode; + if ((c >= 32) && (c <= 126)) { + Console::instance->input << (char)c; + } + break; + } +} + +void JoystickKeyboardController::process_menu_key_event(const SDL_Event& event) { // wait for key mode? @@ -510,37 +580,22 @@ JoystickKeyboardController::get_joystick_options_menu() return joystick_options_menu; } -bool -JoystickKeyboardController::check_cheatcode(const std::string& cheatcode) -{ - if(cheatcode.size() > sizeof(last_keys)) { -#ifdef DEBUG - std::cerr << "Cheat Code too long.\n"; -#endif - return false; - } - - for(int i = 0; i < cheatcode.size(); ++i) { - if(last_keys[sizeof(last_keys)-1 - i] != cheatcode[cheatcode.size()-1-i]) - return false; - } - return true; -} - //---------------------------------------------------------------------------- JoystickKeyboardController::KeyboardMenu::KeyboardMenu( JoystickKeyboardController* _controller) : controller(_controller) { - add_label(_("Keyboard Setup")); + add_label(_("Setup Keyboard")); add_hl(); add_controlfield(Controller::UP, _("Up")); add_controlfield(Controller::DOWN, _("Down")); add_controlfield(Controller::LEFT, _("Left")); add_controlfield(Controller::RIGHT, _("Right")); add_controlfield(Controller::JUMP, _("Jump")); - add_controlfield(Controller::ACTION, _("Shoot/Run")); + add_controlfield(Controller::ACTION, _("Action")); + add_controlfield(Controller::PEEK_LEFT, _("Peek Left")); + add_controlfield(Controller::PEEK_RIGHT, _("Peek Right")); add_hl(); add_back(_("Back")); update(); @@ -608,6 +663,10 @@ JoystickKeyboardController::KeyboardMenu::update() controller->reversemap_key(Controller::JUMP))); get_item_by_id((int) Controller::ACTION).change_input(get_key_name( controller->reversemap_key(Controller::ACTION))); + get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name( + controller->reversemap_key(Controller::PEEK_LEFT))); + get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name( + controller->reversemap_key(Controller::PEEK_RIGHT))); } //--------------------------------------------------------------------------- @@ -616,11 +675,17 @@ JoystickKeyboardController::JoystickMenu::JoystickMenu( JoystickKeyboardController* _controller) : controller(_controller) { - add_label(_("Joystick Setup")); + add_label(_("Setup Joystick")); add_hl(); - add_controlfield(Controller::JUMP, _("Jump")); - add_controlfield(Controller::ACTION, _("Shoot/Run")); - add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu")); + if(controller->joysticks.size() > 0) { + add_controlfield(Controller::JUMP, _("Jump")); + add_controlfield(Controller::ACTION, _("Action")); + add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu")); + add_controlfield(Controller::PEEK_LEFT, _("Peek Left")); + add_controlfield(Controller::PEEK_RIGHT, _("Peek Right")); + } else { + add_deactive(-1, _("No Joysticks found")); + } add_hl(); add_back(_("Back")); update(); @@ -651,6 +716,9 @@ JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item) void JoystickKeyboardController::JoystickMenu::update() { + if(controller->joysticks.size() == 0) + return; + // update menu get_item_by_id((int) Controller::JUMP).change_input(get_button_name( controller->reversemap_joybutton(Controller::JUMP))); @@ -658,5 +726,9 @@ JoystickKeyboardController::JoystickMenu::update() controller->reversemap_joybutton(Controller::ACTION))); get_item_by_id((int) Controller::PAUSE_MENU).change_input(get_button_name( controller->reversemap_joybutton(Controller::PAUSE_MENU))); + get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_button_name( + controller->reversemap_joybutton(Controller::PEEK_LEFT))); + get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_button_name( + controller->reversemap_joybutton(Controller::PEEK_RIGHT))); }