Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/core/input/InputManager.cc @ 2543

Last change on this file since 2543 was 2543, checked in by rgrieder, 15 years ago
  • Fixed a bug in ConfigFileManager::getVectorSize(). If there were no entries, 1 was returned instead of 0.
  • Added getSctionName to the ConfigValueContainer
  • Bugfix in Button::clear()
  • Renamed some joy stick buttons and axes to have them sorted corrected in the config file
  • Removed annoying and useless "Key_084=" from keybindings.ini file (there were about a hundred of them)
  • Bugfix in KeyBinder: All the axes were inverted (which was then corrected in the ini file)
  • Also inverted rotateYaw in SpaceShip and Spectator because that actually corrected the bug from above ;)
  • Some small performance optimisation in InputManager
  • Property svn:eol-style set to native
File size: 48.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30@file
31@brief
32    Implementation of the InputManager that captures all the input from OIS
33    and redirects it to handlers.
34 */
35
36#include "InputManager.h"
37
38#include <climits>
39#include <cassert>
40
41#include "ois/OISException.h"
42#include "ois/OISInputManager.h"
43
44#include "util/Exception.h"
45#include "core/CoreIncludes.h"
46#include "core/ConfigValueIncludes.h"
47#include "core/CommandExecutor.h"
48#include "core/ConsoleCommand.h"
49#include "core/CommandLine.h"
50#include "util/Debug.h"
51
52#include "InputBuffer.h"
53#include "KeyBinder.h"
54#include "KeyDetector.h"
55#include "CalibratorCallback.h"
56#include "InputState.h"
57#include "SimpleInputState.h"
58#include "ExtendedInputState.h"
59#include "JoyStickDeviceNumberListener.h"
60
61namespace orxonox
62{
63    SetConsoleCommand(InputManager, calibrate, true);
64    SetConsoleCommand(InputManager, reload, false);
65    SetCommandLineSwitch(keyboard_no_grab);
66
67    EmptyHandler InputManager::EMPTY_HANDLER;
68    InputManager* InputManager::singletonRef_s = 0;
69
70    using namespace InputDevice;
71
72    /**
73    @brief
74        Defines the |= operator for easier use.
75    */
76    inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval,
77                                                      InputManager::InputManagerState rval)
78    {
79        return (lval = (InputManager::InputManagerState)(lval | rval));
80    }
81
82    /**
83    @brief
84        Defines the &= operator for easier use.
85    */
86    inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval)
87    {
88        return (lval = (InputManager::InputManagerState)(lval & rval));
89    }
90
91    // ############################################################
92    // #####                  Initialisation                  #####
93    // ##########                                        ##########
94    // ############################################################
95
96    /**
97    @brief
98        Constructor only sets member fields to initial zero values
99        and registers the class in the class hierarchy.
100    */
101    InputManager::InputManager()
102        : inputSystem_(0)
103        , keyboard_(0)
104        , mouse_(0)
105        , joySticksSize_(0)
106        , devicesNum_(0)
107        , windowHnd_(0)
108        , internalState_(Uninitialised)
109        , stateEmpty_(0)
110        , stateMaster_(0)
111        , keyDetector_(0)
112        , calibratorCallbackBuffer_(0)
113        , bCalibrating_(false)
114        , keyboardModifiers_(0)
115    {
116        RegisterRootObject(InputManager);
117
118        assert(singletonRef_s == 0);
119        singletonRef_s = this;
120    }
121
122    /**
123    @brief
124        Creates the OIS::InputMananger, the keyboard, the mouse and
125        the joysticks and assigns the key bindings.
126    @param windowHnd
127        The window handle of the render window
128    @param windowWidth
129        The width of the render window
130    @param windowHeight
131        The height of the render window
132    @param joyStickSupport
133        Whether or not to load the joy sticks as well
134    */
135    void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
136    {
137        CCOUT(3) << "Initialising Input System..." << std::endl;
138
139        if (!(internalState_ & OISReady))
140        {
141            CCOUT(4) << "Initialising OIS components..." << std::endl;
142
143            // store handle internally so we can reload OIS
144            windowHnd_ = windowHnd;
145
146            OIS::ParamList paramList;
147            std::ostringstream windowHndStr;
148
149            // Fill parameter list
150            windowHndStr << (unsigned int)windowHnd_;
151            paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
152            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
153            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
154#if defined OIS_LINUX_PLATFORM
155            paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
156            paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
157            paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
158            bool kbNoGrab;
159            CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
160            if (kbNoGrab)
161                paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
162            else
163                paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
164#endif
165
166            inputSystem_ = OIS::InputManager::createInputSystem(paramList);
167            CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
168
169            _initialiseKeyboard();
170
171            _initialiseMouse();
172
173            if (joyStickSupport)
174                _initialiseJoySticks();
175            // Do this anyway to also inform everything when a joystick was detached.
176            _configureNumberOfJoySticks();
177
178            // Set mouse/joystick region
179            if (mouse_)
180                setWindowExtents(windowWidth, windowHeight);
181
182            // clear all buffers
183            _clearBuffers();
184
185            // load joy stick calibration
186            setConfigValues();
187
188            internalState_ |= OISReady;
189
190            CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
191        }
192        else
193        {
194            CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl;
195        }
196
197        if (!(internalState_ & InternalsReady))
198        {
199            CCOUT(4) << "Initialising InputStates components..." << std::endl;
200
201            // Lowest priority empty InputState
202            stateEmpty_ = createInputState<SimpleInputState>("empty", -1);
203            stateEmpty_->setHandler(&EMPTY_HANDLER);
204            activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
205
206            // Always active master InputState
207            stateMaster_ = new ExtendedInputState();
208            stateMaster_->setName("master");
209            stateMaster_->setNumOfJoySticks(joySticksSize_);
210
211            // KeyDetector to evaluate a pressed key's name
212            SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);
213            keyDetector_ = new KeyDetector();
214            detector->setHandler(keyDetector_);
215
216            // Joy stick calibration helper callback
217            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100);
218            calibrator->setHandler(&EMPTY_HANDLER);
219            calibratorCallbackBuffer_ = new InputBuffer();
220            calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
221            calibrator->setKeyHandler(calibratorCallbackBuffer_);
222
223            internalState_ |= InternalsReady;
224
225            CCOUT(4) << "Initialising InputStates complete." << std::endl;
226        }
227
228        _updateActiveStates();
229
230        CCOUT(3) << "Initialising complete." << std::endl;
231    }
232
233    /**
234    @brief
235        Creates a keyboard and sets the event handler.
236    @return
237        False if keyboard stays uninitialised, true otherwise.
238    */
239    void InputManager::_initialiseKeyboard()
240    {
241        if (keyboard_ != 0)
242        {
243            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
244            return;
245        }
246        if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
247        {
248            keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
249            // register our listener in OIS.
250            keyboard_->setEventCallback(this);
251            // note: OIS will not detect keys that have already been down when the keyboard was created.
252            CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
253        }
254        else
255        {
256            ThrowException(InitialisationFailed, "No keyboard found!");
257        }
258    }
259
260    /**
261    @brief
262        Creates a mouse and sets the event handler.
263    @return
264        False if mouse stays uninitialised, true otherwise.
265    */
266    void InputManager::_initialiseMouse()
267    {
268        if (mouse_ != 0)
269        {
270            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
271            return;
272        }
273        try
274        {
275            if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
276            {
277                mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true));
278                // register our listener in OIS.
279                mouse_->setEventCallback(this);
280                CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
281            }
282            else
283            {
284                CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
285            }
286        }
287        catch (OIS::Exception ex)
288        {
289            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
290                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
291            mouse_ = 0;
292        }
293    }
294
295    /**
296    @brief
297        Creates all joy sticks and sets the event handler.
298    @return
299        False joy stick stay uninitialised, true otherwise.
300    */
301    void InputManager::_initialiseJoySticks()
302    {
303        if (joySticksSize_ > 0)
304        {
305            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
306            return;
307        }
308        if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
309        {
310            for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
311            {
312                try
313                {
314                    OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
315                        (inputSystem_->createInputObject(OIS::OISJoyStick, true));
316                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
317                    joySticks_.push_back(stig);
318                    // register our listener in OIS.
319                    stig->setEventCallback(this);
320                }
321                catch (OIS::Exception ex)
322                {
323                    CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n"
324                        << "OIS error message: \"" << ex.eText << "\"" << std::endl;
325                }
326            }
327        }
328        else
329        {
330            //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
331        }
332    }
333
334    /**
335    @brief
336        Sets the size of all the different lists that are dependent on the number
337        of joy stick devices created.
338    @remarks
339        No matter whether there are a mouse and/or keyboard, they will always
340        occupy 2 places in the device number dependent lists.
341    */
342    void InputManager::_configureNumberOfJoySticks()
343    {
344        joySticksSize_ = joySticks_.size();
345        devicesNum_ = 2 + joySticksSize_;
346        joyStickButtonsDown_ .resize(joySticksSize_);
347        povStates_           .resize(joySticksSize_);
348        sliderStates_        .resize(joySticksSize_);
349        joySticksCalibration_.resize(joySticksSize_);
350
351        for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
352        {
353            // reset the calibration with default values
354            for (unsigned int i = 0; i < 24; i++)
355            {
356                joySticksCalibration_[iJoyStick].negativeCoeff[i] = 1.0f/32767.0f;
357                joySticksCalibration_[iJoyStick].positiveCoeff[i] = 1.0f/32768.0f;
358                joySticksCalibration_[iJoyStick].zeroStates[i] = 0;
359            }
360        }
361
362        // state management
363        activeStatesTop_.resize(devicesNum_);
364
365        // inform all states
366        for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
367            it != inputStatesByPriority_.end(); ++it)
368        {
369            it->second->setNumOfJoySticks(joySticksSize_);
370        }
371        // inform master state
372        if (stateMaster_)
373            this->stateMaster_->setNumOfJoySticks(joySticksSize_);
374
375        // inform all JoyStick Device Number Listeners
376        for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
377            it->JoyStickDeviceNumberChanged(joySticksSize_);
378
379    }
380
381    /**
382    @brief
383        Sets the configurable values.
384        This mainly concerns joy stick calibrations.
385    */
386    void InputManager::setConfigValues()
387    {
388        if (joySticksSize_ > 0)
389        {
390            std::vector<double> coeffPos;
391            std::vector<double> coeffNeg;
392            std::vector<int> zero;
393            coeffPos.resize(24);
394            coeffNeg.resize(24);
395            zero.resize(24);
396            for (unsigned int i = 0; i < 24; i++)
397            {
398                coeffPos[i] =  1.0f/32767.0f;
399                coeffNeg[i] =  1.0f/32768.0f;
400                zero[i]     =  0;
401            }
402
403            ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
404            if (!cont)
405            {
406                cont = new ConfigValueContainer(ConfigFileType::Settings, getIdentifier(), getIdentifier()->getName(), "CoeffPos", coeffPos);
407                getIdentifier()->addConfigValueContainer("CoeffPos", cont);
408            }
409            cont->getValue(&coeffPos, this);
410
411            cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
412            if (!cont)
413            {
414                cont = new ConfigValueContainer(ConfigFileType::Settings, getIdentifier(), getIdentifier()->getName(), "CoeffNeg", coeffNeg);
415                getIdentifier()->addConfigValueContainer("CoeffNeg", cont);
416            }
417            cont->getValue(&coeffNeg, this);
418
419            cont = getIdentifier()->getConfigValueContainer("Zero");
420            if (!cont)
421            {
422                cont = new ConfigValueContainer(ConfigFileType::Settings, getIdentifier(), getIdentifier()->getName(), "Zero", zero);
423                getIdentifier()->addConfigValueContainer("Zero", cont);
424            }
425            cont->getValue(&zero, this);
426
427            // copy values to our own variables
428            for (unsigned int i = 0; i < 24; i++)
429            {
430                joySticksCalibration_[0].positiveCoeff[i] = coeffPos[i];
431                joySticksCalibration_[0].negativeCoeff[i] = coeffNeg[i];
432                joySticksCalibration_[0].zeroStates[i]    = zero[i];
433            }
434        }
435    }
436
437
438    // ############################################################
439    // #####                    Destruction                   #####
440    // ##########                                        ##########
441    // ############################################################
442
443    /**
444    @brief
445        Destroys all the created input devices and states.
446    */
447    InputManager::~InputManager()
448    {
449        if (internalState_ != Uninitialised)
450        {
451            try
452            {
453                CCOUT(3) << "Destroying ..." << std::endl;
454
455                // kick all active states 'nicely'
456                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
457                    rit != activeStates_.rend(); ++rit)
458                {
459                    (*rit).second->onLeave();
460                }
461
462                // Destroy calibrator helper handler and state
463                delete keyDetector_;
464                requestDestroyState("calibrator");
465                // Destroy KeyDetector and state
466                delete calibratorCallbackBuffer_;
467                requestDestroyState("detector");
468                // destroy the empty InputState
469                _destroyState(this->stateEmpty_);
470                // destroy the master input state. This might trigger a memory leak
471                // because the user has forgotten to destroy the KeyBinder or any Handler!
472                delete stateMaster_;
473
474                // destroy all user InputStates
475                while (inputStatesByPriority_.size() > 0)
476                    _destroyState((*inputStatesByPriority_.rbegin()).second);
477
478                // destroy the devices
479                _destroyKeyboard();
480                _destroyMouse();
481                _destroyJoySticks();
482
483                OIS::InputManager::destroyInputSystem(inputSystem_);
484
485                CCOUT(3) << "Destroying done." << std::endl;
486            }
487            catch (OIS::Exception& ex)
488            {
489                CCOUT(1) << "An exception has occured while destroying:\n" << ex.what()
490                         << "This could lead to a possible memory/resource leak!" << std::endl;
491            }
492        }
493
494        singletonRef_s = 0;
495    }
496
497    /**
498    @brief
499        Destroys the keyboard and sets it to 0.
500    */
501    void InputManager::_destroyKeyboard()
502    {
503        assert(inputSystem_);
504        if (keyboard_)
505            inputSystem_->destroyInputObject(keyboard_);
506        keyboard_ = 0;
507        CCOUT(4) << "Keyboard destroyed." << std::endl;
508    }
509
510    /**
511    @brief
512        Destroys the mouse and sets it to 0.
513    */
514    void InputManager::_destroyMouse()
515    {
516        assert(inputSystem_);
517        if (mouse_)
518            inputSystem_->destroyInputObject(mouse_);
519        mouse_ = 0;
520        CCOUT(4) << "Mouse destroyed." << std::endl;
521    }
522
523    /**
524    @brief
525        Destroys all the joy sticks and resizes the lists to 0.
526    */
527    void InputManager::_destroyJoySticks()
528    {
529        if (joySticksSize_ > 0)
530        {
531            assert(inputSystem_);
532            for (unsigned int i = 0; i < joySticksSize_; i++)
533                if (joySticks_[i] != 0)
534                    inputSystem_->destroyInputObject(joySticks_[i]);
535
536            joySticks_.clear();
537            // don't use _configureNumberOfJoySticks(), might mess with registered handler if
538            // downgrading from 2 to 1 joystick
539            //_configureNumberOfJoySticks();
540            joySticksSize_ = 0;
541        }
542        CCOUT(4) << "Joy sticks destroyed." << std::endl;
543    }
544
545    /**
546    @brief
547        Removes and destroys an InputState.
548    @return
549        True if state was removed immediately, false if postponed.
550    */
551    void InputManager::_destroyState(InputState* state)
552    {
553        assert(state && !(this->internalState_ & Ticking));
554        std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
555        if (it != this->activeStates_.end())
556        {
557            this->activeStates_.erase(it);
558            _updateActiveStates();
559        }
560        inputStatesByPriority_.erase(state->getPriority());
561        inputStatesByName_.erase(state->getName());
562        delete state;
563    }
564
565    void InputManager::_clearBuffers()
566    {
567        keysDown_.clear();
568        keyboardModifiers_ = 0;
569        mouseButtonsDown_.clear();
570        for (unsigned int i = 0; i < joySticksSize_; ++i)
571        {
572            joyStickButtonsDown_[i].clear();
573            for (int j = 0; j < 4; ++j)
574            {
575                sliderStates_[i].sliderStates[j].x = 0;
576                sliderStates_[i].sliderStates[j].y = 0;
577                povStates_[i][j] = 0;
578            }
579        }
580    }
581
582
583    // ############################################################
584    // #####                     Reloading                    #####
585    // ##########                                        ##########
586    // ############################################################
587
588    /**
589    @brief
590        Public interface. Only reloads immediately if the call stack doesn't
591        include the tick() method.
592    @param joyStickSupport
593        Whether or not to initialise joy sticks as well.
594    */
595    void InputManager::reloadInputSystem(bool joyStickSupport)
596    {
597        if (internalState_ & Ticking)
598        {
599            // We cannot destroy OIS right now, because reload was probably
600            // caused by a user clicking on a GUI item. The backtrace would then
601            // include an OIS method. So it would be a very bad thing to destroy it..
602            internalState_ |= ReloadRequest;
603            // Misuse of internalState_: We can easily store the joyStickSupport bool.
604            // use Uninitialised as 0 value in order to make use of the overloaded |= operator
605            internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
606        }
607        else if (internalState_ & OISReady)
608        {
609            _reload(joyStickSupport);
610        }
611        else
612        {
613            CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or"
614                     << "joy sticks are currently calibrating." << std::endl;
615        }
616    }
617
618    /**
619    @brief
620        Internal reload method. Destroys the OIS devices and loads them again.
621    */
622    void InputManager::_reload(bool joyStickSupport)
623    {
624        try
625        {
626            CCOUT(3) << "Reloading ..." << std::endl;
627
628            // Save mouse clipping size
629            int mouseWidth  = mouse_->getMouseState().width;
630            int mouseHeight = mouse_->getMouseState().height;
631
632            internalState_ &= ~OISReady;
633
634            // destroy the devices
635            _destroyKeyboard();
636            _destroyMouse();
637            _destroyJoySticks();
638
639            OIS::InputManager::destroyInputSystem(inputSystem_);
640            inputSystem_ = 0;
641
642            // clear all buffers containing input information
643            _clearBuffers();
644
645            initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport);
646
647            CCOUT(3) << "Reloading done." << std::endl;
648        }
649        catch (OIS::Exception& ex)
650        {
651            CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl;
652        }
653    }
654
655    // ############################################################
656    // #####                  Runtime Methods                 #####
657    // ##########                                        ##########
658    // ############################################################
659
660    /**
661    @brief
662        Updates the states and the InputState situation.
663    @param dt
664        Delta time
665    */
666    void InputManager::tick(float dt)
667    {
668        if (internalState_ == Uninitialised)
669            return;
670        else if (internalState_ & ReloadRequest)
671        {
672            _reload(internalState_ & JoyStickSupport);
673            internalState_ &= ~ReloadRequest;
674            internalState_ &= ~JoyStickSupport;
675        }
676
677        // check for states to leave
678        if (!stateLeaveRequests_.empty())
679        {
680            for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin();
681                rit != stateLeaveRequests_.rend(); ++rit)
682            {
683                (*rit)->onLeave();
684                // just to be sure that the state actually is registered
685                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
686
687                activeStates_.erase((*rit)->getPriority());
688                _updateActiveStates();
689            }
690            stateLeaveRequests_.clear();
691        }
692
693        // check for states to enter
694        if (!stateEnterRequests_.empty())
695        {
696            for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin();
697                rit != stateEnterRequests_.rend(); ++rit)
698            {
699                // just to be sure that the state actually is registered
700                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
701
702                activeStates_[(*rit)->getPriority()] = (*rit);
703                _updateActiveStates();
704                (*rit)->onEnter();
705            }
706            stateEnterRequests_.clear();
707        }
708
709        // check for states to destroy
710        if (!stateDestroyRequests_.empty())
711        {
712            for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin();
713                rit != stateDestroyRequests_.rend(); ++rit)
714            {
715                _destroyState((*rit));
716            }
717            stateDestroyRequests_.clear();
718        }
719
720        // check whether a state has changed its EMPTY_HANDLER situation
721        bool bUpdateRequired = false;
722        for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
723        {
724            if (it->second->handlersChanged())
725            {
726                it->second->resetHandlersChanged();
727                bUpdateRequired = true;
728            }
729        }
730        if (bUpdateRequired)
731            _updateActiveStates();
732
733        // mark that we capture and distribute input
734        internalState_ |= Ticking;
735
736        // Capture all the input. This calls the event handlers in InputManager.
737        if (keyboard_)
738            keyboard_->capture();
739        if (mouse_)
740            mouse_->capture();
741        for (unsigned  int i = 0; i < joySticksSize_; i++)
742            joySticks_[i]->capture();
743
744        if (!bCalibrating_)
745        {
746            // call all the handlers for the held key events
747            for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
748            {
749                KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
750                activeStatesTop_[Keyboard]->keyHeld(kEvt);
751                stateMaster_->keyHeld(kEvt);
752            }
753
754            // call all the handlers for the held mouse button events
755            for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
756            {
757                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
758                stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);
759            }
760
761            // call all the handlers for the held joy stick button events
762            for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
763                for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
764                {
765                    activeStatesTop_[JoyStick0 + iJoyStick]
766                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
767                    stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
768                }
769
770            // tick the handlers for each active handler
771            for (unsigned int i = 0; i < devicesNum_; ++i)
772            {
773                activeStatesTop_[i]->tickInput(dt, i);
774                if (stateMaster_->isInputDeviceEnabled(i))
775                    stateMaster_->tickInput(dt, i);
776            }
777
778            // tick the handler with a general tick afterwards
779            for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
780                activeStatesTicked_[i]->tickInput(dt);
781            stateMaster_->tickInput(dt);
782        }
783
784        internalState_ &= ~Ticking;
785    }
786
787    /**
788    @brief
789        Updates the currently active states (according to activeStates_) for each device.
790        Also, a list of all active states (no duplicates!) is compiled for the general tick.
791    */
792    void InputManager::_updateActiveStates()
793    {
794        for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
795            for (unsigned int i = 0; i < devicesNum_; ++i)
796                if (it->second->isInputDeviceEnabled(i))
797                    activeStatesTop_[i] = it->second;
798
799        // update tickables (every state will only appear once)
800        // Using a std::set to avoid duplicates
801        std::set<InputState*> tempSet;
802        for (unsigned int i = 0; i < devicesNum_; ++i)
803            tempSet.insert(activeStatesTop_[i]);
804
805        // copy the content of the set back to the actual vector
806        activeStatesTicked_.clear();
807        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
808            activeStatesTicked_.push_back(*it);
809
810        this->mouseButtonsDown_.clear();
811    }
812
813    /**
814    @brief
815        Processes the accumultated data for the joy stick calibration.
816    */
817    void InputManager::_completeCalibration()
818    {
819        for (unsigned int i = 0; i < 24; i++)
820        {
821            // positive coefficient
822            if (marginalsMax_[i] == INT_MIN)
823                marginalsMax_[i] =  32767;
824            // coefficients
825            if (marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i])
826            {
827                joySticksCalibration_[0].positiveCoeff[i]
828                    = 1.0f/(marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]);
829            }
830            else
831                joySticksCalibration_[0].positiveCoeff[i] =  1.0f;
832
833            // config value
834            ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
835            assert(cont);
836            cont->set(i, joySticksCalibration_[0].positiveCoeff[i]);
837
838            // negative coefficient
839            if (marginalsMin_[i] == INT_MAX)
840                marginalsMin_[i] = -32768;
841            // coefficients
842            if (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i])
843            {
844                joySticksCalibration_[0].negativeCoeff[i] = -1.0f
845                    / (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]);
846            }
847            else
848                joySticksCalibration_[0].negativeCoeff[i] =  1.0f;
849            // config value
850            cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
851            assert(cont);
852            cont->set(i, joySticksCalibration_[0].negativeCoeff[i]);
853
854            // zero states
855            if (i < 8)
856            {
857                if (!(i & 1))
858                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abX;
859                else
860                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abY;
861            }
862            else
863            {
864                if (i - 8 < joySticks_[0]->getJoyStickState().mAxes.size())
865                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mAxes[i - 8].abs;
866                else
867                    joySticksCalibration_[0].zeroStates[i] = 0;
868            }
869            // config value
870            cont = getIdentifier()->getConfigValueContainer("Zero");
871            assert(cont);
872            cont->set(i, joySticksCalibration_[0].zeroStates[i]);
873        }
874
875        // restore old input state
876        requestLeaveState("calibrator");
877        bCalibrating_ = false;
878    }
879
880    void InputManager::clearBuffers()
881    {
882        this->keysDown_.clear();
883        this->mouseButtonsDown_.clear();
884        for (unsigned int i = 0; i < this->joySticksSize_; ++i)
885            this->joyStickButtonsDown_[i].clear();
886    }
887
888
889    // ############################################################
890    // #####                    OIS events                    #####
891    // ##########                                        ##########
892    // ############################################################
893
894    // ###### Key Events ######
895
896    /**
897    @brief
898        Event handler for the keyPressed Event.
899    @param e
900        Event information
901    */
902    bool InputManager::keyPressed(const OIS::KeyEvent &e)
903    {
904        // check whether the key already is in the list (can happen when focus was lost)
905        unsigned int iKey = 0;
906        while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key)
907            iKey++;
908        if (iKey == keysDown_.size())
909            keysDown_.push_back(Key(e));
910        else
911        {
912            // This happens when XAutoRepeat is set under linux. The KeyPressed event gets then sent
913            // continuously.
914            return true;
915        }
916
917        // update modifiers
918        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
919            keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
920        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
921            keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
922        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
923            keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
924
925        KeyEvent kEvt(e, keyboardModifiers_);
926        activeStatesTop_[Keyboard]->keyPressed(kEvt);
927        stateMaster_->keyPressed(kEvt);
928
929        return true;
930    }
931
932    /**
933    @brief
934        Event handler for the keyReleased Event.
935    @param e
936        Event information
937    */
938    bool InputManager::keyReleased(const OIS::KeyEvent &e)
939    {
940        // remove the key from the keysDown_ list
941        for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
942        {
943            if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key)
944            {
945                keysDown_.erase(keysDown_.begin() + iKey);
946                break;
947            }
948        }
949
950        // update modifiers
951        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
952            keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
953        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
954            keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
955        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
956            keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
957
958        KeyEvent kEvt(e, keyboardModifiers_);
959        activeStatesTop_[Keyboard]->keyReleased(kEvt);
960        stateMaster_->keyReleased(kEvt);
961
962        return true;
963    }
964
965
966    // ###### Mouse Events ######
967
968    /**
969    @brief
970        Event handler for the mouseMoved Event.
971    @param e
972        Event information
973    */
974    bool InputManager::mouseMoved(const OIS::MouseEvent &e)
975    {
976        // check for actual moved event
977        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
978        {
979            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
980            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
981            IntVector2 clippingSize(e.state.width, e.state.height);
982            activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);
983            stateMaster_->mouseMoved(abs, rel, clippingSize);
984        }
985
986        // check for mouse scrolled event
987        if (e.state.Z.rel != 0)
988        {
989            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
990            stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
991        }
992
993        return true;
994    }
995
996    /**
997    @brief
998        Event handler for the mousePressed Event.
999    @param e
1000        Event information
1001    @param id
1002        The ID of the mouse button
1003    */
1004    bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
1005    {
1006        // check whether the button already is in the list (can happen when focus was lost)
1007        unsigned int iButton = 0;
1008        while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id)
1009            iButton++;
1010        if (iButton == mouseButtonsDown_.size())
1011            mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
1012
1013        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
1014        stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);
1015
1016        return true;
1017    }
1018
1019    /**
1020    @brief
1021        Event handler for the mouseReleased Event.
1022    @param e
1023        Event information
1024    @param id
1025        The ID of the mouse button
1026    */
1027    bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
1028    {
1029        // remove the button from the keysDown_ list
1030        for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
1031        {
1032            if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id)
1033            {
1034                mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
1035                break;
1036            }
1037        }
1038
1039        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
1040        stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);
1041
1042        return true;
1043    }
1044
1045
1046    // ###### Joy Stick Events ######
1047
1048    /**
1049    @brief
1050        Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent
1051    */
1052    inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
1053    {
1054        // use the device to identify which one called the method
1055        OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
1056        unsigned int iJoyStick = 0;
1057        while (joySticks_[iJoyStick] != joyStick)
1058            iJoyStick++;
1059        // assert: Unknown joystick fired an event.
1060        assert(iJoyStick != joySticksSize_);
1061        return iJoyStick;
1062    }
1063
1064    bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
1065    {
1066        unsigned int iJoyStick = _getJoystick(arg);
1067
1068        // check whether the button already is in the list (can happen when focus was lost)
1069        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
1070        unsigned int iButton = 0;
1071        while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
1072            iButton++;
1073        if (iButton == buttonsDown.size())
1074            buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
1075
1076        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
1077        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
1078
1079        return true;
1080    }
1081
1082    bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
1083    {
1084        unsigned int iJoyStick = _getJoystick(arg);
1085
1086        // remove the button from the joyStickButtonsDown_ list
1087        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
1088        for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
1089        {
1090            if (buttonsDown[iButton] == button)
1091            {
1092                buttonsDown.erase(buttonsDown.begin() + iButton);
1093                break;
1094            }
1095        }
1096
1097        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
1098        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
1099
1100        return true;
1101    }
1102
1103    /**
1104    @brief
1105        Calls the states for a particular axis with our enumeration.
1106        Used by OIS sliders and OIS axes.
1107    */
1108    void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
1109    {
1110        if (bCalibrating_)
1111        {
1112            if (value > marginalsMax_[axis])
1113                marginalsMax_[axis] = value;
1114            if (value < marginalsMin_[axis])
1115                marginalsMin_[axis] = value;
1116        }
1117        else
1118        {
1119            float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis];
1120            if (fValue > 0.0f)
1121                fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis];
1122            else
1123                fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis];
1124
1125            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
1126            stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);
1127        }
1128    }
1129
1130    bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
1131    {
1132        unsigned int iJoyStick = _getJoystick(arg);
1133
1134        // keep in mind that the first 8 axes are reserved for the sliders
1135        _fireAxis(iJoyStick, axis + sliderAxes, arg.state.mAxes[axis].abs);
1136
1137        return true;
1138    }
1139
1140    bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
1141    {
1142        unsigned int iJoyStick = _getJoystick(arg);
1143
1144        if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
1145            _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
1146        else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
1147            _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
1148
1149        return true;
1150    }
1151
1152    bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
1153    {
1154        unsigned int iJoyStick = _getJoystick(arg);
1155
1156        // translate the POV into 8 simple buttons
1157
1158        int lastState = povStates_[iJoyStick][id];
1159        if (lastState & OIS::Pov::North)
1160            buttonReleased(arg, 32 + id * 4 + 0);
1161        if (lastState & OIS::Pov::South)
1162            buttonReleased(arg, 32 + id * 4 + 1);
1163        if (lastState & OIS::Pov::East)
1164            buttonReleased(arg, 32 + id * 4 + 2);
1165        if (lastState & OIS::Pov::West)
1166            buttonReleased(arg, 32 + id * 4 + 3);
1167
1168        povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
1169
1170        int currentState = povStates_[iJoyStick][id];
1171        if (currentState & OIS::Pov::North)
1172            buttonPressed(arg, 32 + id * 4 + 0);
1173        if (currentState & OIS::Pov::South)
1174            buttonPressed(arg, 32 + id * 4 + 1);
1175        if (currentState & OIS::Pov::East)
1176            buttonPressed(arg, 32 + id * 4 + 2);
1177        if (currentState & OIS::Pov::West)
1178            buttonPressed(arg, 32 + id * 4 + 3);
1179
1180        return true;
1181    }
1182
1183
1184    // ############################################################
1185    // #####         Other Public Interface Methods           #####
1186    // ##########                                        ##########
1187    // ############################################################
1188
1189    /**
1190    @brief
1191        Adjusts the mouse window metrics.
1192        This method has to be called every time the size of the window changes.
1193    @param width
1194        The new width of the render window
1195    @param^height
1196        The new height of the render window
1197    */
1198    void InputManager::setWindowExtents(const int width, const int height)
1199    {
1200        if (mouse_)
1201        {
1202            // Set mouse region (if window resizes, we should alter this to reflect as well)
1203            mouse_->getMouseState().width  = width;
1204            mouse_->getMouseState().height = height;
1205        }
1206    }
1207
1208    /**
1209    @brief
1210        Sets the the name of the command used by the KeyDetector as callback.
1211    @param command
1212        Command name as string
1213    */
1214    void InputManager::setKeyDetectorCallback(const std::string& command)
1215    {
1216        this->keyDetector_->setCallbackCommand(command);
1217    }
1218
1219    // ###### InputStates ######
1220
1221    /**
1222    @brief
1223        Adds a new key handler.
1224    @param handler
1225        Pointer to the handler object.
1226    @param name
1227        Unique name of the handler.
1228    @param priority
1229        Unique integer number. Higher means more prioritised.
1230    @return
1231        True if added, false if name or priority already existed.
1232    */
1233    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
1234    {
1235        if (name == "")
1236            return false;
1237        if (!state)
1238            return false;
1239        if (inputStatesByName_.find(name) == inputStatesByName_.end())
1240        {
1241            if (inputStatesByPriority_.find(priority)
1242                == inputStatesByPriority_.end())
1243            {
1244                inputStatesByName_[name] = state;
1245                inputStatesByPriority_[priority] = state;
1246                state->setNumOfJoySticks(numberOfJoySticks());
1247                state->setName(name);
1248                state->setPriority(priority);
1249                return true;
1250            }
1251            else
1252            {
1253                COUT(2) << "Warning: Could not add an InputState with the same priority '"
1254                    << priority << "'." << std::endl;
1255                return false;
1256            }
1257        }
1258        else
1259        {
1260            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
1261            return false;
1262        }
1263    }
1264
1265    /**
1266    @brief
1267        Removes and destroys an input state internally.
1268    @param name
1269        Name of the handler.
1270    @return
1271        True if removal was successful, false if name was not found.
1272    @remarks
1273        You can't remove the internal states "empty", "calibrator" and "detector".
1274        The removal process is being postponed if InputManager::tick() is currently running.
1275    */
1276    bool InputManager::requestDestroyState(const std::string& name)
1277    {
1278        if (name == "empty")
1279        {
1280            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
1281            return false;
1282        }
1283        std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
1284        if (it != inputStatesByName_.end())
1285        {
1286            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
1287            {
1288                // The state is still active. We have to postpone
1289                stateLeaveRequests_.insert(it->second);
1290                stateDestroyRequests_.insert(it->second);
1291            }
1292            else if (this->internalState_ & Ticking)
1293            {
1294                // cannot remove state while ticking
1295                stateDestroyRequests_.insert(it->second);
1296            }
1297            else
1298                _destroyState(it->second);
1299
1300            return true;
1301        }
1302        return false;
1303    }
1304
1305    /**
1306    @brief
1307        Returns the pointer to the requested InputState.
1308    @param name
1309        Unique name of the state.
1310    @return
1311        Pointer to the instance, 0 if name was not found.
1312    */
1313    InputState* InputManager::getState(const std::string& name)
1314    {
1315        std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
1316        if (it != inputStatesByName_.end())
1317            return it->second;
1318        else
1319            return 0;
1320    }
1321
1322    /**
1323    @brief
1324        Returns the current input state (there might be others active too!)
1325    @return
1326        The current highest prioritised active input state.
1327    */
1328    InputState* InputManager::getCurrentState()
1329    {
1330        return (*activeStates_.rbegin()).second;
1331    }
1332
1333    /**
1334    @brief
1335        Activates a specific input state.
1336        It might not be really activated if the priority is too low!
1337    @param name
1338        Unique name of the state.
1339    @return
1340        False if name was not found, true otherwise.
1341    */
1342    bool InputManager::requestEnterState(const std::string& name)
1343    {
1344        // get pointer from the map with all stored handlers
1345        std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
1346        if (it != inputStatesByName_.end())
1347        {
1348            // exists
1349            if (activeStates_.find(it->second->getPriority()) == activeStates_.end())
1350            {
1351                // not active
1352                if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end())
1353                {
1354                    // not scheduled for destruction
1355                    // set prevents a state being added multiple times
1356                    stateEnterRequests_.insert(it->second);
1357                    return true;
1358                }
1359            }
1360        }
1361        return false;
1362    }
1363
1364    /**
1365    @brief
1366        Deactivates a specific input state.
1367    @param name
1368        Unique name of the state.
1369    @return
1370        False if name was not found, true otherwise.
1371    */
1372    bool InputManager::requestLeaveState(const std::string& name)
1373    {
1374        // get pointer from the map with all stored handlers
1375        std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
1376        if (it != inputStatesByName_.end())
1377        {
1378            // exists
1379            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
1380            {
1381                // active
1382                stateLeaveRequests_.insert(it->second);
1383                return true;
1384            }
1385        }
1386        return false;
1387    }
1388
1389
1390    // ############################################################
1391    // #####                Console Commands                  #####
1392    // ##########                                        ##########
1393    // ############################################################
1394
1395    /**
1396    @brief
1397        Starts joy stick calibration.
1398    */
1399    void InputManager::calibrate()
1400    {
1401        getInstance().bCalibrating_ = true;
1402        getInstance().requestEnterState("calibrator");
1403    }
1404
1405    /**
1406    @brief
1407        Reloads the input system
1408    */
1409    void InputManager::reload(bool joyStickSupport)
1410    {
1411        getInstance().reloadInputSystem(joyStickSupport);
1412    }
1413}
Note: See TracBrowser for help on using the repository browser.