Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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