Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 1638 for code/branches/gui/src


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

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

Location:
code/branches/gui
Files:
11 added
77 edited
5 copied

Legend:

Unmodified
Added
Removed
  • code/branches/gui

  • code/branches/gui/src/core/CMakeLists.txt

    r1612 r1638  
    44  Core.cc
    55  Error.cc
     6  Exception.cc
    67  Language.cc
    78  OrxonoxClass.cc
     
    4142  input/Button.cc
    4243  input/CalibratorCallback.cc
     44  input/ExtendedInputState.cc
    4345  input/HalfAxis.cc
    4446  input/InputBuffer.cc
     
    4749  input/KeyBinder.cc
    4850  input/KeyDetector.cc
     51  input/SimpleInputState.cc
    4952
    5053  tolua/tolua_bind.cc
  • code/branches/gui/src/core/ClassTreeMask.h

    r1505 r1638  
    6060    step back, and so on.
    6161
    62     Example: A and B are childs of BaseObject, A1 and A2 are childs of A, B1 and B2 are childs of B.
     62    Example: A and B are children of BaseObject, A1 and A2 are children of A, B1 and B2 are children of B.
    6363    The ClassTreeMaskIterator would move trough the tree in the following order:
    6464    BaseObject, A, A1, A2, B, B1, B2.
  • code/branches/gui/src/core/CommandExecutor.h

    r1505 r1638  
    3636#include "CommandEvaluation.h"
    3737
    38 namespace orxonox
    39 {
     38namespace orxonox // tolua_export
     39{ // tolua_export
    4040    class _CoreExport CommandExecutor
     41    /*
     42    class CommandExecutor { // tolua_export
     43    */
    4144    {
    4245        public:
    43             static bool execute(const std::string& command, bool useTcl = true);
     46            static bool execute(const std::string& command, bool useTcl = true); // tolua_export
    4447            static std::string complete(const std::string& command);
    4548            static std::string hint(const std::string& command);
     
    98101            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_;
    99102            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_LC_;
    100     };
    101 }
     103    }; // tolua_export
     104} // tolua_export
    102105
    103106#endif /* _CommandExecutor_H__ */
  • code/branches/gui/src/core/Core.cc

    r1535 r1638  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
  • code/branches/gui/src/core/Core.h

    r1535 r1638  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
     
    2929/**
    3030    @file Core.h
    31     @brief Definition of the Core class.
     31    @brief Declaration of the Core class.
    3232
    3333    The Core class is a singleton, only used to configure some variables
  • code/branches/gui/src/core/CoreIncludes.h

    r1543 r1638  
    105105    @param StringOrInt The name or the network ID of the class
    106106*/
    107 #define ID(StringOrInt) \
     107#define GetIdentifier(StringOrInt) \
    108108    orxonox::Factory::getIdentifier(StringOrInt)
    109109
  • code/branches/gui/src/core/CorePrereqs.h

    r1543 r1638  
    158158
    159159  // input
    160   //class GUIInputHandler;
    161160  class BaseCommand;
    162161  class BufferedParamCommand;
    163162  class Button;
    164163  class CalibratorCallback;
     164  class ExtendedInputState;
    165165  class HalfAxis;
    166166  class InputBuffer;
    167167  class InputManager;
     168  class InputState;
    168169  class JoyStickHandler;
    169170  class MouseHandler;
     
    173174  class ParamCommand;
    174175  class SimpleCommand;
     176  class SimpleInputState;
    175177}
    176178
  • code/branches/gui/src/core/Error.cc

    r1505 r1638  
    3737namespace orxonox
    3838{
    39         Error::Error(std::string errorMsg, int errorCode)
    40         {
    41                 COUT(1) << "############################ "<< std::endl
    42                                                         << "#         Error "<<errorCode<< "          #"<< std::endl
    43                                                         << "############################ "<< std::endl
    44                                                         << "An error occured in Orxonox: "<< std::endl;
     39    Error::Error(std::string errorMsg, int errorCode)
     40    {
     41        COUT(1) << "############################ "<< std::endl
     42                            << "#         Error "<<errorCode<< "          #"<< std::endl
     43                            << "############################ "<< std::endl
     44                            << "An error occured in Orxonox: "<< std::endl;
    4545
    46                 if (errorMsg=="")
    47                 {
    48                         switch (errorCode)
    49                         {
    50                                 case 1:
    51                                         errorMsg = "Some error!";
    52                                         break;
    53                                 default:
    54                                         errorMsg = "Unknown error!";
    55                         }
    56                 }
    57                 COUT(1) << errorMsg << std::endl<< std::endl;
    58         }
     46        if (errorMsg=="")
     47        {
     48            switch (errorCode)
     49            {
     50                case 1:
     51                    errorMsg = "Some error!";
     52                    break;
     53                default:
     54                    errorMsg = "Unknown error!";
     55            }
     56        }
     57        COUT(1) << errorMsg << std::endl<< std::endl;
     58    }
    5959}
  • code/branches/gui/src/core/Error.h

    r1505 r1638  
    2929/**
    3030    @file Error.h
    31     @brief Definition of the Error class.
     31    @brief Declaration of the Error class.
    3232*/
    3333
     
    4141namespace orxonox
    4242{
    43         class _CoreExport Error
    44         {
    45         public:
    46                 Error(std::string errorMsg = "", int errorCode = 0);
    47         private:
     43    class _CoreExport Error
     44    {
     45    public:
     46        Error(std::string errorMsg = "", int errorCode = 0);
     47    private:
    4848
    49         };
     49    };
    5050}
    5151
  • code/branches/gui/src/core/Identifier.h

    r1543 r1638  
    7676         - the name
    7777         - a list with all objects
    78          - parents and childs
     78         - parents and children
    7979         - the factory (if available)
    8080         - the networkID that can be synchronised with the server
  • code/branches/gui/src/core/OrxonoxClass.h

    r1505 r1638  
    2929/**
    3030    @file OrxonoxClass.h
    31     @brief Definition of the OrxonoxClass Class.
     31    @brief Declaration of the OrxonoxClass Class.
    3232
    3333    All objects and interfaces of the game-logic (not the engine) are derived from OrxonoxClass.
  • code/branches/gui/src/core/Script.cc

    r1555 r1638  
    6060    luaopen_debug(luaState_);
    6161#endif
    62     tolua_core_open(luaState_);
     62    tolua_Core_open(luaState_);
    6363    output_ = "";
    6464  }
  • code/branches/gui/src/core/Shell.cc

    r1540 r1638  
    3434#include "ConsoleCommand.h"
    3535#include "input/InputInterfaces.h"
     36#include "input/SimpleInputState.h"
     37#include "input/InputManager.h"
    3638
    3739#define SHELL_UPDATE_LISTENERS(function) \
     
    5759        this->clearLines();
    5860
    59         this->inputBuffer_ = 0;
    60         this->setInputBuffer(new InputBuffer());
     61        this->inputBuffer_ = new InputBuffer();
     62        this->configureInputBuffer();
     63        InputManager::createSimpleInputState("console", 40)->setKeyHandler(this->inputBuffer_);
    6164
    6265        this->outputBuffer_.registerListener(this);
    6366
    6467        this->setConfigValues();
     68    }
     69
     70    Shell::~Shell()
     71    {
     72        SimpleInputState * inputState = dynamic_cast<SimpleInputState*>(InputManager::getState("console"));
     73        if (inputState)
     74        {
     75            inputState->removeAndDestroyAllHandlers();
     76            InputManager::destroyState("console");
     77        }
    6578    }
    6679
     
    97110    }
    98111
    99     void Shell::setInputBuffer(InputBuffer* buffer)
    100     {
    101         if (this->inputBuffer_)
    102         {
    103             this->inputBuffer_->unregisterListener(this);
    104             // TODO: may be very dangerous. InputManager already deletes InputBuffer instance!!!
    105             delete this->inputBuffer_;
    106         }
    107 
    108         this->inputBuffer_ = buffer;
     112    void Shell::configureInputBuffer()
     113    {
    109114        this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
    110115        this->inputBuffer_->registerListener(this, &Shell::execute, '\r', false);
  • code/branches/gui/src/core/Shell.h

    r1535 r1638  
    7171            void unregisterListener(ShellListener* listener);
    7272
    73             void setInputBuffer(InputBuffer* buffer);
    7473            inline InputBuffer& getInputBuffer()
    7574                { return (*this->inputBuffer_); }
     
    105104            Shell();
    106105            Shell(const Shell& other);
    107             virtual ~Shell() {}
     106            virtual ~Shell();
     107
     108            void configureInputBuffer();
    108109
    109110            void addToHistory(const std::string& command);
  • code/branches/gui/src/core/SignalHandler.h

    r1505 r1638  
    2929/**
    3030    @file SignalHandler.h
    31     @brief Definition of the SignalHandler class.
     31    @brief Declaration of the SignalHandler class.
    3232*/
    3333
  • code/branches/gui/src/core/XMLPort.h

    r1628 r1638  
    288288                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
    289289                            {
    290                                 Identifier* identifier = ID(child->Value());
     290                                Identifier* identifier = GetIdentifier(child->Value());
    291291                                if (identifier)
    292292                                {
  • code/branches/gui/src/core/input/Button.cc

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    r1535 r1638  
    2828
    2929/**
    30  @file
    31  @brief Different definitions of input processing.
    32  */
     30@file
     31@brief
     32    Different definitions of input processing.
     33*/
    3334
    3435#ifndef _KeyDetector_H__
     
    4142namespace orxonox
    4243{
    43   class _CoreExport KeyDetector : public KeyBinder
    44   {
    45   public:
    46     KeyDetector();
    47     ~KeyDetector();
    48     void loadBindings();
     44    class _CoreExport KeyDetector : public KeyBinder
     45    {
     46    public:
     47        KeyDetector();
     48        ~KeyDetector();
     49        void loadBindings(const std::string& command);
    4950
    50   protected:
    51     void readTrigger(Button& button);
    52   };
     51    protected:
     52        void readTrigger(Button& button);
     53
     54    private:
     55        std::string command_;
     56    };
    5357}
    5458
  • code/branches/gui/src/core/tolua/tolua.pkg

    r1505 r1638  
    11$cfile "../../src/core/Script_clean.h"
     2$cfile "../../src/core/CommandExecutor.h"
  • code/branches/gui/src/network/Client.cc

    r1534 r1638  
    227227  void Client::processClassid(classid *clid){
    228228    orxonox::Identifier *id;
    229     id=ID(std::string(clid->message));
     229    id=GetIdentifier(std::string(clid->message));
    230230    if(id!=NULL)
    231231      id->setNetworkID(clid->clid);
    232232    COUT(4) << "Client: received and set network id: " << clid->clid << "; classname: " << clid->message << std::endl;
    233     COUT(4) << "id(classid)->getName " << ID((unsigned int)clid->clid)->getName() << std::endl;
     233    COUT(4) << "id(classid)->getName " << GetIdentifier((unsigned int)clid->clid)->getName() << std::endl;
    234234    delete clid;
    235235    return;
  • code/branches/gui/src/network/ClientConnection.cc

    r1534 r1638  
    4242#include <iostream>
    4343// boost.thread library for multithreading support
     44#include <boost/thread/thread.hpp>
    4445#include <boost/bind.hpp>
    4546
  • code/branches/gui/src/network/ClientConnection.h

    r1534 r1638  
    4545#include <string>
    4646#include <enet/enet.h>
    47 #include <boost/thread/thread.hpp>
     47#include <boost/thread/recursive_mutex.hpp>
     48#include "PacketBuffer.h"
    4849
    49 #include "PacketBuffer.h"
     50namespace boost { class thread; }
    5051
    5152namespace network
  • code/branches/gui/src/network/ConnectionManager.cc

    r1534 r1638  
    4040#include <iostream>
    4141// boost.thread library for multithreading support
     42#include <boost/thread/thread.hpp>
    4243#include <boost/bind.hpp>
    4344
  • code/branches/gui/src/network/ConnectionManager.h

    r1505 r1638  
    4747// enet library for networking support
    4848#include <enet/enet.h>
    49 #include <boost/thread/thread.hpp>
    5049#include <boost/thread/recursive_mutex.hpp>
    5150
    5251#include "PacketBuffer.h"
    5352#include "PacketManager.h"
     53
     54namespace boost { class thread; }
    5455
    5556namespace std
  • code/branches/gui/src/network/GameStateClient.cc

    r1625 r1638  
    177177          ///sigsegv may happen here again for some reason
    178178          ///sigsegv is receved after the COUT(4) above
    179           orxonox::Identifier* id = ID((unsigned int)sync.classID);
     179          orxonox::Identifier* id = GetIdentifier((unsigned int)sync.classID);
    180180          if(!id){
    181181            COUT(3) << "We could not identify a new object; classid: " << sync.classID << " uint: " << (unsigned int)sync.classID << " objectID: " << sync.objectID << " size: " << sync.length << std::endl;
  • code/branches/gui/src/network/GameStateManager.cc

    r1534 r1638  
    4444#include <iostream>
    4545#include <zlib.h>
    46 #include <assert.h>
     46#include <cassert>
    4747
    4848#include "core/CoreIncludes.h"
     
    278278        COUT(4) << "loadsnapshot: creating new object " << std::endl;
    279279        //COUT(4) << "loadSnapshot:\tclassid: " << sync.classID << ", name: " << ID((unsigned int) sync.classID)->getName() << std::endl;
    280         orxonox::Identifier* id = ID((unsigned int)sync.classID);
     280        orxonox::Identifier* id = GetIdentifier((unsigned int)sync.classID);
    281281        if(!id){
    282282          COUT(4) << "We could not identify a new object; classid: " << sync.classID << std::endl;
  • code/branches/gui/src/network/Server.cc

    r1556 r1638  
    4242
    4343#include <iostream>
     44#include <cassert>
    4445
    4546
     
    370371    if(!client)
    371372      return false;
    372     orxonox::Identifier* id = ID("SpaceShip");
     373    orxonox::Identifier* id = GetIdentifier("SpaceShip");
    373374    if(!id){
    374375      COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;
  • code/branches/gui/src/orxonox/GraphicsEngine.cc

    r1625 r1638  
    2727 */
    2828
    29  /**
    30     @file orxonox.cc
    31     @brief Orxonox class
    32   */
     29/**
     30@file
     31@brief
     32    Implementation of an partial interface to Ogre.
     33*/
    3334
    3435#include "OrxonoxStableHeaders.h"
     
    5051#include "core/CommandExecutor.h"
    5152#include "core/ConsoleCommand.h"
     53#include "core/Exception.h"
    5254
    5355#include "overlays/console/InGameConsole.h"
     
    5759#include "tools/WindowEventListener.h"
    5860
     61#include "objects/CameraHandler.h"
    5962
    6063namespace orxonox
    6164{
    62   /**
    63     @brief Returns the singleton instance and creates it the first time.
    64     @return The only instance of GraphicsEngine.
    65   */
    66   /*static*/ GraphicsEngine& GraphicsEngine::getSingleton()
    67   {
    68     static GraphicsEngine theOnlyInstance;
    69     return theOnlyInstance;
    70   }
    71 
    72   /**
    73     @brief Only use constructor to initialise variables and pointers!
    74   */
    75   GraphicsEngine::GraphicsEngine() :
    76     root_(0),
    77     scene_(0),
    78     renderWindow_(0)
    79   {
    80     RegisterObject(GraphicsEngine);
    81 
    82     this->detailLevelParticle_ = 0;
    83 
    84     this->setConfigValues();
    85     CCOUT(4) << "Constructed" << std::endl;
    86   }
    87 
    88   void GraphicsEngine::setConfigValues()
    89   {
    90     SetConfigValue(resourceFile_,    "resources.cfg").description("Location of the resources file in the data path.");
    91     SetConfigValue(ogreConfigFile_,  "ogre.cfg").description("Location of the Ogre config file");
    92     SetConfigValue(ogrePluginsFile_, "plugins.cfg").description("Location of the Ogre plugins file");
    93     SetConfigValue(ogreLogFile_,     "ogre.log").description("Logfile for messages from Ogre. \
    94                                                              Use \"\" to suppress log file creation.");
    95     SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
    96     SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
    97     SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");
    98 
    99     unsigned int old = this->detailLevelParticle_;
    100     SetConfigValue(detailLevelParticle_, 2).description("O: off, 1: low, 2: normal, 3: high");
    101 
    102     if (this->detailLevelParticle_ != old)
    103       for (Iterator<ParticleInterface> it = ObjectList<ParticleInterface>::begin(); it; ++it)
    104         it->detailLevelChanged(this->detailLevelParticle_);
    105   }
    106 
    107   /**
    108     @brief Called after main() --> call destroyObjects()!
    109   */
    110   GraphicsEngine::~GraphicsEngine()
    111   {
    112     this->destroy();
    113   }
    114 
    115   /**
    116     @brief Destroys all the internal objects. Call this method when you
    117            normally would call the destructor.
    118   */
    119   void GraphicsEngine::destroy()
    120   {
    121     CCOUT(4) << "Destroying objects..." << std::endl;
    122     Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
    123     if (this->root_)
    124       delete this->root_;
    125     this->root_ = 0;
    126     this->scene_ = 0;
    127     this->renderWindow_ = 0;
    128     // delete the ogre log and the logManager (since we have created it).
    129     if (Ogre::LogManager::getSingletonPtr() != 0)
    130     {
    131       Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
    132       Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
    133       delete Ogre::LogManager::getSingletonPtr();
    134     }
    135     CCOUT(4) << "Destroying objects done" << std::endl;
    136   }
    137 
    138   /**
    139     @brief Creates the Ogre Root object and sets up the ogre log.
    140   */
    141   bool GraphicsEngine::setup()
    142   {
    143     CCOUT(3) << "Setting up..." << std::endl;
    144     // temporary overwrite of dataPath, change ini file for permanent change
    145 
    146 // TODO: LogManager doesn't work on specific systems. The why is unknown yet.
     65    GraphicsEngine* GraphicsEngine::singletonRef_s = 0;
     66
     67    /**
     68    @brief
     69        Returns the singleton instance.
     70    @return
     71        The only instance of GraphicsEngine.
     72    */
     73    /*static*/ GraphicsEngine& GraphicsEngine::getSingleton()
     74    {
     75        assert(singletonRef_s);
     76        return *singletonRef_s;
     77    }
     78
     79    /**
     80    @brief
     81        Non-initialising constructor.
     82    */
     83    GraphicsEngine::GraphicsEngine()
     84        : root_(0)
     85        , renderWindow_(0)
     86        , levelSceneManager_(0)
     87        , levelViewport_(0)
     88    {
     89        RegisterObject(GraphicsEngine);
     90
     91        singletonRef_s = this;
     92
     93        this->detailLevelParticle_ = 0;
     94
     95        this->setConfigValues();
     96        CCOUT(4) << "Constructed" << std::endl;
     97    }
     98
     99    void GraphicsEngine::setConfigValues()
     100    {
     101        SetConfigValue(resourceFile_,    "resources.cfg").description("Location of the resources file in the data path.");
     102        SetConfigValue(ogreConfigFile_,  "ogre.cfg").description("Location of the Ogre config file");
     103        SetConfigValue(ogrePluginsFile_, "plugins.cfg").description("Location of the Ogre plugins file");
     104        SetConfigValue(ogreLogFile_,     "ogre.log").description("Logfile for messages from Ogre. \
     105                                                                 Use \"\" to suppress log file creation.");
     106        SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
     107        SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
     108        SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");
     109
     110        unsigned int old = this->detailLevelParticle_;
     111        SetConfigValue(detailLevelParticle_, 2).description("O: off, 1: low, 2: normal, 3: high");
     112
     113        if (this->detailLevelParticle_ != old)
     114            for (Iterator<ParticleInterface> it = ObjectList<ParticleInterface>::begin(); it; ++it)
     115                it->detailLevelChanged(this->detailLevelParticle_);
     116    }
     117
     118    /**
     119    @brief
     120        Destroys all the Ogre related objects
     121    */
     122    GraphicsEngine::~GraphicsEngine()
     123    {
     124        CCOUT(4) << "Destroying objects..." << std::endl;
     125        Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
     126        if (this->root_)
     127            delete this->root_;
     128        this->root_ = 0;
     129        this->levelSceneManager_ = 0;
     130        this->renderWindow_ = 0;
     131
    147132#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
    148     // create a logManager
    149     // note: If there's already a logManager, Ogre will complain by a failed assertation.
    150     // but that shouldn't happen, since this is the first time to create a logManager..
    151     Ogre::LogManager* logger = new Ogre::LogManager();
    152     CCOUT(4) << "Ogre LogManager created" << std::endl;
    153 
    154     // create our own log that we can listen to
    155     Ogre::Log *myLog;
    156     if (this->ogreLogFile_ == "")
    157       myLog = logger->createLog("ogre.log", true, false, true);
    158     else
    159       myLog = logger->createLog(this->ogreLogFile_, true, false, false);
    160     CCOUT(4) << "Ogre Log created" << std::endl;
    161 
    162     myLog->setLogDetail(Ogre::LL_BOREME);
    163     myLog->addListener(this);
     133        // delete the ogre log and the logManager (since we have created it).
     134        if (Ogre::LogManager::getSingletonPtr() != 0)
     135        {
     136            Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
     137            Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
     138            delete Ogre::LogManager::getSingletonPtr();
     139        }
     140        CCOUT(4) << "Destroying objects done" << std::endl;
    164141#endif
    165142
    166     // Root will detect that we've already created a Log
    167     CCOUT(4) << "Creating Ogre Root..." << std::endl;
    168 
    169     if (ogrePluginsFile_ == "")
    170     {
    171       COUT(1) << "Error: Ogre plugins file set to \"\". Cannot load." << std::endl;
    172       return false;
    173     }
    174     if (ogreConfigFile_ == "")
    175     {
    176       COUT(1) << "Error: Ogre config file set to \"\". Cannot load." << std::endl;
    177       return false;
    178     }
    179     if (ogreLogFile_ == "")
    180     {
    181       COUT(1) << "Error: Ogre log file set to \"\". Cannot load." << std::endl;
    182       return false;
    183     }
    184 
    185     try
    186     {
    187       root_ = new Ogre::Root(ogrePluginsFile_, ogreConfigFile_, ogreLogFile_);
    188     }
    189     catch (Ogre::Exception ex)
    190     {
    191       COUT(2) << "Error: There was an exception when creating Ogre Root." << std::endl;
    192       return false;
    193     }
    194 
    195     if (!root_->getInstalledPlugins().size())
    196     {
    197       COUT(1) << "Error: No plugins declared. Cannot load Ogre." << std::endl;
    198       COUT(0) << "Is the plugins file correctly declared?" << std::endl;
    199       return false;
    200     }
    201 
    202 #if 0
    203     // tame the ogre ouput so we don't get all the mess in the console
    204     Ogre::Log* defaultLog = Ogre::LogManager::getSingleton().getDefaultLog();
    205     defaultLog->setDebugOutputEnabled(false);
    206     defaultLog->setLogDetail(Ogre::LL_BOREME);
    207     defaultLog->addListener(this);
     143        singletonRef_s = 0;
     144    }
     145
     146    /**
     147    @brief
     148        Creates the Ogre Root object and sets up the ogre log.
     149    */
     150    void GraphicsEngine::setup()
     151    {
     152        CCOUT(3) << "Setting up..." << std::endl;
     153
     154        // TODO: LogManager doesn't work on linux platform. The why is yet unknown.
     155#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
     156        // create a new logManager
     157        Ogre::LogManager* logger = new Ogre::LogManager();
     158        CCOUT(4) << "Ogre LogManager created" << std::endl;
     159
     160        // create our own log that we can listen to
     161        Ogre::Log *myLog;
     162        if (this->ogreLogFile_ == "")
     163            myLog = logger->createLog("ogre.log", true, false, true);
     164        else
     165            myLog = logger->createLog(this->ogreLogFile_, true, false, false);
     166        CCOUT(4) << "Ogre Log created" << std::endl;
     167
     168        myLog->setLogDetail(Ogre::LL_BOREME);
     169        myLog->addListener(this);
    208170#endif
    209171
    210     CCOUT(4) << "Creating Ogre Root done" << std::endl;
    211 
    212     // specify where Ogre has to look for resources. This call doesn't parse anything yet!
    213     if (!declareRessourceLocations())
    214       return false;
    215 
    216     CCOUT(3) << "Set up done." << std::endl;
    217     return true;
    218   }
    219 
    220   bool GraphicsEngine::declareRessourceLocations()
    221   {
    222     CCOUT(4) << "Declaring Resources" << std::endl;
    223     //TODO: Specify layout of data file and maybe use xml-loader
    224     //TODO: Work with ressource groups (should be generated by a special loader)
    225 
    226     if (resourceFile_ == "")
    227     {
    228       COUT(1) << "Error: Resource file set to \"\". Cannot load." << std::endl;
    229       return false;
    230     }
    231 
    232     // Load resource paths from data file using configfile ressource type
    233     Ogre::ConfigFile cf;
    234     try
    235     {
    236       cf.load(Settings::getDataPath() + resourceFile_);
    237     }
    238     catch (Ogre::Exception ex)
    239     {
    240       COUT(1) << "Error: Could not load resources.cfg in path " << Settings::getDataPath() << std::endl;
    241       COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
    242       return false;
    243     }
    244 
    245     // Go through all sections & settings in the file
    246     Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
    247 
    248     std::string secName, typeName, archName;
    249     while (seci.hasMoreElements())
    250     {
    251       try
    252       {
    253         secName = seci.peekNextKey();
    254         Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
    255         Ogre::ConfigFile::SettingsMultiMap::iterator i;
    256         for (i = settings->begin(); i != settings->end(); ++i)
    257         {
    258           typeName = i->first; // for instance "FileSystem" or "Zip"
    259           archName = i->second; // name (and location) of archive
    260 
    261           Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    262               std::string(Settings::getDataPath() + archName), typeName, secName);
    263         }
    264       }
    265       catch (Ogre::Exception ex)
    266       {
    267         COUT(2) << "Exception while reading resources.cfg. Proceeding.." << ex.getDescription() << std::endl;
    268       }
    269     }
    270     return true;
    271   }
    272 
    273   bool GraphicsEngine::loadRenderer()
    274   {
    275     CCOUT(4) << "Configuring Renderer" << std::endl;
    276 
    277     // check for file existence because Ogre displays exceptions if not
    278     std::ifstream probe;
    279     probe.open(ogreConfigFile_.c_str());
    280     if (!probe)
    281     {
    282       // create a zero sized file
    283       std::ofstream creator;
    284       creator.open(ogreConfigFile_.c_str());
    285       creator.close();
    286     }
    287     else
    288       probe.close();
    289 
    290     if (!root_->restoreConfig())
    291       if (!root_->showConfigDialog())
    292         return false;
    293 
    294     CCOUT(4) << "Creating render window" << std::endl;
    295     try
    296     {
    297       this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
    298     }
    299     catch (Ogre::Exception ex)
    300     {
    301       COUT(2) << "Error: There was an exception when initialising Ogre Root." << std::endl;
    302       return false;
    303     }
    304 
    305     if (!root_->isInitialised())
    306     {
    307       CCOUT(2) << "Error: Initialising Ogre root object failed." << std::endl;
    308       return false;
    309     }
    310     Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
    311     Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
    312     return true;
    313   }
    314 
    315   bool GraphicsEngine::initialiseResources()
    316   {
    317     CCOUT(4) << "Initialising resources" << std::endl;
    318     //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
    319     try
    320     {
    321       Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    322       /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
    323       for (unsigned int i = 0; i < str.size(); i++)
    324       {
    325         Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
    326       }*/
    327     }
    328     catch (Ogre::Exception e)
    329     {
    330       CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
    331       CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
    332       return false;
    333     }
    334     return true;
    335   }
    336 
    337   /**
    338    * @brief Creates the SceneManager
    339    */
    340   bool GraphicsEngine::createNewScene()
    341   {
    342     CCOUT(4) << "Creating new SceneManager..." << std::endl;
    343     if (scene_)
    344     {
    345       CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
    346       return false;
    347     }
    348     scene_ = root_->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
    349     CCOUT(3) << "Created SceneManager: " << scene_ << std::endl;
    350     return true;
    351   }
    352 
    353   /**
    354     Returns the window handle of the render window.
    355     At least the InputHandler uses this to create the OIS::InputManager
    356     @return The window handle of the render window
    357   */
    358   size_t GraphicsEngine::getWindowHandle()
    359   {
    360     if (this->renderWindow_)
    361     {
    362       size_t windowHnd = 0;
    363       this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
    364       return windowHnd;
    365     }
    366     else
    367       return 0;
    368   }
    369 
    370   /**
    371     Get the width of the current render window
    372     @return The width of the current render window
    373   */
    374   int GraphicsEngine::getWindowWidth() const
    375   {
    376     if (this->renderWindow_)
    377       return this->renderWindow_->getWidth();
    378     else
    379       return 0;
    380   }
    381 
    382   /**
    383     Get the height of the current render window
    384     @return The height of the current render window
    385   */
    386   int GraphicsEngine::getWindowHeight() const
    387   {
    388     if (this->renderWindow_)
    389       return this->renderWindow_->getHeight();
    390     else
    391       return 0;
    392   }
    393 
    394   /**
    395     @brief Returns the window aspect ratio height/width.
    396     @return The ratio
    397   */
    398   float GraphicsEngine::getWindowAspectRatio() const
    399   {
    400     if (this->renderWindow_)
    401         return (float)this->renderWindow_->getHeight() / (float)this->renderWindow_->getWidth();
    402     else
    403         return 1.0f;
    404   }
    405 
    406   /**
    407     @brief Method called by the LogListener interface from Ogre.
    408     We use it to capture Ogre log messages and handle it ourselves.
    409     @param message The message to be logged
    410     @param lml The message level the log is using
    411     @param maskDebug If we are printing to the console or not
    412     @param logName the name of this log (so you can have several listeners
    413                    for different logs, and identify them)
    414   */
    415   void GraphicsEngine::messageLogged(const std::string& message,
    416     Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
    417   {
    418     int orxonoxLevel;
    419     switch (lml)
    420     {
    421       case Ogre::LML_TRIVIAL:
    422         orxonoxLevel = this->ogreLogLevelTrivial_;
    423         break;
    424       case Ogre::LML_NORMAL:
    425         orxonoxLevel = this->ogreLogLevelNormal_;
    426         break;
    427       case Ogre::LML_CRITICAL:
    428         orxonoxLevel = this->ogreLogLevelCritical_;
    429         break;
    430       default:
    431         orxonoxLevel = 0;
    432     }
    433     OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
    434         << "Ogre: " << message << std::endl;
    435   }
    436 
    437   /**
    438   * Window has moved.
    439   * @param rw The render window it occured in
    440   */
    441   void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
    442   {
    443     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    444       it->windowMoved();
    445   }
    446 
    447   /**
    448   * Window has resized.
    449   * @param rw The render window it occured in
    450   * @note GraphicsEngine has a render window stored itself. This is the same
    451   *       as rw. But we have to be careful when using multiple render windows!
    452   */
    453   void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)
    454   {
    455     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    456       it->windowResized(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
    457   }
    458 
    459   /**
    460   * Window has changed Focus.
    461   * @param rw The render window it occured in
    462   */
    463   void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
    464   {
    465     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    466       it->windowFocusChanged();
    467   }
    468 
    469   /**
    470   * Window was closed.
    471   * @param rw The render window it occured in
    472   */
    473   void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
    474   {
    475     // using CommandExecutor in order to avoid depending on Orxonox.h.
    476     CommandExecutor::execute("exit", false);
    477   }
     172        // Root will detect that we've already created a Log
     173        CCOUT(4) << "Creating Ogre Root..." << std::endl;
     174
     175        if (ogrePluginsFile_ == "")
     176        {
     177            COUT(2) << "Warning: Ogre plugins file set to \"\". Defaulting to plugins.cfg" << std::endl;
     178            ModifyConfigValue(ogrePluginsFile_, tset, "plugins.cfg");
     179        }
     180        if (ogreConfigFile_ == "")
     181        {
     182            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
     183            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
     184        }
     185        if (ogreLogFile_ == "")
     186        {
     187            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
     188            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
     189        }
     190
     191        root_ = new Ogre::Root(ogrePluginsFile_, ogreConfigFile_, ogreLogFile_);
     192
     193        if (!root_->getInstalledPlugins().size())
     194        {
     195            ThrowException(PluginsNotFound, "No Ogre plugins declared. Cannot load Ogre.");
     196        }
     197
     198#if 0 // Ogre 1.4.3 doesn't support setDebugOutputEnabled(.)
     199//#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
     200        // tame the ogre ouput so we don't get all the mess in the console
     201        Ogre::Log* defaultLog = Ogre::LogManager::getSingleton().getDefaultLog();
     202        defaultLog->setDebugOutputEnabled(false);
     203        defaultLog->setLogDetail(Ogre::LL_BOREME);
     204        defaultLog->addListener(this);
     205#endif
     206
     207        CCOUT(4) << "Creating Ogre Root done" << std::endl;
     208
     209        // specify where Ogre has to look for resources. This call doesn't parse anything yet!
     210        declareRessourceLocations();
     211
     212        CCOUT(3) << "Set up done." << std::endl;
     213    }
     214
     215    void GraphicsEngine::declareRessourceLocations()
     216    {
     217        CCOUT(4) << "Declaring Resources" << std::endl;
     218        //TODO: Specify layout of data file and maybe use xml-loader
     219        //TODO: Work with ressource groups (should be generated by a special loader)
     220
     221        if (resourceFile_ == "")
     222        {
     223            COUT(2) << "Warning: Ogre resource file set to \"\". Defaulting to resources.cfg" << std::endl;
     224            ModifyConfigValue(resourceFile_, tset, "resources.cfg");
     225        }
     226
     227        // Load resource paths from data file using configfile ressource type
     228        Ogre::ConfigFile cf;
     229        try
     230        {
     231            cf.load(Settings::getDataPath() + resourceFile_);
     232        }
     233        catch (Ogre::Exception& ex)
     234        {
     235            COUT(1) << ex.getFullDescription() << std::endl;
     236            COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
     237            throw;
     238        }
     239
     240        // Go through all sections & settings in the file
     241        Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
     242
     243        std::string secName, typeName, archName;
     244        while (seci.hasMoreElements())
     245        {
     246            try
     247            {
     248                secName = seci.peekNextKey();
     249                Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
     250                Ogre::ConfigFile::SettingsMultiMap::iterator i;
     251                for (i = settings->begin(); i != settings->end(); ++i)
     252                {
     253                    typeName = i->first; // for instance "FileSystem" or "Zip"
     254                    archName = i->second; // name (and location) of archive
     255
     256                    Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
     257                        std::string(Settings::getDataPath() + archName), typeName, secName);
     258                }
     259            }
     260            catch (Ogre::Exception& ex)
     261            {
     262                COUT(1) << ex.getFullDescription() << std::endl;
     263            }
     264        }
     265    }
     266
     267    bool GraphicsEngine::loadRenderer()
     268    {
     269        CCOUT(4) << "Configuring Renderer" << std::endl;
     270
     271        // check for file existence because Ogre displays exceptions if not
     272        std::ifstream probe;
     273        probe.open(ogreConfigFile_.c_str());
     274        if (!probe)
     275        {
     276            // create a zero sized file
     277            std::ofstream creator;
     278            creator.open(ogreConfigFile_.c_str());
     279            creator.close();
     280        }
     281        else
     282            probe.close();
     283
     284        if (!root_->restoreConfig())
     285            if (!root_->showConfigDialog())
     286                return false;
     287
     288        CCOUT(4) << "Creating render window" << std::endl;
     289        try
     290        {
     291            this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
     292        }
     293        catch (...)
     294        {
     295            COUT(2) << "Error: There was an exception when initialising Ogre Root." << std::endl;
     296            return false;
     297        }
     298
     299        if (!root_->isInitialised())
     300        {
     301            CCOUT(2) << "Error: Initialising Ogre root object failed." << std::endl;
     302            return false;
     303        }
     304        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
     305        //Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
     306
     307        // create a full screen viewport in which to render the scene and the loading screen
     308        // The GUI uses its own one to be able to render on top of everything.
     309        // That explains why the Z order here is only 1 and not 0 (top most)
     310        this->levelViewport_ = this->renderWindow_->addViewport(0, 1);
     311
     312        return true;
     313    }
     314
     315    bool GraphicsEngine::initialiseResources()
     316    {
     317        CCOUT(4) << "Initialising resources" << std::endl;
     318        //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
     319        try
     320        {
     321            Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
     322            /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
     323            for (unsigned int i = 0; i < str.size(); i++)
     324            {
     325            Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
     326            }*/
     327        }
     328        catch (Ogre::Exception& e)
     329        {
     330            CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
     331            CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
     332            return false;
     333        }
     334        return true;
     335    }
     336
     337    /**
     338    @brief
     339        Creates the SceneManager
     340    */
     341    bool GraphicsEngine::createNewScene()
     342    {
     343        CCOUT(4) << "Creating new SceneManager..." << std::endl;
     344        if (levelSceneManager_)
     345        {
     346            CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
     347            return false;
     348        }
     349        this->levelSceneManager_ = this->root_->createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
     350        CCOUT(3) << "Created SceneManager: " << levelSceneManager_ << std::endl;
     351        return true;
     352    }
     353
     354    /**
     355    @brief
     356        Returns the window handle of the render window.
     357        At least the InputHandler uses this to create the OIS::InputManager
     358    @return
     359        The window handle of the render window
     360    */
     361    size_t GraphicsEngine::getWindowHandle()
     362    {
     363        if (this->renderWindow_)
     364        {
     365            size_t windowHnd = 0;
     366            this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
     367            return windowHnd;
     368        }
     369        else
     370            return 0;
     371    }
     372
     373    /**
     374    @brief
     375        Get the width of the render window
     376    @return
     377        The width of the render window
     378    */
     379    int GraphicsEngine::getWindowWidth() const
     380    {
     381        if (this->renderWindow_)
     382            return this->renderWindow_->getWidth();
     383        else
     384            return 0;
     385    }
     386
     387    /**
     388    @brief
     389        Get the height of the render window
     390    @return
     391        The height of the render window
     392    */
     393    int GraphicsEngine::getWindowHeight() const
     394    {
     395        if (this->renderWindow_)
     396            return this->renderWindow_->getHeight();
     397        else
     398            return 0;
     399    }
     400
     401    /**
     402    @brief
     403        Returns the window aspect ratio height/width.
     404    @return
     405        The window aspect ratio
     406    */
     407    float GraphicsEngine::getWindowAspectRatio() const
     408    {
     409        if (this->renderWindow_)
     410            return (float)this->renderWindow_->getHeight() / (float)this->renderWindow_->getWidth();
     411        else
     412            return 1.0f;
     413    }
     414
     415    /**
     416    @brief
     417        Method called by the LogListener interface from Ogre.
     418        We use it to capture Ogre log messages and handle it ourselves.
     419    @param message
     420        The message to be logged
     421    @param lml
     422        The message level the log is using
     423    @param maskDebug
     424        If we are printing to the console or not
     425    @param logName
     426        The name of this log (so you can have several listeners
     427        for different logs, and identify them)
     428    */
     429    void GraphicsEngine::messageLogged(const std::string& message,
     430        Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
     431    {
     432        int orxonoxLevel;
     433        switch (lml)
     434        {
     435        case Ogre::LML_TRIVIAL:
     436            orxonoxLevel = this->ogreLogLevelTrivial_;
     437            break;
     438        case Ogre::LML_NORMAL:
     439            orxonoxLevel = this->ogreLogLevelNormal_;
     440            break;
     441        case Ogre::LML_CRITICAL:
     442            orxonoxLevel = this->ogreLogLevelCritical_;
     443            break;
     444        default:
     445            orxonoxLevel = 0;
     446        }
     447        OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
     448            << "Ogre: " << message << std::endl;
     449    }
     450
     451    /**
     452    @brief
     453        Window has moved.
     454    @param rw
     455        The render window it occured in
     456    */
     457    void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
     458    {
     459        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     460            it->windowMoved();
     461    }
     462
     463    /**
     464    @brief
     465        Window has resized.
     466    @param rw
     467        The render window it occured in
     468    @note
     469        GraphicsEngine has a render window stored itself. This is the same
     470        as rw. But we have to be careful when using multiple render windows!
     471    */
     472    void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)
     473    {
     474        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     475            it->windowResized(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
     476    }
     477
     478    /**
     479    @brief
     480        Window focus has changed.
     481    @param rw
     482        The render window it occured in
     483    */
     484    void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
     485    {
     486        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     487            it->windowFocusChanged();
     488    }
     489
     490    /**
     491    @brief
     492        Window was closed.
     493    @param rw
     494        The render window it occured in
     495    */
     496    void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
     497    {
     498        // using CommandExecutor in order to avoid depending on Orxonox.h.
     499        CommandExecutor::execute("exit", false);
     500    }
    478501
    479502}
  • code/branches/gui/src/orxonox/GraphicsEngine.h

    r1625 r1638  
    5454    class _OrxonoxExport GraphicsEngine : public Ogre::WindowEventListener, public Ogre::LogListener, public OrxonoxClass
    5555    {
    56         public:
    57             void setConfigValues();
    58             bool setup();
    59             bool declareRessourceLocations();
    60             bool loadRenderer();
    61             bool initialiseResources();
    62             bool createNewScene();
     56    public:
     57        GraphicsEngine();
     58        ~GraphicsEngine();
    6359
    64             void destroy();
     60        void setConfigValues();
     61        void setup();
     62        void declareRessourceLocations();
     63        bool loadRenderer();
     64        bool initialiseResources();
     65        bool createNewScene();
    6566
    66             Ogre::SceneManager* getSceneManager() { return scene_; }
     67        void setLevelSceneManager(Ogre::SceneManager* sceneMgr) { this->levelSceneManager_ = sceneMgr; }
     68        Ogre::SceneManager* getLevelSceneManager() { return levelSceneManager_; }
    6769
    68             // several window properties
    69             Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
    70             size_t getWindowHandle();
    71             int getWindowWidth() const;
    72             int getWindowHeight() const;
    73             float getWindowAspectRatio() const;
    74             float getAverageFramesPerSecond() const { return this->avgFramesPerSecond_; }
    75             float getAverageTickTime() const { return this->avgTickTime_; }
    76             void setAverageTickTime(float tickTime) { this->avgTickTime_ = tickTime; }
    77             void setAverageFramesPerSecond(float fps) { this->avgFramesPerSecond_ = fps; }
     70        Ogre::Viewport* getLevelViewport() { return this->levelViewport_; }
    7871
    79             void setWindowActivity(bool activity)
    80             { if (this->renderWindow_) this->renderWindow_->setActive(activity); }
     72        // several window properties
     73        Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
     74        size_t getWindowHandle();
     75        int getWindowWidth() const;
     76        int getWindowHeight() const;
     77        float getWindowAspectRatio() const;
     78        float getAverageFramesPerSecond() const   { return this->avgFramesPerSecond_; }
     79        float getAverageTickTime() const          { return this->avgTickTime_; }
     80        void setAverageTickTime(float tickTime)   { this->avgTickTime_ = tickTime; }
     81        void setAverageFramesPerSecond(float fps) { this->avgFramesPerSecond_ = fps; }
    8182
    82             void windowMoved       (Ogre::RenderWindow* rw);
    83             void windowResized     (Ogre::RenderWindow* rw);
    84             void windowFocusChanged(Ogre::RenderWindow* rw);
    85             void windowClosed      (Ogre::RenderWindow* rw);
     83        void setWindowActivity(bool activity)
     84        { if (this->renderWindow_) this->renderWindow_->setActive(activity); }
    8685
    87             inline unsigned int getDetailLevelParticle() const
    88               { return this->detailLevelParticle_; }
     86        inline unsigned int getDetailLevelParticle() const
     87        { return this->detailLevelParticle_; }
    8988
    90             static GraphicsEngine& getSingleton();
    91             static GraphicsEngine* getSingletonPtr() { return &getSingleton(); }
     89        static GraphicsEngine& getSingleton();
     90        static GraphicsEngine* getSingletonPtr() { return &getSingleton(); }
    9291
     92    private:
     93        // don't mess with singletons
     94        GraphicsEngine(GraphicsEngine&) { }
    9395
    94         private:
    95             // don't mess with singletons
    96             GraphicsEngine();
    97             ~GraphicsEngine();
    98             GraphicsEngine(GraphicsEngine&) { }
     96        //! Method called by the LogListener from Ogre
     97        void messageLogged(const std::string&, Ogre::LogMessageLevel,
     98            bool, const std::string&);
    9999
    100             //! Method called by the LogListener from Ogre
    101             void messageLogged(const std::string&, Ogre::LogMessageLevel,
    102                              bool, const std::string&);
     100        // window events from Ogre::WindowEventListener
     101        void windowMoved       (Ogre::RenderWindow* rw);
     102        void windowResized     (Ogre::RenderWindow* rw);
     103        void windowFocusChanged(Ogre::RenderWindow* rw);
     104        void windowClosed      (Ogre::RenderWindow* rw);
    103105
    104             Ogre::Root*         root_;                  //!< Ogre's root
    105             Ogre::SceneManager* scene_;                 //!< scene manager of the game
    106             Ogre::RenderWindow* renderWindow_;          //!< the current render window
    107             std::string         resourceFile_;          //!< resources file name
    108             std::string         ogreConfigFile_;        //!< ogre config file name
    109             std::string         ogrePluginsFile_;       //!< ogre plugins file name
    110             std::string         ogreLogFile_;           //!< log file name for Ogre log messages
    111             int                 ogreLogLevelTrivial_;   //!< Corresponding Orxonx debug level for LL_TRIVIAL
    112             int                 ogreLogLevelNormal_;    //!< Corresponding Orxonx debug level for LL_NORMAL
    113             int                 ogreLogLevelCritical_;  //!< Corresponding Orxonx debug level for LL_CRITICAL
    114             unsigned int        detailLevelParticle_;   //!< Detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
    115             float               avgTickTime_;           //!< time in ms to tick() one frame
    116             float               avgFramesPerSecond_;    //!< number of frames processed in one second
     106        Ogre::Root*         root_;                  //!< Ogre's root
     107        Ogre::RenderWindow* renderWindow_;          //!< the current render window
     108        Ogre::SceneManager* levelSceneManager_;     //!< scene manager of the game
     109        Ogre::Viewport*     levelViewport_;         //!< default full size viewport for the level
     110
     111        // stats
     112        float               avgTickTime_;           //!< time in ms to tick() one frame
     113        float               avgFramesPerSecond_;    //!< number of frames processed in one second
     114
     115        // config values
     116        std::string         resourceFile_;          //!< resources file name
     117        std::string         ogreConfigFile_;        //!< ogre config file name
     118        std::string         ogrePluginsFile_;       //!< ogre plugins file name
     119        std::string         ogreLogFile_;           //!< log file name for Ogre log messages
     120        int                 ogreLogLevelTrivial_;   //!< Corresponding Orxonx debug level for LL_TRIVIAL
     121        int                 ogreLogLevelNormal_;    //!< Corresponding Orxonx debug level for LL_NORMAL
     122        int                 ogreLogLevelCritical_;  //!< Corresponding Orxonx debug level for LL_CRITICAL
     123        unsigned int        detailLevelParticle_;   //!< Detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
     124
     125        static GraphicsEngine* singletonRef_s;      //!< Pointer to the Singleton
    117126    };
    118127}
  • code/branches/gui/src/orxonox/Main.cc

    r1535 r1638  
    2222 *   Author:
    2323 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
     24 *      Reto Grieder
    2425 *   Co-authors:
    2526 *      ...
     
    3536
    3637#include <exception>
     38#include <cassert>
    3739
    3840#include "util/OrxonoxPlatform.h"
     41#include "util/ArgReader.h"
    3942#include "core/SignalHandler.h"
     43#include "core/Debug.h"
     44#include "network/ClientConnection.h"
     45#include "Settings.h"
    4046#include "Orxonox.h"
    4147
    4248using namespace orxonox;
     49
    4350#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_APPLE
    4451#include <CoreFoundation/CoreFoundation.h>
     
    4956             std::string macBundlePath()
    5057{
    51   char path[1024];
    52   CFBundleRef mainBundle = CFBundleGetMainBundle();
    53   assert(mainBundle);
     58    char path[1024];
     59    CFBundleRef mainBundle = CFBundleGetMainBundle();
     60    assert(mainBundle);
    5461
    55   CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
    56   assert(mainBundleURL);
     62    CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
     63    assert(mainBundleURL);
    5764
    58   CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
    59   assert(cfStringRef);
     65    CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
     66    assert(cfStringRef);
    6067
    61   CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
     68    CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
    6269
    63   CFRelease(mainBundleURL);
    64   CFRelease(cfStringRef);
     70    CFRelease(mainBundleURL);
     71    CFRelease(cfStringRef);
    6572
    66   return std::string(path);
     73    return std::string(path);
    6774}
    6875#endif
     76
     77bool parseCommandLine(int argc, char** argv)
     78{
     79    ArgReader args;
     80    std::string errorStr = args.parse(argc, argv);
     81    if (errorStr != "")
     82    {
     83        COUT(1) << "Command Line: Parsing failed.\n" << errorStr << std::endl;
     84        return false;
     85    }
     86
     87    // Argument reader parses the command line to check syntax.
     88    // Settings Singleton then stores the arguments. It always
     89    // expects a default value.
     90    bool success = true;
     91    success &= Settings::addCommandLineArgument<std::string>
     92        ("mode",     args.getArgument("mode"),     "standalone");
     93    success &= Settings::addCommandLineArgument<std::string>
     94        ("dataPath", args.getArgument("dataPath"), "./");
     95    success &= Settings::addCommandLineArgument<std::string>
     96        ("ip",       args.getArgument("ip"),       "127.0.0.0");
     97    success &= Settings::addCommandLineArgument<int>
     98        ("port",     args.getArgument("port"),     NETWORK_PORT);
     99
     100    if (!success)
     101        return false;
     102
     103    if (!args.allChecked())
     104    {
     105        COUT(1) << "Command Line: Parsing failed.\nNot all arguments were matched." << std::endl;
     106        return false;
     107    }
     108
     109    return true;
     110}
    69111
    70112#ifdef __cplusplus
     
    72114#endif
    73115
    74 int main(int argc, char **argv)
     116int main(int argc, char** argv)
    75117{
    76   //try {
     118    // create a signal handler (only works for linux)
    77119    SignalHandler::getInstance()->doCatch(argv[0], "orxonox.log");
    78     Orxonox* orx = Orxonox::getSingleton();
    79120
    80     bool res = false;
     121    if (!parseCommandLine(argc, argv))
     122    {
     123        COUT(0) << "Usage:" << std::endl << "orxonox [--mode client|server|dedicated|standalone] "
     124                << "[--data PATH] [--ip IP] [--port PORT]" << std::endl;
     125        return 0;
     126    }
     127
     128    Orxonox orxonoxInstance;
     129
     130    try
     131    {
    81132#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_APPLE
    82     res = orx->init(argc, argv, macBundlePath());
     133        orxonoxInstance.start(macBundlePath());
    83134#else
    84     res = orx->init(argc, argv);
     135        orxonoxInstance.start();
    85136#endif
     137    }
     138    catch (std::exception& ex)
     139    {
     140        COUT(1) << ex.what() << std::endl;
     141        COUT(1) << "Abort." << std::endl;
     142    }
    86143
    87     if (res)
    88       orx->start();
    89     orx->destroySingleton();
    90   /*}
    91   catch (std::exception &ex)
    92   {
    93     std::cerr << "Exception:\n";
    94     std::cerr << ex.what() << "\n";
    95     return 1;
    96   }*/
    97 
    98   return 0;
     144    return 0;
    99145}
    100146
  • code/branches/gui/src/orxonox/Orxonox.cc

    r1625 r1638  
    2222 *   Author:
    2323 *      Reto Grieder
     24 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
    2425 *   Co-authors:
    25  *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
     26 *      ...
    2627 *
    2728 */
     
    3839//****** STD *******
    3940#include <deque>
     41#include <cassert>
    4042
    4143//****** OGRE ******
     
    5052// util
    5153//#include "util/Sleep.h"
    52 #include "util/ArgReader.h"
    5354
    5455// core
    5556#include "core/ConfigFileManager.h"
     57#include "core/ConfigValueIncludes.h"
    5658#include "core/ConsoleCommand.h"
    5759#include "core/Debug.h"
    5860#include "core/Loader.h"
     61#include "core/Exception.h"
    5962#include "core/input/InputManager.h"
     63#include "core/input/SimpleInputState.h"
     64#include "core/input/KeyBinder.h"
    6065#include "core/TclBind.h"
    6166#include "core/Core.h"
     
    6974
    7075// objects and tools
    71 #include "overlays/OverlayGroup.h"
    7276#include "overlays/console/InGameConsole.h"
    7377#include "objects/Tickable.h"
    7478#include "objects/Backlight.h"
    7579#include "tools/ParticleInterface.h"
     80#include "gui/GUIManager.h"
    7681
    7782#include "GraphicsEngine.h"
     
    8590namespace orxonox
    8691{
    87   SetConsoleCommandShortcut(Orxonox, exit).setKeybindMode(KeybindMode::OnPress);
    88   SetConsoleCommandShortcut(Orxonox, slomo).setAccessLevel(AccessLevel::Offline).setDefaultValue(0, 1.0).setAxisParamIndex(0).setIsAxisRelative(false);
    89   SetConsoleCommandShortcut(Orxonox, setTimeFactor).setAccessLevel(AccessLevel::Offline).setDefaultValue(0, 1.0);
     92  SetConsoleCommand(Orxonox, exit, true).setKeybindMode(KeybindMode::OnPress);
     93  SetConsoleCommand(Orxonox, slomo, true).setAccessLevel(AccessLevel::Offline).setDefaultValue(0, 1.0).setAxisParamIndex(0).setIsAxisRelative(false);
     94  SetConsoleCommand(Orxonox, setTimeFactor, true).setAccessLevel(AccessLevel::Offline).setDefaultValue(0, 1.0);
     95  SetConsoleCommand(Orxonox, loadGame, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, "standalone");
    9096
    9197  /**
     
    106112    , bAbort_(false)
    107113    , timefactor_(1.0f)
    108     , mode_(STANDALONE)
    109     , serverIp_("")
    110     , serverPort_(NETWORK_PORT)
    111   {
     114    , mode_(GameMode::GM_Unspecified)
     115    , debugRefreshTime_(0.0f)
     116  {
     117    RegisterRootObject(Orxonox);
     118
     119    assert(singletonRef_s == 0);
     120    singletonRef_s = this;
    112121  }
    113122
     
    118127  {
    119128    // keep in mind: the order of deletion is very important!
    120     Loader::unload(startLevel_);
     129    Loader::unload();
    121130    if (this->startLevel_)
    122131      delete this->startLevel_;
     
    136145      delete this->timer_;
    137146    InputManager::destroy();
    138     GraphicsEngine::getSingleton().destroy();
     147
     148    if (this->ogre_)
     149      delete ogre_;
    139150
    140151    if (network::Client::getSingleton())
     
    142153    if (server_g)
    143154      delete network::Server::getSingleton();
     155
     156    singletonRef_s = 0;
     157  }
     158
     159  void Orxonox::setConfigValues()
     160  {
     161    SetConfigValue(debugRefreshTime_, 0.2).description("Sets the time interval at which average fps, etc. get updated.");
    144162  }
    145163
     
    157175   * @return singleton reference
    158176   */
    159   Orxonox* Orxonox::getSingleton()
    160   {
    161     if (!singletonRef_s)
    162       singletonRef_s = new Orxonox();
    163     return singletonRef_s;
    164   }
    165 
    166   /**
    167     @brief Destroys the Orxonox singleton.
    168   */
    169   void Orxonox::destroySingleton()
    170   {
    171     if (singletonRef_s)
    172       delete singletonRef_s;
    173     singletonRef_s = 0;
     177  Orxonox& Orxonox::getSingleton()
     178  {
     179    assert(singletonRef_s);
     180    return *singletonRef_s;
    174181  }
    175182
     
    179186  void Orxonox::setTimeFactor(float factor)
    180187  {
    181     float change = factor / Orxonox::getSingleton()->getTimeFactor();
    182     Orxonox::getSingleton()->timefactor_ = factor;
     188    float change = factor / Orxonox::getSingleton().getTimeFactor();
     189    Orxonox::getSingleton().timefactor_ = factor;
    183190    for (Iterator<ParticleInterface> it = ObjectList<ParticleInterface>::begin(); it; ++it)
    184191        it->setSpeedFactor(it->getSpeedFactor() * change);
    185192
    186193    for (Iterator<Backlight> it = ObjectList<Backlight>::begin(); it; ++it)
    187         it->setTimeFactor(Orxonox::getSingleton()->getTimeFactor());
    188   }
    189 
    190   /**
    191    * initialization of Orxonox object
    192    * @param argc argument counter
    193    * @param argv list of argumenst
     194        it->setTimeFactor(Orxonox::getSingleton().getTimeFactor());
     195  }
     196
     197
     198  /**
     199   * Starts the whole Game.
    194200   * @param path path to config (in home dir or something)
    195201   */
    196   bool Orxonox::init(int argc, char **argv)
     202  void Orxonox::start()
    197203  {
    198204#ifdef _DEBUG
     
    203209    Factory::createClassHierarchy();
    204210
    205     std::string mode;
    206     std::string tempDataPath;
    207 
    208     ArgReader ar(argc, argv);
    209     ar.checkArgument("mode", &mode, false);
    210     ar.checkArgument("data", &tempDataPath, false);
    211     ar.checkArgument("ip",   &serverIp_, false);
    212     ar.checkArgument("port", &serverPort_, false);
    213     if(ar.errorHandling())
    214     {
    215       COUT(1) << "Error while parsing command line arguments" << std::endl;
    216       COUT(1) << ar.getErrorString();
    217       COUT(0) << "Usage:" << std::endl << "orxonox [mode client|server|dedicated|standalone] "
    218         << "[--data PATH] [--ip IP] [--port PORT]" << std::endl;
    219       return false;
    220     }
    221 
    222     if (mode == "client")
    223       mode_ = CLIENT;
    224     else if (mode == "server")
    225       mode_ = SERVER;
    226     else if (mode == "dedicated")
    227       mode_ = DEDICATED;
    228     else
    229     {
    230       if (mode == "")
    231         mode = "standalone";
    232       if (mode != "standalone")
     211    setConfigValues();
     212
     213    const Settings::CommandLineArgument* mode = Settings::getCommandLineArgument("mode");
     214    assert(mode);
     215    if (!mode->bHasDefaultValue_)
     216    {
     217      Settings::setGameMode(mode->value_);
     218      this->mode_ = Settings::getGameMode();
     219    }
     220    COUT(3) << "Orxonox: Game mode is " << mode_.name << "." << std::endl;
     221
     222    const Settings::CommandLineArgument* dataPath = Settings::getCommandLineArgument("dataPath");
     223    assert(dataPath);
     224    if (!dataPath->bHasDefaultValue_)
     225    {
     226      if (*dataPath->value_.getString().end() != '/' && *dataPath->value_.getString().end() != '\\')
     227        Settings::tsetDataPath(dataPath->value_.getString() + "/");
     228      else
     229        Settings::tsetDataPath(dataPath->value_.getString());
     230    }
     231
     232    try
     233    {
     234        // initialise TCL
     235        TclBind::getInstance().setDataPath(Settings::getDataPath());
     236
     237        ogre_ = new GraphicsEngine();
     238        ogre_->setup();       // creates ogre root and other essentials
     239
     240        if (mode_.showsGraphics)
     241        {
     242          ogre_->loadRenderer();    // creates the render window
     243
     244          // TODO: Spread this so that this call only initialises things needed for the Console and GUI
     245          ogre_->initialiseResources();
     246
     247          // Calls the InputManager which sets up the input devices.
     248          // The render window width and height are used to set up the mouse movement.
     249          InputManager::initialise(ogre_->getWindowHandle(),
     250                ogre_->getWindowWidth(), ogre_->getWindowHeight(), true, true, true);
     251          KeyBinder* keyBinder = new KeyBinder();
     252          InputManager::createSimpleInputState("game", 20)->setHandler(keyBinder);
     253
     254          // Load the InGameConsole
     255          InGameConsole::getInstance().initialise();
     256
     257          // load the CEGUI interface
     258          GUIManager::getInstance().initialise();
     259        }
     260
     261        bool showGUI = true;
     262        if (mode_.mode != GameMode::Unspecified)
     263        {
     264          showGUI = false;
     265          // a game mode was specified with the command line
     266          // we therefore load the game and level directly
     267
     268          if (!loadLevel(this->mode_))
     269          {
     270            COUT(1) << "Loading with predefined mode failed. Showing main menu." << std::endl;
     271            showGUI = true;
     272            mode_ = GameMode::GM_Unspecified;
     273          }
     274        }
     275       
     276        if (showGUI)
     277        {
     278          // show main menu
     279          //GraphicsEngine::getSingleton().createNewScene();
     280          GUIManager::getInstance().showGUI("MainMenu", true);
     281        }
     282    }
     283    catch (std::exception& ex)
     284    {
     285      COUT(1) << ex.what() << std::endl;
     286      COUT(1) << "Loading sequence aborted." << std::endl;
     287      return;
     288    }
     289
     290    modeRequest_ = mode_;
     291    // here happens the game
     292    startRenderLoop();
     293
     294    if (mode_.mode == GameMode::Client)
     295      network::Client::getSingleton()->closeConnection();
     296
     297    if (mode_.hasServer)
     298      server_g->close();
     299  }
     300
     301  void Orxonox::loadGame(const std::string& name)
     302  {
     303      const GameMode& mode = Settings::getGameMode(name);
     304      if (mode.mode == GameMode::None)
     305          return;
     306
     307      getSingleton().modeRequest_ = mode;
     308  }
     309
     310  bool Orxonox::loadLevel(const GameMode& mode)
     311  {
     312      bool success = true;
     313
     314      if (mode.showsGraphics)
    233315      {
    234         COUT(2) << "Warning: mode \"" << mode << "\" doesn't exist. "
    235           << "Defaulting to standalone" << std::endl;
    236         mode = "standalone";
     316        // create Ogre SceneManager for the level
     317        ogre_->createNewScene();
     318
     319        if (!loadPlayground())
     320            return false;
    237321      }
    238       mode_ = STANDALONE;
    239     }
    240     COUT(3) << "Orxonox: Mode is " << mode << "." << std::endl;
    241 
    242     if (tempDataPath != "")
    243     {
    244       if (tempDataPath[tempDataPath.size() - 1] != '/')
    245         tempDataPath += "/";
    246       Settings::tsetDataPath(tempDataPath);
    247     }
    248 
    249     // initialise TCL
    250     TclBind::getInstance().setDataPath(Settings::getDataPath());
    251 
    252     //if (mode_ == DEDICATED)
    253       // TODO: decide what to do here
    254     //else
    255 
    256     // for playable server, client and standalone, the startup
    257     // procedure until the GUI is identical
    258 
    259     ogre_ = &GraphicsEngine::getSingleton();
    260     if (!ogre_->setup())       // creates ogre root and other essentials
    261       return false;
    262 
    263     return true;
    264   }
    265 
    266   /**
    267    * start modules
    268    */
    269   bool Orxonox::start()
    270   {
    271     if (mode_ == DEDICATED)
    272     {
    273       // do something else
    274     }
    275     else
    276     { // not dedicated server
    277       if (!ogre_->loadRenderer())    // creates the render window
    278         return false;
    279 
    280       // TODO: Spread this so that this call only initialises things needed for the Console
    281       if (!ogre_->initialiseResources())
    282         return false;
    283 
    284       // Load the InGameConsole
    285       InGameConsole::getInstance().initialise();
    286 
    287       // Calls the InputManager which sets up the input devices.
    288       // The render window width and height are used to set up the mouse movement.
    289       if (!InputManager::initialise(ogre_->getWindowHandle(),
    290             ogre_->getWindowWidth(), ogre_->getWindowHeight(), true, true, true))
    291         return false;
    292 
    293       // TOOD: load the GUI here
    294       // set InputManager to GUI mode
    295       InputManager::setInputState(InputManager::IS_GUI);
    296       // TODO: run GUI here
    297 
    298       // The following lines depend very much on the GUI output, so they're probably misplaced here..
    299 
    300       InputManager::setInputState(InputManager::IS_NONE);
    301 
    302       // create Ogre SceneManager
    303       ogre_->createNewScene();
    304 
    305       if (!loadPlayground())
    306         return false;
    307     }
    308 
    309     switch (mode_)
    310     {
    311     case SERVER:
    312       if (!serverLoad())
    313         return false;
    314       break;
    315     case CLIENT:
    316       if (!clientLoad())
    317         return false;
    318       break;
    319     case DEDICATED:
    320       if (!serverLoad())
    321         return false;
    322       break;
    323     default:
    324       if (!standaloneLoad())
    325         return false;
    326     }
    327 
    328     InputManager::setInputState(InputManager::IS_NORMAL);
    329 
    330     return startRenderLoop();
     322
     323      switch (mode.mode)
     324      {
     325      case GameMode::Server:
     326        success &= serverLoad();
     327        break;
     328      case GameMode::Client:
     329        success &= clientLoad();
     330        break;
     331      case GameMode::Dedicated:
     332        success &= serverLoad();
     333        break;
     334      case GameMode::Standalone:
     335        success &= standaloneLoad();
     336        break;
     337      default: // never happens
     338          assert(false);
     339      }
     340     
     341      if (success)
     342        InputManager::requestEnterState("game");
     343
     344      return success;
    331345  }
    332346
     
    337351  bool Orxonox::loadPlayground()
    338352  {
    339     // Init audio
    340     //auMan_ = new audio::AudioManager();
    341     //auMan_->ambientAdd("a1");
    342     //auMan_->ambientAdd("a2");
    343     //auMan_->ambientAdd("a3");
    344     //auMan->ambientAdd("ambient1");
    345     //auMan_->ambientStart();
     353    // Start the Radar
     354    this->radar_ = new Radar();
    346355
    347356    // Load the HUD
    348357    COUT(3) << "Orxonox: Loading HUD" << std::endl;
    349358    hud_ = new Level(Settings::getDataPath() + "overlay/hud.oxo");
    350     Loader::load(hud_);
    351 
    352     // Start the Radar
    353     this->radar_ = new Radar();
    354 
    355     return true;
     359    return Loader::load(hud_);
     360  }
     361
     362  /**
     363   * Helper method to load a level.
     364   */
     365  bool Orxonox::loadScene()
     366  {
     367    COUT(0) << "Loading level..." << std::endl;
     368    startLevel_ = new Level(Settings::getDataPath() + "levels/sample.oxw");
     369    return Loader::open(startLevel_);
    356370  }
    357371
     
    363377    COUT(0) << "Loading level in server mode" << std::endl;
    364378
     379    assert(Settings::getCommandLineArgument("port"));
     380    int serverPort = Settings::getCommandLineArgument("port")->value_;
    365381    //server_g = new network::Server(serverPort_);
    366     server_g = network::Server::createSingleton(serverPort_);
     382    server_g = network::Server::createSingleton(serverPort);
    367383
    368384    if (!loadScene())
     
    381397    COUT(0) << "Loading level in client mode" << std::endl;\
    382398
    383     if (serverIp_.compare("") == 0)
     399    assert(Settings::getCommandLineArgument("port"));
     400    assert(Settings::getCommandLineArgument("ip"));
     401    int serverPort = Settings::getCommandLineArgument("port")->value_;
     402    std::string serverIP = Settings::getCommandLineArgument("ip")->value_;
     403
     404    if (serverIP.compare("") == 0)
    384405      client_g = network::Client::createSingleton();
    385406    else
    386 
    387       client_g = network::Client::createSingleton(serverIp_, serverPort_);
     407      client_g = network::Client::createSingleton(serverIP, serverPort);
    388408
    389409    if(!client_g->establishConnection())
     
    408428
    409429  /**
    410    * Helper method to load a level.
    411    */
    412   bool Orxonox::loadScene()
    413   {
    414     startLevel_ = new Level("levels/sample.oxw");
    415     Loader::open(startLevel_);
    416 
    417     return true;
    418   }
    419 
    420 
    421   /**
    422430    Main loop of the orxonox game.
    423     About the loop: The design is almost exactly like the one in ogre, so that
    424     if any part of ogre registers a framelisteners, it will still behave
    425     correctly. Furthermore the time smoothing feature from ogre has been
    426     implemented too. If turned on (see orxonox constructor), it will calculate
    427     the dt_n by means of the recent most dt_n-1, dt_n-2, etc.
     431    We use the Ogre::Timer to measure time since it uses the most precise
     432    method an a platform (however the windows timer lacks time when under
     433    heavy kernel load!).
     434    There is a simple mechanism to measure the average time spent in our
     435    ticks as it may indicate performance issues.
     436    A note about the Ogre::FrameListener: Even though we don't use them,
     437    they still get called. However, the delta times are not correct (except
     438    for timeSinceLastFrame, which is the most important). A little research
     439    as shown that there is probably only one FrameListener that doesn't even
     440    need the time. So we shouldn't run into problems.
    428441  */
    429   bool Orxonox::startRenderLoop()
    430   {
    431     // first check whether ogre root object has been created
    432     if (Ogre::Root::getSingletonPtr() == 0)
    433     {
    434       COUT(2) << "Orxonox Error: Could not start rendering. No Ogre root object found" << std::endl;
    435       return false;
    436     }
     442  void Orxonox::startRenderLoop()
     443  {
    437444    Ogre::Root& ogreRoot = Ogre::Root::getSingleton();
    438 
    439445
    440446    // use the ogre timer class to measure time.
     
    444450    unsigned long frameCount = 0;
    445451   
    446     // TODO: this would very well fit into a configValue
    447     const unsigned long refreshTime = 200000;
     452    const unsigned long refreshTime = debugRefreshTime_ * 1000000.0f;
    448453    unsigned long refreshStartTime = 0;
    449454    unsigned long tickTime = 0;
     
    454459    unsigned long timeAfterTick = 0;
    455460
     461    int sleepTime = 0;
     462
     463    // TODO: Update time in seconds every 7 seconds to avoid any overflow (7 secs is very tight)
     464
    456465    COUT(3) << "Orxonox: Starting the main loop." << std::endl;
    457466
     467    try
     468    {
    458469    timer_->reset();
    459470    while (!bAbort_)
    460471    {
    461       // get current time
    462       timeBeforeTickOld = timeBeforeTick;
    463       timeBeforeTick    = timer_->getMicroseconds();
    464       float dt = (timeBeforeTick - timeBeforeTickOld) / 1000000.0;
    465 
    466 
    467       // tick the core (needs real time for input and tcl thread management)
    468       Core::tick(dt);
    469 
    470       // Call those objects that need the real time
    471       for (Iterator<TickableReal> it = ObjectList<TickableReal>::start(); it; ++it)
    472         it->tick(dt);
    473       // Call the scene objects
    474       for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; ++it)
    475         it->tick(dt * this->timefactor_);
    476 
    477       // call server/client with normal dt
    478       if (client_g)
    479         client_g->tick(dt * this->timefactor_);
    480       if (server_g)
    481         server_g->tick(dt * this->timefactor_);
    482 
    483 
    484       // get current time once again
    485       timeAfterTick = timer_->getMicroseconds();
    486 
    487       tickTime += timeAfterTick - timeBeforeTick;
    488       if (timeAfterTick > refreshStartTime + refreshTime)
    489       {
    490         GraphicsEngine::getSingleton().setAverageTickTime(
    491             (float)tickTime * 0.001 / (frameCount - oldFrameCount));
    492         GraphicsEngine::getSingleton().setAverageFramesPerSecond(
    493             (float)(frameCount - oldFrameCount) / (timeAfterTick - refreshStartTime) * 1000000.0);
    494         oldFrameCount = frameCount;
    495         tickTime = 0;
    496         refreshStartTime = timeAfterTick;
    497       }
    498 
    499 
    500       // don't forget to call _fireFrameStarted in ogre to make sure
    501       // everything goes smoothly
    502       Ogre::FrameEvent evt;
    503       evt.timeSinceLastFrame = dt;
    504       evt.timeSinceLastEvent = dt; // note: same time, but shouldn't matter anyway
    505       ogreRoot._fireFrameStarted(evt);
    506 
    507       if (mode_ != DEDICATED)
    508       {
    509         // Pump messages in all registered RenderWindows
    510         // This calls the WindowEventListener objects.
    511         Ogre::WindowEventUtilities::messagePump();
    512         // make sure the window stays active even when not focused
    513         // (probably only necessary on windows)
    514         GraphicsEngine::getSingleton().setWindowActivity(true);
    515 
    516         // render
    517         ogreRoot._updateAllRenderTargets();
    518       }
    519 
    520       // again, just to be sure ogre works fine
    521       ogreRoot._fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
    522 
    523       ++frameCount;
    524     }
    525 
    526     if (mode_ == CLIENT)
    527       network::Client::getSingleton()->closeConnection();
    528     else if (mode_ == SERVER)
    529       server_g->close();
    530 
    531     return true;
     472        // get current time
     473        timeBeforeTickOld = timeBeforeTick;
     474        timeBeforeTick    = timer_->getMicroseconds();
     475        float dt = (timeBeforeTick - timeBeforeTickOld) / 1000000.0;
     476
     477        // check whether we have to load a game
     478        if (mode_.mode != modeRequest_.mode && mode_.mode == GameMode::Unspecified)
     479        {
     480            this->loadLevel(modeRequest_);
     481            this->modeRequest_ = GameMode::GM_None;
     482        }
     483
     484
     485        // tick the core (needs real time for input and tcl thread management)
     486        Core::tick(dt);
     487
     488        // Call those objects that need the real time
     489        for (Iterator<TickableReal> it = ObjectList<TickableReal>::start(); it; ++it)
     490          it->tick(dt);
     491        // Call the scene objects
     492        for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; ++it)
     493          it->tick(dt * this->timefactor_);
     494
     495        // call server/client with normal dt
     496        if (client_g)
     497          client_g->tick(dt * this->timefactor_);
     498        if (server_g)
     499          server_g->tick(dt * this->timefactor_);
     500
     501
     502        // get current time once again
     503        timeAfterTick = timer_->getMicroseconds();
     504
     505        tickTime += timeAfterTick - timeBeforeTick;
     506        if (timeAfterTick > refreshStartTime + refreshTime)
     507        {
     508          GraphicsEngine::getSingleton().setAverageTickTime(
     509              (float)tickTime * 0.001 / (frameCount - oldFrameCount));
     510          float avgFPS = (float)(frameCount - oldFrameCount) / (timeAfterTick - refreshStartTime) * 1000000.0;
     511          GraphicsEngine::getSingleton().setAverageFramesPerSecond(avgFPS);
     512
     513          if (avgFPS > 60.0)
     514            sleepTime++;
     515          else
     516            sleepTime--;
     517          if (sleepTime < 0)
     518              sleepTime = 0;
     519
     520          oldFrameCount = frameCount;
     521          tickTime = 0;
     522          refreshStartTime = timeAfterTick;
     523        }
     524
     525        // do some sleeping when the frameRate is over 60
     526        if (sleepTime > 0)
     527          msleep(sleepTime);
     528
     529
     530        // don't forget to call _fireFrameStarted in ogre to make sure
     531        // everything goes smoothly
     532        Ogre::FrameEvent evt;
     533        evt.timeSinceLastFrame = dt;
     534        evt.timeSinceLastEvent = dt; // note: same time, but shouldn't matter anyway
     535        ogreRoot._fireFrameStarted(evt);
     536
     537        if (mode_.showsGraphics)
     538        {
     539          // Pump messages in all registered RenderWindows
     540          // This calls the WindowEventListener objects.
     541          Ogre::WindowEventUtilities::messagePump();
     542          // make sure the window stays active even when not focused
     543          // (probably only necessary on windows)
     544          GraphicsEngine::getSingleton().setWindowActivity(true);
     545
     546          // tick CEGUI
     547          GUIManager::getInstance().tick(dt);
     548
     549          // render
     550          ogreRoot._updateAllRenderTargets();
     551        }
     552
     553        // again, just to be sure ogre works fine
     554        ogreRoot._fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
     555
     556        ++frameCount;
     557    }
     558    }
     559    catch (std::exception& ex)
     560    {
     561      // something went wrong.
     562      COUT(1) << ex.what() << std::endl;
     563      COUT(1) << "Main loop was stopped by an unhandled exception. Shutting down." << std::endl;
     564    }
    532565  }
    533566}
  • code/branches/gui/src/orxonox/Orxonox.h

    r1625 r1638  
    2222 *   Author:
    2323 *      Reto Grieder
     24 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
    2425 *   Co-authors:
    25  *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
     26 *      ...
    2627 *
    2728 */
     
    4142
    4243#include <OgrePrerequisites.h>
     44
     45#include "core/OrxonoxClass.h"
    4346#include "audio/AudioPrereqs.h"
     47#include "GraphicsEngine.h"
     48#include "Settings.h"
    4449
    45 #include "GraphicsEngine.h"
    46 
    47 namespace orxonox {
    48 
    49   enum gameMode{
    50     SERVER,
    51     CLIENT,
    52     STANDALONE,
    53     DEDICATED
    54   };
    55 
     50namespace orxonox
     51{
    5652  //! Orxonox singleton class
    57   class _OrxonoxExport Orxonox
     53    class _OrxonoxExport Orxonox : public OrxonoxClass
    5854  {
    5955    public:
    60       bool init(int argc, char **argv);
    61       bool start();
     56      Orxonox();
     57      ~Orxonox();
     58
     59      void start();
     60      void setConfigValues();
    6261
    6362      void abortRequest();
    6463
    65       static Orxonox* getSingleton();
    66       static void destroySingleton();
     64      static Orxonox& getSingleton();
    6765
    68       static inline void slomo(float factor) { Orxonox::setTimeFactor(factor); }
     66      static void slomo(float factor) { Orxonox::setTimeFactor(factor); }
     67      static float getTimeFactor()    { return Orxonox::getSingleton().timefactor_; }
     68      static void loadGame(const std::string& name);
     69      static void exit()              { Orxonox::getSingleton().abortRequest(); }
    6970      static void setTimeFactor(float factor = 1.0);
    70       static inline float getTimeFactor() { return Orxonox::getSingleton()->timefactor_; }
    71       static inline void exit() { Orxonox::getSingleton()->abortRequest(); }
    7271
    7372   private:
    7473      // don't mess with singletons
    75       Orxonox();
    7674      Orxonox(Orxonox& instance);
    77       Orxonox& operator=(const Orxonox& instance);
    78       ~Orxonox();
    7975
    80       bool loadPlayground();
    81 
     76      bool loadLevel(const GameMode& mode);
    8277      bool serverLoad();
    8378      bool clientLoad();
    8479      bool standaloneLoad();
    8580
     81      bool loadPlayground();
    8682      bool loadScene();
    87 
    88       bool startRenderLoop();
    89 
    90       float calculateEventTime(unsigned long, std::deque<unsigned long>&);
     83      void startRenderLoop();
    9184
    9285    private:
     
    10194
    10295      // this is used to identify the mode (server/client/...) we're in
    103       gameMode              mode_;
    104       std::string           serverIp_;
    105       int                   serverPort_;
     96      GameMode              mode_;
     97      GameMode              modeRequest_;
     98
     99      // config values
     100      float                 debugRefreshTime_;
    106101
    107102      static Orxonox *singletonRef_s;
  • code/branches/gui/src/orxonox/OrxonoxStableHeaders.h

    r1631 r1638  
    4545#  define WIN32_LEAN_AND_MEAN
    4646#endif
    47 // not including the entire Ogre.h doesn't exceed the default heap size for pch
    48 //#include <Ogre.h>
    49 #include <OgreBillboardSet.h>
    50 #include <OgreCamera.h>
    51 #include <OgreColourValue.h>
    52 #include <OgreConfigFile.h>
    53 #include <OgreEntity.h>
    54 #include <OgreException.h>
    55 #include <OgreFrameListener.h>
    56 #include <OgreLight.h>
    57 #include <OgreLog.h>
    58 #include <OgreLogManager.h>
    59 #include <OgreMath.h>
    60 #include <OgreMatrix3.h>
    61 #include <OgreMatrix4.h>
    62 #include <OgreMesh.h>
    63 #include <OgreOverlay.h>
    64 #include <OgreOverlayElement.h>
    65 #include <OgreOverlayManager.h>
    66 #include <OgreParticleEmitter.h>
    67 #include <OgreParticleSystem.h>
    68 #include <OgreQuaternion.h>
    69 #include <OgreResourceGroupManager.h>
    70 #include <OgreRenderWindow.h>
    71 #include <OgreRoot.h>
    72 #include <OgreSceneManager.h>
    73 #include <OgreSceneNode.h>
    74 #include <OgreString.h>
    75 #include <OgreStringConverter.h>
    76 #include <OgreTextureManager.h>
    77 #include <OgreTimer.h>
    78 #include <OgreVector2.h>
    79 #include <OgreVector3.h>
    80 #include <OgreVector3.h>
    81 #include <OgreViewport.h>
    82 #include <OgreWindowEventUtilities.h>
     47
     48#include <Ogre.h>
     49#include <CEGUI.h>
     50#include <boost/thread/recursive_mutex.hpp>
    8351
    8452//-----------------------------------------------------------------------
     
    8654//-----------------------------------------------------------------------
    8755
    88 #include "ois/OIS.h"
    89 #include "cpptcl/CppTcl.h"
    9056#include "tinyxml/ticpp.h"
    9157#include "tinyxml/tinyxml.h"
     
    10470#include "core/CoreIncludes.h"
    10571#include "core/ConfigValueIncludes.h"
     72#include "core/CommandExecutor.h"
    10673#include "core/Debug.h"
     74#include "core/Executor.h"
    10775#include "core/OutputBuffer.h"
    10876#include "core/OutputHandler.h"
    109 #include "core/Executor.h"
    11077#include "core/XMLPort.h"
    11178
  • code/branches/gui/src/orxonox/Radar.cc

    r1625 r1638  
    3434#include "OrxonoxStableHeaders.h"
    3535#include "Radar.h"
    36 #include <float.h>
     36#include <cfloat>
     37#include <cassert>
    3738#include "objects/WorldEntity.h"
    3839#include "objects/SpaceShip.h"
  • code/branches/gui/src/orxonox/RadarViewable.h

    r1625 r1638  
    3232#include "OrxonoxPrereqs.h"
    3333#include <string>
     34#include <cassert>
    3435#include "util/Math.h"
    3536#include "core/Debug.h"
  • code/branches/gui/src/orxonox/Settings.cc

    r1535 r1638  
    2828
    2929/**
    30     @file
    31     @brief Implementation of the Settings class.
     30@file
     31@brief
     32    Implementation of the Settings class.
    3233*/
    3334
     
    3536#include "Settings.h"
    3637
     38#include "util/String.h"
    3739#include "core/CoreIncludes.h"
    3840#include "core/ConfigValueIncludes.h"
     
    4042namespace orxonox
    4143{
    42   /**
    43     @brief Constructor: Registers the object and sets the config-values.
    44   */
    45   Settings::Settings()
    46   {
    47     RegisterRootObject(Settings);
    48     setConfigValues();
    49   }
    5044
    51   Settings::~Settings()
    52   {
    53   }
     45// Using a macro makes the above list much more readable.
     46// Settings::addGameMode adds the mode in a map, so we can access game modes by string.
     47#define CreateGameMode(name, showsGraphics, isMaster, hasServer)                                        \
     48    const GameMode GameMode::GM_##name = { GameMode::name, showsGraphics, isMaster, hasServer, #name }; \
     49    bool temporaryVariable##name = Settings::addGameMode(&GameMode::GM_##name)
    5450
    55   /**
    56     @brief Returns a unique instance of Core.
    57     @return The instance
    58   */
    59   Settings& Settings::getSingleton()
    60   {
    61     static Settings instance;
    62     return instance;
    63   }
     51    //                          showsGraphics  isMaster  hasServer
     52    CreateGameMode(None,        false,         false,    false);
     53    CreateGameMode(Unspecified, true,          false,    false);
     54    CreateGameMode(Server,      true,          true,     true );
     55    CreateGameMode(Client,      true,          false,    false);
     56    CreateGameMode(Standalone,  true,          true,     false);
     57    CreateGameMode(Dedicated,   false,         true,     true );
    6458
    65   /**
    66     @brief Function to collect the SetConfigValue-macro calls.
    67   */
    68   void Settings::setConfigValues()
    69   {
    70     SetConfigValue(dataPath_, "../../Media/").description("Relative path to the game data.");
    71     if (dataPath_ != "" && dataPath_[dataPath_.size() - 1] != '/')
     59    /**
     60    @brief
     61        Constructor: Registers the object and sets the config-values.
     62    */
     63    Settings::Settings()
    7264    {
    73       ModifyConfigValue(dataPath_, set, dataPath_ + "/");
     65        RegisterRootObject(Settings);
     66        gameMode_ = GameMode::GM_Unspecified;
     67        setConfigValues();
    7468    }
    7569
    76     if (dataPath_ == "")
     70    /**
     71    @brief
     72        Returns a unique instance of Core.
     73    @return
     74        The instance
     75    */
     76    Settings& Settings::getInstance()
    7777    {
    78       ModifyConfigValue(dataPath_, set, "/");
    79       COUT(2) << "Warning: Data path set to \"/\", is that really correct?" << std::endl;
     78        static Settings instance;
     79        return instance;
    8080    }
    81   }
    8281
    83   /**
    84     @brief Temporary sets the data path
    85     @param path The new data path
    86   */
    87   void Settings::_tsetDataPath(const std::string& path)
    88   {
    89     ModifyConfigValue(dataPath_, tset, path);
    90   }
     82    /**
     83    @brief
     84        Function to collect the SetConfigValue-macro calls.
     85    */
     86    void Settings::setConfigValues()
     87    {
     88        SetConfigValue(dataPath_, "../../Media/").description("Relative path to the game data.");
     89        if (dataPath_ != "" && dataPath_[dataPath_.size() - 1] != '/')
     90        {
     91            ModifyConfigValue(dataPath_, set, dataPath_ + "/");
     92        }
    9193
    92   /*static*/ void Settings::tsetDataPath(const std::string& path)
    93   {
    94     getSingleton()._tsetDataPath(path);
    95   }
     94        if (dataPath_ == "")
     95        {
     96            ModifyConfigValue(dataPath_, set, "/");
     97            COUT(2) << "Warning: Data path set to \"/\", is that really correct?" << std::endl;
     98        }
     99    }
    96100
    97   /**
    98     @brief Returns the relative path to the game data.
    99     @return The path to the game data
    100   */
    101   /*static*/ const std::string& Settings::getDataPath()
    102   {
    103     return getSingleton().dataPath_;
    104   }
     101    /**
     102    @brief
     103        Temporary sets the data path
     104    @param path
     105        The new data path
     106    */
     107    void Settings::_tsetDataPath(const std::string& path)
     108    {
     109        ModifyConfigValue(dataPath_, tset, path);
     110    }
     111
     112    /**
     113    @brief
     114        Sets the game mode.
     115    */
     116    /*static*/ void Settings::setGameMode(const std::string& mode)
     117    {
     118        std::string modeL = getLowercase(mode);
     119        std::map<std::string, const GameMode*>::const_iterator it = getInstance().gameModes_.find(modeL);
     120        if (it != getInstance().gameModes_.end())
     121            getInstance().gameMode_ = *(*it).second;
     122        else
     123        {
     124            COUT(2) << "Warning: mode \"" << mode << "\" doesn't exist. "
     125                    << "Defaulting to 'Standalone'" << std::endl;
     126            getInstance().gameMode_ = GameMode::GM_Standalone;
     127        }
     128    }
     129
     130    /*static*/ bool Settings::addGameMode(const GameMode* mode)
     131    {
     132        getInstance().gameModes_[getLowercase(mode->name)] = mode;
     133        return true;
     134    }
     135
     136
     137    /**
     138    @brief
     139        Gets an argument from the command line by name.
     140    @return
     141        Is 0 if name was not found.
     142    */
     143    /*static*/ const Settings::CommandLineArgument* Settings::getCommandLineArgument(const std::string &name)
     144    {
     145        std::map<std::string, CommandLineArgument>::const_iterator it = getInstance().commandArguments_.find(name);
     146        if (it != getInstance().commandArguments_.end())
     147        {
     148            return &((*it).second);
     149        }
     150        else
     151            return 0;
     152    }
     153
    105154}
  • code/branches/gui/src/orxonox/Settings.h

    r1535 r1638  
    2929/**
    3030    @file Core.h
    31     @brief Definition of the Settings class.
     31    @brief Declaration of the Settings class.
    3232
    3333    The static Settings class is only used to configure some variables
     
    4141#include <string>
    4242#include "core/OrxonoxClass.h"
     43#include "core/Debug.h"
     44#include "util/MultiTypeMath.h"
     45#include "util/Convert.h"
    4346
    4447namespace orxonox
    4548{
    46   class _OrxonoxExport Settings : public OrxonoxClass
    47   {
     49    /**
     50    @brief
     51        Defines a bit field structure that holds the mode as enum plus
     52        the attributes as single named bits.
     53        Every different GameMode is stored as static const, but if you wish to
     54        compare two modes, you will have to use the 'mode' member variable.
     55    */
     56    struct GameMode
     57    {
     58        enum Mode
     59        {
     60            None,
     61            Unspecified,
     62            Server,
     63            Client,
     64            Standalone,
     65            Dedicated,
     66        };
     67
     68        Mode mode;
     69        bool showsGraphics;
     70        bool isMaster;
     71        bool hasServer;
     72        std::string name;
     73
     74        static const GameMode GM_None;
     75        static const GameMode GM_Unspecified;
     76        static const GameMode GM_Server;
     77        static const GameMode GM_Client;
     78        static const GameMode GM_Standalone;
     79        static const GameMode GM_Dedicated;
     80    };
     81
     82
     83    class _OrxonoxExport Settings : public OrxonoxClass
     84    {
    4885    public:
    49       void setConfigValues();
     86        struct CommandLineArgument
     87        {
     88            std::string name_;
     89            MultiTypeMath value_;
     90            bool bHasDefaultValue_;
     91        };
    5092
    51       static const std::string& getDataPath();
     93        void setConfigValues();
    5294
    53       static void tsetDataPath(const std::string& path);
     95        static const std::string& getDataPath();
     96        static void tsetDataPath(const std::string& path);
     97
     98        static const GameMode& getGameMode();
     99        static const GameMode& getGameMode(const std::string& name);
     100        static void setGameMode(const GameMode& mode);
     101        static void setGameMode(const std::string& mode);
     102        static bool addGameMode(const GameMode* mode);
     103
     104        static const CommandLineArgument* getCommandLineArgument(const std::string& name);
     105        template <class T>
     106        static bool addCommandLineArgument(const std::string &name, const std::string& valueStr, const T& defaultValue);
    54107
    55108    private:
    56       Settings();
    57       Settings(const Settings& instance);
    58       ~Settings();
    59       static Settings& getSingleton();
     109        Settings();
     110        Settings(const Settings& instance);
     111        ~Settings() { }
     112        static Settings& getInstance();
    60113
    61       void _tsetDataPath(const std::string& path);
     114        void _tsetDataPath(const std::string& path);
    62115
    63       std::string dataPath_;               //!< Path to the game data
    64   };
     116        std::string dataPath_;                                        //!< Path to the game data
     117        GameMode gameMode_;                                           //!< Current game mode
     118        std::map<std::string, const GameMode*> gameModes_;            //!< Holds all game modes for easy string access
     119        //! holds all command line arguments (even if not given!)
     120        std::map<std::string, CommandLineArgument> commandArguments_;
     121    };
     122
     123    /**
     124    @brief
     125        Returns the relative path to the game data.
     126    */
     127    inline const std::string& Settings::getDataPath()
     128    {
     129        return getInstance().dataPath_;
     130    }
     131
     132    inline void Settings::tsetDataPath(const std::string& path)
     133    {
     134        getInstance()._tsetDataPath(path);
     135    }
     136
     137    inline const GameMode& Settings::getGameMode()
     138    {
     139        return getInstance().gameMode_;
     140    }
     141
     142    inline const GameMode& Settings::getGameMode(const std::string& name)
     143    {
     144        if (getInstance().gameModes_.find(name) != getInstance().gameModes_.end())
     145            return *getInstance().gameModes_[name];
     146        else
     147        {
     148            COUT(2) << "Warning: GameMode '" << name << "' doesn't exist." << std::endl;
     149            return GameMode::GM_None;
     150        }
     151    }
     152
     153    inline void Settings::setGameMode(const GameMode& mode)
     154    {
     155        getInstance().gameMode_ = mode;
     156    }
     157
     158    /**
     159    @brief
     160        Adds one argument of the command line to the map of command line arguments.
     161    @param name
     162        Name of the command line option.
     163    @param valueStr
     164        The value of the command line option as string
     165    @param defaultValue
     166        Default value for the option (marked when used).
     167    @return
     168        Dummy return value to enable code execution before main().
     169    */
     170    template <class T>
     171    bool Settings::addCommandLineArgument(const std::string &name, const std::string& valueStr, const T& defaultValue)
     172    {
     173        T value;
     174        bool useDefault = false;
     175        if (valueStr == "")
     176        {
     177            // note: ArgReader only returns "" for not found arguments, " " otherwise for empty ones.
     178            value = defaultValue;
     179            useDefault = true;
     180        }
     181        else if (!convertValue(&value, valueStr))
     182        {
     183            COUT(1) << "Command Line: Couldn't read option '" << name << "'." << std::endl;
     184            return false;
     185        }
     186        CommandLineArgument arg = { name, MultiTypeMath(value), useDefault };
     187        getInstance().commandArguments_[name] = arg;
     188        return true;
     189    }
    65190}
    66191
  • code/branches/gui/src/orxonox/objects/Ambient.cc

    r1625 r1638  
    6565
    6666    bool Ambient::create(){
    67       GraphicsEngine::getSingleton().getSceneManager()->setAmbientLight(ambientLight_);
     67      GraphicsEngine::getSingleton().getLevelSceneManager()->setAmbientLight(ambientLight_);
    6868      return Synchronisable::create();
    6969    }
     
    7676    void Ambient::setAmbientLight(const ColourValue& colour)
    7777    {
    78             GraphicsEngine::getSingleton().getSceneManager()->setAmbientLight(colour);
     78        GraphicsEngine::getSingleton().getLevelSceneManager()->setAmbientLight(colour);
    7979      ambientLight_=colour;     
    8080    }
  • code/branches/gui/src/orxonox/objects/Backlight.cc

    r1608 r1638  
    5858        this->attachObject(this->billboard_.getBillboardSet());
    5959
    60         this->ribbonTrail_ = GraphicsEngine::getSingleton().getSceneManager()->createRibbonTrail(this->getName() + "RibbonTrail");
    61         this->ribbonTrailNode_ = GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(this->getName() + "RibbonTrailNode");
     60        this->ribbonTrail_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createRibbonTrail(this->getName() + "RibbonTrail");
     61        this->ribbonTrailNode_ = GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode(this->getName() + "RibbonTrailNode");
    6262        this->ribbonTrailNode_->attachObject(this->ribbonTrail_);
    6363        this->ribbonTrail_->addNode(this->getNode());
     
    6868        this->ribbonTrail_->setMaterialName("Trail/backlighttrail");
    6969
    70         this->setTimeFactor(Orxonox::getSingleton()->getTimeFactor());
     70        this->setTimeFactor(Orxonox::getSingleton().getTimeFactor());
    7171    }
    7272
     
    7676        {
    7777            this->detachObject(this->billboard_.getBillboardSet());
    78             GraphicsEngine::getSingleton().getSceneManager()->destroySceneNode(this->getName() + "RibbonTrailNode");
    79             GraphicsEngine::getSingleton().getSceneManager()->destroyRibbonTrail(this->ribbonTrail_);
     78            GraphicsEngine::getSingleton().getLevelSceneManager()->destroySceneNode(this->getName() + "RibbonTrailNode");
     79            GraphicsEngine::getSingleton().getLevelSceneManager()->destroyRibbonTrail(this->ribbonTrail_);
    8080        }
    8181    }
  • code/branches/gui/src/orxonox/objects/Camera.cc

    r1505 r1638  
    5252  {
    5353    this->bHasFocus_ = false;
    54     this->cameraNode_ = GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(node->getName() + "Camera");
     54    this->cameraNode_ = GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode(node->getName() + "Camera");
    5555    if( node != NULL )
    5656      this->setPositionNode(node);
     
    6060  {
    6161    CameraHandler::getInstance()->releaseFocus(this);
    62     GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->removeAndDestroyChild(cameraNode_->getName());
     62    GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->removeAndDestroyChild(cameraNode_->getName());
    6363  }
    6464
  • code/branches/gui/src/orxonox/objects/CameraHandler.cc

    r1505 r1638  
    4444  CameraHandler::CameraHandler()
    4545  {
    46     this->cam_ = GraphicsEngine::getSingleton().getSceneManager()->createCamera("Cam");
    47     GraphicsEngine::getSingleton().getRenderWindow()->addViewport(this->cam_);
     46    this->cam_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createCamera("Cam");
     47    GraphicsEngine::getSingleton().getLevelViewport()->setCamera(this->cam_);
     48    GraphicsEngine::getSingleton().getRenderWindow()->addViewport(this->cam_, 2, 0.4, 0.4, 0.2, 0.2);
    4849    /*this->activeCamera_ = *ObjectList<Camera>::begin();
    4950    this->activeCamera_->cam_ = this->cam_;*/
  • code/branches/gui/src/orxonox/objects/ParticleSpawner.cc

    r1608 r1638  
    7979        this->setPosition(this->getNode()->getParent()->getPosition());
    8080        this->getNode()->getParent()->removeChild(this->getNode());
    81         GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->addChild(this->getNode());
     81        GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->addChild(this->getNode());
    8282        if (this->particle_)
    8383            this->particle_->setEnabled(false);
  • code/branches/gui/src/orxonox/objects/Projectile.cc

    r1602 r1638  
    7575        SetConfigValue(speed_, 5000.0).description("The speed of a projectile in units per second");
    7676
    77         if(this->owner_)
     77    if(this->owner_)
    7878          this->setVelocity(this->owner_->getInitialDir() * this->speed_);
    7979    }
  • code/branches/gui/src/orxonox/objects/Skybox.cc

    r1558 r1638  
    5656    void Skybox::setSkybox(const std::string& skyboxname)
    5757    {
    58         GraphicsEngine::getSingleton().getSceneManager()->setSkyBox(true, skyboxname);
     58        GraphicsEngine::getSingleton().getLevelSceneManager()->setSkyBox(true, skyboxname);
    5959    }
    6060
     
    9292    {
    9393        BaseObject::changedVisibility();
    94         GraphicsEngine::getSingleton().getSceneManager()->setSkyBox(this->isVisible(), this->skyboxSrc_);
     94        GraphicsEngine::getSingleton().getLevelSceneManager()->setSkyBox(this->isVisible(), this->skyboxSrc_);
    9595    }
    9696}
  • code/branches/gui/src/orxonox/objects/Tickable.h

    r1535 r1638  
    2929/*!
    3030    @file Tickable.h
    31     @brief Definition of the Tickable interface.
     31    @brief Declaration of the Tickable interface.
    3232
    3333    The Tickable interface provides a tick(dt) function, that gets called every frame.
  • code/branches/gui/src/orxonox/objects/WorldEntity.cc

    r1625 r1638  
    4949        RegisterObject(WorldEntity);
    5050
    51         if (GraphicsEngine::getSingleton().getSceneManager())
     51        if (GraphicsEngine::getSingleton().getLevelSceneManager())
    5252        {
    5353            std::ostringstream name;
    5454            name << (WorldEntity::worldEntityCounter_s++);
    5555            this->setName("WorldEntity" + name.str());
    56             this->node_ = GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(this->getName());
     56            this->node_ = GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode(this->getName());
    5757
    5858            registerAllVariables();
     
    7777        {
    7878            this->getNode()->removeAndDestroyAllChildren();
    79             GraphicsEngine::getSingleton().getSceneManager()->destroySceneNode(this->getName());
     79            GraphicsEngine::getSingleton().getLevelSceneManager()->destroySceneNode(this->getName());
    8080        }
    8181    }
     
    178178    void WorldEntity::attachObject(const WorldEntity& obj) const
    179179    {
    180         GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->removeChild(obj.getNode());
     180        GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->removeChild(obj.getNode());
    181181        this->getNode()->addChild(obj.getNode());
    182182    }
     
    184184    void WorldEntity::attachObject(WorldEntity* obj) const
    185185    {
    186         GraphicsEngine::getSingleton().getSceneManager()->getRootSceneNode()->removeChild(obj->getNode());
     186        GraphicsEngine::getSingleton().getLevelSceneManager()->getRootSceneNode()->removeChild(obj->getNode());
    187187        this->getNode()->addChild(obj->getNode());
    188188    }
  • code/branches/gui/src/orxonox/overlays/console/InGameConsole.cc

    r1633 r1638  
    5959        @brief Constructor: Creates and initializes the InGameConsole.
    6060    */
    61     InGameConsole::InGameConsole() :
    62         consoleOverlay_(0), consoleOverlayContainer_(0),
    63         consoleOverlayNoise_(0), consoleOverlayCursor_(0), consoleOverlayBorder_(0),
    64         consoleOverlayTextAreas_(0)
     61    InGameConsole::InGameConsole()
     62        : consoleOverlay_(0)
     63        , consoleOverlayContainer_(0)
     64        , consoleOverlayNoise_(0)
     65        , consoleOverlayCursor_(0)
     66        , consoleOverlayBorder_(0)
     67        , consoleOverlayTextAreas_(0)
     68        , emptySceneManager_(0)
     69        , emptyCamera_(0)
     70        , viewport_(0)
    6571    {
    6672        RegisterObject(InGameConsole);
     
    188194
    189195        Shell::getInstance().addOutputLevel(true);
     196
     197        // create a sceneManager in order to render in our own viewport
     198        this->emptySceneManager_ = Ogre::Root::getSingleton()
     199            .createSceneManager(Ogre::ST_GENERIC, "Console/EmptySceneManager");
     200        this->emptyCamera_ = this->emptySceneManager_->createCamera("Console/EmptyCamera");
     201        this->viewport_ = GraphicsEngine::getSingleton().getRenderWindow()->addViewport(emptyCamera_, 10);
     202        this->viewport_->setOverlaysEnabled(true);
     203        this->viewport_->setClearEveryFrame(false);
    190204
    191205        COUT(4) << "Info: InGameConsole initialized" << std::endl;
     
    476490        {
    477491            this->bActive_ = true;
    478             InputManager::setInputState(InputManager::IS_CONSOLE);
     492            InputManager::requestEnterState("console");
    479493            Shell::getInstance().registerListener(this);
    480494
     
    498512        {
    499513            this->bActive_ = false;
    500             InputManager::setInputState(InputManager::IS_NORMAL);
     514            InputManager::requestLeaveState("console");
    501515            Shell::getInstance().unregisterListener(this);
    502516
  • code/branches/gui/src/orxonox/overlays/console/InGameConsole.h

    r1625 r1638  
    4545    class _OrxonoxExport InGameConsole : public TickableReal, public ShellListener, public WindowEventListener
    4646    {
    47         public: // functions
    48             void initialise();
    49             void destroy();
    50             void setConfigValues();
     47    public: // functions
     48        void initialise();
     49        void destroy();
     50        void setConfigValues();
    5151
    52             void tick(float dt);
     52        void tick(float dt);
    5353
    54             static InGameConsole& getInstance();
     54        static InGameConsole& getInstance();
    5555
    56             static void openConsole();
    57             static void closeConsole();
     56        static void openConsole();
     57        static void closeConsole();
    5858
    59         private: // functions
    60             InGameConsole();
    61             InGameConsole(const InGameConsole& other) {}
    62             ~InGameConsole();
     59    private: // functions
     60        InGameConsole();
     61        InGameConsole(const InGameConsole& other) {}
     62        ~InGameConsole();
    6363
    64             void activate();
    65             void deactivate();
     64        void activate();
     65        void deactivate();
    6666
    67             void linesChanged();
    68             void onlyLastLineChanged();
    69             void lineAdded();
    70             void inputChanged();
    71             void cursorChanged();
    72             void exit();
     67        void linesChanged();
     68        void onlyLastLineChanged();
     69        void lineAdded();
     70        void inputChanged();
     71        void cursorChanged();
     72        void exit();
    7373
    74             void shiftLines();
    75             void colourLine(int colourcode, int index);
    76             void setCursorPosition(unsigned int pos);
    77             void print(const std::string& text, int index, bool alwaysShift = false);
     74        void shiftLines();
     75        void colourLine(int colourcode, int index);
     76        void setCursorPosition(unsigned int pos);
     77        void print(const std::string& text, int index, bool alwaysShift = false);
    7878
    79             void windowResized(int newWidth, int newHeight);
     79        void windowResized(int newWidth, int newHeight);
    8080
    81             static Ogre::UTFString convert2UTF(std::string s);
     81        static Ogre::UTFString convert2UTF(std::string s);
    8282
    83         private: // variables
    84             bool bActive_;
    85             int windowW_;
    86             int windowH_;
    87             int desiredTextWidth_;
    88             unsigned int maxCharsPerLine_;
    89             unsigned int numLinesShifted_;
    90             int scroll_;
    91             float cursor_;
    92             unsigned int inputWindowStart_;
    93             bool bShowCursor_;
    94             std::string displayedText_;
    95             Ogre::Overlay* consoleOverlay_;
    96             Ogre::OverlayContainer* consoleOverlayContainer_;
    97             Ogre::PanelOverlayElement* consoleOverlayNoise_;
    98             Ogre::TextAreaOverlayElement* consoleOverlayCursor_;
    99             Ogre::BorderPanelOverlayElement* consoleOverlayBorder_;
    100             Ogre::TextAreaOverlayElement** consoleOverlayTextAreas_;
     83    private: // variables
     84        bool bActive_;
     85        int windowW_;
     86        int windowH_;
     87        int desiredTextWidth_;
     88        unsigned int maxCharsPerLine_;
     89        unsigned int numLinesShifted_;
     90        int scroll_;
     91        float cursor_;
     92        unsigned int inputWindowStart_;
     93        bool bShowCursor_;
     94        std::string displayedText_;
     95        Ogre::Overlay* consoleOverlay_;
     96        Ogre::OverlayContainer* consoleOverlayContainer_;
     97        Ogre::PanelOverlayElement* consoleOverlayNoise_;
     98        Ogre::TextAreaOverlayElement* consoleOverlayCursor_;
     99        Ogre::BorderPanelOverlayElement* consoleOverlayBorder_;
     100        Ogre::TextAreaOverlayElement** consoleOverlayTextAreas_;
    101101
    102             // config values
    103             float relativeWidth;
    104             float relativeHeight;
    105             float blinkTime;
    106             float scrollSpeed_;
    107             float noiseSize_;
    108             char cursorSymbol_;
     102        Ogre::SceneManager* emptySceneManager_;     //!< dummy SceneManager to render overlays in empty windows
     103        Ogre::Camera*       emptyCamera_;           //!< dummy camera to render overlays in empty windows
     104        Ogre::Viewport*     viewport_;
     105
     106        // config values
     107        float relativeWidth;
     108        float relativeHeight;
     109        float blinkTime;
     110        float scrollSpeed_;
     111        float noiseSize_;
     112        char cursorSymbol_;
    109113    };
    110114}
  • code/branches/gui/src/orxonox/overlays/hud/HUDSpeedBar.cc

    r1626 r1638  
    5454            float v = ship->getVelocity().length();
    5555            float value = v / ship->getMaxSpeed();
    56                         if (value != this->getValue())
     56            if (value != this->getValue())
    5757                this->setValue(value);
    5858        }
  • code/branches/gui/src/orxonox/tolua/tolua.pkg

    r1505 r1638  
     1$cfile "../../src/orxonox/gui/GUIManager.h"
  • code/branches/gui/src/orxonox/tools/BillboardSet.cc

    r1602 r1638  
    5050        std::ostringstream name;
    5151        name << (BillboardSet::billboardSetCounter_s++);
    52         this->billboardSet_ = GraphicsEngine::getSingleton().getSceneManager()->createBillboardSet("Billboard" + name.str(), count);
     52        this->billboardSet_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
    5353        this->billboardSet_->createBillboard(Vector3::ZERO);
    5454        this->billboardSet_->setMaterialName(file);
     
    5959        std::ostringstream name;
    6060        name << (BillboardSet::billboardSetCounter_s++);
    61         this->billboardSet_ = GraphicsEngine::getSingleton().getSceneManager()->createBillboardSet("Billboard" + name.str(), count);
     61        this->billboardSet_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
    6262        this->billboardSet_->createBillboard(Vector3::ZERO, colour);
    6363        this->billboardSet_->setMaterialName(file);
     
    6868        std::ostringstream name;
    6969        name << (BillboardSet::billboardSetCounter_s++);
    70         this->billboardSet_ = GraphicsEngine::getSingleton().getSceneManager()->createBillboardSet("Billboard" + name.str(), count);
     70        this->billboardSet_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
    7171        this->billboardSet_->createBillboard(position);
    7272        this->billboardSet_->setMaterialName(file);
     
    7777        std::ostringstream name;
    7878        name << (BillboardSet::billboardSetCounter_s++);
    79         this->billboardSet_ = GraphicsEngine::getSingleton().getSceneManager()->createBillboardSet("Billboard" + name.str(), count);
     79        this->billboardSet_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
    8080        this->billboardSet_->createBillboard(position, colour);
    8181        this->billboardSet_->setMaterialName(file);
     
    8585    {
    8686        if (this->billboardSet_)
    87             GraphicsEngine::getSingleton().getSceneManager()->destroyBillboardSet(this->billboardSet_);
     87            GraphicsEngine::getSingleton().getLevelSceneManager()->destroyBillboardSet(this->billboardSet_);
    8888    }
    8989}
  • code/branches/gui/src/orxonox/tools/Light.cc

    r1505 r1638  
    4949        std::ostringstream name;
    5050        name << (Light::lightCounter_s++);
    51         this->light_ = GraphicsEngine::getSingleton().getSceneManager()->createLight("Light" + name.str());
     51        this->light_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createLight("Light" + name.str());
    5252        this->light_->setType(type);
    5353        this->light_->setDiffuseColour(diffuse);
     
    5858    {
    5959        if (this->light_)
    60             GraphicsEngine::getSingleton().getSceneManager()->destroyLight(this->light_);
     60            GraphicsEngine::getSingleton().getLevelSceneManager()->destroyLight(this->light_);
    6161    }
    6262}
  • code/branches/gui/src/orxonox/tools/Mesh.cc

    r1505 r1638  
    4949        std::ostringstream name;
    5050        name << (Mesh::meshCounter_s++);
    51         this->entity_ = GraphicsEngine::getSingleton().getSceneManager()->createEntity("Mesh" + name.str(), file);
     51        this->entity_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createEntity("Mesh" + name.str(), file);
    5252    }
    5353
     
    5555    {
    5656        if (this->entity_)
    57             GraphicsEngine::getSingleton().getSceneManager()->destroyEntity(this->entity_);
     57            GraphicsEngine::getSingleton().getLevelSceneManager()->destroyEntity(this->entity_);
    5858    }
    5959}
  • code/branches/gui/src/orxonox/tools/ParticleInterface.cc

    r1563 r1638  
    5555    this->bEnabled_ = true;
    5656    this->detaillevel_ = (unsigned int)detaillevel;
    57     this->particleSystem_ = GraphicsEngine::getSingleton().getSceneManager()->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName);
    58     this->particleSystem_->setSpeedFactor(Orxonox::getSingleton()->getTimeFactor());
     57    this->particleSystem_ = GraphicsEngine::getSingleton().getLevelSceneManager()->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName);
     58    this->particleSystem_->setSpeedFactor(Orxonox::getSingleton().getTimeFactor());
    5959
    6060    if (GraphicsEngine::getSingleton().getDetailLevelParticle() < (unsigned int)this->detaillevel_)
     
    7272  {
    7373    this->particleSystem_->removeAllEmitters();
    74     GraphicsEngine::getSingleton().getSceneManager()->destroyParticleSystem(particleSystem_);
     74    GraphicsEngine::getSingleton().getLevelSceneManager()->destroyParticleSystem(particleSystem_);
    7575  }
    7676
     
    171171  void ParticleInterface::setSpeedFactor(float factor)
    172172  {
    173     this->particleSystem_->setSpeedFactor(Orxonox::getSingleton()->getTimeFactor() * factor);
     173    this->particleSystem_->setSpeedFactor(Orxonox::getSingleton().getTimeFactor() * factor);
    174174  }
    175175  float ParticleInterface::getSpeedFactor() const
    176176  {
    177     return (this->particleSystem_->getSpeedFactor() / Orxonox::getSingleton()->getTimeFactor());
     177    return (this->particleSystem_->getSpeedFactor() / Orxonox::getSingleton().getTimeFactor());
    178178  }
    179179
  • code/branches/gui/src/orxonox/tools/WindowEventListener.h

    r1625 r1638  
    4545        virtual ~WindowEventListener() { }
    4646
    47                     /** Window has moved position */
    48                     virtual void windowMoved() { }
     47            /** Window has moved position */
     48            virtual void windowMoved() { }
    4949
    50                     /** Window has resized */
    51                     virtual void windowResized(int newWidth, int newHeight) { }
     50            /** Window has resized */
     51            virtual void windowResized(int newWidth, int newHeight) { }
    5252
    53                     /** Window has lost/gained focus */
    54                     virtual void windowFocusChanged() { }
     53            /** Window has lost/gained focus */
     54            virtual void windowFocusChanged() { }
    5555    };
    5656}
  • code/branches/gui/src/tolua/tolua++.h

    r1505 r1638  
    1717#define TOLUA_H
    1818
     19/* original code */
     20/*
    1921#ifndef TOLUA_API
    2022#define TOLUA_API extern
    2123#endif
     24*/
     25
     26/********************************
     27******* ORXONOX CHANGES *********
     28********************************/
     29
     30#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined( TOLUA_STATIC_BUILD )
     31#  ifdef TOLUA_SHARED_BUILD
     32#    define TOLUA_API __declspec(dllexport)
     33#  else
     34#    if defined( __MINGW32__ )
     35#      define TOLUA_API
     36#    else
     37#      define TOLUA_API __declspec(dllimport)
     38#    endif
     39#  endif
     40#else
     41#  define TOLUA_API extern
     42#endif
     43
     44/********************************
     45****** END ORXONOX CHANGES ******
     46********************************/
    2247
    2348#define TOLUA_VERSION "tolua++-1.0.92"
  • code/branches/gui/src/tolua/toluabind.c

    r1505 r1638  
    1212
    1313/* Exported function */
    14 TOLUA_API int  tolua_tolua_open (lua_State* tolua_S);
     14int  tolua_tolua_open (lua_State* tolua_S);
    1515
    1616
     
    2121
    2222/* Open function */
    23 TOLUA_API int tolua_tolua_open (lua_State* tolua_S)
     23int tolua_tolua_open (lua_State* tolua_S)
    2424{
    2525 tolua_open(tolua_S);
     
    76227622
    76237623#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
    7624  TOLUA_API int luaopen_tolua (lua_State* tolua_S) {
     7624 int luaopen_tolua (lua_State* tolua_S) {
    76257625 return tolua_tolua_open(tolua_S);
    76267626};
  • code/branches/gui/src/util/ArgReader.cc

    r1535 r1638  
    2222 *   Author:
    2323 *      Reto Grieder
     24 *      Benjamin Knecht <beni_at_orxonox.net>
    2425 *   Co-authors:
    25  *      Benjamin Knecht <beni_at_orxonox.net>
     26 *      ...
    2627 *
    2728 */
     
    3536#include "SubString.h"
    3637
    37 ArgReader::ArgReader(int argc, char **argv)
     38std::string ArgReader::parse(int argc, char **argv)
    3839{
    39   failure_ = false;
    40   errorString_ = "";
    41   CmdLineArg arg;
     40    std::string errorString;
     41    CmdLineArg arg;
     42    int i = 1;
     43    while (i < argc)
     44    {
     45        if (argv[i][0] == '-' && argv[i][1] == '-') // name
     46        {
     47            if (argv[i][2] == '\0')
     48            {
     49                errorString += "Expected word after \"--\".\n";
     50            }
     51            arg.bChecked_ = false;
     52            arg.name_ = argv[i] + 2;
     53            arg.value_ = " ";
     54            arguments_.push_back(arg);
     55        }
     56        else // value
     57        {
     58            if (arguments_.size() == 0)
     59            {
     60                errorString += "Expected \"--\" in command line arguments.\n";
     61                arg.bChecked_ = false;
     62                arg.name_ = "";
     63                arg.value_ = " ";
     64                arguments_.push_back(arg);
     65            }
    4266
    43   int i = 1;
    44   while (i < argc)
    45   {
    46     if (argv[i][0] == '-' && argv[i][1] == '-') // name
    47     {
    48       if (argv[i][2] == '\0')
    49       {
    50         failure_ = true;
    51         errorString_ += "Expected word after \"--\".\n";
    52       }
    53       arg.bChecked_ = false;
    54       arg.name_ = argv[i] + 2;
    55       arg.value_ = "";
    56       arguments_.push_back(arg);
     67            if (arguments_.back().value_ != " ")
     68                arguments_.back().value_ += " " + std::string(argv[i]);
     69            else
     70                arguments_.back().value_ = argv[i];
     71        }
     72        ++i;
    5773    }
    58     else // value
    59     {
    60       if (arguments_.size() == 0)
    61       {
    62         failure_ = true;
    63         errorString_ += "Expected \"--\" in command line arguments.\n";
    64         arg.bChecked_ = false;
    65         arg.name_ = "";
    66         arg.value_ = "";
    67         arguments_.push_back(arg);
    68       }
    69 
    70       if (arguments_.back().value_ != "")
    71         arguments_.back().value_ += " " + std::string(argv[i]);
    72       else
    73         arguments_.back().value_ = argv[i];
    74     }
    75     ++i;
    76   }
     74    return errorString;
    7775}
    7876
    79 bool ArgReader::errorHandling()
     77const std::string& ArgReader::getArgument(const std::string& option)
    8078{
    81   bool argumentsChecked = true;
    82   for (unsigned int i = 1; i < arguments_.size(); ++i)
    83     argumentsChecked &= arguments_[i].bChecked_;
    84 
    85   if (!argumentsChecked)
    86     errorString_ += "Not all arguments could be matched.\n";
    87 
    88   return !argumentsChecked || failure_;
     79    unsigned int iArg = 0;
     80    while (iArg < arguments_.size())
     81    {
     82        if (arguments_[iArg].name_ == option)
     83        {
     84            arguments_[iArg].bChecked_ = true;
     85            return arguments_[iArg].value_;
     86        }
     87        ++iArg;
     88    }
     89    return blankString;
    8990}
    9091
    91 const std::string& ArgReader::getErrorString()
     92bool ArgReader::allChecked()
    9293{
    93   return errorString_;
     94    bool argumentsChecked = true;
     95    for (unsigned int i = 1; i < arguments_.size(); ++i)
     96        argumentsChecked &= arguments_[i].bChecked_;
     97
     98    return argumentsChecked;
    9499}
  • code/branches/gui/src/util/ArgReader.h

    r1535 r1638  
    2222 *   Author:
    2323 *      Reto Grieder
     24 *      Benjamin Knecht <beni_at_orxonox.net>
    2425 *   Co-authors:
    25  *      Benjamin Knecht <beni_at_orxonox.net>
     26 *      ...
    2627 *
    2728 */
     
    4243#include "Convert.h"
    4344
    44 struct _UtilExport CmdLineArg
    45 {
    46   std::string name_;
    47   std::string value_;
    48   bool bChecked_;
    49 };
    5045
    5146class _UtilExport ArgReader
    5247{
    53   public:
    54     ArgReader(int argc, char **argv);
    55     template <class T>
    56     void checkArgument(std::string option, T* value, bool must = false);
    57     bool errorHandling();
    58     const std::string& getErrorString();
     48public:
     49    ArgReader() { }
     50    std::string parse(int argc, char **argv);
     51    const std::string& getArgument(const std::string& option);
     52    bool allChecked();
    5953
    60   private:
     54private:
     55    struct CmdLineArg
     56    {
     57        std::string name_;
     58        std::string value_;
     59        bool bChecked_;
     60    };
     61
    6162    std::vector<CmdLineArg> arguments_;
    62     bool failure_;
    63     std::string errorString_;
    6463};
    6564
    66 template <class T>
    67 void ArgReader::checkArgument(std::string option, T* value, bool must)
    68 {
    69   unsigned int iArg = 0;
    70   while (iArg < arguments_.size())
    71   {
    72     if (arguments_[iArg].name_ == option)
    73       break;
    74     ++iArg;
    75   }
    76   if (iArg == arguments_.size())
    77   {
    78     if (must)
    79     {
    80       failure_ = true;
    81       errorString_ += "Cannot find mandatory argument \"" + option + "\"\n";
    82       return;
    83     }
    84     else
    85       return;
    86   }
    87 
    88   arguments_[iArg].bChecked_ = true;
    89 
    90   if (!convertValue(value, arguments_[iArg].value_))
    91   {
    92     failure_ = true;
    93     errorString_ += "Cannot convert argument value for option \"" + option + "\"\n";
    94   }
    95 }
    96 
    97 template <>
    98 void ArgReader::checkArgument(std::string option, bool* value, bool must)
    99 {
    100   // for type bool, only check whether the option was set or not
    101   unsigned int iArg = 0;
    102   while (iArg < arguments_.size())
    103   {
    104     if (arguments_[iArg].name_ == option)
    105     {
    106       arguments_[iArg].bChecked_ = true;
    107       *value = true;
    108       break;
    109     }
    110     ++iArg;
    111   }
    112   if (iArg == arguments_.size())
    113     *value = false;
    114 }
    115 
    11665#endif /* _ArgReader_H__ */
  • code/branches/gui/src/util/OrxonoxPlatform.h

    r1505 r1638  
    103103#else
    104104#  define ORXONOX_ARCH_TYPE ORXONOX_ARCHITECTURE_32
     105#endif
     106
     107// try to define function information
     108#ifndef __FUNCTIONNAME__
     109#  if ORXONOX_COMPILER == ORXONOX_COMPILER_BORL
     110#    define __FUNCTIONNAME__ __FUNC__
     111#  elif ORXONOX_COMPILER == ORXONOX_COMPILER_GNUC
     112#    define __FUNCTIONNAME__ __PRETTY_FUNCTION__
     113#  elif ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
     114#    define __FUNCTIONNAME__ __FUNCTION__
     115#  else
     116#    define __FUNCTIONNAME__
     117#  endif
    105118#endif
    106119
     
    265278// generated code from nvparse etc). I doubt very much that these calls
    266279// will ever be actually removed from VC anyway, it would break too much code.
    267 //#     pragma warning( disable: 4996)
     280//# pragma warning( disable: 4996)
    268281
    269282// disable: "conditional expression constant", always occurs on
  • code/branches/gui/src/util/Sleep.h

    r1505 r1638  
    2929/**
    3030 @file  Sleep.h
    31  @brief Macros for using sleep() and usleep() under windows
     31 @brief Functions for using sleep() and usleep() under windows
    3232 */
    3333
Note: See TracChangeset for help on using the changeset viewer.