Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 20, 2008, 7:49:26 PM (16 years ago)
Author:
rgrieder
Message:

merged input branch into gui test branch (was about time)
svn save (it's still a mess and CMLs haven't been updated)
I'll have to create a special project to create the tolua_bind files for tolua itself anyway..

Location:
code/branches/gui
Files:
18 edited
5 copied

Legend:

Unmodified
Added
Removed
  • code/branches/gui

  • code/branches/gui/src/core/input/Button.cc

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "Button.h"
     
    4445namespace orxonox
    4546{
    46   void Button::clear()
    47   {
    48     for (unsigned int j = 0; j < 3; j++)
    49     {
    50       if (nCommands_[j])
    51       {
    52         // delete all commands and the command pointer array
    53         for (unsigned int i = 0; i < nCommands_[j]; i++)
    54           delete commands_[j][i];
    55         delete[] commands_[j];
    56         commands_[j] = 0;
    57         nCommands_[j] = 0;
    58       }
    59       else
    60       {
    61         commands_[j] = 0;
    62       }
    63     }
    64   }
    65 
    66   void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
    67   {
    68     if (isEmpty(bindingString_))
    69     {
    70       clear();
    71       return;
    72     }
    73 
    74     // use std::vector for a temporary dynamic array
    75     std::vector<BaseCommand*> commands[3];
    76 
    77 
    78     // separate the commands
    79     SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
    80         '\\', false, '"', false, '(', ')', false, '\0');
    81 
    82     for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
    83     {
    84       if (commandStrings[iCommand] != "")
    85       {
    86         SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     47    void Button::clear()
     48    {
     49        for (unsigned int j = 0; j < 3; j++)
     50        {
     51            if (nCommands_[j])
     52            {
     53                // delete all commands and the command pointer array
     54                for (unsigned int i = 0; i < nCommands_[j]; i++)
     55                    delete commands_[j][i];
     56                delete[] commands_[j];
     57                commands_[j] = 0;
     58                nCommands_[j] = 0;
     59            }
     60            else
     61            {
     62                commands_[j] = 0;
     63            }
     64        }
     65    }
     66
     67    void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
     68    {
     69        if (isEmpty(bindingString_))
     70        {
     71            clear();
     72            return;
     73        }
     74
     75        // use std::vector for a temporary dynamic array
     76        std::vector<BaseCommand*> commands[3];
     77
     78
     79        // separate the commands
     80        SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
    8781            '\\', false, '"', false, '(', ')', false, '\0');
    8882
    89         unsigned int iToken = 0;
    90 
    91         // for real axes, we can feed a ButtonThreshold argument as entire command
    92         if (getLowercase(tokens[0]) == "buttonthreshold")
    93         {
    94           if (tokens.size() == 1)
    95             continue;
    96           // may fail, but doesn't matter
    97           convertValue(&buttonThreshold_, tokens[1]);
    98           continue;
    99         }
    100 
    101         // first argument can be OnPress, OnHold OnRelease or nothing
    102         KeybindMode::Enum mode = KeybindMode::None;
    103         if (getLowercase(tokens[iToken]) == "onpress")
    104           mode = KeybindMode::OnPress,   iToken++;
    105         if (getLowercase(tokens[iToken]) == "onrelease")
    106           mode = KeybindMode::OnRelease, iToken++;
    107         if (getLowercase(tokens[iToken]) == "onhold")
    108           mode = KeybindMode::OnHold,    iToken++;
    109 
    110         if (iToken == tokens.size())
    111           continue;
    112 
    113         // second argument can be the amplitude for the case it as an axis command
    114         // default amplitude is 1.0f
    115         float paramModifier = 1.0f;
    116         if (getLowercase(tokens[iToken]) == "scale")
    117         {
    118           iToken++;
    119           if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
    120           {
    121             COUT(2) << "Error while parsing key binding " << name_
    122                 << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
    123             if (iToken == tokens.size())
    124               continue;
    125           }
    126           iToken++;
    127         }
    128 
    129         // no more arguments expected except for the actual command
    130         if (iToken == tokens.size())
    131           continue;
    132 
    133         std::string commandStr;
    134         while (iToken != tokens.size())
    135           commandStr += tokens[iToken++] + " ";
    136 
    137         // evaluate the command
    138         CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
    139         if (!eval.isValid())
    140           continue;
    141 
    142         // check for param command
    143         int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
    144         if (paramIndex >= 0)
    145         {
    146           // parameter supported command
    147           ParamCommand* cmd = new ParamCommand();
    148           cmd->paramModifier_ = paramModifier;
    149           cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
    150 
    151           // add command to the buffer if not yet existing
    152           for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
    153           {
    154             if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
    155                 == getLowercase(commandStr))
    156             {
    157               // already in list
    158               cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
    159               break;
    160             }
    161           }
    162           if (cmd->paramCommand_ == 0)
    163           {
    164             cmd->paramCommand_ = new BufferedParamCommand();
    165             paramCommandBuffer.push_back(cmd->paramCommand_);
    166             cmd->paramCommand_->evaluation_ = eval;
    167             cmd->paramCommand_->paramIndex_ = paramIndex;
    168           }
    169 
    170 
    171           // we don't know whether this is an actual axis or just a button
    172           if (mode == KeybindMode::None)
    173           {
    174             if (!addParamCommand(cmd))
    175             {
    176               mode = eval.getConsoleCommand()->getKeybindMode();
    177               commands[mode].push_back(cmd);
    178             }
    179           }
     83        for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
     84        {
     85            if (commandStrings[iCommand] != "")
     86            {
     87                SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     88                    '\\', false, '"', false, '(', ')', false, '\0');
     89
     90                KeybindMode::Enum mode = KeybindMode::None;
     91                float paramModifier = 1.0f;
     92                std::string commandStr = "";
     93
     94                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
     95                {
     96                    std::string token = getLowercase(tokens[iToken]);
     97
     98                    if (token == "onpress")
     99                        mode = KeybindMode::OnPress;
     100                    else if (token == "onrelease")
     101                        mode = KeybindMode::OnRelease;
     102                    else if (token == "onhold")
     103                        mode = KeybindMode::OnHold;
     104                    else if (token == "buttonthreshold")
     105                    {
     106                        // for real axes, we can feed a ButtonThreshold argument
     107                        ++iToken;
     108                        if (iToken == tokens.size())
     109                            continue;
     110                        // may fail, but doesn't matter (default value already set)
     111                        if (!convertValue(&buttonThreshold_, tokens[iToken + 1]))
     112                            parseError("Could not parse 'ButtonThreshold' argument. \
     113                                Switching to default value.", true);
     114                    }
     115                    else if (token == "scale")
     116                    {
     117                        ++iToken;
     118                        if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
     119                            parseError("Could not parse 'scale' argument. Switching to default value.", true);
     120                    }
     121                    else
     122                    {
     123                        // no input related argument
     124                        // we interpret everything from here as a command string
     125                        while (iToken != tokens.size())
     126                            commandStr += tokens[iToken++] + " ";
     127                    }
     128                }
     129
     130                if (commandStr == "")
     131                {
     132                    parseError("No command string given.", false);
     133                    continue;
     134                }
     135
     136                // evaluate the command
     137                CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
     138                if (!eval.isValid())
     139                {
     140                    parseError("Command evaluation failed.", true);
     141                    continue;
     142                }
     143
     144                // check for param command
     145                int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
     146                if (paramIndex >= 0)
     147                {
     148                    // parameter supported command
     149                    ParamCommand* cmd = new ParamCommand();
     150                    cmd->paramModifier_ = paramModifier;
     151                    cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
     152
     153                    // add command to the buffer if not yet existing
     154                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
     155                    {
     156                        if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
     157                            == getLowercase(commandStr))
     158                        {
     159                            // already in list
     160                            cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
     161                            break;
     162                        }
     163                    }
     164                    if (cmd->paramCommand_ == 0)
     165                    {
     166                        cmd->paramCommand_ = new BufferedParamCommand();
     167                        paramCommandBuffer.push_back(cmd->paramCommand_);
     168                        cmd->paramCommand_->evaluation_ = eval;
     169                        cmd->paramCommand_->paramIndex_ = paramIndex;
     170                    }
     171
     172
     173                    // we don't know whether this is an actual axis or just a button
     174                    if (mode == KeybindMode::None)
     175                    {
     176                        if (!addParamCommand(cmd))
     177                        {
     178                            mode = eval.getConsoleCommand()->getKeybindMode();
     179                            commands[mode].push_back(cmd);
     180                        }
     181                    }
     182                }
     183                else
     184                {
     185                    SimpleCommand* cmd = new SimpleCommand();
     186                    cmd->evaluation_ = eval;
     187
     188                    if (mode == KeybindMode::None)
     189                        mode = eval.getConsoleCommand()->getKeybindMode();
     190
     191                    commands[mode].push_back(cmd);
     192                }
     193            }
     194        }
     195
     196        for (unsigned int j = 0; j < 3; j++)
     197        {
     198            nCommands_[j] = commands[j].size();
     199            if (nCommands_[j])
     200            {
     201                commands_[j] = new BaseCommand*[nCommands_[j]];
     202                for (unsigned int i = 0; i < commands[j].size(); i++)
     203                    commands_[j][i] = commands[j][i];
     204            }
     205            else
     206                commands_[j] = 0;
     207        }
     208    }
     209
     210    bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
     211    {
     212        // execute all the parsed commands in the string
     213        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
     214            commands_[mode][iCommand]->execute(abs, rel);
     215        return true;
     216    }
     217
     218    inline void Button::parseError(std::string message, bool serious)
     219    {
     220        if (serious)
     221        {
     222            COUT(2) << "Error while parsing binding for button/axis" << this->name_ << ". "
     223                << message << std::endl;
    180224        }
    181225        else
    182226        {
    183           SimpleCommand* cmd = new SimpleCommand();
    184           cmd->evaluation_ = eval;
    185 
    186           if (mode == KeybindMode::None)
    187             mode = eval.getConsoleCommand()->getKeybindMode();
    188 
    189           commands[mode].push_back(cmd);
    190         }
    191       }
    192     }
    193 
    194     for (unsigned int j = 0; j < 3; j++)
    195     {
    196       nCommands_[j] = commands[j].size();
    197       if (nCommands_[j])
    198       {
    199         commands_[j] = new BaseCommand*[nCommands_[j]];
    200         for (unsigned int i = 0; i < commands[j].size(); i++)
    201           commands_[j][i] = commands[j][i];
    202       }
    203       else
    204         commands_[j] = 0;
    205     }
    206   }
    207 
    208   bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
    209   {
    210     // execute all the parsed commands in the string
    211     for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
    212       commands_[mode][iCommand]->execute(abs, rel);
    213     return true;
    214   }
     227            COUT(3) << "Warning while parsing binding for button/axis" << this->name_ << ". "
     228                << message << std::endl;
     229        }
     230    }
    215231}
  • code/branches/gui/src/core/input/Button.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _Button_H__
     
    4243namespace orxonox
    4344{
    44   class _CoreExport Button
    45   {
    46   public:
    47     Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }
    48     virtual ~Button() { clear(); }
    49     virtual void clear();
    50     virtual bool addParamCommand(ParamCommand* command) { return false; }
    51     void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
    52     bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
     45    class _CoreExport Button
     46    {
     47    public:
     48        Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }
     49        virtual ~Button() { clear(); }
     50        virtual void clear();
     51        virtual bool addParamCommand(ParamCommand* command) { return false; }
     52        void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
     53        bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
    5354
    54     //! The configured string value
    55     std::string bindingString_;
    56     //! Name of the trigger as strings
    57     std::string name_;
    58     //! Basic commands for OnPress, OnHold and OnRelease
    59     BaseCommand** commands_[3];
    60     //! Number of basic commands
    61     unsigned int nCommands_[3];
    62     //! Says how much it takes for an analog axis to trigger a button
    63     //! Note: This variable is here to have only one parse() function.
    64     float buttonThreshold_;
    65   };
     55        //! The configured string value
     56        std::string bindingString_;
     57        //! Name of the trigger as strings
     58        std::string name_;
     59        //! Basic commands for OnPress, OnHold and OnRelease
     60        BaseCommand** commands_[3];
     61        //! Number of basic commands
     62        unsigned int nCommands_[3];
     63        //! Says how much it takes for an analog axis to trigger a button
     64        //! Note: This variable is here to have only one parse() function.
     65        float buttonThreshold_;
     66
     67    private:
     68        void parseError(std::string message, bool serious);
     69    };
    6670}
    6771
  • code/branches/gui/src/core/input/CalibratorCallback.cc

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "CalibratorCallback.h"
     
    3738namespace orxonox
    3839{
    39   void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt)
    40   {
    41     if (evt.key == KeyCode::Return)
     40    void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt)
    4241    {
    43       InputManager::setInputState(InputManager::IS_NOCALIBRATE);
     42        if (evt.key == KeyCode::Return)
     43        {
     44            //InputManager::setInputState(InputManager::IS_NOCALIBRATE);
     45        }
    4446    }
    45   }
    4647}
  • code/branches/gui/src/core/input/CalibratorCallback.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _CalibratorCallback_H__
     
    3637
    3738#include "core/CorePrereqs.h"
    38 
    3939#include "InputInterfaces.h"
    4040
    4141namespace orxonox
    4242{
    43   class _CoreExport CalibratorCallback : public KeyHandler
    44   {
    45   public:
    46     CalibratorCallback() {}
    47     ~CalibratorCallback() {}
     43    class _CoreExport CalibratorCallback : public KeyHandler
     44    {
     45    public:
     46        CalibratorCallback()  { }
     47        ~CalibratorCallback() { }
    4848
    49   private:
    50     void keyPressed (const KeyEvent& evt);
    51     void keyReleased(const KeyEvent& evt) {}
    52     void keyHeld    (const KeyEvent& evt) {}
     49    private:
     50        void keyPressed (const KeyEvent& evt);
     51        void keyReleased(const KeyEvent& evt) { }
     52        void keyHeld    (const KeyEvent& evt) { }
    5353
    54     void tickInput(float dt, const HandlerState &state) { }
    55   };
     54        void tickInput(float dt) { }
     55    };
    5656}
    5757
  • code/branches/gui/src/core/input/HalfAxis.cc

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "HalfAxis.h"
     
    3839namespace orxonox
    3940{
    40   void HalfAxis::clear()
    41   {
    42     Button::clear();
    43     if (nParamCommands_)
     41    void HalfAxis::clear()
    4442    {
    45       // delete all commands and the command pointer array
    46       for (unsigned int i = 0; i < nParamCommands_; i++)
    47         delete paramCommands_[i];
    48       delete[] paramCommands_;
    49       nParamCommands_ = 0;
     43        Button::clear();
     44        if (nParamCommands_)
     45        {
     46            // delete all commands and the command pointer array
     47            for (unsigned int i = 0; i < nParamCommands_; i++)
     48                delete paramCommands_[i];
     49            delete[] paramCommands_;
     50            nParamCommands_ = 0;
     51        }
     52        else
     53        {
     54            nParamCommands_ = 0; nParamCommands_ = 0;
     55        }
    5056    }
    51     else
     57
     58    bool HalfAxis::addParamCommand(ParamCommand* command)
    5259    {
    53       nParamCommands_ = 0; nParamCommands_ = 0;
     60        ParamCommand** cmds = paramCommands_;
     61        paramCommands_ = new ParamCommand*[++nParamCommands_];
     62        unsigned int i;
     63        for (i = 0; i < nParamCommands_ - 1; i++)
     64            paramCommands_[i] = cmds[i];
     65        paramCommands_[i] = command;
     66        if (nParamCommands_ > 1)
     67            delete[] cmds;
     68        return true;
    5469    }
    55   }
    5670
    57   bool HalfAxis::addParamCommand(ParamCommand* command)
    58   {
    59     ParamCommand** cmds = paramCommands_;
    60     paramCommands_ = new ParamCommand*[++nParamCommands_];
    61     unsigned int i;
    62     for (i = 0; i < nParamCommands_ - 1; i++)
    63       paramCommands_[i] = cmds[i];
    64     paramCommands_[i] = command;
    65     if (nParamCommands_ > 1)
    66       delete[] cmds;
    67     return true;
    68   }
    69 
    70   bool HalfAxis::execute()
    71   {
    72     bool success = true;
    73     for (unsigned int i = 0; i < nParamCommands_; i++)
    74       success = success && paramCommands_[i]->execute(absVal_, relVal_);
    75     return success;
    76   }
     71    bool HalfAxis::execute()
     72    {
     73        bool success = true;
     74        for (unsigned int i = 0; i < nParamCommands_; i++)
     75            success = success && paramCommands_[i]->execute(absVal_, relVal_);
     76        return success;
     77    }
    7778}
  • code/branches/gui/src/core/input/HalfAxis.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _HalfAxis_H__
     
    4041namespace orxonox
    4142{
    42   class _CoreExport HalfAxis : public Button
    43   {
    44   public:
    45     HalfAxis() : relVal_(0.0f), absVal_(0.0f), paramCommands_(0), nParamCommands_(0),
    46                  wasDown_(false), hasChanged_(false) { }
    47     using Button::execute;
    48     bool execute();
    49     bool addParamCommand(ParamCommand* command);
    50     void clear();
     43    class _CoreExport HalfAxis : public Button
     44    {
     45    public:
     46        HalfAxis()
     47            : relVal_(0.0f)
     48            , absVal_(0.0f)
     49            , paramCommands_(0)
     50            , nParamCommands_(0)
     51            , wasDown_(false)
     52            , hasChanged_(false)
     53        { }
     54        using Button::execute;
     55        bool execute();
     56        bool addParamCommand(ParamCommand* command);
     57        void clear();
    5158
    52     // axis related
    53     float relVal_;
    54     float absVal_;
    55     ParamCommand** paramCommands_;
    56     unsigned int nParamCommands_;
     59        // axis related
     60        float relVal_;
     61        float absVal_;
     62        ParamCommand** paramCommands_;
     63        unsigned int nParamCommands_;
    5764
    58     // button related
    59     bool wasDown_;
    60     bool hasChanged_;
    61   };
     65        // button related
     66        bool wasDown_;
     67        bool hasChanged_;
     68    };
    6269}
    6370
  • code/branches/gui/src/core/input/InputBuffer.cc

    r1535 r1638  
    220220        @param dt Delta time
    221221    */
    222     void InputBuffer::tickInput(float dt, const HandlerState& state)
     222    void InputBuffer::tickInput(float dt)
    223223    {
    224224        timeSinceKeyPressed_ += dt;
  • code/branches/gui/src/core/input/InputBuffer.h

    r1535 r1638  
    170170            void processKey (const KeyEvent &e);
    171171
    172             void tickInput(float dt, const HandlerState& state);
     172            void tickInput(float dt);
     173            void tickInput(float dt, int device) { }
    173174
    174175            std::string buffer_;
  • code/branches/gui/src/core/input/InputCommands.cc

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "InputCommands.h"
     
    3738namespace orxonox
    3839{
    39   // ###############################
    40   // ###  BufferedParamCommand   ###
    41   // ###############################
     40    // ###############################
     41    // ###  BufferedParamCommand   ###
     42    // ###############################
    4243
    43   /**
    44   * Executes a buffered command. This is used for commands with additional
    45   * parameters.
    46   * @return True if command execution was successful or value was zero.
    47   */
    48   bool BufferedParamCommand::execute()
    49   {
    50     if (nValuesAdded_)
     44    /**
     45    @brief
     46        Executes a buffered command. This is used for commands with additional
     47        parameters.
     48    @return
     49        True if command execution was successful or value was zero.
     50    */
     51    bool BufferedParamCommand::execute()
    5152    {
    52       BufferedParamCommand& cmd = *this;
    53       cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
    54       // reset
    55       cmd.nValuesAdded_ = 0;
    56       cmd.value_ = 0;
    57       return cmd.evaluation_.execute();
     53        if (nValuesAdded_)
     54        {
     55            BufferedParamCommand& cmd = *this;
     56            cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
     57            // reset
     58            cmd.nValuesAdded_ = 0;
     59            cmd.value_ = 0;
     60            return cmd.evaluation_.execute();
     61        }
     62        else
     63            return true;
    5864    }
    59     else
    60       return true;
    61   }
    6265
    63   // ###############################
    64   // #####    SimpleCommand    #####
    65   // ###############################
     66    // ###############################
     67    // #####    SimpleCommand    #####
     68    // ###############################
    6669
    67   /**
    68   * Executes a simple command with no additional paramters.
    69   * @return True if command execution was successful, false otherwise.
    70   */
    71   bool SimpleCommand::execute(float abs, float rel)
    72   {
    73     return evaluation_.execute();
    74   }
     70    /**
     71    @brief
     72        Executes a simple command with no additional paramters.
     73    @return
     74        True if command execution was successful, false otherwise.
     75    */
     76    bool SimpleCommand::execute(float abs, float rel)
     77    {
     78        return evaluation_.execute();
     79    }
    7580
    76   // ###############################
    77   // #####    ParamCommand     #####
    78   // ###############################
     81    // ###############################
     82    // #####    ParamCommand     #####
     83    // ###############################
    7984
    80   /**
    81   * Executes a parameter command. The commmand string is not directly executed,
    82   * but instead stored in a buffer list so that values can be combined.
    83   * @return Always true.
    84   */
    85   bool ParamCommand::execute(float abs, float rel)
    86   {
    87     BufferedParamCommand& cmd = *paramCommand_;
    88     // command has an additional parameter
    89     if (bRelative_)
     85    /**
     86    @brief
     87        Executes a parameter command. The commmand string is not directly executed,
     88        but instead stored in a buffer list so that values can be combined.
     89    @return
     90        Always true.
     91    */
     92    bool ParamCommand::execute(float abs, float rel)
    9093    {
    91       if (rel != 0.0f)
    92       {
    93         // we have to calculate a relative movement.
    94         // paramModifier_ says how much one keystroke is
    95         cmd.value_ += paramModifier_ * rel;
    96       }
     94        BufferedParamCommand& cmd = *paramCommand_;
     95        // command has an additional parameter
     96        if (bRelative_)
     97        {
     98            if (rel != 0.0f)
     99            {
     100                // we have to calculate a relative movement.
     101                // paramModifier_ says how much one keystroke is
     102                cmd.value_ += paramModifier_ * rel;
     103            }
     104        }
     105        else if (abs != 0.0f)
     106        {
     107            // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
     108            // and normally this is caught in tickInput(), but that threshold cannot be to high
     109            // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
     110            // Someone only uses buttons with an active joystick. The joy stick value could then
     111            // be 0.05 for instance and the the key value 1. Without handling the problem, the final
     112            // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
     113            float absQ = abs * abs;
     114            float valueQ = cmd.value_ * cmd.value_;
     115            if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
     116            {
     117                cmd.value_ = abs * paramModifier_;
     118                cmd.nValuesAdded_ = 1;
     119            }
     120            else if (absQ * 50.0f < valueQ)
     121            {
     122                // abs is too small, we just don't do anything
     123            }
     124            else
     125            {
     126                // we have to calculate the absolute position of the axis.
     127                // Since there might be another axis that is affected, we have to wait and
     128                // store the result in a temporary place
     129                cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
     130            }
     131        }
     132        return true;
    97133    }
    98     else if (abs != 0.0f)
    99     {
    100       // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
    101       // and normally this is caught in tickInput(), but that threshold cannot be to high
    102       // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
    103       // Someone only uses buttons with an active joystick. The joy stick value could then
    104       // be 0.05 for instance and the the key value 1. Without handling the problem, the final
    105       // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
    106       float absQ = abs * abs;
    107       float valueQ = cmd.value_ * cmd.value_;
    108       if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
    109       {
    110         cmd.value_ = abs * paramModifier_;
    111         cmd.nValuesAdded_ = 1;
    112       }
    113       else if (absQ * 50.0f < valueQ)
    114       {
    115         // abs is too small, we just don't do anything
    116       }
    117       else
    118       {
    119         // we have to calculate the absolute position of the axis.
    120         // Since there might be another axis that is affected, we have to wait and
    121         // store the result in a temporary place
    122         cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
    123       }
    124     }
    125     return true;
    126   }
    127134}
  • code/branches/gui/src/core/input/InputCommands.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _InputCommands_H__
     
    4041namespace orxonox
    4142{
    42   class _CoreExport BufferedParamCommand
    43   {
    44   public:
    45     BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
    46     bool execute();
     43    class _CoreExport BufferedParamCommand
     44    {
     45    public:
     46        BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
     47        bool execute();
    4748
    48     float value_;
    49     unsigned int nValuesAdded_;
    50     int paramIndex_;
    51     CommandEvaluation evaluation_;
    52   };
     49        float value_;
     50        unsigned int nValuesAdded_;
     51        int paramIndex_;
     52        CommandEvaluation evaluation_;
     53    };
    5354
    54   class _CoreExport BaseCommand
    55   {
    56   public:
    57     virtual ~BaseCommand() { }
    58     virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
    59   };
     55    class _CoreExport BaseCommand
     56    {
     57    public:
     58        virtual ~BaseCommand() { }
     59        virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
     60    };
    6061
    61   class _CoreExport SimpleCommand : public BaseCommand
    62   {
    63   public:
    64     bool execute(float abs = 1.0f, float rel = 1.0f);
     62    class _CoreExport SimpleCommand : public BaseCommand
     63    {
     64    public:
     65        bool execute(float abs = 1.0f, float rel = 1.0f);
    6566
    66     CommandEvaluation evaluation_;
    67   };
     67        CommandEvaluation evaluation_;
     68    };
    6869
    69   class _CoreExport ParamCommand : public BaseCommand
    70   {
    71   public:
    72     ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
    73     bool execute(float abs = 1.0f, float rel = 1.0f);
     70    class _CoreExport ParamCommand : public BaseCommand
     71    {
     72    public:
     73        ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
     74        bool execute(float abs = 1.0f, float rel = 1.0f);
    7475
    75     bool bRelative_;
    76     float paramModifier_;
    77     BufferedParamCommand* paramCommand_;
    78   };
     76        bool bRelative_;
     77        float paramModifier_;
     78        BufferedParamCommand* paramCommand_;
     79    };
    7980}
    8081
  • code/branches/gui/src/core/input/InputInterfaces.h

    r1556 r1638  
    2828
    2929/**
    30  @file
    31  @brief Declarations of various interface classes for the input management.
     30@file
     31@brief
     32    Declarations of various interface classes for the input management.
    3233*/
    3334
     
    3738#include "core/CorePrereqs.h"
    3839
    39 #include "src/ois/OISKeyboard.h"
    40 #include "src/ois/OISMouse.h"
    41 #include "src/ois/OISJoyStick.h"
     40#include "ois/OISKeyboard.h"
     41#include "ois/OISMouse.h"
     42#include "ois/OISJoyStick.h"
    4243#include "util/Math.h"
    4344
    4445namespace orxonox
    4546{
    46   namespace KeyCode
    47   {
    48     // note: KeyCode comments were directly taken from OISKeyboard.h
    49     enum Enum
    50     {
    51       Unassigned    = OIS::KC_UNASSIGNED,
    52       Escape        = OIS::KC_ESCAPE,
    53       NumRow1       = OIS::KC_1,
    54       NumRow2       = OIS::KC_2,
    55       NumRow3       = OIS::KC_3,
    56       NumRow4       = OIS::KC_4,
    57       NumRow5       = OIS::KC_5,
    58       NumRow6       = OIS::KC_6,
    59       NumRow7       = OIS::KC_7,
    60       NumRow8       = OIS::KC_8,
    61       NumRow9       = OIS::KC_9,
    62       NumRow0       = OIS::KC_0,
    63       Minus         = OIS::KC_MINUS,           // - on main keyboard
    64       Equals        = OIS::KC_EQUALS,
    65       Back          = OIS::KC_BACK,            // backspace
    66       Tab           = OIS::KC_TAB,
    67       Q             = OIS::KC_Q,
    68       W             = OIS::KC_W,
    69       E             = OIS::KC_E,
    70       R             = OIS::KC_R,
    71       T             = OIS::KC_T,
    72       Y             = OIS::KC_Y,
    73       U             = OIS::KC_U,
    74       I             = OIS::KC_I,
    75       O             = OIS::KC_O,
    76       P             = OIS::KC_P,
    77       LeftBracket   = OIS::KC_LBRACKET,
    78       RightBracket  = OIS::KC_RBRACKET,
    79       Return        = OIS::KC_RETURN,          // Enter on main keyboard
    80       LeftControl   = OIS::KC_LCONTROL,
    81       A             = OIS::KC_A,
    82       S             = OIS::KC_S,
    83       D             = OIS::KC_D,
    84       F             = OIS::KC_F,
    85       G             = OIS::KC_G,
    86       H             = OIS::KC_H,
    87       J             = OIS::KC_J,
    88       K             = OIS::KC_K,
    89       L             = OIS::KC_L,
    90       Semicolon     = OIS::KC_SEMICOLON,
    91       Apostrophe    = OIS::KC_APOSTROPHE,
    92       Grave         = OIS::KC_GRAVE,           // accent
    93       LeftShift     = OIS::KC_LSHIFT,
    94       Backslash     = OIS::KC_BACKSLASH,
    95       Z             = OIS::KC_Z,
    96       X             = OIS::KC_X,
    97       C             = OIS::KC_C,
    98       V             = OIS::KC_V,
    99       B             = OIS::KC_B,
    100       N             = OIS::KC_N,
    101       M             = OIS::KC_M,
    102       Comma         = OIS::KC_COMMA,
    103       Period        = OIS::KC_PERIOD,          // . on main keyboard
    104       Slash         = OIS::KC_SLASH,           // / on main keyboard
    105       RightShift    = OIS::KC_RSHIFT,
    106       Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
    107       LeftAlt       = OIS::KC_LMENU,           // left Alt
    108       Space         = OIS::KC_SPACE,
    109       CapsLock      = OIS::KC_CAPITAL,
    110       F1            = OIS::KC_F1,
    111       F2            = OIS::KC_F2,
    112       F3            = OIS::KC_F3,
    113       F4            = OIS::KC_F4,
    114       F5            = OIS::KC_F5,
    115       F6            = OIS::KC_F6,
    116       F7            = OIS::KC_F7,
    117       F8            = OIS::KC_F8,
    118       F9            = OIS::KC_F9,
    119       F10           = OIS::KC_F10,
    120       Numlock       = OIS::KC_NUMLOCK,
    121       Scrolllock    = OIS::KC_SCROLL,          // Scroll Lock
    122       Numpad7       = OIS::KC_NUMPAD7,
    123       Numpad8       = OIS::KC_NUMPAD8,
    124       Numpad9       = OIS::KC_NUMPAD9,
    125       NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
    126       Numpad4       = OIS::KC_NUMPAD4,
    127       Numpad5       = OIS::KC_NUMPAD5,
    128       Numpad6       = OIS::KC_NUMPAD6,
    129       NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
    130       Numpad1       = OIS::KC_NUMPAD1,
    131       Numpad2       = OIS::KC_NUMPAD2,
    132       Numpad3       = OIS::KC_NUMPAD3,
    133       Numpad0       = OIS::KC_NUMPAD0,
    134       NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
    135       LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
    136       F11           = OIS::KC_F11,
    137       F12           = OIS::KC_F12,
    138       F13           = OIS::KC_F13,             //                     (NEC PC98)
    139       F14           = OIS::KC_F14,             //                     (NEC PC98)
    140       F15           = OIS::KC_F15,             //                     (NEC PC98)
    141       Kana          = OIS::KC_KANA,            // (Japanese keyboard)
    142       ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
    143       Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
    144       NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
    145       Yen           = OIS::KC_YEN,             // (Japanese keyboard)
    146       ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
    147       NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
    148       PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
    149       AT            = OIS::KC_AT,              //                     (NEC PC98)
    150       Colon         = OIS::KC_COLON,           //                     (NEC PC98)
    151       Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
    152       Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
    153       Stop          = OIS::KC_STOP,            //                     (NEC PC98)
    154       AX            = OIS::KC_AX,              //                     (Japan AX)
    155       Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
    156       NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
    157       NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
    158       RightControl  = OIS::KC_RCONTROL,
    159       Mute          = OIS::KC_MUTE,            // Mute
    160       Calculator    = OIS::KC_CALCULATOR,      // Calculator
    161       PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
    162       MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
    163       VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
    164       VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
    165       WebHome       = OIS::KC_WEBHOME,         // Web home
    166       NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
    167       Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
    168       SYSRQ         = OIS::KC_SYSRQ,
    169       RightAlt      = OIS::KC_RMENU,           // right Alt
    170       Pause         = OIS::KC_PAUSE,           // Pause
    171       Home          = OIS::KC_HOME,            // Home on arrow keypad
    172       Up            = OIS::KC_UP,              // UpArrow on arrow keypad
    173       PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
    174       Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
    175       Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
    176       End           = OIS::KC_END,             // End on arrow keypad
    177       Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
    178       PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
    179       Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
    180       Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
    181       LeftWindows   = OIS::KC_LWIN,            // Left Windows key
    182       RightWindows  = OIS::KC_RWIN,            // Right Windows key
    183       Apps          = OIS::KC_APPS,            // AppMenu key
    184       Power         = OIS::KC_POWER,           // System Power
    185       Sleep         = OIS::KC_SLEEP,           // System Sleep
    186       Wake          = OIS::KC_WAKE,            // System Wake
    187       WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
    188       WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
    189       WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
    190       WebStop       = OIS::KC_WEBSTOP,         // Web Stop
    191       WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
    192       WebBack       = OIS::KC_WEBBACK,         // Web Back
    193       MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
    194       Mail          = OIS::KC_MAIL,            // Mail
    195       MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
    196     };
    197   }
    198 
    199   namespace MouseButton
    200   {
    201     enum Enum
    202     {
    203       Left    = OIS::MB_Left,
    204       Right   = OIS::MB_Right,
    205       Middle  = OIS::MB_Middle,
    206       Button3 = OIS::MB_Button3,
    207       Button4 = OIS::MB_Button4,
    208       Button5 = OIS::MB_Button5,
    209       Button6 = OIS::MB_Button6,
    210       Button7 = OIS::MB_Button7
    211     };
    212   }
    213 
    214   namespace KeyboardModifier
    215   {
    216     enum Enum
    217     {
    218       Shift = 0x0000001,
    219       Ctrl  = 0x0000010,
    220       Alt   = 0x0000100
    221     };
    222   }
    223 
    224   struct _CoreExport Key
    225   {
    226     Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { }
    227     KeyCode::Enum key;
    228     unsigned int text;
    229   };
    230 
    231   class _CoreExport KeyEvent
    232   {
    233   public:
    234     KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { }
    235     KeyEvent(const OIS::KeyEvent& evt, unsigned int mod) : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { }
    236     KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { }
    237     bool isModifierDown(KeyboardModifier::Enum modifier) const { return (KeyboardModifier::Enum)modifier&modifiers; }
    238 
    239     const KeyCode::Enum key;
    240     unsigned int text;
    241     unsigned int modifiers;
    242   };
    243 
    244   //typedef OIS::MouseState MouseState;
    245 
    246   /*class _CoreExport JoyStickState
    247   {
    248   public:
    249     JoyStickState(const OIS::JoyStickState& state, int ID) : OIS::JoyStickState(state), mJoyStickID(ID) { }
    250     JoyStickState() { clear(); }
    251     int mJoyStickID;
    252                 JoyStickState() { clear(); }
    253 
    254                 std::vector<bool> mButtons;
    255                 int axes[16];
    256                 std::vector<Vector3> mVectors;
    257   };*/
    258 
    259   /**
    260   * Helper struct to determine which handlers of an object (can implement
    261   * multiple handlers) are active.
    262   */
    263   struct HandlerState
    264   {
    265     HandlerState() : key(false), mouse(false), joyStick(false) { }
    266     bool key;
    267     bool mouse;
    268     bool joyStick;
    269   };
    270 
    271   class _CoreExport InputTickable
    272   {
    273   public:
    274     virtual ~InputTickable() { }
    275     virtual void tickInput(float dt, const HandlerState& state) = 0;
    276   };
    277 
    278   /**
    279     @brief Interface class used for key input listeners.
    280   */
    281   class _CoreExport KeyHandler : virtual public InputTickable
    282   {
    283   public:
    284     virtual ~KeyHandler() { }
    285     virtual void keyPressed (const KeyEvent& evt) = 0;
    286     virtual void keyReleased(const KeyEvent& evt) = 0;
    287     virtual void keyHeld    (const KeyEvent& evt) = 0;
    288     //virtual void tickKey    (float dt) { }
    289   };
    290 
    291   /**
    292     @brief Interface class used for mouse input listeners.
    293   */
    294   class _CoreExport MouseHandler : virtual public InputTickable
    295   {
    296   public:
    297     virtual ~MouseHandler() { }
    298     virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
    299     virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
    300     virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
    301     virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
    302     virtual void mouseScrolled      (int abs, int rel)     = 0;
    303     //virtual void tickMouse          (float dt) { }
    304   };
    305 
    306 
    307   /**
    308     @brief Interface class used for joy stick input listeners.
    309   */
    310   class _CoreExport JoyStickHandler : virtual public InputTickable
    311   {
    312   public:
    313     virtual ~JoyStickHandler() { }
    314     virtual void joyStickButtonPressed (int joyStickID, int button) = 0;
    315     virtual void joyStickButtonReleased(int joyStickID, int button) = 0;
    316     virtual void joyStickButtonHeld    (int joyStickID, int button) = 0;
    317     virtual void joyStickAxisMoved     (int joyStickID, int axis, float value) = 0;
    318     //virtual bool joyStickVector3Moved  (int joyStickID, int index /*, fill list*/) {return true;}
    319     //virtual void tickJoyStick          (float dt) { }
    320   };
     47    namespace KeyCode
     48    {
     49        // note: KeyCode comments were directly copied from OISKeyboard.h
     50        enum Enum
     51        {
     52            Unassigned    = OIS::KC_UNASSIGNED,
     53            Escape        = OIS::KC_ESCAPE,
     54            NumRow1       = OIS::KC_1,
     55            NumRow2       = OIS::KC_2,
     56            NumRow3       = OIS::KC_3,
     57            NumRow4       = OIS::KC_4,
     58            NumRow5       = OIS::KC_5,
     59            NumRow6       = OIS::KC_6,
     60            NumRow7       = OIS::KC_7,
     61            NumRow8       = OIS::KC_8,
     62            NumRow9       = OIS::KC_9,
     63            NumRow0       = OIS::KC_0,
     64            Minus         = OIS::KC_MINUS,           // - on main keyboard
     65            Equals        = OIS::KC_EQUALS,
     66            Back          = OIS::KC_BACK,            // backspace
     67            Tab           = OIS::KC_TAB,
     68            Q             = OIS::KC_Q,
     69            W             = OIS::KC_W,
     70            E             = OIS::KC_E,
     71            R             = OIS::KC_R,
     72            T             = OIS::KC_T,
     73            Y             = OIS::KC_Y,
     74            U             = OIS::KC_U,
     75            I             = OIS::KC_I,
     76            O             = OIS::KC_O,
     77            P             = OIS::KC_P,
     78            LeftBracket   = OIS::KC_LBRACKET,
     79            RightBracket  = OIS::KC_RBRACKET,
     80            Return        = OIS::KC_RETURN,          // Enter on main keyboard
     81            LeftControl   = OIS::KC_LCONTROL,
     82            A             = OIS::KC_A,
     83            S             = OIS::KC_S,
     84            D             = OIS::KC_D,
     85            F             = OIS::KC_F,
     86            G             = OIS::KC_G,
     87            H             = OIS::KC_H,
     88            J             = OIS::KC_J,
     89            K             = OIS::KC_K,
     90            L             = OIS::KC_L,
     91            Semicolon     = OIS::KC_SEMICOLON,
     92            Apostrophe    = OIS::KC_APOSTROPHE,
     93            Grave         = OIS::KC_GRAVE,           // accent
     94            LeftShift     = OIS::KC_LSHIFT,
     95            Backslash     = OIS::KC_BACKSLASH,
     96            Z             = OIS::KC_Z,
     97            X             = OIS::KC_X,
     98            C             = OIS::KC_C,
     99            V             = OIS::KC_V,
     100            B             = OIS::KC_B,
     101            N             = OIS::KC_N,
     102            M             = OIS::KC_M,
     103            Comma         = OIS::KC_COMMA,
     104            Period        = OIS::KC_PERIOD,          // . on main keyboard
     105            Slash         = OIS::KC_SLASH,           // / on main keyboard
     106            RightShift    = OIS::KC_RSHIFT,
     107            Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
     108            LeftAlt       = OIS::KC_LMENU,           // left Alt
     109            Space         = OIS::KC_SPACE,
     110            CapsLock      = OIS::KC_CAPITAL,
     111            F1            = OIS::KC_F1,
     112            F2            = OIS::KC_F2,
     113            F3            = OIS::KC_F3,
     114            F4            = OIS::KC_F4,
     115            F5            = OIS::KC_F5,
     116            F6            = OIS::KC_F6,
     117            F7            = OIS::KC_F7,
     118            F8            = OIS::KC_F8,
     119            F9            = OIS::KC_F9,
     120            F10           = OIS::KC_F10,
     121            Numlock       = OIS::KC_NUMLOCK,
     122            Scrolllock    = OIS::KC_SCROLL,          // Scroll Lock
     123            Numpad7       = OIS::KC_NUMPAD7,
     124            Numpad8       = OIS::KC_NUMPAD8,
     125            Numpad9       = OIS::KC_NUMPAD9,
     126            NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
     127            Numpad4       = OIS::KC_NUMPAD4,
     128            Numpad5       = OIS::KC_NUMPAD5,
     129            Numpad6       = OIS::KC_NUMPAD6,
     130            NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
     131            Numpad1       = OIS::KC_NUMPAD1,
     132            Numpad2       = OIS::KC_NUMPAD2,
     133            Numpad3       = OIS::KC_NUMPAD3,
     134            Numpad0       = OIS::KC_NUMPAD0,
     135            NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
     136            LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
     137            F11           = OIS::KC_F11,
     138            F12           = OIS::KC_F12,
     139            F13           = OIS::KC_F13,             //                     (NEC PC98)
     140            F14           = OIS::KC_F14,             //                     (NEC PC98)
     141            F15           = OIS::KC_F15,             //                     (NEC PC98)
     142            Kana          = OIS::KC_KANA,            // (Japanese keyboard)
     143            ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
     144            Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
     145            NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
     146            Yen           = OIS::KC_YEN,             // (Japanese keyboard)
     147            ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
     148            NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
     149            PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
     150            AT            = OIS::KC_AT,              //                     (NEC PC98)
     151            Colon         = OIS::KC_COLON,           //                     (NEC PC98)
     152            Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
     153            Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
     154            Stop          = OIS::KC_STOP,            //                     (NEC PC98)
     155            AX            = OIS::KC_AX,              //                     (Japan AX)
     156            Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
     157            NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
     158            NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
     159            RightControl  = OIS::KC_RCONTROL,
     160            Mute          = OIS::KC_MUTE,            // Mute
     161            Calculator    = OIS::KC_CALCULATOR,      // Calculator
     162            PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
     163            MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
     164            VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
     165            VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
     166            WebHome       = OIS::KC_WEBHOME,         // Web home
     167            NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
     168            Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
     169            SYSRQ         = OIS::KC_SYSRQ,
     170            RightAlt      = OIS::KC_RMENU,           // right Alt
     171            Pause         = OIS::KC_PAUSE,           // Pause
     172            Home          = OIS::KC_HOME,            // Home on arrow keypad
     173            Up            = OIS::KC_UP,              // UpArrow on arrow keypad
     174            PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
     175            Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
     176            Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
     177            End           = OIS::KC_END,             // End on arrow keypad
     178            Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
     179            PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
     180            Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
     181            Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
     182            LeftWindows   = OIS::KC_LWIN,            // Left Windows key
     183            RightWindows  = OIS::KC_RWIN,            // Right Windows key
     184            Apps          = OIS::KC_APPS,            // AppMenu key
     185            Power         = OIS::KC_POWER,           // System Power
     186            Sleep         = OIS::KC_SLEEP,           // System Sleep
     187            Wake          = OIS::KC_WAKE,            // System Wake
     188            WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
     189            WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
     190            WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
     191            WebStop       = OIS::KC_WEBSTOP,         // Web Stop
     192            WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
     193            WebBack       = OIS::KC_WEBBACK,         // Web Back
     194            MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
     195            Mail          = OIS::KC_MAIL,            // Mail
     196            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
     197        };
     198    }
     199
     200    namespace MouseButton
     201    {
     202        enum Enum
     203        {
     204            Left    = OIS::MB_Left,
     205            Right   = OIS::MB_Right,
     206            Middle  = OIS::MB_Middle,
     207            Button3 = OIS::MB_Button3,
     208            Button4 = OIS::MB_Button4,
     209            Button5 = OIS::MB_Button5,
     210            Button6 = OIS::MB_Button6,
     211            Button7 = OIS::MB_Button7
     212        };
     213    }
     214
     215    namespace KeyboardModifier
     216    {
     217        enum Enum
     218        {
     219            Shift = 0x0000001,
     220            Ctrl  = 0x0000010,
     221            Alt   = 0x0000100
     222        };
     223    }
     224   
     225    namespace InputDevice
     226    {
     227        enum Enum
     228        {
     229            Keyboard,
     230            Mouse,
     231            JoyStick0,
     232            JoyStick1,
     233            JoyStick2,
     234            JoyStick3,
     235            // note: No problem if there are more joy sticks. This enum is just for convenience.
     236        };
     237    }
     238
     239    struct _CoreExport Key
     240    {
     241        Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { }
     242        KeyCode::Enum key;
     243        unsigned int text;
     244    };
     245
     246    class _CoreExport KeyEvent
     247    {
     248    public:
     249        KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { }
     250        KeyEvent(const OIS::KeyEvent& evt, unsigned int mod)
     251            : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { }
     252        KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { }
     253        bool isModifierDown(KeyboardModifier::Enum modifier) const
     254            { return (KeyboardModifier::Enum)modifier&modifiers; }
     255
     256        const KeyCode::Enum key;
     257        unsigned int text;
     258        unsigned int modifiers;
     259    };
     260
     261    //typedef OIS::MouseState MouseState;
     262
     263    /*class _CoreExport JoyStickState
     264    {
     265    public:
     266        JoyStickState(const OIS::JoyStickState& state, int ID) : OIS::JoyStickState(state), mJoyStickID(ID) { }
     267        JoyStickState() { clear(); }
     268        int mJoyStickID;
     269        JoyStickState() { clear(); }
     270
     271        std::vector<bool> mButtons;
     272        int axes[16];
     273        std::vector<Vector3> mVectors;
     274    };*/
     275
     276    /**
     277    @brief
     278        Helper struct to determine which handlers of an object (can implement
     279        multiple handlers) are active.
     280    */
     281    //struct HandlerState
     282    //{
     283    //    HandlerState() : keyboard(false), mouse(false) { }
     284    //    bool keyboard;
     285    //    bool mouse;
     286    //    std::vector<bool> joySticks;
     287    //};
     288
     289    class _CoreExport InputTickable
     290    {
     291    public:
     292        virtual ~InputTickable() { }
     293        virtual void tickInput(float dt) = 0;
     294        //virtual void tickInput(float dt, unsigned int device) = 0;
     295    };
     296
     297    /**
     298    @brief
     299        Interface class used for key input listeners.
     300    */
     301    class _CoreExport KeyHandler : virtual public InputTickable
     302    {
     303    public:
     304        virtual ~KeyHandler() { }
     305        virtual void keyPressed (const KeyEvent& evt) = 0;
     306        virtual void keyReleased(const KeyEvent& evt) = 0;
     307        virtual void keyHeld    (const KeyEvent& evt) = 0;
     308        virtual void tickKey    (float dt) { }
     309    };
     310
     311    /**
     312    @brief
     313        Interface class used for mouse input listeners.
     314    */
     315    class _CoreExport MouseHandler : virtual public InputTickable
     316    {
     317    public:
     318        virtual ~MouseHandler() { }
     319        virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
     320        virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
     321        virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
     322        virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
     323        virtual void mouseScrolled      (int abs, int rel)     = 0;
     324        virtual void tickMouse          (float dt) { }
     325    };
     326
     327
     328    /**
     329    @brief
     330        Interface class used for joy stick input listeners.
     331    */
     332    class _CoreExport JoyStickHandler : virtual public InputTickable
     333    {
     334    public:
     335        virtual ~JoyStickHandler() { }
     336        virtual void joyStickButtonPressed (unsigned int joyStickID, unsigned int button) = 0;
     337        virtual void joyStickButtonReleased(unsigned int joyStickID, unsigned int button) = 0;
     338        virtual void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button) = 0;
     339        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
     340        //virtual bool joyStickVector3Moved  (unsigned int joyStickID, unsigned int index /*, fill list*/) {return true;}
     341        virtual void tickJoyStick          (float dt, unsigned int device) { }
     342    };
     343
     344    class _CoreExport EmptyHandler : public KeyHandler, public MouseHandler, public JoyStickHandler
     345    {
     346    private:
     347        void tickInput(float dt) { }
     348        void tickInput(float dt, unsigned int device) { }
     349
     350        void keyPressed (const KeyEvent& evt) { }
     351        void keyReleased(const KeyEvent& evt) { }
     352        void keyHeld    (const KeyEvent& evt) { }
     353
     354        void mouseButtonPressed (MouseButton::Enum id) { }
     355        void mouseButtonReleased(MouseButton::Enum id) { }
     356        void mouseButtonHeld    (MouseButton::Enum id) { }
     357        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
     358        void mouseScrolled      (int abs, int rel) { }
     359
     360        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button) { }
     361        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button) { }
     362        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button) { }
     363        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) { }
     364    };
    321365
    322366}
  • code/branches/gui/src/core/input/InputManager.cc

    r1555 r1638  
    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"
     
    4247#include "core/CommandExecutor.h"
    4348#include "core/ConsoleCommand.h"
    44 #include "core/Shell.h"               // hack!
    4549
    4650#include "InputBuffer.h"
     
    4852#include "KeyDetector.h"
    4953#include "CalibratorCallback.h"
    50 
    51 #include "src/ois/OISException.h"
    52 #include "src/ois/OISInputManager.h"
     54#include "InputState.h"
     55#include "SimpleInputState.h"
     56#include "ExtendedInputState.h"
    5357
    5458namespace orxonox
    5559{
    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,
     60    SetConsoleCommandShortcut(InputManager, keyBind);
     61    SetConsoleCommandShortcut(InputManager, storeKeyStroke);
     62    SetConsoleCommandShortcut(InputManager, calibrate);
     63
     64    using namespace InputDevice;
     65
     66    // ###############################
     67    // ###    Internal Methods     ###
     68    // ###############################
     69    // ###############################
     70
     71    /**
     72    @brief
     73        Constructor only sets member fields to initial zero values
     74        and registers the class in the class hierarchy.
     75    */
     76    InputManager::InputManager()
     77        : inputSystem_(0)
     78        , keyboard_(0)
     79        , mouse_(0)
     80        , joySticksSize_(0)
     81        , devicesNum_(0)
     82        , stateDetector_(0)
     83        , stateCalibrator_(0)
     84        , stateEmpty_(0)
     85        , keyboardModifiers_(0)
     86        , bCalibrating_(false)
     87    {
     88        RegisterRootObject(InputManager);
     89    }
     90
     91    /**
     92    @brief
     93        The one instance of the InputManager is stored in this function.
     94    @return
     95        A reference to the only instance of the InputManager
     96    */
     97    InputManager& InputManager::_getInstance()
     98    {
     99        static InputManager theOnlyInstance;
     100        return theOnlyInstance;
     101    }
     102
     103    /**
     104    @brief
     105        Destructor only called at the end of the program, after main.
     106    */
     107    InputManager::~InputManager()
     108    {
     109        _destroy();
     110    }
     111
     112
     113    // ############################################################
     114    // #####                  Initialisation                  #####
     115    // ##########                                        ##########
     116    // ############################################################
     117
     118    /**
     119    @brief
     120        Creates the OIS::InputMananger, the keyboard, the mouse and
     121        the joysticks and assigns the key bindings.
     122    @param windowHnd
     123        The window handle of the render window
     124    @param windowWidth
     125        The width of the render window
     126    @param windowHeight
     127        The height of the render window
     128    */
     129    bool InputManager::_initialise(const size_t windowHnd, int windowWidth, int windowHeight,
     130                                   bool createKeyboard, bool createMouse, bool createJoySticks)
     131    {
     132        if (inputSystem_ == 0)
     133        {
     134            CCOUT(3) << "Initialising Input System..." << std::endl;
     135            CCOUT(ORX_DEBUG) << "Initialising OIS components..." << std::endl;
     136
     137            OIS::ParamList paramList;
     138            std::ostringstream windowHndStr;
     139
     140            // Fill parameter list
     141            windowHndStr << (unsigned int)windowHnd;
     142            paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
     143            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
     144            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
     145//#if defined OIS_LINUX_PLATFORM
     146            //paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
     147//#endif
     148
     149            try
     150            {
     151                inputSystem_ = OIS::InputManager::createInputSystem(paramList);
     152                CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
     153            }
     154            catch (OIS::Exception ex)
     155            {
     156                CCOUT(ORX_ERROR) << "Error: Failed creating an OIS input system."
     157                    << "OIS message: \"" << ex.eText << "\"" << std::endl;
     158                inputSystem_ = 0;
     159                return false;
     160            }
     161
     162            if (createKeyboard)
     163                _initialiseKeyboard();
     164
     165            if (createMouse)
     166                _initialiseMouse();
     167
     168            if (createJoySticks)
     169                _initialiseJoySticks();
     170
     171            // set all the std::vector list sizes now that the devices have been created
     172            _redimensionLists();
     173
     174            // Set mouse/joystick region
     175            if (mouse_)
     176            {
     177                setWindowExtents(windowWidth, windowHeight);
     178            }
     179
     180            CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
     181
     182            // InputManager holds the input buffer --> create one and add it.
     183            //buffer_ = new InputBuffer();
     184            //addKeyHandler(buffer_, "buffer");
     185            //Shell::getInstance().setInputBuffer(buffer_);
     186
     187            setConfigValues();
     188
     189            stateEmpty_ = createSimpleInputState("empty", -1);
     190            stateEmpty_->setHandler(new EmptyHandler());
     191            activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
     192
     193            stateDetector_ = createSimpleInputState("detector", 101);
     194            KeyDetector* temp = new KeyDetector();
     195            temp->loadBindings("storeKeyStroke");
     196            stateDetector_->setHandler(temp);
     197
     198            stateCalibrator_ = createSimpleInputState("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            _updateActiveStates();
     205
     206            CCOUT(ORX_DEBUG) << "Initialising complete." << std::endl;
     207        }
     208        else
     209        {
     210            CCOUT(ORX_WARNING) << "Warning: OIS compoments already initialised, skipping" << std::endl;
     211        }
     212        return true;
     213    }
     214
     215    /**
     216    @brief
     217        Creates a keyboard and sets the event handler.
     218    @return
     219        False if keyboard stays uninitialised, true otherwise.
     220    */
     221    bool InputManager::_initialiseKeyboard()
     222    {
     223        if (keyboard_ != 0)
     224        {
     225            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
     226            return true;
     227        }
     228        try
     229        {
     230            if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
     231            {
     232                keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
     233                // register our listener in OIS.
     234                keyboard_->setEventCallback(this);
     235                // note: OIS will not detect keys that have already been down when the keyboard was created.
     236                CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
     237                return true;
     238            }
     239            else
     240            {
     241                CCOUT(ORX_WARNING) << "Warning: No keyboard found!" << std::endl;
     242                return false;
     243            }
     244        }
     245        catch (OIS::Exception ex)
     246        {
     247            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS keyboard\n"
     248                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
     249            keyboard_ = 0;
     250            return false;
     251        }
     252    }
     253
     254    /**
     255    @brief
     256        Creates a mouse and sets the event handler.
     257    @return
     258        False if mouse stays uninitialised, true otherwise.
     259    */
     260    bool InputManager::_initialiseMouse()
     261    {
     262        if (mouse_ != 0)
     263        {
     264            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
     265            return true;
     266        }
     267        try
     268        {
     269            if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
     270            {
     271                mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true));
     272                // register our listener in OIS.
     273                mouse_->setEventCallback(this);
     274                CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
     275                return true;
     276            }
     277            else
     278            {
     279                CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
     280                return false;
     281            }
     282        }
     283        catch (OIS::Exception ex)
     284        {
     285            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
     286                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
     287            mouse_ = 0;
     288            return false;
     289        }
     290    }
     291
     292    /**
     293    @brief
     294        Creates all joy sticks and sets the event handler.
     295    @return
     296        False joy stick stay uninitialised, true otherwise.
     297    */
     298    bool InputManager::_initialiseJoySticks()
     299    {
     300        if (joySticksSize_ > 0)
     301        {
     302            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
     303            return true;
     304        }
     305        bool success = false;
     306        if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
     307        {
     308            for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
     309            {
     310                try
     311                {
     312                    OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
     313                        (inputSystem_->createInputObject(OIS::OISJoyStick, true));
     314                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
     315                    joySticks_.push_back(stig);
     316                    // register our listener in OIS.
     317                    stig->setEventCallback(this);
     318                    success = true;
     319                }
     320                catch (OIS::Exception ex)
     321                {
     322                    CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n"
     323                        << "OIS error message: \"" << ex.eText << "\"" << std::endl;
     324                }
     325            }
     326        }
     327        else
     328        {
     329            CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
     330            return false;
     331        }
     332        return success;
     333    }
     334
     335    void InputManager::_redimensionLists()
     336    {
     337        joySticksSize_ = joySticks_.size();
     338        devicesNum_ = 2 + joySticksSize_;
     339        joyStickButtonsDown_ .resize(joySticksSize_);
     340        povStates_           .resize(joySticksSize_);
     341        sliderStates_        .resize(joySticksSize_);
     342        joySticksCalibration_.resize(joySticksSize_);
     343
     344        for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
     345        {
     346            // reset the calibration with default values
     347            for (unsigned int i = 0; i < 24; i++)
     348            {
     349                joySticksCalibration_[iJoyStick].negativeCoeff[i] = 1.0f/32767.0f;
     350                joySticksCalibration_[iJoyStick].positiveCoeff[i] = 1.0f/32768.0f;
     351                joySticksCalibration_[iJoyStick].zeroStates[i] = 0;
     352            }
     353        }
     354
     355        // state management
     356        activeStatesTop_.resize(devicesNum_);
     357
     358        // inform all registered states
     359        for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
     360            it != inputStatesByPriority_.end(); ++it)
     361            (*it).second->setNumOfJoySticks(joySticksSize_);
     362    }
     363
     364    /**
     365    @brief
     366        Sets the configurable values. Use keybindings.ini as file..
     367    */
     368    void InputManager::setConfigValues()
     369    {
     370        if (joySticksSize_)
     371        {
     372            std::vector<MultiTypeMath> coeffPos;
     373            std::vector<MultiTypeMath> coeffNeg;
     374            std::vector<MultiTypeMath> zero;
     375            coeffPos.resize(24);
     376            coeffNeg.resize(24);
     377            zero.resize(24);
     378            for (unsigned int i = 0; i < 24; i++)
     379            {
     380                coeffPos[i] =  1.0f/32767.0f;
     381                coeffNeg[i] =  1.0f/32768.0f;
     382                zero[i]     =  0;
     383            }
     384
     385            ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
     386            if (!cont)
     387            {
     388                cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffPos", coeffPos);
     389                getIdentifier()->addConfigValueContainer("CoeffPos", cont);
     390            }
     391            cont->getValue(&coeffPos);
     392
     393            cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
     394            if (!cont)
     395            {
     396                cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffNeg", coeffNeg);
     397                getIdentifier()->addConfigValueContainer("CoeffNeg", cont);
     398            }
     399            cont->getValue(&coeffNeg);
     400
     401            cont = getIdentifier()->getConfigValueContainer("Zero");
     402            if (!cont)
     403            {
     404                cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "Zero", zero);
     405                getIdentifier()->addConfigValueContainer("Zero", cont);
     406            }
     407            cont->getValue(&zero);
     408
     409            // copy values to our own variables
     410            for (unsigned int i = 0; i < 24; i++)
     411            {
     412                joySticksCalibration_[0].positiveCoeff[i] = coeffPos[i];
     413                joySticksCalibration_[0].negativeCoeff[i] = coeffNeg[i];
     414                joySticksCalibration_[0].zeroStates[i]    = zero[i];
     415            }
     416        }
     417    }
     418
     419
     420    // ############################################################
     421    // #####                    Destruction                   #####
     422    // ##########                                        ##########
     423    // ############################################################
     424
     425    /**
     426    @brief
     427        Destroys all the created input devices and sets the InputManager to construction state.
     428    */
     429    void InputManager::_destroy()
     430    {
     431        if (inputSystem_)
     432        {
     433            CCOUT(ORX_DEBUG) << "Destroying ..." << std::endl;
     434
     435            // kick all active states 'nicely'
     436            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
     437                rit != activeStates_.rend(); ++rit)
     438                (*rit).second->onLeave();
     439            activeStates_.clear();
     440
     441            // destroy our own states
     442            stateEmpty_->removeAndDestroyAllHandlers();
     443            stateCalibrator_->removeAndDestroyAllHandlers();
     444            stateDetector_->removeAndDestroyAllHandlers();
     445            _destroyState(stateEmpty_);
     446            _destroyState(stateCalibrator_);
     447            _destroyState(stateDetector_);
     448            stateEmpty_ = 0;
     449            stateCalibrator_ = 0;
     450            stateDetector_ = 0;
     451
     452            // we don't remove the other states yet because the singleton might still exist.
     453            // So people can still removeAndDestroy their states
     454            //inputStatesByName_.clear();
     455            //inputStatesByPriority_.clear();
     456
     457            // destroy the devices
     458            _destroyKeyboard();
     459            _destroyMouse();
     460            _destroyJoySticks();
     461
     462            _redimensionLists();
     463
     464            OIS::InputManager::destroyInputSystem(inputSystem_);
     465            inputSystem_ = 0;
     466
     467            CCOUT(ORX_DEBUG) << "Destroying done." << std::endl;
     468        }
     469    }
     470
     471    /**
     472    @brief
     473        Destroys the keyboard and sets it to 0.
     474    */
     475    void InputManager::_destroyKeyboard()
     476    {
     477        if (keyboard_)
     478            inputSystem_->destroyInputObject(keyboard_);
     479        keyboard_ = 0;
     480        keysDown_.clear();
     481        CCOUT(ORX_DEBUG) << "Keyboard destroyed." << std::endl;
     482    }
     483
     484    /**
     485    @brief
     486        Destroys the mouse and sets it to 0.
     487    */
     488    void InputManager::_destroyMouse()
     489    {
     490        if (mouse_)
     491            inputSystem_->destroyInputObject(mouse_);
     492        mouse_ = 0;
     493        mouseButtonsDown_.clear();
     494        CCOUT(ORX_DEBUG) << "Mouse destroyed." << std::endl;
     495    }
     496
     497    /**
     498    @brief
     499        Destroys all the joy sticks and resizes the lists to 0.
     500    */
     501    void InputManager::_destroyJoySticks()
     502    {
     503        if (joySticksSize_ > 0)
     504        {
     505            // note: inputSystem_ can never be 0, or else the code is mistaken
     506            for (unsigned int i = 0; i < joySticksSize_; i++)
     507                if (joySticks_[i] != 0)
     508                    inputSystem_->destroyInputObject(joySticks_[i]);
     509
     510            joySticks_.clear();
     511        }
     512        CCOUT(ORX_DEBUG) << "Joy sticks destroyed." << std::endl;
     513    }
     514
     515    void InputManager::_destroyState(InputState* state)
     516    {
     517        assert(state);
     518        inputStatesByPriority_.erase(state->getPriority());
     519        inputStatesByName_.erase(state->getName());
     520        delete state;
     521    }
     522
     523
     524    // ############################################################
     525    // #####                  Runtime Methods                 #####
     526    // ##########                                        ##########
     527    // ############################################################
     528
     529    /**
     530    @brief
     531        Updates the InputManager. Tick is called by the Core class.
     532    @param dt
     533        Delta time
     534    */
     535    void InputManager::_tick(float dt)
     536    {
     537        if (inputSystem_ == 0)
     538            return;
     539
     540        // check for states to leave (don't use unsigned int!)
     541        for (int i = stateLeaveRequests_.size() - 1; i >= 0; --i)
     542        {
     543            stateLeaveRequests_[i]->onLeave();
     544            // just to be sure that the state actually is registered
     545            assert(inputStatesByName_.find(stateLeaveRequests_[i]->getName()) != inputStatesByName_.end());
     546           
     547            activeStates_.erase(stateLeaveRequests_[i]->getPriority());
     548            _updateActiveStates();
     549            stateLeaveRequests_.pop_back();
     550        }
     551
     552
     553        // check for states to enter (don't use unsigned int!)
     554        for (int i = stateEnterRequests_.size() - 1; i >= 0; --i)
     555        {
     556            // just to be sure that the state actually is registered
     557            assert(inputStatesByName_.find(stateEnterRequests_[i]->getName()) != inputStatesByName_.end());
     558           
     559            activeStates_[stateEnterRequests_[i]->getPriority()] = stateEnterRequests_[i];
     560            _updateActiveStates();
     561            stateEnterRequests_[i]->onEnter();
     562            stateEnterRequests_.pop_back();
     563        }
     564
     565        // Capture all the input. This calls the event handlers in InputManager.
     566        if (keyboard_)
     567            keyboard_->capture();
     568        if (mouse_)
     569            mouse_->capture();
     570        for (unsigned  int i = 0; i < joySticksSize_; i++)
     571            joySticks_[i]->capture();
     572
     573        if (!bCalibrating_)
     574        {
     575            // call all the handlers for the held key events
     576            for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
     577                activeStatesTop_[Keyboard]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_));
     578
     579            // call all the handlers for the held mouse button events
     580            for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
     581                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
     582
     583            // call all the handlers for the held joy stick button events
     584            for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
     585                for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
     586                    activeStatesTop_[JoyStick0 + iJoyStick]
     587                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
     588
     589            // tick the handlers for each active handler
     590            for (unsigned int i = 0; i < devicesNum_; ++i)
     591                activeStatesTop_[i]->tickInput(dt, i);
     592
     593            // tick the handler with a general tick afterwards
     594            for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
     595                activeStatesTicked_[i]->tickInput(dt);
     596        }
     597    }
     598
     599    void InputManager::_updateActiveStates()
     600    {
     601        for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
     602            for (unsigned int i = 0; i < devicesNum_; ++i)
     603                if ((*it).second->isInputDeviceEnabled(i))
     604                    activeStatesTop_[i] = (*it).second;
     605
     606        // update tickables (every state will only appear once)
     607        // Using a std::set to avoid duplicates
     608        std::set<InputState*> tempSet;
     609        for (unsigned int i = 0; i < devicesNum_; ++i)
     610            tempSet.insert(activeStatesTop_[i]);
     611
     612        // copy the content of the set back to the actual vector
     613        activeStatesTicked_.clear();
     614        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
     615            activeStatesTicked_.push_back(*it);
     616    }
     617
     618    void InputManager::_completeCalibration()
     619    {
     620        for (unsigned int i = 0; i < 24; i++)
     621        {
     622            // positive coefficient
     623            if (marginalsMax_[i] == INT_MIN)
     624                marginalsMax_[i] =  32767;
     625            // coefficients
     626            if (marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i])
     627            {
     628                joySticksCalibration_[0].positiveCoeff[i]
     629                    = 1.0f/(marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]);
     630            }
     631            else
     632                joySticksCalibration_[0].positiveCoeff[i] =  1.0f;
     633
     634            // config value
     635            ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
     636            assert(cont);
     637            cont->set(i, joySticksCalibration_[0].positiveCoeff[i]);
     638
     639            // negative coefficient
     640            if (marginalsMin_[i] == INT_MAX)
     641                marginalsMin_[i] = -32768;
     642            // coefficients
     643            if (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i])
     644            {
     645                joySticksCalibration_[0].negativeCoeff[i] = -1.0f
     646                    / (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]);
     647            }
     648            else
     649                joySticksCalibration_[0].negativeCoeff[i] =  1.0f;
     650            // config value
     651            cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
     652            assert(cont);
     653            cont->set(i, joySticksCalibration_[0].negativeCoeff[i]);
     654
     655            // zero states
     656            if (i < 8)
     657            {
     658                if (!(i & 1))
     659                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abX;
     660                else
     661                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abY;
     662            }
     663            else
     664            {
     665                if (i - 8 < joySticks_[0]->getJoyStickState().mAxes.size())
     666                    joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mAxes[i - 8].abs;
     667                else
     668                    joySticksCalibration_[0].zeroStates[i] = 0;
     669            }
     670            // config value
     671            cont = getIdentifier()->getConfigValueContainer("Zero");
     672            assert(cont);
     673            cont->set(i, joySticksCalibration_[0].zeroStates[i]);
     674        }
     675
     676        // restore old input state
     677        requestLeaveState("calibrator");
     678    }
     679
     680
     681    // ############################################################
     682    // #####                    OIS events                    #####
     683    // ##########                                        ##########
     684    // ############################################################
     685
     686    // ###### Key Events ######
     687
     688    /**
     689    @brief
     690        Event handler for the keyPressed Event.
     691    @param e
     692        Event information
     693    */
     694    bool InputManager::keyPressed(const OIS::KeyEvent &e)
     695    {
     696        // check whether the key already is in the list (can happen when focus was lost)
     697        unsigned int iKey = 0;
     698        while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::Enum)e.key)
     699            iKey++;
     700        if (iKey == keysDown_.size())
     701            keysDown_.push_back(Key(e));
     702
     703        // update modifiers
     704        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
     705            keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
     706        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
     707            keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
     708        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
     709            keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
     710
     711        activeStatesTop_[Keyboard]->keyPressed(KeyEvent(e, keyboardModifiers_));
     712
     713        return true;
     714    }
     715
     716    /**
     717    @brief
     718        Event handler for the keyReleased Event.
     719    @param e
     720        Event information
     721    */
     722    bool InputManager::keyReleased(const OIS::KeyEvent &e)
     723    {
     724        // remove the key from the keysDown_ list
     725        for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
     726        {
     727            if (keysDown_[iKey].key == (KeyCode::Enum)e.key)
     728            {
     729                keysDown_.erase(keysDown_.begin() + iKey);
     730                break;
     731            }
     732        }
     733
     734        // update modifiers
     735        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
     736            keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
     737        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
     738            keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
     739        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
     740            keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
     741
     742        activeStatesTop_[Keyboard]->keyReleased(KeyEvent(e, keyboardModifiers_));
     743
     744        return true;
     745    }
     746
     747
     748    // ###### Mouse Events ######
     749
     750    /**
     751    @brief
     752        Event handler for the mouseMoved Event.
     753    @param e
     754        Event information
     755    */
     756    bool InputManager::mouseMoved(const OIS::MouseEvent &e)
     757    {
     758        // check for actual moved event
     759        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
     760        {
     761            activeStatesTop_[Mouse]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs),
     762                    IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height));
     763        }
     764
     765        // check for mouse scrolled event
     766        if (e.state.Z.rel != 0)
     767        {
     768            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
     769        }
     770
     771        return true;
     772    }
     773
     774    /**
     775    @brief
     776        Event handler for the mousePressed Event.
     777    @param e
     778        Event information
     779    @param id
     780        The ID of the mouse button
     781    */
     782    bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
     783    {
     784        // check whether the button already is in the list (can happen when focus was lost)
     785        unsigned int iButton = 0;
     786        while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButton::Enum)id)
     787            iButton++;
     788        if (iButton == mouseButtonsDown_.size())
     789            mouseButtonsDown_.push_back((MouseButton::Enum)id);
     790
     791        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButton::Enum)id);
     792
     793        return true;
     794    }
     795
     796    /**
     797    @brief
     798        Event handler for the mouseReleased Event.
     799    @param e
     800        Event information
     801    @param id
     802        The ID of the mouse button
     803    */
     804    bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
     805    {
     806        // remove the button from the keysDown_ list
     807        for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
     808        {
     809            if (mouseButtonsDown_[iButton] == (MouseButton::Enum)id)
     810            {
     811                mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
     812                break;
     813            }
     814        }
     815
     816        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButton::Enum)id);
     817
     818        return true;
     819    }
     820
     821
     822    // ###### Joy Stick Events ######
     823
     824    inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
     825    {
     826        // use the device to identify which one called the method
     827        OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
     828        unsigned int iJoyStick = 0;
     829        while (joySticks_[iJoyStick] != joyStick)
     830            iJoyStick++;
     831        // assert: Unknown joystick fired an event.
     832        assert(iJoyStick != joySticksSize_);
     833        return iJoyStick;
     834    }
     835
     836    bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
     837    {
     838        unsigned int iJoyStick = _getJoystick(arg);
     839
     840        // check whether the button already is in the list (can happen when focus was lost)
     841        std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
     842        unsigned int iButton = 0;
     843        while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
     844            iButton++;
     845        if (iButton == buttonsDown.size())
     846            buttonsDown.push_back(button);
     847
     848        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, button);
     849
     850        return true;
     851    }
     852
     853    bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
     854    {
     855        unsigned int iJoyStick = _getJoystick(arg);
     856
     857        // remove the button from the joyStickButtonsDown_ list
     858        std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
     859        for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
     860        {
     861            if (buttonsDown[iButton] == button)
     862            {
     863                buttonsDown.erase(buttonsDown.begin() + iButton);
     864                break;
     865            }
     866        }
     867
     868        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, button);
     869
     870        return true;
     871    }
     872
     873    void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
     874    {
     875        if (bCalibrating_)
     876        {
     877            if (value > marginalsMax_[axis])
     878                marginalsMax_[axis] = value;
     879            if (value < marginalsMin_[axis])
     880                marginalsMin_[axis] = value;
     881        }
     882        else
     883        {
     884            float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis];
     885            if (fValue > 0.0f)
     886                fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis];
     887            else
     888                fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis];
     889
     890            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
     891        }
     892    }
     893
     894    bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
     895    {
     896        unsigned int iJoyStick = _getJoystick(arg);
     897
     898        // keep in mind that the first 8 axes are reserved for the sliders
     899        _fireAxis(iJoyStick, axis + 8, arg.state.mAxes[axis].abs);
     900
     901        return true;
     902    }
     903
     904    bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
     905    {
     906        unsigned int iJoyStick = _getJoystick(arg);
     907
     908        if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
     909            _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
     910        else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
     911            _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
     912
     913        return true;
     914    }
     915
     916    bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
     917    {
     918        unsigned int iJoyStick = _getJoystick(arg);
     919
     920        // translate the POV into 8 simple buttons
     921        int lastState = povStates_[iJoyStick][id];
     922        if (lastState & OIS::Pov::North)
     923            buttonReleased(arg, 32 + id * 4 + 0);
     924        if (lastState & OIS::Pov::South)
     925            buttonReleased(arg, 32 + id * 4 + 1);
     926        if (lastState & OIS::Pov::East)
     927            buttonReleased(arg, 32 + id * 4 + 2);
     928        if (lastState & OIS::Pov::West)
     929            buttonReleased(arg, 32 + id * 4 + 3);
     930
     931        povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
     932
     933        int currentState = povStates_[iJoyStick][id];
     934        if (currentState & OIS::Pov::North)
     935            buttonPressed(arg, 32 + id * 4 + 0);
     936        if (currentState & OIS::Pov::South)
     937            buttonPressed(arg, 32 + id * 4 + 1);
     938        if (currentState & OIS::Pov::East)
     939            buttonPressed(arg, 32 + id * 4 + 2);
     940        if (currentState & OIS::Pov::West)
     941            buttonPressed(arg, 32 + id * 4 + 3);
     942
     943        return true;
     944    }
     945
     946
     947    // ############################################################
     948    // #####            Static Interface Methods              #####
     949    // ##########                                        ##########
     950    // ############################################################
     951
     952    std::string InputManager::bindingCommmandString_s = "";
     953
     954    bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    105955        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")));
    120 //#if defined OIS_LINUX_PLATFORM
    121 //      paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
    122 //#endif
    123 
    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;
     956    {
     957        return _getInstance()._initialise(windowHnd, windowWidth, windowHeight,
     958            createKeyboard, createMouse, createJoySticks);
     959    }
     960
     961    bool InputManager::initialiseKeyboard()
     962    {
     963        return _getInstance()._initialiseKeyboard();
     964    }
     965
     966    bool InputManager::initialiseMouse()
     967    {
     968        return _getInstance()._initialiseMouse();
     969    }
     970
     971    bool InputManager::initialiseJoySticks()
     972    {
     973        return _getInstance()._initialiseJoySticks();
     974    }
     975
     976    int InputManager::numberOfKeyboards()
     977    {
     978        if (_getInstance().keyboard_ != 0)
     979            return 1;
     980        else
     981            return 0;
     982    }
     983
     984    int InputManager::numberOfMice()
     985    {
     986        if (_getInstance().mouse_ != 0)
     987            return 1;
     988        else
     989            return 0;
     990    }
     991
     992    int InputManager::numberOfJoySticks()
     993    {
     994        return _getInstance().joySticksSize_;
     995    }
     996
     997    /*bool InputManager::isKeyDown(KeyCode::Enum key)
     998    {
     999    if (_getInstance().keyboard_)
     1000        return _getInstance().keyboard_->isKeyDown((OIS::KeyCode)key);
     1001    else
    1341002        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     }
     1003    }*/
     1004
     1005    /*bool InputManager::isModifierDown(KeyboardModifier::Enum modifier)
     1006    {
     1007    if (_getInstance().keyboard_)
     1008        return isModifierDown(modifier);
    1791009    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;
    2111010        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;
     1011    }*/
     1012
     1013    /*const MouseState InputManager::getMouseState()
     1014    {
     1015    if (_getInstance().mouse_)
     1016        return _getInstance().mouse_->getMouseState();
     1017    else
     1018        return MouseState();
     1019    }*/
     1020
     1021    /*const JoyStickState InputManager::getJoyStickState(unsigned int ID)
     1022    {
     1023    if (ID < _getInstance().joySticksSize_)
     1024        return JoyStickState(_getInstance().joySticks_[ID]->getJoyStickState(), ID);
     1025    else
     1026        return JoyStickState();
     1027    }*/
     1028
     1029    void InputManager::destroy()
     1030    {
     1031        _getInstance()._destroy();
     1032    }
     1033
     1034    void InputManager::destroyKeyboard()
     1035    {
     1036        return _getInstance()._destroyKeyboard();
     1037    }
     1038
     1039    void InputManager::destroyMouse()
     1040    {
     1041        return _getInstance()._destroyMouse();
     1042    }
     1043
     1044    void InputManager::destroyJoySticks()
     1045    {
     1046        return _getInstance()._destroyJoySticks();
     1047    }
     1048
     1049
     1050    /**
     1051    @brief
     1052        Adjusts the mouse window metrics.
     1053        This method has to be called every time the size of the window changes.
     1054    @param width
     1055        The new width of the render window
     1056    @param^height
     1057        The new height of the render window
     1058    */
     1059    void InputManager::setWindowExtents(const int width, const int height)
     1060    {
     1061        if (_getInstance().mouse_)
     1062        {
     1063            // Set mouse region (if window resizes, we should alter this to reflect as well)
     1064            const OIS::MouseState &mouseState = _getInstance().mouse_->getMouseState();
     1065            mouseState.width  = width;
     1066            mouseState.height = height;
     1067        }
     1068    }
     1069
     1070    void InputManager::storeKeyStroke(const std::string& name)
     1071    {
     1072        requestLeaveState("detector");
     1073        COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl;
     1074        CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false);
     1075    }
     1076
     1077    void InputManager::keyBind(const std::string& command)
     1078    {
     1079        bindingCommmandString_s = command;
     1080        requestEnterState("detector");
     1081        COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
     1082    }
     1083
     1084    void InputManager::calibrate()
     1085    {
     1086        requestEnterState("calibrator");
     1087    }
     1088
     1089    void InputManager::tick(float dt)
     1090    {
     1091        _getInstance()._tick(dt);
     1092    }
     1093
     1094    // ###### InputStates ######
     1095
     1096    /**
     1097    @brief
     1098        Adds a new key handler.
     1099    @param handler
     1100        Pointer to the handler object.
     1101    @param name
     1102        Unique name of the handler.
     1103    @return
     1104        True if added, false if name already existed.
     1105    */
     1106    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
     1107    {
     1108        if (name == "")
     1109            return false;
     1110        if (_getInstance().inputStatesByName_.find(name) == _getInstance().inputStatesByName_.end())
     1111        {
     1112            if (_getInstance().inputStatesByPriority_.find(priority)
     1113                == _getInstance().inputStatesByPriority_.end())
     1114            {
     1115                _getInstance().inputStatesByName_[name] = state;
     1116                _getInstance().inputStatesByPriority_[priority] = state;
     1117                state->setNumOfJoySticks(numberOfJoySticks());
     1118                state->setName(name);
     1119                state->setPriority(priority);
     1120                return true;
     1121            }
     1122            else
     1123            {
     1124                COUT(2) << "Warning: Could not add an InputState with the same priority '"
     1125                    << priority << "'." << std::endl;
     1126                return false;
     1127            }
     1128        }
     1129        else
     1130        {
     1131            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
     1132            return false;
     1133        }
     1134    }
     1135
     1136    SimpleInputState* InputManager::createSimpleInputState(const std::string &name, int priority)
     1137    {
     1138        SimpleInputState* state = new SimpleInputState();
     1139        if (_getInstance()._configureInputState(state, name, priority))
     1140            return state;
     1141        else
     1142        {
     1143            delete state;
     1144            return 0;
     1145        }
     1146    }
     1147
     1148    ExtendedInputState* InputManager::createExtendedInputState(const std::string &name, int priority)
     1149    {
     1150        ExtendedInputState* state = new ExtendedInputState();
     1151        if (_getInstance()._configureInputState(state, name, priority))
     1152            return state;
     1153        else
     1154        {
     1155            delete state;
     1156            return 0;
     1157        }
     1158    }
     1159
     1160    /**
     1161    @brief
     1162        Removes a Key handler from the list.
     1163    @param name
     1164        Unique name of the handler.
     1165    @return
     1166        True if removal was successful, false if name was not found.
     1167    */
     1168    bool InputManager::destroyState(const std::string& name)
     1169    {
     1170        if (name == "empty" || name == "calibrator" || name == "detector")
     1171        {
     1172            COUT(2) << "InputManager: Removing the '" << name << "' state is not allowed!" << std::endl;
     1173            return false;
     1174        }
     1175        std::map<std::string, InputState*>::iterator it = _getInstance().inputStatesByName_.find(name);
     1176        if (it != _getInstance().inputStatesByName_.end())
     1177        {
     1178            _getInstance()._destroyState((*it).second);
     1179            return true;
     1180        }
    2481181        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<MultiTypeMath> coeffPos;
    324       std::vector<MultiTypeMath> coeffNeg;
    325       std::vector<MultiTypeMath> 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);
    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);
    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);
    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         }
     1182    }
     1183
     1184    /**
     1185    @brief
     1186        Returns the pointer to a handler.
     1187    @param name
     1188        Unique name of the handler.
     1189    @return
     1190        Pointer to the instance, 0 if name was not found.
     1191    */
     1192    InputState* InputManager::getState(const std::string& name)
     1193    {
     1194        std::map<std::string, InputState*>::iterator it = _getInstance().inputStatesByName_.find(name);
     1195        if (it != _getInstance().inputStatesByName_.end())
     1196            return (*it).second;
    5991197        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 
    726     // update modifiers
    727     if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
    728       keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
    729     if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
    730       keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
    731     if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
    732       keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
    733 
    734     for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++)
    735       activeKeyHandlers_[i]->keyPressed(KeyEvent(e, keyboardModifiers_));
    736 
    737     return true;
    738   }
    739 
    740   /**
    741     @brief Event handler for the keyReleased Event.
    742     @param e Event information
    743   */
    744   bool InputManager::keyReleased(const OIS::KeyEvent &e)
    745   {
    746     // remove the key from the keysDown_ list
    747     for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
    748     {
    749       if (keysDown_[iKey].key == (KeyCode::Enum)e.key)
    750       {
    751         keysDown_.erase(keysDown_.begin() + iKey);
    752         break;
    753       }
    754     }
    755 
    756     // update modifiers
    757     if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
    758       keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
    759     if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
    760       keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
    761     if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
    762       keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
    763 
    764     for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++)
    765       activeKeyHandlers_[i]->keyReleased(KeyEvent(e, keyboardModifiers_));
    766 
    767     return true;
    768   }
    769 
    770 
    771   // ###### Mouse Events ######
    772 
    773   /**
    774     @brief Event handler for the mouseMoved Event.
    775     @param e Event information
    776   */
    777   bool InputManager::mouseMoved(const OIS::MouseEvent &e)
    778   {
    779     // check for actual moved event
    780     if (e.state.X.rel != 0 || e.state.Y.rel != 0)
    781     {
    782       for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
    783         activeMouseHandlers_[i]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs),
    784             IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height));
    785     }
    786 
    787     // check for mouse scrolled event
    788     if (e.state.Z.rel != 0)
    789     {
    790       for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
    791         activeMouseHandlers_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
    792     }
    793 
    794     return true;
    795   }
    796 
    797   /**
    798     @brief Event handler for the mousePressed Event.
    799     @param e Event information
    800     @param id The ID of the mouse button
    801   */
    802   bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
    803   {
    804     // check whether the button already is in the list (can happen when focus was lost)
    805     unsigned int iButton = 0;
    806     while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButton::Enum)id)
    807       iButton++;
    808     if (iButton == mouseButtonsDown_.size())
    809       mouseButtonsDown_.push_back((MouseButton::Enum)id);
    810 
    811     for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
    812       activeMouseHandlers_[i]->mouseButtonPressed((MouseButton::Enum)id);
    813 
    814     return true;
    815   }
    816 
    817   /**
    818     @brief Event handler for the mouseReleased Event.
    819     @param e Event information
    820     @param id The ID of the mouse button
    821   */
    822   bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
    823   {
    824     // remove the button from the keysDown_ list
    825     for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
    826     {
    827       if (mouseButtonsDown_[iButton] == (MouseButton::Enum)id)
    828       {
    829         mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
    830         break;
    831       }
    832     }
    833 
    834     for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
    835       activeMouseHandlers_[i]->mouseButtonReleased((MouseButton::Enum)id);
    836 
    837     return true;
    838   }
    839 
    840 
    841   // ###### Joy Stick Events ######
    842 
    843   inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
    844   {
    845     // use the device to identify which one called the method
    846     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    847     unsigned int iJoyStick = 0;
    848     while (joySticks_[iJoyStick] != joyStick)
    849     {
    850       iJoyStick++;
    851       if (iJoyStick == joySticksSize_)
    852       {
    853         CCOUT(3) << "Unknown joystick fired an event. This means there is a bug somewhere! Aborting." << std::endl;
    854         abort();
    855       }
    856     }
    857     return iJoyStick;
    858   }
    859 
    860   bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
    861   {
    862     unsigned int iJoyStick = _getJoystick(arg);
    863 
    864     // check whether the button already is in the list (can happen when focus was lost)
    865     std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    866     unsigned int iButton = 0;
    867     while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
    868       iButton++;
    869     if (iButton == buttonsDown.size())
    870       buttonsDown.push_back(button);
    871 
    872     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    873       activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonPressed(iJoyStick, button);
    874 
    875     return true;
    876   }
    877 
    878   bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
    879   {
    880     unsigned int iJoyStick = _getJoystick(arg);
    881 
    882     // remove the button from the joyStickButtonsDown_ list
    883     std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    884     for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
    885     {
    886       if (buttonsDown[iButton] == button)
    887       {
    888         buttonsDown.erase(buttonsDown.begin() + iButton);
    889         break;
    890       }
    891     }
    892 
    893     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    894       activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonReleased(iJoyStick, button);
    895 
    896     return true;
    897   }
    898 
    899   void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
    900   {
    901     if (state_ == IS_CALIBRATE)
    902     {
    903       if (value > marginalsMax_[axis])
    904         marginalsMax_[axis] = value;
    905       if (value < marginalsMin_[axis])
    906         marginalsMin_[axis] = value;
    907     }
    908     else
    909     {
    910       float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis];
    911       if (fValue > 0.0f)
    912         fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis];
    913       else
    914         fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis];
    915 
    916       for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    917         activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis, fValue);
    918     }
    919   }
    920 
    921   bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
    922   {
    923     //if (arg.state.mAxes[axis].abs > 10000 || arg.state.mAxes[axis].abs < -10000)
    924     //{ CCOUT(3) << "axis " << axis << " moved" << arg.state.mAxes[axis].abs << std::endl;}
    925 
    926     unsigned int iJoyStick = _getJoystick(arg);
    927 
    928     // keep in mind that the first 8 axes are reserved for the sliders
    929     _fireAxis(iJoyStick, axis + 8, arg.state.mAxes[axis].abs);
    930 
    931     return true;
    932   }
    933 
    934   bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
    935   {
    936     //if (arg.state.mSliders[id].abX > 10000 || arg.state.mSliders[id].abX < -10000)
    937     //{CCOUT(3) << "slider " << id << " moved" << arg.state.mSliders[id].abX << std::endl;}
    938     //CCOUT(3) << arg.state.mSliders[id].abX << "\t |" << arg.state.mSliders[id].abY << std::endl;
    939 
    940     unsigned int iJoyStick = _getJoystick(arg);
    941 
    942     if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
    943       _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
    944     else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
    945       _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
    946 
    947     return true;
    948   }
    949 
    950   bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
    951   {
    952     unsigned int iJoyStick = _getJoystick(arg);
    953 
    954     // translate the POV into 8 simple buttons
    955     int lastState = povStates_[iJoyStick][id];
    956     if (lastState & OIS::Pov::North)
    957       buttonReleased(arg, 32 + id * 4 + 0);
    958     if (lastState & OIS::Pov::South)
    959       buttonReleased(arg, 32 + id * 4 + 1);
    960     if (lastState & OIS::Pov::East)
    961       buttonReleased(arg, 32 + id * 4 + 2);
    962     if (lastState & OIS::Pov::West)
    963       buttonReleased(arg, 32 + id * 4 + 3);
    964 
    965     povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
    966 
    967     int currentState = povStates_[iJoyStick][id];
    968     if (currentState & OIS::Pov::North)
    969       buttonPressed(arg, 32 + id * 4 + 0);
    970     if (currentState & OIS::Pov::South)
    971       buttonPressed(arg, 32 + id * 4 + 1);
    972     if (currentState & OIS::Pov::East)
    973       buttonPressed(arg, 32 + id * 4 + 2);
    974     if (currentState & OIS::Pov::West)
    975       buttonPressed(arg, 32 + id * 4 + 3);
    976 
    977     return true;
    978   }
    979 
    980   /*bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id)
    981   {
    982     unsigned int iJoyStick = _getJoystick(arg);
    983 
    984     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    985       activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickVector3Moved(JoyStickState(arg.state, iJoyStick), id);
    986 
    987     return true;
    988   }*/
    989 
    990 
    991   // ################################
    992   // ### Static Interface Methods ###
    993   // ################################
    994   // ################################
    995 
    996   std::string InputManager::bindingCommmandString_s = "";
    997 
    998   bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    999     bool createKeyboard, bool createMouse, bool createJoySticks)
    1000   {
    1001     return _getSingleton()._initialise(windowHnd, windowWidth, windowHeight,
    1002           createKeyboard, createMouse, createJoySticks);
    1003   }
    1004 
    1005   bool InputManager::initialiseKeyboard()
    1006   {
    1007     return _getSingleton()._initialiseKeyboard();
    1008   }
    1009 
    1010   bool InputManager::initialiseMouse()
    1011   {
    1012     return _getSingleton()._initialiseMouse();
    1013   }
    1014 
    1015   bool InputManager::initialiseJoySticks()
    1016   {
    1017     return _getSingleton()._initialiseJoySticks();
    1018   }
    1019 
    1020   int InputManager::numberOfKeyboards()
    1021   {
    1022     if (_getSingleton().keyboard_ != 0)
    1023       return 1;
    1024     else
    1025       return 0;
    1026   }
    1027 
    1028   int InputManager::numberOfMice()
    1029   {
    1030     if (_getSingleton().mouse_ != 0)
    1031       return 1;
    1032     else
    1033       return 0;
    1034   }
    1035 
    1036   int InputManager::numberOfJoySticks()
    1037   {
    1038     return _getSingleton().joySticksSize_;
    1039   }
    1040 
    1041   /*bool InputManager::isKeyDown(KeyCode::Enum key)
    1042   {
    1043     if (_getSingleton().keyboard_)
    1044       return _getSingleton().keyboard_->isKeyDown((OIS::KeyCode)key);
    1045     else
    1046       return false;
    1047   }*/
    1048 
    1049   /*bool InputManager::isModifierDown(KeyboardModifier::Enum modifier)
    1050   {
    1051     if (_getSingleton().keyboard_)
    1052       return isModifierDown(modifier);
    1053     else
    1054       return false;
    1055   }*/
    1056 
    1057   /*const MouseState InputManager::getMouseState()
    1058   {
    1059     if (_getSingleton().mouse_)
    1060       return _getSingleton().mouse_->getMouseState();
    1061     else
    1062       return MouseState();
    1063   }*/
    1064 
    1065   /*const JoyStickState InputManager::getJoyStickState(unsigned int ID)
    1066   {
    1067     if (ID < _getSingleton().joySticksSize_)
    1068       return JoyStickState(_getSingleton().joySticks_[ID]->getJoyStickState(), ID);
    1069     else
    1070       return JoyStickState();
    1071   }*/
    1072 
    1073   void InputManager::destroy()
    1074   {
    1075     _getSingleton()._destroy();
    1076   }
    1077 
    1078   void InputManager::destroyKeyboard()
    1079   {
    1080     return _getSingleton()._destroyKeyboard();
    1081   }
    1082 
    1083   void InputManager::destroyMouse()
    1084   {
    1085     return _getSingleton()._destroyMouse();
    1086   }
    1087 
    1088   void InputManager::destroyJoySticks()
    1089   {
    1090     return _getSingleton()._destroyJoySticks();
    1091   }
    1092 
    1093 
    1094   /**
    1095     @brief Adjusts the mouse window metrics.
    1096     This method has to be called every time the size of the window changes.
    1097     @param width The new width of the render window
    1098     @param height the new height of the render window
    1099   */
    1100   void InputManager::setWindowExtents(const int width, const int height)
    1101   {
    1102     if (_getSingleton().mouse_)
    1103     {
    1104       // Set mouse region (if window resizes, we should alter this to reflect as well)
    1105       const OIS::MouseState &mouseState = _getSingleton().mouse_->getMouseState();
    1106       mouseState.width  = width;
    1107       mouseState.height = height;
    1108     }
    1109   }
    1110 
    1111   /**
    1112     @brief Sets the input mode to either GUI, inGame or Buffer
    1113     @param mode The new input mode
    1114     @remark Only has an affect if the mode actually changes
    1115   */
    1116   void InputManager::setInputState(const InputState state)
    1117   {
    1118     _getSingleton().stateRequest_ = state;
    1119   }
    1120 
    1121   /**
    1122     @brief Returns the current input handling method
    1123     @return The current input mode.
    1124   */
    1125   InputManager::InputState InputManager::getInputState()
    1126   {
    1127     return _getSingleton().state_;
    1128   }
    1129 
    1130   void InputManager::storeKeyStroke(const std::string& name)
    1131   {
    1132     setInputState(IS_NODETECT);
    1133     COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl;
    1134     CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false);
    1135   }
    1136 
    1137   void InputManager::keyBind(const std::string& command)
    1138   {
    1139     bindingCommmandString_s = command;
    1140     setInputState(IS_DETECT);
    1141     COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
    1142   }
    1143 
    1144   void InputManager::calibrate()
    1145   {
    1146     _getSingleton().setInputState(IS_CALIBRATE);
    1147   }
    1148 
    1149   void InputManager::tick(float dt)
    1150   {
    1151     _getSingleton()._tick(dt);
    1152   }
    1153 
    1154   // ###### KeyHandler ######
    1155 
    1156   /**
    1157     @brief Adds a new key handler.
    1158     @param handler Pointer to the handler object.
    1159     @param name Unique name of the handler.
    1160     @return True if added, false if name already existed.
    1161   */
    1162   bool InputManager::addKeyHandler(KeyHandler* handler, const std::string& name)
    1163   {
    1164     if (!handler)
    1165       return false;
    1166     if (_getSingleton().keyHandlers_.find(name) == _getSingleton().keyHandlers_.end())
    1167     {
    1168       _getSingleton().keyHandlers_[name] = handler;
    1169       return true;
    1170     }
    1171     else
    1172       return false;
    1173   }
    1174 
    1175   /**
    1176     @brief Removes a Key handler from the list.
    1177     @param name Unique name of the handler.
    1178     @return True if removal was successful, false if name was not found.
    1179   */
    1180   bool InputManager::removeKeyHandler(const std::string &name)
    1181   {
    1182     disableKeyHandler(name);
    1183     std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name);
    1184     if (it != _getSingleton().keyHandlers_.end())
    1185     {
    1186       _getSingleton().keyHandlers_.erase(it);
    1187       return true;
    1188     }
    1189     else
    1190       return false;
    1191   }
    1192 
    1193   /**
    1194     @brief Returns the pointer to a handler.
    1195     @param name Unique name of the handler.
    1196     @return Pointer to the instance, 0 if name was not found.
    1197   */
    1198   KeyHandler* InputManager::getKeyHandler(const std::string& name)
    1199   {
    1200     std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name);
    1201     if (it != _getSingleton().keyHandlers_.end())
    1202     {
    1203       return (*it).second;
    1204     }
    1205     else
    1206       return 0;
    1207   }
    1208 
    1209   /**
    1210     @brief Enables a specific key handler that has already been added.
    1211     @param name Unique name of the handler.
    1212     @return False if name was not found, true otherwise.
    1213   */
    1214   bool InputManager::enableKeyHandler(const std::string& name)
    1215   {
    1216     // get pointer from the map with all stored handlers
    1217     std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
    1218     if (mapIt == _getSingleton().keyHandlers_.end())
    1219       return false;
    1220     // see whether the handler already is in the list
    1221     for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
    1222           it != _getSingleton().activeKeyHandlers_.end(); it++)
    1223     {
    1224       if ((*it) == (*mapIt).second)
    1225       {
    1226         return true;
    1227       }
    1228     }
    1229     _getSingleton().activeKeyHandlers_.push_back((*mapIt).second);
    1230     _getSingleton().stateRequest_ = IS_CUSTOM;
    1231     _getSingleton()._updateTickables();
    1232     return true;
    1233   }
    1234 
    1235   /**
    1236     @brief Disables a specific key handler.
    1237     @param name Unique name of the handler.
    1238     @return False if name was not found, true otherwise.
    1239   */
    1240   bool InputManager::disableKeyHandler(const std::string &name)
    1241   {
    1242     // get pointer from the map with all stored handlers
    1243     std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
    1244     if (mapIt == _getSingleton().keyHandlers_.end())
    1245       return false;
    1246     // look for the handler in the list
    1247     for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
    1248           it != _getSingleton().activeKeyHandlers_.end(); it++)
    1249     {
    1250       if ((*it) == (*mapIt).second)
    1251       {
    1252         _getSingleton().activeKeyHandlers_.erase(it);
    1253         _getSingleton().stateRequest_ = IS_CUSTOM;
    1254         _getSingleton()._updateTickables();
    1255         return true;
    1256       }
    1257     }
    1258     return true;
    1259   }
    1260 
    1261   /**
    1262     @brief Checks whether a key handler is active
    1263     @param name Unique name of the handler.
    1264     @return False if key handler is not active or doesn't exist, true otherwise.
    1265   */
    1266   bool InputManager::isKeyHandlerActive(const std::string& name)
    1267   {
    1268     // get pointer from the map with all stored handlers
    1269     std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
    1270     if (mapIt == _getSingleton().keyHandlers_.end())
    1271       return false;
    1272     // see whether the handler already is in the list
    1273     for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
    1274           it != _getSingleton().activeKeyHandlers_.end(); it++)
    1275     {
    1276       if ((*it) == (*mapIt).second)
    1277         return true;
    1278     }
    1279     return false;
    1280   }
    1281 
    1282 
    1283   // ###### MouseHandler ######
    1284   /**
    1285     @brief Adds a new mouse handler.
    1286     @param handler Pointer to the handler object.
    1287     @param name Unique name of the handler.
    1288     @return True if added, false if name already existed.
    1289   */
    1290   bool InputManager::addMouseHandler(MouseHandler* handler, const std::string& name)
    1291   {
    1292     if (!handler)
    1293       return false;
    1294     if (_getSingleton().mouseHandlers_.find(name) == _getSingleton().mouseHandlers_.end())
    1295     {
    1296       _getSingleton().mouseHandlers_[name] = handler;
    1297       return true;
    1298     }
    1299     else
    1300       return false;
    1301   }
    1302 
    1303   /**
    1304     @brief Removes a Mouse handler from the list.
    1305     @param name Unique name of the handler.
    1306     @return True if removal was successful, false if name was not found.
    1307   */
    1308   bool InputManager::removeMouseHandler(const std::string &name)
    1309   {
    1310     disableMouseHandler(name);
    1311     std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name);
    1312     if (it != _getSingleton().mouseHandlers_.end())
    1313     {
    1314       _getSingleton().mouseHandlers_.erase(it);
    1315       return true;
    1316     }
    1317     else
    1318       return false;
    1319   }
    1320 
    1321   /**
    1322     @brief Returns the pointer to a handler.
    1323     @param name Unique name of the handler.
    1324     @return Pointer to the instance, 0 if name was not found.
    1325   */
    1326   MouseHandler* InputManager::getMouseHandler(const std::string& name)
    1327   {
    1328     std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name);
    1329     if (it != _getSingleton().mouseHandlers_.end())
    1330     {
    1331       return (*it).second;
    1332     }
    1333     else
    1334       return 0;
    1335   }
    1336 
    1337   /**
    1338     @brief Enables a specific mouse handler that has already been added.
    1339     @param name Unique name of the handler.
    1340     @return False if name was not found, true otherwise.
    1341   */
    1342   bool InputManager::enableMouseHandler(const std::string& name)
    1343   {
    1344     // get pointer from the map with all stored handlers
    1345     std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
    1346     if (mapIt == _getSingleton().mouseHandlers_.end())
    1347       return false;
    1348     // see whether the handler already is in the list
    1349     for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
    1350           it != _getSingleton().activeMouseHandlers_.end(); it++)
    1351     {
    1352       if ((*it) == (*mapIt).second)
    1353       {
    1354         return true;
    1355       }
    1356     }
    1357     _getSingleton().activeMouseHandlers_.push_back((*mapIt).second);
    1358     _getSingleton().stateRequest_ = IS_CUSTOM;
    1359     _getSingleton()._updateTickables();
    1360     return true;
    1361   }
    1362 
    1363   /**
    1364     @brief Disables a specific mouse handler.
    1365     @param name Unique name of the handler.
    1366     @return False if name was not found, true otherwise.
    1367   */
    1368   bool InputManager::disableMouseHandler(const std::string &name)
    1369   {
    1370     // get pointer from the map with all stored handlers
    1371     std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
    1372     if (mapIt == _getSingleton().mouseHandlers_.end())
    1373       return false;
    1374     // look for the handler in the list
    1375     for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
    1376           it != _getSingleton().activeMouseHandlers_.end(); it++)
    1377     {
    1378       if ((*it) == (*mapIt).second)
    1379       {
    1380         _getSingleton().activeMouseHandlers_.erase(it);
    1381         _getSingleton().stateRequest_ = IS_CUSTOM;
    1382         _getSingleton()._updateTickables();
    1383         return true;
    1384       }
    1385     }
    1386     return true;
    1387   }
    1388 
    1389   /**
    1390     @brief Checks whether a mouse handler is active
    1391     @param name Unique name of the handler.
    1392     @return False if key handler is not active or doesn't exist, true otherwise.
    1393   */
    1394   bool InputManager::isMouseHandlerActive(const std::string& name)
    1395   {
    1396     // get pointer from the map with all stored handlers
    1397     std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
    1398     if (mapIt == _getSingleton().mouseHandlers_.end())
    1399       return false;
    1400     // see whether the handler already is in the list
    1401     for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
    1402           it != _getSingleton().activeMouseHandlers_.end(); it++)
    1403     {
    1404       if ((*it) == (*mapIt).second)
    1405         return true;
    1406     }
    1407     return false;
    1408   }
    1409 
    1410 
    1411   // ###### JoyStickHandler ######
    1412 
    1413   /**
    1414     @brief Adds a new joy stick handler.
    1415     @param handler Pointer to the handler object.
    1416     @param name Unique name of the handler.
    1417     @return True if added, false if name already existed.
    1418   */
    1419   bool InputManager::addJoyStickHandler(JoyStickHandler* handler, const std::string& name)
    1420   {
    1421     if (!handler)
    1422       return false;
    1423     if (_getSingleton().joyStickHandlers_.find(name) == _getSingleton().joyStickHandlers_.end())
    1424     {
    1425       _getSingleton().joyStickHandlers_[name] = handler;
    1426       return true;
    1427     }
    1428     else
    1429       return false;
    1430   }
    1431 
    1432   /**
    1433     @brief Removes a JoyStick handler from the list.
    1434     @param name Unique name of the handler.
    1435     @return True if removal was successful, false if name was not found.
    1436   */
    1437   bool InputManager::removeJoyStickHandler(const std::string &name)
    1438   {
    1439     for (std::vector<OIS::JoyStick*>::iterator itstick = _getSingleton().joySticks_.begin();
    1440           itstick != _getSingleton().joySticks_.end(); itstick++)
    1441       disableJoyStickHandler(name, itstick - _getSingleton().joySticks_.begin());
    1442 
    1443     std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name);
    1444     if (it != _getSingleton().joyStickHandlers_.end())
    1445     {
    1446       _getSingleton().joyStickHandlers_.erase(it);
    1447       return true;
    1448     }
    1449     else
    1450       return false;
    1451   }
    1452 
    1453   /**
    1454     @brief Returns the pointer to a handler.
    1455     @param name Unique name of the handler.
    1456     @return Pointer to the instance, 0 if name was not found.
    1457   */
    1458   JoyStickHandler* InputManager::getJoyStickHandler(const std::string& name)
    1459   {
    1460     std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name);
    1461     if (it != _getSingleton().joyStickHandlers_.end())
    1462     {
    1463       return (*it).second;
    1464     }
    1465     else
    1466       return 0;
    1467   }
    1468 
    1469   /**
    1470     @brief Enables a specific joy stick handler that has already been added.
    1471     @param name Unique name of the handler.
    1472     @return False if name or id was not found, true otherwise.
    1473   */
    1474   bool InputManager::enableJoyStickHandler(const std::string& name, unsigned int ID)
    1475   {
    1476     // get handler pointer from the map with all stored handlers
    1477     std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
    1478     if (handlerIt == _getSingleton().joyStickHandlers_.end())
    1479       return false;
    1480 
    1481     // check for existence of the ID
    1482     if (ID >= _getSingleton().joySticksSize_)
    1483       return false;
    1484 
    1485     // see whether the handler already is in the list
    1486     for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
    1487           it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
    1488     {
    1489       if ((*it) == (*handlerIt).second)
    1490       {
    1491         return true;
    1492       }
    1493     }
    1494     _getSingleton().activeJoyStickHandlers_[ID].push_back((*handlerIt).second);
    1495     _getSingleton().stateRequest_ = IS_CUSTOM;
    1496     _getSingleton()._updateTickables();
    1497     return true;
    1498   }
    1499 
    1500   /**
    1501     @brief Disables a specific joy stick handler.
    1502     @param name Unique name of the handler.
    1503     @return False if name or id was not found, true otherwise.
    1504   */
    1505   bool InputManager::disableJoyStickHandler(const std::string &name, unsigned int ID)
    1506   {
    1507     // get handler pointer from the map with all stored handlers
    1508     std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
    1509     if (handlerIt == _getSingleton().joyStickHandlers_.end())
    1510       return false;
    1511 
    1512     // check for existence of the ID
    1513     if (ID >= _getSingleton().joySticksSize_)
    1514       return false;
    1515 
    1516     // look for the handler in the list
    1517     for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
    1518           it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
    1519     {
    1520       if ((*it) == (*handlerIt).second)
    1521       {
    1522         _getSingleton().activeJoyStickHandlers_[ID].erase(it);
    1523         _getSingleton().stateRequest_ = IS_CUSTOM;
    1524         _getSingleton()._updateTickables();
    1525         return true;
    1526       }
    1527     }
    1528     return true;
    1529   }
    1530 
    1531   /**
    1532     @brief Checks whether a joy stick handler is active
    1533     @param name Unique name of the handler.
    1534     @return False if key handler is not active or doesn't exist, true otherwise.
    1535   */
    1536   bool InputManager::isJoyStickHandlerActive(const std::string& name, unsigned int ID)
    1537   {
    1538     // get handler pointer from the map with all stored handlers
    1539     std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
    1540     if (handlerIt == _getSingleton().joyStickHandlers_.end())
    1541       return false;
    1542 
    1543     // check for existence of the ID
    1544     if (ID >= _getSingleton().joySticksSize_)
    1545       return false;
    1546 
    1547     // see whether the handler already is in the list
    1548     for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
    1549           it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
    1550     {
    1551       if ((*it) == (*handlerIt).second)
    1552         return true;
    1553     }
    1554     return false;
    1555   }
    1556 
     1198            return 0;
     1199    }
     1200
     1201    /**
     1202    @brief
     1203        Returns the current input handling method
     1204    @return
     1205        The current input mode.
     1206    */
     1207    InputState* InputManager::getCurrentState()
     1208    {
     1209        return (*_getInstance().activeStates_.rbegin()).second;
     1210    }
     1211
     1212    /**
     1213    @brief
     1214        Enables a specific key handler that has already been added.
     1215    @param name
     1216        Unique name of the handler.
     1217    @return
     1218        False if name was not found, true otherwise.
     1219    */
     1220    bool InputManager::requestEnterState(const std::string& name)
     1221    {
     1222        // get pointer from the map with all stored handlers
     1223        std::map<std::string, InputState*>::const_iterator it = _getInstance().inputStatesByName_.find(name);
     1224        if (it != _getInstance().inputStatesByName_.end())
     1225        {
     1226            _getInstance().stateEnterRequests_.push_back((*it).second);
     1227            return true;
     1228        }
     1229        return false;
     1230    }
     1231
     1232    bool InputManager::requestLeaveState(const std::string& name)
     1233    {
     1234        // get pointer from the map with all stored handlers
     1235        std::map<std::string, InputState*>::const_iterator it = _getInstance().inputStatesByName_.find(name);
     1236        if (it != _getInstance().inputStatesByName_.end())
     1237        {
     1238            _getInstance().stateLeaveRequests_.push_back((*it).second);
     1239            return true;
     1240        }
     1241        return false;
     1242    }
    15571243}
  • code/branches/gui/src/core/input/InputManager.h

    r1555 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of a little Input handler that distributes everything
    32         coming from OIS.
    33  */
     30@file
     31@brief
     32    Implementation of a little Input handler that distributes everything
     33    coming from OIS.
     34*/
    3435
    3536#ifndef _InputManager_H__
     
    4041#include <map>
    4142#include <vector>
    42 
     43#include <stack>
    4344#include "util/Math.h"
    4445#include "core/OrxonoxClass.h"
     
    4748namespace orxonox
    4849{
    49   /**
    50   * Helper class to realise a vector<int[4]>
    51   */
    52   class POVStates
    53   {
    54   public:
    55     int operator[](unsigned int index) { return povStates[index]; }
    56     int povStates[4];
    57   };
    58 
    59   /**
    60   * Helper class to realise a vector< {int[4], int[4]} >
    61   */
    62   class SliderStates
    63   {
    64   public:
    65     IntVector2 sliderStates[4];
    66   };
    67 
    68   /**
    69   * Struct for storing a custom input state
    70   */
    71   struct StoredState
    72   {
    73     std::vector<KeyHandler*>                    activeKeyHandlers_;
    74     std::vector<MouseHandler*>                  activeMouseHandlers_;
    75     std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
    76     std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
    77   };
    78 
    79   struct JoyStickCalibration
    80   {
    81     int zeroStates[24];
    82     float positiveCoeff[24];
    83     float negativeCoeff[24];
    84   };
    85 
    86   /**
    87     @brief Captures and distributes mouse and keyboard input.
    88   */
    89   class _CoreExport InputManager
     50    /**
     51    @brief
     52        Helper class to realise a vector<int[4]>
     53    */
     54    class POVStates
     55    {
     56    public:
     57        int operator[](unsigned int index) { return povStates[index]; }
     58        int povStates[4];
     59    };
     60
     61    /**
     62    @brief
     63        Helper class to realise a vector< {int[4], int[4]} >
     64    */
     65    class SliderStates
     66    {
     67    public:
     68        IntVector2 sliderStates[4];
     69    };
     70
     71    struct JoyStickCalibration
     72    {
     73        int zeroStates[24];
     74        float positiveCoeff[24];
     75        float negativeCoeff[24];
     76    };
     77
     78    /**
     79    @brief
     80        Captures and distributes mouse and keyboard input.
     81    */
     82    class _CoreExport InputManager
    9083        : public OrxonoxClass,
    91           public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
    92   {
    93   public: // enumerations
    94     /**
    95       @brief Designates the way input is handled and redirected.
    96     */
    97     enum InputState
    98     {
    99       IS_UNINIT,    //!< InputManager has not yet been initialised.
    100       IS_NONE,      //!< Input is discarded.
    101       IS_NORMAL,    //!< Normal play state. Key and button bindings are active.
    102       IS_GUI,       //!< All OIS input events are passed to CEGUI.
    103       IS_CONSOLE,   //!< Keyboard input is redirected to the InputBuffer.
    104       IS_DETECT,    //!< All the input additionally goes to the KeyDetector
    105       IS_NODETECT,  //!< remove KeyDetector
    106       IS_NOCALIBRATE,
    107       IS_CALIBRATE,
    108       IS_CUSTOM     //!< Any possible configuration.
    109     };
    110 
    111   public: // member functions
    112     void setConfigValues();
    113 
    114   public: // static functions
    115     static bool initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    116           bool createKeyboard = true, bool createMouse = true, bool createJoySticks = false);
    117     static bool initialiseKeyboard();
    118     static bool initialiseMouse();
    119     static bool initialiseJoySticks();
    120     static int  numberOfKeyboards();
    121     static int  numberOfMice();
    122     static int  numberOfJoySticks();
    123 
    124     static void destroy();
    125     static void destroyKeyboard();
    126     static void destroyMouse();
    127     static void destroyJoySticks();
    128 
    129     //static bool isModifierDown(KeyboardModifier::Enum modifier);
    130     //static bool isKeyDown(KeyCode::Enum key);
    131     //static const MouseState getMouseState();
    132     //static const JoyStickState getJoyStickState(unsigned int ID);
    133 
    134     static void setWindowExtents(const int width, const int height);
    135 
    136     static void setInputState(const InputState state);
    137     static InputState getInputState();
    138 
    139     static void storeKeyStroke(const std::string& name);
    140     static void keyBind(const std::string& command);
    141 
    142     static void calibrate();
    143 
    144     static void tick(float dt);
    145 
    146     static bool addKeyHandler                 (KeyHandler* handler, const std::string& name);
    147     static bool removeKeyHandler              (const std::string& name);
    148     static KeyHandler* getKeyHandler          (const std::string& name);
    149     static bool enableKeyHandler              (const std::string& name);
    150     static bool disableKeyHandler             (const std::string& name);
    151     static bool isKeyHandlerActive            (const std::string& name);
    152 
    153     static bool addMouseHandler               (MouseHandler* handler, const std::string& name);
    154     static bool removeMouseHandler            (const std::string& name);
    155     static MouseHandler* getMouseHandler      (const std::string& name);
    156     static bool enableMouseHandler            (const std::string& name);
    157     static bool disableMouseHandler           (const std::string& name);
    158     static bool isMouseHandlerActive          (const std::string& name);
    159 
    160     static bool addJoyStickHandler            (JoyStickHandler* handler, const std::string& name);
    161     static bool removeJoyStickHandler         (const std::string& name);
    162     static JoyStickHandler* getJoyStickHandler(const std::string& name);
    163     static bool enableJoyStickHandler         (const std::string& name, unsigned int id);
    164     static bool disableJoyStickHandler        (const std::string& name, unsigned int id);
    165     static bool isJoyStickHandlerActive       (const std::string& name, unsigned int id);
    166 
    167   private: // functions
    168     // don't mess with a Singleton
    169     InputManager ();
    170     InputManager (const InputManager&);
    171     ~InputManager();
    172 
    173     // Intenal methods
    174     bool _initialise(const size_t, int, int, bool, bool, bool);
    175     bool _initialiseKeyboard();
    176     bool _initialiseMouse();
    177     bool _initialiseJoySticks();
    178 
    179     void _destroy();
    180     void _destroyKeyboard();
    181     void _destroyMouse();
    182     void _destroyJoySticks();
    183 
    184     void _updateTickables();
    185 
    186     void _saveState();
    187     void _restoreState();
    188 
    189     void _completeCalibration();
    190 
    191     void _fireAxis(unsigned int iJoyStick, int axis, int value);
    192     unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
    193 
    194     void _tick(float dt);
    195 
    196     // input events
    197     bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
    198     bool mouseReleased (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
    199     bool mouseMoved    (const OIS::MouseEvent    &arg);
    200     bool keyPressed    (const OIS::KeyEvent      &arg);
    201     bool keyReleased   (const OIS::KeyEvent      &arg);
    202     bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
    203     bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
    204     bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
    205     bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
    206     bool povMoved      (const OIS::JoyStickEvent &arg, int id);
    207     //bool vector3Moved  (const OIS::JoyStickEvent &arg, int id);
    208 
    209     static InputManager& _getSingleton();
    210     static InputManager* _getSingletonPtr() { return &_getSingleton(); }
    211 
    212   private: // variables
    213     OIS::InputManager*                          inputSystem_;     //!< OIS input manager
    214     OIS::Keyboard*                              keyboard_;        //!< OIS mouse
    215     OIS::Mouse*                                 mouse_;           //!< OIS keyboard
    216     std::vector<OIS::JoyStick*>                 joySticks_;       //!< OIS joy sticks
    217     unsigned int                                joySticksSize_;
    218 
    219     KeyBinder*                                  keyBinder_;       //!< KeyBinder instance
    220     KeyDetector*                                keyDetector_;     //!< KeyDetector instance
    221     InputBuffer*                                buffer_;          //!< InputBuffer instance
    222     CalibratorCallback*                         calibratorCallback_;
    223 
    224     InputState state_;
    225     InputState stateRequest_;
    226     InputState savedState_;
    227     unsigned int keyboardModifiers_;
    228     StoredState savedHandlers_;
    229 
    230     // joystick calibration
    231     //std::vector<int> marginalsMaxConfig_;
    232     //std::vector<int> marginalsMinConfig_;
    233     int marginalsMax_[24];
    234     int marginalsMin_[24];
    235     bool bCalibrated_;
    236 
    237     //! Keeps track of the joy stick POV states
    238     std::vector<POVStates>                      povStates_;
    239     //! Keeps track of the possibly two slider axes
    240     std::vector<SliderStates>                   sliderStates_;
    241     std::vector<JoyStickCalibration>            joySticksCalibration_;
    242 
    243     std::map<std::string, KeyHandler*>          keyHandlers_;
    244     std::map<std::string, MouseHandler*>        mouseHandlers_;
    245     std::map<std::string, JoyStickHandler*>     joyStickHandlers_;
    246 
    247     std::vector<KeyHandler*>                    activeKeyHandlers_;
    248     std::vector<MouseHandler*>                  activeMouseHandlers_;
    249     std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
    250     std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
    251 
    252     std::vector<Key>                            keysDown_;
    253     std::vector<MouseButton::Enum>              mouseButtonsDown_;
    254     std::vector<std::vector<int> >              joyStickButtonsDown_;
    255 
    256     static std::string                          bindingCommmandString_s;
    257   };
     84        public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
     85    {
     86        // --> setConfigValues is private
     87        friend ClassIdentifier<InputManager>;
     88
     89    public: // static functions
     90        static bool initialise(const size_t windowHnd, int windowWidth, int windowHeight,
     91                               bool createKeyboard = true, bool createMouse = true, bool createJoySticks = false);
     92        static bool initialiseKeyboard();
     93        static bool initialiseMouse();
     94        static bool initialiseJoySticks();
     95        static int  numberOfKeyboards();
     96        static int  numberOfMice();
     97        static int  numberOfJoySticks();
     98
     99        static void destroy();
     100        static void destroyKeyboard();
     101        static void destroyMouse();
     102        static void destroyJoySticks();
     103
     104        //static bool isModifierDown(KeyboardModifier::Enum modifier);
     105        //static bool isKeyDown(KeyCode::Enum key);
     106        //static const MouseState getMouseState();
     107        //static const JoyStickState getJoyStickState(unsigned int ID);
     108
     109        static void setWindowExtents(const int width, const int height);
     110
     111        static void storeKeyStroke(const std::string& name);
     112        static void keyBind(const std::string& command);
     113
     114        static void calibrate();
     115
     116        static void tick(float dt);
     117
     118        static SimpleInputState*   createSimpleInputState  (const std::string& name, int priority);
     119        static ExtendedInputState* createExtendedInputState(const std::string& name, int priority);
     120        static bool destroyState (const std::string& name);
     121        //static bool removeState (const std::string& name);
     122        static InputState* getState       (const std::string& name);
     123        static InputState* getCurrentState();
     124        static bool requestEnterState     (const std::string& name);
     125        static bool requestLeaveState     (const std::string& name);
     126
     127    private: // functions
     128        // don't mess with a Singleton
     129        InputManager ();
     130        InputManager (const InputManager&);
     131        ~InputManager();
     132
     133        // Intenal methods
     134        bool _initialise(const size_t, int, int, bool, bool, bool);
     135        bool _initialiseKeyboard();
     136        bool _initialiseMouse();
     137        bool _initialiseJoySticks();
     138        void _redimensionLists();
     139
     140        void _destroy();
     141        void _destroyKeyboard();
     142        void _destroyMouse();
     143        void _destroyJoySticks();
     144        void _destroyState(InputState* state);
     145
     146        void _completeCalibration();
     147
     148        void _fireAxis(unsigned int iJoyStick, int axis, int value);
     149        unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
     150
     151        void _tick(float dt);
     152
     153        void _updateActiveStates();
     154        bool _configureInputState(InputState* state, const std::string& name, int priority);
     155
     156        // input events
     157        bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
     158        bool mouseReleased (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
     159        bool mouseMoved    (const OIS::MouseEvent    &arg);
     160        bool keyPressed    (const OIS::KeyEvent      &arg);
     161        bool keyReleased   (const OIS::KeyEvent      &arg);
     162        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
     163        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
     164        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
     165        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
     166        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
     167
     168        void setConfigValues();
     169
     170        static InputManager& _getInstance();
     171
     172    private: // variables
     173        OIS::InputManager*                          inputSystem_;     //!< OIS input manager
     174        OIS::Keyboard*                              keyboard_;        //!< OIS mouse
     175        OIS::Mouse*                                 mouse_;           //!< OIS keyboard
     176        std::vector<OIS::JoyStick*>                 joySticks_;       //!< OIS joy sticks
     177        unsigned int                                joySticksSize_;
     178        unsigned int                                devicesNum_;
     179
     180        // some internally handled states
     181        SimpleInputState*                                 stateDetector_;   //!< KeyDetector instance
     182        SimpleInputState*                                 stateCalibrator_;
     183        SimpleInputState*                                 stateEmpty_;
     184
     185        std::map<std::string, InputState*>          inputStatesByName_;
     186        std::map<int, InputState*>                  inputStatesByPriority_;
     187
     188        std::vector<InputState*> stateEnterRequests_;                  //!< Request to enter a new state
     189        std::vector<InputState*> stateLeaveRequests_;                    //!< Request to leave the current state
     190
     191        std::map<int, InputState*> activeStates_;
     192        std::vector<InputState*>   activeStatesTop_;    //!< Current input states for joy stick events.
     193        std::vector<InputState*>   activeStatesTicked_;    //!< Current input states for joy stick events.
     194
     195        // joystick calibration
     196        //std::vector<int> marginalsMaxConfig_;
     197        //std::vector<int> marginalsMinConfig_;
     198        int marginalsMax_[24];
     199        int marginalsMin_[24];
     200        bool bCalibrated_;
     201        bool bCalibrating_;
     202
     203        unsigned int keyboardModifiers_;           //!< Bit mask representing keyboard modifiers
     204        //! Keeps track of the joy stick POV states
     205        std::vector<POVStates>                      povStates_;
     206        //! Keeps track of the possibly two slider axes
     207        std::vector<SliderStates>                   sliderStates_;
     208        std::vector<JoyStickCalibration>            joySticksCalibration_;
     209
     210        std::vector<Key>                            keysDown_;
     211        std::vector<MouseButton::Enum>              mouseButtonsDown_;
     212        std::vector<std::vector<int> >              joyStickButtonsDown_;
     213
     214        static std::string                          bindingCommmandString_s;
     215    };
    258216
    259217}
  • code/branches/gui/src/core/input/KeyBinder.cc

    r1567 r1638  
    4343namespace orxonox
    4444{
    45   /**
    46     @brief Constructor that does as little as necessary.
    47   */
    48   KeyBinder::KeyBinder() : deriveTime_(0.0f)
    49   {
    50     mouseRelative_[0] = 0;
    51     mouseRelative_[1] = 0;
    52     mousePosition_[0] = 0;
    53     mousePosition_[1] = 0;
    54 
    55     RegisterRootObject(KeyBinder);
    56 
    57     // keys
    58     std::string keyNames[] = {
    59       "UNASSIGNED",
    60       "ESCAPE",
    61       "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
    62       "MINUS", "EQUALS", "BACK", "TAB",
    63       "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
    64       "LBRACKET", "RBRACKET",
    65       "RETURN", "LCONTROL",
    66       "A", "S", "D", "F", "G", "H", "J", "K", "L",
    67       "SEMICOLON", "APOSTROPHE", "GRAVE",
    68       "LSHIFT", "BACKSLASH",
    69       "Z", "X", "C", "V", "B", "N", "M",
    70       "COMMA", "PERIOD", "SLASH",
    71       "RSHIFT",
    72       "MULTIPLY",
    73       "LMENU",
    74       "SPACE",
    75       "CAPITAL",
    76       "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
    77       "NUMLOCK", "SCROLL",
    78       "NUMPAD7", "NUMPAD8", "NUMPAD9",
    79       "SUBTRACT",
    80       "NUMPAD4", "NUMPAD5", "NUMPAD6",
    81       "ADD",
    82       "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
    83       "DECIMAL",
    84       "","",
    85       "OEM_102",
    86       "F11", "F12",
    87       "","","","","","","","","","","",
    88       "F13", "F14", "F15",
    89       "","","","","","","","","","",
    90       "KANA",
    91       "","",
    92       "ABNT_C1",
    93       "","","","","",
    94       "CONVERT",
    95       "",
    96       "NOCONVERT",
    97       "",
    98       "YEN",
    99       "ABNT_C2",
    100       "","","","","","","","","","","","","","",
    101       "NUMPADEQUALS",
    102       "","",
    103       "PREVTRACK",
    104       "AT",
    105       "COLON", "UNDERLINE",
    106       "KANJI",
    107       "STOP",
    108       "AX",
    109       "UNLABELED",
    110       "NEXTTRACK",
    111       "","",
    112       "NUMPADENTER",
    113       "RCONTROL",
    114       "","",
    115       "MUTE",
    116       "CALCULATOR",
    117       "PLAYPAUSE",
    118       "",
    119       "MEDIASTOP",
    120       "","","","","","","","","",
    121       "VOLUMEDOWN",
    122       "",
    123       "VOLUMEUP",
    124       "",
    125       "WEBHOME",
    126       "NUMPADCOMMA",
    127       "",
    128       "DIVIDE",
    129       "",
    130       "SYSRQ",
    131       "RMENU",
    132       "","","","","","","","","","","","",
    133       "PAUSE",
    134       "",
    135       "HOME",
    136       "UP",
    137       "PGUP",
    138       "",
    139       "LEFT",
    140       "",
    141       "RIGHT",
    142       "",
    143       "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
    144       "","","","","","","",
    145       "LWIN", "RWIN", "APPS",
    146       "POWER", "SLEEP",
    147       "","","",
    148       "WAKE",
    149       "",
    150       "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
    151       "MYCOMPUTER", "MAIL", "MEDIASELECT"
    152     };
    153     for (unsigned int i = 0; i < nKeys_s; i++)
    154       keys_[i].name_ = "Key" + keyNames[i];
    155 
    156     // mouse buttons
    157     std::string mouseButtonNames[] = {
    158       "MouseLeft", "MouseRight", "MouseMiddle",
    159       "MouseButton3", "MouseButton4", "MouseButton5",
    160       "MouseButton6", "MouseButton7",
    161       "MouseWheel1Up", "MouseWheel1Down",
    162       "MouseWheel2Up", "MouseWheel2Down" };
    163     for (unsigned int i = 0; i < nMouseButtons_s; i++)
    164       mouseButtons_[i].name_ = mouseButtonNames[i];
    165 
    166     // joy stick buttons
    167     for (unsigned int i = 0; i < 32; i++)
    168       joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
    169     for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
    170     {
    171                   joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
    172                   joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
    173                   joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
    174                   joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
    175     }
    176 
    177     // half axes
    178     std::string rawNames[nHalfAxes_s/2];
    179     rawNames[0] = "MouseX";
    180     rawNames[1] = "MouseY";
    181     rawNames[2] = "Empty1";
    182     rawNames[3] = "Empty2";
    183     for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
    184       rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3);
    185     for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
    186     {
    187       halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
    188       halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
    189     }
    190 
    191     for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
    192       halfAxes_[i].buttonThreshold_ = buttonThreshold_;
    193   }
    194 
    195   /**
    196     @brief Destructor
    197   */
    198   KeyBinder::~KeyBinder()
    199   {
    200     // almost no destructors required because most of the arrays are static.
    201     clearBindings(); // does some destruction work
    202   }
    203 
    204   /**
    205     @brief Loads the key and button bindings.
    206     @return True if loading succeeded.
    207   */
    208   void KeyBinder::loadBindings()
    209   {
    210     COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
    211 
    212     clearBindings();
    213 
    214     std::ifstream infile;
    215     infile.open("keybindings.ini");
    216     if (!infile)
    217     {
    218       ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "def_keybindings.ini");
    219       ConfigFileManager::getSingleton()->save(CFT_Keybindings, "keybindings.ini");
    220     }
    221     else
    222       infile.close();
    223     ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
    224 
    225     // parse key bindings
    226     setConfigValues();
    227 
    228     COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
    229   }
    230 
    231   /**
    232     @brief Loader for the key bindings, managed by config values.
    233   */
    234   void KeyBinder::setConfigValues()
    235   {
    236     SetConfigValueGeneric(KeyBinder, analogThreshold_, 0.05f)  .description("Threshold for analog axes until which the state is 0.");
    237     SetConfigValueGeneric(KeyBinder, mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
    238     SetConfigValueGeneric(KeyBinder, bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
    239     SetConfigValueGeneric(KeyBinder, derivePeriod_, 0.05f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
    240     SetConfigValueGeneric(KeyBinder, mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived.");
    241     SetConfigValueGeneric(KeyBinder, bClipMouse_, true).description("Whether or not to clip absolute value of mouse in non derive mode.");
    242 
    243     float oldThresh = buttonThreshold_;
    244     SetConfigValueGeneric(KeyBinder, buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
    245     if (oldThresh != buttonThreshold_)
    246       for (unsigned int i = 0; i < nHalfAxes_s; i++)
    247         if (halfAxes_[i].buttonThreshold_ == oldThresh)
    248           halfAxes_[i].buttonThreshold_ = buttonThreshold_;
    249 
    250     // keys
    251     for (unsigned int i = 0; i < nKeys_s; i++)
    252       readTrigger(keys_[i]);
    253     // mouse buttons
    254     for (unsigned int i = 0; i < nMouseButtons_s; i++)
    255       readTrigger(mouseButtons_[i]);
    256     // joy stick buttons
    257     for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
    258       readTrigger(joyStickButtons_[i]);
    259     // half axes
    260     for (unsigned int i = 0; i < nHalfAxes_s; i++)
    261       readTrigger(halfAxes_[i]);
    262   }
    263 
    264   void KeyBinder::readTrigger(Button& button)
    265   {
    266     // config value stuff
    267     ConfigValueContainer* cont = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
    268     if (!cont)
    269     {
    270       cont = new ConfigValueContainer(CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "");
    271       ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
    272     }
    273     std::string old = button.bindingString_;
    274     cont->getValue(&button.bindingString_);
    275 
    276     // keybinder stuff
    277     if (old != button.bindingString_)
    278     {
    279       // clear everything so we don't get old axis ParamCommands mixed up
    280       button.clear();
    281 
    282       // binding has changed
    283       button.parse(paramCommandBuffer_);
    284     }
    285   }
    286 
    287   /**
    288     @brief Overwrites all bindings with ""
    289   */
    290   void KeyBinder::clearBindings()
    291   {
    292     for (unsigned int i = 0; i < nKeys_s; i++)
    293       keys_[i].clear();
    294 
    295     for (unsigned int i = 0; i < nMouseButtons_s; i++)
    296       mouseButtons_[i].clear();
    297 
    298     for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
    299       joyStickButtons_[i].clear();
    300 
    301     for (unsigned int i = 0; i < nHalfAxes_s; i++)
    302       halfAxes_[i].clear();
    303 
    304     for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
    305       delete paramCommandBuffer_[i];
    306     paramCommandBuffer_.clear();
    307   }
    308 
    309   void KeyBinder::resetJoyStickAxes()
    310   {
    311     for (unsigned int i = 8; i < nHalfAxes_s; i++)
    312     {
    313       halfAxes_[i].absVal_ = 0.0f;
    314       halfAxes_[i].relVal_ = 0.0f;
    315     }
    316   }
    317 
    318   void KeyBinder::tickInput(float dt, const HandlerState& state)
    319   {
    320     // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
    321     unsigned int iBegin = 8;
    322     unsigned int iEnd   = 8;
    323     if (state.joyStick)
    324       iEnd = nHalfAxes_s;
    325     if (state.mouse)
    326       iBegin = 0;
    327     for (unsigned int i = iBegin; i < iEnd; i++)
    328     {
    329       if (halfAxes_[i].hasChanged_)
    330       {
    331         if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
    332         {
    333           halfAxes_[i].wasDown_ = true;
    334           if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
    335             halfAxes_[i].execute(KeybindMode::OnPress);
    336         }
    337         else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
    338         {
    339           halfAxes_[i].wasDown_ = false;
    340           if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
    341             halfAxes_[i].execute(KeybindMode::OnRelease);
    342         }
    343         halfAxes_[i].hasChanged_ = false;
    344       }
    345 
    346       if (halfAxes_[i].wasDown_)
    347       {
    348         if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
    349           halfAxes_[i].execute(KeybindMode::OnHold);
    350       }
    351 
    352       // these are the actually useful axis bindings for analog input AND output
    353       if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
    354       {
    355         //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
    356         halfAxes_[i].execute();
    357       }
    358     }
    359 
    360     if (bDeriveMouseInput_ && state.mouse)
    361     {
    362       if (deriveTime_ > derivePeriod_)
    363       {
    364         //CCOUT(3) << "mouse abs: ";
     45    /**
     46    @brief
     47        Constructor that does as little as necessary.
     48    */
     49    KeyBinder::KeyBinder()
     50        : deriveTime_(0.0f)
     51    {
     52        mouseRelative_[0] = 0;
     53        mouseRelative_[1] = 0;
     54        mousePosition_[0] = 0;
     55        mousePosition_[1] = 0;
     56
     57        RegisterRootObject(KeyBinder);
     58
     59        // keys
     60        std::string keyNames[] = {
     61        "UNASSIGNED",
     62        "ESCAPE",
     63        "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
     64        "MINUS", "EQUALS", "BACK", "TAB",
     65        "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
     66        "LBRACKET", "RBRACKET",
     67        "RETURN", "LCONTROL",
     68        "A", "S", "D", "F", "G", "H", "J", "K", "L",
     69        "SEMICOLON", "APOSTROPHE", "GRAVE",
     70        "LSHIFT", "BACKSLASH",
     71        "Z", "X", "C", "V", "B", "N", "M",
     72        "COMMA", "PERIOD", "SLASH",
     73        "RSHIFT",
     74        "MULTIPLY",
     75        "LMENU",
     76        "SPACE",
     77        "CAPITAL",
     78        "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
     79        "NUMLOCK", "SCROLL",
     80        "NUMPAD7", "NUMPAD8", "NUMPAD9",
     81        "SUBTRACT",
     82        "NUMPAD4", "NUMPAD5", "NUMPAD6",
     83        "ADD",
     84        "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
     85        "DECIMAL",
     86        "","",
     87        "OEM_102",
     88        "F11", "F12",
     89        "","","","","","","","","","","",
     90        "F13", "F14", "F15",
     91        "","","","","","","","","","",
     92        "KANA",
     93        "","",
     94        "ABNT_C1",
     95        "","","","","",
     96        "CONVERT",
     97        "",
     98        "NOCONVERT",
     99        "",
     100        "YEN",
     101        "ABNT_C2",
     102        "","","","","","","","","","","","","","",
     103        "NUMPADEQUALS",
     104        "","",
     105        "PREVTRACK",
     106        "AT",
     107        "COLON", "UNDERLINE",
     108        "KANJI",
     109        "STOP",
     110        "AX",
     111        "UNLABELED",
     112        "NEXTTRACK",
     113        "","",
     114        "NUMPADENTER",
     115        "RCONTROL",
     116        "","",
     117        "MUTE",
     118        "CALCULATOR",
     119        "PLAYPAUSE",
     120        "",
     121        "MEDIASTOP",
     122        "","","","","","","","","",
     123        "VOLUMEDOWN",
     124        "",
     125        "VOLUMEUP",
     126        "",
     127        "WEBHOME",
     128        "NUMPADCOMMA",
     129        "",
     130        "DIVIDE",
     131        "",
     132        "SYSRQ",
     133        "RMENU",
     134        "","","","","","","","","","","","",
     135        "PAUSE",
     136        "",
     137        "HOME",
     138        "UP",
     139        "PGUP",
     140        "",
     141        "LEFT",
     142        "",
     143        "RIGHT",
     144        "",
     145        "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
     146        "","","","","","","",
     147        "LWIN", "RWIN", "APPS",
     148        "POWER", "SLEEP",
     149        "","","",
     150        "WAKE",
     151        "",
     152        "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
     153        "MYCOMPUTER", "MAIL", "MEDIASELECT"
     154        };
     155        for (unsigned int i = 0; i < nKeys_s; i++)
     156            keys_[i].name_ = "Key" + keyNames[i];
     157
     158        // mouse buttons
     159        std::string mouseButtonNames[] = {
     160            "MouseLeft",     "MouseRight",   "MouseMiddle",
     161            "MouseButton3",  "MouseButton4", "MouseButton5",
     162            "MouseButton6",  "MouseButton7",
     163            "MouseWheel1Up", "MouseWheel1Down",
     164            "MouseWheel2Up", "MouseWheel2Down"
     165        };
     166        for (unsigned int i = 0; i < nMouseButtons_s; i++)
     167            mouseButtons_[i].name_ = mouseButtonNames[i];
     168
     169        // joy stick buttons
     170        for (unsigned int i = 0; i < 32; i++)
     171            joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
     172        for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
     173        {
     174            joyStickButtons_[i + 0].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "North";
     175            joyStickButtons_[i + 1].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "South";
     176            joyStickButtons_[i + 2].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "East";
     177            joyStickButtons_[i + 3].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "West";
     178        }
     179
     180        // half axes
     181        std::string rawNames[nHalfAxes_s/2];
     182        rawNames[0] = "MouseX";
     183        rawNames[1] = "MouseY";
     184        rawNames[2] = "Empty1";
     185        rawNames[3] = "Empty2";
     186        for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
     187            rawNames[i] = "JoyAxis" + convertToString(i - 3);
     188        for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
     189        {
     190            halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
     191            halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
     192        }
     193
     194        for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
     195            halfAxes_[i].buttonThreshold_ = buttonThreshold_;
     196    }
     197
     198    /**
     199    @brief
     200        Destructor
     201    */
     202    KeyBinder::~KeyBinder()
     203    {
     204        // almost no destructors required because most of the arrays are static.
     205        clearBindings(); // does some destruction work
     206    }
     207
     208    /**
     209    @brief
     210        Loads the key and button bindings.
     211    @return
     212        True if loading succeeded.
     213    */
     214    void KeyBinder::loadBindings()
     215    {
     216        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
     217
     218        clearBindings();
     219
     220        std::ifstream infile;
     221        infile.open("keybindings.ini");
     222        if (!infile)
     223        {
     224            ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "def_keybindings.ini");
     225            ConfigFileManager::getSingleton()->save(CFT_Keybindings, "keybindings.ini");
     226        }
     227        else
     228            infile.close();
     229        ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
     230
     231        // parse key bindings
     232        setConfigValues();
     233
     234        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
     235    }
     236
     237    /**
     238    @brief
     239        Loader for the key bindings, managed by config values.
     240    */
     241    void KeyBinder::setConfigValues()
     242    {
     243        SetConfigValueGeneric(KeyBinder, analogThreshold_, 0.05f)
     244            .description("Threshold for analog axes until which the state is 0.");
     245        SetConfigValueGeneric(KeyBinder, mouseSensitivity_, 1.0f)
     246            .description("Mouse sensitivity.");
     247        SetConfigValueGeneric(KeyBinder, bDeriveMouseInput_, false)
     248            .description("Whether or not to derive moues movement for the absolute value.");
     249        SetConfigValueGeneric(KeyBinder, derivePeriod_, 0.05f)
     250            .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
     251        SetConfigValueGeneric(KeyBinder, mouseSensitivityDerived_, 1.0f)
     252            .description("Mouse sensitivity if mouse input is derived.");
     253        SetConfigValueGeneric(KeyBinder, bClipMouse_, true)
     254            .description("Whether or not to clip absolute value of mouse in non derive mode.");
     255
     256        float oldThresh = buttonThreshold_;
     257        SetConfigValueGeneric(KeyBinder, buttonThreshold_, 0.80f)
     258            .description("Threshold for analog axes until which the button is not pressed.");
     259        if (oldThresh != buttonThreshold_)
     260            for (unsigned int i = 0; i < nHalfAxes_s; i++)
     261                if (halfAxes_[i].buttonThreshold_ == oldThresh)
     262                    halfAxes_[i].buttonThreshold_ = buttonThreshold_;
     263
     264        // keys
     265        for (unsigned int i = 0; i < nKeys_s; i++)
     266            readTrigger(keys_[i]);
     267        // mouse buttons
     268        for (unsigned int i = 0; i < nMouseButtons_s; i++)
     269            readTrigger(mouseButtons_[i]);
     270        // joy stick buttons
     271        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
     272            readTrigger(joyStickButtons_[i]);
     273        // half axes
     274        for (unsigned int i = 0; i < nHalfAxes_s; i++)
     275            readTrigger(halfAxes_[i]);
     276    }
     277
     278    void KeyBinder::readTrigger(Button& button)
     279    {
     280        // config value stuff
     281        ConfigValueContainer* cont
     282            = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
     283        if (!cont)
     284        {
     285            cont = new ConfigValueContainer
     286                (CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "");
     287            ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
     288        }
     289        std::string old = button.bindingString_;
     290        cont->getValue(&button.bindingString_);
     291
     292        // keybinder stuff
     293        if (old != button.bindingString_)
     294        {
     295            // clear everything so we don't get old axis ParamCommands mixed up
     296            button.clear();
     297
     298            // binding has changed
     299            button.parse(paramCommandBuffer_);
     300        }
     301    }
     302
     303    /**
     304    @brief
     305        Overwrites all bindings with ""
     306    */
     307    void KeyBinder::clearBindings()
     308    {
     309        for (unsigned int i = 0; i < nKeys_s; i++)
     310            keys_[i].clear();
     311
     312        for (unsigned int i = 0; i < nMouseButtons_s; i++)
     313            mouseButtons_[i].clear();
     314
     315        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
     316            joyStickButtons_[i].clear();
     317
     318        for (unsigned int i = 0; i < nHalfAxes_s; i++)
     319            halfAxes_[i].clear();
     320
     321        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     322            delete paramCommandBuffer_[i];
     323        paramCommandBuffer_.clear();
     324    }
     325
     326    void KeyBinder::resetJoyStickAxes()
     327    {
     328        for (unsigned int i = 8; i < nHalfAxes_s; i++)
     329        {
     330            halfAxes_[i].absVal_ = 0.0f;
     331            halfAxes_[i].relVal_ = 0.0f;
     332        }
     333    }
     334
     335    void KeyBinder::tickMouse(float dt)
     336    {
     337        tickDevices(0, 8);
     338
     339        if (bDeriveMouseInput_)
     340        {
     341            if (deriveTime_ > derivePeriod_)
     342            {
     343                //CCOUT(3) << "mouse abs: ";
     344                for (int i = 0; i < 2; i++)
     345                {
     346                    if (mouseRelative_[i] > 0)
     347                    {
     348                        halfAxes_[2*i + 0].absVal_
     349                            =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
     350                        halfAxes_[2*i + 1].absVal_ = 0.0f;
     351                    }
     352                    else if (mouseRelative_[i] < 0)
     353                    {
     354                        halfAxes_[2*i + 0].absVal_ = 0.0f;
     355                        halfAxes_[2*i + 1].absVal_
     356                            = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
     357                    }
     358                    else
     359                    {
     360                        halfAxes_[2*i + 0].absVal_ = 0.0f;
     361                        halfAxes_[2*i + 1].absVal_ = 0.0f;
     362                    }
     363                    //COUT(3) << mouseRelative_[i] << " | ";
     364                    mouseRelative_[i] = 0;
     365                    halfAxes_[2*i + 0].hasChanged_ = true;
     366                    halfAxes_[2*i + 1].hasChanged_ = true;
     367                }
     368                deriveTime_ = 0.0f;
     369                //COUT(3) << std::endl;
     370            }
     371            else
     372                deriveTime_ += dt;
     373        }
     374    }
     375
     376    void KeyBinder::tickJoyStick(float dt, int device)
     377    {
     378        tickDevices(8, nHalfAxes_s);
     379    }
     380
     381    void KeyBinder::tickInput(float dt)
     382    {
     383        // execute all buffered bindings (additional parameter)
     384        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     385            paramCommandBuffer_[i]->execute();
     386
     387        // always reset the relative movement of the mouse
     388        for (unsigned int i = 0; i < 8; i++)
     389            halfAxes_[i].relVal_ = 0.0f;
     390    }
     391
     392    void KeyBinder::tickDevices(unsigned int begin, unsigned int end)
     393    {
     394        for (unsigned int i = begin; i < end; i++)
     395        {
     396            // button mode
     397            // TODO: optimize out all the half axes that don't act as a button at the moment
     398            if (halfAxes_[i].hasChanged_)
     399            {
     400                if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
     401                {
     402                    halfAxes_[i].wasDown_ = true;
     403                    if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
     404                        halfAxes_[i].execute(KeybindMode::OnPress);
     405                }
     406                else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
     407                {
     408                    halfAxes_[i].wasDown_ = false;
     409                    if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
     410                        halfAxes_[i].execute(KeybindMode::OnRelease);
     411                }
     412                halfAxes_[i].hasChanged_ = false;
     413            }
     414
     415            if (halfAxes_[i].wasDown_)
     416            {
     417                if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
     418                    halfAxes_[i].execute(KeybindMode::OnHold);
     419            }
     420
     421            // these are the actually useful axis bindings for analog input
     422            if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
     423            {
     424                //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
     425                halfAxes_[i].execute();
     426            }
     427        }
     428    }
     429
     430    void KeyBinder::keyPressed (const KeyEvent& evt)
     431    { keys_[evt.key].execute(KeybindMode::OnPress); }
     432
     433    void KeyBinder::keyReleased(const KeyEvent& evt)
     434    { keys_[evt.key].execute(KeybindMode::OnRelease); }
     435
     436    void KeyBinder::keyHeld    (const KeyEvent& evt)
     437    { keys_[evt.key].execute(KeybindMode::OnHold); }
     438
     439
     440    void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
     441    { mouseButtons_[id].execute(KeybindMode::OnPress); }
     442
     443    void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
     444    { mouseButtons_[id].execute(KeybindMode::OnRelease); }
     445
     446    void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
     447    { mouseButtons_[id].execute(KeybindMode::OnHold); }
     448
     449
     450    void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, unsigned int button)
     451    { joyStickButtons_[button].execute(KeybindMode::OnPress); }
     452
     453    void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, unsigned int button)
     454    { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
     455
     456    void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, unsigned int button)
     457    { joyStickButtons_[button].execute(KeybindMode::OnHold); }
     458
     459    /**
     460    @brief
     461        Event handler for the mouseMoved Event.
     462    @param e
     463        Mouse state information
     464    */
     465    void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
     466    {
     467        // y axis of mouse input is inverted
     468        int rel[] = { rel_.x, -rel_.y };
     469
     470        if (!bDeriveMouseInput_)
     471        {
     472            for (int i = 0; i < 2; i++)
     473            {
     474                if (rel[i])
     475                {
     476                    // absolute
     477                    halfAxes_[2*i + 0].hasChanged_ = true;
     478                    halfAxes_[2*i + 1].hasChanged_ = true;
     479                    mousePosition_[i] += rel[i];
     480
     481                    if (bClipMouse_)
     482                    {
     483                        if (mousePosition_[i] > 1024)
     484                            mousePosition_[i] =  1024;
     485                        if (mousePosition_[i] < -1024)
     486                            mousePosition_[i] = -1024;
     487                    }
     488
     489                    if (mousePosition_[i] >= 0)
     490                    {
     491                        halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
     492                        halfAxes_[2*i + 1].absVal_ =  0.0f;
     493                    }
     494                    else
     495                    {
     496                        halfAxes_[2*i + 0].absVal_ =  0.0f;
     497                        halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
     498                    }
     499                }
     500            }
     501        }
     502        else
     503        {
     504            mouseRelative_[0] += rel[0];
     505            mouseRelative_[1] += rel[1];
     506        }
     507
     508        // relative
    365509        for (int i = 0; i < 2; i++)
    366510        {
    367           if (mouseRelative_[i] > 0)
    368           {
    369             halfAxes_[2*i + 0].absVal_ =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
    370             halfAxes_[2*i + 1].absVal_ = 0.0f;
    371           }
    372           else if (mouseRelative_[i] < 0)
    373           {
    374             halfAxes_[2*i + 0].absVal_ = 0.0f;
    375             halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
    376           }
    377           else
    378           {
    379             halfAxes_[2*i + 0].absVal_ = 0.0f;
    380             halfAxes_[2*i + 1].absVal_ = 0.0f;
    381           }
    382           //COUT(3) << mouseRelative_[i] << " | ";
    383           mouseRelative_[i] = 0;
    384           halfAxes_[2*i + 0].hasChanged_ = true;
    385           halfAxes_[2*i + 1].hasChanged_ = true;
    386         }
    387         deriveTime_ = 0.0f;
    388         //COUT(3) << std::endl;
    389       }
    390       else
    391         deriveTime_ += dt;
    392     }
    393 
    394     // execute all buffered bindings (addional parameter)
    395     for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
    396       paramCommandBuffer_[i]->execute();
    397 
    398     // always reset the relative movement of the mouse
    399     if (state.mouse)
    400       for (unsigned int i = 0; i < 8; i++)
    401         halfAxes_[i].relVal_ = 0.0f;
    402   }
    403 
    404   void KeyBinder::keyPressed (const KeyEvent& evt)
    405   { keys_[evt.key].execute(KeybindMode::OnPress); }
    406 
    407   void KeyBinder::keyReleased(const KeyEvent& evt)
    408   { keys_[evt.key].execute(KeybindMode::OnRelease); }
    409 
    410   void KeyBinder::keyHeld    (const KeyEvent& evt)
    411   { keys_[evt.key].execute(KeybindMode::OnHold); }
    412 
    413 
    414   void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
    415   { mouseButtons_[id].execute(KeybindMode::OnPress); }
    416 
    417   void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
    418   { mouseButtons_[id].execute(KeybindMode::OnRelease); }
    419 
    420   void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
    421   { mouseButtons_[id].execute(KeybindMode::OnHold); }
    422 
    423 
    424   void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
    425   { joyStickButtons_[button].execute(KeybindMode::OnPress); }
    426 
    427   void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
    428   { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
    429 
    430   void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
    431   { joyStickButtons_[button].execute(KeybindMode::OnHold); }
    432 
    433   /**
    434     @brief Event handler for the mouseMoved Event.
    435     @param e Mouse state information
    436   */
    437   void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
    438   {
    439     // y axis of mouse input is inverted
    440     int rel[] = { rel_.x, -rel_.y };
    441 
    442     if (!bDeriveMouseInput_)
    443     {
    444       for (int i = 0; i < 2; i++)
    445       {
    446         if (rel[i])
    447         {
    448           // absolute
    449           halfAxes_[2*i + 0].hasChanged_ = true;
    450           halfAxes_[2*i + 1].hasChanged_ = true;
    451           mousePosition_[i] += rel[i];
    452 
    453           if (bClipMouse_)
    454           {
    455             if (mousePosition_[i] > 1024)
    456               mousePosition_[i] =  1024;
    457             if (mousePosition_[i] < -1024)
    458               mousePosition_[i] = -1024;
    459           }
    460 
    461           if (mousePosition_[i] >= 0)
    462           {
    463             halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
    464             halfAxes_[2*i + 1].absVal_ =  0.0f;
    465           }
    466           else
    467           {
    468             halfAxes_[2*i + 0].absVal_ =  0.0f;
    469             halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
    470           }
    471         }
    472       }
    473     }
    474     else
    475     {
    476       mouseRelative_[0] += rel[0];
    477       mouseRelative_[1] += rel[1];
    478     }
    479 
    480     // relative
    481     for (int i = 0; i < 2; i++)
    482     {
    483       if (rel[i] > 0)
    484         halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
    485       else
    486         halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
    487     }
    488   }
    489 
    490   /**
     511            if (rel[i] > 0)
     512                halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
     513            else
     514                halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
     515        }
     516    }
     517
     518    /**
    491519    @brief Event handler for the mouseScrolled Event.
    492520    @param e Mouse state information
    493   */
    494   void KeyBinder::mouseScrolled(int abs, int rel)
    495   {
    496     //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
    497 
    498     if (rel > 0)
    499       for (int i = 0; i < rel/120; i++)
    500         mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
    501     else
    502       for (int i = 0; i < -rel/120; i++)
    503         mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
    504   }
    505 
    506   void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value)
    507   {
    508     // TODO: Use proper calibration values instead of generally 16-bit integer
    509     int i = 8 + axis * 2;
    510     if (value >= 0)
    511     {
    512       //if (value > 10000)
    513       //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
    514 
    515       halfAxes_[i].absVal_ = value;
    516       halfAxes_[i].relVal_ = value;
    517       halfAxes_[i].hasChanged_ = true;
    518       if (halfAxes_[i + 1].absVal_ > 0.0f)
    519       {
    520         halfAxes_[i + 1].absVal_ = -0.0f;
    521         halfAxes_[i + 1].relVal_ = -0.0f;
    522         halfAxes_[i + 1].hasChanged_ = true;
    523       }
    524     }
    525     else
    526     {
    527       //if (value < -10000)
    528       //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
    529 
    530       halfAxes_[i + 1].absVal_ = -value;
    531       halfAxes_[i + 1].relVal_ = -value;
    532       halfAxes_[i + 1].hasChanged_ = true;
    533       if (halfAxes_[i].absVal_ > 0.0f)
    534       {
    535         halfAxes_[i].absVal_ = -0.0f;
    536         halfAxes_[i].relVal_ = -0.0f;
    537         halfAxes_[i].hasChanged_ = true;
    538       }
    539     }
    540   }
     521    */
     522    void KeyBinder::mouseScrolled(int abs, int rel)
     523    {
     524        //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
     525
     526        if (rel > 0)
     527            for (int i = 0; i < rel/120; i++)
     528                mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
     529        else
     530            for (int i = 0; i < -rel/120; i++)
     531                mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
     532    }
     533
     534    void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
     535    {
     536        int i = 8 + axis * 2;
     537        if (value >= 0)
     538        {
     539            //if (value > 10000)
     540            //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
     541
     542            halfAxes_[i].absVal_ = value;
     543            halfAxes_[i].relVal_ = value;
     544            halfAxes_[i].hasChanged_ = true;
     545            if (halfAxes_[i + 1].absVal_ > 0.0f)
     546            {
     547                halfAxes_[i + 1].absVal_ = -0.0f;
     548                halfAxes_[i + 1].relVal_ = -0.0f;
     549                halfAxes_[i + 1].hasChanged_ = true;
     550            }
     551        }
     552        else
     553        {
     554            //if (value < -10000)
     555            //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
     556
     557            halfAxes_[i + 1].absVal_ = -value;
     558            halfAxes_[i + 1].relVal_ = -value;
     559            halfAxes_[i + 1].hasChanged_ = true;
     560            if (halfAxes_[i].absVal_ > 0.0f)
     561            {
     562                halfAxes_[i].absVal_ = -0.0f;
     563                halfAxes_[i].relVal_ = -0.0f;
     564                halfAxes_[i].hasChanged_ = true;
     565            }
     566        }
     567    }
    541568}
  • code/branches/gui/src/core/input/KeyBinder.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _KeyBinder_H__
     
    4647namespace orxonox
    4748{
    48   /**
    49     @brief Handles mouse, keyboard and joy stick input while in the actual game mode.
    50            Manages the key bindings.
    51   */
    52   class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, public OrxonoxClass
    53   {
    54   public:
    55     KeyBinder ();
    56     virtual ~KeyBinder();
     49    /**
     50    @brief
     51        Handles mouse, keyboard and joy stick input while in the actual game mode.
     52        Manages the key bindings.
     53    */
     54    class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, public OrxonoxClass
     55    {
     56    public:
     57        KeyBinder ();
     58        virtual ~KeyBinder();
    5759
    58     void loadBindings();
    59     void clearBindings();
    60     void setConfigValues();
    61     void resetJoyStickAxes();
     60        void loadBindings();
     61        void clearBindings();
     62        void setConfigValues();
     63        void resetJoyStickAxes();
    6264
    63   protected: // functions
    64     void tickInput(float dt, const HandlerState& state);
     65    protected: // functions
     66        void tickInput(float dt);
     67        //void tickInput(float dt, int device);
     68        void tickKey(float dt) { }
     69        void tickMouse(float dt);
     70        void tickJoyStick(float dt, int device);
     71        void tickDevices(unsigned int begin, unsigned int end);
    6572
    66     virtual void readTrigger(Button& button);
     73        virtual void readTrigger(Button& button);
    6774
    68     void keyPressed (const KeyEvent& evt);
    69     void keyReleased(const KeyEvent& evt);
    70     void keyHeld    (const KeyEvent& evt);
     75        void keyPressed (const KeyEvent& evt);
     76        void keyReleased(const KeyEvent& evt);
     77        void keyHeld    (const KeyEvent& evt);
    7178
    72     void mouseButtonPressed (MouseButton::Enum id);
    73     void mouseButtonReleased(MouseButton::Enum id);
    74     void mouseButtonHeld    (MouseButton::Enum id);
    75     void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
    76     void mouseScrolled      (int abs, int rel);
     79        void mouseButtonPressed (MouseButton::Enum id);
     80        void mouseButtonReleased(MouseButton::Enum id);
     81        void mouseButtonHeld    (MouseButton::Enum id);
     82        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
     83        void mouseScrolled      (int abs, int rel);
    7784
    78     void joyStickButtonPressed (int joyStickID, int button);
    79     void joyStickButtonReleased(int joyStickID, int button);
    80     void joyStickButtonHeld    (int joyStickID, int button);
    81     void joyStickAxisMoved     (int joyStickID, int axis, float value);
     85        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button);
     86        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button);
     87        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button);
     88        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
    8289
    83   protected: // variables
    84     //! denotes the number of different keys there are in OIS.
    85     static const unsigned int nKeys_s = 0xEE;
    86     //! Actual key bindings as bundle for Press, Hold and Release
    87     Button keys_ [nKeys_s];
     90    protected: // variables
     91        //! denotes the number of different keys there are in OIS.
     92        static const unsigned int nKeys_s = 0xEE;
     93        //! Actual key bindings as bundle for Press, Hold and Release
     94        Button keys_ [nKeys_s];
    8895
    89     //! denotes the number of different mouse buttons there are in OIS.
    90     static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels
    91     //! Actual key bindings as bundle for Press, Hold and Release
    92     Button mouseButtons_ [nMouseButtons_s];
     96        //! denotes the number of different mouse buttons there are in OIS.
     97        static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels
     98        //! Actual key bindings as bundle for Press, Hold and Release
     99        Button mouseButtons_ [nMouseButtons_s];
    93100
    94     //! denotes the number of different joy stick buttons there are in OIS.
    95     static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons
    96     //! Actual key bindings as bundle for Press, Hold and Release
    97     Button joyStickButtons_ [nJoyStickButtons_s];
     101        //! denotes the number of different joy stick buttons there are in OIS.
     102        static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons
     103        //! Actual key bindings as bundle for Press, Hold and Release
     104        Button joyStickButtons_ [nJoyStickButtons_s];
    98105
    99     //! denotes the number of half axes (every axis twice) there can be.
    100     static const unsigned int nHalfAxes_s = 56;
    101     /**
    102     * Array with all the half axes for mouse and joy sticks.
    103     * Keep in mind that the positions are fixed and that the first entry is the
    104     * positive one and the second is negative.
    105     * Sequence is as follows:
    106     *  0 -  3: Mouse x and y
    107     *  4 -  7: empty
    108     *  8 - 23: joy stick slider axes 1 to 8
    109     * 24 - 55: joy stick axes 1 - 16
    110     */
    111     HalfAxis halfAxes_[nHalfAxes_s];
     106        //! denotes the number of half axes (every axis twice) there can be.
     107        static const unsigned int nHalfAxes_s = 56;
     108        /**
     109        * Array with all the half axes for mouse and joy sticks.
     110        * Keep in mind that the positions are fixed and that the first entry is the
     111        * positive one and the second is negative.
     112        * Sequence is as follows:
     113        *  0 -  3: Mouse x and y
     114        *  4 -  7: empty
     115        *  8 - 23: joy stick slider axes 1 to 8
     116        * 24 - 55: joy stick axes 1 - 16
     117        */
     118        HalfAxis halfAxes_[nHalfAxes_s];
    112119
    113     /**
    114     * Commands that have additional parameters (axes) are executed at the end of
    115     * the tick() so that all values can be buffered for single execution.
    116     */
    117     std::vector<BufferedParamCommand*> paramCommandBuffer_;
     120        /**
     121        @brief
     122            Commands that have additional parameters (axes) are executed at the end of
     123            the tick() so that all values can be buffered for single execution.
     124        */
     125        std::vector<BufferedParamCommand*> paramCommandBuffer_;
    118126
    119     //! Keeps track of the absolute mouse value (incl. scroll wheel)
    120     int mousePosition_[2];
    121     //! Used to derive mouse input if requested
    122     int mouseRelative_[2];
    123     float deriveTime_;
     127        //! Keeps track of the absolute mouse value (incl. scroll wheel)
     128        int mousePosition_[2];
     129        //! Used to derive mouse input if requested
     130        int mouseRelative_[2];
     131        float deriveTime_;
    124132
    125     //##### ConfigValues #####
    126     //! Threshold for analog triggers until which the state is 0.
    127     float analogThreshold_;
    128     //! Threshold for analog triggers until which the button is not pressed.
    129     float buttonThreshold_;
    130     //! Derive mouse input for absolute values?
    131     bool bDeriveMouseInput_;
    132     //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
    133     float derivePeriod_;
    134     //! mouse sensitivity
    135     float mouseSensitivity_;
    136     //! mouse sensitivity if mouse input is derived
    137     float mouseSensitivityDerived_;
    138     //! Whether or not to clip abslute mouse values to 1024
    139     bool bClipMouse_;
    140   };
     133
     134        //##### ConfigValues #####
     135
     136        //! Threshold for analog triggers until which the state is 0.
     137        float analogThreshold_;
     138        //! Threshold for analog triggers until which the button is not pressed.
     139        float buttonThreshold_;
     140        //! Derive mouse input for absolute values?
     141        bool bDeriveMouseInput_;
     142        //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
     143        float derivePeriod_;
     144        //! mouse sensitivity
     145        float mouseSensitivity_;
     146        //! mouse sensitivity if mouse input is derived
     147        float mouseSensitivityDerived_;
     148        //! Whether or not to clip abslute mouse values to 1024
     149        bool bClipMouse_;
     150    };
    141151}
    142152
  • code/branches/gui/src/core/input/KeyDetector.cc

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "KeyDetector.h"
     
    4243namespace orxonox
    4344{
    44   /**
    45     @brief Constructor
    46   */
    47   KeyDetector::KeyDetector()
    48   {
    49     RegisterObject(KeyDetector);
    50   }
     45    /**
     46    @brief
     47        Constructor
     48    */
     49    KeyDetector::KeyDetector()
     50    {
     51        RegisterObject(KeyDetector);
     52    }
    5153
    52   /**
    53     @brief Destructor
    54   */
    55   KeyDetector::~KeyDetector()
    56   {
    57   }
     54    /**
     55    @brief
     56        Destructor
     57    */
     58    KeyDetector::~KeyDetector()
     59    {
     60    }
    5861
    59   /**
    60     @brief Loads the key and button bindings.
    61     @return True if loading succeeded.
    62   */
    63   void KeyDetector::loadBindings()
    64   {
    65     clearBindings();
    66     setConfigValues();
    67   }
     62    /**
     63    @brief
     64        Loads the key and button bindings.
     65    @return
     66        True if loading succeeded.
     67    */
     68    void KeyDetector::loadBindings(const std::string& command)
     69    {
     70        clearBindings();
     71        setConfigValues();
     72        this->command_ = command;
     73    }
    6874
    69   void KeyDetector::readTrigger(Button& button)
    70   {
    71     SimpleCommand* cmd = new SimpleCommand();
    72     cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
    73     button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
    74     button.commands_[KeybindMode::OnPress][0] = cmd;
    75     button.nCommands_[KeybindMode::OnPress] = 1;
    76   }
     75    void KeyDetector::readTrigger(Button& button)
     76    {
     77        SimpleCommand* cmd = new SimpleCommand();
     78        cmd->evaluation_ = CommandExecutor::evaluate(this->command_ + " " + button.name_);
     79        button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
     80        button.commands_[KeybindMode::OnPress][0] = cmd;
     81        button.nCommands_[KeybindMode::OnPress] = 1;
     82    }
    7783}
  • code/branches/gui/src/core/input/KeyDetector.h

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _KeyDetector_H__
     
    4142namespace orxonox
    4243{
    43   class _CoreExport KeyDetector : public KeyBinder
    44   {
    45   public:
    46     KeyDetector();
    47     ~KeyDetector();
    48     void loadBindings();
     44    class _CoreExport KeyDetector : public KeyBinder
     45    {
     46    public:
     47        KeyDetector();
     48        ~KeyDetector();
     49        void loadBindings(const std::string& command);
    4950
    50   protected:
    51     void readTrigger(Button& button);
    52   };
     51    protected:
     52        void readTrigger(Button& button);
     53
     54    private:
     55        std::string command_;
     56    };
    5357}
    5458
Note: See TracChangeset for help on using the changeset viewer.