Changeset 3327 for code/trunk/src/core/input
- Timestamp:
- Jul 19, 2009, 5:31:02 PM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 7 deleted
- 16 edited
- 12 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/core4 merged: 3269,3271-3275,3278,3285,3290-3294,3310
- Property svn:mergeinfo changed
-
code/trunk/src/core/input/Button.cc
r3280 r3327 60 60 nCommands_[2]=0; 61 61 this->configContainer_ = 0; 62 clear();63 62 } 64 63 … … 83 82 commands_[j] = 0; 84 83 nCommands_[j] = 0; 85 }86 else87 {88 commands_[j] = 0;89 84 } 90 85 } -
code/trunk/src/core/input/Button.h
r3280 r3327 36 36 #define _Button_H__ 37 37 38 #include " core/CorePrereqs.h"38 #include "InputPrereqs.h" 39 39 40 40 #include <string> -
code/trunk/src/core/input/CMakeLists.txt
r3196 r3327 1 1 ADD_SOURCE_FILES(CORE_SRC_FILES 2 2 Button.cc 3 ExtendedInputState.cc4 3 HalfAxis.cc 5 4 InputBuffer.cc 6 5 InputCommands.cc 7 6 InputManager.cc 8 JoyStickDeviceNumberListener.cc 7 InputState.cc 8 JoyStick.cc 9 JoyStickQuantityListener.cc 9 10 KeyBinder.cc 11 Keyboard.cc 10 12 KeyDetector.cc 11 SimpleInputState.cc13 Mouse.cc 12 14 ) -
code/trunk/src/core/input/HalfAxis.cc
r1887 r3327 49 49 nParamCommands_ = 0; 50 50 } 51 else52 {53 nParamCommands_ = 0; nParamCommands_ = 0;54 }55 51 } 56 52 -
code/trunk/src/core/input/HalfAxis.h
r3196 r3327 36 36 #define _HalfAxis_H__ 37 37 38 #include " core/CorePrereqs.h"38 #include "InputPrereqs.h" 39 39 40 40 #include "Button.h" -
code/trunk/src/core/input/InputBuffer.cc
r3301 r3327 184 184 185 185 186 void InputBuffer::processKey(const KeyEvent &evt)187 { 188 if (evt.isModifierDown(KeyboardModifier::Alt) && evt. key== KeyCode::Tab)186 void InputBuffer::processKey(const KeyEvent& evt) 187 { 188 if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab) 189 189 return; 190 190 191 191 for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 192 192 { 193 if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt. key))193 if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode())) 194 194 (*it)->callFunction(); 195 195 } … … 197 197 if (evt.isModifierDown(KeyboardModifier::Ctrl)) 198 198 { 199 if (evt. key== KeyCode::V)199 if (evt.getKeyCode() == KeyCode::V) 200 200 this->insert(fromClipboard()); 201 else if (evt. key== KeyCode::C)201 else if (evt.getKeyCode() == KeyCode::C) 202 202 toClipboard(this->buffer_); 203 else if (evt. key== KeyCode::X)203 else if (evt.getKeyCode() == KeyCode::X) 204 204 { 205 205 toClipboard(this->buffer_); … … 209 209 else if (evt.isModifierDown(KeyboardModifier::Shift)) 210 210 { 211 if (evt. key== KeyCode::Insert)211 if (evt.getKeyCode() == KeyCode::Insert) 212 212 this->insert(fromClipboard()); 213 else if (evt. key== KeyCode::Delete)213 else if (evt.getKeyCode() == KeyCode::Delete) 214 214 { 215 215 toClipboard(this->buffer_); … … 218 218 } 219 219 220 this->insert(static_cast<char>(evt. text));220 this->insert(static_cast<char>(evt.getText())); 221 221 } 222 222 … … 225 225 @param dt Delta time 226 226 */ 227 void InputBuffer:: updateInput(float dt)227 void InputBuffer::keyboardUpdated(float dt) 228 228 { 229 229 timeSinceKeyPressed_ += dt; … … 239 239 } 240 240 241 void InputBuffer:: keyPressed(const KeyEvent &evt)242 { 243 lastKey_ = evt. key;241 void InputBuffer::buttonPressed(const KeyEvent& evt) 242 { 243 lastKey_ = evt.getKeyCode(); 244 244 timeSinceKeyPressed_ = 0.0; 245 245 timeSinceKeyRepeated_ = keyRepeatDeleay_; … … 249 249 } 250 250 251 void InputBuffer:: keyHeld(const KeyEvent& evt)252 { 253 if (evt. key== lastKey_)251 void InputBuffer::buttonHeld(const KeyEvent& evt) 252 { 253 if (evt.getKeyCode() == lastKey_) 254 254 { 255 255 while (keysToRepeat_) -
code/trunk/src/core/input/InputBuffer.h
r3196 r3327 30 30 #define _InputBuffer_H__ 31 31 32 #include " core/CorePrereqs.h"32 #include "InputPrereqs.h" 33 33 34 34 #include <list> 35 35 #include <string> 36 36 #include "core/OrxonoxClass.h" 37 #include "Input Interfaces.h"37 #include "InputHandler.h" 38 38 39 39 namespace orxonox … … 74 74 }; 75 75 76 class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass76 class _CoreExport InputBuffer : public InputHandler, public OrxonoxClass 77 77 { 78 78 public: … … 165 165 bool charIsAllowed(const char& input); 166 166 167 void keyPressed (const KeyEvent& evt); 168 void keyReleased(const KeyEvent& evt) { } 169 void keyHeld (const KeyEvent& evt); 170 void processKey (const KeyEvent &e); 167 void buttonPressed(const KeyEvent& evt); 168 void buttonHeld (const KeyEvent& evt); 169 void processKey (const KeyEvent& evt); 171 170 172 void updateInput(float dt); 173 void updateKey(float dt) { } 171 void keyboardUpdated(float dt); 174 172 175 173 std::string buffer_; -
code/trunk/src/core/input/InputCommands.h
r2087 r3327 36 36 #define _InputCommands_H__ 37 37 38 #include " core/CorePrereqs.h"38 #include "InputPrereqs.h" 39 39 #include "core/CommandEvaluation.h" 40 40 -
code/trunk/src/core/input/InputDevice.h
r3276 r3327 29 29 /** 30 30 @file 31 @brief 31 @brief 32 Implementation of InputDevice and InputDeviceTemplated 32 33 */ 33 34 … … 38 39 39 40 #include <vector> 40 #include <boost/foreach.hpp>41 41 #include <ois/OISInputManager.h> 42 42 43 43 #include "util/Debug.h" 44 44 #include "core/Clock.h" 45 // TODO: Try to remove this46 #include "InputManager.h"47 45 #include "InputState.h" 48 46 … … 51 49 /** 52 50 @brief 51 Abstract base class for all input devices (mouse, keyboard and joy sticks). 52 53 It provides common virtual functions to be used by the InputManager. 53 54 */ 54 55 class InputDevice 55 56 { 56 friend class InputManager;57 58 57 public: 59 InputDevice(unsigned int id) : bCalibrating_(false), id_(id) { } 58 //! Only resets the members 59 InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { } 60 60 virtual ~InputDevice() { } 61 virtual std::string getClassName() = 0; 61 //! Returns the device class (derived) name as string 62 virtual std::string getClassName() const = 0; 63 //! Updates the device which should in turn distribute events 62 64 virtual void update(const Clock& time) = 0; 65 //! Clear all button related buffers 63 66 virtual void clearBuffers() = 0; 64 67 68 //! Start calibrating (only useful for joy sticks) 65 69 void startCalibration() 66 70 { … … 69 73 } 70 74 75 //! Stop calibrating and evaluate the data (only useful for joy sticks) 71 76 void stopCalibration() 72 77 { … … 75 80 } 76 81 77 unsigned int getDeviceID() { return this->id_; } 82 //! Returns a reference to the internal input state vector. Use with care! 83 std::vector<InputState*>& getStateListRef() { return this->inputStates_; } 84 //! Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard) 85 unsigned int getDeviceID() const { return this->deviceID_; } 86 //! Tells whether the device is in calibration mode 87 bool isCalibrating() const { return bCalibrating_; } 78 88 79 89 protected: 90 //! To be ovrridden by the subclass 80 91 virtual void calibrationStarted() { } 92 //! To be ovrridden by the subclass 81 93 virtual void calibrationStopped() { } 82 bool isCalibrating() { return bCalibrating_; } 83 84 // InputState handling 94 95 //! List of all input states that receive events from this device 85 96 std::vector<InputState*> inputStates_; 86 97 87 98 private: 88 InputDevice(const InputDevice& rhs); 89 90 std::vector<InputState*>& getStateListRef() 91 { 92 return this->inputStates_; 93 } 94 95 bool bCalibrating_; 96 const unsigned int id_; 99 InputDevice(const InputDevice& rhs); //!< Don't use! 100 101 bool bCalibrating_; //!< Whether the device is in calibration mode 102 const unsigned int deviceID_; //!< ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard) 97 103 }; 98 104 99 105 /** 100 106 @brief 107 Heavily templated base class for all three input devices. 108 109 The purpose of this class is not to provide an interface but rather 110 to reduce code redundancy. This concerns device creation and destruction 111 as well as common code for button events (press, release, hold). 112 113 In order to derive from this class you have to supply it with a struct 114 as template parameter that contains the necessary type traits. 101 115 */ 102 116 template <class Traits> … … 110 124 111 125 public: 112 InputDeviceTemplated(unsigned int id) 126 //! Creates the OIS device 127 InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager) 113 128 : InputDevice(id) 114 { 115 OIS::InputManager* system = InputManager::getInstance().getInputSystem(); 116 oisDevice_ = static_cast<OISDeviceClass*>(system->createInputObject(OISDeviceValue, true)); 129 , oisInputManager_(oisInputManager) 130 { 131 oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true)); 132 // Note: after the static_cast here, the casted this pointer becomes 133 // invalid right until the subclass has been constructed! 117 134 oisDevice_->setEventCallback(static_cast<DeviceClass*>(this)); 118 135 COUT(4) << "Instantiated a " << this->getClassName() << std::endl; 119 136 } 120 137 138 //! Destroys the OIS device 121 139 virtual ~InputDeviceTemplated() 122 140 { 123 141 try 124 142 { 125 InputManager::getInstance().getInputSystem()->destroyInputObject(oisDevice_);143 oisInputManager_->destroyInputObject(oisDevice_); 126 144 } 127 145 catch (...) … … 131 149 } 132 150 133 OISDeviceClass* getOISDevice() 134 { 135 return this->oisDevice_; 136 } 137 138 std::string getClassName() 139 { 140 return InputDeviceNames::values[OISDeviceValue]; 141 } 142 151 //! Captures OIS events (which then get distributed to the derived class) and creates the button held events 143 152 void update(const Clock& time) 144 153 { 145 154 oisDevice_->capture(); 146 155 147 if (!this->isCalibrating()) 148 { 149 // Call all the states with the held button event 150 for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB) 151 for (unsigned int iS = 0; iS < inputStates_.size(); ++iS) 152 inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>( 153 this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB])); 154 155 // Call states with device update events 156 for (unsigned int i = 0; i < inputStates_.size(); ++i) 157 inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID()); 158 } 156 // Call all the states with the held button event 157 for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB) 158 for (unsigned int iS = 0; iS < inputStates_.size(); ++iS) 159 inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>( 160 this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB])); 161 162 // Call states with device update events 163 for (unsigned int i = 0; i < inputStates_.size(); ++i) 164 inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID()); 159 165 160 166 static_cast<DeviceClass*>(this)->updateImpl(time); 161 167 } 162 168 169 //! Clears the list of pressed buttons and calls the derived class's method 163 170 void clearBuffers() 164 171 { … … 167 174 } 168 175 176 // Returns a pointer to the OIS device 177 OISDeviceClass* getOISDevice() { return this->oisDevice_; } 178 // Returns the name of the derived class as string 179 std::string getClassName() const { return DeviceClass::getClassNameImpl(); } 180 169 181 protected: 170 void buttonPressed(ButtonTypeParam button) 182 //! Common code for all button pressed events (updates pressed buttons list and calls the input states) 183 FORCEINLINE void buttonPressed(ButtonTypeParam button) 171 184 { 172 185 // check whether the button already is in the list (can happen when focus was lost) … … 184 197 } 185 198 186 void buttonReleased(ButtonTypeParam button) 199 //! Common code for all button released events (updates pressed buttons list and calls the input states) 200 FORCEINLINE void buttonReleased(ButtonTypeParam button) 187 201 { 188 202 // remove the button from the pressedButtons_ list … … 201 215 } 202 216 217 //! Managed pointer to the OIS device 203 218 OISDeviceClass* oisDevice_; 204 219 205 220 private: 206 void clearBuffersImpl() { } //!< Fallback dummy function for static polymorphism 207 void updateImpl(const Clock& time) { } //!< Fallback dummy function for static polymorphism 221 //!< Fallback dummy function for static polymorphism 222 void clearBuffersImpl() { } 223 //!< Fallback dummy function for static polymorphism 224 void updateImpl(const Clock& time) { } 208 225 //!< Fallback dummy function for static polymorphism 209 226 ButtonType& getButtonEventArg(ButtonType& button) { return button; } 210 227 211 std::vector<ButtonType> pressedButtons_; 228 std::vector<ButtonType> pressedButtons_; //!< List of all buttons that are currently pressed down 229 OIS::InputManager* oisInputManager_; //!< Pointer to the OIS InputManager that can create and destroy devices 212 230 }; 213 231 } -
code/trunk/src/core/input/InputHandler.h
r3276 r3327 27 27 */ 28 28 29 /**30 @file31 @brief32 Declarations of various interface classes for the input management.33 */34 35 29 #ifndef _InputHandler_H__ 36 30 #define _InputHandler_H__ … … 41 35 namespace orxonox 42 36 { 37 namespace ButtonEvent 38 { 39 //! Helper enum to deploy events with the help of templates 40 enum Value 41 { 42 Press, 43 Release, 44 Hold 45 }; 46 47 //! Enables function overloading with integer values 48 template <ButtonEvent::Value Event> 49 struct EnumToType { }; 50 typedef EnumToType<Press> TPress; 51 typedef EnumToType<Release> TRelease; 52 typedef EnumToType<Hold> THold; 53 } 54 55 namespace KeyboardModifier 56 { 57 //! Keyboard modifiers (shift, ctrl and alt) 58 enum Enum 59 { 60 Shift = 0x0000001, 61 Ctrl = 0x0000010, 62 Alt = 0x0000100 63 }; 64 } 65 66 //! Event argument for key events 67 class _CoreExport KeyEvent 68 { 69 public: 70 KeyEvent(const OIS::KeyEvent& evt) 71 : key_(static_cast<KeyCode::ByEnum>(evt.key)) 72 , text_(evt.text) 73 , modifiers_(0) 74 { } 75 bool operator==(const KeyEvent& rhs) const 76 { return rhs.key_ == key_; } 77 bool operator!=(const KeyEvent& rhs) const 78 { return rhs.key_ != key_; } 79 void setModifiers(int modifiers) 80 { modifiers_ = modifiers; } 81 82 bool isModifierDown(KeyboardModifier::Enum modifier) const 83 { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); } 84 KeyCode::ByEnum getKeyCode() const 85 { return key_; } 86 unsigned int getText() const { return text_; } 87 88 private: 89 KeyCode::ByEnum key_; 90 unsigned int text_; 91 int modifiers_; 92 }; 93 43 94 /** 44 95 @brief 96 Base class for all input handlers like KeyBinder, InputBuffer, etc. 97 98 Derive from this class if you wish to receive input events. 99 But keep in mind that this is pointless wihtout first having an InputState. 100 @note 101 The definitions for the button events with the weird arguments are simply 102 to avoid redunant code in the input devices. 45 103 */ 46 104 class _CoreExport InputHandler … … 83 141 virtual void allDevicesUpdated(float dt) { } 84 142 143 //! Use this input handler if you want to occupy a device in an input state. 85 144 static InputHandler EMPTY; 86 145 }; -
code/trunk/src/core/input/InputManager.cc
r3301 r3327 30 30 @file 31 31 @brief 32 Implementation of the InputManager that captures all the input from OIS 33 and redirects it to handlers. 34 */ 32 Implementation of the InputManager and a static variable from the InputHandler. 33 */ 35 34 36 35 #include "InputManager.h" 37 36 37 #include <cassert> 38 38 #include <climits> 39 #include <cassert>40 39 #include <ois/OISException.h> 41 40 #include <ois/OISInputManager.h> 42 43 #include "util/Convert.h" 41 #include <boost/foreach.hpp> 42 44 43 #include "util/Exception.h" 45 44 #include "util/ScopeGuard.h" … … 49 48 #include "core/ConsoleCommand.h" 50 49 #include "core/CommandLine.h" 50 #include "core/Functor.h" 51 51 52 52 #include "InputBuffer.h" 53 53 #include "KeyDetector.h" 54 #include "InputState.h" 55 #include "SimpleInputState.h" 56 #include "ExtendedInputState.h" 57 #include "JoyStickDeviceNumberListener.h" 58 59 // HACK (include this as last, X11 seems to define some macros...) 60 #ifdef ORXONOX_PLATFORM_LINUX 61 # include <ois/linux/LinuxMouse.h> 62 #endif 54 #include "JoyStick.h" 55 #include "JoyStickQuantityListener.h" 56 #include "Mouse.h" 57 #include "Keyboard.h" 63 58 64 59 namespace orxonox 65 60 { 66 SetConsoleCommand(InputManager, calibrate, true);67 SetConsoleCommand(InputManager, reload, false);68 #ifdef ORXONOX_PLATFORM_LINUX69 SetConsoleCommand(InputManager, grabMouse, true);70 SetConsoleCommand(InputManager, ungrabMouse, true);71 #endif72 61 SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard"); 73 62 74 EmptyHandler InputManager::EMPTY_HANDLER; 63 // Abuse of this source file for the InputHandler 64 InputHandler InputHandler::EMPTY; 65 75 66 InputManager* InputManager::singletonRef_s = 0; 76 67 77 using namespace InputDevice; 78 79 /** 80 @brief 81 Defines the |= operator for easier use. 82 */ 83 inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval, 84 InputManager::InputManagerState rval) 85 { 86 return (lval = (InputManager::InputManagerState)(lval | rval)); 87 } 88 89 /** 90 @brief 91 Defines the &= operator for easier use. 92 */ 93 inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval) 94 { 95 return (lval = (InputManager::InputManagerState)(lval & rval)); 68 //! Defines the |= operator for easier use. 69 inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval) 70 { 71 return (lval = (InputManager::State)(lval | rval)); 72 } 73 74 //! Defines the &= operator for easier use. 75 inline InputManager::State operator&=(InputManager::State& lval, int rval) 76 { 77 return (lval = (InputManager::State)(lval & rval)); 96 78 } 97 79 … … 100 82 // ########## ########## 101 83 // ############################################################ 102 103 /** 104 @brief 105 Constructor only sets member fields to initial zero values 106 and registers the class in the class hierarchy. 107 */ 108 InputManager::InputManager() 109 : inputSystem_(0) 110 , keyboard_(0) 111 , mouse_(0) 112 , joySticksSize_(0) 113 , devicesNum_(0) 84 InputManager::InputManager(size_t windowHnd) 85 : internalState_(Bad) 86 , oisInputManager_(0) 87 , devices_(2) 114 88 , windowHnd_(0) 115 , internalState_(Uninitialised) 116 , stateEmpty_(0) 89 , emptyState_(0) 117 90 , keyDetector_(0) 118 , calibratorCallbackBuffer_(0) 119 , keyboardModifiers_(0) 91 , calibratorCallbackHandler_(0) 120 92 { 121 93 RegisterRootObject(InputManager); … … 124 96 singletonRef_s = this; 125 97 126 setConfigValues(); 127 } 128 129 /** 130 @brief 131 Sets the configurable values. 132 */ 98 CCOUT(4) << "Constructing..." << std::endl; 99 100 this->setConfigValues(); 101 102 this->loadDevices(windowHnd); 103 104 // Lowest priority empty InputState 105 emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty); 106 emptyState_->setHandler(&InputHandler::EMPTY); 107 activeStates_[emptyState_->getPriority()] = emptyState_; 108 109 // KeyDetector to evaluate a pressed key's name 110 InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector); 111 // Create a callback to avoid buttonHeld events after the key has been detected 112 FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers); 113 bufferFunctor->setObject(this); 114 detector->setLeaveFunctor(bufferFunctor); 115 keyDetector_ = new KeyDetector(); 116 detector->setHandler(keyDetector_); 117 118 // Joy stick calibration helper callback 119 InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator); 120 calibrator->setHandler(&InputHandler::EMPTY); 121 calibratorCallbackHandler_ = new InputBuffer(); 122 calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true); 123 calibrator->setKeyHandler(calibratorCallbackHandler_); 124 125 this->updateActiveStates(); 126 127 { 128 // calibrate console command 129 FunctorMember<InputManager>* functor = createFunctor(&InputManager::calibrate); 130 functor->setObject(this); 131 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "calibrate"), true); 132 } 133 { 134 // reload console command 135 FunctorMember<InputManager>* functor = createFunctor(&InputManager::reload); 136 functor->setObject(this); 137 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false); 138 } 139 140 internalState_ = Nothing; 141 CCOUT(4) << "Construction complete." << std::endl; 142 } 143 133 144 void InputManager::setConfigValues() 134 145 { 135 SetConfigValue(calibrationFilename_, "joystick_calibration.ini")136 .description("Ini filename for the the joy stick calibration data.")137 .callback(this, &InputManager::_calibrationFileCallback);138 }139 140 /**141 @brief142 Callback for the joy stick calibration config file. @see setConfigValues.143 */144 void InputManager::_calibrationFileCallback()145 {146 ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);147 146 } 148 147 … … 150 149 @brief 151 150 Creates the OIS::InputMananger, the keyboard, the mouse and 152 the joys ticks and assigns the key bindings.151 the joys ticks. If either of the first two fail, this method throws an exception. 153 152 @param windowHnd 154 153 The window handle of the render window … … 157 156 @param windowHeight 158 157 The height of the render window 159 @param joyStickSupport160 Whether or not to load the joy sticks as well161 158 */ 162 void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport) 163 { 164 CCOUT(3) << "Initialising Input System..." << std::endl; 165 166 if (!(internalState_ & OISReady)) 167 { 168 CCOUT(4) << "Initialising OIS components..." << std::endl; 169 170 // store handle internally so we can reload OIS 171 windowHnd_ = windowHnd; 172 173 OIS::ParamList paramList; 174 std::ostringstream windowHndStr; 175 176 // Fill parameter list 177 windowHndStr << static_cast<unsigned int>(windowHnd); 178 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 159 void InputManager::loadDevices(size_t windowHnd) 160 { 161 CCOUT(3) << "Loading input devices..." << std::endl; 162 163 // When loading the devices they should not already be loaded 164 assert(internalState_ & Bad); 165 assert(devices_[InputDeviceEnumerator::Mouse] == 0); 166 assert(devices_[InputDeviceEnumerator::Keyboard] == 0); 167 assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick); 168 169 // store handle internally so we can reload OIS 170 windowHnd_ = windowHnd; 171 172 OIS::ParamList paramList; 173 std::ostringstream windowHndStr; 174 175 // Fill parameter list 176 windowHndStr << static_cast<unsigned int>(windowHnd); 177 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 179 178 #if defined(ORXONOX_PLATFORM_WINDOWS) 180 181 182 183 179 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 180 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 181 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE"))); 182 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND"))); 184 183 #elif defined(ORXONOX_PLATFORM_LINUX) 185 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 186 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); 187 paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true")); 188 bool kbNoGrab; 189 CommandLine::getValue("keyboard_no_grab", &kbNoGrab); 190 if (kbNoGrab) 191 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); 184 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 185 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); 186 paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true")); 187 bool kbNoGrab; 188 CommandLine::getValue("keyboard_no_grab", &kbNoGrab); 189 if (kbNoGrab) 190 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); 191 else 192 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true"))); 193 #endif 194 195 try 196 { 197 oisInputManager_ = OIS::InputManager::createInputSystem(paramList); 198 // Exception-safety 199 Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_); 200 CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl; 201 202 if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0) 203 devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_); 192 204 else 193 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true"))); 194 #endif 195 205 ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!"); 206 207 // Successful initialisation 208 guard.Dismiss(); 209 } 210 catch (std::exception& ex) 211 { 212 oisInputManager_ = NULL; 213 internalState_ |= Bad; 214 ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what()); 215 } 216 217 // TODO: Remove the two parameters 218 this->loadMouse(); 219 this->loadJoySticks(); 220 221 // Reorder states in case some joy sticks were added/removed 222 this->updateActiveStates(); 223 224 CCOUT(3) << "Input devices loaded." << std::endl; 225 } 226 227 //! Creates a new orxonox::Mouse 228 void InputManager::loadMouse() 229 { 230 if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0) 231 { 196 232 try 197 233 { 198 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 199 // Exception-safety 200 Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_); 201 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 202 203 _initialiseKeyboard(); 204 205 // Nothing below should throw anymore, dismiss the guard 206 guard.Dismiss(); 207 } 208 catch (OIS::Exception& ex) 209 { 210 ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what()); 211 } 212 213 _initialiseMouse(); 214 215 if (joyStickSupport) 216 _initialiseJoySticks(); 217 // Do this anyway to also inform when a joystick was detached. 218 _configureJoySticks(); 219 220 // Set mouse/joystick region 221 if (mouse_) 222 setWindowExtents(windowWidth, windowHeight); 223 224 // clear all buffers 225 _clearBuffers(); 226 227 internalState_ |= OISReady; 228 229 CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl; 234 devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_); 235 } 236 catch (const OIS::Exception& ex) 237 { 238 CCOUT(2) << "Warning: Failed to create Mouse:" << ex.eText << std::endl 239 << "Proceeding without mouse support." << std::endl; 240 } 230 241 } 231 242 else 232 { 233 CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl; 234 } 235 236 if (!(internalState_ & InternalsReady)) 237 { 238 CCOUT(4) << "Initialising InputStates components..." << std::endl; 239 240 // Lowest priority empty InputState 241 stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty); 242 stateEmpty_->setHandler(&EMPTY_HANDLER); 243 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 244 245 // KeyDetector to evaluate a pressed key's name 246 SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector); 247 keyDetector_ = new KeyDetector(); 248 detector->setHandler(keyDetector_); 249 250 // Joy stick calibration helper callback 251 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator); 252 calibrator->setHandler(&EMPTY_HANDLER); 253 calibratorCallbackBuffer_ = new InputBuffer(); 254 calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true); 255 calibrator->setKeyHandler(calibratorCallbackBuffer_); 256 257 internalState_ |= InternalsReady; 258 259 CCOUT(4) << "Initialising InputStates complete." << std::endl; 260 } 261 262 _updateActiveStates(); 263 264 CCOUT(3) << "Initialising complete." << std::endl; 243 CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl; 244 } 245 246 //! Creates as many joy sticks as are available. 247 void InputManager::loadJoySticks() 248 { 249 for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++) 250 { 251 try 252 { 253 devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_)); 254 } 255 catch (std::exception ex) 256 { 257 CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl; 258 } 259 } 260 261 // inform all JoyStick Device Number Listeners 262 std::vector<JoyStick*> joyStickList; 263 for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i) 264 joyStickList.push_back(static_cast<JoyStick*>(devices_[i])); 265 JoyStickQuantityListener::changeJoyStickQuantity(joyStickList); 266 } 267 268 void InputManager::setKeyDetectorCallback(const std::string& command) 269 { 270 this->keyDetector_->setCallbackCommand(command); 271 } 272 273 // ############################################################ 274 // ##### Destruction ##### 275 // ########## ########## 276 // ############################################################ 277 278 InputManager::~InputManager() 279 { 280 CCOUT(4) << "Destroying..." << std::endl; 281 282 // Destroy calibrator helper handler and state 283 delete keyDetector_; 284 this->destroyState("calibrator"); 285 // Destroy KeyDetector and state 286 delete calibratorCallbackHandler_; 287 this->destroyState("detector"); 288 // destroy the empty InputState 289 this->destroyStateInternal(this->emptyState_); 290 291 // destroy all user InputStates 292 while (statesByName_.size() > 0) 293 this->destroyStateInternal((*statesByName_.rbegin()).second); 294 295 if (!(internalState_ & Bad)) 296 this->destroyDevices(); 297 298 CCOUT(4) << "Destruction complete." << std::endl; 299 singletonRef_s = 0; 265 300 } 266 301 267 302 /** 268 303 @brief 269 Creates a keyboard and sets the event handler.270 @ return271 False if keyboard stays uninitialised, true otherwise.304 Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager) 305 @throw 306 Method does not throw 272 307 */ 273 void InputManager::_initialiseKeyboard() 274 { 275 if (keyboard_ != 0) 276 { 277 CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl; 278 return; 279 } 280 if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0) 281 { 282 keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true); 283 // register our listener in OIS. 284 keyboard_->setEventCallback(this); 285 // note: OIS will not detect keys that have already been down when the keyboard was created. 286 CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl; 287 } 288 else 289 { 290 ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!"); 291 } 292 } 293 294 /** 295 @brief 296 Creates a mouse and sets the event handler. 297 @return 298 False if mouse stays uninitialised, true otherwise. 299 */ 300 void InputManager::_initialiseMouse() 301 { 302 if (mouse_ != 0) 303 { 304 CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl; 305 return; 306 } 308 void InputManager::destroyDevices() 309 { 310 CCOUT(3) << "Destroying devices..." << std::endl; 311 312 BOOST_FOREACH(InputDevice*& device, devices_) 313 { 314 if (device == NULL) 315 continue; 316 std::string className = device->getClassName(); 317 try 318 { 319 delete device; 320 device = 0; 321 CCOUT(4) << className << " destroyed." << std::endl; 322 } 323 catch (...) 324 { 325 CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl; 326 } 327 } 328 devices_.resize(InputDeviceEnumerator::FirstJoyStick); 329 330 assert(oisInputManager_ != NULL); 307 331 try 308 332 { 309 if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0) 310 { 311 mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true)); 312 // register our listener in OIS. 313 mouse_->setEventCallback(this); 314 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl; 315 } 316 else 317 { 318 CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl; 319 } 320 } 321 catch (OIS::Exception ex) 322 { 323 CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n" 324 << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl; 325 mouse_ = 0; 326 } 327 } 328 329 /** 330 @brief 331 Creates all joy sticks and sets the event handler. 332 @return 333 False joy stick stay uninitialised, true otherwise. 334 */ 335 void InputManager::_initialiseJoySticks() 336 { 337 if (joySticksSize_ > 0) 338 { 339 CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl; 340 return; 341 } 342 if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0) 343 { 344 for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++) 345 { 346 try 347 { 348 OIS::JoyStick* stig = static_cast<OIS::JoyStick*> 349 (inputSystem_->createInputObject(OIS::OISJoyStick, true)); 350 CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl; 351 joySticks_.push_back(stig); 352 // register our listener in OIS. 353 stig->setEventCallback(this); 354 } 355 catch (OIS::Exception ex) 356 { 357 CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n" 358 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 359 } 360 } 361 } 362 } 363 364 /** 365 @brief 366 Helper function that loads the config value vector of one coefficient 367 */ 368 void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue) 369 { 370 list.resize(size); 371 unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName); 372 if (configValueVectorSize > size) 373 configValueVectorSize = size; 374 375 for (unsigned int i = 0; i < configValueVectorSize; ++i) 376 { 377 list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue( 378 ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false)); 379 } 380 381 // fill the rest with default values 382 for (unsigned int i = configValueVectorSize; i < size; ++i) 383 { 384 list[i] = defaultValue; 385 } 386 } 387 388 /** 389 @brief 390 Sets the size of all the different lists that are dependent on the number 391 of joy stick devices created and loads the joy stick calibration. 392 @remarks 393 No matter whether there are a mouse and/or keyboard, they will always 394 occupy 2 places in the device number dependent lists. 395 */ 396 void InputManager::_configureJoySticks() 397 { 398 joySticksSize_ = joySticks_.size(); 399 devicesNum_ = 2 + joySticksSize_; 400 joyStickIDs_ .resize(joySticksSize_); 401 joyStickButtonsDown_ .resize(joySticksSize_); 402 povStates_ .resize(joySticksSize_); 403 sliderStates_ .resize(joySticksSize_); 404 joyStickMinValues_ .resize(joySticksSize_); 405 joyStickMaxValues_ .resize(joySticksSize_); 406 joyStickMiddleValues_.resize(joySticksSize_); 407 joyStickCalibrations_.resize(joySticksSize_); 408 409 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 410 { 411 // Generate some sort of execution unique id per joy stick 412 std::string id = "JoyStick_"; 413 id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Button)) + "_"; 414 id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis)) + "_"; 415 id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Slider)) + "_"; 416 id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_POV)) + "_"; 417 id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Vector3)) + "_"; 418 id += joySticks_[iJoyStick]->vendor(); 419 for (unsigned int i = 0; i < iJoyStick; ++i) 420 { 421 if (id == joyStickIDs_[i]) 422 { 423 // Two joysticks are probably equal --> add the index as well 424 id += "_" + multi_cast<std::string>(iJoyStick); 425 } 426 } 427 joyStickIDs_[iJoyStick] = id; 428 429 size_t axes = sliderAxes + (size_t)this->joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis); 430 loadCalibration(joyStickMinValues_[iJoyStick], id, "MinValue", axes, -32768); 431 loadCalibration(joyStickMaxValues_[iJoyStick], id, "MaxValue", axes, 32768); 432 loadCalibration(joyStickMiddleValues_[iJoyStick], id, "MiddleValue", axes, 0); 433 } 434 435 _evaluateCalibration(); 436 437 // state management 438 activeStatesTriggered_.resize(devicesNum_); 439 440 // inform all states 441 for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin(); 442 it != inputStatesByName_.end(); ++it) 443 { 444 it->second->setNumOfJoySticks(joySticksSize_); 445 } 446 447 // inform all JoyStick Device Number Listeners 448 for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it) 449 it->JoyStickDeviceNumberChanged(joySticksSize_); 450 451 } 452 453 void InputManager::_evaluateCalibration() 454 { 455 for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick) 456 { 457 for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); i++) 458 { 459 this->joyStickCalibrations_[iJoyStick].middleValue[i] = this->joyStickMiddleValues_[iJoyStick][i]; 460 this->joyStickCalibrations_[iJoyStick].negativeCoeff[i] = - 1.0f / (this->joyStickMinValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]); 461 this->joyStickCalibrations_[iJoyStick].positiveCoeff[i] = 1.0f / (this->joyStickMaxValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]); 462 } 463 } 464 } 465 466 void InputManager::_startCalibration() 467 { 468 for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick) 469 { 470 // Set initial values 471 for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); ++i) 472 this->joyStickMinValues_[iJoyStick][i] = INT_MAX; 473 for (unsigned int i = 0; i < this->joyStickMaxValues_[iJoyStick].size(); ++i) 474 this->joyStickMaxValues_[iJoyStick][i] = INT_MIN; 475 for (unsigned int i = 0; i < this->joyStickMiddleValues_[iJoyStick].size(); ++i) 476 this->joyStickMiddleValues_[iJoyStick][i] = 0; 477 } 478 479 getInstance().internalState_ |= Calibrating; 480 getInstance().requestEnterState("calibrator"); 481 } 482 483 void InputManager::_completeCalibration() 484 { 485 for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick) 486 { 487 // Get the middle positions now 488 unsigned int iAxis = 0; 489 for (unsigned int i = 0; i < sliderAxes/2; ++i) 490 { 491 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abX; 492 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abY; 493 } 494 // Note: joyStickMiddleValues_[iJoyStick] was already correctly resized in _configureJoySticks() 495 assert(joySticks_[iJoyStick]->getJoyStickState().mAxes.size() == joyStickMiddleValues_[iJoyStick].size() - sliderAxes); 496 for (unsigned int i = 0; i < joyStickMiddleValues_[iJoyStick].size() - sliderAxes; ++i) 497 { 498 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mAxes[i].abs; 499 } 500 501 for (unsigned int i = 0; i < joyStickMinValues_[iJoyStick].size(); ++i) 502 { 503 // Minimum values 504 if (joyStickMinValues_[iJoyStick][i] == INT_MAX) 505 joyStickMinValues_[iJoyStick][i] = -32768; 506 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 507 this->joyStickIDs_[iJoyStick], "MinValue", i, multi_cast<std::string>(joyStickMinValues_[iJoyStick][i]), false); 508 509 // Maximum values 510 if (joyStickMaxValues_[iJoyStick][i] == INT_MIN) 511 joyStickMaxValues_[iJoyStick][i] = 32767; 512 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 513 this->joyStickIDs_[iJoyStick], "MaxValue", i, multi_cast<std::string>(joyStickMaxValues_[iJoyStick][i]), false); 514 515 // Middle values 516 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 517 this->joyStickIDs_[iJoyStick], "MiddleValue", i, multi_cast<std::string>(joyStickMiddleValues_[iJoyStick][i]), false); 518 } 519 } 520 521 _evaluateCalibration(); 522 523 // restore old input state 524 requestLeaveState("calibrator"); 525 internalState_ &= ~Calibrating; 526 } 527 528 // ############################################################ 529 // ##### Destruction ##### 530 // ########## ########## 531 // ############################################################ 532 533 /** 534 @brief 535 Destroys all the created input devices and states. 536 */ 537 InputManager::~InputManager() 538 { 539 if (internalState_ != Uninitialised) 540 { 541 CCOUT(3) << "Destroying ..." << std::endl; 542 543 // kick all active states 'nicely' 544 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 545 rit != activeStates_.rend(); ++rit) 546 { 547 (*rit).second->onLeave(); 548 } 549 550 // Destroy calibrator helper handler and state 551 delete keyDetector_; 552 requestDestroyState("calibrator"); 553 // Destroy KeyDetector and state 554 delete calibratorCallbackBuffer_; 555 requestDestroyState("detector"); 556 // destroy the empty InputState 557 _destroyState(this->stateEmpty_); 558 559 // destroy all user InputStates 560 while (inputStatesByName_.size() > 0) 561 _destroyState((*inputStatesByName_.rbegin()).second); 562 563 // destroy the devices 564 _destroyKeyboard(); 565 _destroyMouse(); 566 _destroyJoySticks(); 567 568 try 569 { 570 OIS::InputManager::destroyInputSystem(inputSystem_); 571 } 572 catch (...) 573 { 574 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl; 575 } 576 } 577 578 singletonRef_s = 0; 579 } 580 581 /** 582 @brief 583 Destroys the keyboard and sets it to 0. 584 */ 585 void InputManager::_destroyKeyboard() 586 { 587 assert(inputSystem_); 588 try 589 { 590 if (keyboard_) 591 inputSystem_->destroyInputObject(keyboard_); 592 keyboard_ = 0; 593 CCOUT(4) << "Keyboard destroyed." << std::endl; 333 OIS::InputManager::destroyInputSystem(oisInputManager_); 594 334 } 595 335 catch (...) 596 336 { 597 CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl; 598 } 599 } 600 601 /** 602 @brief 603 Destroys the mouse and sets it to 0. 604 */ 605 void InputManager::_destroyMouse() 606 { 607 assert(inputSystem_); 608 try 609 { 610 if (mouse_) 611 inputSystem_->destroyInputObject(mouse_); 612 mouse_ = 0; 613 CCOUT(4) << "Mouse destroyed." << std::endl; 614 } 615 catch (...) 616 { 617 CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl; 618 } 619 } 620 621 /** 622 @brief 623 Destroys all the joy sticks and resizes the lists to 0. 624 */ 625 void InputManager::_destroyJoySticks() 626 { 627 if (joySticksSize_ > 0) 628 { 629 assert(inputSystem_); 630 for (unsigned int i = 0; i < joySticksSize_; i++) 631 { 632 try 633 { 634 if (joySticks_[i] != 0) 635 inputSystem_->destroyInputObject(joySticks_[i]); 636 } 637 catch (...) 638 { 639 CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl; 640 } 641 } 642 643 joySticks_.clear(); 644 // don't use _configureNumberOfJoySticks(), might mess with registered handler if 645 // downgrading from 2 to 1 joystick 646 //_configureNumberOfJoySticks(); 647 joySticksSize_ = 0; 648 } 649 CCOUT(4) << "Joy sticks destroyed." << std::endl; 650 } 651 652 /** 653 @brief 654 Removes and destroys an InputState. 655 @return 656 True if state was removed immediately, false if postponed. 657 */ 658 void InputManager::_destroyState(InputState* state) 659 { 660 assert(state && !(this->internalState_ & Ticking)); 661 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 662 if (it != this->activeStates_.end()) 663 { 664 this->activeStates_.erase(it); 665 _updateActiveStates(); 666 } 667 inputStatesByName_.erase(state->getName()); 668 delete state; 669 } 670 671 void InputManager::_clearBuffers() 672 { 673 keysDown_.clear(); 674 keyboardModifiers_ = 0; 675 mouseButtonsDown_.clear(); 676 for (unsigned int i = 0; i < joySticksSize_; ++i) 677 { 678 joyStickButtonsDown_[i].clear(); 679 for (int j = 0; j < 4; ++j) 680 { 681 sliderStates_[i].sliderStates[j].x = 0; 682 sliderStates_[i].sliderStates[j].y = 0; 683 povStates_[i][j] = 0; 684 } 685 } 686 } 687 337 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl; 338 } 339 oisInputManager_ = NULL; 340 341 internalState_ |= Bad; 342 CCOUT(3) << "Destroyed devices." << std::endl; 343 } 688 344 689 345 // ############################################################ … … 692 348 // ############################################################ 693 349 694 /** 695 @brief 696 Public interface. Only reloads immediately if the call stack doesn't 697 include the update() method. 698 @param joyStickSupport 699 Whether or not to initialise joy sticks as well. 700 */ 701 void InputManager::reloadInputSystem(bool joyStickSupport) 350 void InputManager::reload() 702 351 { 703 352 if (internalState_ & Ticking) 704 353 { 705 354 // We cannot destroy OIS right now, because reload was probably 706 // caused by a user clicking on a GUI item. The backtrace would then355 // caused by a user clicking on a GUI item. The stack trace would then 707 356 // include an OIS method. So it would be a very bad thing to destroy it.. 708 357 internalState_ |= ReloadRequest; 709 // Misuse of internalState_: We can easily store the joyStickSupport bool. 710 // use Uninitialised as 0 value in order to make use of the overloaded |= operator 711 internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised; 712 } 713 else if (internalState_ & OISReady) 714 { 715 _reload(joyStickSupport); 716 } 358 } 359 else if (internalState_ & Calibrating) 360 CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl; 717 361 else 718 { 719 CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or" 720 << "joy sticks are currently calibrating." << std::endl; 721 } 722 } 723 724 /** 725 @brief 726 Internal reload method. Destroys the OIS devices and loads them again. 727 */ 728 void InputManager::_reload(bool joyStickSupport) 729 { 730 try 731 { 732 CCOUT(3) << "Reloading ..." << std::endl; 733 734 // Save mouse clipping size 735 int mouseWidth = mouse_->getMouseState().width; 736 int mouseHeight = mouse_->getMouseState().height; 737 738 internalState_ &= ~OISReady; 739 740 // destroy the devices 741 _destroyKeyboard(); 742 _destroyMouse(); 743 _destroyJoySticks(); 744 745 OIS::InputManager::destroyInputSystem(inputSystem_); 746 inputSystem_ = 0; 747 748 // clear all buffers containing input information 749 _clearBuffers(); 750 751 initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport); 752 753 CCOUT(3) << "Reloading done." << std::endl; 754 } 755 catch (OIS::Exception& ex) 756 { 757 CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl; 758 } 362 reloadInternal(); 363 } 364 365 //! Internal reload method. Destroys the OIS devices and loads them again. 366 void InputManager::reloadInternal() 367 { 368 CCOUT(3) << "Reloading ..." << std::endl; 369 370 this->destroyDevices(); 371 this->loadDevices(windowHnd_); 372 373 internalState_ &= ~Bad; 374 internalState_ &= ~ReloadRequest; 375 CCOUT(3) << "Reloading complete." << std::endl; 759 376 } 760 377 … … 764 381 // ############################################################ 765 382 766 /**767 @brief768 Updates the states and the InputState situation.769 @param time770 Clock holding the current time.771 */772 383 void InputManager::update(const Clock& time) 773 384 { 774 if (internalState_ == Uninitialised) 775 return; 385 if (internalState_ & Bad) 386 ThrowException(General, "InputManager was not correctly reloaded."); 387 776 388 else if (internalState_ & ReloadRequest) 777 { 778 _reload(internalState_ & JoyStickSupport); 779 internalState_ &= ~ReloadRequest; 780 internalState_ &= ~JoyStickSupport; 781 } 389 reloadInternal(); 782 390 783 391 // check for states to leave … … 787 395 it != stateLeaveRequests_.end(); ++it) 788 396 { 789 (*it)-> onLeave();397 (*it)->left(); 790 398 // just to be sure that the state actually is registered 791 assert( inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());399 assert(statesByName_.find((*it)->getName()) != statesByName_.end()); 792 400 793 401 activeStates_.erase((*it)->getPriority()); 794 402 if ((*it)->getPriority() < InputStatePriority::HighPriority) 795 403 (*it)->setPriority(0); 796 _updateActiveStates();404 updateActiveStates(); 797 405 } 798 406 stateLeaveRequests_.clear(); … … 806 414 { 807 415 // just to be sure that the state actually is registered 808 assert( inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());416 assert(statesByName_.find((*it)->getName()) != statesByName_.end()); 809 417 810 418 if ((*it)->getPriority() == 0) 811 419 { 812 420 // Get smallest possible priority between 1 and maxStateStackSize_s 813 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator814 421 for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 815 422 rit != activeStates_.rend(); ++rit) 816 #else817 for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();818 rit != activeStates_.rend(); ++rit)819 #endif820 423 { 821 424 if (rit->first < InputStatePriority::HighPriority) … … 830 433 } 831 434 activeStates_[(*it)->getPriority()] = (*it); 832 _updateActiveStates();833 (*it)-> onEnter();435 updateActiveStates(); 436 (*it)->entered(); 834 437 } 835 438 stateEnterRequests_.clear(); … … 842 445 it != stateDestroyRequests_.end(); ++it) 843 446 { 844 _destroyState((*it));447 destroyStateInternal((*it)); 845 448 } 846 449 stateDestroyRequests_.clear(); 847 450 } 848 451 849 // check whether a state has changed its EMPTY _HANDLERsituation452 // check whether a state has changed its EMPTY situation 850 453 bool bUpdateRequired = false; 851 454 for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it) 852 455 { 853 if (it->second->ha ndlersChanged())854 { 855 it->second->reset HandlersChanged();456 if (it->second->hasExpired()) 457 { 458 it->second->resetExpiration(); 856 459 bUpdateRequired = true; 857 460 } 858 461 } 859 462 if (bUpdateRequired) 860 _updateActiveStates();463 updateActiveStates(); 861 464 862 465 // mark that we now start capturing and distributing input 863 466 internalState_ |= Ticking; 864 467 865 // Capture all the input. This calls the event handlers in InputManager. 866 if (keyboard_) 867 keyboard_->capture(); 868 if (mouse_) 869 mouse_->capture(); 870 for (unsigned int i = 0; i < joySticksSize_; i++) 871 joySticks_[i]->capture(); 872 873 if (!(internalState_ & Calibrating)) 874 { 875 // call all the handlers for the held key events 876 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 877 { 878 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_); 879 880 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 881 activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt); 882 } 883 884 // call all the handlers for the held mouse button events 885 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 886 { 887 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 888 activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]); 889 } 890 891 // call all the handlers for the held joy stick button events 892 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 893 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 894 { 895 for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState) 896 activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 897 } 898 899 // update the handlers for each active handler 900 for (unsigned int i = 0; i < devicesNum_; ++i) 901 { 902 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 903 activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i); 904 } 905 906 // update the handler with a general tick afterwards 907 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 908 activeStatesTicked_[i]->updateInput(time.getDeltaTime()); 909 } 468 // Capture all the input and handle it 469 BOOST_FOREACH(InputDevice* device, devices_) 470 if (device != NULL) 471 device->update(time); 472 473 // Update the states 474 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 475 activeStatesTicked_[i]->update(time.getDeltaTime()); 910 476 911 477 internalState_ &= ~Ticking; … … 917 483 Also, a list of all active states (no duplicates!) is compiled for the general update(). 918 484 */ 919 void InputManager::_updateActiveStates() 920 { 921 for (unsigned int i = 0; i < devicesNum_; ++i) 922 { 485 void InputManager::updateActiveStates() 486 { 487 // temporary resize 488 for (unsigned int i = 0; i < devices_.size(); ++i) 489 { 490 if (devices_[i] == NULL) 491 continue; 492 std::vector<InputState*>& states = devices_[i]->getStateListRef(); 923 493 bool occupied = false; 924 activeStatesTriggered_[i].clear(); 925 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator 494 states.clear(); 926 495 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit) 927 496 { 928 #else929 for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)930 {931 #endif932 497 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_)) 933 498 { 934 activeStatesTriggered_[i].push_back(rit->second);499 states.push_back(rit->second); 935 500 if (!rit->second->bTransparent_) 936 501 occupied = true; … … 942 507 // Using a std::set to avoid duplicates 943 508 std::set<InputState*> tempSet; 944 for (unsigned int i = 0; i < devicesNum_; ++i) 945 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 946 tempSet.insert(activeStatesTriggered_[i][iState]); 509 for (unsigned int i = 0; i < devices_.size(); ++i) 510 if (devices_[i] != NULL) 511 for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState) 512 tempSet.insert(devices_[i]->getStateListRef()[iState]); 947 513 948 514 // copy the content of the std::set back to the actual vector … … 950 516 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) 951 517 activeStatesTicked_.push_back(*it); 952 953 this->mouseButtonsDown_.clear(); 954 } 955 956 /** 957 @brief 958 Clears all buffers that store what keys/buttons are being pressed at the moment. 959 */ 518 } 519 960 520 void InputManager::clearBuffers() 961 521 { 962 this->keysDown_.clear(); 963 this->mouseButtonsDown_.clear(); 964 for (unsigned int i = 0; i < this->joySticksSize_; ++i) 965 this->joyStickButtonsDown_[i].clear(); 966 } 967 968 969 // ############################################################ 970 // ##### OIS events ##### 522 BOOST_FOREACH(InputDevice* device, devices_) 523 if (device != NULL) 524 device->clearBuffers(); 525 } 526 527 void InputManager::calibrate() 528 { 529 COUT(0) << "Move all joy stick axes fully in all directions." << std::endl 530 << "When done, put the axex in the middle position and press enter." << std::endl; 531 532 BOOST_FOREACH(InputDevice* device, devices_) 533 if (device != NULL) 534 device->startCalibration(); 535 536 internalState_ |= Calibrating; 537 enterState("calibrator"); 538 } 539 540 //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well! 541 void InputManager::stopCalibration() 542 { 543 BOOST_FOREACH(InputDevice* device, devices_) 544 if (device != NULL) 545 device->stopCalibration(); 546 547 // restore old input state 548 leaveState("calibrator"); 549 internalState_ &= ~Calibrating; 550 // Clear buffers to prevent button hold events 551 this->clearBuffers(); 552 553 COUT(0) << "Calibration has been stored." << std::endl; 554 } 555 556 //! Gets called by WindowEventListener upon focus change --> clear buffers 557 void InputManager::windowFocusChanged() 558 { 559 this->clearBuffers(); 560 } 561 562 // ############################################################ 563 // ##### Iput States ##### 971 564 // ########## ########## 972 565 // ############################################################ 973 566 974 // ###### Key Events ###### 975 976 /** 977 @brief 978 Event handler for the keyPressed Event. 979 @param e 980 Event information 981 */ 982 bool InputManager::keyPressed(const OIS::KeyEvent &e) 983 { 984 // check whether the key already is in the list (can happen when focus was lost) 985 unsigned int iKey = 0; 986 while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key) 987 iKey++; 988 if (iKey == keysDown_.size()) 989 keysDown_.push_back(Key(e)); 990 else 991 { 992 // This happens when XAutoRepeat is set under linux. The KeyPressed event gets then sent 993 // continuously. 994 return true; 995 } 996 997 // update modifiers 998 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 999 keyboardModifiers_ |= KeyboardModifier::Alt; // alt key 1000 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 1001 keyboardModifiers_ |= KeyboardModifier::Ctrl; // ctrl key 1002 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 1003 keyboardModifiers_ |= KeyboardModifier::Shift; // shift key 1004 1005 KeyEvent kEvt(e, keyboardModifiers_); 1006 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 1007 activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt); 1008 1009 return true; 1010 } 1011 1012 /** 1013 @brief 1014 Event handler for the keyReleased Event. 1015 @param e 1016 Event information 1017 */ 1018 bool InputManager::keyReleased(const OIS::KeyEvent &e) 1019 { 1020 // remove the key from the keysDown_ list 1021 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 1022 { 1023 if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key) 1024 { 1025 keysDown_.erase(keysDown_.begin() + iKey); 1026 break; 1027 } 1028 } 1029 1030 // update modifiers 1031 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 1032 keyboardModifiers_ &= ~KeyboardModifier::Alt; // alt key 1033 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 1034 keyboardModifiers_ &= ~KeyboardModifier::Ctrl; // ctrl key 1035 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 1036 keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key 1037 1038 KeyEvent kEvt(e, keyboardModifiers_); 1039 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 1040 activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt); 1041 1042 return true; 1043 } 1044 1045 1046 // ###### Mouse Events ###### 1047 1048 /** 1049 @brief 1050 Event handler for the mouseMoved Event. 1051 @param e 1052 Event information 1053 */ 1054 bool InputManager::mouseMoved(const OIS::MouseEvent &e) 1055 { 1056 // check for actual moved event 1057 if (e.state.X.rel != 0 || e.state.Y.rel != 0) 1058 { 1059 IntVector2 abs(e.state.X.abs, e.state.Y.abs); 1060 IntVector2 rel(e.state.X.rel, e.state.Y.rel); 1061 IntVector2 clippingSize(e.state.width, e.state.height); 1062 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1063 activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize); 1064 } 1065 1066 // check for mouse scrolled event 1067 if (e.state.Z.rel != 0) 1068 { 1069 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1070 activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 1071 } 1072 1073 return true; 1074 } 1075 1076 /** 1077 @brief 1078 Event handler for the mousePressed Event. 1079 @param e 1080 Event information 1081 @param id 1082 The ID of the mouse button 1083 */ 1084 bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) 1085 { 1086 // check whether the button already is in the list (can happen when focus was lost) 1087 unsigned int iButton = 0; 1088 while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id) 1089 iButton++; 1090 if (iButton == mouseButtonsDown_.size()) 1091 mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id); 1092 1093 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1094 activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id); 1095 1096 return true; 1097 } 1098 1099 /** 1100 @brief 1101 Event handler for the mouseReleased Event. 1102 @param e 1103 Event information 1104 @param id 1105 The ID of the mouse button 1106 */ 1107 bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) 1108 { 1109 // remove the button from the keysDown_ list 1110 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 1111 { 1112 if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id) 1113 { 1114 mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton); 1115 break; 1116 } 1117 } 1118 1119 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1120 activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id); 1121 1122 return true; 1123 } 1124 1125 1126 // ###### Joy Stick Events ###### 1127 1128 /** 1129 @brief 1130 Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent 1131 */ 1132 inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg) 1133 { 1134 // use the device to identify which one called the method 1135 OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device; 1136 unsigned int iJoyStick = 0; 1137 while (joySticks_[iJoyStick] != joyStick) 1138 iJoyStick++; 1139 // assert: Unknown joystick fired an event. 1140 assert(iJoyStick != joySticksSize_); 1141 return iJoyStick; 1142 } 1143 1144 bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button) 1145 { 1146 unsigned int iJoyStick = _getJoystick(arg); 1147 1148 // check whether the button already is in the list (can happen when focus was lost) 1149 std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 1150 unsigned int iButton = 0; 1151 while (iButton < buttonsDown.size() && buttonsDown[iButton] != button) 1152 iButton++; 1153 if (iButton == buttonsDown.size()) 1154 buttonsDown.push_back((JoyStickButtonCode::ByEnum)button); 1155 1156 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1157 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1158 1159 return true; 1160 } 1161 1162 bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button) 1163 { 1164 unsigned int iJoyStick = _getJoystick(arg); 1165 1166 // remove the button from the joyStickButtonsDown_ list 1167 std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 1168 for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++) 1169 { 1170 if (buttonsDown[iButton] == button) 1171 { 1172 buttonsDown.erase(buttonsDown.begin() + iButton); 1173 break; 1174 } 1175 } 1176 1177 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1178 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1179 1180 return true; 1181 } 1182 1183 /** 1184 @brief 1185 Calls the states for a particular axis with our enumeration. 1186 Used by OIS sliders and OIS axes. 1187 */ 1188 void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value) 1189 { 1190 if (internalState_ & Calibrating) 1191 { 1192 if (value < joyStickMinValues_[iJoyStick][axis]) 1193 joyStickMinValues_[iJoyStick][axis] = value; 1194 if (value > joyStickMaxValues_[iJoyStick][axis]) 1195 joyStickMaxValues_[iJoyStick][axis] = value; 1196 } 1197 else 1198 { 1199 float fValue = static_cast<float>(value - joyStickCalibrations_[iJoyStick].middleValue[axis]); 1200 if (fValue > 0.0f) 1201 fValue *= joyStickCalibrations_[iJoyStick].positiveCoeff[axis]; 1202 else 1203 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis]; 1204 1205 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1206 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue); 1207 } 1208 } 1209 1210 bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis) 1211 { 1212 unsigned int iJoyStick = _getJoystick(arg); 1213 1214 // keep in mind that the first 8 axes are reserved for the sliders 1215 _fireAxis(iJoyStick, axis + sliderAxes, arg.state.mAxes[axis].abs); 1216 1217 return true; 1218 } 1219 1220 bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id) 1221 { 1222 unsigned int iJoyStick = _getJoystick(arg); 1223 1224 if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX) 1225 _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX); 1226 else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY) 1227 _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY); 1228 1229 return true; 1230 } 1231 1232 bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id) 1233 { 1234 unsigned int iJoyStick = _getJoystick(arg); 1235 1236 // translate the POV into 8 simple buttons 1237 1238 int lastState = povStates_[iJoyStick][id]; 1239 if (lastState & OIS::Pov::North) 1240 buttonReleased(arg, 32 + id * 4 + 0); 1241 if (lastState & OIS::Pov::South) 1242 buttonReleased(arg, 32 + id * 4 + 1); 1243 if (lastState & OIS::Pov::East) 1244 buttonReleased(arg, 32 + id * 4 + 2); 1245 if (lastState & OIS::Pov::West) 1246 buttonReleased(arg, 32 + id * 4 + 3); 1247 1248 povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction; 1249 1250 int currentState = povStates_[iJoyStick][id]; 1251 if (currentState & OIS::Pov::North) 1252 buttonPressed(arg, 32 + id * 4 + 0); 1253 if (currentState & OIS::Pov::South) 1254 buttonPressed(arg, 32 + id * 4 + 1); 1255 if (currentState & OIS::Pov::East) 1256 buttonPressed(arg, 32 + id * 4 + 2); 1257 if (currentState & OIS::Pov::West) 1258 buttonPressed(arg, 32 + id * 4 + 3); 1259 1260 return true; 1261 } 1262 1263 1264 // ############################################################ 1265 // ##### Other Public Interface Methods ##### 1266 // ########## ########## 1267 // ############################################################ 1268 1269 /** 1270 @brief 1271 Adjusts the mouse window metrics. 1272 This method has to be called every time the size of the window changes. 1273 @param width 1274 The new width of the render window 1275 @param^height 1276 The new height of the render window 1277 */ 1278 void InputManager::setWindowExtents(const int width, const int height) 1279 { 1280 if (mouse_) 1281 { 1282 // Set mouse region (if window resizes, we should alter this to reflect as well) 1283 mouse_->getMouseState().width = width; 1284 mouse_->getMouseState().height = height; 1285 } 1286 } 1287 1288 /** 1289 @brief 1290 Sets the the name of the command used by the KeyDetector as callback. 1291 @param command 1292 Command name as string 1293 */ 1294 void InputManager::setKeyDetectorCallback(const std::string& command) 1295 { 1296 this->keyDetector_->setCallbackCommand(command); 1297 } 1298 1299 // ###### InputStates ###### 1300 1301 /** 1302 @brief 1303 Adds a new key handler. 1304 @param handler 1305 Pointer to the handler object. 1306 @param name 1307 Unique name of the handler. 1308 @param priority 1309 Determines which InputState gets the input. Higher is better. 1310 Use 0 to handle it implicitely by the order of activation. 1311 Otherwise numbers larger than maxStateStackSize_s have to be used! 1312 @return 1313 True if added, false if name or priority already existed. 1314 */ 1315 bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority) 567 InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority) 1316 568 { 1317 569 if (name == "") 1318 return false; 1319 if (!state) 1320 return false; 1321 if (inputStatesByName_.find(name) == inputStatesByName_.end()) 570 return 0; 571 if (statesByName_.find(name) == statesByName_.end()) 1322 572 { 1323 573 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1324 574 { 1325 575 // Make sure we don't add two high priority states with the same priority 1326 for (std::map<std::string, InputState*>::const_iterator it = this-> inputStatesByName_.begin();1327 it != this-> inputStatesByName_.end(); ++it)576 for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin(); 577 it != this->statesByName_.end(); ++it) 1328 578 { 1329 579 if (it->second->getPriority() == priority) 1330 580 { 1331 581 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1332 << priority<< "' != 0." << std::endl;1333 return false;582 << static_cast<int>(priority) << "' != 0." << std::endl; 583 return 0; 1334 584 } 1335 585 } 1336 586 } 1337 inputStatesByName_[name] = state; 1338 state->setNumOfJoySticks(numberOfJoySticks()); 1339 state->setName(name); 1340 state->bAlwaysGetsInput_ = bAlwaysGetsInput; 1341 state->bTransparent_ = bTransparent; 1342 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1343 state->setPriority(priority); 1344 return true; 587 InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority); 588 statesByName_[name] = state; 589 590 return state; 1345 591 } 1346 592 else 1347 593 { 1348 594 COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl; 1349 return false; 1350 } 1351 } 1352 1353 /** 1354 @brief 1355 Removes and destroys an input state internally. 1356 @param name 1357 Name of the handler. 1358 @return 1359 True if removal was successful, false if name was not found. 1360 @remarks 1361 You can't remove the internal states "empty", "calibrator" and "detector". 1362 The removal process is being postponed if InputManager::update() is currently running. 1363 */ 1364 bool InputManager::requestDestroyState(const std::string& name) 1365 { 1366 if (name == "empty") 1367 { 1368 COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl; 1369 return false; 1370 } 1371 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name); 1372 if (it != inputStatesByName_.end()) 1373 { 1374 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 1375 { 1376 // The state is still active. We have to postpone 1377 stateLeaveRequests_.insert(it->second); 1378 stateDestroyRequests_.insert(it->second); 1379 } 1380 else if (this->internalState_ & Ticking) 1381 { 1382 // cannot remove state while ticking 1383 stateDestroyRequests_.insert(it->second); 1384 } 1385 else 1386 _destroyState(it->second); 1387 1388 return true; 1389 } 1390 return false; 1391 } 1392 1393 /** 1394 @brief 1395 Returns the pointer to the requested InputState. 1396 @param name 1397 Unique name of the state. 1398 @return 1399 Pointer to the instance, 0 if name was not found. 1400 */ 595 return 0; 596 } 597 } 598 1401 599 InputState* InputManager::getState(const std::string& name) 1402 600 { 1403 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);1404 if (it != inputStatesByName_.end())601 std::map<std::string, InputState*>::iterator it = statesByName_.find(name); 602 if (it != statesByName_.end()) 1405 603 return it->second; 1406 604 else … … 1408 606 } 1409 607 1410 /** 1411 @brief 1412 Returns the current input state (there might be others active too!) 1413 @return 1414 The current highest prioritised active input state. 1415 */ 1416 InputState* InputManager::getCurrentState() 1417 { 1418 return (*activeStates_.rbegin()).second; 1419 } 1420 1421 /** 1422 @brief 1423 Activates a specific input state. 1424 It might not be really activated if the priority is too low! 1425 @param name 1426 Unique name of the state. 1427 @return 1428 False if name was not found, true otherwise. 1429 */ 1430 bool InputManager::requestEnterState(const std::string& name) 608 bool InputManager::enterState(const std::string& name) 1431 609 { 1432 610 // get pointer from the map with all stored handlers 1433 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);1434 if (it != inputStatesByName_.end())611 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 612 if (it != statesByName_.end()) 1435 613 { 1436 614 // exists … … 1450 628 } 1451 629 1452 /** 1453 @brief 1454 Deactivates a specific input state. 1455 @param name 1456 Unique name of the state. 1457 @return 1458 False if name was not found, true otherwise. 1459 */ 1460 bool InputManager::requestLeaveState(const std::string& name) 630 bool InputManager::leaveState(const std::string& name) 1461 631 { 1462 632 if (name == "empty") … … 1466 636 } 1467 637 // get pointer from the map with all stored handlers 1468 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);1469 if (it != inputStatesByName_.end())638 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 639 if (it != statesByName_.end()) 1470 640 { 1471 641 // exists … … 1480 650 } 1481 651 1482 1483 // ############################################################ 1484 // ##### Console Commands ##### 1485 // ########## ########## 1486 // ############################################################ 1487 1488 /** 1489 @brief 1490 Starts joy stick calibration. 1491 */ 1492 void InputManager::calibrate() 1493 { 1494 COUT(0) << "Move all joy stick axes fully in all directions." << std::endl 1495 << "When done, put the axex in the middle position and press enter." << std::endl; 1496 1497 getInstance()._startCalibration(); 1498 } 1499 1500 /** 1501 @brief 1502 Reloads the input system 1503 */ 1504 void InputManager::reload(bool joyStickSupport) 1505 { 1506 getInstance().reloadInputSystem(joyStickSupport); 1507 } 1508 1509 1510 // ############################################################ 1511 // ##### ugly hacks ##### 1512 // ########## ########## 1513 // ############################################################ 1514 1515 #ifdef ORXONOX_PLATFORM_LINUX 1516 void InputManager::grabMouse() 1517 { 1518 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_); 1519 assert(linuxMouse); 1520 linuxMouse->grab(true); 1521 } 1522 1523 void InputManager::ungrabMouse() 1524 { 1525 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_); 1526 assert(linuxMouse); 1527 linuxMouse->grab(false); 1528 } 1529 #endif 652 bool InputManager::destroyState(const std::string& name) 653 { 654 if (name == "empty") 655 { 656 COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl; 657 return false; 658 } 659 std::map<std::string, InputState*>::iterator it = statesByName_.find(name); 660 if (it != statesByName_.end()) 661 { 662 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 663 { 664 // The state is still active. We have to postpone 665 stateLeaveRequests_.insert(it->second); 666 stateDestroyRequests_.insert(it->second); 667 } 668 else if (this->internalState_ & Ticking) 669 { 670 // cannot remove state while ticking 671 stateDestroyRequests_.insert(it->second); 672 } 673 else 674 destroyStateInternal(it->second); 675 676 return true; 677 } 678 return false; 679 } 680 681 //! Destroys an InputState internally. 682 void InputManager::destroyStateInternal(InputState* state) 683 { 684 assert(state && !(this->internalState_ & Ticking)); 685 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 686 if (it != this->activeStates_.end()) 687 { 688 this->activeStates_.erase(it); 689 updateActiveStates(); 690 } 691 statesByName_.erase(state->getName()); 692 delete state; 693 } 1530 694 } -
code/trunk/src/core/input/InputManager.h
r3196 r3327 27 27 */ 28 28 29 /**30 @file31 @brief32 Implementation of a little Input handler that distributes everything33 coming from OIS.34 */35 36 29 #ifndef _InputManager_H__ 37 30 #define _InputManager_H__ 38 31 39 #include " core/CorePrereqs.h"32 #include "InputPrereqs.h" 40 33 41 34 #include <map> … … 43 36 #include <string> 44 37 #include <vector> 45 #include <ois/OISKeyboard.h> 46 #include <ois/OISMouse.h> 47 #include <ois/OISJoyStick.h> 48 49 #include "util/Math.h" 50 #include "util/OrxEnum.h" 51 #include "core/OrxonoxClass.h" 52 #include "InputInterfaces.h" 38 39 #include "core/WindowEventListener.h" 40 #include "InputState.h" 53 41 54 42 namespace orxonox … … 56 44 /** 57 45 @brief 58 Helper class to realise a vector<int[4]> 46 Manages the input devices (mouse, keyboard, joy sticks) and the input states. 47 48 Every input device has its own wrapper class which does the actualy input event 49 distribution. The InputManager only creates reloads (on request) those devices. 50 51 The other functionality concerns handling InputStates. They act as a layer 52 between InputHandlers (like the KeyBinder or the GUIManager) and InputDevices. 53 InputStates are memory managed by the IputManager. You cannot create or destroy 54 them on your own. Therefore all states get destroyed with the InputManager d'tor. 55 @note 56 - The actual lists containing all the InputStates for a specific device are stored 57 in the InputDevices themselves. 58 - The devices_ vector always has at least two elements: Keyboard (first) and mouse. 59 You best access them intenally with InputDeviceEnumerator::Keyboard/Mouse 60 The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick. 61 - Keyboard construction is mandatory , mouse and joy sticks are not. 62 If the OIS::InputManager or the Keyboard fail, an exception is thrown. 59 63 */ 60 class POVStates64 class _CoreExport InputManager : public WindowEventListener 61 65 { 62 66 public: 63 int& operator[](unsigned int index) { return povStates[index]; } 64 int povStates[4]; 65 }; 66 67 /** 68 @brief 69 Helper class to realise a vector< {int[4], int[4]} > 70 */ 71 class SliderStates 72 { 73 public: 74 IntVector2 sliderStates[4]; 75 }; 76 77 struct JoyStickCalibration 78 { 79 int middleValue[24]; 80 float positiveCoeff[24]; 81 float negativeCoeff[24]; 82 }; 83 84 struct InputStatePriority : OrxEnum<InputStatePriority> 85 { 86 OrxEnumConstructors(InputStatePriority); 87 88 static const int Empty = -1; 89 static const int Dynamic = 0; 90 91 static const int HighPriority = 1000; 92 static const int Console = HighPriority + 0; 93 static const int Calibrator = HighPriority + 1; 94 static const int Detector = HighPriority + 2; 95 }; 96 97 /** 98 @brief 99 Captures and distributes mouse and keyboard input. 100 */ 101 class _CoreExport InputManager 102 : public OrxonoxClass, 103 public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener 104 { 105 // --> setConfigValues is private 106 friend class ClassIdentifier<InputManager>; 107 108 public: 109 enum InputManagerState 67 //! Represents internal states of the InputManager. 68 enum State 110 69 { 111 Uninitialised = 0x00, 112 OISReady = 0x01, 113 InternalsReady = 0x02, 114 Ticking = 0x04, 115 Calibrating = 0x08, 116 ReloadRequest = 0x10, 117 JoyStickSupport = 0x20 // used with ReloadRequest to store a bool 70 Nothing = 0x00, 71 Bad = 0x02, 72 Ticking = 0x04, 73 Calibrating = 0x08, 74 ReloadRequest = 0x10, 118 75 }; 119 76 120 InputManager (); 77 /** 78 @brief 79 Loads the devices and initialises the KeyDetector and the Calibrator. 80 81 If either the OIS input system and/or the keyboard could not be created, 82 the constructor fails with an std::exception. 83 */ 84 InputManager(size_t windowHnd); 85 //! Destroys all devices AND all input states! 121 86 ~InputManager(); 122 123 void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true); 124 125 void reloadInputSystem(bool joyStickSupport = true); 126 87 void setConfigValues(); 88 89 /** 90 @brief 91 Updates the devices (which distribute the input events) and the input states. 92 93 Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request 94 was submitted while updating, the request wil be postponed until the next update call. 95 */ 96 void update(const Clock& time); 97 //! Clears all input device buffers. This usually only includes the pressed button list. 127 98 void clearBuffers(); 128 129 unsigned int numberOfKeyboards() { return keyboard_ ? 1 : 0; } 130 unsigned int numberOfMice() { return mouse_ ? 1 : 0; } 131 unsigned int numberOfJoySticks() { return joySticksSize_; } 132 133 void setWindowExtents(const int width, const int height); 99 //! Starts joy stick calibration. 100 void calibrate(); 101 /** 102 @brief 103 Reloads all the input devices. Use this method to initialise new joy sticks. 104 @note 105 Only reloads immediately if the call stack doesn't include the update() method. 106 */ 107 void reload(); 108 109 //------------------------------- 110 // Input States 111 //------------------------------- 112 /** 113 @brief 114 Creates a new InputState that gets managed by the InputManager. 115 @remarks 116 The InputManager will take care of the state completely. That also 117 means it gets deleted when the InputManager is destroyed! 118 @param name 119 Unique name of the InputState when referenced as string 120 @param priority 121 Priority matters when multiple states are active. You can specify any 122 number, but 1 - 99 is preferred (99 means high priority). 123 */ 124 InputState* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic); 125 /** 126 @brief 127 Returns a pointer to a InputState referenced by name. 128 @return 129 Returns NULL if state was not found. 130 */ 131 InputState* getState(const std::string& name); 132 /** 133 @brief 134 Activates a specific input state. 135 It might not be actually activated if the priority is too low! 136 @return 137 False if name was not found, true otherwise. 138 */ 139 bool enterState(const std::string& name); 140 /** 141 @brief 142 Deactivates a specific input state. 143 @return 144 False if name was not found, true otherwise. 145 */ 146 bool leaveState(const std::string& name); 147 /** 148 @brief 149 Removes and destroys an input state. 150 @return 151 True if removal was successful, false if name was not found. 152 @remarks 153 - You can't remove the internal states "empty", "calibrator" and "detector". 154 - The removal process is being postponed if InputManager::update() is currently running. 155 */ 156 bool destroyState(const std::string& name); 157 158 //------------------------------- 159 // Various getters and setters 160 //------------------------------- 161 //! Sets the the name of the command used by the KeyDetector as callback. 134 162 void setKeyDetectorCallback(const std::string& command); 135 136 template <class T> 137 T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic); 138 139 InputState* getState (const std::string& name); 140 InputState* getCurrentState(); 141 bool requestDestroyState (const std::string& name); 142 bool requestEnterState (const std::string& name); 143 bool requestLeaveState (const std::string& name); 144 145 #ifdef ORXONOX_PLATFORM_LINUX 146 // HACK! 147 static void grabMouse(); 148 static void ungrabMouse(); 149 #endif 150 151 void update(const Clock& time); 152 153 static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 154 static InputManager* getInstancePtr() { return singletonRef_s; } 155 156 // console commands 157 static void calibrate(); 158 static void reload(bool joyStickSupport = true); 159 160 public: // variables 161 static EmptyHandler EMPTY_HANDLER; 162 static const unsigned int sliderAxes = 8; 163 //! Returns the number of joy stick that have been created since the c'tor or last call to reload(). 164 unsigned int getJoyStickQuantity() const 165 { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; } 166 //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing! 167 OIS::InputManager* getOISInputManager() 168 { return this->oisInputManager_; } 169 170 //! Returns a reference to the singleton instance 171 static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 163 172 164 173 private: // functions 165 174 // don't mess with a Singleton 166 InputManager 175 InputManager(const InputManager&); 167 176 168 177 // Intenal methods 169 void _initialiseKeyboard(); 170 void _initialiseMouse(); 171 void _initialiseJoySticks(); 172 void _configureJoySticks(); 173 174 void _loadCalibration(); 175 void _startCalibration(); 176 void _completeCalibration(); 177 void _evaluateCalibration(); 178 179 void _destroyKeyboard(); 180 void _destroyMouse(); 181 void _destroyJoySticks(); 182 void _destroyState(InputState* state); 183 void _clearBuffers(); 184 185 void _reload(bool joyStickSupport); 186 187 void _fireAxis(unsigned int iJoyStick, int axis, int value); 188 unsigned int _getJoystick(const OIS::JoyStickEvent& arg); 189 190 void _updateActiveStates(); 191 bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority); 192 193 // input events 194 bool mousePressed (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 195 bool mouseReleased (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 196 bool mouseMoved (const OIS::MouseEvent &arg); 197 bool keyPressed (const OIS::KeyEvent &arg); 198 bool keyReleased (const OIS::KeyEvent &arg); 199 bool buttonPressed (const OIS::JoyStickEvent &arg, int button); 200 bool buttonReleased(const OIS::JoyStickEvent &arg, int button); 201 bool axisMoved (const OIS::JoyStickEvent &arg, int axis); 202 bool sliderMoved (const OIS::JoyStickEvent &arg, int id); 203 bool povMoved (const OIS::JoyStickEvent &arg, int id); 204 // don't remove that! Or else add OIS as dependency library to orxonox. 205 bool vector3Moved (const OIS::JoyStickEvent &arg, int id) { return true; } 206 207 void setConfigValues(); 208 void _calibrationFileCallback(); 178 void loadDevices(size_t windowHnd); 179 void loadMouse(); 180 void loadJoySticks(); 181 void destroyDevices(); 182 183 void stopCalibration(); 184 void reloadInternal(); 185 186 void destroyStateInternal(InputState* state); 187 void updateActiveStates(); 188 189 // From WindowEventListener 190 void windowFocusChanged(); 209 191 210 192 private: // variables 211 OIS::InputManager* inputSystem_; //!< OIS input manager 212 OIS::Keyboard* keyboard_; //!< OIS mouse 213 OIS::Mouse* mouse_; //!< OIS keyboard 214 std::vector<OIS::JoyStick*> joySticks_; //!< OIS joy sticks 215 unsigned int joySticksSize_; 216 std::vector<std::string> joyStickIDs_; //!< Execution unique identification strings for the joy sticks 217 unsigned int devicesNum_; 218 size_t windowHnd_; //!< Render window handle 219 InputManagerState internalState_; //!< Current internal state 193 State internalState_; //!< Current internal state 194 OIS::InputManager* oisInputManager_; //!< OIS input manager 195 std::vector<InputDevice*> devices_; //!< List of all input devices (keyboard, mouse, joy sticks) 196 // TODO: Get this from the GraphicsManager during reload 197 size_t windowHnd_; //!< Render window handle (used to reload the InputManager) 220 198 221 199 // some internally handled states and handlers 222 SimpleInputState* stateEmpty_;200 InputState* emptyState_; //!< Lowest priority states (makes handling easier) 223 201 KeyDetector* keyDetector_; //!< KeyDetector instance 224 InputBuffer* calibratorCallbackBuffer_; 225 226 std::map<std::string, InputState*> inputStatesByName_; 227 228 std::set<InputState*> stateEnterRequests_; //!< Request to enter a new state 229 std::set<InputState*> stateLeaveRequests_; //!< Request to leave a running state 230 std::set<InputState*> stateDestroyRequests_; //!< Request to destroy a state 231 232 std::map<int, InputState*> activeStates_; 233 std::vector<std::vector<InputState*> > activeStatesTriggered_; 234 std::vector<InputState*> activeStatesTicked_; 235 236 // joystick calibration 237 std::vector<std::vector<int> > joyStickMinValues_; 238 std::vector<std::vector<int> > joyStickMaxValues_; 239 std::vector<std::vector<int> > joyStickMiddleValues_; 240 std::vector<ConfigValueContainer*> calibrationConfigValueContainers_; 241 std::vector<JoyStickCalibration> joyStickCalibrations_; 242 243 unsigned int keyboardModifiers_; //!< Bit mask representing keyboard modifiers. 244 std::vector<POVStates> povStates_; //!< Keeps track of the joy stick POV states. 245 std::vector<SliderStates> sliderStates_; //!< Keeps track of the possibly two slider axes. 246 247 std::vector<Key> keysDown_; 248 std::vector<MouseButtonCode::ByEnum> mouseButtonsDown_; 249 std::vector<std::vector<JoyStickButtonCode::ByEnum> > joyStickButtonsDown_; 250 251 // ConfigValues 252 std::string calibrationFilename_; //!< Joy stick calibration ini filename 253 254 static InputManager* singletonRef_s; 202 //! InputBuffer that reacts to the Enter key when calibrating the joy sticks 203 InputBuffer* calibratorCallbackHandler_; 204 205 std::map<std::string, InputState*> statesByName_; //!< Contains all the created input states by name 206 std::map<int, InputState*> activeStates_; //!< Contains all active input states by priority (std::map is sorted!) 207 std::vector<InputState*> activeStatesTicked_; //!< Like activeStates_, but only contains the ones that currently receive events 208 209 std::set<InputState*> stateEnterRequests_; //!< Requests to enter a new state 210 std::set<InputState*> stateLeaveRequests_; //!< Requests to leave a running state 211 std::set<InputState*> stateDestroyRequests_; //!< Requests to destroy a state 212 213 static InputManager* singletonRef_s; //!< Pointer reference to the singleton 255 214 }; 256 257 /**258 @brief259 Creates a new InputState by type, name and priority.260 261 You will have to use this method because the262 c'tors and d'tors are private.263 @remarks264 The InputManager will take care of the state completely. That also265 means it gets deleted when the InputManager is destroyed!266 @param name267 Name of the InputState when referenced as string268 @param priority269 Priority matters when multiple states are active. You can specify any270 number, but 1 - 99 is preferred (99 means high).271 */272 template <class T>273 T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)274 {275 T* state = new T;276 if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))277 return state;278 else279 {280 delete state;281 return 0;282 }283 }284 215 } 285 216 -
code/trunk/src/core/input/InputPrereqs.h
r3276 r3327 30 30 @file 31 31 @brief 32 Declarations of various interface classes for the input management. 32 Declarations of all key/button/axis code enumeration and string literals 33 and an input device enumeration. 33 34 */ 34 35 … … 52 53 const unsigned int numberOfKeys = 0xEE; // 238 53 54 54 // note: KeyCode comments were directly copied from OISKeyboard.h55 //! Key codes as enumeration 55 56 enum ByEnum 56 57 { … … 202 203 }; 203 204 204 // Names as string. Has no real linkage!205 //! Key codes as strings 205 206 const char* const ByString[] = 206 207 { … … 307 308 const unsigned int numberOfButtons = 8; 308 309 310 //! Mouse button codes as enumeration 309 311 enum ByEnum 310 312 { … … 319 321 }; 320 322 321 // Names as string. Has no real linkage!323 // Mouse button codes as strings 322 324 const char* const ByString[] = 323 325 { … … 337 339 const unsigned int numberOfAxes = 2; 338 340 341 // Mouse axis codes as enumeration 339 342 enum ByEnum 340 343 { … … 343 346 }; 344 347 345 // Names as string. Has no real linkage!348 // Mouse axis codes as strings 346 349 const char* const ByString[] = 347 350 { … … 356 359 const unsigned int numberOfButtons = 64; 357 360 361 // Joy stick button codes as enumeration 358 362 enum ByEnum 359 363 { … … 380 384 }; 381 385 382 // Names as string. Has no real linkage!386 // Joy stick button codes as strings 383 387 const char* const ByString[] = 384 388 { … … 406 410 const unsigned int numberOfAxes = 24; 407 411 412 // Joy stick axis codes as enumeration 408 413 enum ByEnum 409 414 { … … 416 421 }; 417 422 418 // Names as string. Has no real linkage!423 // Joy stick axis codes as strings 419 424 const char* const ByString[] = 420 425 { … … 435 440 namespace InputDeviceEnumerator 436 441 { 442 //! Used to access the devices in an array 437 443 enum Value 438 444 { … … 442 448 }; 443 449 } 444 445 namespace ButtonEvent446 {447 enum Value448 {449 Press,450 Release,451 Hold452 };453 454 template <ButtonEvent::Value Event>455 struct EnumToType { };456 typedef EnumToType<Press> TPress;457 typedef EnumToType<Release> TRelease;458 typedef EnumToType<Hold> THold;459 }460 461 462 namespace KeyboardModifier463 {464 enum Enum465 {466 Shift = 0x0000001,467 Ctrl = 0x0000010,468 Alt = 0x0000100469 };470 }471 472 class _CoreExport KeyEvent473 {474 public:475 KeyEvent(const OIS::KeyEvent& evt)476 : key_(static_cast<KeyCode::ByEnum>(evt.key))477 , text_(evt.text)478 , modifiers_(0)479 { }480 bool operator==(const KeyEvent& rhs) const481 { return rhs.key_ == key_; }482 bool operator!=(const KeyEvent& rhs) const483 { return rhs.key_ != key_; }484 void setModifiers(int modifiers)485 { modifiers_ = modifiers; }486 487 bool isModifierDown(KeyboardModifier::Enum modifier) const488 { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }489 KeyCode::ByEnum getKeyCode() const490 { return key_; }491 unsigned int getText() const { return text_; }492 493 private:494 KeyCode::ByEnum key_;495 unsigned int text_;496 int modifiers_;497 };498 499 500 //-----------------------------------------------------------------------501 // Device type traits502 //-----------------------------------------------------------------------503 504 struct KeyboardTraits505 {506 typedef Keyboard DeviceClass;507 typedef OIS::Keyboard OISDeviceClass;508 typedef KeyEvent ButtonType;509 typedef KeyEvent& ButtonTypeParam;510 static const OIS::Type OISDeviceValue = OIS::OISKeyboard;511 };512 513 struct MouseTraits514 {515 typedef Mouse DeviceClass;516 typedef OIS::Mouse OISDeviceClass;517 typedef MouseButtonCode::ByEnum ButtonType;518 typedef MouseButtonCode::ByEnum ButtonTypeParam;519 static const OIS::Type OISDeviceValue = OIS::OISMouse;520 };521 522 struct JoyStickTraits523 {524 typedef JoyStick DeviceClass;525 typedef OIS::JoyStick OISDeviceClass;526 typedef JoyStickButtonCode::ByEnum ButtonType;527 typedef JoyStickButtonCode::ByEnum ButtonTypeParam;528 static const OIS::Type OISDeviceValue = OIS::OISJoyStick;529 };530 531 // Note: Entries correspond to OIS::Type enum532 namespace InputDeviceNames533 {534 const char* const values[] = { "", "Keyboard", "Mouse", "JoyStick" };535 }536 450 } 537 451 -
code/trunk/src/core/input/InputState.cc
r3276 r3327 32 32 namespace orxonox 33 33 { 34 InputState::InputState() 35 : priority_(0) 36 , bAlwaysGetsInput_(false) 37 , bTransparent_(false) 34 //! Sets priority of it's a high priority and resizes the handler list 35 InputState::InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority) 36 : name_(name) 37 , bAlwaysGetsInput_(bAlwaysGetsInput) 38 , bTransparent_(bTransparent) 38 39 , bExpired_(true) 39 40 , handlers_(2) … … 42 43 , leaveFunctor_(0) 43 44 { 45 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 46 priority_ = priority; 47 else 48 priority_ = 0; 49 50 handlers_.resize(InputDeviceEnumerator::FirstJoyStick + this->getJoyStickList().size(), NULL); 44 51 } 45 52 … … 52 59 } 53 60 54 void InputState::JoyStickQuantityChanged(unsigned int n) 61 //! Called by JoyStickQuantityListener upon joy stick adding/removal 62 void InputState::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) 55 63 { 56 64 unsigned int oldSize = handlers_.size(); 57 handlers_.resize(InputDeviceEnumerator::FirstJoyStick + n, NULL);65 handlers_.resize(InputDeviceEnumerator::FirstJoyStick + joyStickList.size(), NULL); 58 66 59 67 for (unsigned int i = oldSize; i < handlers_.size(); ++i) … … 63 71 } 64 72 65 /**66 @brief67 Adds a joy stick handler.68 @param handler69 Pointer to the handler object.70 @param joyStickID71 ID of the joy stick72 @return73 True if added, false otherwise.74 */75 73 bool InputState::setJoyStickHandler(InputHandler* handler, unsigned int joyStick) 76 74 { … … 84 82 } 85 83 86 /** 87 @brief 88 Adds a joy stick handler. 89 @param handler 90 Pointer to the handler object. 91 @return 92 True if added, false if handler already existed. 93 */ 94 bool InputState::setJoyStickHandler(InputHandler* handler) 84 void InputState::setJoyStickHandler(InputHandler* handler) 95 85 { 96 86 joyStickHandlerAll_ = handler; … … 98 88 handlers_[i] = handler; 99 89 bExpired_ = true; 100 return true;101 90 } 102 91 103 /** 104 @brief 105 Adds a handler of any kind. dynamic_cast determines to which list it is added. 106 @param handler 107 Pointer to the handler object. 108 @return 109 True if added, false if handler already existed. 110 */ 111 bool InputState::setHandler(InputHandler* handler) 92 void InputState::setHandler(InputHandler* handler) 112 93 { 113 94 setKeyHandler(handler); 114 95 setMouseHandler(handler); 115 returnsetJoyStickHandler(handler);96 setJoyStickHandler(handler); 116 97 } 117 98 -
code/trunk/src/core/input/InputState.h
r3196 r3327 27 27 */ 28 28 29 /**30 @file31 @brief32 */33 34 29 #ifndef _InputState_H__ 35 30 #define _InputState_H__ 36 31 37 #include "core/CorePrereqs.h" 38 32 #include "InputPrereqs.h" 33 34 #include <cassert> 39 35 #include <string> 40 36 #include <vector> 41 #include "InputInterfaces.h" 37 38 #include "util/OrxEnum.h" 39 #include "InputHandler.h" 40 #include "JoyStickQuantityListener.h" 42 41 43 42 namespace orxonox 44 43 { 45 class _CoreExport InputState 44 //! Enumeration wrapper for input state priorities 45 struct InputStatePriority : OrxEnum<InputStatePriority> 46 { 47 OrxEnumConstructors(InputStatePriority); 48 49 static const int Empty = -1; 50 static const int Dynamic = 0; 51 52 static const int HighPriority = 1000; 53 static const int Console = HighPriority + 0; 54 static const int Calibrator = HighPriority + 1; 55 static const int Detector = HighPriority + 2; 56 }; 57 58 /** 59 @brief 60 InputStates allow you to customise the input event targets at runtime. 61 62 The general idea is a stack: Every activated InputState will be pushed on 63 that stack and only the top one gets the input events. This is done for 64 every device (keyboard, mouse, all joy sticks) separately to allow 65 for intance keyboard input capturing for the console while you can still 66 steer a ship with the mouse. 67 There are two exceptions to this behaviour though: 68 - If an InputState is created with the 'Transparent' parameter on, the 69 state will not prevent input from getting to the state below it on the stack. 70 This can be useful for instance if you need to deploy input to multiple 71 handlers: Simply create two InputStates and make the high priority one transparent. 72 - If an InputState is created with the 'AlwaysGetsInput' parameter on, then 73 the state will always receive input as long as it is activated. 74 - Note: If you mark an InputState with both parameters on, then it will 75 not influence ony other InputState at all. 76 77 Priorities 78 ********** 79 Every InputState has a priority when on the stack, but mostly this 80 priority is dynamic (InputStatePriority::Dynamic) which means that a state 81 pushed onto the stack will simply have a higher priority than the top one. 82 This behaviour really only applies to normal states that don't have 83 a high priority (InputStatePriority::HighPriority). These 'special' ones 84 are used for features like the KeyDetector or the console. Use with care! 85 */ 86 class _CoreExport InputState : public JoyStickQuantityListener 46 87 { 47 88 friend class InputManager; 48 89 90 //! Marks the index in the handler vector for the keyboard handler 91 static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard; 92 //! Marks the index in the handler vector for the mouse handler 93 static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse; 94 //! Marks the index in the handler vector for the first joy stick handler 95 static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick; 96 49 97 public: 98 //! Sets the keyboard event handler (overwrites if there already was one!) 99 void setKeyHandler (InputHandler* handler) 100 { handlers_[keyboardIndex_s] = handler; bExpired_ = true; } 101 //! Sets the mouse event handler (overwrites if there already was one!) 102 void setMouseHandler (InputHandler* handler) 103 { handlers_[mouseIndex_s] = handler; bExpired_ = true; } 104 /** 105 @brief 106 Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!) 107 @return 108 Returns false if the specified device was not found 109 */ 110 bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick); 111 //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!) 112 void setJoyStickHandler(InputHandler* handler); 113 //! Sets an InputHandler to be used for all devices 114 void setHandler (InputHandler* handler); 115 116 //! Returns the name of the state (which is unique!) 50 117 const std::string& getName() const { return name_; } 118 //! Returns the priority of the state (which is unique if != 0) 51 119 int getPriority() const { return priority_; } 52 120 53 bool isInputDeviceEnabled(unsigned int device) 121 //! Tells whether there a handler installed for a specific device 122 bool isInputDeviceEnabled(unsigned int device); 123 124 //! Returns true if the handler situation has changed 125 bool hasExpired() { return this->bExpired_; } 126 //! Call this if you have applied the changes resulting from changed handlers 127 void resetExpiration() { bExpired_ = false; } 128 129 //! Updates one specific device handler with #device#Updated 130 void update(float dt, unsigned int device); 131 //! Updates all handlers with allDevicesUpdated 132 void update(float dt); 133 134 //! Generic function that distributes all 9 button events 135 template <typename EventType, class Traits> 136 void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button); 137 138 //! Event handler 139 void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize); 140 //! Event handler 141 void mouseScrolled(int abs, int rel); 142 //! Event handler 143 void joyStickAxisMoved(unsigned int device, unsigned int axis, float value); 144 145 // Functors 146 //! Called when the state is being activated (even if it doesn't get any events afterwards!) 147 void entered(); 148 //! Called upon deactivation of the state 149 void left(); 150 //! Sets a functor to be called upon activation of the state 151 void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; } 152 //! Sets a functor to be called upon deactivation of the state 153 void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; } 154 155 private: 156 InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority); 157 ~InputState() { } 158 159 void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList); 160 161 //! Sets the priority (only to be used by the InputManager!) 162 void setPriority(int priority) { priority_ = priority; } 163 164 const std::string name_; //!< Name of the state 165 const bool bAlwaysGetsInput_; //!< See class declaration for explanation 166 const bool bTransparent_; //!< See class declaration for explanation 167 int priority_; //!< Current priority (might change) 168 bool bExpired_; //!< See hasExpired() 169 std::vector<InputHandler*> handlers_; //!< Vector with all handlers where the index is the device ID 170 //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached) 171 InputHandler* joyStickHandlerAll_; 172 Functor* enterFunctor_; //!< Functor to be executed on enter 173 Functor* leaveFunctor_; //!< Functor to be executed on leave 174 }; 175 176 FORCEINLINE void InputState::update(float dt) 177 { 178 for (unsigned int i = 0; i < handlers_.size(); ++i) 179 if (handlers_[i] != NULL) 180 handlers_[i]->allDevicesUpdated(dt); 181 } 182 183 FORCEINLINE void InputState::update(float dt, unsigned int device) 184 { 185 switch (device) 54 186 { 55 if (device < bInputDeviceEnabled_.size()) 56 return bInputDeviceEnabled_[device]; 57 else 58 return false; 187 case InputDeviceEnumerator::Keyboard: 188 if (handlers_[keyboardIndex_s] != NULL) 189 handlers_[keyboardIndex_s]->keyboardUpdated(dt); 190 break; 191 192 case InputDeviceEnumerator::Mouse: 193 if (handlers_[mouseIndex_s] != NULL) 194 handlers_[mouseIndex_s]->mouseUpdated(dt); 195 break; 196 197 default: // joy sticks 198 if (handlers_[device] != NULL) 199 handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt); 200 break; 59 201 } 60 61 bool handlersChanged() { return this->bHandlersChanged_; } 62 void resetHandlersChanged() { bHandlersChanged_ = false; } 63 64 virtual void onEnter() = 0; 65 virtual void onLeave() = 0; 66 67 virtual void registerOnEnter(Executor* executor) { executorOnEnter_ = executor; } 68 virtual void unRegisterOnEnter() { executorOnEnter_ = 0; } 69 virtual void registerOnLeave(Executor* executor) { executorOnLeave_ = executor; } 70 virtual void unRegisterOnLeave() { executorOnLeave_ = 0; } 71 72 virtual void updateInput(float dt, unsigned int device) = 0; 73 virtual void updateInput(float dt) = 0; 74 75 virtual void keyPressed (const KeyEvent& evt) = 0; 76 virtual void keyReleased(const KeyEvent& evt) = 0; 77 virtual void keyHeld (const KeyEvent& evt) = 0; 78 79 virtual void mouseButtonPressed (MouseButtonCode::ByEnum id) = 0; 80 virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0; 81 virtual void mouseButtonHeld (MouseButtonCode::ByEnum id) = 0; 82 virtual void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0; 83 virtual void mouseScrolled (int abs, int rel) = 0; 84 85 virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0; 86 virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0; 87 virtual void joyStickButtonHeld (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0; 88 virtual void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value) = 0; 89 90 protected: 91 InputState() 92 : bHandlersChanged_(false) 93 , executorOnEnter_(0) 94 , executorOnLeave_(0) 95 , priority_(0) 96 , bAlwaysGetsInput_(false) 97 , bTransparent_(false) 98 { } 99 virtual ~InputState() { } 100 101 virtual void numberOfJoySticksChanged(unsigned int n) = 0; 102 void setInputDeviceEnabled(unsigned int device, bool bEnabled) 103 { 104 if (device < bInputDeviceEnabled_.size()) 105 bInputDeviceEnabled_[device] = bEnabled; 106 } 107 108 bool bHandlersChanged_; 109 Executor* executorOnEnter_; 110 Executor* executorOnLeave_; 111 112 private: 113 void setNumOfJoySticks(unsigned int n) 114 { 115 bInputDeviceEnabled_.resize(n + 2); 116 numberOfJoySticksChanged(n); 117 } 118 void setName(const std::string& name) { name_ = name; } 119 void setPriority(int priority) { priority_ = priority; } 120 121 std::string name_; 122 int priority_; 123 std::vector<bool> bInputDeviceEnabled_; 124 bool bAlwaysGetsInput_; 125 bool bTransparent_; 126 }; 202 } 203 204 template <typename EventType, class Traits> 205 FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button) 206 { 207 assert(device < handlers_.size()); 208 if (handlers_[device] != NULL) 209 handlers_[device]->buttonEvent(device, button, EventType()); 210 } 211 212 FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) 213 { 214 if (handlers_[mouseIndex_s] != NULL) 215 handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize); 216 } 217 218 FORCEINLINE void InputState::mouseScrolled(int abs, int rel) 219 { 220 if (handlers_[mouseIndex_s] != NULL) 221 handlers_[mouseIndex_s]->mouseScrolled(abs, rel); 222 } 223 224 FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value) 225 { 226 assert(device < handlers_.size()); 227 if (handlers_[device] != NULL) 228 handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value); 229 } 127 230 } 128 231 -
code/trunk/src/core/input/JoyStick.cc
r3270 r3327 27 27 */ 28 28 29 /**30 @file31 @brief32 Implementation of the JoyStick wrapper class.33 */34 35 29 #include "JoyStick.h" 36 30 37 31 #include <ois/OISJoyStick.h> 38 #include <ois/OISInputManager.h>39 32 #include <boost/foreach.hpp> 40 33 … … 44 37 #include "util/Convert.h" 45 38 #include "InputState.h" 46 #include "InputManager.h"47 39 48 40 namespace orxonox 49 41 { 50 /** 51 @brief 52 Helper function that loads the config value vector of one coefficient 53 */ 42 //! Helper function that loads the config value vector of one coefficient 54 43 void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue); 55 44 56 JoyStick::JoyStick(const std::vector<InputState*>& states, unsigned int id)57 : id_(id) 58 , bCalibrating_(false)59 , inputStates_(states)45 std::vector<std::string> JoyStick::deviceNames_s; 46 47 JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager) 48 : super(id, oisInputManager) 60 49 { 61 50 RegisterRootObject(JoyStick); 62 51 this->setConfigValues(); 63 64 OIS::InputManager* system = InputManager::getInstance().getInputSystem(); 65 oisJoyStick_ = static_cast<OIS::JoyStick*>(system->createInputObject(OIS::OISJoyStick, true)); 66 oisJoyStick_->setEventCallback(this); 67 68 idString_ = "JoyStick_"; 69 std::string name = oisJoyStick_->vendor(); 70 replaceCharacters(name, ' ', '_'); 71 idString_ += name + "_"; 72 idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Button)) + "_"; 73 idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis)) + "_"; 74 idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Slider)) + "_"; 75 idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_POV)); 76 //idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Vector3)); 77 78 if (InputManager::getInstance().checkJoyStickID(idString_) == false) 79 { 80 // Make the ID unique for this execution time. 81 idString_ += "_" + multi_cast<std::string>(id_); 82 } 83 84 COUT(4) << "Created OIS joy stick with ID " << idString_ << std::endl; 52 // Initialise POV and Slider states 53 this->clearBuffersImpl(); 54 55 // Generate unique name 56 if (oisDevice_->vendor().empty()) 57 deviceName_ = "Unknown_"; 58 else 59 { 60 std::string name = oisDevice_->vendor(); 61 replaceCharacters(name, ' ', '_'); 62 deviceName_ = name + "_"; 63 } 64 deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button)) + "_"; 65 deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis)) + "_"; 66 deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider)) + "_"; 67 deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV)); 68 //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3)); 69 70 BOOST_FOREACH(std::string& idString, deviceNames_s) 71 { 72 if (deviceName_ == idString) 73 { 74 // Make the ID unique for this execution time. 75 deviceName_ += "_" + multi_cast<std::string>(this->getDeviceName()); 76 break; 77 } 78 } 79 80 COUT(4) << "Created OIS joy stick with ID " << deviceName_ << std::endl; 85 81 86 82 // Load calibration 87 size_t axes = sliderAxes_s + static_cast<size_t>(ois JoyStick_->getNumberOfComponents(OIS::OIS_Axis));88 loadCalibration(configMinValues_, idString_, "MinValue", axes, -32768);89 loadCalibration(configMaxValues_, idString_, "MaxValue", axes, 32768);90 loadCalibration(configZeroValues_, idString_, "ZeroValue", axes, 0);83 size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis)); 84 loadCalibration(configMinValues_, deviceName_, "MinValue", axes, -32768); 85 loadCalibration(configMaxValues_, deviceName_, "MaxValue", axes, 32768); 86 loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0); 91 87 this->evaluateCalibration(); 92 88 } 93 89 94 JoyStick::~JoyStick() 95 { 96 try 97 { 98 OIS::InputManager* system = InputManager::getInstance().getInputSystem(); 99 system->destroyInputObject(oisJoyStick_); 100 } 101 catch (...) 102 { 103 COUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl; 104 } 105 } 106 107 /** 108 @brief 109 Callback for the joy stick calibration config file. @see setConfigValues. 110 */ 90 //! Callback for the joy stick calibration config file. 111 91 void JoyStick::calibrationFileCallback() 112 92 { … … 114 94 } 115 95 116 /**117 @brief118 Sets the configurable values.119 */120 96 void JoyStick::setConfigValues() 121 97 { … … 140 116 // fill the rest with default values 141 117 for (unsigned int i = configValueVectorSize; i < size; ++i) 142 {143 118 list[i] = defaultValue; 144 } 145 } 146 147 void JoyStick::startCalibration() 148 { 149 bCalibrating_ = true; 150 119 } 120 121 //! Called by InputDevice when calibration mode has started 122 void JoyStick::calibrationStarted() 123 { 151 124 // Set initial values 152 125 BOOST_FOREACH(int& minVal, configMinValues_) … … 158 131 } 159 132 160 void JoyStick::stopCalibration() 133 //! Called by InputDevice when calibration mode has stopped 134 void JoyStick::calibrationStopped() 161 135 { 162 136 // Get the middle positions now … … 164 138 for (unsigned int i = 0; i < sliderAxes_s/2; ++i) 165 139 { 166 configZeroValues_[iAxis++] = ois JoyStick_->getJoyStickState().mSliders[i].abX;167 configZeroValues_[iAxis++] = ois JoyStick_->getJoyStickState().mSliders[i].abY;168 } 169 // Note: joyStick MiddleValues_[iJoyStick] was already correctly resised in loadCalibration()170 assert(ois JoyStick_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);140 configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX; 141 configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY; 142 } 143 // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration() 144 assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s); 171 145 for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i) 172 configZeroValues_[iAxis++] = ois JoyStick_->getJoyStickState().mAxes[i].abs;146 configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs; 173 147 174 148 for (unsigned int i = 0; i < configMinValues_.size(); ++i) … … 178 152 configMinValues_[i] = -32768; 179 153 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 180 idString_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);154 deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false); 181 155 182 156 // Maximum values … … 184 158 configMaxValues_[i] = 32767; 185 159 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 186 idString_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);160 deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false); 187 161 188 162 // Middle values 189 163 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration, 190 idString_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);164 deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false); 191 165 } 192 166 193 167 this->evaluateCalibration(); 194 195 bCalibrating_ = false; 196 } 197 168 } 169 170 //! Evaluates the accumulated values during calibration 198 171 void JoyStick::evaluateCalibration() 199 172 { … … 206 179 } 207 180 208 void JoyStick::clearBuffer()209 {210 pressedButtons_.clear();181 //! Resets the pov states 182 void JoyStick::clearBuffersImpl() 183 { 211 184 for (int j = 0; j < 4; ++j) 212 {213 185 povStates_[j] = 0; 214 sliderStates_[j][0] = 0; 215 sliderStates_[j][1] = 0; 216 } 217 } 218 219 220 // ###### Events ###### 221 222 void JoyStick::capture() 223 { 224 oisJoyStick_->capture(); 225 226 // call all the handlers for the held joy stick button events 227 for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++) 228 { 229 BOOST_FOREACH(InputState* state, inputStates_) 230 state->joyStickButtonHeld(id_, pressedButtons_[iButton]); 231 } 232 } 233 234 bool JoyStick::buttonPressed(const OIS::JoyStickEvent &arg, int button) 235 { 236 // check whether the button already is in the list (can happen when focus was lost) 237 unsigned int iButton = 0; 238 while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button) 239 iButton++; 240 if (iButton == pressedButtons_.size()) 241 pressedButtons_.push_back(static_cast<JoyStickButtonCode::ByEnum>(button)); 242 243 BOOST_FOREACH(InputState* state, inputStates_) 244 state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button)); 245 246 return true; 247 } 248 249 bool JoyStick::buttonReleased(const OIS::JoyStickEvent &arg, int button) 250 { 251 // remove the button from the pressedButtons_ list 252 for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++) 253 { 254 if (static_cast<int>(pressedButtons_[iButton]) == button) 255 { 256 pressedButtons_.erase(pressedButtons_.begin() + iButton); 257 break; 258 } 259 } 260 261 BOOST_FOREACH(InputState* state, inputStates_) 262 state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button)); 263 264 return true; 265 } 266 267 /** 268 @brief 269 Calls the states for a particular axis with our enumeration. 270 Used by OIS sliders and OIS axes. 271 */ 186 } 187 188 //! Generic method to forward axis events 272 189 void JoyStick::fireAxis(int axis, int value) 273 190 { 274 if ( bCalibrating_)191 if (this->isCalibrating()) 275 192 { 276 193 if (value < configMinValues_[axis]) … … 288 205 289 206 BOOST_FOREACH(InputState* state, inputStates_) 290 state->joyStickAxisMoved(id_, axis, fValue); 291 } 292 } 293 207 state->joyStickAxisMoved(this->getDeviceID(), axis, fValue); 208 } 209 } 210 211 //! OIS joy stick axis event handler 294 212 bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis) 295 213 { … … 300 218 } 301 219 220 //! A Slider always has an X and an Y direction! 302 221 bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id) 303 222 { … … 310 229 } 311 230 231 //! A POV is the big button that can point in all directions (but only in one at once) 312 232 bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id) 313 233 { -
code/trunk/src/core/input/JoyStick.h
r3270 r3327 27 27 */ 28 28 29 /** 30 @file 31 @brief 32 */ 29 #ifndef _Core_JoyStick_H__ 30 #define _Core_JoyStick_H__ 33 31 34 #ifndef _JoyStick_H__ 35 #define _JoyStick_H__ 36 37 #include "core/CorePrereqs.h" 32 #include "InputPrereqs.h" 38 33 39 34 #include <string> 40 35 #include <vector> 41 #include "Input Interfaces.h"36 #include "InputDevice.h" 42 37 43 38 namespace orxonox 44 39 { 45 class _CoreExport JoyStick : public OrxonoxClass, public OIS::JoyStickListener 40 //! Template parameter collection for the base class 41 struct JoyStickTraits 46 42 { 47 private: 48 struct JoyStickCalibration 49 { 50 }; 43 typedef JoyStick DeviceClass; 44 typedef OIS::JoyStick OISDeviceClass; 45 typedef JoyStickButtonCode::ByEnum ButtonType; 46 typedef JoyStickButtonCode::ByEnum ButtonTypeParam; 47 static const OIS::Type OISDeviceValue = OIS::OISJoyStick; 48 }; 49 50 /** 51 @brief 52 Wraps around an OIS::JoyStick and forwards the input events to 53 a list of input states. 54 55 The class also supports joy stick calibration and stores the values 56 in an ini-file. 57 */ 58 class _CoreExport JoyStick 59 : public OrxonoxClass 60 , public InputDeviceTemplated<JoyStickTraits> 61 , public OIS::JoyStickListener 62 { 63 friend class InputDeviceTemplated<JoyStickTraits>; 64 //! Super class alias 65 typedef InputDeviceTemplated<JoyStickTraits> super; 51 66 52 67 public: 53 JoyStick(const std::vector<InputState*>& states, unsigned int id);54 ~JoyStick();55 68 //! Assigns a generated ID string and loads the calibration (if present) 69 JoyStick(unsigned int id, OIS::InputManager* oisInputManager); 70 ~JoyStick() { } 56 71 void setConfigValues(); 57 72 58 OIS::JoyStick* getOISJoyStick() { return this->oisJoyStick_; } 59 const std::string& getIDString() const { return this->idString_; } 60 61 void startCalibration(); 62 void stopCalibration(); 63 64 void capture(); 65 void clearBuffer(); 73 //! Returns the name generated from the number of knobs and the device name 74 const std::string& getDeviceName() const { return this->deviceName_; } 66 75 67 76 private: 77 void calibrationStarted(); 78 void calibrationStopped(); 79 void evaluateCalibration(); 80 81 void clearBuffersImpl(); 68 82 void calibrationFileCallback(); 69 void evaluateCalibration();70 83 void fireAxis(int axis, int value); 71 84 72 bool buttonPressed (const OIS::JoyStickEvent &arg, int button); 73 bool buttonReleased(const OIS::JoyStickEvent &arg, int button); 85 //! OIS event handler 86 bool buttonPressed (const OIS::JoyStickEvent &arg, int button) 87 { 88 super::buttonPressed(static_cast<JoyStickButtonCode::ByEnum>(button)); 89 return true; 90 } 91 92 //! OIS event handler 93 bool buttonReleased(const OIS::JoyStickEvent &arg, int button) 94 { 95 super::buttonReleased(static_cast<JoyStickButtonCode::ByEnum>(button)); 96 return true; 97 } 98 74 99 bool axisMoved (const OIS::JoyStickEvent &arg, int axis); 75 100 bool sliderMoved (const OIS::JoyStickEvent &arg, int id); 76 101 bool povMoved (const OIS::JoyStickEvent &arg, int id); 77 // don't remove that! Or else add OIS as dependency library to orxonox (it actually is..)102 //! OIS event handler (don't remove that because of OIS version issues!) 78 103 bool vector3Moved (const OIS::JoyStickEvent &arg, int id) { return true; } 79 104 80 static const unsigned int sliderAxes_s = 8; 105 //! Returns the class name as string 106 static std::string getClassNameImpl() { return "JoyStick"; } 81 107 82 OIS::JoyStick* oisJoyStick_;83 const unsigned int id_;84 std::string idString_;108 std::string deviceName_; //!< Name generated by the number of knobs and the device name 109 int povStates_[4]; //!< Internal states for the POVs 110 int sliderStates_[4][2]; //!< Internal states for the Sliders (each slider has X and Y!) 85 111 86 112 // calibration 87 bool bCalibrating_; 88 int zeroValues_[24]; 89 float positiveCoeffs_[24]; 90 float negativeCoeffs_[24]; 113 int zeroValues_[24]; //!< Axes values when the knob is in the middle 114 float positiveCoeffs_[24]; //!< Maps the negative part of an axis to a 0.0 to 1.0 floating range 115 float negativeCoeffs_[24]; //!< Maps the positive part of an axis to a 0.0 to 1.0 floating range 91 116 92 std::vector<int> configMinValues_; 93 std::vector<int> configMaxValues_; 94 std::vector<int> configZeroValues_; 95 96 int povStates_[4]; 97 int sliderStates_[4][2]; 98 std::vector<JoyStickButtonCode::ByEnum> pressedButtons_; 99 100 // InputState handling 101 const std::vector<InputState*>& inputStates_; 117 std::vector<int> configZeroValues_; //!< Config file stored axis values when the knob is in the middle 118 std::vector<int> configMinValues_; //!< Config file stored minimum axis values 119 std::vector<int> configMaxValues_; //!< Config file stored maximum axis values 102 120 103 121 // ConfigValues 104 std::string calibrationFilename_; //!< Joy stick calibration ini filename 122 std::string calibrationFilename_; //!< Joy stick calibration ini filename 123 124 //! Contains a list of all names to avoid duplicates 125 static std::vector<std::string> deviceNames_s; 126 127 //!< Maximum number of slider axes 128 static const unsigned int sliderAxes_s = 8; 105 129 }; 106 130 } 107 131 108 #endif /* _ JoyStick_H__ */132 #endif /* _Core_JoyStick_H__ */ -
code/trunk/src/core/input/JoyStickQuantityListener.cc
r3276 r3327 27 27 */ 28 28 29 /** 30 @file 31 @brief 32 Implementation of the JoyStickQuantityListener class. 33 */ 29 #include "JoyStickQuantityListener.h" 34 30 35 #include "JoyStickQuantityListener.h"36 31 #include "core/CoreIncludes.h" 32 #include "core/ObjectList.h" 37 33 38 34 namespace orxonox 39 35 { 36 std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s; 37 40 38 JoyStickQuantityListener::JoyStickQuantityListener() 41 39 { 42 40 RegisterObject(JoyStickQuantityListener); 43 41 } 42 43 //! Calls all registered objects and sets the static variable 44 /*static*/ void JoyStickQuantityListener::changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList) 45 { 46 joyStickList_s = joyStickList; 47 for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it) 48 it->JoyStickQuantityChanged(joyStickList); 49 } 44 50 } -
code/trunk/src/core/input/JoyStickQuantityListener.h
r3276 r3327 40 40 namespace orxonox 41 41 { 42 //! Derive from this class to get informed when joy sticks get added/removed 42 43 class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass 43 44 { 44 public: 45 friend class InputManager; 46 protected: 45 47 JoyStickQuantityListener(); 46 48 virtual ~JoyStickQuantityListener() { } 47 49 48 virtual void JoyStickQuantityChanged(unsigned int value) = 0; 50 //! Returns a list with all JoySticks currently loaded 51 const std::vector<JoyStick*>& getJoyStickList() const { return joyStickList_s; } 52 53 private: 54 //! Called whenever joy sticks get added/removed 55 virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) = 0; 56 57 static void changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList); 58 59 //! Static variable that holds the latest distributed information 60 static std::vector<JoyStick*> joyStickList_s; 49 61 }; 50 62 } -
code/trunk/src/core/input/KeyBinder.cc
r3301 r3327 40 40 #include "core/ConfigFileManager.h" 41 41 #include "InputCommands.h" 42 #include " InputManager.h"42 #include "JoyStick.h" 43 43 44 44 namespace orxonox … … 49 49 */ 50 50 KeyBinder::KeyBinder() 51 : numberOfJoySticks_(0) 52 , deriveTime_(0.0f) 51 : deriveTime_(0.0f) 53 52 { 54 53 mouseRelative_[0] = 0; … … 56 55 mousePosition_[0] = 0; 57 56 mousePosition_[1] = 0; 57 58 joyStickButtons_.reserve(1000); 59 joyStickAxes_.reserve(1000); 58 60 59 61 RegisterRootObject(KeyBinder); … … 80 82 else 81 83 nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons]; 82 mouseButtons_[i].name_ = std::string("Mouse") +nameSuffix;84 mouseButtons_[i].name_ = nameSuffix; 83 85 mouseButtons_[i].paramCommandBuffer_ = ¶mCommandBuffer_; 84 86 mouseButtons_[i].groupName_ = "MouseButtons"; … … 87 89 for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++) 88 90 { 89 mouseAxes_[i].name_ = std::string("Mouse") +MouseAxisCode::ByString[i / 2];91 mouseAxes_[i].name_ = MouseAxisCode::ByString[i / 2]; 90 92 if (i & 1) 91 93 mouseAxes_[i].name_ += "Pos"; … … 100 102 101 103 // initialise joy sticks separatly to allow for reloading 102 numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks(); 103 initialiseJoyStickBindings(); 104 105 // collect all Buttons and HalfAxes 106 compilePointerLists(); 104 this->JoyStickQuantityChanged(this->getJoyStickList()); 107 105 108 106 // set them here to use allHalfAxes_ … … 152 150 } 153 151 154 void KeyBinder::JoyStick DeviceNumberChanged(unsigned int value)155 { 156 unsigned int oldValue = numberOfJoySticks_;157 numberOfJoySticks_ = value;152 void KeyBinder::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) 153 { 154 unsigned int oldValue = joySticks_.size(); 155 joySticks_ = joyStickList; 158 156 159 157 // initialise joy stick bindings … … 166 164 if (configFile_ != ConfigFileType::NoType) 167 165 { 168 for (unsigned int iDev = oldValue; iDev < numberOfJoySticks_; ++iDev)166 for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev) 169 167 { 170 168 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i) … … 181 179 void KeyBinder::initialiseJoyStickBindings() 182 180 { 183 this->joyStickAxes_.resize( numberOfJoySticks_);184 this->joyStickButtons_.resize( numberOfJoySticks_);181 this->joyStickAxes_.resize(joySticks_.size()); 182 this->joyStickButtons_.resize(joySticks_.size()); 185 183 186 184 // reinitialise all joy stick binings (doesn't overwrite the old ones) 187 for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)188 { 189 std::string deviceN umber = multi_cast<std::string>(iDev);185 for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++) 186 { 187 std::string deviceName = joySticks_[iDev]->getDeviceName(); 190 188 // joy stick buttons 191 189 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++) 192 190 { 193 joyStickButtons_[iDev][i].name_ = std::string("JoyStick") + deviceNumber +JoyStickButtonCode::ByString[i];191 joyStickButtons_[iDev][i].name_ = JoyStickButtonCode::ByString[i]; 194 192 joyStickButtons_[iDev][i].paramCommandBuffer_ = ¶mCommandBuffer_; 195 joyStickButtons_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Buttons";193 joyStickButtons_[iDev][i].groupName_ = "JoyStickButtons_" + deviceName; 196 194 } 197 195 // joy stick axes 198 196 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++) 199 197 { 200 joyStickAxes_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickAxisCode::ByString[i >> 1];198 joyStickAxes_[iDev][i].name_ = JoyStickAxisCode::ByString[i / 2]; 201 199 if (i & 1) 202 200 joyStickAxes_[iDev][i].name_ += "Pos"; … … 204 202 joyStickAxes_[iDev][i].name_ += "Neg"; 205 203 joyStickAxes_[iDev][i].paramCommandBuffer_ = ¶mCommandBuffer_; 206 joyStickAxes_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Axes";204 joyStickAxes_[iDev][i].groupName_ = "JoyStickAxes_" + deviceName; 207 205 } 208 206 } … … 217 215 for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++) 218 216 if (!keys_[i].name_.empty()) 219 allButtons_[keys_[i]. name_] = keys_ + i;217 allButtons_[keys_[i].groupName_ + "." + keys_[i].name_] = keys_ + i; 220 218 for (unsigned int i = 0; i < numberOfMouseButtons_; i++) 221 allButtons_[mouseButtons_[i]. name_] = mouseButtons_ + i;219 allButtons_[mouseButtons_[i].groupName_ + "." + mouseButtons_[i].name_] = mouseButtons_ + i; 222 220 for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++) 223 221 { 224 allButtons_[mouseAxes_[i]. name_] = mouseAxes_ + i;222 allButtons_[mouseAxes_[i].groupName_ + "." + mouseAxes_[i].name_] = mouseAxes_ + i; 225 223 allHalfAxes_.push_back(mouseAxes_ + i); 226 224 } 227 for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)225 for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++) 228 226 { 229 227 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++) 230 allButtons_[joyStickButtons_[iDev][i]. name_] = &(joyStickButtons_[iDev][i]);228 allButtons_[joyStickButtons_[iDev][i].groupName_ + "." + joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]); 231 229 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++) 232 230 { 233 allButtons_[joyStickAxes_[iDev][i]. name_] = &(joyStickAxes_[iDev][i]);231 allButtons_[joyStickAxes_[iDev][i].groupName_ + "." + joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]); 234 232 allHalfAxes_.push_back(&(joyStickAxes_[iDev][i])); 235 233 } … … 301 299 void KeyBinder::resetJoyStickAxes() 302 300 { 303 for (unsigned int iDev = 0; iDev < numberOfJoySticks_; ++iDev)301 for (unsigned int iDev = 0; iDev < joySticks_.size(); ++iDev) 304 302 { 305 303 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++) … … 311 309 } 312 310 313 void KeyBinder:: updateMouse(float dt)311 void KeyBinder::mouseUpdated(float dt) 314 312 { 315 313 if (bDeriveMouseInput_) … … 364 362 } 365 363 366 void KeyBinder:: updateJoyStick(float dt, unsigned int joyStick)364 void KeyBinder::joyStickUpdated(unsigned int joyStick, float dt) 367 365 { 368 366 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++) … … 480 478 } 481 479 482 void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value) 483 { 484 int i = axis * 2; 480 void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value) 481 { 482 int i = axisID * 2; 483 JoyStickAxisVector& axis = joyStickAxes_[device]; 485 484 if (value < 0) 486 485 { 487 joyStickAxes_[joyStickID][i].absVal_ = -value;488 joyStickAxes_[joyStickID][i].relVal_ = -value;489 joyStickAxes_[joyStickID][i].hasChanged_ = true;490 if ( joyStickAxes_[joyStickID][i + 1].absVal_ > 0.0f)491 { 492 joyStickAxes_[joyStickID][i + 1].absVal_ = -0.0f;493 joyStickAxes_[joyStickID][i + 1].relVal_ = -0.0f;494 joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;486 axis[i].absVal_ = -value; 487 axis[i].relVal_ = -value; 488 axis[i].hasChanged_ = true; 489 if (axis[i + 1].absVal_ > 0.0f) 490 { 491 axis[i + 1].absVal_ = -0.0f; 492 axis[i + 1].relVal_ = -0.0f; 493 axis[i + 1].hasChanged_ = true; 495 494 } 496 495 } 497 496 else 498 497 { 499 joyStickAxes_[joyStickID][i + 1].absVal_ = value;500 joyStickAxes_[joyStickID][i + 1].relVal_ = value;501 joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;502 if ( joyStickAxes_[joyStickID][i].absVal_ > 0.0f)503 { 504 joyStickAxes_[joyStickID][i].absVal_ = -0.0f;505 joyStickAxes_[joyStickID][i].relVal_ = -0.0f;506 joyStickAxes_[joyStickID][i].hasChanged_ = true;498 axis[i + 1].absVal_ = value; 499 axis[i + 1].relVal_ = value; 500 axis[i + 1].hasChanged_ = true; 501 if (axis[i].absVal_ > 0.0f) 502 { 503 axis[i].absVal_ = -0.0f; 504 axis[i].relVal_ = -0.0f; 505 axis[i].hasChanged_ = true; 507 506 } 508 507 } -
code/trunk/src/core/input/KeyBinder.h
r3196 r3327 36 36 #define _KeyBinder_H__ 37 37 38 #include " core/CorePrereqs.h"38 #include "InputPrereqs.h" 39 39 40 40 #include <cassert> … … 42 42 #include <vector> 43 43 44 #include "Input Interfaces.h"44 #include "InputHandler.h" 45 45 #include "Button.h" 46 46 #include "HalfAxis.h" 47 47 #include "InputCommands.h" 48 #include "JoyStick DeviceNumberListener.h"48 #include "JoyStickQuantityListener.h" 49 49 50 50 namespace orxonox … … 55 55 Manages the key bindings. 56 56 */ 57 class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, 58 public JoyStickDeviceNumberListener 57 class _CoreExport KeyBinder : public InputHandler, public JoyStickQuantityListener 59 58 { 60 59 public: … … 69 68 70 69 protected: // functions 71 void updateInput(float dt); 72 void updateKey(float dt) { } 73 void updateMouse(float dt); 74 void updateJoyStick(float dt, unsigned int joyStick); 70 void allDevicesUpdated(float dt); 71 void mouseUpdated(float dt); 72 void joyStickUpdated(unsigned int joyStick, float dt); 75 73 // internal 76 74 void tickHalfAxis(HalfAxis& halfAxis); 77 75 78 76 void buttonThresholdChanged(); 79 // from JoyStick DeviceNumberListener interface80 virtual void JoyStick DeviceNumberChanged(unsigned int value);77 // from JoyStickQuantityListener interface 78 virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList); 81 79 void initialiseJoyStickBindings(); 82 80 void compilePointerLists(); 83 81 84 void keyPressed (const KeyEvent& evt);85 void keyReleased(const KeyEvent& evt);86 void keyHeld (const KeyEvent& evt);87 88 void mouseButtonPressed (MouseButtonCode::ByEnum id);89 void mouseButtonReleased(MouseButtonCode::ByEnum id);90 void mouseButtonHeld (MouseButtonCode::ByEnum id);91 void mouseMoved 92 void mouseScrolled 93 94 void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);95 void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);96 void joyStickButtonHeld (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);97 void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value);82 void buttonPressed (const KeyEvent& evt); 83 void buttonReleased(const KeyEvent& evt); 84 void buttonHeld (const KeyEvent& evt); 85 86 void buttonPressed (MouseButtonCode::ByEnum button); 87 void buttonReleased(MouseButtonCode::ByEnum button); 88 void buttonHeld (MouseButtonCode::ByEnum button); 89 void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize); 90 void mouseScrolled (int abs, int rel); 91 92 void buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button); 93 void buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button); 94 void buttonHeld (unsigned int device, JoyStickButtonCode::ByEnum button); 95 void axisMoved (unsigned int device, unsigned int axis, float value); 98 96 99 97 protected: // variables 100 98 //! Currently active joy sticks 101 unsigned int numberOfJoySticks_;99 std::vector<JoyStick*> joySticks_; 102 100 103 101 //! Actual key bindings for keys on the keyboard … … 172 170 }; 173 171 174 inline void KeyBinder:: keyPressed (const KeyEvent& evt)175 { assert(!keys_[evt. key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnPress); }176 177 inline void KeyBinder:: keyReleased(const KeyEvent& evt)178 { assert(!keys_[evt. key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnRelease); }179 180 inline void KeyBinder:: keyHeld (const KeyEvent& evt)181 { assert(!keys_[evt. key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnHold); }182 183 184 inline void KeyBinder:: mouseButtonPressed (MouseButtonCode::ByEnum id)185 { mouseButtons_[ id].execute(KeybindMode::OnPress); }186 187 inline void KeyBinder:: mouseButtonReleased(MouseButtonCode::ByEnum id)188 { mouseButtons_[ id].execute(KeybindMode::OnRelease); }189 190 inline void KeyBinder:: mouseButtonHeld (MouseButtonCode::ByEnum id)191 { mouseButtons_[ id].execute(KeybindMode::OnHold); }192 193 194 inline void KeyBinder:: joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)195 { joyStickButtons_[ joyStickID][id].execute(KeybindMode::OnPress); }196 197 inline void KeyBinder:: joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)198 { joyStickButtons_[ joyStickID][id].execute(KeybindMode::OnRelease); }199 200 inline void KeyBinder:: joyStickButtonHeld (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)201 { joyStickButtons_[ joyStickID][id].execute(KeybindMode::OnHold); }202 203 inline void KeyBinder:: updateInput(float dt)172 inline void KeyBinder::buttonPressed (const KeyEvent& evt) 173 { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnPress); } 174 175 inline void KeyBinder::buttonReleased(const KeyEvent& evt) 176 { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnRelease); } 177 178 inline void KeyBinder::buttonHeld (const KeyEvent& evt) 179 { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnHold); } 180 181 182 inline void KeyBinder::buttonPressed (MouseButtonCode::ByEnum button) 183 { mouseButtons_[button].execute(KeybindMode::OnPress); } 184 185 inline void KeyBinder::buttonReleased(MouseButtonCode::ByEnum button) 186 { mouseButtons_[button].execute(KeybindMode::OnRelease); } 187 188 inline void KeyBinder::buttonHeld (MouseButtonCode::ByEnum button) 189 { mouseButtons_[button].execute(KeybindMode::OnHold); } 190 191 192 inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button) 193 { joyStickButtons_[device][button].execute(KeybindMode::OnPress); } 194 195 inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button) 196 { joyStickButtons_[device][button].execute(KeybindMode::OnRelease); } 197 198 inline void KeyBinder::buttonHeld (unsigned int device, JoyStickButtonCode::ByEnum button) 199 { joyStickButtons_[device][button].execute(KeybindMode::OnHold); } 200 201 inline void KeyBinder::allDevicesUpdated(float dt) 204 202 { 205 203 // execute all buffered bindings (additional parameter) -
code/trunk/src/core/input/KeyDetector.cc
r3196 r3327 26 26 * 27 27 */ 28 29 /**30 @file31 @brief32 Implementation of the different input handlers.33 */34 28 35 29 #include "KeyDetector.h" … … 68 62 for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it) 69 63 { 70 it->second->bindingString_ = callbackCommand_ + it->second-> name_;64 it->second->bindingString_ = callbackCommand_ + it->second->groupName_ + "." + it->second->name_; 71 65 it->second->parse(); 72 66 } 73 67 } 74 68 75 void KeyDetector::JoyStick DeviceNumberChanged(unsigned int value)69 void KeyDetector::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) 76 70 { 77 KeyBinder::JoyStick DeviceNumberChanged(value);71 KeyBinder::JoyStickQuantityChanged(joyStickList); 78 72 setCallbackCommand(callbackCommand_); 79 73 } -
code/trunk/src/core/input/KeyDetector.h
r3196 r3327 27 27 */ 28 28 29 /**30 @file31 @brief32 Different definitions of input processing.33 */34 35 29 #ifndef _KeyDetector_H__ 36 30 #define _KeyDetector_H__ 37 31 38 #include " core/CorePrereqs.h"32 #include "InputPrereqs.h" 39 33 40 34 #include <string> … … 49 43 ~KeyDetector(); 50 44 void setCallbackCommand(const std::string& command); 51 void JoyStick DeviceNumberChanged(unsigned int value);45 void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList); 52 46 53 47 private: -
code/trunk/src/core/input/Keyboard.h
r3276 r3327 31 31 32 32 #include "InputPrereqs.h" 33 34 #include "InputHandler.h" 33 35 #include "InputDevice.h" 34 36 35 37 namespace orxonox 36 38 { 39 //! Template parameter collection for the base class 40 struct KeyboardTraits 41 { 42 typedef Keyboard DeviceClass; 43 typedef OIS::Keyboard OISDeviceClass; 44 typedef KeyEvent ButtonType; 45 typedef KeyEvent& ButtonTypeParam; 46 static const OIS::Type OISDeviceValue = OIS::OISKeyboard; 47 }; 48 37 49 /** 38 50 @brief … … 51 63 52 64 public: 53 Keyboard(unsigned int id) : super(id), modifiers_(0) { } 65 //! Only resets the keyboard modifiers. Initialising is done in the base class. 66 Keyboard(unsigned int id, OIS::InputManager* oisInputManager) : super(id, oisInputManager), modifiers_(0) { } 54 67 ~Keyboard() { } 55 68 56 69 private: 57 // TODO: Do we need to reset the modifiers?58 void clearBuffersImpl() { }70 //! Resets the keyboard modifiers 71 void clearBuffersImpl() { this->modifiers_ = 0; } 59 72 //! Translates the KeyHandle to a KeyEvent 60 KeyEvent& getButtonEventArg(KeyEvent& button) { button.setModifiers(modifiers_); return button; } 73 KeyEvent& getButtonEventArg(KeyEvent& button) 74 { 75 button.setModifiers(modifiers_); 76 return button; 77 } 61 78 62 79 bool keyPressed(const OIS::KeyEvent& arg); 63 80 bool keyReleased(const OIS::KeyEvent& arg); 81 82 //! Returns the class name as string 83 static std::string getClassNameImpl() { return "Keyboard"; } 64 84 65 85 //! Bit mask representing keyboard modifiers -
code/trunk/src/core/input/Mouse.cc
r3276 r3327 30 30 31 31 #include <ois/OISMouse.h> 32 #include <boost/foreach.hpp> 32 #include "core/ConsoleCommand.h" 33 #include "core/CoreIncludes.h" 33 34 #include "InputState.h" 34 #include "core/ConsoleCommand.h"35 35 36 // HACK (include this as last, X11 seems to define some macros...)37 36 #ifdef ORXONOX_PLATFORM_LINUX 38 # include <ois/linux/LinuxMouse.h> 37 // include this as last, X11 seems to define some macros... 38 #include <ois/linux/LinuxMouse.h> 39 39 #endif 40 40 41 41 namespace orxonox 42 42 { 43 Mouse::Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight)44 : super(id )43 Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager) 44 : super(id, oisInputManager) 45 45 { 46 this->setMouseClipping(windowWidth, windowHeight); 47 // HACK: 48 instancePointer_s = this; 49 } 46 RegisterRootObject(Mouse); 47 this->windowResized(this->getWindowWidth(), this->getWindowHeight()); 50 48 51 void Mouse::setMouseClipping(unsigned int width, unsigned int height) 52 {53 oisDevice_->getMouseState().width = width;54 oisDevice_->getMouseState().height = height;55 }56 57 unsigned int Mouse::getClippingWidth() const58 {59 return oisDevice_->getMouseState().width;60 }61 62 unsigned int Mouse::getClippingHeight() const63 {64 return oisDevice_->getMouseState().height; 49 #ifdef ORXONOX_PLATFORM_LINUX 50 { 51 // Mouse grab console command 52 FunctorMember<Mouse>* functor = createFunctor(&Mouse::grab); 53 functor->setObject(this); 54 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "grab"), false); 55 } 56 { 57 // Mouse ungrab console command 58 FunctorMember<Mouse>* functor = createFunctor(&Mouse::ungrab); 59 functor->setObject(this); 60 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "ungrab"), false); 61 } 62 #endif 65 63 } 66 64 … … 74 72 IntVector2 rel(e.state.X.rel, e.state.Y.rel); 75 73 IntVector2 clippingSize(e.state.width, e.state.height); 76 BOOST_FOREACH(InputState* state, inputStates_)77 state->mouseMoved(abs, rel, clippingSize);74 for (unsigned int i = 0; i < inputStates_.size(); ++i) 75 inputStates_[i]->mouseMoved(abs, rel, clippingSize); 78 76 } 79 77 … … 81 79 if (e.state.Z.rel != 0) 82 80 { 83 BOOST_FOREACH(InputState* state, inputStates_)84 state->mouseScrolled(e.state.Z.abs, e.state.Z.rel);81 for (unsigned int i = 0; i < inputStates_.size(); ++i) 82 inputStates_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 85 83 } 86 84 … … 88 86 } 89 87 90 // ############################################################ 91 // ##### ugly hacks ##### 92 // ########## ########## 93 // ############################################################ 94 95 // HACK: 96 SetConsoleCommand(Mouse, setMouseClipping_s, false); 97 #ifdef ORXONOX_PLATFORM_LINUX 98 SetConsoleCommand(Mouse, grabMouse, true); 99 SetConsoleCommand(Mouse, ungrabMouse, true); 100 #endif 101 Mouse* Mouse::instancePointer_s = NULL; 88 void Mouse::windowResized(unsigned int newWidth, unsigned int newHeight) 89 { 90 oisDevice_->getMouseState().width = newWidth; 91 oisDevice_->getMouseState().height = newHeight; 92 } 102 93 103 94 #ifdef ORXONOX_PLATFORM_LINUX 104 void Mouse::grab Mouse()95 void Mouse::grab() 105 96 { 106 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>( instancePointer_s->oisDevice_);97 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_); 107 98 assert(linuxMouse); 108 99 linuxMouse->grab(true); 109 100 } 110 101 111 void Mouse::ungrab Mouse()102 void Mouse::ungrab() 112 103 { 113 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>( instancePointer_s->oisDevice_);104 OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_); 114 105 assert(linuxMouse); 115 106 linuxMouse->grab(false); -
code/trunk/src/core/input/Mouse.h
r3276 r3327 31 31 32 32 #include "InputPrereqs.h" 33 33 34 #include "InputDevice.h" 35 #include "core/WindowEventListener.h" 34 36 35 37 namespace orxonox 36 38 { 39 //! Template parameter collection for the base class 40 struct MouseTraits 41 { 42 typedef Mouse DeviceClass; 43 typedef OIS::Mouse OISDeviceClass; 44 typedef MouseButtonCode::ByEnum ButtonType; 45 typedef MouseButtonCode::ByEnum ButtonTypeParam; 46 static const OIS::Type OISDeviceValue = OIS::OISMouse; 47 }; 48 37 49 /** 38 50 @brief … … 43 55 : public InputDeviceTemplated<MouseTraits> 44 56 , public OIS::MouseListener 57 , public WindowEventListener 45 58 { 46 59 friend class InputDeviceTemplated<MouseTraits>; … … 49 62 50 63 public: 51 Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight); 64 //! Only sets the clipping size. Initialising is done in the base class. 65 Mouse(unsigned int id, OIS::InputManager* oisInputManager); 52 66 ~Mouse() { } 53 67 54 /**55 @brief56 Adjusts the mouse window metrics.57 58 This method has to be called every time the size of the window changes.59 */60 void setMouseClipping(unsigned int width, unsigned int height);61 unsigned int getClippingWidth() const;62 unsigned int getClippingHeight() const;63 64 // HACK!65 static void setMouseClipping_s(unsigned int width, unsigned int height)66 { instancePointer_s->setMouseClipping(width, height); }67 void setConfigValues() { }68 68 #ifdef ORXONOX_PLATFORM_LINUX 69 // HACK!70 static void grabMouse();71 static void ungrabMouse();69 // TODO: Make this a feature rather than a hack 70 void grab(); 71 void ungrab(); 72 72 #endif 73 73 74 74 private: 75 // TODO: Do we need to reset the mouse position?76 void clearBuffersImpl() { }77 78 75 //! OIS event handler 79 76 bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id) … … 92 89 bool mouseMoved(const OIS::MouseEvent &arg); 93 90 94 // HACK: 95 static Mouse* instancePointer_s; 91 void windowResized(unsigned int newWidth, unsigned int newHeight); 92 93 // Returns the class name as string 94 static std::string getClassNameImpl() { return "Mouse"; } 96 95 }; 97 96 }
Note: See TracChangeset
for help on using the changeset viewer.