Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/core/KeyBinder.cc @ 1413

Last change on this file since 1413 was 1413, checked in by rgrieder, 16 years ago
  • renamed InputHandler to KeyBinder
  • added feature to detect a key in input part
  • added def_keybindings.ini and removed keybindings.ini
File size: 25.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30 @file
31 @brief Implementation of the different input handlers.
32 */
33
34#include "KeyBinder.h"
35#include <fstream>
36#include "util/Convert.h"
37#include "util/SubString.h"
38#include "util/String.h"
39#include "Debug.h"
40#include "ConfigValueIncludes.h"
41#include "CoreIncludes.h"
42#include "CommandExecutor.h"
43#include "Executor.h"
44
45namespace orxonox
46{
47  // ###############################
48  // ######      Button       ######
49  // ###############################
50
51  bool BufferedParamCommand::execute()
52  {
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 CommandExecutor::execute(cmd.evaluation_);
61    }
62    else
63      return true;
64  }
65
66  bool SimpleCommand::execute(float abs, float rel)
67  {
68    return CommandExecutor::execute(evaluation_);
69  }
70
71  bool ParamCommand::execute(float abs, float rel)
72  {
73    BufferedParamCommand& paramCommand = *paramCommand_;
74    // command has an additional parameter
75    if (bRelative_ && (rel > 0 || rel < 0))
76    {
77      // we have to calculate a relative movement.
78      // paramModifier_ says how much one keystroke is
79      paramCommand.value_ += paramModifier_ * rel;
80    }
81    else if (abs > 0 || abs < 0)
82    {
83      // we have to calculate absolute position of the axis.
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]) == "scale")
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, float abs, float rel)
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(abs, rel);
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  // ###############################
302  // ######     KeyBinder     ######
303  // ###############################
304
305  /**
306    @brief Constructor that does as little as necessary.
307  */
308  KeyBinder::KeyBinder() : deriveTime_(0.0f)
309  {
310    mouseRelative_[0] = 0;
311    mouseRelative_[1] = 0;
312    mousePosition_[0] = 0;
313    mousePosition_[1] = 0;
314
315    RegisterObject(KeyBinder);
316
317    // keys
318    std::string keyNames[] = {
319      "UNASSIGNED",
320      "ESCAPE",
321      "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
322      "MINUS", "EQUALS", "BACK", "TAB",
323      "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
324      "LBRACKET", "RBRACKET",
325      "RETURN", "LCONTROL",
326      "A", "S", "D", "F", "G", "H", "J", "K", "L",
327      "SEMICOLON", "APOSTROPHE", "GRAVE",
328      "LSHIFT", "BACKSLASH",
329      "Z", "X", "C", "V", "B", "N", "M",
330      "COMMA", "PERIOD", "SLASH",
331      "RSHIFT",
332      "MULTIPLY",
333      "LMENU",
334      "SPACE",
335      "CAPITAL",
336      "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
337      "NUMLOCK", "SCROLL",
338      "NUMPAD7", "NUMPAD8", "NUMPAD9",
339      "SUBTRACT",
340      "NUMPAD4", "NUMPAD5", "NUMPAD6",
341      "ADD",
342      "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
343      "DECIMAL",
344      "","",
345      "OEM_102",
346      "F11", "F12",
347      "","","","","","","","","","","",
348      "F13", "F14", "F15",
349      "","","","","","","","","","",
350      "KANA",
351      "","",
352      "ABNT_C1",
353      "","","","","",
354      "CONVERT",
355      "",
356      "NOCONVERT",
357      "",
358      "YEN",
359      "ABNT_C2",
360      "","","","","","","","","","","","","","",
361      "NUMPADEQUALS",
362      "","",
363      "PREVTRACK",
364      "AT",
365      "COLON", "UNDERLINE",
366      "KANJI",
367      "STOP",
368      "AX",
369      "UNLABELED",
370      "NEXTTRACK",
371      "","",
372      "NUMPADENTER",
373      "RCONTROL",
374      "","",
375      "MUTE",
376      "CALCULATOR",
377      "PLAYPAUSE",
378      "",
379      "MEDIASTOP",
380      "","","","","","","","","",
381      "VOLUMEDOWN",
382      "",
383      "VOLUMEUP",
384      "",
385      "WEBHOME",
386      "NUMPADCOMMA",
387      "",
388      "DIVIDE",
389      "",
390      "SYSRQ",
391      "RMENU",
392      "","","","","","","","","","","","",
393      "PAUSE",
394      "",
395      "HOME",
396      "UP",
397      "PGUP",
398      "",
399      "LEFT",
400      "",
401      "RIGHT",
402      "",
403      "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
404      "","","","","","","",
405      "LWIN", "RWIN", "APPS",
406      "POWER", "SLEEP",
407      "","","",
408      "WAKE",
409      "",
410      "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
411      "MYCOMPUTER", "MAIL", "MEDIASELECT"
412    };
413    for (unsigned int i = 0; i < nKeys_s; i++)
414      keys_[i].name_ = "Key" + keyNames[i];
415
416    // mouse buttons
417    std::string mouseButtonNames[] = {
418      "MouseLeft", "MouseRight", "MouseMiddle",
419      "MouseButton3", "MouseButton4", "MouseButton5",
420      "MouseButton6", "MouseButton7",
421      "MouseWheel1Up", "MouseWheel1Down",
422      "MouseWheel2Up", "MouseWheel2Down" };
423    for (unsigned int i = 0; i < nMouseButtons_s; i++)
424      mouseButtons_[i].name_ = mouseButtonNames[i];
425
426    // joy stick buttons
427    for (unsigned int i = 0; i < 32; i++)
428      joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
429    for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
430    {
431                  joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
432                  joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
433                  joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
434                  joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
435    }
436
437    // half axes
438    std::string rawNames[nHalfAxes_s/2];
439    rawNames[0] = "MouseX";
440    rawNames[1] = "MouseY";
441    rawNames[2] = "Empty1";
442    rawNames[3] = "Empty2";
443    for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
444      rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3);
445    for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
446    {
447      halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
448      halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
449    }
450
451    for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
452      halfAxes_[i].buttonThreshold_ = buttonThreshold_;
453  }
454
455  /**
456    @brief Destructor
457  */
458  KeyBinder::~KeyBinder()
459  {
460    // almost no destructors required because most of the arrays are static.
461    clearBindings(); // does some destruction work
462  }
463
464  /**
465    @brief Loads the key and button bindings.
466    @return True if loading succeeded.
467  */
468  void KeyBinder::loadBindings()
469  {
470    COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
471
472    clearBindings();
473
474    std::ifstream infile;
475    infile.open("keybindings.ini");
476    if (!infile.is_open())
477    {
478      ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, keybindingsDefault_);
479      ConfigFileManager::getSingleton()->save(CFT_Keybindings, "keybindings.ini");
480    }
481    infile.close();
482    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
483
484    // parse key bindings
485    setConfigValues();
486
487    COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
488  }
489
490  /**
491    @brief Loader for the key bindings, managed by config values.
492  */
493  void KeyBinder::setConfigValues()
494  {
495    SetConfigValue(analogThreshold_, 0.01f)  .description("Threshold for analog axes until which the state is 0.");
496    SetConfigValue(mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
497    SetConfigValue(bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
498    SetConfigValue(derivePeriod_, 0.1f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
499    SetConfigValue(mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived.");
500    SetConfigValue(keybindingsDefault_, "def_keybindings.ini").description("Default ini file for the keybindings.");
501
502    float oldThresh = buttonThreshold_;
503    SetConfigValue(buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
504    if (oldThresh != buttonThreshold_)
505      for (unsigned int i = 0; i < nHalfAxes_s; i++)
506        if (halfAxes_[i].buttonThreshold_ == oldThresh)
507          halfAxes_[i].buttonThreshold_ = buttonThreshold_;
508
509    // keys
510    for (unsigned int i = 0; i < nKeys_s; i++)
511      readTrigger(keys_[i]);
512    // mouse buttons
513    for (unsigned int i = 0; i < nMouseButtons_s; i++)
514      readTrigger(mouseButtons_[i]);
515    // joy stick buttons
516    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
517      readTrigger(joyStickButtons_[i]);
518    // half axes
519    for (unsigned int i = 0; i < nHalfAxes_s; i++)
520      readTrigger(halfAxes_[i]);
521  }
522
523  void KeyBinder::readTrigger(Button& button)
524  {
525    // config value stuff
526    ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer(button.name_);
527    if (!cont)
528    {
529      cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), button.name_, "");
530      getIdentifier()->addConfigValueContainer(button.name_, cont);
531    }
532    std::string old = button.bindingString_;
533    cont->getValue(&button.bindingString_);
534
535    // keybinder stuff
536    if (old != button.bindingString_)
537    {
538      // binding has changed
539      button.parse(paramCommandBuffer_);
540    }
541  }
542
543  /**
544    @brief Overwrites all bindings with ""
545  */
546  void KeyBinder::clearBindings()
547  {
548    for (unsigned int i = 0; i < nKeys_s; i++)
549      keys_[i].clear();
550
551    for (unsigned int i = 0; i < nMouseButtons_s; i++)
552      mouseButtons_[i].clear();
553
554    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
555      joyStickButtons_[i].clear();
556
557    for (unsigned int i = 0; i < nHalfAxes_s; i++)
558      halfAxes_[i].clear();
559
560    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
561      delete paramCommandBuffer_[i];
562    paramCommandBuffer_.clear();
563  }
564
565  void KeyBinder::tickInput(float dt, const HandlerState& state)
566  {
567    // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
568    unsigned int iBegin = 8;
569    unsigned int iEnd   = 8;
570    if (state.joyStick)
571      iEnd = nHalfAxes_s;
572    if (state.mouse)
573      iBegin = 0;
574    for (unsigned int i = iBegin; i < iEnd; i++)
575    {
576      if (halfAxes_[i].hasChanged_)
577      {
578        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
579        {
580          halfAxes_[i].wasDown_ = true;
581          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
582            halfAxes_[i].execute(KeybindMode::OnPress);
583        }
584        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
585        {
586          halfAxes_[i].wasDown_ = false;
587          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
588            halfAxes_[i].execute(KeybindMode::OnRelease);
589        }
590        if (halfAxes_[i].wasDown_)
591        {
592          if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
593            halfAxes_[i].execute(KeybindMode::OnHold);
594        }
595        halfAxes_[i].hasChanged_ = false;
596      }
597
598      // these are the actually useful axis bindings for analog input AND output
599      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
600      {
601        //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
602        halfAxes_[i].execute();
603      }
604    }
605
606    if (bDeriveMouseInput_ && state.mouse)
607    {
608      if (deriveTime_ > derivePeriod_)
609      {
610        //CCOUT(3) << "mouse abs: ";
611        for (int i = 0; i < 2; i++)
612        {
613          if (mouseRelative_[i] > 0)
614          {
615            halfAxes_[2*i + 0].absVal_ =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
616            halfAxes_[2*i + 1].absVal_ = 0.0f;
617          }
618          else if (mouseRelative_[i] < 0)
619          {
620            halfAxes_[2*i + 0].absVal_ = 0.0f;
621            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
622          }
623          else
624          {
625            halfAxes_[2*i + 0].absVal_ = 0.0f;
626            halfAxes_[2*i + 1].absVal_ = 0.0f;
627          }
628          //COUT(3) << mouseRelative_[i] << " | ";
629          mouseRelative_[i] = 0;
630        }
631        deriveTime_ = 0.0f;
632        //COUT(3) << std::endl;
633      }
634      else
635        deriveTime_ += dt;
636    }
637
638    // execute all buffered bindings (addional parameter)
639    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
640      paramCommandBuffer_[i]->execute();
641
642    // always reset the relative movement of the mouse
643    if (state.mouse)
644      for (unsigned int i = 0; i < 8; i++)
645        halfAxes_[i].relVal_ = 0.0f;
646  }
647
648  void KeyBinder::keyPressed (const KeyEvent& evt)
649  { keys_[evt.key].execute(KeybindMode::OnPress); }
650
651  void KeyBinder::keyReleased(const KeyEvent& evt)
652  { keys_[evt.key].execute(KeybindMode::OnRelease); }
653
654  void KeyBinder::keyHeld    (const KeyEvent& evt)
655  { keys_[evt.key].execute(KeybindMode::OnHold); }
656
657
658  void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
659  { mouseButtons_[id].execute(KeybindMode::OnPress); }
660
661  void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
662  { mouseButtons_[id].execute(KeybindMode::OnRelease); }
663
664  void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
665  { mouseButtons_[id].execute(KeybindMode::OnHold); }
666
667
668  void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
669  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
670
671  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
672  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
673
674  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
675  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
676
677  /**
678    @brief Event handler for the mouseMoved Event.
679    @param e Mouse state information
680  */
681  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
682  {
683    if (!bDeriveMouseInput_)
684    {
685      // y axis of mouse input is inverted
686      int rel[] = { rel_.x, -rel_.y };
687
688      //COUT(3) << rel[0] << " | " << rel[1] << std::endl;
689
690      for (int i = 0; i < 2; i++)
691      {
692        if (rel[i])
693        {
694          // absolute
695          if (mousePosition_[i] >= 0)
696          {
697            mousePosition_[i] += rel[i];
698            halfAxes_[0 + 2*i].hasChanged_ = true;
699            if (mousePosition_[i] < 0)
700            {
701              halfAxes_[1 + 2*i].hasChanged_ = true;
702              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024 * mouseSensitivity_;
703              halfAxes_[0 + 2*i].absVal_ =  0.0f;
704            }
705            else
706              halfAxes_[0 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024 * mouseSensitivity_;
707          }
708          else
709          {
710            mousePosition_[i] += rel[i];
711            halfAxes_[1 + 2*i].hasChanged_ = true;
712            if (mousePosition_[i] > 0)
713            {
714              halfAxes_[0 + 2*i].hasChanged_ = true;
715              halfAxes_[0 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024 * mouseSensitivity_;
716              halfAxes_[1 + 2*i].absVal_ =  0.0f;
717            }
718            else
719              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024 * mouseSensitivity_;
720          }
721          //COUT(3) << "half axis 0: " << halfAxes_[0].absVal_ << std::endl;
722          //COUT(3) << "half axis 1: " << halfAxes_[1].absVal_ << std::endl;
723          //COUT(3) << "half axis 2: " << halfAxes_[2].absVal_ << std::endl;
724          //COUT(3) << "half axis 3: " << halfAxes_[3].absVal_ << std::endl;
725
726          // relative
727          if (rel[i] > 0)
728            halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
729          else
730            halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
731        }
732      }
733    }
734    else
735    {
736      mouseRelative_[0] += rel_.x;
737      mouseRelative_[1] -= rel_.y;
738    }
739  }
740
741  /**
742    @brief Event handler for the mouseScrolled Event.
743    @param e Mouse state information
744  */
745  void KeyBinder::mouseScrolled(int abs, int rel)
746  {
747    //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
748
749    if (rel > 0)
750      for (int i = 0; i < rel/120; i++)
751        mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
752    else
753      for (int i = 0; i < -rel/120; i++)
754        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
755  }
756
757  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, int value)
758  {
759    // TODO: check whether 16 bit integer as general axis value is a good idea (works under windows)
760    int i = 8 + axis * 2;
761    if (value >= 0)
762    {
763      //if (value > 10000)
764      //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
765
766      halfAxes_[i].absVal_ = ((float)value)/0x8000;
767      halfAxes_[i].relVal_ = ((float)value)/0x8000;
768      halfAxes_[i].hasChanged_ = true;
769      if (halfAxes_[i + 1].absVal_ > 0)
770      {
771        halfAxes_[i + 1].absVal_ = -0.0f;
772        halfAxes_[i + 1].relVal_ = -0.0f;
773        halfAxes_[i + 1].hasChanged_ = true;
774      }
775    }
776    else
777    {
778      //if (value < -10000)
779      //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
780
781      halfAxes_[i + 1].absVal_ = -((float)value)/0x8000;
782      halfAxes_[i + 1].relVal_ = -((float)value)/0x8000;
783      halfAxes_[i + 1].hasChanged_ = true;
784      if (halfAxes_[i].absVal_ > 0)
785      {
786        halfAxes_[i].absVal_ = -0.0f;
787        halfAxes_[i].relVal_ = -0.0f;
788        halfAxes_[i].hasChanged_ = true;
789      }
790    }
791  }
792
793
794  // ###############################
795  // #####     KeyDetector     #####
796  // ###############################
797
798  /**
799    @brief Constructor
800  */
801  KeyDetector::KeyDetector()
802  {
803    RegisterObject(KeyDetector);
804  }
805
806  /**
807    @brief Destructor
808  */
809  KeyDetector::~KeyDetector()
810  {
811  }
812
813  /**
814    @brief Loads the key and button bindings.
815    @return True if loading succeeded.
816  */
817  void KeyDetector::loadBindings()
818  {
819    clearBindings();
820    setConfigValues();
821  }
822
823  /**
824    @brief Loader for the key bindings, managed by config values.
825  */
826  void KeyDetector::setConfigValues()
827  {
828    // keys
829    for (unsigned int i = 0; i < nKeys_s; i++)
830      readTrigger(keys_[i]);
831    // mouse buttons
832    for (unsigned int i = 0; i < nMouseButtons_s; i++)
833      readTrigger(mouseButtons_[i]);
834    // joy stick buttons
835    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
836      readTrigger(joyStickButtons_[i]);
837    // half axes
838    for (unsigned int i = 0; i < nHalfAxes_s; i++)
839      readTrigger(halfAxes_[i]);
840  }
841
842  void KeyDetector::readTrigger(Button& button)
843  {
844    // binding has changed
845    button.parse(paramCommandBuffer_);
846    SimpleCommand* cmd = new SimpleCommand();
847    cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
848    button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
849    button.commands_[KeybindMode::OnPress][0] = cmd;
850    button.nCommands_[KeybindMode::OnPress] = 1;
851  }
852}
Note: See TracBrowser for help on using the repository browser.