Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 1795)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 1887)
@@ -41,4 +41,5 @@
 #include "core/ConfigFileManager.h"
 #include "InputCommands.h"
+#include "InputManager.h"
 
 namespace orxonox
@@ -49,5 +50,6 @@
     */
     KeyBinder::KeyBinder()
-        : deriveTime_(0.0f)
+        : numberOfJoySticks_(0)
+        , deriveTime_(0.0f)
     {
         mouseRelative_[0] = 0;
@@ -58,141 +60,59 @@
         RegisterRootObject(KeyBinder);
 
+        // intialise all buttons and half axes to avoid creating everything with 'new'
         // keys
-        std::string keyNames[] = {
-        "UNASSIGNED",
-        "ESCAPE",
-        "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
-        "MINUS", "EQUALS", "BACK", "TAB",
-        "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
-        "LBRACKET", "RBRACKET",
-        "RETURN", "LCONTROL",
-        "A", "S", "D", "F", "G", "H", "J", "K", "L",
-        "SEMICOLON", "APOSTROPHE", "GRAVE",
-        "LSHIFT", "BACKSLASH",
-        "Z", "X", "C", "V", "B", "N", "M",
-        "COMMA", "PERIOD", "SLASH",
-        "RSHIFT",
-        "MULTIPLY",
-        "LMENU",
-        "SPACE",
-        "CAPITAL",
-        "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
-        "NUMLOCK", "SCROLL",
-        "NUMPAD7", "NUMPAD8", "NUMPAD9",
-        "SUBTRACT",
-        "NUMPAD4", "NUMPAD5", "NUMPAD6",
-        "ADD",
-        "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
-        "DECIMAL",
-        "","",
-        "OEM_102",
-        "F11", "F12",
-        "","","","","","","","","","","",
-        "F13", "F14", "F15",
-        "","","","","","","","","","",
-        "KANA",
-        "","",
-        "ABNT_C1",
-        "","","","","",
-        "CONVERT",
-        "",
-        "NOCONVERT",
-        "",
-        "YEN",
-        "ABNT_C2",
-        "","","","","","","","","","","","","","",
-        "NUMPADEQUALS",
-        "","",
-        "PREVTRACK",
-        "AT",
-        "COLON", "UNDERLINE",
-        "KANJI",
-        "STOP",
-        "AX",
-        "UNLABELED",
-        "NEXTTRACK",
-        "","",
-        "NUMPADENTER",
-        "RCONTROL",
-        "","",
-        "MUTE",
-        "CALCULATOR",
-        "PLAYPAUSE",
-        "",
-        "MEDIASTOP",
-        "","","","","","","","","",
-        "VOLUMEDOWN",
-        "",
-        "VOLUMEUP",
-        "",
-        "WEBHOME",
-        "NUMPADCOMMA",
-        "",
-        "DIVIDE",
-        "",
-        "SYSRQ",
-        "RMENU",
-        "","","","","","","","","","","","",
-        "PAUSE",
-        "",
-        "HOME",
-        "UP",
-        "PGUP",
-        "",
-        "LEFT",
-        "",
-        "RIGHT",
-        "",
-        "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
-        "","","","","","","",
-        "LWIN", "RWIN", "APPS",
-        "POWER", "SLEEP",
-        "","","",
-        "WAKE",
-        "",
-        "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
-        "MYCOMPUTER", "MAIL", "MEDIASELECT"
-        };
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            keys_[i].name_ = "Key" + keyNames[i];
-
-        // mouse buttons
-        std::string mouseButtonNames[] = {
-            "MouseLeft",     "MouseRight",   "MouseMiddle",
-            "MouseButton3",  "MouseButton4", "MouseButton5",
-            "MouseButton6",  "MouseButton7",
-            "MouseWheel1Up", "MouseWheel1Down",
-            "MouseWheel2Up", "MouseWheel2Down"
-        };
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            mouseButtons_[i].name_ = mouseButtonNames[i];
-
-        // joy stick buttons
-        for (unsigned int i = 0; i < 32; i++)
-            joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
-        for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
-        {
-            joyStickButtons_[i + 0].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "North";
-            joyStickButtons_[i + 1].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "South";
-            joyStickButtons_[i + 2].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "East";
-            joyStickButtons_[i + 3].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "West";
-        }
-
-        // half axes
-        std::string rawNames[nHalfAxes_s/2];
-        rawNames[0] = "MouseX";
-        rawNames[1] = "MouseY";
-        rawNames[2] = "Empty1";
-        rawNames[3] = "Empty2";
-        for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
-            rawNames[i] = "JoyAxis" + convertToString(i - 3);
-        for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
-        {
-            halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
-            halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
-        }
-
-        for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
-            halfAxes_[i].buttonThreshold_ = buttonThreshold_;
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+        {
+            std::string keyname = KeyCode::ByString[i];
+            if (!keyname.empty())
+            {
+                keys_[i].name_ = std::string("Key") + keyname;
+            }
+            else
+            {
+                // some keys have name "" because the code is not occupied by OIS
+                // Use "Key_" plus the number as name to put it at the end of the config file section
+                std::string number = convertToString(i);
+                if (i < 100)
+                    number.insert(0, "0");
+                keys_[i].name_ = std::string("Key_") + number;
+            }
+            keys_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            keys_[i].groupName_ = "Keys";
+        }
+        // mouse buttons plus 4 mouse wheel buttons only 'generated' by KeyBinder
+        const char* const mouseWheelNames[] = { "Wheel1Down", "Wheel1Up", "Wheel2Down", "Wheel2Up" };
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+        {
+            std::string nameSuffix;
+            if (i < MouseButtonCode::numberOfButtons)
+                nameSuffix = MouseButtonCode::ByString[i];
+            else
+                nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
+            mouseButtons_[i].name_ = std::string("Mouse") + nameSuffix;
+            mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseButtons_[i].groupName_ = "MouseButtons";
+        }
+        // mouse axes
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            mouseAxes_[i].name_ = std::string("Mouse") + MouseAxisCode::ByString[i >> 1];
+            if (i & 1)
+                mouseAxes_[i].name_ += "Pos";
+            else
+                mouseAxes_[i].name_ += "Neg";
+            mouseAxes_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseAxes_[i].groupName_ = "MouseAxes";
+        }
+
+        // initialise joy sticks separatly to allow for reloading
+        numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks();
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes
+        compilePointerLists();
+
+        // set them here to use allHalfAxes_
+        setConfigValues();
     }
 
