Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1444 was 1444, checked in by rgrieder, 16 years ago

Added 'calibrate' command for the joystick
Simply type 'calibrate', move your axes around, center them press enter again.
Values are stored in keybindings.ini

File size: 26.6 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 <limits.h>
37#include "util/Convert.h"
38#include "util/SubString.h"
39#include "util/String.h"
40#include "Debug.h"
41#include "ConfigValueIncludes.h"
42#include "CoreIncludes.h"
43#include "CommandExecutor.h"
44#include "Executor.h"
45// TODO: only needed by the CalibratorCallback class; move to new file
46#include "InputManager.h"
47
48namespace orxonox
49{
50  // ###############################
51  // ###  BufferedParamCommand   ###
52  // ###############################
53
54  /**
55  * Executes a buffered command. This is used for commands with additional
56  * parameters.
57  * @return True if command execution was successful or value was zero.
58  */
59  bool BufferedParamCommand::execute()
60  {
61    if (nValuesAdded_)
62    {
63      BufferedParamCommand& cmd = *this;
64      cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
65      // reset
66      cmd.nValuesAdded_ = 0;
67      cmd.value_ = 0;
68      return CommandExecutor::execute(cmd.evaluation_);
69    }
70    else
71      return true;
72  }
73
74  // ###############################
75  // #####    SimpleCommand    #####
76  // ###############################
77
78  /**
79  * Executes a simple command with no additional paramters.
80  * @return True if command execution was successful, false otherwise.
81  */
82  bool SimpleCommand::execute(float abs, float rel)
83  {
84    return CommandExecutor::execute(evaluation_);
85  }
86
87  // ###############################
88  // #####    ParamCommand     #####
89  // ###############################
90
91  /**
92  * Executes a parameter command. The commmand string is not directly executed,
93  * but instead stored in a buffer list so that values can be combined.
94  * @return Always true.
95  */
96  bool ParamCommand::execute(float abs, float rel)
97  {
98    BufferedParamCommand& cmd = *paramCommand_;
99    // command has an additional parameter
100    if (bRelative_)
101    {
102      if (rel != 0.0f)
103      {
104        // we have to calculate a relative movement.
105        // paramModifier_ says how much one keystroke is
106        cmd.value_ += paramModifier_ * rel;
107      }
108    }
109    else if (abs != 0.0f)
110    {
111      // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
112      // and normally this is caught in tickInput(), but that threshold cannot be to high
113      // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
114      // Someone only uses buttons with an active joystick. The joy stick value could then
115      // be 0.05 for instance and the the key value 1. Without handling the problem, the final
116      // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
117      float absQ = abs * abs;
118      float valueQ = cmd.value_ * cmd.value_;
119      if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
120      {
121        cmd.value_ = abs * paramModifier_;
122        cmd.nValuesAdded_ = 1;
123      }
124      else if (absQ * 50.0f < valueQ)
125      {
126        // abs is too small, we just don't do anything
127      }
128      else
129      {
130        // we have to calculate the absolute position of the axis.
131        // Since there might be another axis that is affected, we have to wait and
132        // store the result in a temporary place
133        cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
134      }
135    }
136    return true;
137  }
138
139  // ###############################
140  // #####       Button        #####
141  // ###############################
142
143  void Button::clear()
144  {
145    for (unsigned int j = 0; j < 3; j++)
146    {
147      if (nCommands_[j])
148      {
149        // delete all commands and the command pointer array
150        for (unsigned int i = 0; i < nCommands_[j]; i++)
151          delete commands_[j][i];
152        delete[] commands_[j];
153        commands_[j] = 0;
154        nCommands_[j] = 0;
155      }
156      else
157      {
158        commands_[j] = 0;
159      }
160    }
161  }
162
163  void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
164  {
165    if (isEmpty(bindingString_))
166    {
167      clear();
168      return;
169    }
170
171    // use std::vector for a temporary dynamic array
172    std::vector<BaseCommand*> commands[3];
173
174
175    // separate the commands
176    SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
177        '\\', false, '"', false, '(', ')', false, '\0');
178
179    for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
180    {
181      if (commandStrings[iCommand] != "")
182      {
183        SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
184            '\\', false, '"', false, '(', ')', false, '\0');
185       
186        unsigned int iToken = 0;
187
188        // for real axes, we can feed a ButtonThreshold argument as entire command
189        if (getLowercase(tokens[0]) == "buttonthreshold")
190        {
191          if (tokens.size() == 1)
192            continue;
193          // may fail, but doesn't matter
194          convertValue(&buttonThreshold_, tokens[1]);
195          continue;
196        }
197
198        // first argument can be OnPress, OnHold OnRelease or nothing
199        KeybindMode::Enum mode = KeybindMode::None;
200        if (getLowercase(tokens[iToken]) == "onpress")
201          mode = KeybindMode::OnPress,   iToken++;
202        if (getLowercase(tokens[iToken]) == "onrelease")
203          mode = KeybindMode::OnRelease, iToken++;
204        if (getLowercase(tokens[iToken]) == "onhold")
205          mode = KeybindMode::OnHold,    iToken++;
206
207        if (iToken == tokens.size())
208          continue;
209
210        // second argument can be the amplitude for the case it as an axis command
211        // default amplitude is 1.0f
212        float paramModifier = 1.0f;
213        if (getLowercase(tokens[iToken]) == "scale")
214        {
215          iToken++;
216          if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
217          {
218            COUT(2) << "Error while parsing key binding " << name_
219                << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
220            if (iToken == tokens.size())
221              continue;
222          }
223          iToken++;
224        }
225
226        // no more arguments expected except for the actual command
227        if (iToken == tokens.size())
228          continue;
229
230        std::string commandStr;
231        while (iToken != tokens.size())
232          commandStr += tokens[iToken++] + " ";
233
234        // evaluate the command
235        CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
236        if (!eval.isValid())
237          continue;
238
239        // check for param command
240        int paramIndex = eval.getEvaluatedExecutor()->getAxisParamIndex();
241        if (paramIndex >= 0)
242        {
243          // parameter supported command
244          ParamCommand* cmd = new ParamCommand();
245          cmd->paramModifier_ = paramModifier;
246          cmd->bRelative_ = eval.getEvaluatedExecutor()->getIsAxisRelative();
247
248          // add command to the buffer if not yet existing
249          for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
250          {
251            if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getCommandString())
252                == getLowercase(commandStr))
253            {
254              // already in list
255              cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
256              break;
257            }
258          }
259          if (cmd->paramCommand_ == 0)
260          {
261            cmd->paramCommand_ = new BufferedParamCommand();
262            paramCommandBuffer.push_back(cmd->paramCommand_);
263            cmd->paramCommand_->evaluation_ = eval;
264            cmd->paramCommand_->paramIndex_ = paramIndex;
265          }
266
267
268          // we don't know whether this is an actual axis or just a button
269          if (mode == KeybindMode::None)
270          {
271            if (!addParamCommand(cmd))
272            {
273              mode = eval.getEvaluatedExecutor()->getKeybindMode();
274              commands[mode].push_back(cmd);
275            }
276          }
277        }
278        else
279        {
280          SimpleCommand* cmd = new SimpleCommand();
281          cmd->evaluation_ = eval;
282
283          if (mode == KeybindMode::None)
284            mode = eval.getEvaluatedExecutor()->getKeybindMode();
285
286          commands[mode].push_back(cmd);
287        }
288      }
289    }
290
291    for (unsigned int j = 0; j < 3; j++)
292    {
293      nCommands_[j] = commands[j].size();
294      if (nCommands_[j])
295      {
296        commands_[j] = new BaseCommand*[nCommands_[j]];
297        for (unsigned int i = 0; i < commands[j].size(); i++)
298          commands_[j][i] = commands[j][i];
299      }
300      else
301        commands_[j] = 0;
302    }
303  }
304
305  bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
306  {
307    // execute all the parsed commands in the string
308    for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
309      commands_[mode][iCommand]->execute(abs, rel);
310    return true;
311  }
312
313  // ###############################
314  // #####      HalfAxis       #####
315  // ###############################
316
317  void HalfAxis::clear()
318  {
319    Button::clear();
320    if (nParamCommands_)
321    {
322      // delete all commands and the command pointer array
323      for (unsigned int i = 0; i < nParamCommands_; i++)
324        delete paramCommands_[i];
325      delete[] paramCommands_;
326      nParamCommands_ = 0;
327    }
328    else
329    {
330      nParamCommands_ = 0; nParamCommands_ = 0;
331    }
332  }
333 
334  bool HalfAxis::addParamCommand(ParamCommand* command)
335  {
336    ParamCommand** cmds = paramCommands_;
337    paramCommands_ = new ParamCommand*[++nParamCommands_];
338    unsigned int i;
339    for (i = 0; i < nParamCommands_ - 1; i++)
340      paramCommands_[i] = cmds[i];
341    paramCommands_[i] = command;
342    delete[] cmds;
343    return true;
344  }
345
346  bool HalfAxis::execute()
347  {
348    bool success = true;
349    for (unsigned int i = 0; i < nParamCommands_; i++)
350      success = success && paramCommands_[i]->execute(absVal_, relVal_);
351    return success;
352  }
353
354
355  // ###############################
356  // ######     KeyBinder     ######
357  // ###############################
358
359  /**
360    @brief Constructor that does as little as necessary.
361  */
362  KeyBinder::KeyBinder() : deriveTime_(0.0f)
363  {
364    mouseRelative_[0] = 0;
365    mouseRelative_[1] = 0;
366    mousePosition_[0] = 0;
367    mousePosition_[1] = 0;
368
369    RegisterObject(KeyBinder);
370
371    // keys
372    std::string keyNames[] = {
373      "UNASSIGNED",
374      "ESCAPE",
375      "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
376      "MINUS", "EQUALS", "BACK", "TAB",
377      "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
378      "LBRACKET", "RBRACKET",
379      "RETURN", "LCONTROL",
380      "A", "S", "D", "F", "G", "H", "J", "K", "L",
381      "SEMICOLON", "APOSTROPHE", "GRAVE",
382      "LSHIFT", "BACKSLASH",
383      "Z", "X", "C", "V", "B", "N", "M",
384      "COMMA", "PERIOD", "SLASH",
385      "RSHIFT",
386      "MULTIPLY",
387      "LMENU",
388      "SPACE",
389      "CAPITAL",
390      "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
391      "NUMLOCK", "SCROLL",
392      "NUMPAD7", "NUMPAD8", "NUMPAD9",
393      "SUBTRACT",
394      "NUMPAD4", "NUMPAD5", "NUMPAD6",
395      "ADD",
396      "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
397      "DECIMAL",
398      "","",
399      "OEM_102",
400      "F11", "F12",
401      "","","","","","","","","","","",
402      "F13", "F14", "F15",
403      "","","","","","","","","","",
404      "KANA",
405      "","",
406      "ABNT_C1",
407      "","","","","",
408      "CONVERT",
409      "",
410      "NOCONVERT",
411      "",
412      "YEN",
413      "ABNT_C2",
414      "","","","","","","","","","","","","","",
415      "NUMPADEQUALS",
416      "","",
417      "PREVTRACK",
418      "AT",
419      "COLON", "UNDERLINE",
420      "KANJI",
421      "STOP",
422      "AX",
423      "UNLABELED",
424      "NEXTTRACK",
425      "","",
426      "NUMPADENTER",
427      "RCONTROL",
428      "","",
429      "MUTE",
430      "CALCULATOR",
431      "PLAYPAUSE",
432      "",
433      "MEDIASTOP",
434      "","","","","","","","","",
435      "VOLUMEDOWN",
436      "",
437      "VOLUMEUP",
438      "",
439      "WEBHOME",
440      "NUMPADCOMMA",
441      "",
442      "DIVIDE",
443      "",
444      "SYSRQ",
445      "RMENU",
446      "","","","","","","","","","","","",
447      "PAUSE",
448      "",
449      "HOME",
450      "UP",
451      "PGUP",
452      "",
453      "LEFT",
454      "",
455      "RIGHT",
456      "",
457      "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
458      "","","","","","","",
459      "LWIN", "RWIN", "APPS",
460      "POWER", "SLEEP",
461      "","","",
462      "WAKE",
463      "",
464      "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
465      "MYCOMPUTER", "MAIL", "MEDIASELECT"
466    };
467    for (unsigned int i = 0; i < nKeys_s; i++)
468      keys_[i].name_ = "Key" + keyNames[i];
469
470    // mouse buttons
471    std::string mouseButtonNames[] = {
472      "MouseLeft", "MouseRight", "MouseMiddle",
473      "MouseButton3", "MouseButton4", "MouseButton5",
474      "MouseButton6", "MouseButton7",
475      "MouseWheel1Up", "MouseWheel1Down",
476      "MouseWheel2Up", "MouseWheel2Down" };
477    for (unsigned int i = 0; i < nMouseButtons_s; i++)
478      mouseButtons_[i].name_ = mouseButtonNames[i];
479
480    // joy stick buttons
481    for (unsigned int i = 0; i < 32; i++)
482      joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
483    for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
484    {
485                  joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
486                  joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
487                  joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
488                  joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
489    }
490
491    // half axes
492    std::string rawNames[nHalfAxes_s/2];
493    rawNames[0] = "MouseX";
494    rawNames[1] = "MouseY";
495    rawNames[2] = "Empty1";
496    rawNames[3] = "Empty2";
497    for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
498      rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3);
499    for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
500    {
501      halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
502      halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
503    }
504
505    for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
506      halfAxes_[i].buttonThreshold_ = buttonThreshold_;
507  }
508
509  /**
510    @brief Destructor
511  */
512  KeyBinder::~KeyBinder()
513  {
514    // almost no destructors required because most of the arrays are static.
515    clearBindings(); // does some destruction work
516  }
517
518  /**
519    @brief Loads the key and button bindings.
520    @return True if loading succeeded.
521  */
522  void KeyBinder::loadBindings()
523  {
524    COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
525
526    clearBindings();
527
528    std::ifstream infile;
529    infile.open("keybindings.ini");
530    if (!infile.is_open())
531    {
532      ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "def_keybindings.ini");
533      ConfigFileManager::getSingleton()->save(CFT_Keybindings, "keybindings.ini");
534    }
535    infile.close();
536    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
537
538    // parse key bindings
539    setConfigValues();
540
541    COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
542  }
543
544  /**
545    @brief Loader for the key bindings, managed by config values.
546  */
547  void KeyBinder::setConfigValues()
548  {
549    SetConfigValueGeneric(KeyBinder, analogThreshold_, 0.01f)  .description("Threshold for analog axes until which the state is 0.");
550    SetConfigValueGeneric(KeyBinder, mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
551    SetConfigValueGeneric(KeyBinder, bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
552    SetConfigValueGeneric(KeyBinder, derivePeriod_, 0.5f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
553    SetConfigValueGeneric(KeyBinder, mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived.");
554    SetConfigValueGeneric(KeyBinder, bClipMouse_, true).description("Whether or not to clip absolute value of mouse in non derive mode.");
555
556    float oldThresh = buttonThreshold_;
557    SetConfigValueGeneric(KeyBinder, buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
558    if (oldThresh != buttonThreshold_)
559      for (unsigned int i = 0; i < nHalfAxes_s; i++)
560        if (halfAxes_[i].buttonThreshold_ == oldThresh)
561          halfAxes_[i].buttonThreshold_ = buttonThreshold_;
562
563    // keys
564    for (unsigned int i = 0; i < nKeys_s; i++)
565      readTrigger(keys_[i]);
566    // mouse buttons
567    for (unsigned int i = 0; i < nMouseButtons_s; i++)
568      readTrigger(mouseButtons_[i]);
569    // joy stick buttons
570    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
571      readTrigger(joyStickButtons_[i]);
572    // half axes
573    for (unsigned int i = 0; i < nHalfAxes_s; i++)
574      readTrigger(halfAxes_[i]);
575  }
576
577  void KeyBinder::readTrigger(Button& button)
578  {
579    // config value stuff
580    ConfigValueContainer* cont = ClassManager<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
581    if (!cont)
582    {
583      cont = new ConfigValueContainer(CFT_Keybindings, ClassManager<KeyBinder>::getIdentifier(), button.name_, "");
584      ClassManager<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
585    }
586    std::string old = button.bindingString_;
587    cont->getValue(&button.bindingString_);
588
589    // keybinder stuff
590    if (old != button.bindingString_)
591    {
592      // clear everything so we don't get old axis ParamCommands mixed up
593      button.clear();
594
595      // binding has changed
596      button.parse(paramCommandBuffer_);
597    }
598  }
599
600  /**
601    @brief Overwrites all bindings with ""
602  */
603  void KeyBinder::clearBindings()
604  {
605    for (unsigned int i = 0; i < nKeys_s; i++)
606      keys_[i].clear();
607
608    for (unsigned int i = 0; i < nMouseButtons_s; i++)
609      mouseButtons_[i].clear();
610
611    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
612      joyStickButtons_[i].clear();
613
614    for (unsigned int i = 0; i < nHalfAxes_s; i++)
615      halfAxes_[i].clear();
616
617    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
618      delete paramCommandBuffer_[i];
619    paramCommandBuffer_.clear();
620  }
621
622  void KeyBinder::tickInput(float dt, const HandlerState& state)
623  {
624    // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
625    unsigned int iBegin = 8;
626    unsigned int iEnd   = 8;
627    if (state.joyStick)
628      iEnd = nHalfAxes_s;
629    if (state.mouse)
630      iBegin = 0;
631    for (unsigned int i = iBegin; i < iEnd; i++)
632    {
633      if (halfAxes_[i].hasChanged_)
634      {
635        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
636        {
637          halfAxes_[i].wasDown_ = true;
638          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
639            halfAxes_[i].execute(KeybindMode::OnPress);
640        }
641        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
642        {
643          halfAxes_[i].wasDown_ = false;
644          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
645            halfAxes_[i].execute(KeybindMode::OnRelease);
646        }
647        halfAxes_[i].hasChanged_ = false;
648      }
649
650      if (halfAxes_[i].wasDown_)
651      {
652        if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
653          halfAxes_[i].execute(KeybindMode::OnHold);
654      }
655
656      // these are the actually useful axis bindings for analog input AND output
657      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
658      {
659        //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
660        halfAxes_[i].execute();
661      }
662    }
663
664    if (bDeriveMouseInput_ && state.mouse)
665    {
666      if (deriveTime_ > derivePeriod_)
667      {
668        //CCOUT(3) << "mouse abs: ";
669        for (int i = 0; i < 2; i++)
670        {
671          if (mouseRelative_[i] > 0)
672          {
673            halfAxes_[2*i + 0].absVal_ =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
674            halfAxes_[2*i + 1].absVal_ = 0.0f;
675          }
676          else if (mouseRelative_[i] < 0)
677          {
678            halfAxes_[2*i + 0].absVal_ = 0.0f;
679            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
680          }
681          else
682          {
683            halfAxes_[2*i + 0].absVal_ = 0.0f;
684            halfAxes_[2*i + 1].absVal_ = 0.0f;
685          }
686          //COUT(3) << mouseRelative_[i] << " | ";
687          mouseRelative_[i] = 0;
688          halfAxes_[2*i + 0].hasChanged_ = true;
689          halfAxes_[2*i + 1].hasChanged_ = true;
690        }
691        deriveTime_ = 0.0f;
692        //COUT(3) << std::endl;
693      }
694      else
695        deriveTime_ += dt;
696    }
697
698    // execute all buffered bindings (addional parameter)
699    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
700      paramCommandBuffer_[i]->execute();
701
702    // always reset the relative movement of the mouse
703    if (state.mouse)
704      for (unsigned int i = 0; i < 8; i++)
705        halfAxes_[i].relVal_ = 0.0f;
706  }
707
708  void KeyBinder::keyPressed (const KeyEvent& evt)
709  { keys_[evt.key].execute(KeybindMode::OnPress); }
710
711  void KeyBinder::keyReleased(const KeyEvent& evt)
712  { keys_[evt.key].execute(KeybindMode::OnRelease); }
713
714  void KeyBinder::keyHeld    (const KeyEvent& evt)
715  { keys_[evt.key].execute(KeybindMode::OnHold); }
716
717
718  void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
719  { mouseButtons_[id].execute(KeybindMode::OnPress); }
720
721  void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
722  { mouseButtons_[id].execute(KeybindMode::OnRelease); }
723
724  void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
725  { mouseButtons_[id].execute(KeybindMode::OnHold); }
726
727
728  void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
729  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
730
731  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
732  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
733
734  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
735  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
736
737  /**
738    @brief Event handler for the mouseMoved Event.
739    @param e Mouse state information
740  */
741  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
742  {
743    // y axis of mouse input is inverted
744    int rel[] = { rel_.x, -rel_.y };
745
746    if (!bDeriveMouseInput_)
747    {
748      for (int i = 0; i < 2; i++)
749      {
750        if (rel[i])
751        {
752          // absolute
753          halfAxes_[2*i + 0].hasChanged_ = true;
754          halfAxes_[2*i + 1].hasChanged_ = true;
755          mousePosition_[i] += rel[i];
756
757          if (bClipMouse_)
758          {
759            if (mousePosition_[i] > 1024)
760              mousePosition_[i] =  1024;
761            if (mousePosition_[i] < -1024)
762              mousePosition_[i] = -1024;
763          }
764
765          if (mousePosition_[i] >= 0)
766          {
767            halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
768            halfAxes_[2*i + 1].absVal_ =  0.0f;
769          }
770          else
771          {
772            halfAxes_[2*i + 0].absVal_ =  0.0f;
773            halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
774          }
775        }
776      }
777    }
778    else
779    {
780      mouseRelative_[0] += rel[0];
781      mouseRelative_[1] += rel[1];
782    }
783
784    // relative
785    for (int i = 0; i < 2; i++)
786    {
787      if (rel[i] > 0)
788        halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
789      else
790        halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
791    }
792  }
793
794  /**
795    @brief Event handler for the mouseScrolled Event.
796    @param e Mouse state information
797  */
798  void KeyBinder::mouseScrolled(int abs, int rel)
799  {
800    //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
801
802    if (rel > 0)
803      for (int i = 0; i < rel/120; i++)
804        mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
805    else
806      for (int i = 0; i < -rel/120; i++)
807        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
808  }
809
810  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value)
811  {
812    // TODO: Use proper calibration values instead of generally 16-bit integer
813    int i = 8 + axis * 2;
814    if (value >= 0)
815    {
816      //if (value > 10000)
817      //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
818
819      halfAxes_[i].absVal_ = value;
820      halfAxes_[i].relVal_ = value;
821      halfAxes_[i].hasChanged_ = true;
822      if (halfAxes_[i + 1].absVal_ > 0.0f)
823      {
824        halfAxes_[i + 1].absVal_ = -0.0f;
825        halfAxes_[i + 1].relVal_ = -0.0f;
826        halfAxes_[i + 1].hasChanged_ = true;
827      }
828    }
829    else
830    {
831      //if (value < -10000)
832      //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
833
834      halfAxes_[i + 1].absVal_ = -value;
835      halfAxes_[i + 1].relVal_ = -value;
836      halfAxes_[i + 1].hasChanged_ = true;
837      if (halfAxes_[i].absVal_ > 0.0f)
838      {
839        halfAxes_[i].absVal_ = -0.0f;
840        halfAxes_[i].relVal_ = -0.0f;
841        halfAxes_[i].hasChanged_ = true;
842      }
843    }
844  }
845
846
847  // ###############################
848  // #####     KeyDetector     #####
849  // ###############################
850
851  /**
852    @brief Constructor
853  */
854  KeyDetector::KeyDetector()
855  {
856    RegisterObject(KeyDetector);
857  }
858
859  /**
860    @brief Destructor
861  */
862  KeyDetector::~KeyDetector()
863  {
864  }
865
866  /**
867    @brief Loads the key and button bindings.
868    @return True if loading succeeded.
869  */
870  void KeyDetector::loadBindings()
871  {
872    clearBindings();
873    setConfigValues();
874  }
875
876  void KeyDetector::readTrigger(Button& button)
877  {
878    SimpleCommand* cmd = new SimpleCommand();
879    cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
880    button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
881    button.commands_[KeybindMode::OnPress][0] = cmd;
882    button.nCommands_[KeybindMode::OnPress] = 1;
883  }
884
885
886  // ###############################
887  // ##### CalibratorCallback  #####
888  // ###############################
889
890  void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt)
891  {
892    if (evt.key == KeyCode::Return)
893    {
894      InputManager::setInputState(InputManager::IS_NOCALIBRATE);
895    }
896  }
897}
Note: See TracBrowser for help on using the repository browser.