Changeset 1755 for code/trunk/src/core/input/InputManager.cc
- Timestamp:
- Sep 10, 2008, 1:37:36 AM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
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/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 }
Note: See TracChangeset
for help on using the changeset viewer.