@@ -209,37 +129,10 @@
     /**
     @brief
-        Loads the key and button bindings.
-    @return
-        True if loading succeeded.
-    */
-    void KeyBinder::loadBindings()
-    {
-        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
-
-        clearBindings();
-
-        std::ifstream infile;
-        infile.open("keybindings.ini");
-        if (!infile)
-        {
-            ConfigFileManager::getInstance().setFile(CFT_Keybindings, "def_keybindings.ini");
-            ConfigFileManager::getInstance().save(CFT_Keybindings, "keybindings.ini");
-        }
-        else
-            infile.close();
-        ConfigFileManager::getInstance().setFile(CFT_Keybindings, "keybindings.ini");
-
-        // parse key bindings
-        setConfigValues();
-
-        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
-    }
-
-    /**
-    @brief
         Loader for the key bindings, managed by config values.
     */
     void KeyBinder::setConfigValues()
     {
+        SetConfigValue(defaultKeybindings_, "def_keybindings.ini")
+            .description("Filename of default keybindings.");
         SetConfigValue(analogThreshold_, 0.05f)
             .description("Threshold for analog axes until which the state is 0.");
@@ -252,51 +145,151 @@
         SetConfigValue(mouseSensitivityDerived_, 1.0f)
             .description("Mouse sensitivity if mouse input is derived.");
-        SetConfigValue(bClipMouse_, true)
-            .description("Whether or not to clip absolute value of mouse in non derive mode.");
-
-        float oldThresh = buttonThreshold_;
+        SetConfigValue(mouseWheelStepSize_, 120.0f)
+            .description("Equals one step of the mousewheel.");
         SetConfigValue(buttonThreshold_, 0.80f)
-            .description("Threshold for analog axes until which the button is not pressed.");
-        if (oldThresh != buttonThreshold_)
-            for (unsigned int i = 0; i < nHalfAxes_s; i++)
-                if (halfAxes_[i].buttonThreshold_ == oldThresh)
-                    halfAxes_[i].buttonThreshold_ = buttonThreshold_;
-
-        // keys
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            readTrigger(keys_[i]);
-        // mouse buttons
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            readTrigger(mouseButtons_[i]);
-        // joy stick buttons
-        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
-            readTrigger(joyStickButtons_[i]);
-        // half axes
-        for (unsigned int i = 0; i < nHalfAxes_s; i++)
-            readTrigger(halfAxes_[i]);
-    }
-
-    void KeyBinder::readTrigger(Button& button)
-    {
-        // config value stuff
-        ConfigValueContainer* cont
-            = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
-        if (!cont)
-        {
-            cont = new ConfigValueContainer
-                (CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "", button.name_);
-            ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
-        }
-        std::string old = button.bindingString_;
-        cont->getValue(&button.bindingString_, this);
-
-        // keybinder stuff
-        if (old != button.bindingString_)
-        {
-            // clear everything so we don't get old axis ParamCommands mixed up
-            button.clear();
-
-            // binding has changed
-            button.parse(paramCommandBuffer_);
+            .description("Threshold for analog axes until which the button is not pressed.")
+            .callback(this, &KeyBinder::buttonThresholdChanged);
+    }
+
+    void KeyBinder::buttonThresholdChanged()
+    {
+        for (unsigned int i = 0; i < allHalfAxes_.size(); i++)
+            if (!allHalfAxes_[i]->bButtonThresholdUser_)
+                allHalfAxes_[i]->buttonThreshold_ = this->buttonThreshold_;
+    }
+
+    void KeyBinder::JoyStickDeviceNumberChanged(unsigned int value)
+    {
+        unsigned int oldValue = numberOfJoySticks_;
+        numberOfJoySticks_ = value;
+
+        // initialise joy stick bindings
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes again
+        compilePointerLists();
+
+        // load the bindings if required
+        if (!configFile_.empty())
+        {
+            for (unsigned int iDev = oldValue; iDev < numberOfJoySticks_; ++iDev)
+            {
+                for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
+                    joyStickButtons_[iDev][i].readConfigValue();
+                for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
+                    joyStickAxes_[iDev][i].readConfigValue();
+            }
+        }
+
+        // Set the button threshold for potential new axes
+        buttonThresholdChanged();
+    }
+
+    void KeyBinder::initialiseJoyStickBindings()
+    {
+        this->joyStickAxes_.resize(numberOfJoySticks_);
+        this->joyStickButtons_.resize(numberOfJoySticks_);
+
+        // reinitialise all joy stick binings (doesn't overwrite the old ones)
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
+        {
+            std::string deviceNumber = convertToString(iDev);
+            // joy stick buttons
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+            {
+                joyStickButtons_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickButtonCode::ByString[i];
+                joyStickButtons_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
+                joyStickButtons_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Buttons";
+            }
+            // joy stick axes
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                joyStickAxes_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickAxisCode::ByString[i >> 1];
+                if (i & 1)
+                    joyStickAxes_[iDev][i].name_ += "Pos";
+                else
+                    joyStickAxes_[iDev][i].name_ += "Neg";
+                joyStickAxes_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
+                joyStickAxes_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Axes";
+            }
+        }
+    }
+
+    void KeyBinder::compilePointerLists()
+    {
+        allButtons_.clear();
+        allHalfAxes_.clear();
+
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+            allButtons_[keys_[i].name_] = keys_ + i;
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+            allButtons_[mouseButtons_[i].name_] = mouseButtons_ + i;
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            allButtons_[mouseAxes_[i].name_] = mouseAxes_ + i;
+            allHalfAxes_.push_back(mouseAxes_ + i);
+        }
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
+        {
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+                allButtons_[joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                allButtons_[joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
+                allHalfAxes_.push_back(&(joyStickAxes_[iDev][i]));
+            }
+        }
+    }
+
+    /**
+    @brief
+        Loads the key and button bindings.
+    @return
+        True if loading succeeded.
+    */
+    void KeyBinder::loadBindings(const std::string& filename)
+    {
+        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
+
+        configFile_ = filename;
+        if (configFile_.empty())
+            return;
+
+        // get bindings from default file if filename doesn't exist.
+        std::ifstream infile;
+        infile.open(configFile_.c_str());
+        if (!infile)
+        {
+            ConfigFileManager::getInstance().setFile(CFT_Keybindings, defaultKeybindings_);
+            ConfigFileManager::getInstance().save(CFT_Keybindings, configFile_);
+        }
+        else
+            infile.close();
+        ConfigFileManager::getInstance().setFile(CFT_Keybindings, configFile_);
+
+        // Parse bindings and create the ConfigValueContainers if necessary
+        clearBindings();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->readConfigValue();
+
+        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
+    }
+
+    bool KeyBinder::setBinding(const std::string& binding, const std::string& name, bool bTemporary)
+    {
+        std::map<std::string, Button*>::iterator it = allButtons_.find(name);
+        if (it != allButtons_.end())
+        {
+            if (bTemporary)
+                it->second->configContainer_->tset(binding);
+            else
+                it->second->configContainer_->set(binding);
+            it->second->configContainer_->getValue(&(it->second->bindingString_), it->second);
+            return true;
+        }
+        else
+        {
+            COUT(2) << "Could not find key/button/axis with name '" << name << "'." << std::endl;
+            return false;
         }
     }
