Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 10, 2008, 1:37:36 AM (16 years ago)
Author:
rgrieder
Message:

merged gui back to trunk.
update the media repository!

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/core/input/InputManager.cc

    r1747 r1755  
    2828
    2929/**
    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.
    3334 */
    3435
    3536#include "InputManager.h"
    3637
    37 #include <limits.h>
     38#include <climits>
     39#include <cassert>
     40
     41#include "ois/OISException.h"
     42#include "ois/OISInputManager.h"
    3843
    3944#include "core/CoreIncludes.h"
    4045#include "core/ConfigValueIncludes.h"
     46#include "core/Exception.h"
    4147#include "core/CommandExecutor.h"
    4248#include "core/ConsoleCommand.h"
    43 #include "core/Shell.h"               // hack!
    4449#include "util/Debug.h"
    4550
     
    4853#include "KeyDetector.h"
    4954#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"
    5358
    5459namespace orxonox
    5560{
    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")));
    120152#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")));
    122154#endif
    123155
    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        }
    1341193        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        }
    2111252        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        }
    2481277        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    }
    15591335}
Note: See TracChangeset for help on using the changeset viewer.