Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 1340


Ignore:
Timestamp:
May 21, 2008, 12:23:29 AM (17 years ago)
Author:
rgrieder
Message:
  • tried a more object oriented approach for the KeyBinder
  • things work as far as I can tell
  • tested slomo command on joy stick slider: I was able to steer the time factor with the slider.
  • more infos to come..
Location:
code/branches/input
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • code/branches/input/bin/keybindings.ini

    r1323 r1340  
    11[KeyBinder]
    22KeyUNASSIGNED=
    3 KeyESCAPE=OnHold fire | OnHold AxisAmp -2.4 lookUpDown | OnPress exit
     3KeyESCAPE=OnPress exit
    44Key1=
    55Key2=
     
    154154MouseButton6=
    155155MouseButton7=
    156 MouseXPos=
     156MouseXPos=exit | ButtonThreshold 0.85
    157157MouseXNeg=
    158158MouseYPos=
     
    171171JoyAxis4Neg=
    172172JoyAxis5Pos=
    173 JoyAxis5Neg=
    174 JoyAxis6Pos=
     173JoyAxis5Neg=AxisAmp 10 slomo | ButtonThreshold 0.9 | onPress exit
     174JoyAxis6Pos=AxisAmp  10 slomo
    175175JoyAxis6Neg=
    176176JoyAxis7Pos=
  • code/branches/input/src/core/CommandExecutor.h

    r1323 r1340  
    8787            inline std::string getAdditionalParameter() const
    8888                { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
    89             inline Executor* getExecutor() { return 0; }
     89            inline ExecutorStatic* getEvaluatedExecutor() { return evaluatedExecutor_; }
     90            inline std::string getCommandString() { return this->processedCommand_; }
    9091
    9192            void setEvaluatedParameter(unsigned int index, MultiTypeMath param);
  • code/branches/input/src/core/CorePrereqs.h

    r1323 r1340  
    8282    enum Enum
    8383    {
    84       None,
    8584      OnPress,
    8685      OnHold,
    87       OnRelease
     86      OnRelease,
     87      None
    8888    };
    8989  };
  • code/branches/input/src/core/Executor.cc

    r1062 r1340  
    3939        this->name_ = name;
    4040        this->accessLevel_ = level;
     41        this->keybindMode_ = KeybindMode::OnPress;
     42        this->axisParamIndex_ = -1;
     43        this->bAxisRelative_ = false;
    4144
    4245        this->bAddedDescription_ = false;
  • code/branches/input/src/core/Executor.h

    r1323 r1340  
    204204                { return this->accessLevel_; }
    205205
     206            inline Executor& setKeybindMode(KeybindMode::Enum mode)
     207                { this->keybindMode_ = mode; return *this; }
     208            inline KeybindMode::Enum getKeybindMode() const
     209                { return this->keybindMode_; }
     210
     211            inline Executor& setAxisParamIndex(int index)
     212                { this->axisParamIndex_ = index; return *this; }
     213            inline int getAxisParamIndex() const
     214                { return this->axisParamIndex_; }
     215
     216            inline Executor& setIsAxisRelative(bool val)
     217                { this->bAxisRelative_ = val; return *this; }
     218            inline int getIsAxisRelative() const
     219                { return this->bAxisRelative_; }
     220
    206221            Executor& setDefaultValues(const MultiTypeMath& param1);
    207222            Executor& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2);
     
    233248            MultiTypeMath defaultValue_[MAX_FUNCTOR_ARGUMENTS];
    234249            bool bAddedDefaultValue_[MAX_FUNCTOR_ARGUMENTS];
     250
    235251            KeybindMode::Enum keybindMode_;
    236             int axisParameter_;
     252            int axisParamIndex_;
     253            bool bAxisRelative_;
    237254
    238255        private:
  • code/branches/input/src/core/InputBuffer.cc

    r1323 r1340  
    191191  }
    192192
    193   bool InputBuffer::keyPressed(const KeyEvent &evt)
     193  void InputBuffer::keyPressed(const KeyEvent &evt)
    194194  {
    195195    lastKey_ = evt.key;
     
    199199
    200200    processKey(evt);
    201     return true;
    202   }
    203 
    204   bool InputBuffer::keyHeld(const KeyEvent& evt)
     201  }
     202
     203  void InputBuffer::keyHeld(const KeyEvent& evt)
    205204  {
    206205    if (evt.key == lastKey_)
     
    212211      }
    213212    }
    214     return true;
    215213  }
    216214
  • code/branches/input/src/core/InputBuffer.h

    r1323 r1340  
    101101    bool charIsAllowed(const char& input);
    102102
    103     bool keyPressed (const KeyEvent& evt);
    104     bool keyReleased(const KeyEvent& evt) { return true; }
    105     bool keyHeld    (const KeyEvent& evt);
     103    void keyPressed (const KeyEvent& evt);
     104    void keyReleased(const KeyEvent& evt) { }
     105    void keyHeld    (const KeyEvent& evt);
    106106    void processKey (const KeyEvent &e);
    107107
  • code/branches/input/src/core/InputHandler.cc

    r1323 r1340  
    4545{
    4646  // ###############################
     47  // ######      Button       ######
     48  // ###############################
     49
     50  bool BufferedParamCommand::execute()
     51  {
     52    if (nValuesAdded_)
     53    {
     54      BufferedParamCommand& cmd = *this;
     55      cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
     56      // reset
     57      cmd.nValuesAdded_ = 0;
     58      cmd.value_ = 0;
     59      return CommandExecutor::execute(cmd.evaluation_);
     60    }
     61    else
     62      return true;
     63  }
     64
     65  bool SimpleCommand::execute(float abs, float rel)
     66  {
     67    return CommandExecutor::execute(evaluation_);
     68  }
     69
     70  bool ParamCommand::execute(float abs, float rel)
     71  {
     72    BufferedParamCommand& paramCommand = *paramCommand_;
     73    // command has an additional parameter
     74    if (bRelative_)
     75    {
     76      // we have to calculate a relative movement.
     77      // amplitude says how much one keystroke is
     78      paramCommand.value_ += paramModifier_ * rel;
     79    }
     80    else
     81    {
     82      // we have to calculate absolute position of the axis.
     83      // for a key this simply is 1, but multiplied by a user defined factor
     84      // since there might be another axis that is affected, we have to wait and
     85      // store the result in a temporary place
     86      paramCommand.value_ = (paramCommand.value_ * paramCommand.nValuesAdded_ + paramModifier_ * abs)
     87                            /++paramCommand.nValuesAdded_;
     88    }
     89    return true;
     90  }
     91
     92  void Button::clear()
     93  {
     94    for (unsigned int j = 0; j < 3; j++)
     95    {
     96      if (nCommands_[j])
     97      {
     98        // delete all commands and the command pointer array
     99        for (unsigned int i = 0; i < nCommands_[j]; i++)
     100          delete commands_[j][i];
     101        delete[] commands_[j];
     102        commands_[j] = 0;
     103        nCommands_[j] = 0;
     104      }
     105      else
     106      {
     107        commands_[j] = 0;
     108      }
     109    }
     110  }
     111
     112  void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
     113  {
     114    if (isEmpty(bindingString_))
     115    {
     116      clear();
     117      return;
     118    }
     119
     120    // use std::vector for a temporary dynamic array
     121    std::vector<BaseCommand*> commands[3];
     122
     123
     124    // separate the commands
     125    SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
     126        '\\', false, '"', false, '(', ')', false, '\0');
     127
     128    for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
     129    {
     130      if (commandStrings[iCommand] != "")
     131      {
     132        SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     133            '\\', false, '"', false, '(', ')', false, '\0');
     134       
     135        unsigned int iToken = 0;
     136
     137        // for real axes, we can feed a ButtonThreshold argument as entire command
     138        if (getLowercase(tokens[0]) == "buttonthreshold")
     139        {
     140          if (tokens.size() == 1)
     141            continue;
     142          // may fail, but doesn't matter
     143          convertValue(&buttonThreshold_, tokens[1]);
     144          continue;
     145        }
     146
     147        // first argument can be OnPress, OnHold OnRelease or nothing
     148        KeybindMode::Enum mode = KeybindMode::None;
     149        if (getLowercase(tokens[iToken]) == "onpress")
     150          mode = KeybindMode::OnPress,   iToken++;
     151        if (getLowercase(tokens[iToken]) == "onrelease")
     152          mode = KeybindMode::OnRelease, iToken++;
     153        if (getLowercase(tokens[iToken]) == "onhold")
     154          mode = KeybindMode::OnHold,    iToken++;
     155
     156        if (iToken == tokens.size())
     157          continue;
     158
     159        // second argument can be the amplitude for the case it as an axis command
     160        // default amplitude is 1.0f
     161        float paramModifier = 1.0f;
     162        if (getLowercase(tokens[iToken]) == "axisamp")
     163        {
     164          iToken++;
     165          if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
     166          {
     167            COUT(2) << "Error while parsing key binding " << name_
     168                << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
     169            if (iToken == tokens.size())
     170              continue;
     171          }
     172          iToken++;
     173        }
     174
     175        // no more arguments expected except for the actual command
     176        if (iToken == tokens.size())
     177          continue;
     178
     179        std::string commandStr;
     180        while (iToken != tokens.size())
     181          commandStr += tokens[iToken++] + " ";
     182
     183        // evaluate the command
     184        CommandEvaluation& eval = CommandExecutor::evaluate(commandStr);
     185        if (!eval.isValid())
     186          continue;
     187
     188        // check for param command
     189        int paramIndex = eval.getEvaluatedExecutor()->getAxisParamIndex();
     190        // TODO: check in Executor for correct paramIndex
     191        if (paramIndex >= 0)
     192        {
     193          // parameter supported command
     194          ParamCommand* cmd = new ParamCommand();
     195          cmd->paramModifier_ = paramModifier;
     196          cmd->bRelative_ = eval.getEvaluatedExecutor()->getIsAxisRelative();
     197
     198          // add command to the buffer if not yet existing
     199          for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
     200          {
     201            if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getCommandString())
     202                == getLowercase(commandStr))
     203            {
     204              // already in list
     205              cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
     206              break;
     207            }
     208          }
     209          if (cmd->paramCommand_ == 0)
     210          {
     211            cmd->paramCommand_ = new BufferedParamCommand();
     212            paramCommandBuffer.push_back(cmd->paramCommand_);
     213            cmd->paramCommand_->evaluation_ = eval;
     214            cmd->paramCommand_->paramIndex_ = paramIndex;
     215          }
     216
     217
     218          // we don't know whether this is an actual axis or just a button
     219          if (mode == KeybindMode::None)
     220          {
     221            if (!addParamCommand(cmd))
     222            {
     223              mode = eval.getEvaluatedExecutor()->getKeybindMode();
     224              commands[mode].push_back(cmd);
     225            }
     226          }
     227        }
     228        else
     229        {
     230          SimpleCommand* cmd = new SimpleCommand();
     231          cmd->evaluation_ = eval;
     232
     233          //TODO: check CommandEvaluation for correct KeybindMode
     234          if (mode == KeybindMode::None)
     235            mode = eval.getEvaluatedExecutor()->getKeybindMode();
     236
     237          commands[mode].push_back(cmd);
     238        }
     239      }
     240    }
     241
     242    for (unsigned int j = 0; j < 3; j++)
     243    {
     244      nCommands_[j] = commands[j].size();
     245      if (nCommands_[j])
     246      {
     247        commands_[j] = new BaseCommand*[nCommands_[j]];
     248        for (unsigned int i = 0; i < commands[j].size(); i++)
     249          commands_[j][i] = commands[j][i];
     250      }
     251      else
     252        commands_[j] = 0;
     253    }
     254  }
     255
     256  bool Button::execute(KeybindMode::Enum mode)
     257  {
     258    // execute all the parsed commands in the string
     259    for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
     260      commands_[mode][iCommand]->execute();
     261    return true;
     262  }
     263
     264  void HalfAxis::clear()
     265  {
     266    Button::clear();
     267    if (nParamCommands_)
     268    {
     269      // delete all commands and the command pointer array
     270      for (unsigned int i = 0; i < nParamCommands_; i++)
     271        delete paramCommands_[i];
     272      delete[] paramCommands_;
     273    }
     274    else
     275    {
     276      nParamCommands_ = 0; nParamCommands_ = 0;
     277    }
     278  }
     279 
     280  bool HalfAxis::addParamCommand(ParamCommand* command)
     281  {
     282    ParamCommand** cmds = paramCommands_;
     283    paramCommands_ = new ParamCommand*[++nParamCommands_];
     284    unsigned int i;
     285    for (i = 0; i < nParamCommands_ - 1; i++)
     286      paramCommands_[i] = cmds[i];
     287    paramCommands_[i] = command;
     288    delete[] cmds;
     289    return true;
     290  }
     291
     292  bool HalfAxis::execute()
     293  {
     294    bool success = true;
     295    for (unsigned int i = 0; i < nParamCommands_; i++)
     296      success = success && paramCommands_[i]->execute(absVal_, relVal_);
     297    return success;
     298  }
     299
     300
     301  // ###############################
    47302  // ######     KeyBinder     ######
    48303  // ###############################
     
    54309  {
    55310    RegisterObject(KeyBinder);
    56     clearBindings(true);
    57311
    58312    // keys
     
    60314      "UNASSIGNED",
    61315      "ESCAPE",
    62       "1",
    63       "2",
    64       "3",
    65       "4",
    66       "5",
    67       "6",
    68       "7",
    69       "8",
    70       "9",
    71       "0",
    72       "MINUS",
    73       "EQUALS",
    74       "BACK",
    75       "TAB",
    76       "Q",
    77       "W",
    78       "E",
    79       "R",
    80       "T",
    81       "Y",
    82       "U",
    83       "I",
    84       "O",
    85       "P",
    86       "LBRACKET",
    87       "RBRACKET",
    88       "RETURN",
    89       "LCONTROL",
    90       "A",
    91       "S",
    92       "D",
    93       "F",
    94       "G",
    95       "H",
    96       "J",
    97       "K",
    98       "L",
    99       "SEMICOLON",
    100       "APOSTROPHE",
    101       "GRAVE",
    102       "LSHIFT",
    103       "BACKSLASH",
    104       "Z",
    105       "X",
    106       "C",
    107       "V",
    108       "B",
    109       "N",
    110       "M",
    111       "COMMA",
    112       "PERIOD",
    113       "SLASH",
     316      "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
     317      "MINUS", "EQUALS", "BACK", "TAB",
     318      "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
     319      "LBRACKET", "RBRACKET",
     320      "RETURN", "LCONTROL",
     321      "A", "S", "D", "F", "G", "H", "J", "K", "L",
     322      "SEMICOLON", "APOSTROPHE", "GRAVE",
     323      "LSHIFT", "BACKSLASH",
     324      "Z", "X", "C", "V", "B", "N", "M",
     325      "COMMA", "PERIOD", "SLASH",
    114326      "RSHIFT",
    115327      "MULTIPLY",
     
    117329      "SPACE",
    118330      "CAPITAL",
    119       "F1",
    120       "F2",
    121       "F3",
    122       "F4",
    123       "F5",
    124       "F6",
    125       "F7",
    126       "F8",
    127       "F9",
    128       "F10",
    129       "NUMLOCK",
    130       "SCROLL",
    131       "NUMPAD7",
    132       "NUMPAD8",
    133       "NUMPAD9",
     331      "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
     332      "NUMLOCK", "SCROLL",
     333      "NUMPAD7", "NUMPAD8", "NUMPAD9",
    134334      "SUBTRACT",
    135       "NUMPAD4",
    136       "NUMPAD5",
    137       "NUMPAD6",
     335      "NUMPAD4", "NUMPAD5", "NUMPAD6",
    138336      "ADD",
    139       "NUMPAD1",
    140       "NUMPAD2",
    141       "NUMPAD3",
    142       "NUMPAD0",
     337      "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
    143338      "DECIMAL",
    144339      "","",
    145340      "OEM_102",
    146       "F11",
    147       "F12",
     341      "F11", "F12",
    148342      "","","","","","","","","","","",
    149       "F13",
    150       "F14",
    151       "F15",
     343      "F13", "F14", "F15",
    152344      "","","","","","","","","","",
    153345      "KANA",
     
    166358      "PREVTRACK",
    167359      "AT",
    168       "COLON",
    169       "UNDERLINE",
     360      "COLON", "UNDERLINE",
    170361      "KANJI",
    171362      "STOP",
     
    205396      "RIGHT",
    206397      "",
    207       "END",
    208       "DOWN",
    209       "PGDOWN",
    210       "INSERT",
    211       "DELETE",
     398      "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
    212399      "","","","","","","",
    213       "LWIN",
    214       "RWIN",
    215       "APPS",
    216       "POWER",
    217       "SLEEP",
     400      "LWIN", "RWIN", "APPS",
     401      "POWER", "SLEEP",
    218402      "","","",
    219403      "WAKE",
    220404      "",
    221       "WEBSEARCH",
    222       "WEBFAVORITES",
    223       "WEBREFRESH",
    224       "WEBSTOP",
    225       "WEBFORWARD",
    226       "WEBBACK",
    227       "MYCOMPUTER",
    228       "MAIL",
    229       "MEDIASELECT"
     405      "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
     406      "MYCOMPUTER", "MAIL", "MEDIASELECT"
    230407    };
    231408    for (int i = 0; i < nKeys_s; i++)
    232       namesKeys_[i] = "Key" + keyNames[i];
     409      keys_[i].name_ = "Key" + keyNames[i];
    233410
    234411    // mouse buttons
     
    238415      "MouseButton6", "MouseButton7" };
    239416    for (int i = 0; i < nMouseButtons_s; i++)
    240       namesMouseButtons_[i] = mouseButtonNames[i];
     417      mouseButtons_[i].name_ = mouseButtonNames[i];
    241418
    242419    // joy stick buttons
    243420    for (int i = 0; i < 32; i++)
    244       namesJoyStickButtons_[i] = "JoyButton" + getConvertedValue<int, std::string>(i);
     421      joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
    245422    for (int i = 32; i < nJoyStickButtons_s; i += 4)
    246423    {
    247                   namesJoyStickButtons_[i + 0] = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
    248                   namesJoyStickButtons_[i + 1] = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
    249                   namesJoyStickButtons_[i + 2] = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
    250                   namesJoyStickButtons_[i + 3] = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
     424                  joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
     425                  joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
     426                  joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
     427                  joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
    251428    }
    252429
     
    261438    for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
    262439    {
    263       namesHalfAxes_[i * 2 + 0] = rawNames[i] + "Pos";
    264       namesHalfAxes_[i * 2 + 1] = rawNames[i] + "Neg";
    265     }
     440      halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
     441      halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
     442    }
     443
     444    for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
     445      halfAxes_[i].buttonThreshold_ = buttonThreshold_;
    266446  }
    267447
     
    276456
    277457  /**
     458    @brief Loads the key and button bindings.
     459    @return True if loading succeeded.
     460  */
     461  void KeyBinder::loadBindings()
     462  {
     463    COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
     464
     465    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
     466    clearBindings();
     467    setConfigValues();
     468
     469    COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
     470  }
     471
     472  /**
    278473    @brief Loader for the key bindings, managed by config values.
    279474  */
    280475  void KeyBinder::setConfigValues()
    281476  {
    282     bool success = true;
     477    SetConfigValue(analogThreshold_, 0.01f).description("Threshold for analog axes until which the state is 0.");
     478    float oldThresh = buttonThreshold_;
     479    SetConfigValue(buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
     480    if (oldThresh != buttonThreshold_)
     481      for (unsigned int i = 0; i < nHalfAxes_s; i++)
     482        if (halfAxes_[i].buttonThreshold_ == oldThresh)
     483          halfAxes_[i].buttonThreshold_ = buttonThreshold_;
     484
    283485    // keys
    284     success |= readBindings(namesKeys_, bindingStringsKeys_, bindingsKeys_, nKeys_s);
     486    for (unsigned int i = 0; i < nKeys_s; i++)
     487      readTrigger(keys_[i]);
    285488    // mouse buttons
    286     success |= readBindings(namesMouseButtons_, bindingStringsMouseButtons_, bindingsMouseButtons_, nMouseButtons_s);
     489    for (unsigned int i = 0; i < nMouseButtons_s; i++)
     490      readTrigger(mouseButtons_[i]);
    287491    // joy stick buttons
    288     success |= readBindings(namesJoyStickButtons_, bindingStringsJoyStickButtons_,
    289         bindingsJoyStickButtons_, nJoyStickButtons_s);
     492    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
     493      readTrigger(joyStickButtons_[i]);
    290494    // half axes
    291     success |= readBindings(namesHalfAxes_, bindingStringsHalfAxes_, bindingsHalfAxes_, nHalfAxes_s);
    292    
    293     // TODO: what happens if parsing didn't succeed in all parts? nothing?
    294   }
    295 
    296   bool KeyBinder::readBindings(std::string* names, std::string* bindingStrings,
    297       KeyBindingBundle* bindings, unsigned int size)
    298   {
    299     for (unsigned int i = 0; i < size; i++)
    300     {
    301       // config value stuff
    302       ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer(names[i]);
    303       if (!cont)
    304       {
    305         cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), names[i], "");
    306         getIdentifier()->addConfigValueContainer(names[i], cont);
    307       }
    308       std::string old = bindingStrings[i];
    309       cont->getValue(&bindingStrings[i]);
    310 
    311       // keybinder stuff
    312       if (old != bindingStrings[i])
    313       {
    314         // binding has changed
    315         if (bindingStrings[i] == "")
    316         {
    317           // empty binding, occurs at least the first time since init value is " "
    318           bindings[i].OnPress.clear();
    319           bindings[i].OnRelease.clear();
    320           bindings[i].OnHold.clear();
    321         }
    322         else
    323         {
    324           // actually parse the command(s)
    325           SubString commands(bindingStrings[i], "|", SubString::WhiteSpaces, false,
    326               '\\', false, '"', false, '(', ')', false, '\0');
    327           bindings[i].OnHold.nCommands = 0;
    328           bindings[i].OnHold.commands = new SimpleCommand[64];
    329           bindings[i].OnPress.nCommands = 0;
    330           bindings[i].OnPress.commands = new SimpleCommand[64];
    331           bindings[i].OnRelease.nCommands = 0;
    332           bindings[i].OnRelease.commands = new SimpleCommand[64];
    333           for (unsigned int iCommand = 0; iCommand < commands.size(); iCommand++)
    334           {
    335             if (commands[iCommand] != "")
    336             {
    337               SubString tokens(commands[iCommand], " ", SubString::WhiteSpaces, false,
    338                   '\\', false, '"', false, '(', ')', false, '\0');
    339              
    340               unsigned int iToken = 0;
    341 
    342               // first argument can be OnPress, OnHold OnRelease or nothing
    343               KeybindMode::Enum mode = KeybindMode::None;
    344               if (getLowercase(tokens[iToken]) == "onpress")
    345                 mode = KeybindMode::OnPress,   iToken++;
    346               if (getLowercase(tokens[iToken]) == "onrelease")
    347                 mode = KeybindMode::OnRelease, iToken++;
    348               if (getLowercase(tokens[iToken]) == "onhold")
    349                 mode = KeybindMode::OnHold,    iToken++;
    350 
    351               if (iToken == tokens.size())
    352                 continue;
    353 
    354               SimpleCommand* cmd = new SimpleCommand();
    355 
    356               // second argument can be the amplitude for the case it as an axis command
    357               // default amplitude is 1.0f
    358               if (getLowercase(tokens[iToken]) == "axisamp")
    359               {
    360                 iToken++;
    361                 float value;
    362                 if (iToken == tokens.size() || !convertValue(&value, tokens[iToken]))
    363                 {
    364                   CCOUT(2) << "Error while parsing key binding " << names[i]
    365                       << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
    366                   if (iToken == tokens.size())
    367                   {
    368                     delete cmd;
    369                     continue;
    370                   }
    371                   cmd->axisModifier = 1.0f;
    372                 }
    373                 else
    374                   cmd->axisModifier = value;
    375                 iToken++;
    376               }
    377               else
    378                 cmd->axisModifier = 1.0f;
    379 
    380               // no more arguments expected except for the actual command
    381               if (iToken == tokens.size())
    382               { // no command given
    383                 delete cmd;
    384                 continue;
    385               }
    386               while (iToken != tokens.size())
    387                 cmd->commandStr += tokens[iToken++] + " ";
    388 
    389               // check whether we exceed 64 commands...
    390               if (bindings[i].OnHold.nCommands == 64 || bindings[i].OnPress.nCommands == 64
    391                   || bindings[i].OnRelease.nCommands == 64)
    392               {
    393                 CCOUT(2) << "Error while parsing key binding " << names[i]
    394                     << ". You shouldn't assign more than 64 key bindings to one key "
    395                     << "just to test the parser" << std::endl;
    396               }
    397 
    398               // evaluate the command
    399               cmd->axisCommand = 0;
    400               CommandEvaluation& eval = CommandExecutor::evaluate(cmd->commandStr);
    401               // TOOD: check for axis command
    402               if (false)
    403               {
    404                 cmd->axisCommand->commandStr = cmd->commandStr;
    405                 cmd->commandStr = "";
    406                 cmd->axisCommand->evaluation = eval;
    407                 // add command to the buffer if not yet existing
    408                 for (unsigned int iAxisCmd = 0; iAxisCmd < axisCommands_.size(); iAxisCmd++)
    409                 {
    410                   if (getLowercase(axisCommands_[iAxisCmd]->commandStr) == getLowercase(cmd->commandStr))
    411                   {
    412                     // already in list
    413                     cmd->axisCommand = axisCommands_[iAxisCmd];
    414                     break;
    415                   }
    416                 }
    417                 if (cmd->axisCommand == 0)
    418                 {
    419                   cmd->axisCommand = new AxisCommand();
    420                   axisCommands_.push_back(cmd->axisCommand);
    421                 }
    422                 // TODO: check for relative/absolute command
    423                 cmd->axisCommand->bRelative = false;
    424 
    425                 // axis commands are always OnHold
    426                 *(bindings[i].OnHold.commands + bindings[i].OnHold.nCommands++) = *cmd;
    427               }
    428               else
    429               {
    430                 cmd->evaluation = eval;
    431 
    432                 // TODO: determine whether the command is OnHold, OnPress or OnRelease
    433                 switch (mode)
    434                 {
    435                 case KeybindMode::None:
    436                   *(bindings[i].OnPress.commands + bindings[i].OnPress.nCommands++) = *cmd;
    437                   break;
    438                 case KeybindMode::OnPress:
    439                   *(bindings[i].OnPress.commands + bindings[i].OnPress.nCommands++) = *cmd;
    440                   break;
    441                 case KeybindMode::OnHold:
    442                   *(bindings[i].OnHold.commands + bindings[i].OnHold.nCommands++) = *cmd;
    443                   break;
    444                 case KeybindMode::OnRelease:
    445                   *(bindings[i].OnRelease.commands + bindings[i].OnRelease.nCommands++) = *cmd;
    446                   break;                     
    447                 }
    448               }
    449             }
    450           }
    451 
    452           // redimension arrays with simple commands
    453           SimpleCommand* sCmd = bindings[i].OnHold.commands;
    454           if (bindings[i].OnHold.nCommands)
    455           {
    456             bindings[i].OnHold.commands = new SimpleCommand[bindings[i].OnHold.nCommands];
    457             for (unsigned int iCmd = 0; iCmd < bindings[i].OnHold.nCommands; iCmd++)
    458               bindings[i].OnHold.commands[iCmd] = sCmd[iCmd];
    459           }
    460           else
    461             bindings[i].OnHold.commands = 0;
    462           delete[] sCmd;
    463 
    464           sCmd = bindings[i].OnPress.commands;
    465           if (bindings[i].OnPress.nCommands)
    466           {
    467             bindings[i].OnPress.commands = new SimpleCommand[bindings[i].OnPress.nCommands];
    468             for (unsigned int iCmd = 0; iCmd < bindings[i].OnPress.nCommands; iCmd++)
    469               bindings[i].OnPress.commands[iCmd] = sCmd[iCmd];
    470           }
    471           else
    472             bindings[i].OnPress.commands = 0;
    473           delete[] sCmd;
    474 
    475           sCmd = bindings[i].OnRelease.commands;
    476           if (bindings[i].OnRelease.nCommands)
    477           {
    478             bindings[i].OnRelease.commands = new SimpleCommand[bindings[i].OnRelease.nCommands];
    479             for (unsigned int iCmd = 0; iCmd < bindings[i].OnRelease.nCommands; iCmd++)
    480               bindings[i].OnRelease.commands[iCmd] = sCmd[iCmd];
    481           }
    482           else
    483             bindings[i].OnRelease.commands = 0;
    484           delete[] sCmd;
    485         }
    486       }
    487     }
    488     return true;
     495    for (unsigned int i = 0; i < nHalfAxes_s; i++)
     496      readTrigger(halfAxes_[i]);
     497  }
     498
     499  void KeyBinder::readTrigger(Button& button)
     500  {
     501    // config value stuff
     502    ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer(button.name_);
     503    if (!cont)
     504    {
     505      cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), button.name_, "");
     506      getIdentifier()->addConfigValueContainer(button.name_, cont);
     507    }
     508    std::string old = button.bindingString_;
     509    cont->getValue(&button.bindingString_);
     510
     511    // keybinder stuff
     512    if (old != button.bindingString_)
     513    {
     514      // binding has changed
     515      button.parse(paramCommandBuffer_);
     516    }
    489517  }
    490518
     
    495523  {
    496524    for (int i = 0; i < nKeys_s; i++)
    497     {
    498       clearBundle(bindingsKeys_[i], bInit);
    499       bindingStringsKeys_[i] = " ";
    500     }
     525      keys_[i].clear();
     526
    501527    for (int i = 0; i < nMouseButtons_s; i++)
    502     {
    503       clearBundle(bindingsMouseButtons_[i], bInit);
    504       bindingStringsMouseButtons_[i] = " ";
    505     }
     528      mouseButtons_[i].clear();
     529
    506530    for (int i = 0; i < nJoyStickButtons_s; i++)
    507     {
    508       clearBundle(bindingsJoyStickButtons_[i], bInit);
    509       bindingStringsJoyStickButtons_[i] = " ";
    510     }
     531      joyStickButtons_[i].clear();
     532
    511533    for (int i = 0; i < nHalfAxes_s; i++)
    512     {
    513       clearBundle(bindingsHalfAxes_[i], bInit);
    514       bindingStringsHalfAxes_[i] = " ";
    515     }
    516     for (unsigned int i = 0; i < axisCommands_.size(); i++)
    517       delete axisCommands_[i];
    518     axisCommands_.clear();
    519   }
    520 
    521   void KeyBinder::clearBundle(KeyBindingBundle& bundle, bool bInit)
    522   {
    523     if (!bInit)
    524     {
    525       if (bundle.OnHold.nCommands)
    526         delete[] bundle.OnHold.commands;
    527       if (bundle.OnPress.nCommands)
    528         delete[] bundle.OnPress.commands;
    529       if (bundle.OnRelease.nCommands)
    530         delete[] bundle.OnRelease.commands;
    531     }
    532     bundle.OnPress.nCommands = 0;
    533     bundle.OnHold.nCommands = 0;
    534     bundle.OnRelease.nCommands = 0;
    535   }
    536 
    537   /**
    538     @brief Loads the key and button bindings.
    539     @return True if loading succeeded.
    540   */
    541   bool KeyBinder::loadBindings()
    542   {
    543     COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
    544 
    545     // clear half axes
    546     for (unsigned int i = 0; i < nHalfAxes_s; i++)
    547     {
    548       halfAxes_[i].hasChanged = false;
    549       halfAxes_[i].abs = 0.0f;
    550       halfAxes_[i].rel = 0.0f;
    551       halfAxes_[i].wasDown = false;
    552       halfAxes_[i].threshold = 0.01f;
    553     }
    554 
    555     ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
    556     clearBindings();
    557     setConfigValues();
    558 
    559     COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
    560     return true;
     534      halfAxes_[i].clear();
     535
     536    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     537      delete paramCommandBuffer_[i];
     538    paramCommandBuffer_.clear();
    561539  }
    562540
     
    566544    for (unsigned int i = 0; i < nHalfAxes_s; i++)
    567545    {
    568       if (!halfAxes_[i].hasChanged)
    569       {
    570         if (!halfAxes_[i].wasDown && halfAxes_[i].abs > halfAxes_[i].threshold)
    571         {
    572           halfAxes_[i].wasDown = true;
    573           if (bindingsHalfAxes_[i].OnPress.nCommands)
    574             executeBinding(bindingsHalfAxes_[i].OnPress, halfAxes_[i].rel, halfAxes_[i].abs);
    575         }
    576         else if (halfAxes_[i].wasDown && halfAxes_[i].abs < halfAxes_[i].threshold)
    577         {
    578           halfAxes_[i].wasDown = false;
    579           if (bindingsHalfAxes_[i].OnRelease.nCommands)
    580             executeBinding(bindingsHalfAxes_[i].OnRelease, halfAxes_[i].rel, halfAxes_[i].abs);
    581         }
    582         if (halfAxes_[i].wasDown)
    583         {
    584           executeBinding(bindingsHalfAxes_[i].OnHold, halfAxes_[i].rel, halfAxes_[i].abs);
    585         }
    586         halfAxes_[i].hasChanged = false;
     546      if (halfAxes_[i].hasChanged_)
     547      {
     548        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
     549        {
     550          halfAxes_[i].wasDown_ = true;
     551          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
     552            halfAxes_[i].execute(KeybindMode::OnPress);
     553        }
     554        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
     555        {
     556          halfAxes_[i].wasDown_ = false;
     557          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
     558            halfAxes_[i].execute(KeybindMode::OnRelease);
     559        }
     560        if (halfAxes_[i].wasDown_)
     561        {
     562          if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
     563            halfAxes_[i].execute(KeybindMode::OnHold);
     564        }
     565        halfAxes_[i].hasChanged_ = false;
     566      }
     567
     568      // these are the actually useful axis bindings for analog input AND output
     569      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
     570      {
     571        halfAxes_[i].execute();
    587572      }
    588573    }
    589574
    590575    // execute all buffered bindings (addional parameter)
    591     for (unsigned int i = 0; i < axisCommands_.size(); i++)
    592     {
    593       if (axisCommands_[i]->nValuesAdded > 0)
    594       {
    595         axisCommands_[i]->evaluation.setEvaluatedParameter(0, axisCommands_[i]->value);
    596         // reset
    597         axisCommands_[i]->nValuesAdded = 0;
    598         axisCommands_[i]->value = 0.0f;
    599       }
    600     }
    601   }
    602 
    603   bool KeyBinder::executeBinding(KeyBinding& binding, float axisRel, float axisAbs)
    604   {
    605     // execute all the parsed commands in the string
    606     for (unsigned int iCommand = 0; iCommand < binding.nCommands; iCommand++)
    607     {
    608       SimpleCommand& command = binding.commands[iCommand];
    609       if (command.axisCommand)
    610       {
    611         AxisCommand& axisCommand = *command.axisCommand;
    612         // command has an additional parameter
    613         if (command.axisCommand->bRelative)
    614         {
    615           // we have to calculate a relative movement.
    616           // amplitude says how much one keystroke is
    617           axisCommand.value += command.axisModifier * axisRel;
    618         }
    619         else
    620         {
    621           // we have to calculate absolute position of the axis.
    622           // for a key this simply is 1, but multiplied by a user defined factor
    623           // since there might be another axis that is affected, we have to wait and
    624           // store the result in a temporary place
    625           axisCommand.value =
    626               (axisCommand.value * (axisCommand.nValuesAdded++) + command.axisModifier * axisAbs)
    627               / axisCommand.nValuesAdded;
    628         }
    629       }
    630       else
    631       {
    632         // simple command, just execute directly
    633         // TODO: calculate whether this a Press, Release or Hold event
    634         CommandExecutor::execute(command.evaluation);
    635       }
    636     }
    637     return true;
    638   }
    639 
    640 
    641   /**
    642     @brief Event handler for the keyPressed Event.
    643     @param e Event information
    644   */
    645   bool KeyBinder::keyPressed(const KeyEvent& evt)
    646   {
    647     // find the appropriate key binding
    648     executeBinding(bindingsKeys_[int(evt.key)].OnPress, 1.0, 1.0);
    649 
    650     return true;
    651   }
    652 
    653   /**
    654     @brief Event handler for the keyReleased Event.
    655     @param e Event information
    656   */
    657   bool KeyBinder::keyReleased(const KeyEvent& evt)
    658   {
    659     // find the appropriate key binding
    660     executeBinding(bindingsKeys_[int(evt.key)].OnRelease, 1.0, 1.0);
    661 
    662     return true;
    663   }
    664 
    665   /**
    666     @brief Event handler for the keyHeld Event.
    667     @param e Mouse state information
    668   */
    669   bool KeyBinder::keyHeld(const KeyEvent& evt)
    670   {
    671     // find the appropriate key binding
    672     executeBinding(bindingsKeys_[int(evt.key)].OnHold, 1.0, 1.0);
    673 
    674     return true;
    675   }
     576    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     577      paramCommandBuffer_[i]->execute();
     578
     579    // always reset the relative movement of the mouse
     580    for (unsigned int i = 0; i < 4; i++)
     581      halfAxes_[i].relVal_ = 0;
     582  }
     583
     584  void KeyBinder::keyPressed (const KeyEvent& evt)
     585  { keys_[evt.key].execute(KeybindMode::OnPress); }
     586
     587  void KeyBinder::keyReleased(const KeyEvent& evt)
     588  { keys_[evt.key].execute(KeybindMode::OnRelease); }
     589
     590  void KeyBinder::keyHeld    (const KeyEvent& evt)
     591  { keys_[evt.key].execute(KeybindMode::OnHold); }
     592
     593
     594  void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
     595  { mouseButtons_[id].execute(KeybindMode::OnPress); }
     596
     597  void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
     598  { mouseButtons_[id].execute(KeybindMode::OnRelease); }
     599
     600  void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
     601  { mouseButtons_[id].execute(KeybindMode::OnHold); }
     602
     603
     604  void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
     605  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
     606
     607  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
     608  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
     609
     610  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
     611  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
    676612
    677613  /**
     
    679615    @param e Mouse state information
    680616  */
    681   bool KeyBinder::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
    682   {
    683     halfAxes_[0].hasChanged = true;
    684     halfAxes_[1].hasChanged = true;
    685     halfAxes_[2].hasChanged = true;
    686     halfAxes_[3].hasChanged = true;
     617  void KeyBinder::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     618  {
    687619    // translate absolute mouse position into joystick like behaviour
    688620    if (clippingSize.x > clippingSize.y)
     
    691623      if (abs.x - margin > clippingSize.y)
    692624      {
    693         halfAxes_[0].abs = 1.0f;
    694         halfAxes_[1].abs = 0.0f;
     625        halfAxes_[0].absVal_ = 1.0f;
     626        halfAxes_[1].absVal_ = 0.0f;
    695627      }
    696628      else if (abs.x < margin)
    697629      {
    698         halfAxes_[0].abs = 0.0f;
    699         halfAxes_[1].abs = 1.0f;
     630        halfAxes_[0].absVal_ = 0.0f;
     631        halfAxes_[1].absVal_ = 1.0f;
    700632      }
    701633      else
     
    704636        if (temp > 0)
    705637        {
    706           halfAxes_[0].abs = temp;
    707           halfAxes_[1].abs = 0.0f;
     638          halfAxes_[0].absVal_ = temp;
     639          halfAxes_[1].absVal_ = 0.0f;
    708640        }
    709641        else
    710642        {
    711           halfAxes_[0].abs = 0.0f;
    712           halfAxes_[1].abs = -temp;
     643          halfAxes_[0].absVal_ = 0.0f;
     644          halfAxes_[1].absVal_ = -temp;
    713645        }
    714646      }
     
    717649      if (temp > 0)
    718650      {
    719         halfAxes_[2].abs = temp;
    720         halfAxes_[3].abs = 0.0;
     651        halfAxes_[2].absVal_ = temp;
     652        halfAxes_[3].absVal_ = 0.0;
    721653      }
    722654      else
    723655      {
    724         halfAxes_[2].abs = 0.0;
    725         halfAxes_[3].abs = -temp;
     656        halfAxes_[2].absVal_ = 0.0;
     657        halfAxes_[3].absVal_ = -temp;
    726658      }
    727659    }
     
    731663      if (temp > 0)
    732664      {
    733         halfAxes_[0].abs = temp;
    734         halfAxes_[1].abs = 0.0;
     665        halfAxes_[0].absVal_ = temp;
     666        halfAxes_[1].absVal_ = 0.0;
    735667      }
    736668      else
    737669      {
    738         halfAxes_[0].abs = 0.0;
    739         halfAxes_[1].abs = -temp;
     670        halfAxes_[0].absVal_ = 0.0;
     671        halfAxes_[1].absVal_ = -temp;
    740672      }
    741673
     
    743675      if (abs.y - margin > clippingSize.x)
    744676      {
    745         halfAxes_[2].abs = 0.0;
    746         halfAxes_[3].abs = 1.0;
     677        halfAxes_[2].absVal_ = 0.0;
     678        halfAxes_[3].absVal_ = 1.0;
    747679      }
    748680      else if (abs.y < margin)
    749681      {
    750         halfAxes_[2].abs = 1.0;
    751         halfAxes_[3].abs = 0.0;
     682        halfAxes_[2].absVal_ = 1.0;
     683        halfAxes_[3].absVal_ = 0.0;
    752684      }
    753685      else
     
    756688        if (temp > 0)
    757689        {
    758           halfAxes_[2].abs = temp;
    759           halfAxes_[3].abs = 0.0;
     690          halfAxes_[2].absVal_ = temp;
     691          halfAxes_[3].absVal_ = 0.0;
    760692        }
    761693        else
    762694        {
    763           halfAxes_[2].abs = 0.0;
    764           halfAxes_[3].abs = -temp;
    765         }
    766       }
    767     }
    768    
     695          halfAxes_[2].absVal_ = 0.0;
     696          halfAxes_[3].absVal_ = -temp;
     697        }
     698      }
     699    }
     700
    769701    // relative movements
    770702    if (rel.x > 0)
    771703    {
    772       halfAxes_[0].rel = rel.x;
    773       halfAxes_[1].rel = 0.0;
    774     }
    775     else
    776     {
    777       halfAxes_[0].rel = 0.0;
    778       halfAxes_[1].rel = rel.x;
     704      halfAxes_[0].hasChanged_ = true;
     705      halfAxes_[1].hasChanged_ = true;
     706      halfAxes_[0].relVal_ = rel.x;
     707      halfAxes_[1].relVal_ = 0.0;
     708    }
     709    else if (rel.x < 0)
     710    {
     711      halfAxes_[0].hasChanged_ = true;
     712      halfAxes_[1].hasChanged_ = true;
     713      halfAxes_[0].relVal_ = 0.0;
     714      halfAxes_[1].relVal_ = rel.x;
    779715    }
    780716
    781717    if (rel.y /*!*/ < /*!*/ 0)
    782718    {
    783       halfAxes_[0].rel = -rel.y;
    784       halfAxes_[1].rel = 0.0;
    785     }
    786     else
    787     {
    788       halfAxes_[0].rel = 0.0;
    789       halfAxes_[1].rel = -rel.y;
    790     }
    791 
    792     return true;
     719      halfAxes_[2].hasChanged_ = true;
     720      halfAxes_[3].hasChanged_ = true;
     721      halfAxes_[0].relVal_ = -rel.y;
     722      halfAxes_[1].relVal_ = 0.0;
     723    }
     724    else if (rel.y > 0)
     725    {
     726      halfAxes_[2].hasChanged_ = true;
     727      halfAxes_[3].hasChanged_ = true;
     728      halfAxes_[0].relVal_ = 0.0;
     729      halfAxes_[1].relVal_ = -rel.y;
     730    }
    793731  }
    794732
     
    797735    @param e Mouse state information
    798736  */
    799   bool KeyBinder::mouseScrolled(int abs, int rel)
     737  void KeyBinder::mouseScrolled(int abs, int rel)
    800738  {
    801739    // TODO: obvious...
    802     return true;
    803   }
    804 
    805   /**
    806     @brief Event handler for the mousePressed Event.
    807     @param e Event information
    808     @param id The ID of the mouse button
    809   */
    810   bool KeyBinder::mouseButtonPressed(MouseButton::Enum id)
    811   {
    812     // find the appropriate key binding
    813     executeBinding(bindingsMouseButtons_[int(id)].OnPress, 1.0, 1.0);
    814 
    815     return true;
    816   }
    817 
    818   /**
    819     @brief Event handler for the mouseReleased Event.
    820     @param e Event information
    821     @param id The ID of the mouse button
    822   */
    823   bool KeyBinder::mouseButtonReleased(MouseButton::Enum id)
    824   {
    825     // find the appropriate key binding
    826     executeBinding(bindingsMouseButtons_[int(id)].OnRelease, 1.0, 1.0);
    827 
    828     return true;
    829   }
    830 
    831   /**
    832     @brief Event handler for the mouseHeld Event.
    833     @param e Event information
    834     @param id The ID of the mouse button
    835   */
    836   bool KeyBinder::mouseButtonHeld(MouseButton::Enum id)
    837   {
    838     // find the appropriate key binding
    839     executeBinding(bindingsMouseButtons_[int(id)].OnHold, 1.0, 1.0);
    840 
    841     return true;
    842   }
    843 
    844   bool KeyBinder::joyStickButtonPressed(int joyStickID, int button)
    845   {
    846     // find the appropriate key binding
    847     executeBinding(bindingsJoyStickButtons_[button].OnPress, 1.0, 1.0);
    848 
    849     return true;
    850   }
    851 
    852   bool KeyBinder::joyStickButtonReleased(int joyStickID, int button)
    853   {
    854     // find the appropriate key binding
    855     executeBinding(bindingsJoyStickButtons_[button].OnRelease, 1.0, 1.0);
    856 
    857     return true;
    858   }
    859 
    860   bool KeyBinder::joyStickButtonHeld(int joyStickID, int button)
    861   {
    862     // find the appropriate key binding
    863     executeBinding(bindingsJoyStickButtons_[button].OnHold, 1.0, 1.0);
    864 
    865     return true;
    866   }
    867 
    868   bool KeyBinder::joyStickAxisMoved(int joyStickID, int axis, int value)
     740  }
     741
     742  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, int value)
    869743  {
    870744    // TODO: check whether 16 bit integer as general axis value is a good idea (works under windows)
    871     halfAxes_[8 + axis].hasChanged = true;
     745    //CCOUT(3) << axis << std::endl;
    872746    if (value >= 0)
    873747    {
    874       halfAxes_[8 + axis].abs = ((float)value)/0x1000;
    875       halfAxes_[8 + axis].hasChanged = true;
     748      halfAxes_[8 + axis].absVal_ = ((float)value)/0x8000;
     749      halfAxes_[8 + axis].relVal_ = ((float)value)/0x8000;
     750      halfAxes_[8 + axis].hasChanged_ = true;
    876751    }
    877752    else
    878753    {
    879       halfAxes_[8 + axis + 1].abs = -((float)value)/0x1000;
    880       halfAxes_[8 + axis + 1].hasChanged = true;
    881     }
    882     return true;
     754      halfAxes_[8 + axis + 1].absVal_ = -((float)value)/0x8000;
     755      halfAxes_[8 + axis + 1].relVal_ = -((float)value)/0x8000;
     756      halfAxes_[8 + axis + 1].hasChanged_ = true;
     757    }
    883758  }
    884759
  • code/branches/input/src/core/InputHandler.h

    r1323 r1340  
    3838
    3939#include <string>
     40#include <vector>
    4041
    4142#include "ois/OIS.h"
     
    4748namespace orxonox
    4849{
    49   struct _CoreExport AxisCommand
    50   {
    51     std::string commandStr;
    52     CommandEvaluation evaluation;
    53     bool bRelative;
    54     float value;
    55     unsigned int nValuesAdded;
    56   };
    57 
    58   struct _CoreExport SimpleCommand
    59   {
    60     // for simple binding; direct
    61     std::string commandStr;
    62     CommandEvaluation evaluation;
    63 
    64     // axis binding; buffered
    65     AxisCommand* axisCommand;
    66     float axisModifier;
    67   };
    68 
    69   struct _CoreExport KeyBinding
    70   {
    71     void clear() { commands = 0; nCommands = 0; }
    72     SimpleCommand* commands;
    73     unsigned int nCommands;
    74   };
    75 
    76   struct _CoreExport KeyBindingBundle
    77   {
    78     KeyBinding OnPress;
    79     KeyBinding OnRelease;
    80     KeyBinding OnHold;
    81   };
    82 
    83   struct _CoreExport HalfAxis
    84   {
    85     float rel;
    86     float abs;
    87     float threshold;
    88     bool wasDown;
    89     bool hasChanged;
     50  class _CoreExport BaseCommand
     51  {
     52  public:
     53    virtual ~BaseCommand() { }
     54    virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
     55  };
     56
     57  class _CoreExport BufferedParamCommand
     58  {
     59  public:
     60    BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
     61    bool execute();
     62    float value_;
     63    unsigned int nValuesAdded_;
     64    int paramIndex_;
     65    CommandEvaluation evaluation_;
     66  };
     67
     68  class _CoreExport SimpleCommand : public BaseCommand
     69  {
     70  public:
     71    bool execute(float abs = 1.0f, float rel = 1.0f);
     72
     73    CommandEvaluation evaluation_;
     74  };
     75
     76  class _CoreExport ParamCommand : public BaseCommand
     77  {
     78  public:
     79    ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
     80    bool execute(float abs = 1.0f, float rel = 1.0f);
     81
     82    bool bRelative_;
     83    float paramModifier_;
     84    BufferedParamCommand* paramCommand_;
     85  };
     86
     87  class _CoreExport Button
     88  {
     89  public:
     90    Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }
     91    virtual ~Button() { clear(); }
     92    virtual void clear();
     93    virtual bool addParamCommand(ParamCommand* command) { return false; }
     94    void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
     95    bool execute(KeybindMode::Enum mode);
     96
     97    //! The configured string value
     98    std::string bindingString_;
     99    //! Name of the trigger as strings
     100    std::string name_;
     101    //! Basic commands for OnPress, OnHold and OnRelease
     102    BaseCommand** commands_[3];
     103    //! Number of basic commands
     104    unsigned int nCommands_[3];
     105    //! Says how much it takes for an analog axis to trigger a button
     106    //! Note: This variable is here to have only one parse() function.
     107    float buttonThreshold_;
     108  };
     109
     110
     111  class _CoreExport HalfAxis : public Button
     112  {
     113  public:
     114    HalfAxis() : relVal_(0.0f), absVal_(0.0f), paramCommands_(0), nParamCommands_(0),
     115                 wasDown_(false), hasChanged_(false) { }
     116    bool execute();
     117    bool execute(KeybindMode::Enum mode) { return Button::execute(mode); }
     118    bool addParamCommand(ParamCommand* command);
     119    void clear();
     120
     121    // axis related
     122    float relVal_;
     123    float absVal_;
     124    ParamCommand** paramCommands_;
     125    unsigned int nParamCommands_;
     126
     127    // button related
     128    bool wasDown_;
     129    bool hasChanged_;
    90130  };
    91131
    92132
    93133  /**
    94     @brief Captures mouse, keyboard and joy stick input while in the actual game mode.
     134    @brief Handles mouse, keyboard and joy stick input while in the actual game mode.
    95135           Manages the key bindings.
    96136  */
     
    101141    ~KeyBinder();
    102142
    103     bool loadBindings();
     143    void loadBindings();
    104144    void clearBindings(bool bInit = false);
    105145
     
    107147
    108148  private: // functions
    109     bool readBindings(std::string* names, std::string* bindingStrings, KeyBindingBundle* bindings, unsigned int size);
    110     bool executeBinding(KeyBinding& binding, float axisRel, float axisAbs);
    111     void clearBundle(KeyBindingBundle& bundle, bool bInit);
     149    void readTrigger(Button& button);
     150
     151    //static void clearBundle(KeyBindingBundle& bundle, bool bInit);
     152    //static void redimensionBinding(KeyBinding& binding);
    112153
    113154    void tick(float dt);
    114155
    115     bool keyPressed (const KeyEvent& evt);
    116     bool keyReleased(const KeyEvent& evt);
    117     bool keyHeld    (const KeyEvent& evt);
    118 
    119     bool mouseButtonPressed (MouseButton::Enum id);
    120     bool mouseButtonReleased(MouseButton::Enum id);
    121     bool mouseButtonHeld    (MouseButton::Enum id);
    122     bool mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
    123     bool mouseScrolled      (int abs, int rel);
    124 
    125     bool joyStickButtonPressed (int joyStickID, int button);
    126     bool joyStickButtonReleased(int joyStickID, int button);
    127     bool joyStickButtonHeld    (int joyStickID, int button);
    128     bool joyStickAxisMoved     (int joyStickID, int axis, int value)  ;
     156    void keyPressed (const KeyEvent& evt);
     157    void keyReleased(const KeyEvent& evt);
     158    void keyHeld    (const KeyEvent& evt);
     159
     160    void mouseButtonPressed (MouseButton::Enum id);
     161    void mouseButtonReleased(MouseButton::Enum id);
     162    void mouseButtonHeld    (MouseButton::Enum id);
     163    void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
     164    void mouseScrolled      (int abs, int rel);
     165
     166    void joyStickButtonPressed (int joyStickID, int button);
     167    void joyStickButtonReleased(int joyStickID, int button);
     168    void joyStickButtonHeld    (int joyStickID, int button);
     169    void joyStickAxisMoved     (int joyStickID, int axis, int value);
    129170
    130171  private: // variables
     
    132173    static const unsigned int nKeys_s = 0xEE;
    133174    //! Actual key bindings as bundle for Press, Hold and Release
    134     KeyBindingBundle bindingsKeys_ [nKeys_s];
    135     //! Names of the keys as strings
    136     std::string namesKeys_         [nKeys_s];
    137     //! The configured string values
    138     std::string bindingStringsKeys_[nKeys_s];
     175    Button keys_ [nKeys_s];
    139176
    140177    //! denotes the number of different mouse buttons there are in OIS.
    141178    static const unsigned int nMouseButtons_s = 8;
    142179    //! Actual key bindings as bundle for Press, Hold and Release
    143     KeyBindingBundle bindingsMouseButtons_ [nMouseButtons_s];
    144     //! Names of the mouse buttons as strings
    145     std::string namesMouseButtons_         [nMouseButtons_s];
    146     //! The configured string values
    147     std::string bindingStringsMouseButtons_[nMouseButtons_s];
     180    Button mouseButtons_ [nMouseButtons_s];
    148181
    149182    //! denotes the number of different joy stick buttons there are in OIS.
    150183    static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons
    151184    //! Actual key bindings as bundle for Press, Hold and Release
    152     KeyBindingBundle bindingsJoyStickButtons_ [nJoyStickButtons_s];
    153     //! Names of the joy stick buttons as strings
    154     std::string namesJoyStickButtons_         [nJoyStickButtons_s];
    155     //! The configured string values
    156     std::string bindingStringsJoyStickButtons_[nJoyStickButtons_s];
     185    Button joyStickButtons_ [nJoyStickButtons_s];
    157186
    158187    //! denotes the number of half axes (every axis twice) there can be.
     
    160189    /**
    161190    * Array with all the half axes for mouse and joy sticks.
    162     * Bear in mind that the positions are fixed and that the first entry is the
     191    * Keep in mind that the positions are fixed and that the first entry is the
    163192    * positive one and the second is negative.
    164193    * Sequence is as follows:
     
    169198    */
    170199    HalfAxis halfAxes_[nHalfAxes_s];
    171     //! Actual key bindings as bundle for Press, Hold and Release
    172     KeyBindingBundle bindingsHalfAxes_ [nHalfAxes_s];
    173     //! Names of the half axes
    174     std::string namesHalfAxes_         [nHalfAxes_s];
    175     //! The configured string values
    176     std::string bindingStringsHalfAxes_[nHalfAxes_s];
    177200
    178201    /**
     
    180203    * the tick() so that all values can be buffered for single execution.
    181204    */
    182     std::vector<AxisCommand*> axisCommands_;
     205    std::vector<BufferedParamCommand*> paramCommandBuffer_;
     206
     207    //! Threshold for analog triggers until which the state is 0.
     208    float analogThreshold_;
     209    //! Threshold for analog triggers until which the button is not pressed.
     210    float buttonThreshold_;
    183211  };
    184212
  • code/branches/input/src/core/InputInterfaces.h

    r1323 r1340  
    269269  public:
    270270    virtual ~KeyHandler() { }
    271     virtual bool keyPressed (const KeyEvent& evt) = 0;
    272     virtual bool keyReleased(const KeyEvent& evt) = 0;
    273     virtual bool keyHeld    (const KeyEvent& evt) = 0;
     271    virtual void keyPressed (const KeyEvent& evt) = 0;
     272    virtual void keyReleased(const KeyEvent& evt) = 0;
     273    virtual void keyHeld    (const KeyEvent& evt) = 0;
    274274  };
    275275
     
    281281  public:
    282282    virtual ~MouseHandler() { }
    283     virtual bool mouseButtonPressed (MouseButton::Enum id) = 0;
    284     virtual bool mouseButtonReleased(MouseButton::Enum id) = 0;
    285     virtual bool mouseButtonHeld    (MouseButton::Enum id) = 0;
    286     virtual bool mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
    287     virtual bool mouseScrolled      (int abs, int rel)     = 0;
     283    virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
     284    virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
     285    virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
     286    virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
     287    virtual void mouseScrolled      (int abs, int rel)     = 0;
    288288  };
    289289
     
    296296  public:
    297297    virtual ~JoyStickHandler() { }
    298     virtual bool joyStickButtonPressed (int joyStickID, int button) = 0;
    299     virtual bool joyStickButtonReleased(int joyStickID, int button) = 0;
    300     virtual bool joyStickButtonHeld    (int joyStickID, int button) = 0;
    301     virtual bool joyStickAxisMoved     (int joyStickID, int axis, int value) = 0;
     298    virtual void joyStickButtonPressed (int joyStickID, int button) = 0;
     299    virtual void joyStickButtonReleased(int joyStickID, int button) = 0;
     300    virtual void joyStickButtonHeld    (int joyStickID, int button) = 0;
     301    virtual void joyStickAxisMoved     (int joyStickID, int axis, int value) = 0;
    302302    //virtual bool joyStickVector3Moved  (int joyStickID, int index /*, fill list*/) {return true;}
    303303  };
  • code/branches/input/src/core/InputManager.cc

    r1323 r1340  
    400400          // normal play mode
    401401          // note: we assume that the handlers exist since otherwise, something's wrong anyway.
    402           activeKeyHandlers_.push_back(keyHandlers_["keybinder"]);
    403           activeMouseHandlers_.push_back(mouseHandlers_["keybinder"]);
    404           if (getMouseHandler("SpaceShip"))
    405             activeMouseHandlers_.push_back(mouseHandlers_["SpaceShip"]);
    406           for (unsigned int i = 0; i < joySticksSize_; i++)
    407             activeJoyStickHandlers_[i].push_back(joyStickHandlers_["keybinder"]);
     402          enableKeyHandler("keybinder");
     403          enableMouseHandler("keybinder");
     404          enableMouseHandler("SpaceShip");
     405          enableJoyStickHandler("keybinder", 0);
    408406          break;
    409407
     
    413411
    414412        case IS_CONSOLE:
    415           activeMouseHandlers_.push_back(mouseHandlers_["keybinder"]);
    416           if (getMouseHandler("SpaceShip"))
    417             activeMouseHandlers_.push_back(mouseHandlers_["SpaceShip"]);
    418           for (unsigned int i = 0; i < joySticksSize_; i++)
    419             activeJoyStickHandlers_[i].push_back(joyStickHandlers_["keybinder"]);
    420 
    421           activeKeyHandlers_.push_back(keyHandlers_["buffer"]);
     413          enableMouseHandler("keybinder");
     414          enableMouseHandler("SpaceShip");
     415          enableJoyStickHandler("keybinder", 0);
     416          enableKeyHandler("buffer");
    422417          break;
    423418
  • code/branches/input/src/orxonox/Orxonox.cc

    r1293 r1340  
    8383namespace orxonox
    8484{
    85   ConsoleCommandShortcut(Orxonox, exit, AccessLevel::None);
    86   ConsoleCommandShortcut(Orxonox, slomo, AccessLevel::Offline).setDefaultValue(0, 1.0);
     85  ConsoleCommandShortcut(Orxonox, exit, AccessLevel::None).setKeybindMode(KeybindMode::OnPress);
     86  ConsoleCommandShortcut(Orxonox, slomo, AccessLevel::Offline).setDefaultValue(0, 1.0)
     87    .setAxisParamIndex(0).setIsAxisRelative(false);
    8788  ConsoleCommandShortcut(Orxonox, setTimeFactor, AccessLevel::Offline).setDefaultValue(0, 1.0);
    8889  ConsoleCommandShortcut(Orxonox, activateConsole, AccessLevel::None);
  • code/branches/input/src/orxonox/objects/SpaceShip.cc

    r1323 r1340  
    296296    }
    297297
    298     bool SpaceShip::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     298    void SpaceShip::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
    299299    {
    300300/*
     
    352352            this->mouseYRotation_ = Radian(yRotation);
    353353        }
    354 
    355         return true;
    356     }
    357 
    358     bool SpaceShip::mouseButtonPressed(MouseButton::Enum id)
     354    }
     355
     356    void SpaceShip::mouseButtonPressed(MouseButton::Enum id)
    359357    {
    360358        if (id == MouseButton::Left)
     
    362360        else if (id == MouseButton::Right)
    363361            this->bRMousePressed_ = true;
    364 
    365         return true;
    366     }
    367 
    368     bool SpaceShip::mouseButtonReleased(MouseButton::Enum id)
     362    }
     363
     364    void SpaceShip::mouseButtonReleased(MouseButton::Enum id)
    369365    {
    370366        if (id == MouseButton::Left)
     
    375371            this->camNode_->resetOrientation();
    376372        }
    377 
    378         return true;
    379373    }
    380374
  • code/branches/input/src/orxonox/objects/SpaceShip.h

    r1323 r1340  
    6767                { SpaceShip::instance_s->setMaxSpeed(value); }
    6868
    69             bool mouseButtonPressed (MouseButton::Enum id);
    70             bool mouseButtonReleased(MouseButton::Enum id);
    71             bool mouseButtonHeld    (MouseButton::Enum id) { return true; }
    72             bool mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
    73             bool mouseScrolled      (int abs, int rel) { return true; }
     69            void mouseButtonPressed (MouseButton::Enum id);
     70            void mouseButtonReleased(MouseButton::Enum id);
     71            void mouseButtonHeld    (MouseButton::Enum id) { }
     72            void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
     73            void mouseScrolled      (int abs, int rel) { }
    7474
    7575
Note: See TracChangeset for help on using the changeset viewer.