Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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