Index: /code/branches/input/bin/keybindings.ini
===================================================================
--- /code/branches/input/bin/keybindings.ini	(revision 1343)
+++ /code/branches/input/bin/keybindings.ini	(revision 1344)
@@ -154,12 +154,16 @@
 MouseButton6=
 MouseButton7=
-MouseXPos=exit | ButtonThreshold 0.85
+MouseWheel1Up=AxisAmp 0.1 slomo
+MouseWheel1Down=AxisAmp 0.1 slomo
+MouseWheel2Up=
+MouseWheel2Down=
+MouseXPos= #exit | ButtonThreshold 0.85
 MouseXNeg=
 MouseYPos=
 MouseYNeg=
-MouseWheel1Pos=
-MouseWheel1Neg=
-MouseWheel2Pos=
-MouseWheel2Neg=
+Empty1Pos=
+Empty1Neg=
+Empty2Pos=
+Empty2Neg=
 JoyAxis1Pos=
 JoyAxis1Neg=
Index: /code/branches/input/src/core/InputHandler.cc
===================================================================
--- /code/branches/input/src/core/InputHandler.cc	(revision 1343)
+++ /code/branches/input/src/core/InputHandler.cc	(revision 1344)
@@ -72,15 +72,14 @@
     BufferedParamCommand& paramCommand = *paramCommand_;
     // command has an additional parameter
-    if (bRelative_)
+    if (bRelative_ && (rel > 0 || rel < 0))
     {
       // we have to calculate a relative movement.
-      // amplitude says how much one keystroke is
+      // paramModifier_ says how much one keystroke is
       paramCommand.value_ += paramModifier_ * rel;
     }
-    else
+    else if (abs > 0 || abs < 0)
     {
       // we have to calculate absolute position of the axis.
-      // for a key this simply is 1, but multiplied by a user defined factor
-      // since there might be another axis that is affected, we have to wait and
+      // Since there might be another axis that is affected, we have to wait and
       // store the result in a temporary place
       paramCommand.value_ = (paramCommand.value_ * paramCommand.nValuesAdded_ + paramModifier_ * abs)
@@ -254,9 +253,9 @@
   }
 
-  bool Button::execute(KeybindMode::Enum mode)
+  bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
   {
     // execute all the parsed commands in the string
     for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
-      commands_[mode][iCommand]->execute();
+      commands_[mode][iCommand]->execute(abs, rel);
     return true;
   }
@@ -306,5 +305,5 @@
     @brief Constructor that does as little as necessary.
   */
-  KeyBinder::KeyBinder()
+  KeyBinder::KeyBinder() : deriveTime_(0.0f)
   {
     RegisterObject(KeyBinder);
@@ -413,5 +412,7 @@
       "MouseLeft", "MouseRight", "MouseMiddle",
       "MouseButton3", "MouseButton4", "MouseButton5",
-      "MouseButton6", "MouseButton7" };
+      "MouseButton6", "MouseButton7",
+      "MouseWheel1Up", "MouseWheel1Down",
+      "MouseWheel2Up", "MouseWheel2Down" };
     for (int i = 0; i < nMouseButtons_s; i++)
       mouseButtons_[i].name_ = mouseButtonNames[i];
@@ -432,6 +433,6 @@
     rawNames[0] = "MouseX";
     rawNames[1] = "MouseY";
-    rawNames[2] = "MouseWheel1";
-    rawNames[3] = "MouseWheel2";
+    rawNames[2] = "Empty1";
+    rawNames[3] = "Empty2";
     for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
       rawNames[i] = "JoyAxis" + getConvertedValue<int, std::string>(i - 3);
@@ -475,5 +476,9 @@
   void KeyBinder::setConfigValues()
   {
-    SetConfigValue(analogThreshold_, 0.01f).description("Threshold for analog axes until which the state is 0.");
+    SetConfigValue(analogThreshold_, 0.01f)  .description("Threshold for analog axes until which the state is 0.");
+    SetConfigValue(bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
+    SetConfigValue(derivePeriod_, 0.1f)      .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
+    SetConfigValue(mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
+
     float oldThresh = buttonThreshold_;
     SetConfigValue(buttonThreshold_, 0.80f).description("Threshold for analog axes until which the button is not pressed.");
@@ -573,4 +578,31 @@
     }
 
+    if (bDeriveMouseInput_)
+    {
+      if (deriveTime_ > derivePeriod_)
+      {
+        deriveTime_ = 0.0f;
+        CCOUT(3) << "mouse abs: ";
+        for (int i = 0; i < 2; i++)
+        {
+          if (mouseRelative_[i] > 0)
+          {
+            halfAxes_[2*i + 0].absVal_ = mouseRelative_[i] * derivePeriod_ / 500;
+            halfAxes_[2*i + 1].absVal_ = 0.0f;
+          }
+          else if (mouseRelative_[0] < 0)
+          {
+            halfAxes_[2*i + 0].absVal_ = 0.0f;
+            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] * derivePeriod_ / 500;
+          }
+          COUT(3) << mouseRelative_[i] << " | ";
+          mouseRelative_[i] = 0.0f;
+        }
+        COUT(3) << std::endl;
+      }
+      else
+        deriveTime_ += dt;
+    }
+
     // execute all buffered bindings (addional parameter)
     for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
@@ -578,6 +610,6 @@
 
     // always reset the relative movement of the mouse
-    for (unsigned int i = 0; i < 4; i++)
-      halfAxes_[i].relVal_ = 0;
+    for (unsigned int i = 0; i < 8; i++)
+      halfAxes_[i].relVal_ = 0.0f;
   }
 
