Changeset 1755 for code/trunk/src/core/input
- Timestamp:
- Sep 10, 2008, 1:37:36 AM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 18 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/gui (added) merged: 1636,1638,1640-1647,1649-1654,1656,1659-1665,1670,1672-1674,1686,1688-1692,1694-1697,1704 /code/branches/input (added) merged: 1629-1630
- Property svn:mergeinfo changed
-
code/trunk/src/core/input/Button.cc
r1747 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the different input handlers. 32 */ 30 @file 31 @brief 32 Implementation of the different input handlers. 33 */ 33 34 34 35 #include "Button.h" … … 44 45 namespace orxonox 45 46 { 46 void Button::clear() 47 { 48 for (unsigned int j = 0; j < 3; j++) 49 { 50 if (nCommands_[j]) 51 { 52 // delete all commands and the command pointer array 53 for (unsigned int i = 0; i < nCommands_[j]; i++) 54 delete commands_[j][i]; 55 delete[] commands_[j]; 56 commands_[j] = 0; 57 nCommands_[j] = 0; 58 } 59 else 60 { 61 commands_[j] = 0; 62 } 63 } 64 } 65 66 void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer) 67 { 68 if (isEmpty(bindingString_)) 69 { 70 clear(); 71 return; 72 } 73 74 // use std::vector for a temporary dynamic array 75 std::vector<BaseCommand*> commands[3]; 76 77 78 // separate the commands 79 SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false, 80 '\\', false, '"', false, '(', ')', false, '\0'); 81 82 for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++) 83 { 84 if (commandStrings[iCommand] != "") 85 { 86 SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false, 47 void Button::clear() 48 { 49 for (unsigned int j = 0; j < 3; j++) 50 { 51 if (nCommands_[j]) 52 { 53 // delete all commands and the command pointer array 54 for (unsigned int i = 0; i < nCommands_[j]; i++) 55 delete commands_[j][i]; 56 delete[] commands_[j]; 57 commands_[j] = 0; 58 nCommands_[j] = 0; 59 } 60 else 61 { 62 commands_[j] = 0; 63 } 64 } 65 } 66 67 void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer) 68 { 69 if (isEmpty(bindingString_)) 70 { 71 clear(); 72 return; 73 } 74 75 // use std::vector for a temporary dynamic array 76 std::vector<BaseCommand*> commands[3]; 77 78 79 // separate the commands 80 SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false, 87 81 '\\', false, '"', false, '(', ')', false, '\0'); 88 82 89 unsigned int iToken = 0; 90 91 // for real axes, we can feed a ButtonThreshold argument as entire command 92 if (getLowercase(tokens[0]) == "buttonthreshold") 93 { 94 if (tokens.size() == 1) 95 continue; 96 // may fail, but doesn't matter 97 convertValue(&buttonThreshold_, tokens[1]); 98 continue; 99 } 100 101 // first argument can be OnPress, OnHold OnRelease or nothing 102 KeybindMode::Enum mode = KeybindMode::None; 103 if (getLowercase(tokens[iToken]) == "onpress") 104 mode = KeybindMode::OnPress, iToken++; 105 if (getLowercase(tokens[iToken]) == "onrelease") 106 mode = KeybindMode::OnRelease, iToken++; 107 if (getLowercase(tokens[iToken]) == "onhold") 108 mode = KeybindMode::OnHold, iToken++; 109 110 if (iToken == tokens.size()) 111 continue; 112 113 // second argument can be the amplitude for the case it as an axis command 114 // default amplitude is 1.0f 115 float paramModifier = 1.0f; 116 if (getLowercase(tokens[iToken]) == "scale") 117 { 118 iToken++; 119 if (iToken == tokens.size() || !convertValue(¶mModifier, tokens[iToken])) 120 { 121 COUT(2) << "Error while parsing key binding " << name_ 122 << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl; 123 if (iToken == tokens.size()) 124 continue; 125 } 126 iToken++; 127 } 128 129 // no more arguments expected except for the actual command 130 if (iToken == tokens.size()) 131 continue; 132 133 std::string commandStr; 134 while (iToken != tokens.size()) 135 commandStr += tokens[iToken++] + " "; 136 137 // evaluate the command 138 CommandEvaluation eval = CommandExecutor::evaluate(commandStr); 139 if (!eval.isValid()) 140 continue; 141 142 // check for param command 143 int paramIndex = eval.getConsoleCommand()->getAxisParamIndex(); 144 if (paramIndex >= 0) 145 { 146 // parameter supported command 147 ParamCommand* cmd = new ParamCommand(); 148 cmd->paramModifier_ = paramModifier; 149 cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative(); 150 151 // add command to the buffer if not yet existing 152 for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++) 153 { 154 if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand()) 155 == getLowercase(commandStr)) 156 { 157 // already in list 158 cmd->paramCommand_ = paramCommandBuffer[iParamCmd]; 159 break; 160 } 161 } 162 if (cmd->paramCommand_ == 0) 163 { 164 cmd->paramCommand_ = new BufferedParamCommand(); 165 paramCommandBuffer.push_back(cmd->paramCommand_); 166 cmd->paramCommand_->evaluation_ = eval; 167 cmd->paramCommand_->paramIndex_ = paramIndex; 168 } 169 170 171 // we don't know whether this is an actual axis or just a button 172 if (mode == KeybindMode::None) 173 { 174 if (!addParamCommand(cmd)) 175 { 176 mode = eval.getConsoleCommand()->getKeybindMode(); 177 commands[mode].push_back(cmd); 178 } 179 } 83 for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++) 84 { 85 if (commandStrings[iCommand] != "") 86 { 87 SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false, 88 '\\', false, '"', false, '(', ')', false, '\0'); 89 90 KeybindMode::Enum mode = KeybindMode::None; 91 float paramModifier = 1.0f; 92 std::string commandStr = ""; 93 94 for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken) 95 { 96 std::string token = getLowercase(tokens[iToken]); 97 98 if (token == "onpress") 99 mode = KeybindMode::OnPress; 100 else if (token == "onrelease") 101 mode = KeybindMode::OnRelease; 102 else if (token == "onhold") 103 mode = KeybindMode::OnHold; 104 else if (token == "buttonthreshold") 105 { 106 // for real axes, we can feed a ButtonThreshold argument 107 ++iToken; 108 if (iToken == tokens.size()) 109 continue; 110 // may fail, but doesn't matter (default value already set) 111 if (!convertValue(&buttonThreshold_, tokens[iToken + 1])) 112 parseError("Could not parse 'ButtonThreshold' argument. \ 113 Switching to default value.", true); 114 } 115 else if (token == "scale") 116 { 117 ++iToken; 118 if (iToken == tokens.size() || !convertValue(¶mModifier, tokens[iToken])) 119 parseError("Could not parse 'scale' argument. Switching to default value.", true); 120 } 121 else 122 { 123 // no input related argument 124 // we interpret everything from here as a command string 125 while (iToken != tokens.size()) 126 commandStr += tokens[iToken++] + " "; 127 } 128 } 129 130 if (commandStr == "") 131 { 132 parseError("No command string given.", false); 133 continue; 134 } 135 136 // evaluate the command 137 CommandEvaluation eval = CommandExecutor::evaluate(commandStr); 138 if (!eval.isValid()) 139 { 140 parseError("Command evaluation failed.", true); 141 continue; 142 } 143 144 // check for param command 145 int paramIndex = eval.getConsoleCommand()->getAxisParamIndex(); 146 if (paramIndex >= 0) 147 { 148 // parameter supported command 149 ParamCommand* cmd = new ParamCommand(); 150 cmd->paramModifier_ = paramModifier; 151 cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative(); 152 153 // add command to the buffer if not yet existing 154 for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++) 155 { 156 if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand()) 157 == getLowercase(commandStr)) 158 { 159 // already in list 160 cmd->paramCommand_ = paramCommandBuffer[iParamCmd]; 161 break; 162 } 163 } 164 if (cmd->paramCommand_ == 0) 165 { 166 cmd->paramCommand_ = new BufferedParamCommand(); 167 paramCommandBuffer.push_back(cmd->paramCommand_); 168 cmd->paramCommand_->evaluation_ = eval; 169 cmd->paramCommand_->paramIndex_ = paramIndex; 170 } 171 172 173 // we don't know whether this is an actual axis or just a button 174 if (mode == KeybindMode::None) 175 { 176 if (!addParamCommand(cmd)) 177 { 178 mode = eval.getConsoleCommand()->getKeybindMode(); 179 commands[mode].push_back(cmd); 180 } 181 } 182 } 183 else 184 { 185 SimpleCommand* cmd = new SimpleCommand(); 186 cmd->evaluation_ = eval; 187 188 if (mode == KeybindMode::None) 189 mode = eval.getConsoleCommand()->getKeybindMode(); 190 191 commands[mode].push_back(cmd); 192 } 193 } 194 } 195 196 for (unsigned int j = 0; j < 3; j++) 197 { 198 nCommands_[j] = commands[j].size(); 199 if (nCommands_[j]) 200 { 201 commands_[j] = new BaseCommand*[nCommands_[j]]; 202 for (unsigned int i = 0; i < commands[j].size(); i++) 203 commands_[j][i] = commands[j][i]; 204 } 205 else 206 commands_[j] = 0; 207 } 208 } 209 210 bool Button::execute(KeybindMode::Enum mode, float abs, float rel) 211 { 212 // execute all the parsed commands in the string 213 for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++) 214 commands_[mode][iCommand]->execute(abs, rel); 215 return true; 216 } 217 218 inline void Button::parseError(std::string message, bool serious) 219 { 220 if (serious) 221 { 222 COUT(2) << "Error while parsing binding for button/axis" << this->name_ << ". " 223 << message << std::endl; 180 224 } 181 225 else 182 226 { 183 SimpleCommand* cmd = new SimpleCommand(); 184 cmd->evaluation_ = eval; 185 186 if (mode == KeybindMode::None) 187 mode = eval.getConsoleCommand()->getKeybindMode(); 188 189 commands[mode].push_back(cmd); 190 } 191 } 192 } 193 194 for (unsigned int j = 0; j < 3; j++) 195 { 196 nCommands_[j] = commands[j].size(); 197 if (nCommands_[j]) 198 { 199 commands_[j] = new BaseCommand*[nCommands_[j]]; 200 for (unsigned int i = 0; i < commands[j].size(); i++) 201 commands_[j][i] = commands[j][i]; 202 } 203 else 204 commands_[j] = 0; 205 } 206 } 207 208 bool Button::execute(KeybindMode::Enum mode, float abs, float rel) 209 { 210 // execute all the parsed commands in the string 211 for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++) 212 commands_[mode][iCommand]->execute(abs, rel); 213 return true; 214 } 227 COUT(3) << "Warning while parsing binding for button/axis" << this->name_ << ". " 228 << message << std::endl; 229 } 230 } 215 231 } -
code/trunk/src/core/input/Button.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _Button_H__ … … 42 43 namespace orxonox 43 44 { 44 class _CoreExport Button45 {46 public:47 Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }48 virtual ~Button() { clear(); }49 virtual void clear();50 virtual bool addParamCommand(ParamCommand* command) { return false; }51 void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);52 bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);45 class _CoreExport Button 46 { 47 public: 48 Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); } 49 virtual ~Button() { clear(); } 50 virtual void clear(); 51 virtual bool addParamCommand(ParamCommand* command) { return false; } 52 void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer); 53 bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f); 53 54 54 //! The configured string value 55 std::string bindingString_; 56 //! Name of the trigger as strings 57 std::string name_; 58 //! Basic commands for OnPress, OnHold and OnRelease 59 BaseCommand** commands_[3]; 60 //! Number of basic commands 61 unsigned int nCommands_[3]; 62 //! Says how much it takes for an analog axis to trigger a button 63 //! Note: This variable is here to have only one parse() function. 64 float buttonThreshold_; 65 }; 55 //! The configured string value 56 std::string bindingString_; 57 //! Name of the trigger as strings 58 std::string name_; 59 //! Basic commands for OnPress, OnHold and OnRelease 60 BaseCommand** commands_[3]; 61 //! Number of basic commands 62 unsigned int nCommands_[3]; 63 //! Says how much it takes for an analog axis to trigger a button 64 //! Note: This variable is here to have only one parse() function. 65 float buttonThreshold_; 66 67 private: 68 void parseError(std::string message, bool serious); 69 }; 66 70 } 67 71 -
code/trunk/src/core/input/CalibratorCallback.cc
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the different input handlers. 32 */ 30 @file 31 @brief 32 Implementation of the different input handlers. 33 */ 33 34 34 35 #include "CalibratorCallback.h" … … 37 38 namespace orxonox 38 39 { 39 void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt) 40 { 41 if (evt.key == KeyCode::Return) 40 void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt) 42 41 { 43 InputManager::setInputState(InputManager::IS_NOCALIBRATE); 42 if (evt.key == KeyCode::Return) 43 { 44 //InputManager::setInputState(InputManager::IS_NOCALIBRATE); 45 } 44 46 } 45 }46 47 } -
code/trunk/src/core/input/CalibratorCallback.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _CalibratorCallback_H__ … … 36 37 37 38 #include "core/CorePrereqs.h" 38 39 39 #include "InputInterfaces.h" 40 40 41 41 namespace orxonox 42 42 { 43 class _CoreExport CalibratorCallback : public KeyHandler44 {45 public:46 CalibratorCallback() {}47 ~CalibratorCallback() {}43 class _CoreExport CalibratorCallback : public KeyHandler 44 { 45 public: 46 CalibratorCallback() { } 47 ~CalibratorCallback() { } 48 48 49 private:50 void keyPressed (const KeyEvent& evt);51 void keyReleased(const KeyEvent& evt) {}52 void keyHeld (const KeyEvent& evt) {}49 private: 50 void keyPressed (const KeyEvent& evt); 51 void keyReleased(const KeyEvent& evt) { } 52 void keyHeld (const KeyEvent& evt) { } 53 53 54 void tickInput(float dt, const HandlerState &state) { }55 };54 void tickInput(float dt) { } 55 }; 56 56 } 57 57 -
code/trunk/src/core/input/ExtendedInputState.cc
r1724 r1755 36 36 37 37 #include <assert.h> 38 #include " core/Debug.h"38 #include "util/Debug.h" 39 39 40 40 namespace orxonox -
code/trunk/src/core/input/HalfAxis.cc
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the different input handlers. 32 */ 30 @file 31 @brief 32 Implementation of the different input handlers. 33 */ 33 34 34 35 #include "HalfAxis.h" … … 38 39 namespace orxonox 39 40 { 40 void HalfAxis::clear() 41 { 42 Button::clear(); 43 if (nParamCommands_) 41 void HalfAxis::clear() 44 42 { 45 // delete all commands and the command pointer array 46 for (unsigned int i = 0; i < nParamCommands_; i++) 47 delete paramCommands_[i]; 48 delete[] paramCommands_; 49 nParamCommands_ = 0; 43 Button::clear(); 44 if (nParamCommands_) 45 { 46 // delete all commands and the command pointer array 47 for (unsigned int i = 0; i < nParamCommands_; i++) 48 delete paramCommands_[i]; 49 delete[] paramCommands_; 50 nParamCommands_ = 0; 51 } 52 else 53 { 54 nParamCommands_ = 0; nParamCommands_ = 0; 55 } 50 56 } 51 else 57 58 bool HalfAxis::addParamCommand(ParamCommand* command) 52 59 { 53 nParamCommands_ = 0; nParamCommands_ = 0; 60 ParamCommand** cmds = paramCommands_; 61 paramCommands_ = new ParamCommand*[++nParamCommands_]; 62 unsigned int i; 63 for (i = 0; i < nParamCommands_ - 1; i++) 64 paramCommands_[i] = cmds[i]; 65 paramCommands_[i] = command; 66 if (nParamCommands_ > 1) 67 delete[] cmds; 68 return true; 54 69 } 55 }56 70 57 bool HalfAxis::addParamCommand(ParamCommand* command) 58 { 59 ParamCommand** cmds = paramCommands_; 60 paramCommands_ = new ParamCommand*[++nParamCommands_]; 61 unsigned int i; 62 for (i = 0; i < nParamCommands_ - 1; i++) 63 paramCommands_[i] = cmds[i]; 64 paramCommands_[i] = command; 65 if (nParamCommands_ > 1) 66 delete[] cmds; 67 return true; 68 } 69 70 bool HalfAxis::execute() 71 { 72 bool success = true; 73 for (unsigned int i = 0; i < nParamCommands_; i++) 74 success = success && paramCommands_[i]->execute(absVal_, relVal_); 75 return success; 76 } 71 bool HalfAxis::execute() 72 { 73 bool success = true; 74 for (unsigned int i = 0; i < nParamCommands_; i++) 75 success = success && paramCommands_[i]->execute(absVal_, relVal_); 76 return success; 77 } 77 78 } -
code/trunk/src/core/input/HalfAxis.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _HalfAxis_H__ … … 40 41 namespace orxonox 41 42 { 42 class _CoreExport HalfAxis : public Button 43 { 44 public: 45 HalfAxis() : relVal_(0.0f), absVal_(0.0f), paramCommands_(0), nParamCommands_(0), 46 wasDown_(false), hasChanged_(false) { } 47 using Button::execute; 48 bool execute(); 49 bool addParamCommand(ParamCommand* command); 50 void clear(); 43 class _CoreExport HalfAxis : public Button 44 { 45 public: 46 HalfAxis() 47 : relVal_(0.0f) 48 , absVal_(0.0f) 49 , paramCommands_(0) 50 , nParamCommands_(0) 51 , wasDown_(false) 52 , hasChanged_(false) 53 { } 54 using Button::execute; 55 bool execute(); 56 bool addParamCommand(ParamCommand* command); 57 void clear(); 51 58 52 // axis related53 float relVal_;54 float absVal_;55 ParamCommand** paramCommands_;56 unsigned int nParamCommands_;59 // axis related 60 float relVal_; 61 float absVal_; 62 ParamCommand** paramCommands_; 63 unsigned int nParamCommands_; 57 64 58 // button related59 bool wasDown_;60 bool hasChanged_;61 };65 // button related 66 bool wasDown_; 67 bool hasChanged_; 68 }; 62 69 } 63 70 -
code/trunk/src/core/input/InputBuffer.cc
r1535 r1755 220 220 @param dt Delta time 221 221 */ 222 void InputBuffer::tickInput(float dt , const HandlerState& state)222 void InputBuffer::tickInput(float dt) 223 223 { 224 224 timeSinceKeyPressed_ += dt; -
code/trunk/src/core/input/InputBuffer.h
r1535 r1755 170 170 void processKey (const KeyEvent &e); 171 171 172 void tickInput(float dt, const HandlerState& state); 172 void tickInput(float dt); 173 void tickKey(float dt) { } 173 174 174 175 std::string buffer_; -
code/trunk/src/core/input/InputCommands.cc
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the different input handlers. 32 */ 30 @file 31 @brief 32 Implementation of the different input handlers. 33 */ 33 34 34 35 #include "InputCommands.h" … … 37 38 namespace orxonox 38 39 { 39 // ###############################40 // ### BufferedParamCommand ###41 // ###############################40 // ############################### 41 // ### BufferedParamCommand ### 42 // ############################### 42 43 43 /**44 * Executes a buffered command. This is used for commands with additional45 * parameters.46 * @return True if command execution was successful or value was zero.47 */48 bool BufferedParamCommand::execute()49 {50 if (nValuesAdded_)44 /** 45 @brief 46 Executes a buffered command. This is used for commands with additional 47 parameters. 48 @return 49 True if command execution was successful or value was zero. 50 */ 51 bool BufferedParamCommand::execute() 51 52 { 52 BufferedParamCommand& cmd = *this; 53 cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_); 54 // reset 55 cmd.nValuesAdded_ = 0; 56 cmd.value_ = 0; 57 return cmd.evaluation_.execute(); 53 if (nValuesAdded_) 54 { 55 BufferedParamCommand& cmd = *this; 56 cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_); 57 // reset 58 cmd.nValuesAdded_ = 0; 59 cmd.value_ = 0; 60 return cmd.evaluation_.execute(); 61 } 62 else 63 return true; 58 64 } 59 else60 return true;61 }62 65 63 // ###############################64 // ##### SimpleCommand #####65 // ###############################66 // ############################### 67 // ##### SimpleCommand ##### 68 // ############################### 66 69 67 /** 68 * Executes a simple command with no additional paramters. 69 * @return True if command execution was successful, false otherwise. 70 */ 71 bool SimpleCommand::execute(float abs, float rel) 72 { 73 return evaluation_.execute(); 74 } 70 /** 71 @brief 72 Executes a simple command with no additional paramters. 73 @return 74 True if command execution was successful, false otherwise. 75 */ 76 bool SimpleCommand::execute(float abs, float rel) 77 { 78 return evaluation_.execute(); 79 } 75 80 76 // ###############################77 // ##### ParamCommand #####78 // ###############################81 // ############################### 82 // ##### ParamCommand ##### 83 // ############################### 79 84 80 /** 81 * Executes a parameter command. The commmand string is not directly executed, 82 * but instead stored in a buffer list so that values can be combined. 83 * @return Always true. 84 */ 85 bool ParamCommand::execute(float abs, float rel) 86 { 87 BufferedParamCommand& cmd = *paramCommand_; 88 // command has an additional parameter 89 if (bRelative_) 85 /** 86 @brief 87 Executes a parameter command. The commmand string is not directly executed, 88 but instead stored in a buffer list so that values can be combined. 89 @return 90 Always true. 91 */ 92 bool ParamCommand::execute(float abs, float rel) 90 93 { 91 if (rel != 0.0f) 92 { 93 // we have to calculate a relative movement. 94 // paramModifier_ says how much one keystroke is 95 cmd.value_ += paramModifier_ * rel; 96 } 94 BufferedParamCommand& cmd = *paramCommand_; 95 // command has an additional parameter 96 if (bRelative_) 97 { 98 if (rel != 0.0f) 99 { 100 // we have to calculate a relative movement. 101 // paramModifier_ says how much one keystroke is 102 cmd.value_ += paramModifier_ * rel; 103 } 104 } 105 else if (abs != 0.0f) 106 { 107 // Usually, joy sticks create 'noise' (they return values if they're in 0 position) 108 // and normally this is caught in tickInput(), but that threshold cannot be to high 109 // in order to preserve accuracy. Instead, we have to catch the problem here. An example: 110 // Someone only uses buttons with an active joystick. The joy stick value could then 111 // be 0.05 for instance and the the key value 1. Without handling the problem, the final 112 // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects. 113 float absQ = abs * abs; 114 float valueQ = cmd.value_ * cmd.value_; 115 if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics 116 { 117 cmd.value_ = abs * paramModifier_; 118 cmd.nValuesAdded_ = 1; 119 } 120 else if (absQ * 50.0f < valueQ) 121 { 122 // abs is too small, we just don't do anything 123 } 124 else 125 { 126 // we have to calculate the absolute position of the axis. 127 // Since there might be another axis that is affected, we have to wait and 128 // store the result in a temporary place 129 cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_; 130 } 131 } 132 return true; 97 133 } 98 else if (abs != 0.0f)99 {100 // Usually, joy sticks create 'noise' (they return values if they're in 0 position)101 // and normally this is caught in tickInput(), but that threshold cannot be to high102 // in order to preserve accuracy. Instead, we have to catch the problem here. An example:103 // Someone only uses buttons with an active joystick. The joy stick value could then104 // be 0.05 for instance and the the key value 1. Without handling the problem, the final105 // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.106 float absQ = abs * abs;107 float valueQ = cmd.value_ * cmd.value_;108 if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics109 {110 cmd.value_ = abs * paramModifier_;111 cmd.nValuesAdded_ = 1;112 }113 else if (absQ * 50.0f < valueQ)114 {115 // abs is too small, we just don't do anything116 }117 else118 {119 // we have to calculate the absolute position of the axis.120 // Since there might be another axis that is affected, we have to wait and121 // store the result in a temporary place122 cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;123 }124 }125 return true;126 }127 134 } -
code/trunk/src/core/input/InputCommands.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _InputCommands_H__ … … 40 41 namespace orxonox 41 42 { 42 class _CoreExport BufferedParamCommand43 {44 public:45 BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }46 bool execute();43 class _CoreExport BufferedParamCommand 44 { 45 public: 46 BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { } 47 bool execute(); 47 48 48 float value_;49 unsigned int nValuesAdded_;50 int paramIndex_;51 CommandEvaluation evaluation_;52 };49 float value_; 50 unsigned int nValuesAdded_; 51 int paramIndex_; 52 CommandEvaluation evaluation_; 53 }; 53 54 54 class _CoreExport BaseCommand55 {56 public:57 virtual ~BaseCommand() { }58 virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;59 };55 class _CoreExport BaseCommand 56 { 57 public: 58 virtual ~BaseCommand() { } 59 virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0; 60 }; 60 61 61 class _CoreExport SimpleCommand : public BaseCommand62 {63 public:64 bool execute(float abs = 1.0f, float rel = 1.0f);62 class _CoreExport SimpleCommand : public BaseCommand 63 { 64 public: 65 bool execute(float abs = 1.0f, float rel = 1.0f); 65 66 66 CommandEvaluation evaluation_;67 };67 CommandEvaluation evaluation_; 68 }; 68 69 69 class _CoreExport ParamCommand : public BaseCommand70 {71 public:72 ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }73 bool execute(float abs = 1.0f, float rel = 1.0f);70 class _CoreExport ParamCommand : public BaseCommand 71 { 72 public: 73 ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { } 74 bool execute(float abs = 1.0f, float rel = 1.0f); 74 75 75 bool bRelative_;76 float paramModifier_;77 BufferedParamCommand* paramCommand_;78 };76 bool bRelative_; 77 float paramModifier_; 78 BufferedParamCommand* paramCommand_; 79 }; 79 80 } 80 81 -
code/trunk/src/core/input/InputInterfaces.h
r1556 r1755 28 28 29 29 /** 30 @file 31 @brief Declarations of various interface classes for the input management. 30 @file 31 @brief 32 Declarations of various interface classes for the input management. 32 33 */ 33 34 … … 37 38 #include "core/CorePrereqs.h" 38 39 39 #include " src/ois/OISKeyboard.h"40 #include " src/ois/OISMouse.h"41 #include " src/ois/OISJoyStick.h"40 #include "ois/OISKeyboard.h" 41 #include "ois/OISMouse.h" 42 #include "ois/OISJoyStick.h" 42 43 #include "util/Math.h" 43 44 44 45 namespace orxonox 45 46 { 46 namespace KeyCode 47 { 48 // note: KeyCode comments were directly taken from OISKeyboard.h 49 enum Enum 50 { 51 Unassigned = OIS::KC_UNASSIGNED, 52 Escape = OIS::KC_ESCAPE, 53 NumRow1 = OIS::KC_1, 54 NumRow2 = OIS::KC_2, 55 NumRow3 = OIS::KC_3, 56 NumRow4 = OIS::KC_4, 57 NumRow5 = OIS::KC_5, 58 NumRow6 = OIS::KC_6, 59 NumRow7 = OIS::KC_7, 60 NumRow8 = OIS::KC_8, 61 NumRow9 = OIS::KC_9, 62 NumRow0 = OIS::KC_0, 63 Minus = OIS::KC_MINUS, // - on main keyboard 64 Equals = OIS::KC_EQUALS, 65 Back = OIS::KC_BACK, // backspace 66 Tab = OIS::KC_TAB, 67 Q = OIS::KC_Q, 68 W = OIS::KC_W, 69 E = OIS::KC_E, 70 R = OIS::KC_R, 71 T = OIS::KC_T, 72 Y = OIS::KC_Y, 73 U = OIS::KC_U, 74 I = OIS::KC_I, 75 O = OIS::KC_O, 76 P = OIS::KC_P, 77 LeftBracket = OIS::KC_LBRACKET, 78 RightBracket = OIS::KC_RBRACKET, 79 Return = OIS::KC_RETURN, // Enter on main keyboard 80 LeftControl = OIS::KC_LCONTROL, 81 A = OIS::KC_A, 82 S = OIS::KC_S, 83 D = OIS::KC_D, 84 F = OIS::KC_F, 85 G = OIS::KC_G, 86 H = OIS::KC_H, 87 J = OIS::KC_J, 88 K = OIS::KC_K, 89 L = OIS::KC_L, 90 Semicolon = OIS::KC_SEMICOLON, 91 Apostrophe = OIS::KC_APOSTROPHE, 92 Grave = OIS::KC_GRAVE, // accent 93 LeftShift = OIS::KC_LSHIFT, 94 Backslash = OIS::KC_BACKSLASH, 95 Z = OIS::KC_Z, 96 X = OIS::KC_X, 97 C = OIS::KC_C, 98 V = OIS::KC_V, 99 B = OIS::KC_B, 100 N = OIS::KC_N, 101 M = OIS::KC_M, 102 Comma = OIS::KC_COMMA, 103 Period = OIS::KC_PERIOD, // . on main keyboard 104 Slash = OIS::KC_SLASH, // / on main keyboard 105 RightShift = OIS::KC_RSHIFT, 106 Multiply = OIS::KC_MULTIPLY, // * on numeric keypad 107 LeftAlt = OIS::KC_LMENU, // left Alt 108 Space = OIS::KC_SPACE, 109 CapsLock = OIS::KC_CAPITAL, 110 F1 = OIS::KC_F1, 111 F2 = OIS::KC_F2, 112 F3 = OIS::KC_F3, 113 F4 = OIS::KC_F4, 114 F5 = OIS::KC_F5, 115 F6 = OIS::KC_F6, 116 F7 = OIS::KC_F7, 117 F8 = OIS::KC_F8, 118 F9 = OIS::KC_F9, 119 F10 = OIS::KC_F10, 120 Numlock = OIS::KC_NUMLOCK, 121 Scrolllock = OIS::KC_SCROLL, // Scroll Lock 122 Numpad7 = OIS::KC_NUMPAD7, 123 Numpad8 = OIS::KC_NUMPAD8, 124 Numpad9 = OIS::KC_NUMPAD9, 125 NumpadSubtract= OIS::KC_SUBTRACT, // - on numeric keypad 126 Numpad4 = OIS::KC_NUMPAD4, 127 Numpad5 = OIS::KC_NUMPAD5, 128 Numpad6 = OIS::KC_NUMPAD6, 129 NumpadAdd = OIS::KC_ADD, // + on numeric keypad 130 Numpad1 = OIS::KC_NUMPAD1, 131 Numpad2 = OIS::KC_NUMPAD2, 132 Numpad3 = OIS::KC_NUMPAD3, 133 Numpad0 = OIS::KC_NUMPAD0, 134 NumpadPeriod = OIS::KC_DECIMAL, // . on numeric keypad 135 LessThan = OIS::KC_OEM_102, // < > | on UK/Germany keyboards 136 F11 = OIS::KC_F11, 137 F12 = OIS::KC_F12, 138 F13 = OIS::KC_F13, // (NEC PC98) 139 F14 = OIS::KC_F14, // (NEC PC98) 140 F15 = OIS::KC_F15, // (NEC PC98) 141 Kana = OIS::KC_KANA, // (Japanese keyboard) 142 ABNT_C1 = OIS::KC_ABNT_C1, // / ? on Portugese (Brazilian) keyboards 143 Convert = OIS::KC_CONVERT, // (Japanese keyboard) 144 NoConvert = OIS::KC_NOCONVERT, // (Japanese keyboard) 145 Yen = OIS::KC_YEN, // (Japanese keyboard) 146 ABNT_C2 = OIS::KC_ABNT_C2, // Numpad . on Portugese (Brazilian) keyboards 147 NumpadEquals = OIS::KC_NUMPADEQUALS, // = on numeric keypad (NEC PC98) 148 PreviousTrack = OIS::KC_PREVTRACK, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard) 149 AT = OIS::KC_AT, // (NEC PC98) 150 Colon = OIS::KC_COLON, // (NEC PC98) 151 Underline = OIS::KC_UNDERLINE, // (NEC PC98) 152 Kanji = OIS::KC_KANJI, // (Japanese keyboard) 153 Stop = OIS::KC_STOP, // (NEC PC98) 154 AX = OIS::KC_AX, // (Japan AX) 155 Unlabeled = OIS::KC_UNLABELED, // (J3100) 156 NextTrack = OIS::KC_NEXTTRACK, // Next Track 157 NumpadEnter = OIS::KC_NUMPADENTER, // Enter on numeric keypad 158 RightControl = OIS::KC_RCONTROL, 159 Mute = OIS::KC_MUTE, // Mute 160 Calculator = OIS::KC_CALCULATOR, // Calculator 161 PlayPause = OIS::KC_PLAYPAUSE, // Play / Pause 162 MediaStop = OIS::KC_MEDIASTOP, // Media Stop 163 VolumeDown = OIS::KC_VOLUMEDOWN, // Volume - 164 VolumeUp = OIS::KC_VOLUMEUP, // Volume + 165 WebHome = OIS::KC_WEBHOME, // Web home 166 NumpadComma = OIS::KC_NUMPADCOMMA, // , on numeric keypad (NEC PC98) 167 Divide = OIS::KC_DIVIDE, // / on numeric keypad 168 SYSRQ = OIS::KC_SYSRQ, 169 RightAlt = OIS::KC_RMENU, // right Alt 170 Pause = OIS::KC_PAUSE, // Pause 171 Home = OIS::KC_HOME, // Home on arrow keypad 172 Up = OIS::KC_UP, // UpArrow on arrow keypad 173 PageUp = OIS::KC_PGUP, // PgUp on arrow keypad 174 Left = OIS::KC_LEFT, // LeftArrow on arrow keypad 175 Right = OIS::KC_RIGHT, // RightArrow on arrow keypad 176 End = OIS::KC_END, // End on arrow keypad 177 Down = OIS::KC_DOWN, // DownArrow on arrow keypad 178 PageDown = OIS::KC_PGDOWN, // PgDn on arrow keypad 179 Insert = OIS::KC_INSERT, // Insert on arrow keypad 180 Delete = OIS::KC_DELETE, // Delete on arrow keypad 181 LeftWindows = OIS::KC_LWIN, // Left Windows key 182 RightWindows = OIS::KC_RWIN, // Right Windows key 183 Apps = OIS::KC_APPS, // AppMenu key 184 Power = OIS::KC_POWER, // System Power 185 Sleep = OIS::KC_SLEEP, // System Sleep 186 Wake = OIS::KC_WAKE, // System Wake 187 WebSearch = OIS::KC_WEBSEARCH, // Web Search 188 WebFavorites = OIS::KC_WEBFAVORITES, // Web Favorites 189 WebRefresh = OIS::KC_WEBREFRESH, // Web Refresh 190 WebStop = OIS::KC_WEBSTOP, // Web Stop 191 WebForward = OIS::KC_WEBFORWARD, // Web Forward 192 WebBack = OIS::KC_WEBBACK, // Web Back 193 MyComputer = OIS::KC_MYCOMPUTER, // My Computer 194 Mail = OIS::KC_MAIL, // Mail 195 MediaSelect = OIS::KC_MEDIASELECT // Media Select 196 }; 197 } 198 199 namespace MouseButton 200 { 201 enum Enum 202 { 203 Left = OIS::MB_Left, 204 Right = OIS::MB_Right, 205 Middle = OIS::MB_Middle, 206 Button3 = OIS::MB_Button3, 207 Button4 = OIS::MB_Button4, 208 Button5 = OIS::MB_Button5, 209 Button6 = OIS::MB_Button6, 210 Button7 = OIS::MB_Button7 211 }; 212 } 213 214 namespace KeyboardModifier 215 { 216 enum Enum 217 { 218 Shift = 0x0000001, 219 Ctrl = 0x0000010, 220 Alt = 0x0000100 221 }; 222 } 223 224 struct _CoreExport Key 225 { 226 Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { } 227 KeyCode::Enum key; 228 unsigned int text; 229 }; 230 231 class _CoreExport KeyEvent 232 { 233 public: 234 KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { } 235 KeyEvent(const OIS::KeyEvent& evt, unsigned int mod) : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { } 236 KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { } 237 bool isModifierDown(KeyboardModifier::Enum modifier) const { return (KeyboardModifier::Enum)modifier&modifiers; } 238 239 const KeyCode::Enum key; 240 unsigned int text; 241 unsigned int modifiers; 242 }; 243 244 //typedef OIS::MouseState MouseState; 245 246 /*class _CoreExport JoyStickState 247 { 248 public: 249 JoyStickState(const OIS::JoyStickState& state, int ID) : OIS::JoyStickState(state), mJoyStickID(ID) { } 250 JoyStickState() { clear(); } 251 int mJoyStickID; 252 JoyStickState() { clear(); } 253 254 std::vector<bool> mButtons; 255 int axes[16]; 256 std::vector<Vector3> mVectors; 257 };*/ 258 259 /** 260 * Helper struct to determine which handlers of an object (can implement 261 * multiple handlers) are active. 262 */ 263 struct HandlerState 264 { 265 HandlerState() : key(false), mouse(false), joyStick(false) { } 266 bool key; 267 bool mouse; 268 bool joyStick; 269 }; 270 271 class _CoreExport InputTickable 272 { 273 public: 274 virtual ~InputTickable() { } 275 virtual void tickInput(float dt, const HandlerState& state) = 0; 276 }; 277 278 /** 279 @brief Interface class used for key input listeners. 280 */ 281 class _CoreExport KeyHandler : virtual public InputTickable 282 { 283 public: 284 virtual ~KeyHandler() { } 285 virtual void keyPressed (const KeyEvent& evt) = 0; 286 virtual void keyReleased(const KeyEvent& evt) = 0; 287 virtual void keyHeld (const KeyEvent& evt) = 0; 288 //virtual void tickKey (float dt) { } 289 }; 290 291 /** 292 @brief Interface class used for mouse input listeners. 293 */ 294 class _CoreExport MouseHandler : virtual public InputTickable 295 { 296 public: 297 virtual ~MouseHandler() { } 298 virtual void mouseButtonPressed (MouseButton::Enum id) = 0; 299 virtual void mouseButtonReleased(MouseButton::Enum id) = 0; 300 virtual void mouseButtonHeld (MouseButton::Enum id) = 0; 301 virtual void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0; 302 virtual void mouseScrolled (int abs, int rel) = 0; 303 //virtual void tickMouse (float dt) { } 304 }; 305 306 307 /** 308 @brief Interface class used for joy stick input listeners. 309 */ 310 class _CoreExport JoyStickHandler : virtual public InputTickable 311 { 312 public: 313 virtual ~JoyStickHandler() { } 314 virtual void joyStickButtonPressed (int joyStickID, int button) = 0; 315 virtual void joyStickButtonReleased(int joyStickID, int button) = 0; 316 virtual void joyStickButtonHeld (int joyStickID, int button) = 0; 317 virtual void joyStickAxisMoved (int joyStickID, int axis, float value) = 0; 318 //virtual bool joyStickVector3Moved (int joyStickID, int index /*, fill list*/) {return true;} 319 //virtual void tickJoyStick (float dt) { } 320 }; 47 namespace KeyCode 48 { 49 // note: KeyCode comments were directly copied from OISKeyboard.h 50 enum Enum 51 { 52 Unassigned = OIS::KC_UNASSIGNED, 53 Escape = OIS::KC_ESCAPE, 54 NumRow1 = OIS::KC_1, 55 NumRow2 = OIS::KC_2, 56 NumRow3 = OIS::KC_3, 57 NumRow4 = OIS::KC_4, 58 NumRow5 = OIS::KC_5, 59 NumRow6 = OIS::KC_6, 60 NumRow7 = OIS::KC_7, 61 NumRow8 = OIS::KC_8, 62 NumRow9 = OIS::KC_9, 63 NumRow0 = OIS::KC_0, 64 Minus = OIS::KC_MINUS, // - on main keyboard 65 Equals = OIS::KC_EQUALS, 66 Back = OIS::KC_BACK, // backspace 67 Tab = OIS::KC_TAB, 68 Q = OIS::KC_Q, 69 W = OIS::KC_W, 70 E = OIS::KC_E, 71 R = OIS::KC_R, 72 T = OIS::KC_T, 73 Y = OIS::KC_Y, 74 U = OIS::KC_U, 75 I = OIS::KC_I, 76 O = OIS::KC_O, 77 P = OIS::KC_P, 78 LeftBracket = OIS::KC_LBRACKET, 79 RightBracket = OIS::KC_RBRACKET, 80 Return = OIS::KC_RETURN, // Enter on main keyboard 81 LeftControl = OIS::KC_LCONTROL, 82 A = OIS::KC_A, 83 S = OIS::KC_S, 84 D = OIS::KC_D, 85 F = OIS::KC_F, 86 G = OIS::KC_G, 87 H = OIS::KC_H, 88 J = OIS::KC_J, 89 K = OIS::KC_K, 90 L = OIS::KC_L, 91 Semicolon = OIS::KC_SEMICOLON, 92 Apostrophe = OIS::KC_APOSTROPHE, 93 Grave = OIS::KC_GRAVE, // accent 94 LeftShift = OIS::KC_LSHIFT, 95 Backslash = OIS::KC_BACKSLASH, 96 Z = OIS::KC_Z, 97 X = OIS::KC_X, 98 C = OIS::KC_C, 99 V = OIS::KC_V, 100 B = OIS::KC_B, 101 N = OIS::KC_N, 102 M = OIS::KC_M, 103 Comma = OIS::KC_COMMA, 104 Period = OIS::KC_PERIOD, // . on main keyboard 105 Slash = OIS::KC_SLASH, // / on main keyboard 106 RightShift = OIS::KC_RSHIFT, 107 Multiply = OIS::KC_MULTIPLY, // * on numeric keypad 108 LeftAlt = OIS::KC_LMENU, // left Alt 109 Space = OIS::KC_SPACE, 110 CapsLock = OIS::KC_CAPITAL, 111 F1 = OIS::KC_F1, 112 F2 = OIS::KC_F2, 113 F3 = OIS::KC_F3, 114 F4 = OIS::KC_F4, 115 F5 = OIS::KC_F5, 116 F6 = OIS::KC_F6, 117 F7 = OIS::KC_F7, 118 F8 = OIS::KC_F8, 119 F9 = OIS::KC_F9, 120 F10 = OIS::KC_F10, 121 Numlock = OIS::KC_NUMLOCK, 122 Scrolllock = OIS::KC_SCROLL, // Scroll Lock 123 Numpad7 = OIS::KC_NUMPAD7, 124 Numpad8 = OIS::KC_NUMPAD8, 125 Numpad9 = OIS::KC_NUMPAD9, 126 NumpadSubtract= OIS::KC_SUBTRACT, // - on numeric keypad 127 Numpad4 = OIS::KC_NUMPAD4, 128 Numpad5 = OIS::KC_NUMPAD5, 129 Numpad6 = OIS::KC_NUMPAD6, 130 NumpadAdd = OIS::KC_ADD, // + on numeric keypad 131 Numpad1 = OIS::KC_NUMPAD1, 132 Numpad2 = OIS::KC_NUMPAD2, 133 Numpad3 = OIS::KC_NUMPAD3, 134 Numpad0 = OIS::KC_NUMPAD0, 135 NumpadPeriod = OIS::KC_DECIMAL, // . on numeric keypad 136 LessThan = OIS::KC_OEM_102, // < > | on UK/Germany keyboards 137 F11 = OIS::KC_F11, 138 F12 = OIS::KC_F12, 139 F13 = OIS::KC_F13, // (NEC PC98) 140 F14 = OIS::KC_F14, // (NEC PC98) 141 F15 = OIS::KC_F15, // (NEC PC98) 142 Kana = OIS::KC_KANA, // (Japanese keyboard) 143 ABNT_C1 = OIS::KC_ABNT_C1, // / ? on Portugese (Brazilian) keyboards 144 Convert = OIS::KC_CONVERT, // (Japanese keyboard) 145 NoConvert = OIS::KC_NOCONVERT, // (Japanese keyboard) 146 Yen = OIS::KC_YEN, // (Japanese keyboard) 147 ABNT_C2 = OIS::KC_ABNT_C2, // Numpad . on Portugese (Brazilian) keyboards 148 NumpadEquals = OIS::KC_NUMPADEQUALS, // = on numeric keypad (NEC PC98) 149 PreviousTrack = OIS::KC_PREVTRACK, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard) 150 AT = OIS::KC_AT, // (NEC PC98) 151 Colon = OIS::KC_COLON, // (NEC PC98) 152 Underline = OIS::KC_UNDERLINE, // (NEC PC98) 153 Kanji = OIS::KC_KANJI, // (Japanese keyboard) 154 Stop = OIS::KC_STOP, // (NEC PC98) 155 AX = OIS::KC_AX, // (Japan AX) 156 Unlabeled = OIS::KC_UNLABELED, // (J3100) 157 NextTrack = OIS::KC_NEXTTRACK, // Next Track 158 NumpadEnter = OIS::KC_NUMPADENTER, // Enter on numeric keypad 159 RightControl = OIS::KC_RCONTROL, 160 Mute = OIS::KC_MUTE, // Mute 161 Calculator = OIS::KC_CALCULATOR, // Calculator 162 PlayPause = OIS::KC_PLAYPAUSE, // Play / Pause 163 MediaStop = OIS::KC_MEDIASTOP, // Media Stop 164 VolumeDown = OIS::KC_VOLUMEDOWN, // Volume - 165 VolumeUp = OIS::KC_VOLUMEUP, // Volume + 166 WebHome = OIS::KC_WEBHOME, // Web home 167 NumpadComma = OIS::KC_NUMPADCOMMA, // , on numeric keypad (NEC PC98) 168 Divide = OIS::KC_DIVIDE, // / on numeric keypad 169 SYSRQ = OIS::KC_SYSRQ, 170 RightAlt = OIS::KC_RMENU, // right Alt 171 Pause = OIS::KC_PAUSE, // Pause 172 Home = OIS::KC_HOME, // Home on arrow keypad 173 Up = OIS::KC_UP, // UpArrow on arrow keypad 174 PageUp = OIS::KC_PGUP, // PgUp on arrow keypad 175 Left = OIS::KC_LEFT, // LeftArrow on arrow keypad 176 Right = OIS::KC_RIGHT, // RightArrow on arrow keypad 177 End = OIS::KC_END, // End on arrow keypad 178 Down = OIS::KC_DOWN, // DownArrow on arrow keypad 179 PageDown = OIS::KC_PGDOWN, // PgDn on arrow keypad 180 Insert = OIS::KC_INSERT, // Insert on arrow keypad 181 Delete = OIS::KC_DELETE, // Delete on arrow keypad 182 LeftWindows = OIS::KC_LWIN, // Left Windows key 183 RightWindows = OIS::KC_RWIN, // Right Windows key 184 Apps = OIS::KC_APPS, // AppMenu key 185 Power = OIS::KC_POWER, // System Power 186 Sleep = OIS::KC_SLEEP, // System Sleep 187 Wake = OIS::KC_WAKE, // System Wake 188 WebSearch = OIS::KC_WEBSEARCH, // Web Search 189 WebFavorites = OIS::KC_WEBFAVORITES, // Web Favorites 190 WebRefresh = OIS::KC_WEBREFRESH, // Web Refresh 191 WebStop = OIS::KC_WEBSTOP, // Web Stop 192 WebForward = OIS::KC_WEBFORWARD, // Web Forward 193 WebBack = OIS::KC_WEBBACK, // Web Back 194 MyComputer = OIS::KC_MYCOMPUTER, // My Computer 195 Mail = OIS::KC_MAIL, // Mail 196 MediaSelect = OIS::KC_MEDIASELECT // Media Select 197 }; 198 } 199 200 namespace MouseButton 201 { 202 enum Enum 203 { 204 Left = OIS::MB_Left, 205 Right = OIS::MB_Right, 206 Middle = OIS::MB_Middle, 207 Button3 = OIS::MB_Button3, 208 Button4 = OIS::MB_Button4, 209 Button5 = OIS::MB_Button5, 210 Button6 = OIS::MB_Button6, 211 Button7 = OIS::MB_Button7 212 }; 213 } 214 215 namespace JoyStickButton 216 { 217 enum Enum 218 { 219 Button0 = 0, Button1 = 1, Button2 = 2, Button3 = 3, 220 Button4 = 4, Button5 = 5, Button6 = 6, Button7 = 7, 221 Button8 = 8, Button9 = 9, Button10 = 10, Button11 = 11, 222 Button12 = 12, Button13 = 13, Button14 = 14, Button15 = 15, 223 Button16 = 16, Button17 = 17, Button18 = 18, Button19 = 19, 224 Button20 = 20, Button21 = 21, Button22 = 22, Button23 = 23, 225 Button24 = 24, Button25 = 25, Button26 = 26, Button27 = 27, 226 Button28 = 28, Button29 = 29, Button30 = 30, Button31 = 31, 227 228 POV0North = 32, POV0South = 33, POV0East = 34, POV0West = 35, 229 POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39, 230 231 POV1North = 40, POV1South = 41, POV1East = 42, POV1West = 43, 232 POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47, 233 234 POV2North = 48, POV2South = 49, POV2East = 50, POV2West = 51, 235 POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55, 236 237 POV3North = 56, POV3South = 57, POV3East = 58, POV3West = 59, 238 POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63, 239 }; 240 } 241 242 namespace KeyboardModifier 243 { 244 enum Enum 245 { 246 Shift = 0x0000001, 247 Ctrl = 0x0000010, 248 Alt = 0x0000100 249 }; 250 } 251 252 namespace InputDevice 253 { 254 enum Enum 255 { 256 Keyboard, 257 Mouse, 258 JoyStick0, 259 JoyStick1, 260 JoyStick2, 261 JoyStick3, 262 // note: No problem if there are more joy sticks. This enum is just for convenience. 263 }; 264 } 265 266 struct _CoreExport Key 267 { 268 Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { } 269 KeyCode::Enum key; 270 unsigned int text; 271 }; 272 273 class _CoreExport KeyEvent 274 { 275 public: 276 KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { } 277 KeyEvent(const OIS::KeyEvent& evt, unsigned int mod) 278 : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { } 279 KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { } 280 bool isModifierDown(KeyboardModifier::Enum modifier) const 281 { return (KeyboardModifier::Enum)modifier&modifiers; } 282 283 const KeyCode::Enum key; 284 unsigned int text; 285 unsigned int modifiers; 286 }; 287 288 289 class _CoreExport InputTickable 290 { 291 public: 292 virtual ~InputTickable() { } 293 virtual void tickInput(float dt) = 0; 294 }; 295 296 /** 297 @brief 298 Interface class used for key input listeners. 299 */ 300 class _CoreExport KeyHandler : virtual public InputTickable 301 { 302 public: 303 virtual ~KeyHandler() { } 304 virtual void keyPressed (const KeyEvent& evt) = 0; 305 virtual void keyReleased(const KeyEvent& evt) = 0; 306 virtual void keyHeld (const KeyEvent& evt) = 0; 307 virtual void tickKey (float dt) = 0; 308 }; 309 310 /** 311 @brief 312 Interface class used for mouse input listeners. 313 */ 314 class _CoreExport MouseHandler : virtual public InputTickable 315 { 316 public: 317 virtual ~MouseHandler() { } 318 virtual void mouseButtonPressed (MouseButton::Enum id) = 0; 319 virtual void mouseButtonReleased(MouseButton::Enum id) = 0; 320 virtual void mouseButtonHeld (MouseButton::Enum id) = 0; 321 virtual void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0; 322 virtual void mouseScrolled (int abs, int rel) = 0; 323 virtual void tickMouse (float dt) = 0; 324 }; 325 326 327 /** 328 @brief 329 Interface class used for joy stick input listeners. 330 */ 331 class _CoreExport JoyStickHandler : virtual public InputTickable 332 { 333 public: 334 virtual ~JoyStickHandler() { } 335 virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) = 0; 336 virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) = 0; 337 virtual void joyStickButtonHeld (unsigned int joyStickID, JoyStickButton::Enum id) = 0; 338 virtual void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value) = 0; 339 virtual void tickJoyStick (float dt, unsigned int joyStick) = 0; 340 }; 341 342 class _CoreExport EmptyHandler : public KeyHandler, public MouseHandler, public JoyStickHandler 343 { 344 private: 345 void tickInput(float dt) { } 346 void tickJoyStick(float dt, unsigned int joyStick) { } 347 void tickMouse(float dt) { } 348 void tickKey(float dt) { } 349 350 void keyPressed (const KeyEvent& evt) { } 351 void keyReleased(const KeyEvent& evt) { } 352 void keyHeld (const KeyEvent& evt) { } 353 354 void mouseButtonPressed (MouseButton::Enum id) { } 355 void mouseButtonReleased(MouseButton::Enum id) { } 356 void mouseButtonHeld (MouseButton::Enum id) { } 357 void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { } 358 void mouseScrolled (int abs, int rel) { } 359 360 void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) { } 361 void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) { } 362 void joyStickButtonHeld (unsigned int joyStickID, JoyStickButton::Enum id) { } 363 void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value) { } 364 }; 321 365 322 366 } -
code/trunk/src/core/input/InputManager.cc
r1747 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the InputManager that captures all the input from OIS 32 and redirects it to handlers. 30 @file 31 @brief 32 Implementation of the InputManager that captures all the input from OIS 33 and redirects it to handlers. 33 34 */ 34 35 35 36 #include "InputManager.h" 36 37 37 #include <limits.h> 38 #include <climits> 39 #include <cassert> 40 41 #include "ois/OISException.h" 42 #include "ois/OISInputManager.h" 38 43 39 44 #include "core/CoreIncludes.h" 40 45 #include "core/ConfigValueIncludes.h" 46 #include "core/Exception.h" 41 47 #include "core/CommandExecutor.h" 42 48 #include "core/ConsoleCommand.h" 43 #include "core/Shell.h" // hack!44 49 #include "util/Debug.h" 45 50 … … 48 53 #include "KeyDetector.h" 49 54 #include "CalibratorCallback.h" 50 51 #include " src/ois/OISException.h"52 #include " src/ois/OISInputManager.h"55 #include "InputState.h" 56 #include "SimpleInputState.h" 57 #include "ExtendedInputState.h" 53 58 54 59 namespace orxonox 55 60 { 56 SetConsoleCommandShortcut(InputManager, keyBind); 57 SetConsoleCommandShortcut(InputManager, storeKeyStroke); 58 SetConsoleCommandShortcut(InputManager, calibrate); 59 60 // ############################### 61 // ### Internal Methods ### 62 // ############################### 63 // ############################### 64 65 /** 66 @brief Constructor only sets member fields to initial zero values 67 and registers the class in the class hierarchy. 68 */ 69 InputManager::InputManager() : 70 inputSystem_(0), keyboard_(0), mouse_(0), 71 joySticksSize_(0), 72 keyBinder_(0), keyDetector_(0), buffer_(0), calibratorCallback_(0), 73 state_(IS_UNINIT), stateRequest_(IS_UNINIT), savedState_(IS_UNINIT), 74 keyboardModifiers_(0) 75 { 76 RegisterRootObject(InputManager); 77 } 78 79 /** 80 @brief The one instance of the InputManager is stored in this function. 81 @return A reference to the only instance of the InputManager 82 */ 83 InputManager& InputManager::_getSingleton() 84 { 85 static InputManager theOnlyInstance; 86 return theOnlyInstance; 87 } 88 89 /** 90 @brief Destructor only called at the end of the program, after main. 91 */ 92 InputManager::~InputManager() 93 { 94 _destroy(); 95 } 96 97 /** 98 @brief Creates the OIS::InputMananger, the keyboard, the mouse and 99 the joysticks and assigns the key bindings. 100 @param windowHnd The window handle of the render window 101 @param windowWidth The width of the render window 102 @param windowHeight The height of the render window 103 */ 104 bool InputManager::_initialise(const size_t windowHnd, int windowWidth, int windowHeight, 105 bool createKeyboard, bool createMouse, bool createJoySticks) 106 { 107 if (state_ == IS_UNINIT) 108 { 109 CCOUT(3) << "Initialising Input System..." << std::endl; 110 CCOUT(ORX_DEBUG) << "Initialising OIS components..." << std::endl; 111 112 OIS::ParamList paramList; 113 std::ostringstream windowHndStr; 114 115 // Fill parameter list 116 windowHndStr << (unsigned int)windowHnd; 117 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 118 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 119 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 61 SetConsoleCommand(InputManager, keyBind, true); 62 SetConsoleCommand(InputManager, storeKeyStroke, true); 63 SetConsoleCommand(InputManager, calibrate, true); 64 SetConsoleCommand(InputManager, reload, false); 65 66 std::string InputManager::bindingCommmandString_s = ""; 67 InputManager* InputManager::singletonRef_s = 0; 68 69 using namespace InputDevice; 70 71 /** 72 @brief 73 Defines the |= operator for easier use. 74 */ 75 inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval, 76 InputManager::InputManagerState rval) 77 { 78 return (lval = (InputManager::InputManagerState)(lval | rval)); 79 } 80 81 /** 82 @brief 83 Defines the &= operator for easier use. 84 */ 85 inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval) 86 { 87 return (lval = (InputManager::InputManagerState)(lval & rval)); 88 } 89 90 // ############################################################ 91 // ##### Initialisation ##### 92 // ########## ########## 93 // ############################################################ 94 95 /** 96 @brief 97 Constructor only sets member fields to initial zero values 98 and registers the class in the class hierarchy. 99 */ 100 InputManager::InputManager() 101 : inputSystem_(0) 102 , keyboard_(0) 103 , mouse_(0) 104 , joySticksSize_(0) 105 , devicesNum_(0) 106 , windowHnd_(0) 107 , internalState_(Uninitialised) 108 , stateDetector_(0) 109 , stateCalibrator_(0) 110 , stateEmpty_(0) 111 , bCalibrating_(false) 112 , keyboardModifiers_(0) 113 { 114 RegisterRootObject(InputManager); 115 116 assert(singletonRef_s == 0); 117 singletonRef_s = this; 118 } 119 120 /** 121 @brief 122 Creates the OIS::InputMananger, the keyboard, the mouse and 123 the joysticks and assigns the key bindings. 124 @param windowHnd 125 The window handle of the render window 126 @param windowWidth 127 The width of the render window 128 @param windowHeight 129 The height of the render window 130 @param joyStickSupport 131 Whether or not to load the joy sticks as well 132 */ 133 void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport) 134 { 135 CCOUT(3) << "Initialising Input System..." << std::endl; 136 137 if (!(internalState_ & OISReady)) 138 { 139 CCOUT(4) << "Initialising OIS components..." << std::endl; 140 141 // store handle internally so we can reload OIS 142 windowHnd_ = windowHnd; 143 144 OIS::ParamList paramList; 145 std::ostringstream windowHndStr; 146 147 // Fill parameter list 148 windowHndStr << (unsigned int)windowHnd_; 149 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 150 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 151 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 120 152 #if defined OIS_LINUX_PLATFORM 121 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));153 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 122 154 #endif 123 155 124 try 125 { 126 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 127 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 128 } 129 catch (OIS::Exception ex) 130 { 131 CCOUT(ORX_ERROR) << "Error: Failed creating an OIS input system." 132 << "OIS message: \"" << ex.eText << "\"" << std::endl; 133 inputSystem_ = 0; 156 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 157 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 158 159 _initialiseKeyboard(); 160 161 _initialiseMouse(); 162 163 if (joyStickSupport) 164 _initialiseJoySticks(); 165 166 // Set mouse/joystick region 167 if (mouse_) 168 setWindowExtents(windowWidth, windowHeight); 169 170 // clear all buffers 171 _clearBuffers(); 172 173 // load joy stick calibration 174 setConfigValues(); 175 176 internalState_ |= OISReady; 177 178 CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl; 179 } 180 else 181 { 182 CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl; 183 } 184 185 if (!(internalState_ & InternalsReady)) 186 { 187 CCOUT(4) << "Initialising InputStates components..." << std::endl; 188 189 stateEmpty_ = createInputState<SimpleInputState>("empty", -1); 190 stateEmpty_->setHandler(new EmptyHandler()); 191 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 192 193 stateDetector_ = createInputState<SimpleInputState>("detector", 101); 194 KeyDetector* temp = new KeyDetector(); 195 temp->loadBindings("storeKeyStroke"); 196 stateDetector_->setHandler(temp); 197 198 stateCalibrator_ = createInputState<SimpleInputState>("calibrator", 100); 199 stateCalibrator_->setHandler(new EmptyHandler()); 200 InputBuffer* buffer = new InputBuffer(); 201 buffer->registerListener(this, &InputManager::_completeCalibration, '\r', true); 202 stateCalibrator_->setKeyHandler(buffer); 203 204 internalState_ |= InternalsReady; 205 206 CCOUT(4) << "Initialising InputStates complete." << std::endl; 207 } 208 209 _updateActiveStates(); 210 211 CCOUT(3) << "Initialising complete." << std::endl; 212 } 213 214 /** 215 @brief 216 Creates a keyboard and sets the event handler. 217 @return 218 False if keyboard stays uninitialised, true otherwise. 219 */ 220 void InputManager::_initialiseKeyboard() 221 { 222 if (keyboard_ != 0) 223 { 224 CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl; 225 return; 226 } 227 if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0) 228 { 229 keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true); 230 // register our listener in OIS. 231 keyboard_->setEventCallback(this); 232 // note: OIS will not detect keys that have already been down when the keyboard was created. 233 CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl; 234 } 235 else 236 { 237 ThrowException(InitialisationFailed, "No keyboard found!"); 238 } 239 } 240 241 /** 242 @brief 243 Creates a mouse and sets the event handler. 244 @return 245 False if mouse stays uninitialised, true otherwise. 246 */ 247 void InputManager::_initialiseMouse() 248 { 249 if (mouse_ != 0) 250 { 251 CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl; 252 return; 253 } 254 try 255 { 256 if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0) 257 { 258 mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true)); 259 // register our listener in OIS. 260 mouse_->setEventCallback(this); 261 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl; 262 } 263 else 264 { 265 CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl; 266 } 267 } 268 catch (OIS::Exception ex) 269 { 270 CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n" 271 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 272 mouse_ = 0; 273 } 274 } 275 276 /** 277 @brief 278 Creates all joy sticks and sets the event handler. 279 @return 280 False joy stick stay uninitialised, true otherwise. 281 */ 282 void InputManager::_initialiseJoySticks() 283 { 284 if (joySticksSize_ > 0) 285 { 286 CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl; 287 return; 288 } 289 if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0) 290 { 291 for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++) 292 { 293 try 294 { 295 OIS::JoyStick* stig = static_cast<OIS::JoyStick*> 296 (inputSystem_->createInputObject(OIS::OISJoyStick, true)); 297 CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl; 298 joySticks_.push_back(stig); 299 // register our listener in OIS. 300 stig->setEventCallback(this); 301 } 302 catch (OIS::Exception ex) 303 { 304 CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n" 305 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 306 } 307 } 308 } 309 else 310 { 311 //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl; 312 } 313 _redimensionLists(); 314 } 315 316 /** 317 @brief 318 Sets the size of all the different lists that are dependent on the number 319 of joy stick devices created. 320 @remarks 321 No matter whether there are a mouse and/or keyboard, they will always 322 occupy 2 places in the device number dependent lists. 323 */ 324 void InputManager::_redimensionLists() 325 { 326 joySticksSize_ = joySticks_.size(); 327 devicesNum_ = 2 + joySticksSize_; 328 joyStickButtonsDown_ .resize(joySticksSize_); 329 povStates_ .resize(joySticksSize_); 330 sliderStates_ .resize(joySticksSize_); 331 joySticksCalibration_.resize(joySticksSize_); 332 333 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 334 { 335 // reset the calibration with default values 336 for (unsigned int i = 0; i < 24; i++) 337 { 338 joySticksCalibration_[iJoyStick].negativeCoeff[i] = 1.0f/32767.0f; 339 joySticksCalibration_[iJoyStick].positiveCoeff[i] = 1.0f/32768.0f; 340 joySticksCalibration_[iJoyStick].zeroStates[i] = 0; 341 } 342 } 343 344 // state management 345 activeStatesTop_.resize(devicesNum_); 346 347 // inform all states 348 for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin(); 349 it != inputStatesByPriority_.end(); ++it) 350 it->second->setNumOfJoySticks(joySticksSize_); 351 } 352 353 /** 354 @brief 355 Sets the configurable values. 356 This mainly concerns joy stick calibrations. 357 */ 358 void InputManager::setConfigValues() 359 { 360 if (joySticksSize_ > 0) 361 { 362 std::vector<double> coeffPos; 363 std::vector<double> coeffNeg; 364 std::vector<int> zero; 365 coeffPos.resize(24); 366 coeffNeg.resize(24); 367 zero.resize(24); 368 for (unsigned int i = 0; i < 24; i++) 369 { 370 coeffPos[i] = 1.0f/32767.0f; 371 coeffNeg[i] = 1.0f/32768.0f; 372 zero[i] = 0; 373 } 374 375 ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos"); 376 if (!cont) 377 { 378 cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "CoeffPos", coeffPos); 379 getIdentifier()->addConfigValueContainer("CoeffPos", cont); 380 } 381 cont->getValue(&coeffPos, this); 382 383 cont = getIdentifier()->getConfigValueContainer("CoeffNeg"); 384 if (!cont) 385 { 386 cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "CoeffNeg", coeffNeg); 387 getIdentifier()->addConfigValueContainer("CoeffNeg", cont); 388 } 389 cont->getValue(&coeffNeg, this); 390 391 cont = getIdentifier()->getConfigValueContainer("Zero"); 392 if (!cont) 393 { 394 cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "Zero", zero); 395 getIdentifier()->addConfigValueContainer("Zero", cont); 396 } 397 cont->getValue(&zero, this); 398 399 // copy values to our own variables 400 for (unsigned int i = 0; i < 24; i++) 401 { 402 joySticksCalibration_[0].positiveCoeff[i] = coeffPos[i]; 403 joySticksCalibration_[0].negativeCoeff[i] = coeffNeg[i]; 404 joySticksCalibration_[0].zeroStates[i] = zero[i]; 405 } 406 } 407 } 408 409 410 // ############################################################ 411 // ##### Destruction ##### 412 // ########## ########## 413 // ############################################################ 414 415 /** 416 @brief 417 Destroys all the created input devices and states. 418 */ 419 InputManager::~InputManager() 420 { 421 if (internalState_ != Uninitialised) 422 { 423 try 424 { 425 CCOUT(3) << "Destroying ..." << std::endl; 426 427 // clear our own states 428 stateEmpty_->removeAndDestroyAllHandlers(); 429 stateCalibrator_->removeAndDestroyAllHandlers(); 430 stateDetector_->removeAndDestroyAllHandlers(); 431 432 // kick all active states 'nicely' 433 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 434 rit != activeStates_.rend(); ++rit) 435 { 436 (*rit).second->onLeave(); 437 } 438 439 // destroy all input states 440 while (inputStatesByPriority_.size() > 0) 441 _destroyState((*inputStatesByPriority_.rbegin()).second); 442 443 // destroy the devices 444 _destroyKeyboard(); 445 _destroyMouse(); 446 _destroyJoySticks(); 447 448 OIS::InputManager::destroyInputSystem(inputSystem_); 449 450 CCOUT(3) << "Destroying done." << std::endl; 451 } 452 catch (OIS::Exception& ex) 453 { 454 CCOUT(1) << "An exception has occured while destroying:\n" << ex.what() 455 << "This could lead to a possible memory/resource leak!" << std::endl; 456 } 457 } 458 } 459 460 /** 461 @brief 462 Destroys the keyboard and sets it to 0. 463 */ 464 void InputManager::_destroyKeyboard() 465 { 466 assert(inputSystem_); 467 if (keyboard_) 468 inputSystem_->destroyInputObject(keyboard_); 469 keyboard_ = 0; 470 CCOUT(4) << "Keyboard destroyed." << std::endl; 471 } 472 473 /** 474 @brief 475 Destroys the mouse and sets it to 0. 476 */ 477 void InputManager::_destroyMouse() 478 { 479 assert(inputSystem_); 480 if (mouse_) 481 inputSystem_->destroyInputObject(mouse_); 482 mouse_ = 0; 483 CCOUT(4) << "Mouse destroyed." << std::endl; 484 } 485 486 /** 487 @brief 488 Destroys all the joy sticks and resizes the lists to 0. 489 */ 490 void InputManager::_destroyJoySticks() 491 { 492 if (joySticksSize_ > 0) 493 { 494 assert(inputSystem_); 495 for (unsigned int i = 0; i < joySticksSize_; i++) 496 if (joySticks_[i] != 0) 497 inputSystem_->destroyInputObject(joySticks_[i]); 498 499 joySticks_.clear(); 500 // don't use _redimensionLists(), might mess with registered handler if 501 // downgrading from 2 to 1 joystick 502 //_redimensionLists(); 503 joySticksSize_ = 0; 504 } 505 CCOUT(4) << "Joy sticks destroyed." << std::endl; 506 } 507 508 /** 509 @brief 510 Removes and destroys an InputState. 511 @return 512 True if state was removed immediately, false if postponed. 513 */ 514 void InputManager::_destroyState(InputState* state) 515 { 516 assert(state && !(this->internalState_ & Ticking)); 517 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 518 if (it != this->activeStates_.end()) 519 { 520 this->activeStates_.erase(it); 521 _updateActiveStates(); 522 } 523 inputStatesByPriority_.erase(state->getPriority()); 524 inputStatesByName_.erase(state->getName()); 525 delete state; 526 } 527 528 void InputManager::_clearBuffers() 529 { 530 keysDown_.clear(); 531 keyboardModifiers_ = 0; 532 mouseButtonsDown_.clear(); 533 for (unsigned int i = 0; i < joySticksSize_; ++i) 534 { 535 joyStickButtonsDown_[i].clear(); 536 for (int j = 0; j < 4; ++j) 537 { 538 sliderStates_[i].sliderStates[j].x = 0; 539 sliderStates_[i].sliderStates[j].y = 0; 540 povStates_[i][j] = 0; 541 } 542 } 543 } 544 545 546 // ############################################################ 547 // ##### Reloading ##### 548 // ########## ########## 549 // ############################################################ 550 551 /** 552 @brief 553 Public interface. Only reloads immediately if the call stack doesn't 554 include the tick() method. 555 @param joyStickSupport 556 Whether or not to initialise joy sticks as well. 557 */ 558 void InputManager::reloadInputSystem(bool joyStickSupport) 559 { 560 if (internalState_ & Ticking) 561 { 562 // We cannot destroy OIS right now, because reload was probably 563 // caused by a user clicking on a GUI item. The backtrace would then 564 // include an OIS method. So it would be a very bad thing to destroy it.. 565 internalState_ |= ReloadRequest; 566 // Misuse of internalState_: We can easily store the joyStickSupport bool. 567 // use Uninitialised as 0 value in order to make use of the overloaded |= operator 568 internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised; 569 } 570 else if (internalState_ & OISReady) 571 { 572 _reload(joyStickSupport); 573 } 574 else 575 { 576 CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or" 577 << "joy sticks are currently calibrating." << std::endl; 578 } 579 } 580 581 /** 582 @brief 583 Internal reload method. Destroys the OIS devices and loads them again. 584 */ 585 void InputManager::_reload(bool joyStickSupport) 586 { 587 try 588 { 589 CCOUT(3) << "Reloading ..." << std::endl; 590 591 // Save mouse clipping size 592 int mouseWidth = mouse_->getMouseState().width; 593 int mouseHeight = mouse_->getMouseState().height; 594 595 internalState_ &= ~OISReady; 596 597 // destroy the devices 598 _destroyKeyboard(); 599 _destroyMouse(); 600 _destroyJoySticks(); 601 602 OIS::InputManager::destroyInputSystem(inputSystem_); 603 inputSystem_ = 0; 604 605 // clear all buffers containing input information 606 _clearBuffers(); 607 608 initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport); 609 610 CCOUT(3) << "Reloading done." << std::endl; 611 } 612 catch (OIS::Exception& ex) 613 { 614 CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl; 615 } 616 } 617 618 // ############################################################ 619 // ##### Runtime Methods ##### 620 // ########## ########## 621 // ############################################################ 622 623 /** 624 @brief 625 Updates the InputManager. Tick is called by the Core class. 626 @param dt 627 Delta time 628 */ 629 void InputManager::tick(float dt) 630 { 631 if (internalState_ == Uninitialised) 632 return; 633 else if (internalState_ & ReloadRequest) 634 { 635 _reload(internalState_ & JoyStickSupport); 636 internalState_ &= ~ReloadRequest; 637 internalState_ &= ~JoyStickSupport; 638 } 639 640 // check for states to leave 641 for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin(); 642 rit != stateLeaveRequests_.rend(); ++rit) 643 { 644 (*rit)->onLeave(); 645 // just to be sure that the state actually is registered 646 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 647 648 activeStates_.erase((*rit)->getPriority()); 649 _updateActiveStates(); 650 } 651 stateLeaveRequests_.clear(); 652 653 // check for states to enter 654 for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin(); 655 rit != stateEnterRequests_.rend(); ++rit) 656 { 657 // just to be sure that the state actually is registered 658 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 659 660 activeStates_[(*rit)->getPriority()] = (*rit); 661 _updateActiveStates(); 662 (*rit)->onEnter(); 663 } 664 stateEnterRequests_.clear(); 665 666 // check for states to destroy 667 for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin(); 668 rit != stateDestroyRequests_.rend(); ++rit) 669 { 670 _destroyState((*rit)); 671 } 672 stateDestroyRequests_.clear(); 673 674 // mark that we capture and distribute input 675 internalState_ |= Ticking; 676 677 // Capture all the input. This calls the event handlers in InputManager. 678 if (keyboard_) 679 keyboard_->capture(); 680 if (mouse_) 681 mouse_->capture(); 682 for (unsigned int i = 0; i < joySticksSize_; i++) 683 joySticks_[i]->capture(); 684 685 if (!bCalibrating_) 686 { 687 // call all the handlers for the held key events 688 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 689 activeStatesTop_[Keyboard]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_)); 690 691 // call all the handlers for the held mouse button events 692 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 693 activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]); 694 695 // call all the handlers for the held joy stick button events 696 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 697 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 698 activeStatesTop_[JoyStick0 + iJoyStick] 699 ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 700 701 // tick the handlers for each active handler 702 for (unsigned int i = 0; i < devicesNum_; ++i) 703 activeStatesTop_[i]->tickInput(dt, i); 704 705 // tick the handler with a general tick afterwards 706 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 707 activeStatesTicked_[i]->tickInput(dt); 708 } 709 710 internalState_ &= ~Ticking; 711 } 712 713 /** 714 @brief 715 Updates the currently active states (according to activeStates_) for each device. 716 Also, a list of all active states (no duplicates!) is compiled for the general tick. 717 */ 718 void InputManager::_updateActiveStates() 719 { 720 for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it) 721 for (unsigned int i = 0; i < devicesNum_; ++i) 722 if (it->second->isInputDeviceEnabled(i)) 723 activeStatesTop_[i] = it->second; 724 725 // update tickables (every state will only appear once) 726 // Using a std::set to avoid duplicates 727 std::set<InputState*> tempSet; 728 for (unsigned int i = 0; i < devicesNum_; ++i) 729 tempSet.insert(activeStatesTop_[i]); 730 731 // copy the content of the set back to the actual vector 732 activeStatesTicked_.clear(); 733 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) 734 activeStatesTicked_.push_back(*it); 735 736 this->mouseButtonsDown_.clear(); 737 } 738 739 /** 740 @brief 741 Processes the accumultated data for the joy stick calibration. 742 */ 743 void InputManager::_completeCalibration() 744 { 745 for (unsigned int i = 0; i < 24; i++) 746 { 747 // positive coefficient 748 if (marginalsMax_[i] == INT_MIN) 749 marginalsMax_[i] = 32767; 750 // coefficients 751 if (marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]) 752 { 753 joySticksCalibration_[0].positiveCoeff[i] 754 = 1.0f/(marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]); 755 } 756 else 757 joySticksCalibration_[0].positiveCoeff[i] = 1.0f; 758 759 // config value 760 ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos"); 761 assert(cont); 762 cont->set(i, joySticksCalibration_[0].positiveCoeff[i]); 763 764 // negative coefficient 765 if (marginalsMin_[i] == INT_MAX) 766 marginalsMin_[i] = -32768; 767 // coefficients 768 if (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]) 769 { 770 joySticksCalibration_[0].negativeCoeff[i] = -1.0f 771 / (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]); 772 } 773 else 774 joySticksCalibration_[0].negativeCoeff[i] = 1.0f; 775 // config value 776 cont = getIdentifier()->getConfigValueContainer("CoeffNeg"); 777 assert(cont); 778 cont->set(i, joySticksCalibration_[0].negativeCoeff[i]); 779 780 // zero states 781 if (i < 8) 782 { 783 if (!(i & 1)) 784 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abX; 785 else 786 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abY; 787 } 788 else 789 { 790 if (i - 8 < joySticks_[0]->getJoyStickState().mAxes.size()) 791 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mAxes[i - 8].abs; 792 else 793 joySticksCalibration_[0].zeroStates[i] = 0; 794 } 795 // config value 796 cont = getIdentifier()->getConfigValueContainer("Zero"); 797 assert(cont); 798 cont->set(i, joySticksCalibration_[0].zeroStates[i]); 799 } 800 801 // restore old input state 802 requestLeaveState("calibrator"); 803 bCalibrating_ = false; 804 } 805 806 807 // ############################################################ 808 // ##### OIS events ##### 809 // ########## ########## 810 // ############################################################ 811 812 // ###### Key Events ###### 813 814 /** 815 @brief 816 Event handler for the keyPressed Event. 817 @param e 818 Event information 819 */ 820 bool InputManager::keyPressed(const OIS::KeyEvent &e) 821 { 822 // check whether the key already is in the list (can happen when focus was lost) 823 unsigned int iKey = 0; 824 while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::Enum)e.key) 825 iKey++; 826 if (iKey == keysDown_.size()) 827 keysDown_.push_back(Key(e)); 828 else 829 return true; 830 831 // update modifiers 832 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 833 keyboardModifiers_ |= KeyboardModifier::Alt; // alt key 834 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 835 keyboardModifiers_ |= KeyboardModifier::Ctrl; // ctrl key 836 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 837 keyboardModifiers_ |= KeyboardModifier::Shift; // shift key 838 839 activeStatesTop_[Keyboard]->keyPressed(KeyEvent(e, keyboardModifiers_)); 840 841 return true; 842 } 843 844 /** 845 @brief 846 Event handler for the keyReleased Event. 847 @param e 848 Event information 849 */ 850 bool InputManager::keyReleased(const OIS::KeyEvent &e) 851 { 852 // remove the key from the keysDown_ list 853 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 854 { 855 if (keysDown_[iKey].key == (KeyCode::Enum)e.key) 856 { 857 keysDown_.erase(keysDown_.begin() + iKey); 858 break; 859 } 860 } 861 862 // update modifiers 863 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 864 keyboardModifiers_ &= ~KeyboardModifier::Alt; // alt key 865 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 866 keyboardModifiers_ &= ~KeyboardModifier::Ctrl; // ctrl key 867 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 868 keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key 869 870 activeStatesTop_[Keyboard]->keyReleased(KeyEvent(e, keyboardModifiers_)); 871 872 return true; 873 } 874 875 876 // ###### Mouse Events ###### 877 878 /** 879 @brief 880 Event handler for the mouseMoved Event. 881 @param e 882 Event information 883 */ 884 bool InputManager::mouseMoved(const OIS::MouseEvent &e) 885 { 886 // check for actual moved event 887 if (e.state.X.rel != 0 || e.state.Y.rel != 0) 888 { 889 activeStatesTop_[Mouse]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs), 890 IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height)); 891 } 892 893 // check for mouse scrolled event 894 if (e.state.Z.rel != 0) 895 { 896 activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 897 } 898 899 return true; 900 } 901 902 /** 903 @brief 904 Event handler for the mousePressed Event. 905 @param e 906 Event information 907 @param id 908 The ID of the mouse button 909 */ 910 bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) 911 { 912 // check whether the button already is in the list (can happen when focus was lost) 913 unsigned int iButton = 0; 914 while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButton::Enum)id) 915 iButton++; 916 if (iButton == mouseButtonsDown_.size()) 917 mouseButtonsDown_.push_back((MouseButton::Enum)id); 918 919 activeStatesTop_[Mouse]->mouseButtonPressed((MouseButton::Enum)id); 920 921 return true; 922 } 923 924 /** 925 @brief 926 Event handler for the mouseReleased Event. 927 @param e 928 Event information 929 @param id 930 The ID of the mouse button 931 */ 932 bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) 933 { 934 // remove the button from the keysDown_ list 935 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 936 { 937 if (mouseButtonsDown_[iButton] == (MouseButton::Enum)id) 938 { 939 mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton); 940 break; 941 } 942 } 943 944 activeStatesTop_[Mouse]->mouseButtonReleased((MouseButton::Enum)id); 945 946 return true; 947 } 948 949 950 // ###### Joy Stick Events ###### 951 952 /** 953 @brief 954 Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent 955 */ 956 inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg) 957 { 958 // use the device to identify which one called the method 959 OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device; 960 unsigned int iJoyStick = 0; 961 while (joySticks_[iJoyStick] != joyStick) 962 iJoyStick++; 963 // assert: Unknown joystick fired an event. 964 assert(iJoyStick != joySticksSize_); 965 return iJoyStick; 966 } 967 968 bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button) 969 { 970 unsigned int iJoyStick = _getJoystick(arg); 971 972 // check whether the button already is in the list (can happen when focus was lost) 973 std::vector<JoyStickButton::Enum>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 974 unsigned int iButton = 0; 975 while (iButton < buttonsDown.size() && buttonsDown[iButton] != button) 976 iButton++; 977 if (iButton == buttonsDown.size()) 978 buttonsDown.push_back((JoyStickButton::Enum)button); 979 980 activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButton::Enum)button); 981 982 return true; 983 } 984 985 bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button) 986 { 987 unsigned int iJoyStick = _getJoystick(arg); 988 989 // remove the button from the joyStickButtonsDown_ list 990 std::vector<JoyStickButton::Enum>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 991 for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++) 992 { 993 if (buttonsDown[iButton] == button) 994 { 995 buttonsDown.erase(buttonsDown.begin() + iButton); 996 break; 997 } 998 } 999 1000 activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButton::Enum)button); 1001 1002 return true; 1003 } 1004 1005 /** 1006 @brief 1007 Calls the states for a particular axis with our enumeration. 1008 Used by OIS sliders and OIS axes. 1009 */ 1010 void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value) 1011 { 1012 if (bCalibrating_) 1013 { 1014 if (value > marginalsMax_[axis]) 1015 marginalsMax_[axis] = value; 1016 if (value < marginalsMin_[axis]) 1017 marginalsMin_[axis] = value; 1018 } 1019 else 1020 { 1021 float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis]; 1022 if (fValue > 0.0f) 1023 fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis]; 1024 else 1025 fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis]; 1026 1027 activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue); 1028 } 1029 } 1030 1031 bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis) 1032 { 1033 unsigned int iJoyStick = _getJoystick(arg); 1034 1035 // keep in mind that the first 8 axes are reserved for the sliders 1036 _fireAxis(iJoyStick, axis + 8, arg.state.mAxes[axis].abs); 1037 1038 return true; 1039 } 1040 1041 bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id) 1042 { 1043 unsigned int iJoyStick = _getJoystick(arg); 1044 1045 if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX) 1046 _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX); 1047 else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY) 1048 _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY); 1049 1050 return true; 1051 } 1052 1053 bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id) 1054 { 1055 unsigned int iJoyStick = _getJoystick(arg); 1056 1057 // translate the POV into 8 simple buttons 1058 1059 int lastState = povStates_[iJoyStick][id]; 1060 if (lastState & OIS::Pov::North) 1061 buttonReleased(arg, 32 + id * 4 + 0); 1062 if (lastState & OIS::Pov::South) 1063 buttonReleased(arg, 32 + id * 4 + 1); 1064 if (lastState & OIS::Pov::East) 1065 buttonReleased(arg, 32 + id * 4 + 2); 1066 if (lastState & OIS::Pov::West) 1067 buttonReleased(arg, 32 + id * 4 + 3); 1068 1069 povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction; 1070 1071 int currentState = povStates_[iJoyStick][id]; 1072 if (currentState & OIS::Pov::North) 1073 buttonPressed(arg, 32 + id * 4 + 0); 1074 if (currentState & OIS::Pov::South) 1075 buttonPressed(arg, 32 + id * 4 + 1); 1076 if (currentState & OIS::Pov::East) 1077 buttonPressed(arg, 32 + id * 4 + 2); 1078 if (currentState & OIS::Pov::West) 1079 buttonPressed(arg, 32 + id * 4 + 3); 1080 1081 return true; 1082 } 1083 1084 1085 // ############################################################ 1086 // ##### Other Public Interface Methods ##### 1087 // ########## ########## 1088 // ############################################################ 1089 1090 /** 1091 @brief 1092 Adjusts the mouse window metrics. 1093 This method has to be called every time the size of the window changes. 1094 @param width 1095 The new width of the render window 1096 @param^height 1097 The new height of the render window 1098 */ 1099 void InputManager::setWindowExtents(const int width, const int height) 1100 { 1101 if (mouse_) 1102 { 1103 // Set mouse region (if window resizes, we should alter this to reflect as well) 1104 mouse_->getMouseState().width = width; 1105 mouse_->getMouseState().height = height; 1106 } 1107 } 1108 1109 1110 // ###### InputStates ###### 1111 1112 /** 1113 @brief 1114 Adds a new key handler. 1115 @param handler 1116 Pointer to the handler object. 1117 @param name 1118 Unique name of the handler. 1119 @param priority 1120 Unique integer number. Higher means more prioritised. 1121 @return 1122 True if added, false if name or priority already existed. 1123 */ 1124 bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority) 1125 { 1126 if (name == "") 1127 return false; 1128 if (!state) 1129 return false; 1130 if (inputStatesByName_.find(name) == inputStatesByName_.end()) 1131 { 1132 if (inputStatesByPriority_.find(priority) 1133 == inputStatesByPriority_.end()) 1134 { 1135 inputStatesByName_[name] = state; 1136 inputStatesByPriority_[priority] = state; 1137 state->setNumOfJoySticks(numberOfJoySticks()); 1138 state->setName(name); 1139 state->setPriority(priority); 1140 return true; 1141 } 1142 else 1143 { 1144 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1145 << priority << "'." << std::endl; 1146 return false; 1147 } 1148 } 1149 else 1150 { 1151 COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl; 1152 return false; 1153 } 1154 } 1155 1156 /** 1157 @brief 1158 Removes and destroys an input state internally. 1159 @param name 1160 Name of the handler. 1161 @return 1162 True if removal was successful, false if name was not found. 1163 @remarks 1164 You can't remove the internal states "empty", "calibrator" and "detector". 1165 The removal process is being postponed if InputManager::tick() is currently running. 1166 */ 1167 bool InputManager::requestDestroyState(const std::string& name) 1168 { 1169 if (name == "empty" || name == "calibrator" || name == "detector") 1170 { 1171 COUT(2) << "InputManager: Removing the '" << name << "' state is not allowed!" << std::endl; 1172 return false; 1173 } 1174 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name); 1175 if (it != inputStatesByName_.end()) 1176 { 1177 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 1178 { 1179 // The state is still active. We have to postpone 1180 stateLeaveRequests_.insert(it->second); 1181 stateDestroyRequests_.insert(it->second); 1182 } 1183 else if (this->internalState_ & Ticking) 1184 { 1185 // cannot remove state while ticking 1186 stateDestroyRequests_.insert(it->second); 1187 } 1188 else 1189 _destroyState(it->second); 1190 1191 return true; 1192 } 134 1193 return false; 135 } 136 137 if (createKeyboard) 138 _initialiseKeyboard(); 139 140 if (createMouse) 141 _initialiseMouse(); 142 143 if (createJoySticks) 144 _initialiseJoySticks(); 145 146 // Set mouse/joystick region 147 if (mouse_) 148 { 149 setWindowExtents(windowWidth, windowHeight); 150 } 151 152 state_ = IS_NONE; 153 CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl; 154 155 // InputManager holds the input buffer --> create one and add it. 156 buffer_ = new InputBuffer(); 157 addKeyHandler(buffer_, "buffer"); 158 Shell::getInstance().setInputBuffer(buffer_); 159 160 keyBinder_ = new KeyBinder(); 161 keyBinder_->loadBindings(); 162 addKeyHandler(keyBinder_, "keybinder"); 163 addMouseHandler(keyBinder_, "keybinder"); 164 addJoyStickHandler(keyBinder_, "keybinder"); 165 166 keyDetector_ = new KeyDetector(); 167 keyDetector_->loadBindings(); 168 addKeyHandler(keyDetector_, "keydetector"); 169 addMouseHandler(keyDetector_, "keydetector"); 170 addJoyStickHandler(keyDetector_, "keydetector"); 171 172 calibratorCallback_ = new CalibratorCallback(); 173 addKeyHandler(calibratorCallback_, "calibratorcallback"); 174 175 setConfigValues(); 176 177 CCOUT(ORX_DEBUG) << "Initialising complete." << std::endl; 178 } 179 else 180 { 181 CCOUT(ORX_WARNING) << "Warning: OIS compoments already initialised, skipping" << std::endl; 182 } 183 return true; 184 } 185 186 /** 187 @brief Creates a keyboard and sets the event handler. 188 @return False if keyboard stays uninitialised, true otherwise. 189 */ 190 bool InputManager::_initialiseKeyboard() 191 { 192 if (keyboard_ != 0) 193 { 194 CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl; 195 return true; 196 } 197 try 198 { 199 if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0) 200 { 201 keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true); 202 // register our listener in OIS. 203 keyboard_->setEventCallback(this); 204 // note: OIS will not detect keys that have already been down when the keyboard was created. 205 CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl; 206 return true; 207 } 208 else 209 { 210 CCOUT(ORX_WARNING) << "Warning: No keyboard found!" << std::endl; 1194 } 1195 1196 /** 1197 @brief 1198 Returns the pointer to the requested InputState. 1199 @param name 1200 Unique name of the state. 1201 @return 1202 Pointer to the instance, 0 if name was not found. 1203 */ 1204 InputState* InputManager::getState(const std::string& name) 1205 { 1206 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name); 1207 if (it != inputStatesByName_.end()) 1208 return it->second; 1209 else 1210 return 0; 1211 } 1212 1213 /** 1214 @brief 1215 Returns the current input state (there might be others active too!) 1216 @return 1217 The current highest prioritised active input state. 1218 */ 1219 InputState* InputManager::getCurrentState() 1220 { 1221 return (*activeStates_.rbegin()).second; 1222 } 1223 1224 /** 1225 @brief 1226 Activates a specific input state. 1227 It might not be really activated if the priority is too low! 1228 @param name 1229 Unique name of the state. 1230 @return 1231 False if name was not found, true otherwise. 1232 */ 1233 bool InputManager::requestEnterState(const std::string& name) 1234 { 1235 // get pointer from the map with all stored handlers 1236 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name); 1237 if (it != inputStatesByName_.end()) 1238 { 1239 // exists 1240 if (activeStates_.find(it->second->getPriority()) == activeStates_.end()) 1241 { 1242 // not active 1243 if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end()) 1244 { 1245 // not scheduled for destruction 1246 // set prevents a state being added multiple times 1247 stateEnterRequests_.insert(it->second); 1248 return true; 1249 } 1250 } 1251 } 211 1252 return false; 212 } 213 } 214 catch (OIS::Exception ex) 215 { 216 // TODO: Test this output regarding formatting 217 CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS keyboard\n" 218 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 219 keyboard_ = 0; 220 return false; 221 } 222 } 223 224 /** 225 @brief Creates a mouse and sets the event handler. 226 @return False if mouse stays uninitialised, true otherwise. 227 */ 228 bool InputManager::_initialiseMouse() 229 { 230 if (mouse_ != 0) 231 { 232 CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl; 233 return true; 234 } 235 try 236 { 237 if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0) 238 { 239 mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true)); 240 // register our listener in OIS. 241 mouse_->setEventCallback(this); 242 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl; 243 return true; 244 } 245 else 246 { 247 CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl; 1253 } 1254 1255 /** 1256 @brief 1257 Deactivates a specific input state. 1258 @param name 1259 Unique name of the state. 1260 @return 1261 False if name was not found, true otherwise. 1262 */ 1263 bool InputManager::requestLeaveState(const std::string& name) 1264 { 1265 // get pointer from the map with all stored handlers 1266 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name); 1267 if (it != inputStatesByName_.end()) 1268 { 1269 // exists 1270 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 1271 { 1272 // active 1273 stateLeaveRequests_.insert(it->second); 1274 return true; 1275 } 1276 } 248 1277 return false; 249 } 250 } 251 catch (OIS::Exception ex) 252 { 253 CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n" 254 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 255 mouse_ = 0; 256 return false; 257 } 258 } 259 260 /** 261 @brief Creates all joy sticks and sets the event handler. 262 @return False joy stick stay uninitialised, true otherwise. 263 */ 264 bool InputManager::_initialiseJoySticks() 265 { 266 if (joySticksSize_ > 0) 267 { 268 CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl; 269 return true; 270 } 271 bool success = false; 272 if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0) 273 { 274 for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++) 275 { 276 try 277 { 278 OIS::JoyStick* stig = static_cast<OIS::JoyStick*>(inputSystem_->createInputObject(OIS::OISJoyStick, true)); 279 joySticks_.push_back(stig); 280 // register our listener in OIS. 281 stig->setEventCallback(this); 282 CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl; 283 success = true; 284 } 285 catch (OIS::Exception ex) 286 { 287 CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n" 288 << "OIS error message: \"" << ex.eText << "\"" << std::endl; 289 } 290 } 291 } 292 else 293 { 294 CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl; 295 return false; 296 } 297 joySticksSize_ = joySticks_.size(); 298 activeJoyStickHandlers_.resize(joySticksSize_); 299 joyStickButtonsDown_.resize(joySticksSize_); 300 povStates_.resize(joySticksSize_); 301 sliderStates_.resize(joySticksSize_); 302 joySticksCalibration_.resize(joySticksSize_); 303 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 304 { 305 // reset the calibration with default values 306 for (unsigned int i = 0; i < 24; i++) 307 { 308 joySticksCalibration_[iJoyStick].negativeCoeff[i] = 1.0f/32767.0f; 309 joySticksCalibration_[iJoyStick].positiveCoeff[i] = 1.0f/32768.0f; 310 joySticksCalibration_[iJoyStick].zeroStates[i] = 0; 311 } 312 } 313 return success; 314 } 315 316 /** 317 @brief Sets the configurable values. Use keybindings.ini as file.. 318 */ 319 void InputManager::setConfigValues() 320 { 321 if (joySticksSize_) 322 { 323 std::vector<double> coeffPos; 324 std::vector<double> coeffNeg; 325 std::vector<int> zero; 326 coeffPos.resize(24); 327 coeffNeg.resize(24); 328 zero.resize(24); 329 for (unsigned int i = 0; i < 24; i++) 330 { 331 coeffPos[i] = 1.0f/32767.0f; 332 coeffNeg[i] = 1.0f/32768.0f; 333 zero[i] = 0; 334 } 335 336 ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos"); 337 if (!cont) 338 { 339 cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffPos", coeffPos); 340 getIdentifier()->addConfigValueContainer("CoeffPos", cont); 341 } 342 cont->getValue(&coeffPos, this); 343 344 cont = getIdentifier()->getConfigValueContainer("CoeffNeg"); 345 if (!cont) 346 { 347 cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffNeg", coeffNeg); 348 getIdentifier()->addConfigValueContainer("CoeffNeg", cont); 349 } 350 cont->getValue(&coeffNeg, this); 351 352 cont = getIdentifier()->getConfigValueContainer("Zero"); 353 if (!cont) 354 { 355 cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "Zero", zero); 356 getIdentifier()->addConfigValueContainer("Zero", cont); 357 } 358 cont->getValue(&zero, this); 359 360 // copy values to our own variables 361 for (unsigned int i = 0; i < 24; i++) 362 { 363 joySticksCalibration_[0].positiveCoeff[i] = coeffPos[i]; 364 joySticksCalibration_[0].negativeCoeff[i] = coeffNeg[i]; 365 joySticksCalibration_[0].zeroStates[i] = zero[i]; 366 } 367 } 368 } 369 370 /** 371 @brief Destroys all the created input devices and sets the InputManager to construction state. 372 */ 373 void InputManager::_destroy() 374 { 375 if (state_ != IS_UNINIT) 376 { 377 CCOUT(ORX_DEBUG) << "Destroying ..." << std::endl; 378 379 if (buffer_) 380 delete buffer_; 381 382 if (keyBinder_) 383 delete keyBinder_; 384 385 if (keyDetector_) 386 delete keyDetector_; 387 388 if (calibratorCallback_) 389 delete calibratorCallback_; 390 391 keyHandlers_.clear(); 392 mouseHandlers_.clear(); 393 joyStickHandlers_.clear(); 394 395 _destroyKeyboard(); 396 _destroyMouse(); 397 _destroyJoySticks(); 398 399 activeHandlers_.clear(); 400 401 // inputSystem_ can never be 0, or else the code is mistaken 402 OIS::InputManager::destroyInputSystem(inputSystem_); 403 inputSystem_ = 0; 404 405 state_ = IS_UNINIT; 406 CCOUT(ORX_DEBUG) << "Destroying done." << std::endl; 407 } 408 } 409 410 /** 411 @brief Destroys the keyboard and sets it to 0. 412 */ 413 void InputManager::_destroyKeyboard() 414 { 415 if (keyboard_) 416 // inputSystem_ can never be 0, or else the code is mistaken 417 inputSystem_->destroyInputObject(keyboard_); 418 keyboard_ = 0; 419 activeKeyHandlers_.clear(); 420 keysDown_.clear(); 421 CCOUT(ORX_DEBUG) << "Keyboard destroyed." << std::endl; 422 } 423 424 /** 425 @brief Destroys the mouse and sets it to 0. 426 */ 427 void InputManager::_destroyMouse() 428 { 429 if (mouse_) 430 // inputSystem_ can never be 0, or else the code is mistaken 431 inputSystem_->destroyInputObject(mouse_); 432 mouse_ = 0; 433 activeMouseHandlers_.clear(); 434 mouseButtonsDown_.clear(); 435 CCOUT(ORX_DEBUG) << "Mouse destroyed." << std::endl; 436 } 437 438 /** 439 @brief Destroys all the joy sticks and resizes the lists to 0. 440 */ 441 void InputManager::_destroyJoySticks() 442 { 443 if (joySticksSize_ > 0) 444 { 445 // note: inputSystem_ can never be 0, or else the code is mistaken 446 for (unsigned int i = 0; i < joySticksSize_; i++) 447 if (joySticks_[i] != 0) 448 inputSystem_->destroyInputObject(joySticks_[i]); 449 450 joySticks_.clear(); 451 joySticksSize_ = 0; 452 activeJoyStickHandlers_.clear(); 453 joyStickButtonsDown_.clear(); 454 povStates_.clear(); 455 sliderStates_.clear(); 456 joySticksCalibration_.clear(); 457 } 458 CCOUT(ORX_DEBUG) << "Joy sticks destroyed." << std::endl; 459 } 460 461 void InputManager::_saveState() 462 { 463 savedHandlers_.activeHandlers_ = activeHandlers_; 464 savedHandlers_.activeJoyStickHandlers_ = activeJoyStickHandlers_; 465 savedHandlers_.activeKeyHandlers_ = activeKeyHandlers_; 466 savedHandlers_.activeMouseHandlers_ = activeMouseHandlers_; 467 } 468 469 void InputManager::_restoreState() 470 { 471 activeHandlers_ = savedHandlers_.activeHandlers_; 472 activeJoyStickHandlers_ = savedHandlers_.activeJoyStickHandlers_; 473 activeKeyHandlers_ = savedHandlers_.activeKeyHandlers_; 474 activeMouseHandlers_ = savedHandlers_.activeMouseHandlers_; 475 } 476 477 void InputManager::_updateTickables() 478 { 479 // we can use a map to have a list of unique pointers (an object can implement all 3 handlers) 480 std::map<InputTickable*, HandlerState> tempSet; 481 for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++) 482 tempSet[activeKeyHandlers_[iHandler]].joyStick = true; 483 for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++) 484 tempSet[activeMouseHandlers_[iHandler]].mouse = true; 485 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 486 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 487 tempSet[activeJoyStickHandlers_[iJoyStick][iHandler]].joyStick = true; 488 489 // copy the content of the map back to the actual vector 490 activeHandlers_.clear(); 491 for (std::map<InputTickable*, HandlerState>::const_iterator itHandler = tempSet.begin(); 492 itHandler != tempSet.end(); itHandler++) 493 activeHandlers_.push_back(std::pair<InputTickable*, HandlerState>((*itHandler).first, (*itHandler).second)); 494 } 495 496 497 // ################################# 498 // ### Private Interface Methods ### 499 // ################################# 500 // ################################# 501 502 /** 503 @brief Updates the InputManager. Tick is called by Orxonox. 504 @param dt Delta time 505 */ 506 void InputManager::_tick(float dt) 507 { 508 if (state_ == IS_UNINIT) 509 return; 510 511 if (state_ != stateRequest_) 512 { 513 InputState sr = stateRequest_; 514 switch (sr) 515 { 516 case IS_NORMAL: 517 activeKeyHandlers_.clear(); 518 activeMouseHandlers_.clear(); 519 for (unsigned int i = 0; i < joySticksSize_; i++) 520 activeJoyStickHandlers_[i].clear(); 521 522 // normal play mode 523 // note: we assume that the handlers exist since otherwise, something's wrong anyway. 524 enableKeyHandler("keybinder"); 525 enableMouseHandler("keybinder"); 526 enableJoyStickHandler("keybinder", 0); 527 stateRequest_ = IS_NORMAL; 528 state_ = IS_NORMAL; 529 break; 530 531 case IS_GUI: 532 state_ = IS_GUI; 533 break; 534 535 case IS_CONSOLE: 536 activeKeyHandlers_.clear(); 537 activeMouseHandlers_.clear(); 538 for (unsigned int i = 0; i < joySticksSize_; i++) 539 activeJoyStickHandlers_[i].clear(); 540 541 enableMouseHandler("keybinder"); 542 enableJoyStickHandler("keybinder", 0); 543 enableKeyHandler("buffer"); 544 stateRequest_ = IS_CONSOLE; 545 state_ = IS_CONSOLE; 546 break; 547 548 case IS_DETECT: 549 savedState_ = state_; 550 _saveState(); 551 552 activeKeyHandlers_.clear(); 553 activeMouseHandlers_.clear(); 554 for (unsigned int i = 0; i < joySticksSize_; i++) 555 activeJoyStickHandlers_[i].clear(); 556 557 enableKeyHandler("keydetector"); 558 enableMouseHandler("keydetector"); 559 enableJoyStickHandler("keydetector", 0); 560 561 stateRequest_ = IS_DETECT; 562 state_ = IS_DETECT; 563 break; 564 565 case IS_NODETECT: 566 _restoreState(); 567 keysDown_.clear(); 568 mouseButtonsDown_.clear(); 569 for (unsigned int i = 0; i < joySticksSize_; i++) 570 joyStickButtonsDown_[i].clear(); 571 state_ = IS_NODETECT; 572 stateRequest_ = savedState_; 573 break; 574 575 case IS_CALIBRATE: 576 if (joySticksSize_) 577 { 578 savedState_ = _getSingleton().state_; 579 for (unsigned int i = 0; i < 24; i++) 580 { 581 marginalsMax_[i] = INT_MIN; 582 marginalsMin_[i] = INT_MAX; 583 } 584 COUT(0) << "Move all joy stick axes in all directions a few times. " 585 << "Then put all axes in zero state and hit enter." << std::endl; 586 587 savedState_ = state_; 588 _saveState(); 589 590 activeKeyHandlers_.clear(); 591 activeMouseHandlers_.clear(); 592 for (unsigned int i = 0; i < joySticksSize_; i++) 593 activeJoyStickHandlers_[i].clear(); 594 595 enableKeyHandler("calibratorcallback"); 596 stateRequest_ = IS_CALIBRATE; 597 state_ = IS_CALIBRATE; 598 } 599 else 600 { 601 COUT(3) << "Connot calibrate, no joy stick found!" << std::endl; 602 stateRequest_ = state_; 603 } 604 break; 605 606 case IS_NOCALIBRATE: 607 _completeCalibration(); 608 _restoreState(); 609 keyBinder_->resetJoyStickAxes(); 610 state_ = IS_NOCALIBRATE; 611 stateRequest_ = savedState_; 612 break; 613 614 case IS_NONE: 615 activeKeyHandlers_.clear(); 616 activeMouseHandlers_.clear(); 617 for (unsigned int i = 0; i < joySticksSize_; i++) 618 activeJoyStickHandlers_[i].clear(); 619 state_ = IS_NONE; 620 621 default: 622 break; 623 } 624 } 625 626 // Capture all the input. This calls the event handlers in InputManager. 627 if (mouse_) 628 mouse_->capture(); 629 if (keyboard_) 630 keyboard_->capture(); 631 for (unsigned int i = 0; i < joySticksSize_; i++) 632 joySticks_[i]->capture(); 633 634 if (state_ != IS_CALIBRATE) 635 { 636 // call all the handlers for the held key events 637 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 638 for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++) 639 activeKeyHandlers_[iHandler]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_)); 640 641 // call all the handlers for the held mouse button events 642 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 643 for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++) 644 activeMouseHandlers_[iHandler]->mouseButtonHeld(mouseButtonsDown_[iButton]); 645 646 // call all the handlers for the held joy stick button events 647 for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++) 648 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 649 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 650 activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 651 } 652 653 // call the ticks for the handlers (need to be treated specially) 654 for (unsigned int iHandler = 0; iHandler < activeHandlers_.size(); iHandler++) 655 activeHandlers_[iHandler].first->tickInput(dt, activeHandlers_[iHandler].second); 656 } 657 658 void InputManager::_completeCalibration() 659 { 660 for (unsigned int i = 0; i < 24; i++) 661 { 662 // positive coefficient 663 if (marginalsMax_[i] == INT_MIN) 664 marginalsMax_[i] = 32767; 665 // coefficients 666 if (marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]) 667 joySticksCalibration_[0].positiveCoeff[i] = 1.0f/(marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]); 668 else 669 joySticksCalibration_[0].positiveCoeff[i] = 1.0f; 670 671 // config value 672 ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos"); 673 assert(cont); 674 cont->set(i, joySticksCalibration_[0].positiveCoeff[i]); 675 676 // negative coefficient 677 if (marginalsMin_[i] == INT_MAX) 678 marginalsMin_[i] = -32768; 679 // coefficients 680 if (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]) 681 joySticksCalibration_[0].negativeCoeff[i] = -1.0f/(marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]); 682 else 683 joySticksCalibration_[0].negativeCoeff[i] = 1.0f; 684 // config value 685 cont = getIdentifier()->getConfigValueContainer("CoeffNeg"); 686 assert(cont); 687 cont->set(i, joySticksCalibration_[0].negativeCoeff[i]); 688 689 // zero states 690 if (i < 8) 691 { 692 if (!(i & 1)) 693 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abX; 694 else 695 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abY; 696 } 697 else 698 { 699 if (i - 8 < joySticks_[0]->getJoyStickState().mAxes.size()) 700 joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mAxes[i - 8].abs; 701 else 702 joySticksCalibration_[0].zeroStates[i] = 0; 703 } 704 // config value 705 cont = getIdentifier()->getConfigValueContainer("Zero"); 706 assert(cont); 707 cont->set(i, joySticksCalibration_[0].zeroStates[i]); 708 } 709 } 710 711 // ###### Key Events ###### 712 713 /** 714 @brief Event handler for the keyPressed Event. 715 @param e Event information 716 */ 717 bool InputManager::keyPressed(const OIS::KeyEvent &e) 718 { 719 // check whether the key already is in the list (can happen when focus was lost) 720 unsigned int iKey = 0; 721 while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::Enum)e.key) 722 iKey++; 723 if (iKey == keysDown_.size()) 724 keysDown_.push_back(Key(e)); 725 else 726 return true; 727 728 // update modifiers 729 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 730 keyboardModifiers_ |= KeyboardModifier::Alt; // alt key 731 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 732 keyboardModifiers_ |= KeyboardModifier::Ctrl; // ctrl key 733 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 734 keyboardModifiers_ |= KeyboardModifier::Shift; // shift key 735 736 for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++) 737 activeKeyHandlers_[i]->keyPressed(KeyEvent(e, keyboardModifiers_)); 738 739 return true; 740 } 741 742 /** 743 @brief Event handler for the keyReleased Event. 744 @param e Event information 745 */ 746 bool InputManager::keyReleased(const OIS::KeyEvent &e) 747 { 748 // remove the key from the keysDown_ list 749 for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++) 750 { 751 if (keysDown_[iKey].key == (KeyCode::Enum)e.key) 752 { 753 keysDown_.erase(keysDown_.begin() + iKey); 754 break; 755 } 756 } 757 758 // update modifiers 759 if(e.key == OIS::KC_RMENU || e.key == OIS::KC_LMENU) 760 keyboardModifiers_ &= ~KeyboardModifier::Alt; // alt key 761 if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL) 762 keyboardModifiers_ &= ~KeyboardModifier::Ctrl; // ctrl key 763 if(e.key == OIS::KC_RSHIFT || e.key == OIS::KC_LSHIFT) 764 keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key 765 766 for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++) 767 activeKeyHandlers_[i]->keyReleased(KeyEvent(e, keyboardModifiers_)); 768 769 return true; 770 } 771 772 773 // ###### Mouse Events ###### 774 775 /** 776 @brief Event handler for the mouseMoved Event. 777 @param e Event information 778 */ 779 bool InputManager::mouseMoved(const OIS::MouseEvent &e) 780 { 781 // check for actual moved event 782 if (e.state.X.rel != 0 || e.state.Y.rel != 0) 783 { 784 for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++) 785 activeMouseHandlers_[i]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs), 786 IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height)); 787 } 788 789 // check for mouse scrolled event 790 if (e.state.Z.rel != 0) 791 { 792 for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++) 793 activeMouseHandlers_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 794 } 795 796 return true; 797 } 798 799 /** 800 @brief Event handler for the mousePressed Event. 801 @param e Event information 802 @param id The ID of the mouse button 803 */ 804 bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) 805 { 806 // check whether the button already is in the list (can happen when focus was lost) 807 unsigned int iButton = 0; 808 while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButton::Enum)id) 809 iButton++; 810 if (iButton == mouseButtonsDown_.size()) 811 mouseButtonsDown_.push_back((MouseButton::Enum)id); 812 813 for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++) 814 activeMouseHandlers_[i]->mouseButtonPressed((MouseButton::Enum)id); 815 816 return true; 817 } 818 819 /** 820 @brief Event handler for the mouseReleased Event. 821 @param e Event information 822 @param id The ID of the mouse button 823 */ 824 bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) 825 { 826 // remove the button from the keysDown_ list 827 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 828 { 829 if (mouseButtonsDown_[iButton] == (MouseButton::Enum)id) 830 { 831 mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton); 832 break; 833 } 834 } 835 836 for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++) 837 activeMouseHandlers_[i]->mouseButtonReleased((MouseButton::Enum)id); 838 839 return true; 840 } 841 842 843 // ###### Joy Stick Events ###### 844 845 inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg) 846 { 847 // use the device to identify which one called the method 848 OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device; 849 unsigned int iJoyStick = 0; 850 while (joySticks_[iJoyStick] != joyStick) 851 { 852 iJoyStick++; 853 if (iJoyStick == joySticksSize_) 854 { 855 CCOUT(3) << "Unknown joystick fired an event. This means there is a bug somewhere! Aborting." << std::endl; 856 abort(); 857 } 858 } 859 return iJoyStick; 860 } 861 862 bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button) 863 { 864 unsigned int iJoyStick = _getJoystick(arg); 865 866 // check whether the button already is in the list (can happen when focus was lost) 867 std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 868 unsigned int iButton = 0; 869 while (iButton < buttonsDown.size() && buttonsDown[iButton] != button) 870 iButton++; 871 if (iButton == buttonsDown.size()) 872 buttonsDown.push_back(button); 873 874 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 875 activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonPressed(iJoyStick, button); 876 877 return true; 878 } 879 880 bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button) 881 { 882 unsigned int iJoyStick = _getJoystick(arg); 883 884 // remove the button from the joyStickButtonsDown_ list 885 std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick]; 886 for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++) 887 { 888 if (buttonsDown[iButton] == button) 889 { 890 buttonsDown.erase(buttonsDown.begin() + iButton); 891 break; 892 } 893 } 894 895 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 896 activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonReleased(iJoyStick, button); 897 898 return true; 899 } 900 901 void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value) 902 { 903 if (state_ == IS_CALIBRATE) 904 { 905 if (value > marginalsMax_[axis]) 906 marginalsMax_[axis] = value; 907 if (value < marginalsMin_[axis]) 908 marginalsMin_[axis] = value; 909 } 910 else 911 { 912 float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis]; 913 if (fValue > 0.0f) 914 fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis]; 915 else 916 fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis]; 917 918 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 919 activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis, fValue); 920 } 921 } 922 923 bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis) 924 { 925 //if (arg.state.mAxes[axis].abs > 10000 || arg.state.mAxes[axis].abs < -10000) 926 //{ CCOUT(3) << "axis " << axis << " moved" << arg.state.mAxes[axis].abs << std::endl;} 927 928 unsigned int iJoyStick = _getJoystick(arg); 929 930 // keep in mind that the first 8 axes are reserved for the sliders 931 _fireAxis(iJoyStick, axis + 8, arg.state.mAxes[axis].abs); 932 933 return true; 934 } 935 936 bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id) 937 { 938 //if (arg.state.mSliders[id].abX > 10000 || arg.state.mSliders[id].abX < -10000) 939 //{CCOUT(3) << "slider " << id << " moved" << arg.state.mSliders[id].abX << std::endl;} 940 //CCOUT(3) << arg.state.mSliders[id].abX << "\t |" << arg.state.mSliders[id].abY << std::endl; 941 942 unsigned int iJoyStick = _getJoystick(arg); 943 944 if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX) 945 _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX); 946 else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY) 947 _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY); 948 949 return true; 950 } 951 952 bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id) 953 { 954 unsigned int iJoyStick = _getJoystick(arg); 955 956 // translate the POV into 8 simple buttons 957 int lastState = povStates_[iJoyStick][id]; 958 if (lastState & OIS::Pov::North) 959 buttonReleased(arg, 32 + id * 4 + 0); 960 if (lastState & OIS::Pov::South) 961 buttonReleased(arg, 32 + id * 4 + 1); 962 if (lastState & OIS::Pov::East) 963 buttonReleased(arg, 32 + id * 4 + 2); 964 if (lastState & OIS::Pov::West) 965 buttonReleased(arg, 32 + id * 4 + 3); 966 967 povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction; 968 969 int currentState = povStates_[iJoyStick][id]; 970 if (currentState & OIS::Pov::North) 971 buttonPressed(arg, 32 + id * 4 + 0); 972 if (currentState & OIS::Pov::South) 973 buttonPressed(arg, 32 + id * 4 + 1); 974 if (currentState & OIS::Pov::East) 975 buttonPressed(arg, 32 + id * 4 + 2); 976 if (currentState & OIS::Pov::West) 977 buttonPressed(arg, 32 + id * 4 + 3); 978 979 return true; 980 } 981 982 /*bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id) 983 { 984 unsigned int iJoyStick = _getJoystick(arg); 985 986 for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++) 987 activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickVector3Moved(JoyStickState(arg.state, iJoyStick), id); 988 989 return true; 990 }*/ 991 992 993 // ################################ 994 // ### Static Interface Methods ### 995 // ################################ 996 // ################################ 997 998 std::string InputManager::bindingCommmandString_s = ""; 999 1000 bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight, 1001 bool createKeyboard, bool createMouse, bool createJoySticks) 1002 { 1003 return _getSingleton()._initialise(windowHnd, windowWidth, windowHeight, 1004 createKeyboard, createMouse, createJoySticks); 1005 } 1006 1007 bool InputManager::initialiseKeyboard() 1008 { 1009 return _getSingleton()._initialiseKeyboard(); 1010 } 1011 1012 bool InputManager::initialiseMouse() 1013 { 1014 return _getSingleton()._initialiseMouse(); 1015 } 1016 1017 bool InputManager::initialiseJoySticks() 1018 { 1019 return _getSingleton()._initialiseJoySticks(); 1020 } 1021 1022 int InputManager::numberOfKeyboards() 1023 { 1024 if (_getSingleton().keyboard_ != 0) 1025 return 1; 1026 else 1027 return 0; 1028 } 1029 1030 int InputManager::numberOfMice() 1031 { 1032 if (_getSingleton().mouse_ != 0) 1033 return 1; 1034 else 1035 return 0; 1036 } 1037 1038 int InputManager::numberOfJoySticks() 1039 { 1040 return _getSingleton().joySticksSize_; 1041 } 1042 1043 /*bool InputManager::isKeyDown(KeyCode::Enum key) 1044 { 1045 if (_getSingleton().keyboard_) 1046 return _getSingleton().keyboard_->isKeyDown((OIS::KeyCode)key); 1047 else 1048 return false; 1049 }*/ 1050 1051 /*bool InputManager::isModifierDown(KeyboardModifier::Enum modifier) 1052 { 1053 if (_getSingleton().keyboard_) 1054 return isModifierDown(modifier); 1055 else 1056 return false; 1057 }*/ 1058 1059 /*const MouseState InputManager::getMouseState() 1060 { 1061 if (_getSingleton().mouse_) 1062 return _getSingleton().mouse_->getMouseState(); 1063 else 1064 return MouseState(); 1065 }*/ 1066 1067 /*const JoyStickState InputManager::getJoyStickState(unsigned int ID) 1068 { 1069 if (ID < _getSingleton().joySticksSize_) 1070 return JoyStickState(_getSingleton().joySticks_[ID]->getJoyStickState(), ID); 1071 else 1072 return JoyStickState(); 1073 }*/ 1074 1075 void InputManager::destroy() 1076 { 1077 _getSingleton()._destroy(); 1078 } 1079 1080 void InputManager::destroyKeyboard() 1081 { 1082 return _getSingleton()._destroyKeyboard(); 1083 } 1084 1085 void InputManager::destroyMouse() 1086 { 1087 return _getSingleton()._destroyMouse(); 1088 } 1089 1090 void InputManager::destroyJoySticks() 1091 { 1092 return _getSingleton()._destroyJoySticks(); 1093 } 1094 1095 1096 /** 1097 @brief Adjusts the mouse window metrics. 1098 This method has to be called every time the size of the window changes. 1099 @param width The new width of the render window 1100 @param height the new height of the render window 1101 */ 1102 void InputManager::setWindowExtents(const int width, const int height) 1103 { 1104 if (_getSingleton().mouse_) 1105 { 1106 // Set mouse region (if window resizes, we should alter this to reflect as well) 1107 const OIS::MouseState &mouseState = _getSingleton().mouse_->getMouseState(); 1108 mouseState.width = width; 1109 mouseState.height = height; 1110 } 1111 } 1112 1113 /** 1114 @brief Sets the input mode to either GUI, inGame or Buffer 1115 @param mode The new input mode 1116 @remark Only has an affect if the mode actually changes 1117 */ 1118 void InputManager::setInputState(const InputState state) 1119 { 1120 _getSingleton().stateRequest_ = state; 1121 } 1122 1123 /** 1124 @brief Returns the current input handling method 1125 @return The current input mode. 1126 */ 1127 InputManager::InputState InputManager::getInputState() 1128 { 1129 return _getSingleton().state_; 1130 } 1131 1132 void InputManager::storeKeyStroke(const std::string& name) 1133 { 1134 setInputState(IS_NODETECT); 1135 COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl; 1136 CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false); 1137 } 1138 1139 void InputManager::keyBind(const std::string& command) 1140 { 1141 bindingCommmandString_s = command; 1142 setInputState(IS_DETECT); 1143 COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl; 1144 } 1145 1146 void InputManager::calibrate() 1147 { 1148 _getSingleton().setInputState(IS_CALIBRATE); 1149 } 1150 1151 void InputManager::tick(float dt) 1152 { 1153 _getSingleton()._tick(dt); 1154 } 1155 1156 // ###### KeyHandler ###### 1157 1158 /** 1159 @brief Adds a new key handler. 1160 @param handler Pointer to the handler object. 1161 @param name Unique name of the handler. 1162 @return True if added, false if name already existed. 1163 */ 1164 bool InputManager::addKeyHandler(KeyHandler* handler, const std::string& name) 1165 { 1166 if (!handler) 1167 return false; 1168 if (_getSingleton().keyHandlers_.find(name) == _getSingleton().keyHandlers_.end()) 1169 { 1170 _getSingleton().keyHandlers_[name] = handler; 1171 return true; 1172 } 1173 else 1174 return false; 1175 } 1176 1177 /** 1178 @brief Removes a Key handler from the list. 1179 @param name Unique name of the handler. 1180 @return True if removal was successful, false if name was not found. 1181 */ 1182 bool InputManager::removeKeyHandler(const std::string &name) 1183 { 1184 disableKeyHandler(name); 1185 std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name); 1186 if (it != _getSingleton().keyHandlers_.end()) 1187 { 1188 _getSingleton().keyHandlers_.erase(it); 1189 return true; 1190 } 1191 else 1192 return false; 1193 } 1194 1195 /** 1196 @brief Returns the pointer to a handler. 1197 @param name Unique name of the handler. 1198 @return Pointer to the instance, 0 if name was not found. 1199 */ 1200 KeyHandler* InputManager::getKeyHandler(const std::string& name) 1201 { 1202 std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name); 1203 if (it != _getSingleton().keyHandlers_.end()) 1204 { 1205 return (*it).second; 1206 } 1207 else 1208 return 0; 1209 } 1210 1211 /** 1212 @brief Enables a specific key handler that has already been added. 1213 @param name Unique name of the handler. 1214 @return False if name was not found, true otherwise. 1215 */ 1216 bool InputManager::enableKeyHandler(const std::string& name) 1217 { 1218 // get pointer from the map with all stored handlers 1219 std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name); 1220 if (mapIt == _getSingleton().keyHandlers_.end()) 1221 return false; 1222 // see whether the handler already is in the list 1223 for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin(); 1224 it != _getSingleton().activeKeyHandlers_.end(); it++) 1225 { 1226 if ((*it) == (*mapIt).second) 1227 { 1228 return true; 1229 } 1230 } 1231 _getSingleton().activeKeyHandlers_.push_back((*mapIt).second); 1232 _getSingleton().stateRequest_ = IS_CUSTOM; 1233 _getSingleton()._updateTickables(); 1234 return true; 1235 } 1236 1237 /** 1238 @brief Disables a specific key handler. 1239 @param name Unique name of the handler. 1240 @return False if name was not found, true otherwise. 1241 */ 1242 bool InputManager::disableKeyHandler(const std::string &name) 1243 { 1244 // get pointer from the map with all stored handlers 1245 std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name); 1246 if (mapIt == _getSingleton().keyHandlers_.end()) 1247 return false; 1248 // look for the handler in the list 1249 for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin(); 1250 it != _getSingleton().activeKeyHandlers_.end(); it++) 1251 { 1252 if ((*it) == (*mapIt).second) 1253 { 1254 _getSingleton().activeKeyHandlers_.erase(it); 1255 _getSingleton().stateRequest_ = IS_CUSTOM; 1256 _getSingleton()._updateTickables(); 1257 return true; 1258 } 1259 } 1260 return true; 1261 } 1262 1263 /** 1264 @brief Checks whether a key handler is active 1265 @param name Unique name of the handler. 1266 @return False if key handler is not active or doesn't exist, true otherwise. 1267 */ 1268 bool InputManager::isKeyHandlerActive(const std::string& name) 1269 { 1270 // get pointer from the map with all stored handlers 1271 std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name); 1272 if (mapIt == _getSingleton().keyHandlers_.end()) 1273 return false; 1274 // see whether the handler already is in the list 1275 for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin(); 1276 it != _getSingleton().activeKeyHandlers_.end(); it++) 1277 { 1278 if ((*it) == (*mapIt).second) 1279 return true; 1280 } 1281 return false; 1282 } 1283 1284 1285 // ###### MouseHandler ###### 1286 /** 1287 @brief Adds a new mouse handler. 1288 @param handler Pointer to the handler object. 1289 @param name Unique name of the handler. 1290 @return True if added, false if name already existed. 1291 */ 1292 bool InputManager::addMouseHandler(MouseHandler* handler, const std::string& name) 1293 { 1294 if (!handler) 1295 return false; 1296 if (_getSingleton().mouseHandlers_.find(name) == _getSingleton().mouseHandlers_.end()) 1297 { 1298 _getSingleton().mouseHandlers_[name] = handler; 1299 return true; 1300 } 1301 else 1302 return false; 1303 } 1304 1305 /** 1306 @brief Removes a Mouse handler from the list. 1307 @param name Unique name of the handler. 1308 @return True if removal was successful, false if name was not found. 1309 */ 1310 bool InputManager::removeMouseHandler(const std::string &name) 1311 { 1312 disableMouseHandler(name); 1313 std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name); 1314 if (it != _getSingleton().mouseHandlers_.end()) 1315 { 1316 _getSingleton().mouseHandlers_.erase(it); 1317 return true; 1318 } 1319 else 1320 return false; 1321 } 1322 1323 /** 1324 @brief Returns the pointer to a handler. 1325 @param name Unique name of the handler. 1326 @return Pointer to the instance, 0 if name was not found. 1327 */ 1328 MouseHandler* InputManager::getMouseHandler(const std::string& name) 1329 { 1330 std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name); 1331 if (it != _getSingleton().mouseHandlers_.end()) 1332 { 1333 return (*it).second; 1334 } 1335 else 1336 return 0; 1337 } 1338 1339 /** 1340 @brief Enables a specific mouse handler that has already been added. 1341 @param name Unique name of the handler. 1342 @return False if name was not found, true otherwise. 1343 */ 1344 bool InputManager::enableMouseHandler(const std::string& name) 1345 { 1346 // get pointer from the map with all stored handlers 1347 std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name); 1348 if (mapIt == _getSingleton().mouseHandlers_.end()) 1349 return false; 1350 // see whether the handler already is in the list 1351 for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin(); 1352 it != _getSingleton().activeMouseHandlers_.end(); it++) 1353 { 1354 if ((*it) == (*mapIt).second) 1355 { 1356 return true; 1357 } 1358 } 1359 _getSingleton().activeMouseHandlers_.push_back((*mapIt).second); 1360 _getSingleton().stateRequest_ = IS_CUSTOM; 1361 _getSingleton()._updateTickables(); 1362 return true; 1363 } 1364 1365 /** 1366 @brief Disables a specific mouse handler. 1367 @param name Unique name of the handler. 1368 @return False if name was not found, true otherwise. 1369 */ 1370 bool InputManager::disableMouseHandler(const std::string &name) 1371 { 1372 // get pointer from the map with all stored handlers 1373 std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name); 1374 if (mapIt == _getSingleton().mouseHandlers_.end()) 1375 return false; 1376 // look for the handler in the list 1377 for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin(); 1378 it != _getSingleton().activeMouseHandlers_.end(); it++) 1379 { 1380 if ((*it) == (*mapIt).second) 1381 { 1382 _getSingleton().activeMouseHandlers_.erase(it); 1383 _getSingleton().stateRequest_ = IS_CUSTOM; 1384 _getSingleton()._updateTickables(); 1385 return true; 1386 } 1387 } 1388 return true; 1389 } 1390 1391 /** 1392 @brief Checks whether a mouse handler is active 1393 @param name Unique name of the handler. 1394 @return False if key handler is not active or doesn't exist, true otherwise. 1395 */ 1396 bool InputManager::isMouseHandlerActive(const std::string& name) 1397 { 1398 // get pointer from the map with all stored handlers 1399 std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name); 1400 if (mapIt == _getSingleton().mouseHandlers_.end()) 1401 return false; 1402 // see whether the handler already is in the list 1403 for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin(); 1404 it != _getSingleton().activeMouseHandlers_.end(); it++) 1405 { 1406 if ((*it) == (*mapIt).second) 1407 return true; 1408 } 1409 return false; 1410 } 1411 1412 1413 // ###### JoyStickHandler ###### 1414 1415 /** 1416 @brief Adds a new joy stick handler. 1417 @param handler Pointer to the handler object. 1418 @param name Unique name of the handler. 1419 @return True if added, false if name already existed. 1420 */ 1421 bool InputManager::addJoyStickHandler(JoyStickHandler* handler, const std::string& name) 1422 { 1423 if (!handler) 1424 return false; 1425 if (_getSingleton().joyStickHandlers_.find(name) == _getSingleton().joyStickHandlers_.end()) 1426 { 1427 _getSingleton().joyStickHandlers_[name] = handler; 1428 return true; 1429 } 1430 else 1431 return false; 1432 } 1433 1434 /** 1435 @brief Removes a JoyStick handler from the list. 1436 @param name Unique name of the handler. 1437 @return True if removal was successful, false if name was not found. 1438 */ 1439 bool InputManager::removeJoyStickHandler(const std::string &name) 1440 { 1441 for (std::vector<OIS::JoyStick*>::iterator itstick = _getSingleton().joySticks_.begin(); 1442 itstick != _getSingleton().joySticks_.end(); itstick++) 1443 disableJoyStickHandler(name, itstick - _getSingleton().joySticks_.begin()); 1444 1445 std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name); 1446 if (it != _getSingleton().joyStickHandlers_.end()) 1447 { 1448 _getSingleton().joyStickHandlers_.erase(it); 1449 return true; 1450 } 1451 else 1452 return false; 1453 } 1454 1455 /** 1456 @brief Returns the pointer to a handler. 1457 @param name Unique name of the handler. 1458 @return Pointer to the instance, 0 if name was not found. 1459 */ 1460 JoyStickHandler* InputManager::getJoyStickHandler(const std::string& name) 1461 { 1462 std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name); 1463 if (it != _getSingleton().joyStickHandlers_.end()) 1464 { 1465 return (*it).second; 1466 } 1467 else 1468 return 0; 1469 } 1470 1471 /** 1472 @brief Enables a specific joy stick handler that has already been added. 1473 @param name Unique name of the handler. 1474 @return False if name or id was not found, true otherwise. 1475 */ 1476 bool InputManager::enableJoyStickHandler(const std::string& name, unsigned int ID) 1477 { 1478 // get handler pointer from the map with all stored handlers 1479 std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name); 1480 if (handlerIt == _getSingleton().joyStickHandlers_.end()) 1481 return false; 1482 1483 // check for existence of the ID 1484 if (ID >= _getSingleton().joySticksSize_) 1485 return false; 1486 1487 // see whether the handler already is in the list 1488 for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin(); 1489 it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++) 1490 { 1491 if ((*it) == (*handlerIt).second) 1492 { 1493 return true; 1494 } 1495 } 1496 _getSingleton().activeJoyStickHandlers_[ID].push_back((*handlerIt).second); 1497 _getSingleton().stateRequest_ = IS_CUSTOM; 1498 _getSingleton()._updateTickables(); 1499 return true; 1500 } 1501 1502 /** 1503 @brief Disables a specific joy stick handler. 1504 @param name Unique name of the handler. 1505 @return False if name or id was not found, true otherwise. 1506 */ 1507 bool InputManager::disableJoyStickHandler(const std::string &name, unsigned int ID) 1508 { 1509 // get handler pointer from the map with all stored handlers 1510 std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name); 1511 if (handlerIt == _getSingleton().joyStickHandlers_.end()) 1512 return false; 1513 1514 // check for existence of the ID 1515 if (ID >= _getSingleton().joySticksSize_) 1516 return false; 1517 1518 // look for the handler in the list 1519 for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin(); 1520 it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++) 1521 { 1522 if ((*it) == (*handlerIt).second) 1523 { 1524 _getSingleton().activeJoyStickHandlers_[ID].erase(it); 1525 _getSingleton().stateRequest_ = IS_CUSTOM; 1526 _getSingleton()._updateTickables(); 1527 return true; 1528 } 1529 } 1530 return true; 1531 } 1532 1533 /** 1534 @brief Checks whether a joy stick handler is active 1535 @param name Unique name of the handler. 1536 @return False if key handler is not active or doesn't exist, true otherwise. 1537 */ 1538 bool InputManager::isJoyStickHandlerActive(const std::string& name, unsigned int ID) 1539 { 1540 // get handler pointer from the map with all stored handlers 1541 std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name); 1542 if (handlerIt == _getSingleton().joyStickHandlers_.end()) 1543 return false; 1544 1545 // check for existence of the ID 1546 if (ID >= _getSingleton().joySticksSize_) 1547 return false; 1548 1549 // see whether the handler already is in the list 1550 for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin(); 1551 it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++) 1552 { 1553 if ((*it) == (*handlerIt).second) 1554 return true; 1555 } 1556 return false; 1557 } 1558 1278 } 1279 1280 1281 // ############################################################ 1282 // ##### Console Commands ##### 1283 // ########## ########## 1284 // ############################################################ 1285 1286 /** 1287 @brief 1288 Method for easily storing a string with the command executor. It is used by the 1289 KeyDetector to get assign commands. The KeyDetector simply executes 1290 the command 'storeKeyStroke myName' for each button/axis. 1291 @remarks 1292 This is only a temporary hack until we thourouhgly support multiple KeyBinders. 1293 @param name 1294 The name of the button/axis. 1295 */ 1296 void InputManager::storeKeyStroke(const std::string& name) 1297 { 1298 getInstance().requestLeaveState("detector"); 1299 COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl; 1300 CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false); 1301 } 1302 1303 /** 1304 @brief 1305 Assigns a command string to a key/button/axis. The name is determined via KeyDetector 1306 and InputManager::storeKeyStroke(.). 1307 @param command 1308 Command string that can be executed by the CommandExecutor 1309 */ 1310 void InputManager::keyBind(const std::string& command) 1311 { 1312 bindingCommmandString_s = command; 1313 getInstance().requestEnterState("detector"); 1314 COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl; 1315 } 1316 1317 /** 1318 @brief 1319 Starts joy stick calibration. 1320 */ 1321 void InputManager::calibrate() 1322 { 1323 getInstance().bCalibrating_ = true; 1324 getInstance().requestEnterState("calibrator"); 1325 } 1326 1327 /** 1328 @brief 1329 Reloads the input system 1330 */ 1331 void InputManager::reload(bool joyStickSupport) 1332 { 1333 getInstance().reloadInputSystem(joyStickSupport); 1334 } 1559 1335 } -
code/trunk/src/core/input/InputManager.h
r1555 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of a little Input handler that distributes everything 32 coming from OIS. 33 */ 30 @file 31 @brief 32 Implementation of a little Input handler that distributes everything 33 coming from OIS. 34 */ 34 35 35 36 #ifndef _InputManager_H__ … … 40 41 #include <map> 41 42 #include <vector> 42 43 #include <stack> 43 44 #include "util/Math.h" 44 45 #include "core/OrxonoxClass.h" … … 47 48 namespace orxonox 48 49 { 49 /** 50 * Helper class to realise a vector<int[4]> 51 */ 52 class POVStates 53 { 54 public: 55 int operator[](unsigned int index) { return povStates[index]; } 56 int povStates[4]; 57 }; 58 59 /** 60 * Helper class to realise a vector< {int[4], int[4]} > 61 */ 62 class SliderStates 63 { 64 public: 65 IntVector2 sliderStates[4]; 66 }; 67 68 /** 69 * Struct for storing a custom input state 70 */ 71 struct StoredState 72 { 73 std::vector<KeyHandler*> activeKeyHandlers_; 74 std::vector<MouseHandler*> activeMouseHandlers_; 75 std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_; 76 std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_; 77 }; 78 79 struct JoyStickCalibration 80 { 81 int zeroStates[24]; 82 float positiveCoeff[24]; 83 float negativeCoeff[24]; 84 }; 85 86 /** 87 @brief Captures and distributes mouse and keyboard input. 88 */ 89 class _CoreExport InputManager 50 /** 51 @brief 52 Helper class to realise a vector<int[4]> 53 */ 54 class POVStates 55 { 56 public: 57 int& operator[](unsigned int index) { return povStates[index]; } 58 int povStates[4]; 59 }; 60 61 /** 62 @brief 63 Helper class to realise a vector< {int[4], int[4]} > 64 */ 65 class SliderStates 66 { 67 public: 68 IntVector2 sliderStates[4]; 69 }; 70 71 struct JoyStickCalibration 72 { 73 int zeroStates[24]; 74 float positiveCoeff[24]; 75 float negativeCoeff[24]; 76 }; 77 78 /** 79 @brief 80 Captures and distributes mouse and keyboard input. 81 */ 82 class _CoreExport InputManager 90 83 : public OrxonoxClass, 91 public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener 92 { 93 public: // enumerations 94 /** 95 @brief Designates the way input is handled and redirected. 96 */ 97 enum InputState 98 { 99 IS_UNINIT, //!< InputManager has not yet been initialised. 100 IS_NONE, //!< Input is discarded. 101 IS_NORMAL, //!< Normal play state. Key and button bindings are active. 102 IS_GUI, //!< All OIS input events are passed to CEGUI. 103 IS_CONSOLE, //!< Keyboard input is redirected to the InputBuffer. 104 IS_DETECT, //!< All the input additionally goes to the KeyDetector 105 IS_NODETECT, //!< remove KeyDetector 106 IS_NOCALIBRATE, 107 IS_CALIBRATE, 108 IS_CUSTOM //!< Any possible configuration. 109 }; 110 111 public: // member functions 112 void setConfigValues(); 113 114 public: // static functions 115 static bool initialise(const size_t windowHnd, int windowWidth, int windowHeight, 116 bool createKeyboard = true, bool createMouse = true, bool createJoySticks = false); 117 static bool initialiseKeyboard(); 118 static bool initialiseMouse(); 119 static bool initialiseJoySticks(); 120 static int numberOfKeyboards(); 121 static int numberOfMice(); 122 static int numberOfJoySticks(); 123 124 static void destroy(); 125 static void destroyKeyboard(); 126 static void destroyMouse(); 127 static void destroyJoySticks(); 128 129 //static bool isModifierDown(KeyboardModifier::Enum modifier); 130 //static bool isKeyDown(KeyCode::Enum key); 131 //static const MouseState getMouseState(); 132 //static const JoyStickState getJoyStickState(unsigned int ID); 133 134 static void setWindowExtents(const int width, const int height); 135 136 static void setInputState(const InputState state); 137 static InputState getInputState(); 138 139 static void storeKeyStroke(const std::string& name); 140 static void keyBind(const std::string& command); 141 142 static void calibrate(); 143 144 static void tick(float dt); 145 146 static bool addKeyHandler (KeyHandler* handler, const std::string& name); 147 static bool removeKeyHandler (const std::string& name); 148 static KeyHandler* getKeyHandler (const std::string& name); 149 static bool enableKeyHandler (const std::string& name); 150 static bool disableKeyHandler (const std::string& name); 151 static bool isKeyHandlerActive (const std::string& name); 152 153 static bool addMouseHandler (MouseHandler* handler, const std::string& name); 154 static bool removeMouseHandler (const std::string& name); 155 static MouseHandler* getMouseHandler (const std::string& name); 156 static bool enableMouseHandler (const std::string& name); 157 static bool disableMouseHandler (const std::string& name); 158 static bool isMouseHandlerActive (const std::string& name); 159 160 static bool addJoyStickHandler (JoyStickHandler* handler, const std::string& name); 161 static bool removeJoyStickHandler (const std::string& name); 162 static JoyStickHandler* getJoyStickHandler(const std::string& name); 163 static bool enableJoyStickHandler (const std::string& name, unsigned int id); 164 static bool disableJoyStickHandler (const std::string& name, unsigned int id); 165 static bool isJoyStickHandlerActive (const std::string& name, unsigned int id); 166 167 private: // functions 168 // don't mess with a Singleton 169 InputManager (); 170 InputManager (const InputManager&); 171 ~InputManager(); 172 173 // Intenal methods 174 bool _initialise(const size_t, int, int, bool, bool, bool); 175 bool _initialiseKeyboard(); 176 bool _initialiseMouse(); 177 bool _initialiseJoySticks(); 178 179 void _destroy(); 180 void _destroyKeyboard(); 181 void _destroyMouse(); 182 void _destroyJoySticks(); 183 184 void _updateTickables(); 185 186 void _saveState(); 187 void _restoreState(); 188 189 void _completeCalibration(); 190 191 void _fireAxis(unsigned int iJoyStick, int axis, int value); 192 unsigned int _getJoystick(const OIS::JoyStickEvent& arg); 193 194 void _tick(float dt); 195 196 // input events 197 bool mousePressed (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 198 bool mouseReleased (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 199 bool mouseMoved (const OIS::MouseEvent &arg); 200 bool keyPressed (const OIS::KeyEvent &arg); 201 bool keyReleased (const OIS::KeyEvent &arg); 202 bool buttonPressed (const OIS::JoyStickEvent &arg, int button); 203 bool buttonReleased(const OIS::JoyStickEvent &arg, int button); 204 bool axisMoved (const OIS::JoyStickEvent &arg, int axis); 205 bool sliderMoved (const OIS::JoyStickEvent &arg, int id); 206 bool povMoved (const OIS::JoyStickEvent &arg, int id); 207 //bool vector3Moved (const OIS::JoyStickEvent &arg, int id); 208 209 static InputManager& _getSingleton(); 210 static InputManager* _getSingletonPtr() { return &_getSingleton(); } 211 212 private: // variables 213 OIS::InputManager* inputSystem_; //!< OIS input manager 214 OIS::Keyboard* keyboard_; //!< OIS mouse 215 OIS::Mouse* mouse_; //!< OIS keyboard 216 std::vector<OIS::JoyStick*> joySticks_; //!< OIS joy sticks 217 unsigned int joySticksSize_; 218 219 KeyBinder* keyBinder_; //!< KeyBinder instance 220 KeyDetector* keyDetector_; //!< KeyDetector instance 221 InputBuffer* buffer_; //!< InputBuffer instance 222 CalibratorCallback* calibratorCallback_; 223 224 InputState state_; 225 InputState stateRequest_; 226 InputState savedState_; 227 unsigned int keyboardModifiers_; 228 StoredState savedHandlers_; 229 230 // joystick calibration 231 //std::vector<int> marginalsMaxConfig_; 232 //std::vector<int> marginalsMinConfig_; 233 int marginalsMax_[24]; 234 int marginalsMin_[24]; 235 bool bCalibrated_; 236 237 //! Keeps track of the joy stick POV states 238 std::vector<POVStates> povStates_; 239 //! Keeps track of the possibly two slider axes 240 std::vector<SliderStates> sliderStates_; 241 std::vector<JoyStickCalibration> joySticksCalibration_; 242 243 std::map<std::string, KeyHandler*> keyHandlers_; 244 std::map<std::string, MouseHandler*> mouseHandlers_; 245 std::map<std::string, JoyStickHandler*> joyStickHandlers_; 246 247 std::vector<KeyHandler*> activeKeyHandlers_; 248 std::vector<MouseHandler*> activeMouseHandlers_; 249 std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_; 250 std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_; 251 252 std::vector<Key> keysDown_; 253 std::vector<MouseButton::Enum> mouseButtonsDown_; 254 std::vector<std::vector<int> > joyStickButtonsDown_; 255 256 static std::string bindingCommmandString_s; 257 }; 258 84 public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener 85 { 86 // --> setConfigValues is private 87 friend class ClassIdentifier<InputManager>; 88 // let Core class use tick(.) 89 friend class Core; 90 91 public: 92 enum InputManagerState 93 { 94 Uninitialised = 0x00, 95 OISReady = 0x01, 96 InternalsReady = 0x02, 97 Ticking = 0x04, 98 Calibrating = 0x08, 99 ReloadRequest = 0x10, 100 JoyStickSupport = 0x20 // used with ReloadRequest to store a bool 101 }; 102 103 InputManager (); 104 ~InputManager(); 105 106 void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true); 107 108 void reloadInputSystem(bool joyStickSupport = true); 109 110 int numberOfKeyboards() { return keyboard_ ? 1 : 0; } 111 int numberOfMice() { return mouse_ ? 1 : 0; } 112 int numberOfJoySticks() { return joySticksSize_; } 113 114 void setWindowExtents(const int width, const int height); 115 116 template <class T> 117 T* createInputState(const std::string& name, int priority) 118 { 119 T* state = new T; 120 if (_configureInputState(state, name, priority)) 121 return state; 122 else 123 { 124 delete state; 125 return 0; 126 } 127 } 128 129 InputState* getState (const std::string& name); 130 InputState* getCurrentState(); 131 bool requestDestroyState (const std::string& name); 132 bool requestEnterState (const std::string& name); 133 bool requestLeaveState (const std::string& name); 134 135 void tick(float dt); 136 137 static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 138 static InputManager* getInstancePtr() { return singletonRef_s; } 139 140 public: // console commands 141 static void storeKeyStroke(const std::string& name); 142 static void keyBind(const std::string& command); 143 static void calibrate(); 144 static void reload(bool joyStickSupport = true); 145 146 private: // functions 147 // don't mess with a Singleton 148 InputManager (const InputManager&); 149 150 // Intenal methods 151 void _initialiseKeyboard(); 152 void _initialiseMouse(); 153 void _initialiseJoySticks(); 154 void _redimensionLists(); 155 156 void _destroyKeyboard(); 157 void _destroyMouse(); 158 void _destroyJoySticks(); 159 void _destroyState(InputState* state); 160 void _clearBuffers(); 161 162 void _reload(bool joyStickSupport); 163 164 void _completeCalibration(); 165 166 void _fireAxis(unsigned int iJoyStick, int axis, int value); 167 unsigned int _getJoystick(const OIS::JoyStickEvent& arg); 168 169 void _updateActiveStates(); 170 bool _configureInputState(InputState* state, const std::string& name, int priority); 171 172 // input events 173 bool mousePressed (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 174 bool mouseReleased (const OIS::MouseEvent &arg, OIS::MouseButtonID id); 175 bool mouseMoved (const OIS::MouseEvent &arg); 176 bool keyPressed (const OIS::KeyEvent &arg); 177 bool keyReleased (const OIS::KeyEvent &arg); 178 bool buttonPressed (const OIS::JoyStickEvent &arg, int button); 179 bool buttonReleased(const OIS::JoyStickEvent &arg, int button); 180 bool axisMoved (const OIS::JoyStickEvent &arg, int axis); 181 bool sliderMoved (const OIS::JoyStickEvent &arg, int id); 182 bool povMoved (const OIS::JoyStickEvent &arg, int id); 183 // don't remove that! Or else add OIS as dependency library to orxonox. 184 bool vector3Moved (const OIS::JoyStickEvent &arg, int id) { return true; } 185 186 void setConfigValues(); 187 188 private: // variables 189 OIS::InputManager* inputSystem_; //!< OIS input manager 190 OIS::Keyboard* keyboard_; //!< OIS mouse 191 OIS::Mouse* mouse_; //!< OIS keyboard 192 std::vector<OIS::JoyStick*> joySticks_; //!< OIS joy sticks 193 unsigned int joySticksSize_; 194 unsigned int devicesNum_; 195 size_t windowHnd_; //!< Render window handle 196 InputManagerState internalState_; //!< Current internal state 197 198 // some internally handled states 199 SimpleInputState* stateDetector_; //!< KeyDetector instance 200 SimpleInputState* stateCalibrator_; 201 SimpleInputState* stateEmpty_; 202 203 std::map<std::string, InputState*> inputStatesByName_; 204 std::map<int, InputState*> inputStatesByPriority_; 205 206 std::set<InputState*> stateEnterRequests_; //!< Request to enter a new state 207 std::set<InputState*> stateLeaveRequests_; //!< Request to leave a running state 208 std::set<InputState*> stateDestroyRequests_; //!< Request to destroy a state 209 210 std::map<int, InputState*> activeStates_; 211 std::vector<InputState*> activeStatesTop_; //!< Current input states for joy stick events. 212 std::vector<InputState*> activeStatesTicked_; //!< Current input states for joy stick events. 213 214 // joystick calibration 215 //std::vector<int> marginalsMaxConfig_; 216 //std::vector<int> marginalsMinConfig_; 217 int marginalsMax_[24]; 218 int marginalsMin_[24]; 219 bool bCalibrated_; 220 bool bCalibrating_; 221 222 unsigned int keyboardModifiers_; //!< Bit mask representing keyboard modifiers. 223 std::vector<POVStates> povStates_; //!< Keeps track of the joy stick POV states. 224 std::vector<SliderStates> sliderStates_; //!< Keeps track of the possibly two slider axes. 225 std::vector<JoyStickCalibration> joySticksCalibration_; 226 227 std::vector<Key> keysDown_; 228 std::vector<MouseButton::Enum> mouseButtonsDown_; 229 std::vector<std::vector<JoyStickButton::Enum> > joyStickButtonsDown_; 230 231 static std::string bindingCommmandString_s; 232 static InputManager* singletonRef_s; 233 }; 259 234 } 260 235 -
code/trunk/src/core/input/KeyBinder.cc
r1747 r1755 43 43 namespace orxonox 44 44 { 45 /** 46 @brief Constructor that does as little as necessary. 47 */ 48 KeyBinder::KeyBinder() : deriveTime_(0.0f) 49 { 50 mouseRelative_[0] = 0; 51 mouseRelative_[1] = 0; 52 mousePosition_[0] = 0; 53 mousePosition_[1] = 0; 54 55 RegisterRootObject(KeyBinder); 56 57 // keys 58 std::string keyNames[] = { 59 "UNASSIGNED", 60 "ESCAPE", 61 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", 62 "MINUS", "EQUALS", "BACK", "TAB", 63 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", 64 "LBRACKET", "RBRACKET", 65 "RETURN", "LCONTROL", 66 "A", "S", "D", "F", "G", "H", "J", "K", "L", 67 "SEMICOLON", "APOSTROPHE", "GRAVE", 68 "LSHIFT", "BACKSLASH", 69 "Z", "X", "C", "V", "B", "N", "M", 70 "COMMA", "PERIOD", "SLASH", 71 "RSHIFT", 72 "MULTIPLY", 73 "LMENU", 74 "SPACE", 75 "CAPITAL", 76 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", 77 "NUMLOCK", "SCROLL", 78 "NUMPAD7", "NUMPAD8", "NUMPAD9", 79 "SUBTRACT", 80 "NUMPAD4", "NUMPAD5", "NUMPAD6", 81 "ADD", 82 "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0", 83 "DECIMAL", 84 "","", 85 "OEM_102", 86 "F11", "F12", 87 "","","","","","","","","","","", 88 "F13", "F14", "F15", 89 "","","","","","","","","","", 90 "KANA", 91 "","", 92 "ABNT_C1", 93 "","","","","", 94 "CONVERT", 95 "", 96 "NOCONVERT", 97 "", 98 "YEN", 99 "ABNT_C2", 100 "","","","","","","","","","","","","","", 101 "NUMPADEQUALS", 102 "","", 103 "PREVTRACK", 104 "AT", 105 "COLON", "UNDERLINE", 106 "KANJI", 107 "STOP", 108 "AX", 109 "UNLABELED", 110 "NEXTTRACK", 111 "","", 112 "NUMPADENTER", 113 "RCONTROL", 114 "","", 115 "MUTE", 116 "CALCULATOR", 117 "PLAYPAUSE", 118 "", 119 "MEDIASTOP", 120 "","","","","","","","","", 121 "VOLUMEDOWN", 122 "", 123 "VOLUMEUP", 124 "", 125 "WEBHOME", 126 "NUMPADCOMMA", 127 "", 128 "DIVIDE", 129 "", 130 "SYSRQ", 131 "RMENU", 132 "","","","","","","","","","","","", 133 "PAUSE", 134 "", 135 "HOME", 136 "UP", 137 "PGUP", 138 "", 139 "LEFT", 140 "", 141 "RIGHT", 142 "", 143 "END", "DOWN", "PGDOWN", "INSERT", "DELETE", 144 "","","","","","","", 145 "LWIN", "RWIN", "APPS", 146 "POWER", "SLEEP", 147 "","","", 148 "WAKE", 149 "", 150 "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK", 151 "MYCOMPUTER", "MAIL", "MEDIASELECT" 152 }; 153 for (unsigned int i = 0; i < nKeys_s; i++) 154 keys_[i].name_ = "Key" + keyNames[i]; 155 156 // mouse buttons 157 std::string mouseButtonNames[] = { 158 "MouseLeft", "MouseRight", "MouseMiddle", 159 "MouseButton3", "MouseButton4", "MouseButton5", 160 "MouseButton6", "MouseButton7", 161 "MouseWheel1Up", "MouseWheel1Down", 162 "MouseWheel2Up", "MouseWheel2Down" }; 163 for (unsigned int i = 0; i < nMouseButtons_s; i++) 164 mouseButtons_[i].name_ = mouseButtonNames[i]; 165 166 // joy stick buttons 167 for (unsigned int i = 0; i < 32; i++) 168 joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i); 169 for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4) 170 { 171 joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North"; 172 joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South"; 173 joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East"; 174 joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West"; 175 } 176 177 // half axes 178 std::string rawNames[nHalfAxes_s/2]; 179 rawNames[0] = "MouseX"; 180 rawNames[1] = "MouseY"; 181 rawNames[2] = "Empty1"; 182 rawNames[3] = "Empty2"; 183 for (unsigned int i = 4; i < nHalfAxes_s/2; i++) 184 rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3); 185 for (unsigned int i = 0; i < nHalfAxes_s/2; i++) 186 { 187 halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos"; 188 halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg"; 189 } 190 191 for (unsigned int i = 0; i < this->nHalfAxes_s; i++) 192 halfAxes_[i].buttonThreshold_ = buttonThreshold_; 193 } 194 195 /** 196 @brief Destructor 197 */ 198 KeyBinder::~KeyBinder() 199 { 200 // almost no destructors required because most of the arrays are static. 201 clearBindings(); // does some destruction work 202 } 203 204 /** 205 @brief Loads the key and button bindings. 206 @return True if loading succeeded. 207 */ 208 void KeyBinder::loadBindings() 209 { 210 COUT(3) << "KeyBinder: Loading key bindings..." << std::endl; 211 212 clearBindings(); 213 214 std::ifstream infile; 215 infile.open("keybindings.ini"); 216 if (!infile) 217 { 218 ConfigFileManager::getInstance()->setFile(CFT_Keybindings, "def_keybindings.ini"); 219 ConfigFileManager::getInstance()->save(CFT_Keybindings, "keybindings.ini"); 220 } 221 else 222 infile.close(); 223 ConfigFileManager::getInstance()->setFile(CFT_Keybindings, "keybindings.ini"); 224 225 // parse key bindings 226 setConfigValues(); 227 228 COUT(3) << "KeyBinder: Loading key bindings done." << std::endl; 229 } 230 231 /** 232 @brief Loader for the key bindings, managed by config values. 233 */ 234 void KeyBinder::setConfigValues() 235 { 236 SetConfigValue(analogThreshold_, 0.05f) .description("Threshold for analog axes until which the state is 0."); 237 SetConfigValue(mouseSensitivity_, 1.0f) .description("Mouse sensitivity."); 238 SetConfigValue(bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value."); 239 SetConfigValue(derivePeriod_, 0.05f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier."); 240 SetConfigValue(mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived."); 241 SetConfigValue(bClipMouse_, true).description("Whether or not to clip absolute value of mouse in non derive mode."); 242 243 float oldThresh = buttonThreshold_; 244 SetConfigValue(buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed."); 245 if (oldThresh != buttonThreshold_) 246 for (unsigned int i = 0; i < nHalfAxes_s; i++) 247 if (halfAxes_[i].buttonThreshold_ == oldThresh) 248 halfAxes_[i].buttonThreshold_ = buttonThreshold_; 249 250 // keys 251 for (unsigned int i = 0; i < nKeys_s; i++) 252 readTrigger(keys_[i]); 253 // mouse buttons 254 for (unsigned int i = 0; i < nMouseButtons_s; i++) 255 readTrigger(mouseButtons_[i]); 256 // joy stick buttons 257 for (unsigned int i = 0; i < nJoyStickButtons_s; i++) 258 readTrigger(joyStickButtons_[i]); 259 // half axes 260 for (unsigned int i = 0; i < nHalfAxes_s; i++) 261 readTrigger(halfAxes_[i]); 262 } 263 264 void KeyBinder::readTrigger(Button& button) 265 { 266 // config value stuff 267 ConfigValueContainer* cont = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_); 268 if (!cont) 269 { 270 cont = new ConfigValueContainer(CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "", button.name_); 271 ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont); 272 } 273 std::string old = button.bindingString_; 274 cont->getValue(&button.bindingString_, this); 275 276 // keybinder stuff 277 if (old != button.bindingString_) 278 { 279 // clear everything so we don't get old axis ParamCommands mixed up 280 button.clear(); 281 282 // binding has changed 283 button.parse(paramCommandBuffer_); 284 } 285 } 286 287 /** 288 @brief Overwrites all bindings with "" 289 */ 290 void KeyBinder::clearBindings() 291 { 292 for (unsigned int i = 0; i < nKeys_s; i++) 293 keys_[i].clear(); 294 295 for (unsigned int i = 0; i < nMouseButtons_s; i++) 296 mouseButtons_[i].clear(); 297 298 for (unsigned int i = 0; i < nJoyStickButtons_s; i++) 299 joyStickButtons_[i].clear(); 300 301 for (unsigned int i = 0; i < nHalfAxes_s; i++) 302 halfAxes_[i].clear(); 303 304 for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++) 305 delete paramCommandBuffer_[i]; 306 paramCommandBuffer_.clear(); 307 } 308 309 void KeyBinder::resetJoyStickAxes() 310 { 311 for (unsigned int i = 8; i < nHalfAxes_s; i++) 312 { 313 halfAxes_[i].absVal_ = 0.0f; 314 halfAxes_[i].relVal_ = 0.0f; 315 } 316 } 317 318 void KeyBinder::tickInput(float dt, const HandlerState& state) 319 { 320 // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event. 321 unsigned int iBegin = 8; 322 unsigned int iEnd = 8; 323 if (state.joyStick) 324 iEnd = nHalfAxes_s; 325 if (state.mouse) 326 iBegin = 0; 327 for (unsigned int i = iBegin; i < iEnd; i++) 328 { 329 if (halfAxes_[i].hasChanged_) 330 { 331 if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_) 332 { 333 halfAxes_[i].wasDown_ = true; 334 if (halfAxes_[i].nCommands_[KeybindMode::OnPress]) 335 halfAxes_[i].execute(KeybindMode::OnPress); 336 } 337 else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_) 338 { 339 halfAxes_[i].wasDown_ = false; 340 if (halfAxes_[i].nCommands_[KeybindMode::OnRelease]) 341 halfAxes_[i].execute(KeybindMode::OnRelease); 342 } 343 halfAxes_[i].hasChanged_ = false; 344 } 345 346 if (halfAxes_[i].wasDown_) 347 { 348 if (halfAxes_[i].nCommands_[KeybindMode::OnHold]) 349 halfAxes_[i].execute(KeybindMode::OnHold); 350 } 351 352 // these are the actually useful axis bindings for analog input AND output 353 if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_) 354 { 355 //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl; 356 halfAxes_[i].execute(); 357 } 358 } 359 360 if (bDeriveMouseInput_ && state.mouse) 361 { 362 if (deriveTime_ > derivePeriod_) 363 { 364 //CCOUT(3) << "mouse abs: "; 45 /** 46 @brief 47 Constructor that does as little as necessary. 48 */ 49 KeyBinder::KeyBinder() 50 : deriveTime_(0.0f) 51 { 52 mouseRelative_[0] = 0; 53 mouseRelative_[1] = 0; 54 mousePosition_[0] = 0; 55 mousePosition_[1] = 0; 56 57 RegisterRootObject(KeyBinder); 58 59 // keys 60 std::string keyNames[] = { 61 "UNASSIGNED", 62 "ESCAPE", 63 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", 64 "MINUS", "EQUALS", "BACK", "TAB", 65 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", 66 "LBRACKET", "RBRACKET", 67 "RETURN", "LCONTROL", 68 "A", "S", "D", "F", "G", "H", "J", "K", "L", 69 "SEMICOLON", "APOSTROPHE", "GRAVE", 70 "LSHIFT", "BACKSLASH", 71 "Z", "X", "C", "V", "B", "N", "M", 72 "COMMA", "PERIOD", "SLASH", 73 "RSHIFT", 74 "MULTIPLY", 75 "LMENU", 76 "SPACE", 77 "CAPITAL", 78 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", 79 "NUMLOCK", "SCROLL", 80 "NUMPAD7", "NUMPAD8", "NUMPAD9", 81 "SUBTRACT", 82 "NUMPAD4", "NUMPAD5", "NUMPAD6", 83 "ADD", 84 "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0", 85 "DECIMAL", 86 "","", 87 "OEM_102", 88 "F11", "F12", 89 "","","","","","","","","","","", 90 "F13", "F14", "F15", 91 "","","","","","","","","","", 92 "KANA", 93 "","", 94 "ABNT_C1", 95 "","","","","", 96 "CONVERT", 97 "", 98 "NOCONVERT", 99 "", 100 "YEN", 101 "ABNT_C2", 102 "","","","","","","","","","","","","","", 103 "NUMPADEQUALS", 104 "","", 105 "PREVTRACK", 106 "AT", 107 "COLON", "UNDERLINE", 108 "KANJI", 109 "STOP", 110 "AX", 111 "UNLABELED", 112 "NEXTTRACK", 113 "","", 114 "NUMPADENTER", 115 "RCONTROL", 116 "","", 117 "MUTE", 118 "CALCULATOR", 119 "PLAYPAUSE", 120 "", 121 "MEDIASTOP", 122 "","","","","","","","","", 123 "VOLUMEDOWN", 124 "", 125 "VOLUMEUP", 126 "", 127 "WEBHOME", 128 "NUMPADCOMMA", 129 "", 130 "DIVIDE", 131 "", 132 "SYSRQ", 133 "RMENU", 134 "","","","","","","","","","","","", 135 "PAUSE", 136 "", 137 "HOME", 138 "UP", 139 "PGUP", 140 "", 141 "LEFT", 142 "", 143 "RIGHT", 144 "", 145 "END", "DOWN", "PGDOWN", "INSERT", "DELETE", 146 "","","","","","","", 147 "LWIN", "RWIN", "APPS", 148 "POWER", "SLEEP", 149 "","","", 150 "WAKE", 151 "", 152 "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK", 153 "MYCOMPUTER", "MAIL", "MEDIASELECT" 154 }; 155 for (unsigned int i = 0; i < nKeys_s; i++) 156 keys_[i].name_ = "Key" + keyNames[i]; 157 158 // mouse buttons 159 std::string mouseButtonNames[] = { 160 "MouseLeft", "MouseRight", "MouseMiddle", 161 "MouseButton3", "MouseButton4", "MouseButton5", 162 "MouseButton6", "MouseButton7", 163 "MouseWheel1Up", "MouseWheel1Down", 164 "MouseWheel2Up", "MouseWheel2Down" 165 }; 166 for (unsigned int i = 0; i < nMouseButtons_s; i++) 167 mouseButtons_[i].name_ = mouseButtonNames[i]; 168 169 // joy stick buttons 170 for (unsigned int i = 0; i < 32; i++) 171 joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i); 172 for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4) 173 { 174 joyStickButtons_[i + 0].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "North"; 175 joyStickButtons_[i + 1].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "South"; 176 joyStickButtons_[i + 2].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "East"; 177 joyStickButtons_[i + 3].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "West"; 178 } 179 180 // half axes 181 std::string rawNames[nHalfAxes_s/2]; 182 rawNames[0] = "MouseX"; 183 rawNames[1] = "MouseY"; 184 rawNames[2] = "Empty1"; 185 rawNames[3] = "Empty2"; 186 for (unsigned int i = 4; i < nHalfAxes_s/2; i++) 187 rawNames[i] = "JoyAxis" + convertToString(i - 3); 188 for (unsigned int i = 0; i < nHalfAxes_s/2; i++) 189 { 190 halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos"; 191 halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg"; 192 } 193 194 for (unsigned int i = 0; i < this->nHalfAxes_s; i++) 195 halfAxes_[i].buttonThreshold_ = buttonThreshold_; 196 } 197 198 /** 199 @brief 200 Destructor 201 */ 202 KeyBinder::~KeyBinder() 203 { 204 // almost no destructors required because most of the arrays are static. 205 clearBindings(); // does some destruction work 206 } 207 208 /** 209 @brief 210 Loads the key and button bindings. 211 @return 212 True if loading succeeded. 213 */ 214 void KeyBinder::loadBindings() 215 { 216 COUT(3) << "KeyBinder: Loading key bindings..." << std::endl; 217 218 clearBindings(); 219 220 std::ifstream infile; 221 infile.open("keybindings.ini"); 222 if (!infile) 223 { 224 ConfigFileManager::getInstance()->setFile(CFT_Keybindings, "def_keybindings.ini"); 225 ConfigFileManager::getInstance()->save(CFT_Keybindings, "keybindings.ini"); 226 } 227 else 228 infile.close(); 229 ConfigFileManager::getInstance()->setFile(CFT_Keybindings, "keybindings.ini"); 230 231 // parse key bindings 232 setConfigValues(); 233 234 COUT(3) << "KeyBinder: Loading key bindings done." << std::endl; 235 } 236 237 /** 238 @brief 239 Loader for the key bindings, managed by config values. 240 */ 241 void KeyBinder::setConfigValues() 242 { 243 SetConfigValue(analogThreshold_, 0.05f) 244 .description("Threshold for analog axes until which the state is 0."); 245 SetConfigValue(mouseSensitivity_, 1.0f) 246 .description("Mouse sensitivity."); 247 SetConfigValue(bDeriveMouseInput_, false) 248 .description("Whether or not to derive moues movement for the absolute value."); 249 SetConfigValue(derivePeriod_, 0.05f) 250 .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier."); 251 SetConfigValue(mouseSensitivityDerived_, 1.0f) 252 .description("Mouse sensitivity if mouse input is derived."); 253 SetConfigValue(bClipMouse_, true) 254 .description("Whether or not to clip absolute value of mouse in non derive mode."); 255 256 float oldThresh = buttonThreshold_; 257 SetConfigValue(buttonThreshold_, 0.80f) 258 .description("Threshold for analog axes until which the button is not pressed."); 259 if (oldThresh != buttonThreshold_) 260 for (unsigned int i = 0; i < nHalfAxes_s; i++) 261 if (halfAxes_[i].buttonThreshold_ == oldThresh) 262 halfAxes_[i].buttonThreshold_ = buttonThreshold_; 263 264 // keys 265 for (unsigned int i = 0; i < nKeys_s; i++) 266 readTrigger(keys_[i]); 267 // mouse buttons 268 for (unsigned int i = 0; i < nMouseButtons_s; i++) 269 readTrigger(mouseButtons_[i]); 270 // joy stick buttons 271 for (unsigned int i = 0; i < nJoyStickButtons_s; i++) 272 readTrigger(joyStickButtons_[i]); 273 // half axes 274 for (unsigned int i = 0; i < nHalfAxes_s; i++) 275 readTrigger(halfAxes_[i]); 276 } 277 278 void KeyBinder::readTrigger(Button& button) 279 { 280 // config value stuff 281 ConfigValueContainer* cont 282 = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_); 283 if (!cont) 284 { 285 cont = new ConfigValueContainer 286 (CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "", button.name_); 287 ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont); 288 } 289 std::string old = button.bindingString_; 290 cont->getValue(&button.bindingString_, this); 291 292 // keybinder stuff 293 if (old != button.bindingString_) 294 { 295 // clear everything so we don't get old axis ParamCommands mixed up 296 button.clear(); 297 298 // binding has changed 299 button.parse(paramCommandBuffer_); 300 } 301 } 302 303 /** 304 @brief 305 Overwrites all bindings with "" 306 */ 307 void KeyBinder::clearBindings() 308 { 309 for (unsigned int i = 0; i < nKeys_s; i++) 310 keys_[i].clear(); 311 312 for (unsigned int i = 0; i < nMouseButtons_s; i++) 313 mouseButtons_[i].clear(); 314 315 for (unsigned int i = 0; i < nJoyStickButtons_s; i++) 316 joyStickButtons_[i].clear(); 317 318 for (unsigned int i = 0; i < nHalfAxes_s; i++) 319 halfAxes_[i].clear(); 320 321 for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++) 322 delete paramCommandBuffer_[i]; 323 paramCommandBuffer_.clear(); 324 } 325 326 void KeyBinder::resetJoyStickAxes() 327 { 328 for (unsigned int i = 8; i < nHalfAxes_s; i++) 329 { 330 halfAxes_[i].absVal_ = 0.0f; 331 halfAxes_[i].relVal_ = 0.0f; 332 } 333 } 334 335 void KeyBinder::tickMouse(float dt) 336 { 337 tickDevices(0, 8); 338 339 if (bDeriveMouseInput_) 340 { 341 if (deriveTime_ > derivePeriod_) 342 { 343 //CCOUT(3) << "mouse abs: "; 344 for (int i = 0; i < 2; i++) 345 { 346 if (mouseRelative_[i] > 0) 347 { 348 halfAxes_[2*i + 0].absVal_ 349 = mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_; 350 halfAxes_[2*i + 1].absVal_ = 0.0f; 351 } 352 else if (mouseRelative_[i] < 0) 353 { 354 halfAxes_[2*i + 0].absVal_ = 0.0f; 355 halfAxes_[2*i + 1].absVal_ 356 = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_; 357 } 358 else 359 { 360 halfAxes_[2*i + 0].absVal_ = 0.0f; 361 halfAxes_[2*i + 1].absVal_ = 0.0f; 362 } 363 //COUT(3) << mouseRelative_[i] << " | "; 364 mouseRelative_[i] = 0; 365 halfAxes_[2*i + 0].hasChanged_ = true; 366 halfAxes_[2*i + 1].hasChanged_ = true; 367 } 368 deriveTime_ = 0.0f; 369 //COUT(3) << std::endl; 370 } 371 else 372 deriveTime_ += dt; 373 } 374 } 375 376 void KeyBinder::tickJoyStick(float dt, unsigned int joyStick) 377 { 378 tickDevices(8, nHalfAxes_s); 379 } 380 381 void KeyBinder::tickInput(float dt) 382 { 383 // execute all buffered bindings (additional parameter) 384 for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++) 385 paramCommandBuffer_[i]->execute(); 386 387 // always reset the relative movement of the mouse 388 for (unsigned int i = 0; i < 8; i++) 389 halfAxes_[i].relVal_ = 0.0f; 390 } 391 392 void KeyBinder::tickDevices(unsigned int begin, unsigned int end) 393 { 394 for (unsigned int i = begin; i < end; i++) 395 { 396 // button mode 397 // TODO: optimize out all the half axes that don't act as a button at the moment 398 if (halfAxes_[i].hasChanged_) 399 { 400 if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_) 401 { 402 halfAxes_[i].wasDown_ = true; 403 if (halfAxes_[i].nCommands_[KeybindMode::OnPress]) 404 halfAxes_[i].execute(KeybindMode::OnPress); 405 } 406 else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_) 407 { 408 halfAxes_[i].wasDown_ = false; 409 if (halfAxes_[i].nCommands_[KeybindMode::OnRelease]) 410 halfAxes_[i].execute(KeybindMode::OnRelease); 411 } 412 halfAxes_[i].hasChanged_ = false; 413 } 414 415 if (halfAxes_[i].wasDown_) 416 { 417 if (halfAxes_[i].nCommands_[KeybindMode::OnHold]) 418 halfAxes_[i].execute(KeybindMode::OnHold); 419 } 420 421 // these are the actually useful axis bindings for analog input 422 if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_) 423 { 424 //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl; 425 halfAxes_[i].execute(); 426 } 427 } 428 } 429 430 void KeyBinder::keyPressed (const KeyEvent& evt) 431 { keys_[evt.key].execute(KeybindMode::OnPress); } 432 433 void KeyBinder::keyReleased(const KeyEvent& evt) 434 { keys_[evt.key].execute(KeybindMode::OnRelease); } 435 436 void KeyBinder::keyHeld (const KeyEvent& evt) 437 { keys_[evt.key].execute(KeybindMode::OnHold); } 438 439 440 void KeyBinder::mouseButtonPressed (MouseButton::Enum id) 441 { mouseButtons_[id].execute(KeybindMode::OnPress); } 442 443 void KeyBinder::mouseButtonReleased(MouseButton::Enum id) 444 { mouseButtons_[id].execute(KeybindMode::OnRelease); } 445 446 void KeyBinder::mouseButtonHeld (MouseButton::Enum id) 447 { mouseButtons_[id].execute(KeybindMode::OnHold); } 448 449 450 void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) 451 { joyStickButtons_[id].execute(KeybindMode::OnPress); } 452 453 void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) 454 { joyStickButtons_[id].execute(KeybindMode::OnRelease); } 455 456 void KeyBinder::joyStickButtonHeld (unsigned int joyStickID, JoyStickButton::Enum id) 457 { joyStickButtons_[id].execute(KeybindMode::OnHold); } 458 459 /** 460 @brief 461 Event handler for the mouseMoved Event. 462 @param e 463 Mouse state information 464 */ 465 void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize) 466 { 467 // y axis of mouse input is inverted 468 int rel[] = { rel_.x, -rel_.y }; 469 470 if (!bDeriveMouseInput_) 471 { 472 for (int i = 0; i < 2; i++) 473 { 474 if (rel[i]) 475 { 476 // absolute 477 halfAxes_[2*i + 0].hasChanged_ = true; 478 halfAxes_[2*i + 1].hasChanged_ = true; 479 mousePosition_[i] += rel[i]; 480 481 if (bClipMouse_) 482 { 483 if (mousePosition_[i] > 1024) 484 mousePosition_[i] = 1024; 485 if (mousePosition_[i] < -1024) 486 mousePosition_[i] = -1024; 487 } 488 489 if (mousePosition_[i] >= 0) 490 { 491 halfAxes_[2*i + 0].absVal_ = mousePosition_[i]/1024.0f * mouseSensitivity_; 492 halfAxes_[2*i + 1].absVal_ = 0.0f; 493 } 494 else 495 { 496 halfAxes_[2*i + 0].absVal_ = 0.0f; 497 halfAxes_[2*i + 1].absVal_ = -mousePosition_[i]/1024.0f * mouseSensitivity_; 498 } 499 } 500 } 501 } 502 else 503 { 504 mouseRelative_[0] += rel[0]; 505 mouseRelative_[1] += rel[1]; 506 } 507 508 // relative 365 509 for (int i = 0; i < 2; i++) 366 510 { 367 if (mouseRelative_[i] > 0) 368 { 369 halfAxes_[2*i + 0].absVal_ = mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_; 370 halfAxes_[2*i + 1].absVal_ = 0.0f; 371 } 372 else if (mouseRelative_[i] < 0) 373 { 374 halfAxes_[2*i + 0].absVal_ = 0.0f; 375 halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_; 376 } 377 else 378 { 379 halfAxes_[2*i + 0].absVal_ = 0.0f; 380 halfAxes_[2*i + 1].absVal_ = 0.0f; 381 } 382 //COUT(3) << mouseRelative_[i] << " | "; 383 mouseRelative_[i] = 0; 384 halfAxes_[2*i + 0].hasChanged_ = true; 385 halfAxes_[2*i + 1].hasChanged_ = true; 386 } 387 deriveTime_ = 0.0f; 388 //COUT(3) << std::endl; 389 } 390 else 391 deriveTime_ += dt; 392 } 393 394 // execute all buffered bindings (addional parameter) 395 for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++) 396 paramCommandBuffer_[i]->execute(); 397 398 // always reset the relative movement of the mouse 399 if (state.mouse) 400 for (unsigned int i = 0; i < 8; i++) 401 halfAxes_[i].relVal_ = 0.0f; 402 } 403 404 void KeyBinder::keyPressed (const KeyEvent& evt) 405 { keys_[evt.key].execute(KeybindMode::OnPress); } 406 407 void KeyBinder::keyReleased(const KeyEvent& evt) 408 { keys_[evt.key].execute(KeybindMode::OnRelease); } 409 410 void KeyBinder::keyHeld (const KeyEvent& evt) 411 { keys_[evt.key].execute(KeybindMode::OnHold); } 412 413 414 void KeyBinder::mouseButtonPressed (MouseButton::Enum id) 415 { mouseButtons_[id].execute(KeybindMode::OnPress); } 416 417 void KeyBinder::mouseButtonReleased(MouseButton::Enum id) 418 { mouseButtons_[id].execute(KeybindMode::OnRelease); } 419 420 void KeyBinder::mouseButtonHeld (MouseButton::Enum id) 421 { mouseButtons_[id].execute(KeybindMode::OnHold); } 422 423 424 void KeyBinder::joyStickButtonPressed (int joyStickID, int button) 425 { joyStickButtons_[button].execute(KeybindMode::OnPress); } 426 427 void KeyBinder::joyStickButtonReleased(int joyStickID, int button) 428 { joyStickButtons_[button].execute(KeybindMode::OnRelease); } 429 430 void KeyBinder::joyStickButtonHeld (int joyStickID, int button) 431 { joyStickButtons_[button].execute(KeybindMode::OnHold); } 432 433 /** 434 @brief Event handler for the mouseMoved Event. 435 @param e Mouse state information 436 */ 437 void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize) 438 { 439 // y axis of mouse input is inverted 440 int rel[] = { rel_.x, -rel_.y }; 441 442 if (!bDeriveMouseInput_) 443 { 444 for (int i = 0; i < 2; i++) 445 { 446 if (rel[i]) 447 { 448 // absolute 449 halfAxes_[2*i + 0].hasChanged_ = true; 450 halfAxes_[2*i + 1].hasChanged_ = true; 451 mousePosition_[i] += rel[i]; 452 453 if (bClipMouse_) 454 { 455 if (mousePosition_[i] > 1024) 456 mousePosition_[i] = 1024; 457 if (mousePosition_[i] < -1024) 458 mousePosition_[i] = -1024; 459 } 460 461 if (mousePosition_[i] >= 0) 462 { 463 halfAxes_[2*i + 0].absVal_ = mousePosition_[i]/1024.0f * mouseSensitivity_; 464 halfAxes_[2*i + 1].absVal_ = 0.0f; 465 } 466 else 467 { 468 halfAxes_[2*i + 0].absVal_ = 0.0f; 469 halfAxes_[2*i + 1].absVal_ = -mousePosition_[i]/1024.0f * mouseSensitivity_; 470 } 471 } 472 } 473 } 474 else 475 { 476 mouseRelative_[0] += rel[0]; 477 mouseRelative_[1] += rel[1]; 478 } 479 480 // relative 481 for (int i = 0; i < 2; i++) 482 { 483 if (rel[i] > 0) 484 halfAxes_[0 + 2*i].relVal_ = ((float)rel[i])/1024 * mouseSensitivity_; 485 else 486 halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_; 487 } 488 } 489 490 /** 511 if (rel[i] > 0) 512 halfAxes_[0 + 2*i].relVal_ = ((float)rel[i])/1024 * mouseSensitivity_; 513 else 514 halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_; 515 } 516 } 517 518 /** 491 519 @brief Event handler for the mouseScrolled Event. 492 520 @param e Mouse state information 493 */ 494 void KeyBinder::mouseScrolled(int abs, int rel) 495 { 496 //COUT(3) << mouseButtons_[8].name_ << " " << abs << " | " << rel << std::endl; 497 498 if (rel > 0) 499 for (int i = 0; i < rel/120; i++) 500 mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f); 501 else 502 for (int i = 0; i < -rel/120; i++) 503 mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f); 504 } 505 506 void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value) 507 { 508 // TODO: Use proper calibration values instead of generally 16-bit integer 509 int i = 8 + axis * 2; 510 if (value >= 0) 511 { 512 //if (value > 10000) 513 //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; } 514 515 halfAxes_[i].absVal_ = value; 516 halfAxes_[i].relVal_ = value; 517 halfAxes_[i].hasChanged_ = true; 518 if (halfAxes_[i + 1].absVal_ > 0.0f) 519 { 520 halfAxes_[i + 1].absVal_ = -0.0f; 521 halfAxes_[i + 1].relVal_ = -0.0f; 522 halfAxes_[i + 1].hasChanged_ = true; 523 } 524 } 525 else 526 { 527 //if (value < -10000) 528 //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; } 529 530 halfAxes_[i + 1].absVal_ = -value; 531 halfAxes_[i + 1].relVal_ = -value; 532 halfAxes_[i + 1].hasChanged_ = true; 533 if (halfAxes_[i].absVal_ > 0.0f) 534 { 535 halfAxes_[i].absVal_ = -0.0f; 536 halfAxes_[i].relVal_ = -0.0f; 537 halfAxes_[i].hasChanged_ = true; 538 } 539 } 540 } 521 */ 522 void KeyBinder::mouseScrolled(int abs, int rel) 523 { 524 //COUT(3) << mouseButtons_[8].name_ << " " << abs << " | " << rel << std::endl; 525 526 if (rel > 0) 527 for (int i = 0; i < rel/120; i++) 528 mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f); 529 else 530 for (int i = 0; i < -rel/120; i++) 531 mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f); 532 } 533 534 void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value) 535 { 536 int i = 8 + axis * 2; 537 if (value >= 0) 538 { 539 //if (value > 10000) 540 //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; } 541 542 halfAxes_[i].absVal_ = value; 543 halfAxes_[i].relVal_ = value; 544 halfAxes_[i].hasChanged_ = true; 545 if (halfAxes_[i + 1].absVal_ > 0.0f) 546 { 547 halfAxes_[i + 1].absVal_ = -0.0f; 548 halfAxes_[i + 1].relVal_ = -0.0f; 549 halfAxes_[i + 1].hasChanged_ = true; 550 } 551 } 552 else 553 { 554 //if (value < -10000) 555 //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; } 556 557 halfAxes_[i + 1].absVal_ = -value; 558 halfAxes_[i + 1].relVal_ = -value; 559 halfAxes_[i + 1].hasChanged_ = true; 560 if (halfAxes_[i].absVal_ > 0.0f) 561 { 562 halfAxes_[i].absVal_ = -0.0f; 563 halfAxes_[i].relVal_ = -0.0f; 564 halfAxes_[i].hasChanged_ = true; 565 } 566 } 567 } 541 568 } -
code/trunk/src/core/input/KeyBinder.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _KeyBinder_H__ … … 46 47 namespace orxonox 47 48 { 48 /** 49 @brief Handles mouse, keyboard and joy stick input while in the actual game mode. 50 Manages the key bindings. 51 */ 52 class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, public OrxonoxClass 53 { 54 public: 55 KeyBinder (); 56 virtual ~KeyBinder(); 49 /** 50 @brief 51 Handles mouse, keyboard and joy stick input while in the actual game mode. 52 Manages the key bindings. 53 */ 54 class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, public OrxonoxClass 55 { 56 public: 57 KeyBinder (); 58 virtual ~KeyBinder(); 57 59 58 void loadBindings();59 void clearBindings();60 void setConfigValues();61 void resetJoyStickAxes();60 void loadBindings(); 61 void clearBindings(); 62 void setConfigValues(); 63 void resetJoyStickAxes(); 62 64 63 protected: // functions 64 void tickInput(float dt, const HandlerState& state); 65 protected: // functions 66 void tickInput(float dt); 67 //void tickInput(float dt, int device); 68 void tickKey(float dt) { } 69 void tickMouse(float dt); 70 void tickJoyStick(float dt, unsigned int joyStick); 71 void tickDevices(unsigned int begin, unsigned int end); 65 72 66 virtual void readTrigger(Button& button);73 virtual void readTrigger(Button& button); 67 74 68 void keyPressed (const KeyEvent& evt);69 void keyReleased(const KeyEvent& evt);70 void keyHeld (const KeyEvent& evt);75 void keyPressed (const KeyEvent& evt); 76 void keyReleased(const KeyEvent& evt); 77 void keyHeld (const KeyEvent& evt); 71 78 72 void mouseButtonPressed (MouseButton::Enum id);73 void mouseButtonReleased(MouseButton::Enum id);74 void mouseButtonHeld (MouseButton::Enum id);75 void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);76 void mouseScrolled (int abs, int rel);79 void mouseButtonPressed (MouseButton::Enum id); 80 void mouseButtonReleased(MouseButton::Enum id); 81 void mouseButtonHeld (MouseButton::Enum id); 82 void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize); 83 void mouseScrolled (int abs, int rel); 77 84 78 void joyStickButtonPressed (int joyStickID, int button);79 void joyStickButtonReleased(int joyStickID, int button);80 void joyStickButtonHeld (int joyStickID, int button);81 void joyStickAxisMoved (int joyStickID,int axis, float value);85 void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id); 86 void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id); 87 void joyStickButtonHeld (unsigned int joyStickID, JoyStickButton::Enum id); 88 void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value); 82 89 83 protected: // variables84 //! denotes the number of different keys there are in OIS.85 static const unsigned int nKeys_s = 0xEE;86 //! Actual key bindings as bundle for Press, Hold and Release87 Button keys_ [nKeys_s];90 protected: // variables 91 //! denotes the number of different keys there are in OIS. 92 static const unsigned int nKeys_s = 0xEE; 93 //! Actual key bindings as bundle for Press, Hold and Release 94 Button keys_ [nKeys_s]; 88 95 89 //! denotes the number of different mouse buttons there are in OIS.90 static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels91 //! Actual key bindings as bundle for Press, Hold and Release92 Button mouseButtons_ [nMouseButtons_s];96 //! denotes the number of different mouse buttons there are in OIS. 97 static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels 98 //! Actual key bindings as bundle for Press, Hold and Release 99 Button mouseButtons_ [nMouseButtons_s]; 93 100 94 //! denotes the number of different joy stick buttons there are in OIS.95 static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons96 //! Actual key bindings as bundle for Press, Hold and Release97 Button joyStickButtons_ [nJoyStickButtons_s];101 //! denotes the number of different joy stick buttons there are in OIS. 102 static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons 103 //! Actual key bindings as bundle for Press, Hold and Release 104 Button joyStickButtons_ [nJoyStickButtons_s]; 98 105 99 //! denotes the number of half axes (every axis twice) there can be.100 static const unsigned int nHalfAxes_s = 56;101 /**102 * Array with all the half axes for mouse and joy sticks.103 * Keep in mind that the positions are fixed and that the first entry is the104 * positive one and the second is negative.105 * Sequence is as follows:106 * 0 - 3: Mouse x and y107 * 4 - 7: empty108 * 8 - 23: joy stick slider axes 1 to 8109 * 24 - 55: joy stick axes 1 - 16110 */111 HalfAxis halfAxes_[nHalfAxes_s];106 //! denotes the number of half axes (every axis twice) there can be. 107 static const unsigned int nHalfAxes_s = 56; 108 /** 109 * Array with all the half axes for mouse and joy sticks. 110 * Keep in mind that the positions are fixed and that the first entry is the 111 * positive one and the second is negative. 112 * Sequence is as follows: 113 * 0 - 3: Mouse x and y 114 * 4 - 7: empty 115 * 8 - 23: joy stick slider axes 1 to 8 116 * 24 - 55: joy stick axes 1 - 16 117 */ 118 HalfAxis halfAxes_[nHalfAxes_s]; 112 119 113 /** 114 * Commands that have additional parameters (axes) are executed at the end of 115 * the tick() so that all values can be buffered for single execution. 116 */ 117 std::vector<BufferedParamCommand*> paramCommandBuffer_; 120 /** 121 @brief 122 Commands that have additional parameters (axes) are executed at the end of 123 the tick() so that all values can be buffered for single execution. 124 */ 125 std::vector<BufferedParamCommand*> paramCommandBuffer_; 118 126 119 //! Keeps track of the absolute mouse value (incl. scroll wheel)120 int mousePosition_[2];121 //! Used to derive mouse input if requested122 int mouseRelative_[2];123 float deriveTime_;127 //! Keeps track of the absolute mouse value (incl. scroll wheel) 128 int mousePosition_[2]; 129 //! Used to derive mouse input if requested 130 int mouseRelative_[2]; 131 float deriveTime_; 124 132 125 //##### ConfigValues ##### 126 //! Threshold for analog triggers until which the state is 0. 127 float analogThreshold_; 128 //! Threshold for analog triggers until which the button is not pressed. 129 float buttonThreshold_; 130 //! Derive mouse input for absolute values? 131 bool bDeriveMouseInput_; 132 //! Accuracy of the mouse input deriver. The higher the more precise, but laggier. 133 float derivePeriod_; 134 //! mouse sensitivity 135 float mouseSensitivity_; 136 //! mouse sensitivity if mouse input is derived 137 float mouseSensitivityDerived_; 138 //! Whether or not to clip abslute mouse values to 1024 139 bool bClipMouse_; 140 }; 133 134 //##### ConfigValues ##### 135 136 //! Threshold for analog triggers until which the state is 0. 137 float analogThreshold_; 138 //! Threshold for analog triggers until which the button is not pressed. 139 float buttonThreshold_; 140 //! Derive mouse input for absolute values? 141 bool bDeriveMouseInput_; 142 //! Accuracy of the mouse input deriver. The higher the more precise, but laggier. 143 float derivePeriod_; 144 //! mouse sensitivity 145 float mouseSensitivity_; 146 //! mouse sensitivity if mouse input is derived 147 float mouseSensitivityDerived_; 148 //! Whether or not to clip abslute mouse values to 1024 149 bool bClipMouse_; 150 }; 141 151 } 142 152 -
code/trunk/src/core/input/KeyDetector.cc
r1747 r1755 28 28 29 29 /** 30 @file 31 @brief Implementation of the different input handlers. 32 */ 30 @file 31 @brief 32 Implementation of the different input handlers. 33 */ 33 34 34 35 #include "KeyDetector.h" … … 42 43 namespace orxonox 43 44 { 44 /** 45 @brief Constructor 46 */ 47 KeyDetector::KeyDetector() 48 { 49 RegisterObject(KeyDetector); 50 } 45 /** 46 @brief 47 Constructor 48 */ 49 KeyDetector::KeyDetector() 50 { 51 RegisterObject(KeyDetector); 52 } 51 53 52 /** 53 @brief Destructor 54 */ 55 KeyDetector::~KeyDetector() 56 { 57 } 54 /** 55 @brief 56 Destructor 57 */ 58 KeyDetector::~KeyDetector() 59 { 60 } 58 61 59 /** 60 @brief Loads the key and button bindings. 61 @return True if loading succeeded. 62 */ 63 void KeyDetector::loadBindings() 64 { 65 clearBindings(); 66 setConfigValues(); 67 } 62 /** 63 @brief 64 Loads the key and button bindings. 65 @return 66 True if loading succeeded. 67 */ 68 void KeyDetector::loadBindings(const std::string& command) 69 { 70 this->command_ = command; 71 clearBindings(); 72 setConfigValues(); 73 } 68 74 69 void KeyDetector::readTrigger(Button& button)70 {71 SimpleCommand* cmd = new SimpleCommand();72 cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke" + button.name_);73 button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];74 button.commands_[KeybindMode::OnPress][0] = cmd;75 button.nCommands_[KeybindMode::OnPress] = 1;76 }75 void KeyDetector::readTrigger(Button& button) 76 { 77 SimpleCommand* cmd = new SimpleCommand(); 78 cmd->evaluation_ = CommandExecutor::evaluate(this->command_ + " " + button.name_); 79 button.commands_[KeybindMode::OnPress] = new BaseCommand*[1]; 80 button.commands_[KeybindMode::OnPress][0] = cmd; 81 button.nCommands_[KeybindMode::OnPress] = 1; 82 } 77 83 } -
code/trunk/src/core/input/KeyDetector.h
r1535 r1755 28 28 29 29 /** 30 @file 31 @brief Different definitions of input processing. 32 */ 30 @file 31 @brief 32 Different definitions of input processing. 33 */ 33 34 34 35 #ifndef _KeyDetector_H__ … … 41 42 namespace orxonox 42 43 { 43 class _CoreExport KeyDetector : public KeyBinder44 {45 public:46 KeyDetector();47 ~KeyDetector();48 void loadBindings();44 class _CoreExport KeyDetector : public KeyBinder 45 { 46 public: 47 KeyDetector(); 48 ~KeyDetector(); 49 void loadBindings(const std::string& command); 49 50 50 protected: 51 void readTrigger(Button& button); 52 }; 51 protected: 52 void readTrigger(Button& button); 53 54 private: 55 std::string command_; 56 }; 53 57 } 54 58 -
code/trunk/src/core/input/SimpleInputState.cc
r1724 r1755 36 36 37 37 #include <assert.h> 38 #include " core/Debug.h"38 #include "util/Debug.h" 39 39 #include "core/Executor.h" 40 40
Note: See TracChangeset
for help on using the changeset viewer.