Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

merged gui back to trunk.
update the media repository!

Location:
code/trunk
Files:
18 edited
5 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r1747 r1755  
    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/trunk/src/core/input/Button.h

    r1535 r1755  
    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/trunk/src/core/input/CalibratorCallback.cc

    r1535 r1755  
    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/trunk/src/core/input/CalibratorCallback.h

    r1535 r1755  
    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/trunk/src/core/input/ExtendedInputState.cc

    r1724 r1755  
    3636
    3737#include <assert.h>
    38 #include "core/Debug.h"
     38#include "util/Debug.h"
    3939
    4040namespace orxonox
  • code/trunk/src/core/input/HalfAxis.cc

    r1535 r1755  
    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/trunk/src/core/input/HalfAxis.h

    r1535 r1755  
    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/trunk/src/core/input/InputBuffer.cc

    r1535 r1755  
    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/trunk/src/core/input/InputBuffer.h

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

    r1535 r1755  
    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/trunk/src/core/input/InputCommands.h

    r1535 r1755  
    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/trunk/src/core/input/InputInterfaces.h

    r1556 r1755  
    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 JoyStickButton
     216    {
     217        enum Enum
     218        {
     219            Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
     220            Button4       =  4, Button5       =  5, Button6       =  6, Button7       =  7,
     221            Button8       =  8, Button9       =  9, Button10      = 10, Button11      = 11,
     222            Button12      = 12, Button13      = 13, Button14      = 14, Button15      = 15,
     223            Button16      = 16, Button17      = 17, Button18      = 18, Button19      = 19,
     224            Button20      = 20, Button21      = 21, Button22      = 22, Button23      = 23,
     225            Button24      = 24, Button25      = 25, Button26      = 26, Button27      = 27,
     226            Button28      = 28, Button29      = 29, Button30      = 30, Button31      = 31,
     227
     228            POV0North     = 32, POV0South     = 33, POV0East      = 34, POV0West      = 35,
     229            POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39,
     230
     231            POV1North     = 40, POV1South     = 41, POV1East      = 42, POV1West      = 43,
     232            POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47,
     233
     234            POV2North     = 48, POV2South     = 49, POV2East      = 50, POV2West      = 51,
     235            POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55,
     236
     237            POV3North     = 56, POV3South     = 57, POV3East      = 58, POV3West      = 59,
     238            POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
     239        };
     240    }
     241
     242    namespace KeyboardModifier
     243    {
     244        enum Enum
     245        {
     246            Shift = 0x0000001,
     247            Ctrl  = 0x0000010,
     248            Alt   = 0x0000100
     249        };
     250    }
     251   
     252    namespace InputDevice
     253    {
     254        enum Enum
     255        {
     256            Keyboard,
     257            Mouse,
     258            JoyStick0,
     259            JoyStick1,
     260            JoyStick2,
     261            JoyStick3,
     262            // note: No problem if there are more joy sticks. This enum is just for convenience.
     263        };
     264    }
     265
     266    struct _CoreExport Key
     267    {
     268        Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { }
     269        KeyCode::Enum key;
     270        unsigned int text;
     271    };
     272
     273    class _CoreExport KeyEvent
     274    {
     275    public:
     276        KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { }
     277        KeyEvent(const OIS::KeyEvent& evt, unsigned int mod)
     278            : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { }
     279        KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { }
     280        bool isModifierDown(KeyboardModifier::Enum modifier) const
     281            { return (KeyboardModifier::Enum)modifier&modifiers; }
     282
     283        const KeyCode::Enum key;
     284        unsigned int text;
     285        unsigned int modifiers;
     286    };
     287
     288
     289    class _CoreExport InputTickable
     290    {
     291    public:
     292        virtual ~InputTickable() { }
     293        virtual void tickInput(float dt) = 0;
     294    };
     295
     296    /**
     297    @brief
     298        Interface class used for key input listeners.
     299    */
     300    class _CoreExport KeyHandler : virtual public InputTickable
     301    {
     302    public:
     303        virtual ~KeyHandler() { }
     304        virtual void keyPressed (const KeyEvent& evt) = 0;
     305        virtual void keyReleased(const KeyEvent& evt) = 0;
     306        virtual void keyHeld    (const KeyEvent& evt) = 0;
     307        virtual void tickKey    (float dt) = 0;
     308    };
     309
     310    /**
     311    @brief
     312        Interface class used for mouse input listeners.
     313    */
     314    class _CoreExport MouseHandler : virtual public InputTickable
     315    {
     316    public:
     317        virtual ~MouseHandler() { }
     318        virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
     319        virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
     320        virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
     321        virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
     322        virtual void mouseScrolled      (int abs, int rel)     = 0;
     323        virtual void tickMouse          (float dt) = 0;
     324    };
     325
     326
     327    /**
     328    @brief
     329        Interface class used for joy stick input listeners.
     330    */
     331    class _CoreExport JoyStickHandler : virtual public InputTickable
     332    {
     333    public:
     334        virtual ~JoyStickHandler() { }
     335        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
     336        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) = 0;
     337        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
     338        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
     339        virtual void tickJoyStick          (float dt, unsigned int joyStick) = 0;
     340    };
     341
     342    class _CoreExport EmptyHandler : public KeyHandler, public MouseHandler, public JoyStickHandler
     343    {
     344    private:
     345        void tickInput(float dt) { }
     346        void tickJoyStick(float dt, unsigned int joyStick) { }
     347        void tickMouse(float dt) { }
     348        void tickKey(float dt) { }
     349
     350        void keyPressed (const KeyEvent& evt) { }
     351        void keyReleased(const KeyEvent& evt) { }
     352        void keyHeld    (const KeyEvent& evt) { }
     353
     354        void mouseButtonPressed (MouseButton::Enum id) { }
     355        void mouseButtonReleased(MouseButton::Enum id) { }
     356        void mouseButtonHeld    (MouseButton::Enum id) { }
     357        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
     358        void mouseScrolled      (int abs, int rel) { }
     359
     360        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) { }
     361        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) { }
     362        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id) { }
     363        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) { }
     364    };
    321365
    322366}
  • code/trunk/src/core/input/InputManager.cc

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

    r1555 r1755  
    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   };
    258 
     84        public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
     85    {
     86        // --> setConfigValues is private
     87        friend class ClassIdentifier<InputManager>;
     88        // let Core class use tick(.)
     89        friend class Core;
     90
     91    public:
     92        enum InputManagerState
     93        {
     94            Uninitialised    = 0x00,
     95            OISReady         = 0x01,
     96            InternalsReady   = 0x02,
     97            Ticking          = 0x04,
     98            Calibrating      = 0x08,
     99            ReloadRequest    = 0x10,
     100            JoyStickSupport  = 0x20 // used with ReloadRequest to store a bool
     101        };
     102
     103        InputManager ();
     104        ~InputManager();
     105
     106        void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
     107
     108        void reloadInputSystem(bool joyStickSupport = true);
     109
     110        int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
     111        int  numberOfMice()      { return mouse_    ? 1 : 0; }
     112        int  numberOfJoySticks() { return joySticksSize_; }
     113
     114        void setWindowExtents(const int width, const int height);
     115
     116        template <class T>
     117        T* createInputState(const std::string& name, int priority)
     118        {
     119            T* state = new T;
     120            if (_configureInputState(state, name, priority))
     121                return state;
     122            else
     123            {
     124                delete state;
     125                return 0;
     126            }
     127        }
     128
     129        InputState* getState       (const std::string& name);
     130        InputState* getCurrentState();
     131        bool requestDestroyState   (const std::string& name);
     132        bool requestEnterState     (const std::string& name);
     133        bool requestLeaveState     (const std::string& name);
     134
     135        void tick(float dt);
     136
     137        static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
     138        static InputManager* getInstancePtr() { return singletonRef_s; }
     139
     140    public: // console commands
     141        static void storeKeyStroke(const std::string& name);
     142        static void keyBind(const std::string& command);
     143        static void calibrate();
     144        static void reload(bool joyStickSupport = true);
     145
     146    private: // functions
     147        // don't mess with a Singleton
     148        InputManager (const InputManager&);
     149
     150        // Intenal methods
     151        void _initialiseKeyboard();
     152        void _initialiseMouse();
     153        void _initialiseJoySticks();
     154        void _redimensionLists();
     155
     156        void _destroyKeyboard();
     157        void _destroyMouse();
     158        void _destroyJoySticks();
     159        void _destroyState(InputState* state);
     160        void _clearBuffers();
     161
     162        void _reload(bool joyStickSupport);
     163
     164        void _completeCalibration();
     165
     166        void _fireAxis(unsigned int iJoyStick, int axis, int value);
     167        unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
     168
     169        void _updateActiveStates();
     170        bool _configureInputState(InputState* state, const std::string& name, int priority);
     171
     172        // input events
     173        bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
     174        bool mouseReleased (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
     175        bool mouseMoved    (const OIS::MouseEvent    &arg);
     176        bool keyPressed    (const OIS::KeyEvent      &arg);
     177        bool keyReleased   (const OIS::KeyEvent      &arg);
     178        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
     179        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
     180        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
     181        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
     182        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
     183        // don't remove that! Or else add OIS as dependency library to orxonox.
     184        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
     185
     186        void setConfigValues();
     187
     188    private: // variables
     189        OIS::InputManager*                  inputSystem_;          //!< OIS input manager
     190        OIS::Keyboard*                      keyboard_;             //!< OIS mouse
     191        OIS::Mouse*                         mouse_;                //!< OIS keyboard
     192        std::vector<OIS::JoyStick*>         joySticks_;            //!< OIS joy sticks
     193        unsigned int                        joySticksSize_;
     194        unsigned int                        devicesNum_;
     195        size_t                              windowHnd_;            //!< Render window handle
     196        InputManagerState                   internalState_;        //!< Current internal state
     197
     198        // some internally handled states
     199        SimpleInputState*                   stateDetector_;        //!< KeyDetector instance
     200        SimpleInputState*                   stateCalibrator_;
     201        SimpleInputState*                   stateEmpty_;
     202
     203        std::map<std::string, InputState*>  inputStatesByName_;
     204        std::map<int, InputState*>          inputStatesByPriority_;
     205
     206        std::set<InputState*>               stateEnterRequests_;   //!< Request to enter a new state
     207        std::set<InputState*>               stateLeaveRequests_;   //!< Request to leave a running state
     208        std::set<InputState*>               stateDestroyRequests_; //!< Request to destroy a state
     209
     210        std::map<int, InputState*>          activeStates_;
     211        std::vector<InputState*>            activeStatesTop_;      //!< Current input states for joy stick events.
     212        std::vector<InputState*>            activeStatesTicked_;   //!< Current input states for joy stick events.
     213
     214        // joystick calibration
     215        //std::vector<int> marginalsMaxConfig_;
     216        //std::vector<int> marginalsMinConfig_;
     217        int                                 marginalsMax_[24];
     218        int                                 marginalsMin_[24];
     219        bool                                bCalibrated_;
     220        bool                                bCalibrating_;
     221
     222        unsigned int                        keyboardModifiers_;    //!< Bit mask representing keyboard modifiers.
     223        std::vector<POVStates>              povStates_;            //!< Keeps track of the joy stick POV states.
     224        std::vector<SliderStates>           sliderStates_;         //!< Keeps track of the possibly two slider axes.
     225        std::vector<JoyStickCalibration>    joySticksCalibration_;
     226
     227        std::vector<Key>                    keysDown_;
     228        std::vector<MouseButton::Enum>      mouseButtonsDown_;
     229        std::vector<std::vector<JoyStickButton::Enum> >  joyStickButtonsDown_;
     230
     231        static std::string                  bindingCommmandString_s;
     232        static InputManager*                singletonRef_s;
     233    };
    259234}
    260235
  • code/trunk/src/core/input/KeyBinder.cc

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

    r1535 r1755  
    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, unsigned int joyStick);
     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, JoyStickButton::Enum id);
     86        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id);
     87        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id);
     88        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
    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/trunk/src/core/input/KeyDetector.cc

    r1747 r1755  
    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        this->command_ = command;
     71        clearBindings();
     72        setConfigValues();
     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/trunk/src/core/input/KeyDetector.h

    r1535 r1755  
    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
  • code/trunk/src/core/input/SimpleInputState.cc

    r1724 r1755  
    3636
    3737#include <assert.h>
    38 #include "core/Debug.h"
     38#include "util/Debug.h"
    3939#include "core/Executor.h"
    4040
Note: See TracChangeset for help on using the changeset viewer.