@@ -615,117 +647,57 @@
     @param e Mouse state information
   */
-  void KeyBinder::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
-  {
-    // translate absolute mouse position into joystick like behaviour
-    if (clippingSize.x > clippingSize.y)
-    {
-      int margin = (clippingSize.x - clippingSize.y) / 2;
-      if (abs.x - margin > clippingSize.y)
+  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
+  {
+    if (!bDeriveMouseInput_)
+    {
+      // y axis of mouse input is inverted
+      int rel[] = { rel_.x * mouseSensitivity_, -rel_.y * mouseSensitivity_ };
+
+      COUT(3) << rel[0] << " | " << rel[1] << std::endl;
+
+      for (int i = 0; i < 2; i++)
       {
-        halfAxes_[0].absVal_ = 1.0f;
-        halfAxes_[1].absVal_ = 0.0f;
-      }
-      else if (abs.x < margin)
-      {
-        halfAxes_[0].absVal_ = 0.0f;
-        halfAxes_[1].absVal_ = 1.0f;
-      }
-      else
-      {
-        float temp = ((float)abs.x) / clippingSize.y * 2 - 1;
-        if (temp > 0)
+        if (rel[i])
         {
-          halfAxes_[0].absVal_ = temp;
-          halfAxes_[1].absVal_ = 0.0f;
-        }
-        else
-        {
-          halfAxes_[0].absVal_ = 0.0f;
-          halfAxes_[1].absVal_ = -temp;
+          // absolute
+          if (mousePosition_[i] >= 0)
+          {
+            mousePosition_[i] += rel[i];
+            halfAxes_[0 + 2*i].hasChanged_ = true;
+            if (mousePosition_[i] < 0)
+            {
+              halfAxes_[1 + 2*i].hasChanged_ = true;
+              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024;
+              halfAxes_[0 + 2*i].absVal_ =  0.0f;
+            }
+            else
+              halfAxes_[1 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024;
+          }
+          else
+          {
+            mousePosition_[i] += rel[i];
+            halfAxes_[1 + 2*i].hasChanged_ = true;
+            if (mousePosition_[i] > 0)
+            {
+              halfAxes_[0 + 2*i].hasChanged_ = true;
+              halfAxes_[0 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024;
+              halfAxes_[1 + 2*i].absVal_ =  0.0f;
+            }
+            else
+              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024;
+          }
+
+          // relative
+          if (rel[i] > 0)
+            halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024;
+          else
+            halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024;
         }
       }
-
-      float temp = -((float)abs.y) / clippingSize.y * 2 + 1;
-      if (temp > 0)
-      {
-        halfAxes_[2].absVal_ = temp;
-        halfAxes_[3].absVal_ = 0.0;
-      }
-      else
-      {
-        halfAxes_[2].absVal_ = 0.0;
-        halfAxes_[3].absVal_ = -temp;
-      }
     }
     else
     {
-      float temp = ((float)abs.x) / clippingSize.x * 2 - 1;
-      if (temp > 0)
-      {
-        halfAxes_[0].absVal_ = temp;
-        halfAxes_[1].absVal_ = 0.0;
-      }
-      else
-      {
-        halfAxes_[0].absVal_ = 0.0;
-        halfAxes_[1].absVal_ = -temp;
-      }
-
-      int margin = (clippingSize.y - clippingSize.x) / 2;
-      if (abs.y - margin > clippingSize.x)
-      {
-        halfAxes_[2].absVal_ = 0.0;
-        halfAxes_[3].absVal_ = 1.0;
-      }
-      else if (abs.y < margin)
-      {
-        halfAxes_[2].absVal_ = 1.0;
-        halfAxes_[3].absVal_ = 0.0;
-      }
-      else
-      {
-        float temp = -((float)abs.y) / clippingSize.x * 2 + 1;
-        if (temp > 0)
-        {
-          halfAxes_[2].absVal_ = temp;
-          halfAxes_[3].absVal_ = 0.0;
-        }
-        else
-        {
-          halfAxes_[2].absVal_ = 0.0;
-          halfAxes_[3].absVal_ = -temp;
-        }
-      }
-    }
-
-    // relative movements
-    if (rel.x > 0)
-    {
-      halfAxes_[0].hasChanged_ = true;
-      halfAxes_[1].hasChanged_ = true;
-      halfAxes_[0].relVal_ = rel.x;
-      halfAxes_[1].relVal_ = 0.0;
-    }
-    else if (rel.x < 0)
-    {
-      halfAxes_[0].hasChanged_ = true;
-      halfAxes_[1].hasChanged_ = true;
-      halfAxes_[0].relVal_ = 0.0;
-      halfAxes_[1].relVal_ = rel.x;
-    }
-
-    if (rel.y /*!*/ < /*!*/ 0)
-    {
-      halfAxes_[2].hasChanged_ = true;
-      halfAxes_[3].hasChanged_ = true;
-      halfAxes_[0].relVal_ = -rel.y;
-      halfAxes_[1].relVal_ = 0.0;
-    }
-    else if (rel.y > 0)
-    {
-      halfAxes_[2].hasChanged_ = true;
-      halfAxes_[3].hasChanged_ = true;
-      halfAxes_[0].relVal_ = 0.0;
-      halfAxes_[1].relVal_ = -rel.y;
+      mouseRelative_[0] += rel_.x * mouseSensitivity_;
+      mouseRelative_[1] -= rel_.y * mouseSensitivity_;
     }
   }
@@ -737,5 +709,12 @@
   void KeyBinder::mouseScrolled(int abs, int rel)
   {
-    // TODO: obvious...
+    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);
+    else
+      for (int i = 0; i < -rel/120; i++)
+        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
   }
 
@@ -743,5 +722,5 @@
   {
     // TODO: check whether 16 bit integer as general axis value is a good idea (works under windows)
-    //CCOUT(3) << axis << std::endl;
+    CCOUT(3) << halfAxes_[8 + axis].name_ << std::endl;
     if (value >= 0)
     {
Index: /code/branches/input/src/core/InputHandler.h
===================================================================
--- /code/branches/input/src/core/InputHandler.h	(revision 1343)
+++ /code/branches/input/src/core/InputHandler.h	(revision 1344)
@@ -60,4 +60,5 @@
     BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
     bool execute();
+
     float value_;
     unsigned int nValuesAdded_;
@@ -93,5 +94,5 @@
     virtual bool addParamCommand(ParamCommand* command) { return false; }
     void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
-    bool execute(KeybindMode::Enum mode);
+    bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
 
     //! The configured string value
@@ -114,6 +115,7 @@
     HalfAxis() : relVal_(0.0f), absVal_(0.0f), paramCommands_(0), nParamCommands_(0),
                  wasDown_(false), hasChanged_(false) { }
+    using Button::execute;
     bool execute();
-    bool execute(KeybindMode::Enum mode) { return Button::execute(mode); }
+    //bool execute(KeybindMode::Enum mode) { return Button::execute(mode); }
     bool addParamCommand(ParamCommand* command);
     void clear();
@@ -176,5 +178,5 @@
 
     //! denotes the number of different mouse buttons there are in OIS.
-    static const unsigned int nMouseButtons_s = 8;
+    static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels
     //! Actual key bindings as bundle for Press, Hold and Release
     Button mouseButtons_ [nMouseButtons_s];
@@ -193,5 +195,5 @@
     * Sequence is as follows:
     *  0 -  3: Mouse x and y
-    *  4 -  7: Mouse scroll wheels 1 and 2 (2 not yet supported)
+    *  4 -  7: empty
     *  8 - 23: joy stick (slider) axes 1 to 8
     * 24 - 55: joy stick axes 1 - 16
@@ -205,8 +207,21 @@
     std::vector<BufferedParamCommand*> paramCommandBuffer_;
 
+    //! Keeps track of the absolute mouse value (incl. scroll wheel)
+    int mousePosition_[3];
+    //! Used to derive mouse input if requested
+    int mouseRelative_[2];
+    float deriveTime_;
+
+    //**** ConfigValues *****\\
     //! Threshold for analog triggers until which the state is 0.
     float analogThreshold_;
     //! Threshold for analog triggers until which the button is not pressed.
     float buttonThreshold_;
+    //! Derive mouse input for absolute values?
+    bool bDeriveMouseInput_;
+    //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
+    float derivePeriod_;
+    //! mouse sensitivity
+    float mouseSensitivity_;
   };
 
Index: /code/branches/input/src/util/Math.h
===================================================================
--- /code/branches/input/src/util/Math.h	(revision 1343)
+++ /code/branches/input/src/util/Math.h	(revision 1344)
@@ -156,3 +156,13 @@
 };
 
+class _UtilExport IntVector3
+{
+public:
+  IntVector3() : x(0), y(0), z(0) { }
+  IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }
+  int x;
+  int y;
+  int z;
+};
+
 #endif /* _Util_Math_H__ */
