Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 26.8 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"#include "ConsoleCommand.h"#include "Executor.h"
44// TODO: only needed by the CalibratorCallback class; move to new file
45#include "InputManager.h"
46
47namespace orxonox
48{
49  // ###############################
50  // ###  BufferedParamCommand   ###
51  // ###############################
52
53  /**
54  * Executes a buffered command. This is used for commands with additional
55  * parameters.
56  * @return True if command execution was successful or value was zero.
57  */
58  bool BufferedParamCommand::execute()
59  {
60    if (nValuesAdded_)
61    {
62      BufferedParamCommand& cmd = *this;
63      cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
64      // reset
65      cmd.nValuesAdded_ = 0;
66      cmd.value_ = 0;
67      return cmd.evaluation_.execute();
68    }
69    else
70      return true;
71  }
72
73  // ###############################
74  // #####    SimpleCommand    #####
75  // ###############################
76
77  /**
78  * Executes a simple command with no additional paramters.
79  * @return True if command execution was successful, false otherwise.
80  */
81  bool SimpleCommand::execute(float abs, float rel)
82  {
83    return evaluation_.execute();
84  }
85
86  // ###############################
87  // #####    ParamCommand     #####
88  // ###############################
89
90  /**
91  * Executes a parameter command. The commmand string is not directly executed,
92  * but instead stored in a buffer list so that values can be combined.
93  * @return Always true.
94  */
95  bool ParamCommand::execute(float abs, float rel)
96  {
97    BufferedParamCommand& cmd = *paramCommand_;
98    // command has an additional parameter
99    if (bRelative_)
100    {
101      if (rel != 0.0f)
102      {
103        // we have to calculate a relative movement.
104        // paramModifier_ says how much one keystroke is
105        cmd.value_ += paramModifier_ * rel;
106      }
107    }
108    else if (abs != 0.0f)
109    {
110      // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
111      // and normally this is caught in tickInput(), but that threshold cannot be to high
112      // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
113      // Someone only uses buttons with an active joystick. The joy stick value could then
114      // be 0.05 for instance and the the key value 1. Without handling the problem, the final
115      // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
116      float absQ = abs * abs;
117      float valueQ = cmd.value_ * cmd.value_;
118      if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
119      {
120        cmd.value_ = abs * paramModifier_;
121        cmd.nValuesAdded_ = 1;
122      }
123      else if (absQ * 50.0f < valueQ)
124      {
125        // abs is too small, we just don't do anything
126      }
127      else
128      {
129        // we have to calculate the absolute position of the axis.
130        // Since there might be another axis that is affected, we have to wait and
131        // store the result in a temporary place
132        cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
133      }
134    }
135    return true;
136  }
137
138  // ###############################
139  // #####       Button        #####
140  // ###############################
141
142  void Button::clear()
143  {
144    for (unsigned int j = 0; j < 3; j++)
145    {
146      if (nCommands_[j])
147      {
148        // delete all commands and the command pointer array
149        for (unsigned int i = 0; i < nCommands_[j]; i++)
150          delete commands_[j][i];
151        delete[] commands_[j];
152        commands_[j] = 0;
153        nCommands_[j] = 0;
154      }
155      else
156      {
157        commands_[j] = 0;
158      }
159    }
160  }
161
162  void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
163  {
164    if (isEmpty(bindingString_))
165    {
166      clear();
167      return;
168    }
169
170    // use std::vector for a temporary dynamic array
171    std::vector<BaseCommand*> commands[3];
172
173
174    // separate the commands
175    SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
176        '\\', false, '"', false, '(', ')', false, '\0');
177
178    for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
179    {
180      if (commandStrings[iCommand] != "")
181      {
182        SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
183            '\\', false, '"', false, '(', ')', false, '\0');
184
185        unsigned int iToken = 0;
186
187        // for real axes, we can feed a ButtonThreshold argument as entire command
188        if (getLowercase(tokens[0]) == "buttonthreshold")
189        {
190          if (tokens.size() == 1)
191            continue;
192          // may fail, but doesn't matter
193          convertValue(&buttonThreshold_, tokens[1]);
194          continue;
195        }
196
197        // first argument can be OnPress, OnHold OnRelease or nothing
198        KeybindMode::Enum mode = KeybindMode::None;
199        if (getLowercase(tokens[iToken]) == "onpress")
200          mode = KeybindMode::OnPress,   iToken++;
201        if (getLowercase(tokens[iToken]) == "onrelease")
202          mode = KeybindMode::OnRelease, iToken++;
203        if (getLowercase(tokens[iToken]) == "onhold")
204          mode = KeybindMode::OnHold,    iToken++;
205
206        if (iToken == tokens.size())
207          continue;
208
209        // second argument can be the amplitude for the case it as an axis command
210        // default amplitude is 1.0f
211        float paramModifier = 1.0f;
212        if (getLowercase(tokens[iToken]) == "scale")
213        {
214          iToken++;
215          if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
216          {
217            COUT(2) << "Error while parsing key binding " << name_
218                << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
219            if (iToken == tokens.size())
220              continue;
221          }
222          iToken++;
223        }
224
225        // no more arguments expected except for the actual command
226        if (iToken == tokens.size())
227          continue;
228
229        std::string commandStr;
230        while (iToken != tokens.size())
231          commandStr += tokens[iToken++] + " ";
232
233        // evaluate the command
234        CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
235        if (!eval.isValid())
236          continue;
237
238        // check for param command
239        int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
240        if (paramIndex >= 0)
241        {
242          // parameter supported command
243          ParamCommand* cmd = new ParamCommand();
244          cmd->paramModifier_ = paramModifier;
245          cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
246
247          // add command to the buffer if not yet existing
248          for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
249          {
250            if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
251                == getLowercase(commandStr))
252            {
253              // already in list
254              cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
255              break;
256            }
257          }
258          if (cmd->paramCommand_ == 0)
259          {
260            cmd->paramCommand_ = new BufferedParamCommand();
261            paramCommandBuffer.push_back(cmd->paramCommand_);
262            cmd->paramCommand_->evaluation_ = eval;
263            cmd->paramCommand_->paramIndex_ = paramIndex;
264          }
265
266
267          // we don't know whether this is an actual axis or just a button
268          if (mode == KeybindMode::None)
269          {
270            if (!addParamCommand(cmd))
271            {
272              mode = eval.getConsoleCommand()->getKeybindMode();
273              commands[mode].push_back(cmd);
274            }
275          }
276        }
277        else
278        {
279          SimpleCommand* cmd = new SimpleCommand();
280          cmd->evaluation_ = eval;
281
282          if (mode == KeybindMode::None)
283            mode = eval.getConsoleCommand()->getKeybindMode();
284
285          commands[mode].push_back(cmd);
286        }
287      }
288    }
289
290    for (unsigned int j = 0; j < 3; j++)
291    {
292      nCommands_[j] = commands[j].size();
293      if (nCommands_[j])
294      {
295        commands_[j] = new BaseCommand*[nCommands_[j]];
296        for (unsigned int i = 0; i < commands[j].size(); i++)
297          commands_[j][i] = commands[j][i];
298      }
299      else
300        commands_[j] = 0;
301    }
302  }
303
304  bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
305  {
306    // execute all the parsed commands in the string
307    for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
308      commands_[mode][iCommand]->execute(abs, rel);
309    return true;
310  }
311
312  // ###############################
313  // #####      HalfAxis       #####
314  // ###############################
315
316  void HalfAxis::clear()
317  {
318    Button::clear();
319    if (nParamCommands_)
320    {
321      // delete all commands and the command pointer array
322      for (unsigned int i = 0; i < nParamCommands_; i++)
323        delete paramCommands_[i];
324      delete[] paramCommands_;
325      nParamCommands_ = 0;
326    }
327    else
328    {
329      nParamCommands_ = 0; nParamCommands_ = 0;
330    }
331  }
332
333  bool HalfAxis::addParamCommand(ParamCommand* command)
334  {
335    ParamCommand** cmds = paramCommands_;
336    paramCommands_ = new ParamCommand*[++nParamCommands_];
337    unsigned int i;
338    for (i = 0; i < nParamCommands_ - 1; i++)
339      paramCommands_[i] = cmds[i];
340    paramCommands_[i] = command;
341    if (nParamCommands_ > 1)
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::resetJoyStickAxes()
623  {
624    for (unsigned int i = 8; i < nHalfAxes_s; i++)
625    {
626      halfAxes_[i].absVal_ = 0.0f;
627      halfAxes_[i].relVal_ = 0.0f;
628    }
629  }
630
631  void KeyBinder::tickInput(float dt, const HandlerState& state)
632  {
633    // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
634    unsigned int iBegin = 8;
635    unsigned int iEnd   = 8;
636    if (state.joyStick)
637      iEnd = nHalfAxes_s;
638    if (state.mouse)
639      iBegin = 0;
640    for (unsigned int i = iBegin; i < iEnd; i++)
641    {
642      if (halfAxes_[i].hasChanged_)
643      {
644        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
645        {
646          halfAxes_[i].wasDown_ = true;
647          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
648            halfAxes_[i].execute(KeybindMode::OnPress);
649        }
650        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
651        {
652          halfAxes_[i].wasDown_ = false;
653          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
654            halfAxes_[i].execute(KeybindMode::OnRelease);
655        }
656        halfAxes_[i].hasChanged_ = false;
657      }
658
659      if (halfAxes_[i].wasDown_)
660      {
661        if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
662          halfAxes_[i].execute(KeybindMode::OnHold);
663      }
664
665      // these are the actually useful axis bindings for analog input AND output
666      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
667      {
668        //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
669        halfAxes_[i].execute();
670      }
671    }
672
673    if (bDeriveMouseInput_ && state.mouse)
674    {
675      if (deriveTime_ > derivePeriod_)
676      {
677        //CCOUT(3) << "mouse abs: ";
678        for (int i = 0; i < 2; i++)
679        {
680          if (mouseRelative_[i] > 0)
681          {
682            halfAxes_[2*i + 0].absVal_ =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
683            halfAxes_[2*i + 1].absVal_ = 0.0f;
684          }
685          else if (mouseRelative_[i] < 0)
686          {
687            halfAxes_[2*i + 0].absVal_ = 0.0f;
688            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
689          }
690          else
691          {
692            halfAxes_[2*i + 0].absVal_ = 0.0f;
693            halfAxes_[2*i + 1].absVal_ = 0.0f;
694          }
695          //COUT(3) << mouseRelative_[i] << " | ";
696          mouseRelative_[i] = 0;
697          halfAxes_[2*i + 0].hasChanged_ = true;
698          halfAxes_[2*i + 1].hasChanged_ = true;
699        }
700        deriveTime_ = 0.0f;
701        //COUT(3) << std::endl;
702      }
703      else
704        deriveTime_ += dt;
705    }
706
707    // execute all buffered bindings (addional parameter)
708    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
709      paramCommandBuffer_[i]->execute();
710
711    // always reset the relative movement of the mouse
712    if (state.mouse)
713      for (unsigned int i = 0; i < 8; i++)
714        halfAxes_[i].relVal_ = 0.0f;
715  }
716
717  void KeyBinder::keyPressed (const KeyEvent& evt)
718  { keys_[evt.key].execute(KeybindMode::OnPress); }
719
720  void KeyBinder::keyReleased(const KeyEvent& evt)
721  { keys_[evt.key].execute(KeybindMode::OnRelease); }
722
723  void KeyBinder::keyHeld    (const KeyEvent& evt)
724  { keys_[evt.key].execute(KeybindMode::OnHold); }
725
726
727  void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
728  { mouseButtons_[id].execute(KeybindMode::OnPress); }
729
730  void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
731  { mouseButtons_[id].execute(KeybindMode::OnRelease); }
732
733  void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
734  { mouseButtons_[id].execute(KeybindMode::OnHold); }
735
736
737  void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
738  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
739
740  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
741  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
742
743  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
744  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
745
746  /**
747    @brief Event handler for the mouseMoved Event.
748    @param e Mouse state information
749  */
750  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
751  {
752    // y axis of mouse input is inverted
753    int rel[] = { rel_.x, -rel_.y };
754
755    if (!bDeriveMouseInput_)
756    {
757      for (int i = 0; i < 2; i++)
758      {
759        if (rel[i])
760        {
761          // absolute
762          halfAxes_[2*i + 0].hasChanged_ = true;
763          halfAxes_[2*i + 1].hasChanged_ = true;
764          mousePosition_[i] += rel[i];
765
766          if (bClipMouse_)
767          {
768            if (mousePosition_[i] > 1024)
769              mousePosition_[i] =  1024;
770            if (mousePosition_[i] < -1024)
771              mousePosition_[i] = -1024;
772          }
773
774          if (mousePosition_[i] >= 0)
775          {
776            halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
777            halfAxes_[2*i + 1].absVal_ =  0.0f;
778          }
779          else
780          {
781            halfAxes_[2*i + 0].absVal_ =  0.0f;
782            halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
783          }
784        }
785      }
786    }
787    else
788    {
789      mouseRelative_[0] += rel[0];
790      mouseRelative_[1] += rel[1];
791    }
792
793    // relative
794    for (int i = 0; i < 2; i++)
795    {
796      if (rel[i] > 0)
797        halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
798      else
799        halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
800    }
801  }
802
803  /**
804    @brief Event handler for the mouseScrolled Event.
805    @param e Mouse state information
806  */
807  void KeyBinder::mouseScrolled(int abs, int rel)
808  {
809    //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
810
811    if (rel > 0)
812      for (int i = 0; i < rel/120; i++)
813        mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
814    else
815      for (int i = 0; i < -rel/120; i++)
816        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
817  }
818
819  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value)
820  {
821    // TODO: Use proper calibration values instead of generally 16-bit integer
822    int i = 8 + axis * 2;
823    if (value >= 0)
824    {
825      //if (value > 10000)
826      //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
827
828      halfAxes_[i].absVal_ = value;
829      halfAxes_[i].relVal_ = value;
830      halfAxes_[i].hasChanged_ = true;
831      if (halfAxes_[i + 1].absVal_ > 0.0f)
832      {
833        halfAxes_[i + 1].absVal_ = -0.0f;
834        halfAxes_[i + 1].relVal_ = -0.0f;
835        halfAxes_[i + 1].hasChanged_ = true;
836      }
837    }
838    else
839    {
840      //if (value < -10000)
841      //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
842
843      halfAxes_[i + 1].absVal_ = -value;
844      halfAxes_[i + 1].relVal_ = -value;
845      halfAxes_[i + 1].hasChanged_ = true;
846      if (halfAxes_[i].absVal_ > 0.0f)
847      {
848        halfAxes_[i].absVal_ = -0.0f;
849        halfAxes_[i].relVal_ = -0.0f;
850        halfAxes_[i].hasChanged_ = true;
851      }
852    }
853  }
854
855
856  // ###############################
857  // #####     KeyDetector     #####
858  // ###############################
859
860  /**
861    @brief Constructor
862  */
863  KeyDetector::KeyDetector()
864  {
865    RegisterObject(KeyDetector);
866  }
867
868  /**
869    @brief Destructor
870  */
871  KeyDetector::~KeyDetector()
872  {
873  }
874
875  /**
876    @brief Loads the key and button bindings.
877    @return True if loading succeeded.
878  */
879  void KeyDetector::loadBindings()
880  {
881    clearBindings();
882    setConfigValues();
883  }
884
885  void KeyDetector::readTrigger(Button& button)
886  {
887    SimpleCommand* cmd = new SimpleCommand();
888    cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
889    button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
890    button.commands_[KeybindMode::OnPress][0] = cmd;
891    button.nCommands_[KeybindMode::OnPress] = 1;
892  }
893
894
895  // ###############################
896  // ##### CalibratorCallback  #####
897  // ###############################
898
899  void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt)
900  {
901    if (evt.key == KeyCode::Return)
902    {
903      InputManager::setInputState(InputManager::IS_NOCALIBRATE);
904    }
905  }
906}
Note: See TracBrowser for help on using the repository browser.