1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2010-2015 SuperTuxKart-Team 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 3 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 #ifndef DEVICE_MANAGER_HPP 20 #define DEVICE_MANAGER_HPP 21 22 #include "input/gamepad_config.hpp" 23 #include "input/input_manager.hpp" 24 #include "input/keyboard_config.hpp" 25 #include "states_screens/state_manager.hpp" 26 #include "utils/no_copy.hpp" 27 #include "utils/ptr_vector.hpp" 28 29 #include <irrArray.h> 30 #include <IEventReceiver.h> 31 using namespace irr; 32 33 class DeviceConfig; 34 class InputDevice; 35 class GamePadDevice; 36 class KeyboardDevice; 37 class MultitouchDevice; 38 39 40 enum PlayerAssignMode 41 { 42 NO_ASSIGN, //!< react to all devices 43 DETECT_NEW, //!< notify the manager when an inactive device is being asked to activate with fire 44 ASSIGN //!< only react to assigned devices 45 }; 46 47 /** 48 * \brief This class holds the list of all known devices (ands their configurations), as well as the 49 * list of currently plugged (used) devices. 50 * It thus takes care of finding to which device any given 51 * input belongs, and what action each keypress is bound to, if any (and, since each device is 52 * associated to a player, it also finds which player triggered this action) 53 * These input mapping capabilities should *only* be used through the InputManager, not directly. 54 * 55 * The device manager starts in "no-assign" mode, which means no input configuration is associated 56 * to any player. So all devices will react. This is used in menus before player set-up is done. 57 * Switching back to no-assign mode will also clear anything in devices that was associated with 58 * players in assign mode. 59 * 60 * \ingroup input 61 */ 62 class DeviceManager: public NoCopy 63 { 64 private: 65 66 PtrVector<KeyboardDevice, HOLD> m_keyboards; 67 PtrVector<GamePadDevice, HOLD> m_gamepads; 68 PtrVector<KeyboardConfig, HOLD> m_keyboard_configs; 69 PtrVector<GamepadConfig, HOLD> m_gamepad_configs; 70 MultitouchDevice* m_multitouch_device; 71 72 InputDevice* m_latest_used_device; 73 PlayerAssignMode m_assign_mode; 74 75 76 /** Will be non-null in single-player mode */ 77 StateManager::ActivePlayer* m_single_player; 78 79 /** If this is flag is set the next fire event (if the fire key is not 80 * mapped to anything else) will be mapped to 'select'. This is used 81 * in the kart select GUI to support the old way of adding players by 82 * pressing fire. */ 83 bool m_map_fire_to_select; 84 85 86 InputDevice *mapGamepadInput( Input::InputType type, int deviceID, 87 int btnID, int axisDir, 88 int* value /* inout */, 89 InputManager::InputDriverMode mode, 90 StateManager::ActivePlayer **player /* out */, 91 PlayerAction *action /* out */); 92 InputDevice *mapKeyboardInput(int button_id, 93 InputManager::InputDriverMode mode, 94 StateManager::ActivePlayer **player /* out */, 95 PlayerAction *action /* out */); 96 97 bool load(); 98 void shutdown(); 99 100 public: 101 102 103 DeviceManager(); 104 ~DeviceManager(); 105 106 // ---- Assign mode ---- getAssignMode() const107 PlayerAssignMode getAssignMode() const { return m_assign_mode; } 108 void setAssignMode(const PlayerAssignMode assignMode); 109 110 // ---- Gamepads ---- 111 void addGamepad(GamePadDevice* d); getGamePadAmount() const112 int getGamePadAmount() const { return m_gamepads.size(); } getGamePadConfigAmount() const113 int getGamePadConfigAmount() const { return m_gamepad_configs.size(); } getGamePad(const int i)114 GamePadDevice* getGamePad(const int i) { return m_gamepads.get(i); } getGamepadConfig(const int i)115 GamepadConfig* getGamepadConfig(const int i) { return m_gamepad_configs.get(i); } 116 GamePadDevice* getGamePadFromIrrID(const int i); 117 void clearGamepads(); 118 /** Returns the keyboard that has a binding for this button, or NULL if none */ 119 bool getConfigForGamepad(const int sdl_id, 120 const std::string& name, 121 GamepadConfig **config); 122 123 // ---- Keyboard(s) ---- 124 void addEmptyKeyboard(); 125 void addKeyboard(KeyboardDevice* d); 126 void clearKeyboard(); getKeyboardAmount()127 int getKeyboardAmount() { return m_keyboards.size(); } getActiveKeyboardAmount()128 int getActiveKeyboardAmount() 129 { 130 int active = 0; 131 for (unsigned int i=0;i<m_keyboard_configs.size();i++) 132 { 133 if (m_keyboard_configs[i].isEnabled()) active++; 134 } 135 return active; 136 } getKeyboardConfigAmount() const137 int getKeyboardConfigAmount() const { return m_keyboard_configs.size(); } getKeyboard(const int i)138 KeyboardDevice* getKeyboard(const int i) { return m_keyboards.get(i); } getKeyboardConfig(const int i)139 KeyboardConfig* getKeyboardConfig(const int i) { return m_keyboard_configs.get(i); } 140 KeyboardDevice* getKeyboardFromBtnID(const int btnID); 141 142 // ---- Multitouch device ---- getMultitouchDevice()143 MultitouchDevice* getMultitouchDevice() { return m_multitouch_device; } 144 void clearMultitouchDevices(); 145 void updateMultitouchDevice(); 146 147 148 /** 149 * \brief Delete the given config and removes DeviceManager references to it. 150 */ 151 bool deleteConfig(DeviceConfig* config); 152 153 /** Given some input, finds to which device it belongs and, using the corresponding device object, 154 * maps this input to the corresponding player and game action. 155 * 156 * \return false if player/action could not be set. 157 * \note Special case : can return 'true' but set action to PA_BEFORE_FIRST if the input was used but 158 * is not associated to an action and a player 159 * 160 * \param mode used to determine whether to map game actions or menu actions 161 */ 162 bool translateInput( Input::InputType type, 163 int deviceID, 164 int btnID, 165 int axisDir, 166 int *value /* inout */, 167 InputManager::InputDriverMode mode, 168 StateManager::ActivePlayer** player /* out */, 169 PlayerAction* action /* out */ ); 170 171 void clearLatestUsedDevice(); 172 InputDevice* getLatestUsedDevice(); 173 bool initialize(); 174 void save(); 175 176 // ------------------------------------------------------------------------ 177 /** Returns the active player if there is only a single local player. It 178 * returns NULL if multiplayer is active. */ getSinglePlayer()179 StateManager::ActivePlayer* getSinglePlayer() { return m_single_player; } 180 // ------------------------------------------------------------------------ 181 /** Sets the ActivePlayer if there is only a single local player. p must 182 * be NULL in case of splitscreen. A single player will receive events 183 * from all connected devices. This allows for example a single player 184 * to select a kart with the keyboard, but then use a gamepad for 185 * the actual racing. In splitscreen each player will only receive 186 * events from the device used to connect in the kart selection screen. */ setSinglePlayer(StateManager::ActivePlayer * p)187 void setSinglePlayer(StateManager::ActivePlayer* p) 188 { 189 m_single_player = p; 190 } // setSinglePlayer 191 // ------------------------------------------------------------------------ 192 /** Sets or reset the 'map fire to select' option. 193 */ mapFireToSelect(bool v)194 void mapFireToSelect(bool v) {m_map_fire_to_select = v; } 195 196 }; // DeviceManager 197 198 199 #endif 200