@@ -308,15 +301,6 @@
     void KeyBinder::clearBindings()
     {
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            keys_[i].clear();
-
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            mouseButtons_[i].clear();
-
-        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
-            joyStickButtons_[i].clear();
-
-        for (unsigned int i = 0; i < nHalfAxes_s; i++)
-            halfAxes_[i].clear();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->clear();
 
         for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
@@ -327,8 +311,11 @@
     void KeyBinder::resetJoyStickAxes()
     {
-        for (unsigned int i = 8; i < nHalfAxes_s; i++)
-        {
-            halfAxes_[i].absVal_ = 0.0f;
-            halfAxes_[i].relVal_ = 0.0f;
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; ++iDev)
+        {
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                joyStickAxes_[iDev][i].absVal_ = 0.0f;
+                joyStickAxes_[iDev][i].relVal_ = 0.0f;
+            }
         }
     }
@@ -336,5 +323,5 @@
     void KeyBinder::tickMouse(float dt)
     {
-        tickDevices(0, 8);
+        tickDevices(mouseAxes_, mouseAxes_ + MouseAxisCode::numberOfAxes * 2);
 
         if (bDeriveMouseInput_)
@@ -342,31 +329,28 @@
             if (deriveTime_ > derivePeriod_)
             {
-                //CCOUT(3) << "mouse abs: ";
                 for (int i = 0; i < 2; i++)
                 {
                     if (mouseRelative_[i] > 0)
                     {
-                        halfAxes_[2*i + 0].absVal_
+                        mouseAxes_[2*i + 0].absVal_
                             =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
-                        halfAxes_[2*i + 1].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
                     }
                     else if (mouseRelative_[i] < 0)
                     {
-                        halfAxes_[2*i + 0].absVal_ = 0.0f;
-                        halfAxes_[2*i + 1].absVal_
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_
                             = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
                     }
                     else
                     {
-                        halfAxes_[2*i + 0].absVal_ = 0.0f;
-                        halfAxes_[2*i + 1].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
                     }
-                    //COUT(3) << mouseRelative_[i] << " | ";
                     mouseRelative_[i] = 0;
-                    halfAxes_[2*i + 0].hasChanged_ = true;
-                    halfAxes_[2*i + 1].hasChanged_ = true;
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
                 }
                 deriveTime_ = 0.0f;
-                //COUT(3) << std::endl;
             }
             else
@@ -375,86 +359,40 @@
     }
 
