Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1446 was 1446, checked in by landauf, 16 years ago

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

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 "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    delete[] cmds;
344    return true;
345  }
346
347  bool HalfAxis::execute()
348  {
349    bool success = true;
350    for (unsigned int i = 0; i < nParamCommands_; i++)
351      success = success && paramCommands_[i]->execute(absVal_, relVal_);
352    return success;
353  }
354
355
356  // ###############################
357  // ######     KeyBinder     ######
358  // ###############################
359
360  /**
361    @brief Constructor that does as little as necessary.
362  */
363  KeyBinder::KeyBinder() : deriveTime_(0.0f)
364  {
365    mouseRelative_[0] = 0;
366    mouseRelative_[1] = 0;
367    mousePosition_[0] = 0;
368    mousePosition_[1] = 0;
369
370    RegisterObject(KeyBinder);
371
372    // keys
373    std::string keyNames[] = {
374      "UNASSIGNED",
375      "ESCAPE",
376      "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
377      "MINUS", "EQUALS", "BACK", "TAB",
378      "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
379      "LBRACKET", "RBRACKET",
380      "RETURN", "LCONTROL",
381      "A", "S", "D", "F", "G", "H", "J", "K", "L",
382      "SEMICOLON", "APOSTROPHE", "GRAVE",
383      "LSHIFT", "BACKSLASH",
384      "Z", "X", "C", "V", "B", "N", "M",
385      "COMMA", "PERIOD", "SLASH",
386      "RSHIFT",
387      "MULTIPLY",
388      "LMENU",
389      "SPACE",
390      "CAPITAL",
391      "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
392      "NUMLOCK", "SCROLL",
393      "NUMPAD7", "NUMPAD8", "NUMPAD9",
394      "SUBTRACT",
395      "NUMPAD4", "NUMPAD5", "NUMPAD6",
396      "ADD",
397      "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
398      "DECIMAL",
399      "","",
400      "OEM_102",
401      "F11", "F12",
402      "","","","","","","","","","","",
403      "F13", "F14", "F15",
404      "","","","","","","","","","",
405      "KANA",
406      "","",
407      "ABNT_C1",
408      "","","","","",
409      "CONVERT",
410      "",
411      "NOCONVERT",
412      "",
413      "YEN",
414      "ABNT_C2",
415      "","","","","","","","","","","","","","",
416      "NUMPADEQUALS",
417      "","",
418      "PREVTRACK",
419      "AT",
420      "COLON", "UNDERLINE",
421      "KANJI",
422      "STOP",
423      "AX",
424      "UNLABELED",
425      "NEXTTRACK",
426      "","",
427      "NUMPADENTER",
428      "RCONTROL",
429      "","",
430      "MUTE",
431      "CALCULATOR",
432      "PLAYPAUSE",
433      "",
434      "MEDIASTOP",
435      "","","","","","","","","",
436      "VOLUMEDOWN",
437      "",
438      "VOLUMEUP",
439      "",
440      "WEBHOME",
441      "NUMPADCOMMA",
442      "",
443      "DIVIDE",
444      "",
445      "SYSRQ",
446      "RMENU",
447      "","","","","","","","","","","","",
448      "PAUSE",
449      "",
450      "HOME",
451      "UP",
452      "PGUP",
453      "",
454      "LEFT",
455      "",
456      "RIGHT",
457      "",
458      "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
459      "","","","","","","",
460      "LWIN", "RWIN", "APPS",
461      "POWER", "SLEEP",
462      "","","",
463      "WAKE",
464      "",
465      "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
466      "MYCOMPUTER", "MAIL", "MEDIASELECT"
467    };
468    for (unsigned int i = 0; i < nKeys_s; i++)
469      keys_[i].name_ = "Key" + keyNames[i];
470
471    // mouse buttons
472    std::string mouseButtonNames[] = {
473      "MouseLeft", "MouseRight", "MouseMiddle",
474      "MouseButton3", "MouseButton4", "MouseButton5",
475      "MouseButton6", "MouseButton7",
476      "MouseWheel1Up", "MouseWheel1Down",
477      "MouseWheel2Up", "MouseWheel2Down" };
478    for (unsigned int i = 0; i < nMouseButtons_s; i++)
479      mouseButtons_[i].name_ = mouseButtonNames[i];
480
481    // joy stick buttons
482    for (unsigned int i = 0; i < 32; i++)
483      joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
484    for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
485    {
486                  joyStickButtons_[i + 0].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
487                  joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
488                  joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
489                  joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "West";
490    }
491
492    // half axes
493    std::string rawNames[nHalfAxes_s/2];
494    rawNames[0] = "MouseX";
495    rawNames[1] = "MouseY";
496    rawNames[2] = "Empty1";
497    rawNames[3] = "Empty2";
498    for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
499      rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3);
500    for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
501    {
502      halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
503      halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
504    }
505
506    for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
507      halfAxes_[i].buttonThreshold_ = buttonThreshold_;
508  }
509
510  /**
511    @brief Destructor
512  */
513  KeyBinder::~KeyBinder()
514  {
515    // almost no destructors required because most of the arrays are static.
516    clearBindings(); // does some destruction work
517  }
518
519  /**
520    @brief Loads the key and button bindings.
521    @return True if loading succeeded.
522  */
523  void KeyBinder::loadBindings()
524  {
525    COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
526
527    clearBindings();
528
529    std::ifstream infile;
530    infile.open("keybindings.ini");
531    if (!infile.is_open())
532    {
533      ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "def_keybindings.ini");
534      ConfigFileManager::getSingleton()->save(CFT_Keybindings, "keybindings.ini");
535    }
536    infile.close();
537    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
538
539    // parse key bindings
540    setConfigValues();
541
542    COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
543  }
544
545  /**
546    @brief Loader for the key bindings, managed by config values.
547  */
548  void KeyBinder::setConfigValues()
549  {
550    SetConfigValueGeneric(KeyBinder, analogThreshold_, 0.01f)  .description("Threshold for analog axes until which the state is 0.");
551    SetConfigValueGeneric(KeyBinder, mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
552    SetConfigValueGeneric(KeyBinder, bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
553    SetConfigValueGeneric(KeyBinder, derivePeriod_, 0.5f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
554    SetConfigValueGeneric(KeyBinder, mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived.");
555    SetConfigValueGeneric(KeyBinder, bClipMouse_, true).description("Whether or not to clip absolute value of mouse in non derive mode.");
556
557    float oldThresh = buttonThreshold_;
558    SetConfigValueGeneric(KeyBinder, buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
559    if (oldThresh != buttonThreshold_)
560      for (unsigned int i = 0; i < nHalfAxes_s; i++)
561        if (halfAxes_[i].buttonThreshold_ == oldThresh)
562          halfAxes_[i].buttonThreshold_ = buttonThreshold_;
563
564    // keys
565    for (unsigned int i = 0; i < nKeys_s; i++)
566      readTrigger(keys_[i]);
567    // mouse buttons
568    for (unsigned int i = 0; i < nMouseButtons_s; i++)
569      readTrigger(mouseButtons_[i]);
570    // joy stick buttons
571    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
572      readTrigger(joyStickButtons_[i]);
573    // half axes
574    for (unsigned int i = 0; i < nHalfAxes_s; i++)
575      readTrigger(halfAxes_[i]);
576  }
577
578  void KeyBinder::readTrigger(Button& button)
579  {
580    // config value stuff
581    ConfigValueContainer* cont = ClassManager<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
582    if (!cont)
583    {
584      cont = new ConfigValueContainer(CFT_Keybindings, ClassManager<KeyBinder>::getIdentifier(), button.name_, "");
585      ClassManager<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
586    }
587    std::string old = button.bindingString_;
588    cont->getValue(&button.bindingString_);
589
590    // keybinder stuff
591    if (old != button.bindingString_)
592    {
593      // clear everything so we don't get old axis ParamCommands mixed up
594      button.clear();
595
596      // binding has changed
597      button.parse(paramCommandBuffer_);
598    }
599  }
600
601  /**
602    @brief Overwrites all bindings with ""
603  */
604  void KeyBinder::clearBindings()
605  {
606    for (unsigned int i = 0; i < nKeys_s; i++)
607      keys_[i].clear();
608
609    for (unsigned int i = 0; i < nMouseButtons_s; i++)
610      mouseButtons_[i].clear();
611
612    for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
613      joyStickButtons_[i].clear();
614
615    for (unsigned int i = 0; i < nHalfAxes_s; i++)
616      halfAxes_[i].clear();
617
618    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
619      delete paramCommandBuffer_[i];
620    paramCommandBuffer_.clear();
621  }
622
623  void KeyBinder::tickInput(float dt, const HandlerState& state)
624  {
625    // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
626    unsigned int iBegin = 8;
627    unsigned int iEnd   = 8;
628    if (state.joyStick)
629      iEnd = nHalfAxes_s;
630    if (state.mouse)
631      iBegin = 0;
632    for (unsigned int i = iBegin; i < iEnd; i++)
633    {
634      if (halfAxes_[i].hasChanged_)
635      {
636        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
637        {
638          halfAxes_[i].wasDown_ = true;
639          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
640            halfAxes_[i].execute(KeybindMode::OnPress);
641        }
642        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
643        {
644          halfAxes_[i].wasDown_ = false;
645          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
646            halfAxes_[i].execute(KeybindMode::OnRelease);
647        }
648        halfAxes_[i].hasChanged_ = false;
649      }
650
651      if (halfAxes_[i].wasDown_)
652      {
653        if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
654          halfAxes_[i].execute(KeybindMode::OnHold);
655      }
656
657      // these are the actually useful axis bindings for analog input AND output
658      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
659      {
660        //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
661        halfAxes_[i].execute();
662      }
663    }
664
665    if (bDeriveMouseInput_ && state.mouse)
666    {
667      if (deriveTime_ > derivePeriod_)
668      {
669        //CCOUT(3) << "mouse abs: ";
670        for (int i = 0; i < 2; i++)
671        {
672          if (mouseRelative_[i] > 0)
673          {
674            halfAxes_[2*i + 0].absVal_ =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
675            halfAxes_[2*i + 1].absVal_ = 0.0f;
676          }
677          else if (mouseRelative_[i] < 0)
678          {
679            halfAxes_[2*i + 0].absVal_ = 0.0f;
680            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
681          }
682          else
683          {
684            halfAxes_[2*i + 0].absVal_ = 0.0f;
685            halfAxes_[2*i + 1].absVal_ = 0.0f;
686          }
687          //COUT(3) << mouseRelative_[i] << " | ";
688          mouseRelative_[i] = 0;
689          halfAxes_[2*i + 0].hasChanged_ = true;
690          halfAxes_[2*i + 1].hasChanged_ = true;
691        }
692        deriveTime_ = 0.0f;
693        //COUT(3) << std::endl;
694      }
695      else
696        deriveTime_ += dt;
697    }
698
699    // execute all buffered bindings (addional parameter)
700    for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
701      paramCommandBuffer_[i]->execute();
702
703    // always reset the relative movement of the mouse
704    if (state.mouse)
705      for (unsigned int i = 0; i < 8; i++)
706        halfAxes_[i].relVal_ = 0.0f;
707  }
708
709  void KeyBinder::keyPressed (const KeyEvent& evt)
710  { keys_[evt.key].execute(KeybindMode::OnPress); }
711
712  void KeyBinder::keyReleased(const KeyEvent& evt)
713  { keys_[evt.key].execute(KeybindMode::OnRelease); }
714
715  void KeyBinder::keyHeld    (const KeyEvent& evt)
716  { keys_[evt.key].execute(KeybindMode::OnHold); }
717
718
719  void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
720  { mouseButtons_[id].execute(KeybindMode::OnPress); }
721
722  void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
723  { mouseButtons_[id].execute(KeybindMode::OnRelease); }
724
725  void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
726  { mouseButtons_[id].execute(KeybindMode::OnHold); }
727
728
729  void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
730  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
731
732  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
733  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
734
735  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
736  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
737
738  /**
739    @brief Event handler for the mouseMoved Event.
740    @param e Mouse state information
741  */
742  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
743  {
744    // y axis of mouse input is inverted
745    int rel[] = { rel_.x, -rel_.y };
746
747    if (!bDeriveMouseInput_)
748    {
749      for (int i = 0; i < 2; i++)
750      {
751        if (rel[i])
752        {
753          // absolute
754          halfAxes_[2*i + 0].hasChanged_ = true;
755          halfAxes_[2*i + 1].hasChanged_ = true;
756          mousePosition_[i] += rel[i];
757
758          if (bClipMouse_)
759          {
760            if (mousePosition_[i] > 1024)
761              mousePosition_[i] =  1024;
762            if (mousePosition_[i] < -1024)
763              mousePosition_[i] = -1024;
764          }
765
766          if (mousePosition_[i] >= 0)
767          {
768            halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
769            halfAxes_[2*i + 1].absVal_ =  0.0f;
770          }
771          else
772          {
773            halfAxes_[2*i + 0].absVal_ =  0.0f;
774            halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
775          }
776        }
777      }
778    }
779    else
780    {
781      mouseRelative_[0] += rel[0];
782      mouseRelative_[1] += rel[1];
783    }
784
785    // relative
786    for (int i = 0; i < 2; i++)
787    {
788      if (rel[i] > 0)
789        halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
790      else
791        halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
792    }
793  }
794
795  /**
796    @brief Event handler for the mouseScrolled Event.
797    @param e Mouse state information
798  */
799  void KeyBinder::mouseScrolled(int abs, int rel)
800  {
801    //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
802
803    if (rel > 0)
804      for (int i = 0; i < rel/120; i++)
805        mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
806    else
807      for (int i = 0; i < -rel/120; i++)
808        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
809  }
810
811  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value)
812  {
813    // TODO: Use proper calibration values instead of generally 16-bit integer
814    int i = 8 + axis * 2;
815    if (value >= 0)
816    {
817      //if (value > 10000)
818      //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
819
820      halfAxes_[i].absVal_ = value;
821      halfAxes_[i].relVal_ = value;
822      halfAxes_[i].hasChanged_ = true;
823      if (halfAxes_[i + 1].absVal_ > 0.0f)
824      {
825        halfAxes_[i + 1].absVal_ = -0.0f;
826        halfAxes_[i + 1].relVal_ = -0.0f;
827        halfAxes_[i + 1].hasChanged_ = true;
828      }
829    }
830    else
831    {
832      //if (value < -10000)
833      //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
834
835      halfAxes_[i + 1].absVal_ = -value;
836      halfAxes_[i + 1].relVal_ = -value;
837      halfAxes_[i + 1].hasChanged_ = true;
838      if (halfAxes_[i].absVal_ > 0.0f)
839      {
840        halfAxes_[i].absVal_ = -0.0f;
841        halfAxes_[i].relVal_ = -0.0f;
842        halfAxes_[i].hasChanged_ = true;
843      }
844    }
845  }
846
847
848  // ###############################
849  // #####     KeyDetector     #####
850  // ###############################
851
852  /**
853    @brief Constructor
854  */
855  KeyDetector::KeyDetector()
856  {
857    RegisterObject(KeyDetector);
858  }
859
860  /**
861    @brief Destructor
862  */
863  KeyDetector::~KeyDetector()
864  {
865  }
866
867  /**
868    @brief Loads the key and button bindings.
869    @return True if loading succeeded.
870  */
871  void KeyDetector::loadBindings()
872  {
873    clearBindings();
874    setConfigValues();
875  }
876
877  void KeyDetector::readTrigger(Button& button)
878  {
879    SimpleCommand* cmd = new SimpleCommand();
880    cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
881    button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
882    button.commands_[KeybindMode::OnPress][0] = cmd;
883    button.nCommands_[KeybindMode::OnPress] = 1;
884  }
885
886
887  // ###############################
888  // ##### CalibratorCallback  #####
889  // ###############################
890
891  void CalibratorCallback::keyPressed(const orxonox::KeyEvent &evt)
892  {
893    if (evt.key == KeyCode::Return)
894    {
895      InputManager::setInputState(InputManager::IS_NOCALIBRATE);
896    }
897  }
898}
Note: See TracBrowser for help on using the repository browser.