From: Matthias Braun Date: Sun, 1 May 2005 19:50:12 +0000 (+0000) Subject: and more... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=7ad6b7ed9d8d7c76ec7b70e4c27f47bd424b176e;p=supertux.git and more... SVN-Revision: 2382 --- diff --git a/src/control/codecontroller.cpp b/src/control/codecontroller.cpp new file mode 100644 index 000000000..97397a211 --- /dev/null +++ b/src/control/codecontroller.cpp @@ -0,0 +1,44 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#include + +#include "codecontroller.h" + +CodeController::CodeController() +{} + +CodeController::~CodeController() +{} + +void +CodeController::press(Control c, bool pressed) +{ + controls[c] = pressed; +} + +void +CodeController::update() +{ + Controller::update(); + + for(int i = 0; i < CONTROLCOUNT; ++i) + controls[i] = false; +} diff --git a/src/control/codecontroller.h b/src/control/codecontroller.h new file mode 100644 index 000000000..46b2e9ca2 --- /dev/null +++ b/src/control/codecontroller.h @@ -0,0 +1,40 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#ifndef __CODECONTROLLER_H__ +#define __CODECONTROLLER_H__ + +#include "controller.h" + +/** + * This is a dummy controler that doesn't react to any user input but should + * be controlled by code + */ +class CodeController : public Controller +{ +public: + CodeController(); + virtual ~CodeController(); + + void press(Control c, bool pressed = true); + void update(); +}; + +#endif diff --git a/src/control/controller.cpp b/src/control/controller.cpp new file mode 100644 index 000000000..b8eb8d5f4 --- /dev/null +++ b/src/control/controller.cpp @@ -0,0 +1,76 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#include + +#include "controller.h" + +extern Controller* main_controller; + +const char* Controller::controlNames[] = { + "left", + "right", + "up", + "down", + "jump", + "action", + "pause-menu", + "menu-select", + 0 +}; + +Controller::Controller() +{ + for(int i = 0; i < CONTROLCOUNT; ++i) { + controls[i] = false; + oldControls[i] = false; + } +} + +Controller::~Controller() +{} + +void +Controller::reset() +{ + for(int i = 0; i < CONTROLCOUNT; ++i) { + controls[i] = false; + oldControls[i] = false; + } +} + +bool +Controller::hold(Control control) +{ + return controls[control]; +} + +bool +Controller::pressed(Control control) +{ + return oldControls[control] == false && controls[control] == true; +} + +void +Controller::update() +{ + for(int i = 0; i < CONTROLCOUNT; ++i) + oldControls[i] = controls[i]; +} diff --git a/src/control/controller.h b/src/control/controller.h new file mode 100644 index 000000000..50cdb17f1 --- /dev/null +++ b/src/control/controller.h @@ -0,0 +1,60 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#ifndef __CONTROLLER_H__ +#define __CONTROLLER_H__ + +class Controller +{ +public: + static const char* controlNames[]; + + enum Control { + LEFT = 0, + RIGHT, + UP, + DOWN, + JUMP, + ACTION, + PAUSE_MENU, + MENU_SELECT, + + CONTROLCOUNT + }; + + Controller(); + virtual ~Controller(); + + /** returns true if the control is pressed down */ + bool hold(Control control); + /** returns true if the control has just been pressed down this frame */ + bool pressed(Control control); + + virtual void reset(); + virtual void update(); + +protected: + /** current control status */ + bool controls[CONTROLCOUNT]; + /** control status at last frame */ + bool oldControls[CONTROLCOUNT]; +}; + +#endif diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp new file mode 100644 index 000000000..83cbdbced --- /dev/null +++ b/src/control/joystickkeyboardcontroller.cpp @@ -0,0 +1,662 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#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" + +class JoystickKeyboardController::JoystickMenu : public Menu +{ +public: + JoystickMenu(JoystickKeyboardController* controller); + virtual ~JoystickMenu(); + + void update(); + std::string get_button_name(int button); + virtual void menu_action(MenuItem* item); + JoystickKeyboardController* controller; +}; + +class JoystickKeyboardController::KeyboardMenu : public Menu +{ +public: + KeyboardMenu(JoystickKeyboardController* controller); + ~KeyboardMenu(); + + void update(); + std::string get_key_name(SDLKey key); + virtual void menu_action(MenuItem* item); + JoystickKeyboardController* controller; +}; + +JoystickKeyboardController::JoystickKeyboardController() + : wait_for_key(-1), wait_for_joybutton(-1) +{ + 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)); + keymap.insert(std::make_pair(SDLK_UP, UP)); + keymap.insert(std::make_pair(SDLK_DOWN, DOWN)); + keymap.insert(std::make_pair(SDLK_SPACE, JUMP)); + keymap.insert(std::make_pair(SDLK_LCTRL, ACTION)); + keymap.insert(std::make_pair(SDLK_LALT, ACTION)); + keymap.insert(std::make_pair(SDLK_ESCAPE, PAUSE_MENU)); + keymap.insert(std::make_pair(SDLK_p, PAUSE_MENU)); + 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)); + + 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"; + good = false; + } + if(SDL_JoystickNumAxes(joystick) < 2 + && SDL_JoystickNumHats(joystick) == 0) { + std::cerr << "Joystick " << i << " has less than 2 axes and no hat.\n"; + good = false; + } + if(!good) { + SDL_JoystickClose(joystick); + joysticks.push_back(0); + joystick_names.push_back(""); + continue; + } + + if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons) + min_joybuttons = SDL_JoystickNumButtons(joystick); + if(SDL_JoystickNumButtons(joystick) > max_joybuttons) { + max_joybuttons = SDL_JoystickNumButtons(joystick); + } + + joystick_names.push_back(SDL_JoystickName(i)); + joysticks.push_back(joystick); + } + + use_hat = true; + joyaxis_x = 0; + joyaxis_y = 1; + dead_zone_x = 1000; + dead_zone_y = 1000; + + 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)); + } +} + +JoystickKeyboardController::~JoystickKeyboardController() +{ + for(std::vector::iterator i = joysticks.begin(); + i != joysticks.end(); ++i) { + if(*i != 0) + SDL_JoystickClose(*i); + } + + delete key_options_menu; + delete joystick_options_menu; +} + +void +JoystickKeyboardController::read(const lisp::Lisp& lisp) +{ + const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap"); + if(keymap_lisp) { + keymap.clear(); + lisp::ListIterator iter(keymap_lisp); + while(iter.next()) { + if(iter.item() == "map") { + int key = -1; + std::string control; + const lisp::Lisp* map = iter.lisp(); + map->get("key", key); + map->get("control", control); + if(key < SDLK_FIRST || key >= SDLK_LAST) { + std::cerr << "Invalid key '" << key << "' in keymap.\n"; + continue; + } + + int i = 0; + for(i = 0; controlNames[i] != 0; ++i) { + if(control == controlNames[i]) + break; + } + if(controlNames[i] == 0) { + std::cerr << "Invalid control '" << control << "' in keymap.\n"; + continue; + } + keymap.insert(std::make_pair((SDLKey) key, (Control) i)); + } else { + std::cerr << "Invalid lisp element '" << iter.item() << "' in keymap.\n"; + } + } + } + + const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick"); + if(joystick_lisp) { + joystick_lisp->get("use_hat", use_hat); + joystick_lisp->get("axis_x", joyaxis_x); + joystick_lisp->get("axis_y", joyaxis_y); + joystick_lisp->get("dead_zone_x", dead_zone_x); + joystick_lisp->get("dead_zone_y", dead_zone_y); + lisp::ListIterator iter(joystick_lisp); + while(iter.next()) { + if(iter.item() == "map") { + int button = -1; + std::string control; + const lisp::Lisp* map = iter.lisp(); + map->get("button", button); + map->get("control", control); + if(button < 0 || button >= max_joybuttons) { + std::cerr << "Invalid button '" << button << "' in buttonmap.\n"; + continue; + } + + int i = 0; + for(i = 0; controlNames[i] != 0; ++i) { + if(control == controlNames[i]) + break; + } + if(controlNames[i] == 0) { + std::cerr << "Invalid control '" << control << "' in buttonmap.\n"; + continue; + } + reset_joybutton(button, (Control) i); + } + } + } +} + +void +JoystickKeyboardController::write(lisp::Writer& writer) +{ + writer.start_list("keymap"); + for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) { + writer.start_list("map"); + writer.write_int("key", (int) i->first); + writer.write_string("control", controlNames[i->second]); + writer.end_list("map"); + } + writer.end_list("keymap"); + writer.start_list("joystick"); + writer.write_bool("use_hat", use_hat); + writer.write_int("axis_x", joyaxis_x); + writer.write_int("axis_y", joyaxis_y); + writer.write_int("dead_zone_x", dead_zone_x); + writer.write_int("dead_zone_y", dead_zone_y); + for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); + ++i) { + writer.start_list("map"); + writer.write_int("button", i->first); + writer.write_string("control", controlNames[i->second]); + writer.end_list("map"); + } + writer.end_list("joystick"); +} + +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; + } + break; + + case SDL_JOYAXISMOTION: + if(event.jaxis.axis == joyaxis_x) { + if(event.jaxis.value < -dead_zone_x) { + controls[LEFT] = true; + controls[RIGHT] = false; + } else if(event.jaxis.value > dead_zone_x) { + controls[LEFT] = false; + controls[RIGHT] = true; + } else { + controls[LEFT] = false; + controls[RIGHT] = false; + } + } else if(event.jaxis.axis == joyaxis_y) { + if(event.jaxis.value < -dead_zone_y) { + controls[UP] = true; + controls[DOWN] = false; + } else if(event.jaxis.value > dead_zone_y) { + controls[UP] = false; + controls[DOWN] = true; + } else { + controls[UP] = false; + controls[DOWN] = false; + } + } + break; + + case SDL_JOYHATMOTION: + if(!use_hat) + break; + + if(event.jhat.value & SDL_HAT_UP) { + controls[UP] = true; + controls[DOWN] = false; + } + if(event.jhat.value & SDL_HAT_DOWN) { + controls[UP] = false; + controls[DOWN] = true; + } + if(event.jhat.value & SDL_HAT_LEFT) { + controls[LEFT] = true; + controls[RIGHT] = false; + } + if(event.jhat.value & SDL_HAT_RIGHT) { + controls[LEFT] = false; + controls[RIGHT] = true; + } + if(event.jhat.value == SDL_HAT_CENTERED) { + controls[UP] = false; + controls[DOWN] = false; + controls[LEFT] = false; + controls[RIGHT] = false; + } + break; + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + { + if(wait_for_joybutton >= 0) { + if(event.type == SDL_JOYBUTTONUP) + return; + + Control c = (Control) wait_for_joybutton; + reset_joybutton(event.jbutton.button, c); + reset(); + joystick_options_menu->update(); + wait_for_joybutton = -1; + return; + } + + 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 + return; + } + + controls[i->second] = + event.type == SDL_JOYBUTTONDOWN ? true : false; + break; + } + + default: + break; + } +} + +void +JoystickKeyboardController::process_menu_key_event(const SDL_Event& event) +{ + // wait for key mode? + if(wait_for_key >= 0) { + if(event.type == SDL_KEYUP) + return; + + if(event.key.keysym.sym != SDLK_ESCAPE + && event.key.keysym.sym != SDLK_PAUSE) { + reset_key(event.key.keysym.sym, (Control) wait_for_key); + } + reset(); + key_options_menu->update(); + wait_for_key = -1; + return; + } + if(wait_for_joybutton >= 0) { + if(event.key.keysym.sym == SDLK_ESCAPE) { + reset(); + joystick_options_menu->update(); + wait_for_joybutton = -1; + } + return; + } + + Control control; + /* we use default keys when the menu is open (to avoid problems when + * redefining keys to invalid settings + */ + switch(event.key.keysym.sym) { + case SDLK_UP: + control = UP; + break; + case SDLK_DOWN: + control = DOWN; + break; + case SDLK_LEFT: + control = LEFT; + break; + case SDLK_RIGHT: + control = RIGHT; + break; + case SDLK_SPACE: + case SDLK_RETURN: + case SDLK_KP_ENTER: + control = MENU_SELECT; + break; + case SDLK_ESCAPE: + case SDLK_PAUSE: + control = PAUSE_MENU; + break; + default: + return; + break; + } + + controls[control] = event.type == SDL_KEYDOWN ? true : false; +} + +void +JoystickKeyboardController::reset_joybutton(int button, Control control) +{ + // remove all previous mappings for that control and for that key + for(ButtonMap::iterator i = joy_button_map.begin(); + i != joy_button_map.end(); /* no ++i */) { + if(i->second == control) { + ButtonMap::iterator e = i; + ++i; + joy_button_map.erase(e); + } else { + ++i; + } + } + ButtonMap::iterator i = joy_button_map.find(button); + if(i != joy_button_map.end()) + joy_button_map.erase(i); + + // add new mapping + joy_button_map.insert(std::make_pair(button, control)); + + // map all unused buttons to MENU_SELECT + for(int b = 0; b < max_joybuttons; ++b) { + ButtonMap::iterator i = joy_button_map.find(b); + if(i != joy_button_map.end()) + continue; + + joy_button_map.insert(std::make_pair(b, MENU_SELECT)); + } +} + +void +JoystickKeyboardController::reset_key(SDLKey key, Control control) +{ + // remove all previous mappings for that control and for that key + for(KeyMap::iterator i = keymap.begin(); + i != keymap.end(); /* no ++i */) { + if(i->second == control) { + KeyMap::iterator e = i; + ++i; + keymap.erase(e); + } else { + ++i; + } + } + KeyMap::iterator i = keymap.find(key); + if(i != keymap.end()) + keymap.erase(i); + + // add new mapping + keymap.insert(std::make_pair(key, control)); +} + +SDLKey +JoystickKeyboardController::reversemap_key(Control c) +{ + for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) { + if(i->second == c) + return i->first; + } + + return SDLK_UNKNOWN; +} + +int +JoystickKeyboardController::reversemap_joybutton(Control c) +{ + for(ButtonMap::iterator i = joy_button_map.begin(); + i != joy_button_map.end(); ++i) { + if(i->second == c) + return i->first; + } + + return -1; +} + +Menu* +JoystickKeyboardController::get_key_options_menu() +{ + if(key_options_menu == 0) { + key_options_menu = new KeyboardMenu(this); + } + + return key_options_menu; +} + +Menu* +JoystickKeyboardController::get_joystick_options_menu() +{ + if(joystick_options_menu == 0) { + joystick_options_menu = new JoystickMenu(this); + } + + 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_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_hl(); + add_back(_("Back")); + update(); +} + +JoystickKeyboardController::KeyboardMenu::~KeyboardMenu() +{} + +std::string +JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key) +{ + switch(key) { + case SDLK_UNKNOWN: + return _("None"); + case SDLK_UP: + return _("Up cursor"); + case SDLK_DOWN: + return _("Down cursor"); + case SDLK_LEFT: + return _("Left cursor"); + case SDLK_RIGHT: + return _("Right cursor"); + case SDLK_RETURN: + return _("Return"); + case SDLK_SPACE: + return _("Space"); + case SDLK_RSHIFT: + return _("Right Shift"); + case SDLK_LSHIFT: + return _("Left Shift"); + case SDLK_RCTRL: + return _("Right Control"); + case SDLK_LCTRL: + return _("Left Control"); + case SDLK_RALT: + return _("Right Alt"); + case SDLK_LALT: + return _("Left Alt"); + default: + return SDL_GetKeyName((SDLKey) key); + } +} + +void +JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item) +{ + assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT); + item->change_input(_("Press Key")); + controller->wait_for_key = item->id; +} + +void +JoystickKeyboardController::KeyboardMenu::update() +{ + // update menu + get_item_by_id((int) Controller::UP).change_input(get_key_name( + controller->reversemap_key(Controller::UP))); + get_item_by_id((int) Controller::DOWN).change_input(get_key_name( + controller->reversemap_key(Controller::DOWN))); + get_item_by_id((int) Controller::LEFT).change_input(get_key_name( + controller->reversemap_key(Controller::LEFT))); + get_item_by_id((int) Controller::RIGHT).change_input(get_key_name( + controller->reversemap_key(Controller::RIGHT))); + get_item_by_id((int) Controller::JUMP).change_input(get_key_name( + controller->reversemap_key(Controller::JUMP))); + get_item_by_id((int) Controller::ACTION).change_input(get_key_name( + controller->reversemap_key(Controller::ACTION))); +} + +//--------------------------------------------------------------------------- + +JoystickKeyboardController::JoystickMenu::JoystickMenu( + JoystickKeyboardController* _controller) + : controller(_controller) +{ + add_label(_("Joystick Setup")); + add_hl(); + add_controlfield(Controller::JUMP, _("Jump")); + add_controlfield(Controller::ACTION, _("Shoot/Run")); + add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu")); + add_hl(); + add_back(_("Back")); + update(); +} + +JoystickKeyboardController::JoystickMenu::~JoystickMenu() +{} + +std::string +JoystickKeyboardController::JoystickMenu::get_button_name(int button) +{ + if(button < 0) + return _("None"); + + std::ostringstream name; + name << "Button " << button; + return name.str(); +} + +void +JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item) +{ + assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT); + item->change_input(_("Press Button")); + controller->wait_for_joybutton = item->id; +} + +void +JoystickKeyboardController::JoystickMenu::update() +{ + // update menu + get_item_by_id((int) Controller::JUMP).change_input(get_button_name( + controller->reversemap_joybutton(Controller::JUMP))); + get_item_by_id((int) Controller::ACTION).change_input(get_button_name( + controller->reversemap_joybutton(Controller::ACTION))); + get_item_by_id((int) Controller::PAUSE_MENU).change_input(get_button_name( + controller->reversemap_joybutton(Controller::PAUSE_MENU))); +} + diff --git a/src/control/joystickkeyboardcontroller.h b/src/control/joystickkeyboardcontroller.h new file mode 100644 index 000000000..93fe1ac9d --- /dev/null +++ b/src/control/joystickkeyboardcontroller.h @@ -0,0 +1,107 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2005 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// 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. + +#ifndef __JOYSTICKKEYBOARDCONTROLLER_H__ +#define __JOYSTICKKEYBOARDCONTROLLER_H__ + +#include "controller.h" +#include "lisp/lisp.h" +#include "lisp/writer.h" +#include +#include +#include + +class Menu; + +class JoystickKeyboardController : public Controller +{ +public: + JoystickKeyboardController(); + virtual ~JoystickKeyboardController(); + + /** Process an SDL Event and return true if the event has been used + */ + void process_event(const SDL_Event& event); + + void write(lisp::Writer& writer); + void read(const lisp::Lisp& lisp); + bool check_cheatcode(const std::string& cheatcode); + + Menu* get_key_options_menu(); + Menu* get_joystick_options_menu(); + +private: + void process_menu_key_event(const SDL_Event& event); + + typedef std::map KeyMap; + KeyMap keymap; + + int joystick_count; + std::vector joysticks; + std::vector joystick_names; + + typedef std::map ButtonMap; + ButtonMap joy_button_map; + std::string name; + bool use_hat; + int joyaxis_x; + int joyaxis_y; + int dead_zone_x; + int dead_zone_y; + /// the number of buttons all joysticks have + int min_joybuttons; + /// the max number of buttons a joystick has + int max_joybuttons; + + enum { + MNID_KEY_UP, + MNID_KEY_DOWN, + MNID_KEY_LEFT, + MNID_KEY_RIGHT, + MNID_KEY_JUMP, + MNID_KEY_ACTION + }; + enum { + MNID_JS_JUMP, + MNID_JS_ACTION, + MNID_JS_MENU, + MNID_JS_PAUSE + }; + SDLKey reversemap_key(Control c); + int reversemap_joybutton(Control c); + void reset_joybutton(int button, Control c); + void reset_key(SDLKey key, Control c); + + int wait_for_key; + int wait_for_joybutton; + + class KeyboardMenu; + class JoystickMenu; + + KeyboardMenu* key_options_menu; + JoystickMenu* joystick_options_menu; + friend class KeyboardMenu; + friend class JoystickMenu; + + char last_keys[20]; +}; + +#endif + diff --git a/src/control/semantic.cache b/src/control/semantic.cache new file mode 100644 index 000000000..c9eefee02 --- /dev/null +++ b/src/control/semantic.cache @@ -0,0 +1,59 @@ +;; Object semantic.cache +;; SEMANTICDB Tags save file +(semanticdb-project-database "semantic.cache" + :file "semantic.cache" + :tables (list + (semanticdb-table "controller.h" + :file "controller.h" + :pointmax 703 + :major-mode 'c++-mode + :tokens '(("__CONTROLLER_H__" variable nil nil ((const . t)) nil nil [26 57]) ("Controller" type "class" (("public" label ((reparse-symbol . classsubparts)) [71 78]) ("controlNames" variable "char" nil ((const . t) (typemodifiers "static") (dereference . 1) (pointer . 1)) nil nil [81 115]) ("Control" type "enum" (("LEFT" variable "int" (147 148) ((const . t)) nil ((reparse-symbol . enumsubparts)) [140 148]) ("RIGHT" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [154 160]) ("UP" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [165 168]) ("DOWN" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [173 178]) ("JUMP" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [183 188]) ("ACTION" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [193 200]) ("PAUSE_MENU" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [205 216]) ("MENU_SELECT" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [221 233]) ("CONTROLCOUNT" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [243 259])) nil nil nil ((reparse-symbol . classsubparts)) [121 260]) ("Controller" function ("Controller" type "class") nil ((constructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [264 277]) ("Controller" function "void" nil ((typemodifiers "virtual") (destructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [280 302]) ("hold" function ("bool" type "class") (("control" variable ("Control" type "class") nil nil nil nil [369 385])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [359 386]) ("pressed" function ("bool" type "class") (("control" variable ("Control" type "class") nil nil nil nil [477 493])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [464 494]) ("reset" function ("void") nil ((typemodifiers "virtual") (prototype . t)) nil ((reparse-symbol . classsubparts)) [498 519]) ("update" function ("void") nil ((typemodifiers "virtual") (prototype . t)) nil ((reparse-symbol . classsubparts)) [522 544]) ("protected" label ((reparse-symbol . classsubparts)) [546 556]) ("controls" variable ("bool" type "class") nil ((dereference . 1)) nil nil [591 619]) ("oldControls" variable ("bool" type "class") nil ((dereference . 1)) nil nil [660 691])) nil nil nil nil [52 694])) + :unmatched-syntax 'nil + ) + (semanticdb-table "joystickkeyboardcontroller.h" + :file "joystickkeyboardcontroller.h" + :pointmax 1799 + :major-mode 'c++-mode + :tokens '(("__JOYSTICKKEYBOARDCONTROLLER_H__" variable nil nil ((const . t)) nil nil [42 85]) ("controller.h" include nil nil nil [84 107]) ("lisp/lisp.h" include nil nil nil [108 130]) ("lisp/writer.h" include nil nil nil [131 155]) ("SDL.h" include t nil nil [156 172]) ("string" include t nil nil [173 190]) ("map" include t nil nil [191 205]) ("Menu" type "class" nil nil nil nil nil [207 218]) ("JoystickKeyboardController" type "class" (("public" label ((reparse-symbol . classsubparts)) [275 282]) ("JoystickKeyboardController" function ("JoystickKeyboardController" type "class") nil ((constructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [285 314]) ("JoystickKeyboardController" function "void" nil ((typemodifiers "virtual") (destructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [317 355]) ("process_event" function ("void") (("event" variable ("SDL_Event" type "class") nil ((const . t)) nil nil [454 477])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [435 478]) ("write" function ("void") (("writer" variable ("lisp::Writer" type "class") nil nil nil nil [493 514])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [482 515]) ("read" function ("void") (("lisp" variable ("lisp::Lisp" type "class") nil ((const . t)) nil nil [528 551])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [518 552]) ("get_key_options_menu" function ("Menu" type "class") nil ((pointer . 1) (prototype . t)) nil ((reparse-symbol . classsubparts)) [556 585]) ("get_joystick_options_menu" function ("Menu" type "class") nil ((pointer . 1) (prototype . t)) nil ((reparse-symbol . classsubparts)) [588 622]) ("private" label ((reparse-symbol . classsubparts)) [624 632]) ("process_menu_key_event" function ("void") (("event" variable ("SDL_Event" type "class") nil ((const . t)) nil nil [663 686])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [635 687]) ("KeyMap" type "typedef" nil ("std::map") ((typedef "std::map" type "class")) nil nil [693 734]) ("keymap" variable ("KeyMap" type "class") nil nil nil nil [737 751]) ("joystick_count" variable "int" nil nil nil nil [755 774]) ("joysticks" variable ("std::vector" type "class") nil nil nil nil [777 814]) ("joystick_names" variable ("std::vector" type "class") nil nil nil nil [817 857]) ("ButtonMap" type "typedef" nil ("std::map") ((typedef "std::map" type "class")) nil nil [865 906]) ("joy_button_map" variable ("ButtonMap" type "class") nil nil nil nil [909 934]) ("name" variable ("std::string" type "class") nil nil nil nil [937 954]) ("use_hat" variable ("bool" type "class") nil nil nil nil [957 970]) ("joyaxis_x" variable "int" nil nil nil nil [973 987]) ("joyaxis_y" variable "int" nil nil nil nil [990 1004]) ("dead_zone_x" variable "int" nil nil nil nil [1007 1023]) ("dead_zone_y" variable "int" nil nil nil nil [1026 1042]) ("min_joybuttons" variable "int" nil nil nil nil [1092 1111]) ("max_joybuttons" variable "int" nil nil nil nil [1161 1180]) ("" type "enum" (("MNID_KEY_UP" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1195 1207]) ("MNID_KEY_DOWN" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1212 1226]) ("MNID_KEY_LEFT" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1231 1245]) ("MNID_KEY_RIGHT" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1250 1265]) ("MNID_KEY_JUMP" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1270 1284]) ("MNID_KEY_ACTION" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1289 1308])) nil nil nil ((reparse-symbol . classsubparts)) [1184 1309]) ("" type "enum" (("MNID_JS_JUMP" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1323 1336]) ("MNID_JS_ACTION" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1341 1356]) ("MNID_JS_MENU" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1361 1374]) ("MNID_JS_PAUSE" variable "int" nil ((const . t)) nil ((reparse-symbol . enumsubparts)) [1379 1396])) nil nil nil ((reparse-symbol . classsubparts)) [1312 1397]) ("reversemap_key" function ("SDLKey" type "class") (("c" variable ("Control" type "class") nil nil nil nil [1422 1432])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [1400 1433]) ("reversemap_joybutton" function ("int") (("c" variable ("Control" type "class") nil nil nil nil [1461 1471])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [1436 1472]) ("reset_joybutton" function ("void") (("button" variable "int" nil nil nil nil [1496 1507]) ("c" variable ("Control" type "class") nil nil nil nil [1508 1518])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [1475 1519]) ("reset_key" function ("void") (("key" variable ("SDLKey" type "class") nil nil nil nil [1537 1548]) ("c" variable ("Control" type "class") nil nil nil nil [1549 1559])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [1522 1560]) ("wait_for_key" variable "int" nil nil nil nil [1564 1581]) ("wait_for_joybutton" variable "int" nil nil nil nil [1584 1607]) ("KeyboardMenu" type "class" nil nil nil nil ((reparse-symbol . classsubparts)) [1611 1630]) ("JoystickMenu" type "class" nil nil nil nil ((reparse-symbol . classsubparts)) [1633 1652]) ("key_options_menu" variable ("KeyboardMenu" type "class") nil ((pointer . 1)) nil nil [1658 1689]) ("joystick_options_menu" variable ("JoystickMenu" type "class") nil ((pointer . 1)) nil nil [1692 1728]) ("KeyboardMenu" type "class" nil nil nil nil ((reparse-symbol . classsubparts)) [1738 1757]) ("JoystickMenu" type "class" nil nil nil nil ((reparse-symbol . classsubparts)) [1767 1786])) (("Controller")) nil nil nil [220 1789])) + :unmatched-syntax 'nil + ) + (semanticdb-table "joystickkeyboardcontroller.cpp" + :file "joystickkeyboardcontroller.cpp" + :pointmax 16908 + :major-mode 'c++-mode + :tokens '(("config.h" include t nil nil [1 20]) ("sstream" include t nil nil [22 40]) ("joystickkeyboardcontroller.h" include nil nil nil [41 80]) ("gui/menu.h" include nil nil nil [81 102]) ("app/gettext.h" include nil nil nil [103 127]) ("lisp/lisp.h" include nil nil nil [128 150]) ("lisp/list_iterator.h" include nil nil nil [151 182]) ("JoystickKeyboardController" function ("JoystickKeyboardController" type "class") nil ((parent . "JoystickKeyboardController") (constructor . t)) nil nil [785 3226]) ("JoystickKeyboardController" function "void" nil ((parent . "JoystickKeyboardController") (destructor . t)) nil nil [3228 3499]) ("read" function ("void") (("lisp" variable ("lisp::Lisp" type "class") nil ((const . t)) nil nil [3539 3562])) ((parent . "JoystickKeyboardController")) nil nil [3501 5764]) ("write" function ("void") (("writer" variable ("lisp::Writer" type "class") nil nil nil nil [5805 5826])) ((parent . "JoystickKeyboardController")) nil nil [5766 6671]) ("process_event" function ("void") (("event" variable ("SDL_Event" type "class") nil ((const . t)) nil nil [6720 6743])) ((parent . "JoystickKeyboardController")) nil nil [6673 9532]) ("process_menu_key_event" function ("void") (("event" variable ("SDL_Event" type "class") nil ((const . t)) nil nil [9590 9613])) ((parent . "JoystickKeyboardController")) nil nil [9534 10775]) ("reset_joybutton" function ("void") (("button" variable "int" nil nil nil nil [10826 10837]) ("control" variable ("Control" type "class") nil nil nil nil [10838 10854])) ((parent . "JoystickKeyboardController")) nil nil [10777 11619]) ("reset_key" function ("void") (("key" variable ("SDLKey" type "class") nil nil nil nil [11664 11675]) ("control" variable ("Control" type "class") nil nil nil nil [11676 11692])) ((parent . "JoystickKeyboardController")) nil nil [11621 12132]) ("reversemap_key" function ("SDLKey" type "class") (("c" variable ("Control" type "class") nil nil nil nil [12184 12194])) ((parent . "JoystickKeyboardController")) nil nil [12134 12341]) ("reversemap_joybutton" function ("int") (("c" variable ("Control" type "class") nil nil nil nil [12396 12406])) ((parent . "JoystickKeyboardController")) nil nil [12343 12568]) ("get_key_options_menu" function ("Menu" type "class") nil ((parent . "JoystickKeyboardController") (pointer . 1)) nil nil [12570 12739]) ("get_joystick_options_menu" function ("Menu" type "class") nil ((parent . "JoystickKeyboardController") (pointer . 1)) nil nil [12741 12930]) ("KeyboardMenu" function "int" (("_controller" variable ("JoystickKeyboardController" type "class") nil ((pointer . 1)) nil nil [13072 13112])) ((parent . "JoystickKeyboardController::KeyboardMenu")) nil nil [13012 13558]) ("KeyboardMenu" function "void" nil ((parent . "JoystickKeyboardController::KeyboardMenu") (destructor . t)) nil nil [13560 13620]) ("get_key_name" function ("std::string" type "class") (("key" variable ("SDLKey" type "class") nil nil nil nil [13689 13700])) ((parent . "JoystickKeyboardController::KeyboardMenu")) nil nil [13622 14432]) ("menu_action" function ("void") (("item" variable ("MenuItem" type "class") nil ((pointer . 1)) nil nil [14493 14508])) ((parent . "JoystickKeyboardController::KeyboardMenu")) nil nil [14434 14653]) ("update" function ("void") nil ((parent . "JoystickKeyboardController::KeyboardMenu")) nil nil [14655 15453]) ("JoystickMenu" function "int" (("_controller" variable ("JoystickKeyboardController" type "class") nil ((pointer . 1)) nil nil [15592 15632])) ((parent . "JoystickKeyboardController::JoystickMenu")) nil nil [15534 15923]) ("JoystickMenu" function "void" nil ((parent . "JoystickKeyboardController::JoystickMenu") (destructor . t)) nil nil [15925 15985]) ("get_button_name" function ("std::string" type "class") (("button" variable "int" nil nil nil nil [16057 16068])) ((parent . "JoystickKeyboardController::JoystickMenu")) nil nil [15987 16195]) ("menu_action" function ("void") (("item" variable ("MenuItem" type "class") nil ((pointer . 1)) nil nil [16256 16271])) ((parent . "JoystickKeyboardController::JoystickMenu")) nil nil [16197 16425]) ("update" function ("void") nil ((parent . "JoystickKeyboardController::JoystickMenu")) nil nil [16427 16906])) + :unmatched-syntax '((punctuation 780 . 781) (semantic-list 550 . 780) (symbol 545 . 549) (PUBLIC 538 . 544) (punctuation 536 . 537) (symbol 523 . 535) (punctuation 522 . 523) (punctuation 521 . 522) (symbol 495 . 521) (CLASS 489 . 494) (punctuation 486 . 487) (semantic-list 245 . 486) (symbol 240 . 244) (PUBLIC 233 . 239) (punctuation 231 . 232) (symbol 218 . 230) (punctuation 217 . 218) (punctuation 216 . 217) (symbol 190 . 216) (CLASS 184 . 189)) + ) + (semanticdb-table "codecontroller.h" + :file "codecontroller.h" + :pointmax 354 + :major-mode 'c++-mode + :tokens '(("__CODECONTROLLER_H__" variable nil nil ((const . t)) nil nil [30 61]) ("controller.h" include nil nil nil [60 83]) ("CodeController" type "class" (("public" label ((reparse-symbol . classsubparts)) [239 246]) ("CodeController" function ("CodeController" type "class") nil ((constructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [249 266]) ("CodeController" function "void" nil ((typemodifiers "virtual") (destructor . t) (prototype . t)) nil ((reparse-symbol . classsubparts)) [269 295]) ("press" function ("void") (("c" variable ("Control" type "class") nil nil nil nil [310 320]) ("pressed" variable ("bool" type "class") "true)" nil nil nil [321 341])) ((prototype . t)) nil ((reparse-symbol . classsubparts)) [299 342])) (("Controller")) nil nil nil [195 345])) + :unmatched-syntax 'nil + ) + (semanticdb-table "codecontroller.cpp" + :file "codecontroller.cpp" + :pointmax 207 + :major-mode 'c++-mode + :tokens '(("config.h" include t nil nil [1 20]) ("codecontroller.h" include nil nil nil [22 49]) ("CodeController" function ("CodeController" type "class") nil ((parent . "CodeController") (constructor . t)) nil nil [51 86]) ("CodeController" function "void" nil ((parent . "CodeController") (destructor . t)) nil nil [88 124]) ("press" function ("void") (("c" variable ("Control" type "class") nil nil nil nil [153 163]) ("pressed" variable ("bool" type "class") nil nil nil nil [164 177])) ((parent . "CodeController")) nil nil [126 206])) + :unmatched-syntax 'nil + ) + (semanticdb-table "controller.cpp" + :file "controller.cpp" + :pointmax 809 + :major-mode 'c++-mode + :tokens '(("config.h" include t nil nil [1 20]) ("controller.h" include nil nil nil [22 45]) ("main_controller" variable ("Controller" type "class") nil ((typemodifiers "extern") (pointer . 1)) nil nil [47 82]) ("Controller::controlNames" variable "char" "{ + \"left\", + \"right\", + \"up\", + \"down\", + \"jump\", + \"action\", + \"pause-menu\", + \"menu-select\", + 0 +}" ((const . t) (dereference . 1) (pointer . 1)) nil nil [84 227]) ("Controller" function ("Controller" type "class") nil ((parent . "Controller") (constructor . t)) nil nil [229 356]) ("Controller" function "void" nil ((parent . "Controller") (destructor . t)) nil nil [358 386]) ("reset" function ("void") nil ((parent . "Controller")) nil nil [388 515]) ("hold" function ("bool" type "class") (("control" variable ("Control" type "class") nil nil nil nil [539 555])) ((parent . "Controller")) nil nil [517 587]) ("pressed" function ("bool" type "class") (("control" variable ("Control" type "class") nil nil nil nil [614 630])) ((parent . "Controller")) nil nil [589 703]) ("update" function ("void") nil ((parent . "Controller")) nil nil [705 808])) + :unmatched-syntax 'nil + ) + ) + )