-    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
-    {
-        tickDevices(8, nHalfAxes_s);
-    }
-
-    void KeyBinder::tickInput(float dt)
-    {
-        // execute all buffered bindings (additional parameter)
-        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
-            paramCommandBuffer_[i]->execute();
-
-        // always reset the relative movement of the mouse
-        for (unsigned int i = 0; i < 8; i++)
-            halfAxes_[i].relVal_ = 0.0f;
-    }
-
-    void KeyBinder::tickDevices(unsigned int begin, unsigned int end)
-    {
-        for (unsigned int i = begin; i < end; i++)
+    void KeyBinder::tickDevices(HalfAxis* begin, HalfAxis* end)
+    {
+        for (HalfAxis* current = begin; current < end; ++current) // pointer arithmetic
         {
             // button mode
             // TODO: optimize out all the half axes that don't act as a button at the moment
-            if (halfAxes_[i].hasChanged_)
-            {
-                if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
+            if (current->hasChanged_)
+            {
+                if (!current->wasDown_ && current->absVal_ > current->buttonThreshold_)
                 {
-                    halfAxes_[i].wasDown_ = true;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
-                        halfAxes_[i].execute(KeybindMode::OnPress);
+                    current->wasDown_ = true;
+                    if (current->nCommands_[KeybindMode::OnPress])
+                        current->execute(KeybindMode::OnPress);
                 }
-                else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
+                else if (current->wasDown_ && current->absVal_ < current->buttonThreshold_)
                 {
-                    halfAxes_[i].wasDown_ = false;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
-                        halfAxes_[i].execute(KeybindMode::OnRelease);
+                    current->wasDown_ = false;
+                    if (current->nCommands_[KeybindMode::OnRelease])
+                        current->execute(KeybindMode::OnRelease);
                 }
-                halfAxes_[i].hasChanged_ = false;
-            }
-
-            if (halfAxes_[i].wasDown_)
-            {
-                if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
-                    halfAxes_[i].execute(KeybindMode::OnHold);
+                current->hasChanged_ = false;
+            }
+
+            if (current->wasDown_)
+            {
+                if (current->nCommands_[KeybindMode::OnHold])
+                    current->execute(KeybindMode::OnHold);
             }
 
             // these are the actually useful axis bindings for analog input
-            if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
-            {
-                //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
-                halfAxes_[i].execute();
-            }
-        }
-    }
-
-    void KeyBinder::keyPressed (const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::keyReleased(const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::keyHeld    (const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnHold); }
-
-
-    void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnHold); }
-
-
-    void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnHold); }
+            if (current->relVal_ > analogThreshold_ || current->absVal_ > analogThreshold_)
+            {
+                current->execute();
+            }
+        }
+    }
 
     /**
@@ -473,28 +411,26 @@
             for (int i = 0; i < 2; i++)
             {
-                if (rel[i])
+                if (rel[i]) // performance opt. if rel[i] == 0
                 {
-                    // absolute
-                    halfAxes_[2*i + 0].hasChanged_ = true;
-                    halfAxes_[2*i + 1].hasChanged_ = true;
+                    // write absolute values
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
                     mousePosition_[i] += rel[i];
 
-                    if (bClipMouse_)
-                    {
-                        if (mousePosition_[i] > 1024)
-                            mousePosition_[i] =  1024;
-                        if (mousePosition_[i] < -1024)
-                            mousePosition_[i] = -1024;
-                    }
+                    // clip absolute position
+                    if (mousePosition_[i] > mouseClippingSize_)
+                        mousePosition_[i] =  mouseClippingSize_;
+                    if (mousePosition_[i] < -mouseClippingSize_)
+                        mousePosition_[i] = -mouseClippingSize_;
 
                     if (mousePosition_[i] >= 0)
                     {
-                        halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
-                        halfAxes_[2*i + 1].absVal_ =  0.0f;
+                        mouseAxes_[2*i + 0].absVal_ =   mousePosition_[i]/(float)mouseClippingSize_ * mouseSensitivity_;
+                        mouseAxes_[2*i + 1].absVal_ =  0.0f;
                     }
                     else
                     {
-                        halfAxes_[2*i + 0].absVal_ =  0.0f;
-                        halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
+                        mouseAxes_[2*i + 0].absVal_ =  0.0f;
+                        mouseAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/(float)mouseClippingSize_ * mouseSensitivity_;
                     }
                 }
@@ -511,7 +447,7 @@
         {
             if (rel[i] > 0)
-                halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
-            else
-                halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
+                mouseAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/(float)mouseClippingSize_ * mouseSensitivity_;
+            else
+                mouseAxes_[1 + 2*i].relVal_ = -((float)rel[i])/(float)mouseClippingSize_ * mouseSensitivity_;
         }
     }
@@ -523,45 +459,37 @@
     void KeyBinder::mouseScrolled(int abs, int rel)
     {
-        //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
-
         if (rel > 0)
-            for (int i = 0; i < rel/120; i++)
-                mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
+            for (int i = 0; i < rel/mouseWheelStepSize_; i++)
+                mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/mouseWheelStepSize_);
         else
-            for (int i = 0; i < -rel/120; i++)
-                mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
+            for (int i = 0; i < -rel/mouseWheelStepSize_; i++)
+                mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/mouseWheelStepSize_);
     }
 
     void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
     {
-        int i = 8 + axis * 2;
+        int i = axis * 2;
         if (value >= 0)
         {
-            //if (value > 10000)
-            //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
-
-            halfAxes_[i].absVal_ = value;
-            halfAxes_[i].relVal_ = value;
-            halfAxes_[i].hasChanged_ = true;
-            if (halfAxes_[i + 1].absVal_ > 0.0f)
-            {
-                halfAxes_[i + 1].absVal_ = -0.0f;
-                halfAxes_[i + 1].relVal_ = -0.0f;
-                halfAxes_[i + 1].hasChanged_ = true;
+            joyStickAxes_[joyStickID][i].absVal_ = value;
+            joyStickAxes_[joyStickID][i].relVal_ = value;
+            joyStickAxes_[joyStickID][i].hasChanged_ = true;
+            if (joyStickAxes_[joyStickID][i + 1].absVal_ > 0.0f)
+            {
+                joyStickAxes_[joyStickID][i + 1].absVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i + 1].relVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
             }
         }
         else
         {
-            //if (value < -10000)
-            //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
-
-            halfAxes_[i + 1].absVal_ = -value;
-            halfAxes_[i + 1].relVal_ = -value;
-            halfAxes_[i + 1].hasChanged_ = true;
-            if (halfAxes_[i].absVal_ > 0.0f)
-            {
-                halfAxes_[i].absVal_ = -0.0f;
-                halfAxes_[i].relVal_ = -0.0f;
-                halfAxes_[i].hasChanged_ = true;
+            joyStickAxes_[joyStickID][i + 1].absVal_ = -value;
+            joyStickAxes_[joyStickID][i + 1].relVal_ = -value;
+            joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
+            if (joyStickAxes_[joyStickID][i].absVal_ > 0.0f)
+            {
+                joyStickAxes_[joyStickID][i].absVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i].relVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i].hasChanged_ = true;
             }
         }
