Index: code/branches/network/src/core/InputManager.cc
===================================================================
--- code/branches/network/src/core/InputManager.cc	(revision 1421)
+++ code/branches/network/src/core/InputManager.cc	(revision 1422)
@@ -52,6 +52,6 @@
   InputManager::InputManager() :
       inputSystem_(0), keyboard_(0), mouse_(0),
-      keyBinder_(0), buffer_(0),
       joySticksSize_(0),
+      keyBinder_(0), buffer_(0), keyDetector_(0),
       state_(IS_UNINIT), stateRequest_(IS_UNINIT),
       keyboardModifiers_(0)
Index: code/branches/network/src/core/KeyBinder.cc
===================================================================
--- code/branches/network/src/core/KeyBinder.cc	(revision 1421)
+++ code/branches/network/src/core/KeyBinder.cc	(revision 1422)
@@ -46,7 +46,12 @@
 {
   // ###############################
-  // ######      Button       ######
-  // ###############################
-
+  // ###  BufferedParamCommand   ###
+  // ###############################
+
+  /**
+  * Executes a buffered command. This is used for commands with additional
+  * parameters.
+  * @return True if command execution was successful or value was zero.
+  */
   bool BufferedParamCommand::execute()
   {
@@ -64,4 +69,12 @@
   }
 
+  // ###############################
+  // #####    SimpleCommand    #####
+  // ###############################
+
+  /**
+  * Executes a simple command with no additional paramters.
+  * @return True if command execution was successful, false otherwise.
+  */
   bool SimpleCommand::execute(float abs, float rel)
   {
@@ -69,24 +82,59 @@
   }
 
+  // ###############################
+  // #####    ParamCommand     #####
+  // ###############################
+
+  /**
+  * Executes a parameter command. The commmand string is not directly executed,
+  * but instead stored in a buffer list so that values can be combined.
+  * @return Always true.
+  */
   bool ParamCommand::execute(float abs, float rel)
   {
-    BufferedParamCommand& paramCommand = *paramCommand_;
+    BufferedParamCommand& cmd = *paramCommand_;
     // command has an additional parameter
-    if (bRelative_ && (rel > 0 || rel < 0))
-    {
-      // we have to calculate a relative movement.
-      // paramModifier_ says how much one keystroke is
-      paramCommand.value_ += paramModifier_ * rel;
-    }
-    else if (abs > 0 || abs < 0)
-    {
-      // we have to calculate absolute position of the axis.
-      // 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)
-                            /++paramCommand.nValuesAdded_;
+    if (bRelative_)
+    {
+      if (rel != 0.0f)
+      {
+        // we have to calculate a relative movement.
+        // paramModifier_ says how much one keystroke is
+        cmd.value_ += paramModifier_ * rel;
+      }
+    }
+    else if (abs != 0.0f)
+    {
+      // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
+      // and normally this is caught in tickInput(), but that threshold cannot be to high
+      // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
+      // Someone only uses buttons with an active joystick. The joy stick value could then
+      // be 0.05 for instance and the the key value 1. Without handling the problem, the final
+      // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
+      float absQ = abs * abs;
+      float valueQ = cmd.value_ * cmd.value_;
+      if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
+      {
+        cmd.value_ = abs * paramModifier_;
+        cmd.nValuesAdded_ = 1;
+      }
+      else if (absQ * 50.0f < valueQ)
+      {
+        // abs is too small, we just don't do anything
+      }
+      else
+      {
+        // we have to calculate the absolute position of the axis.
+        // Since there might be another axis that is affected, we have to wait and
+        // store the result in a temporary place
+        cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
+      }
     }
     return true;
   }
+
+  // ###############################
+  // #####       Button        #####
+  // ###############################
 
   void Button::clear()
@@ -259,4 +307,8 @@
     return true;
   }
+
+  // ###############################
+  // #####      HalfAxis       #####
+  // ###############################
 
   void HalfAxis::clear()
@@ -494,5 +546,5 @@
     SetConfigValue(mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
     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(derivePeriod_, 0.5f).description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
     SetConfigValue(mouseSensitivityDerived_, 1.0f).description("Mouse sensitivity if mouse input is derived.");
 
Index: code/branches/network/src/orxonox/Orxonox.cc
===================================================================
--- code/branches/network/src/orxonox/Orxonox.cc	(revision 1421)
+++ code/branches/network/src/orxonox/Orxonox.cc	(revision 1422)
@@ -466,4 +466,8 @@
     timer_->reset();
 
+    float renderTime = 0.0f;
+    float frameTime = 0.0f;
+    clock_t time = 0;
+
     COUT(3) << "Orxonox: Starting the main loop." << std::endl;
 	  while (!bAbort_)
@@ -480,14 +484,21 @@
       evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
       evt.timeSinceLastFrame = calculateEventTime(now, eventTimes[1]);
+      frameTime += evt.timeSinceLastFrame;
 
       // show the current time in the HUD
       // HUD::getSingleton().setTime(now);
+      if (frameTime > 0.4f)
+      {
+        HUD::getSingleton().setRenderTimeRatio(renderTime / frameTime);
+        frameTime = 0.0f;
+        renderTime = 0.0f;
+      }
 
       // Call those objects that need the real time
+      for (Iterator<TickableReal> it = ObjectList<TickableReal>::start(); it; ++it)
+        it->tick((float)evt.timeSinceLastFrame);
+      // Call the scene objects
       for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; ++it)
         it->tick((float)evt.timeSinceLastFrame * this->timefactor_);
-      // Call the scene objects
-      for (Iterator<TickableReal> it = ObjectList<TickableReal>::start(); it; ++it)
-        it->tick((float)evt.timeSinceLastFrame);
       // TODO: currently a hack. Somehow the console doesn't work with OrxonoxClass
       orxonoxConsole_->tick((float)evt.timeSinceLastFrame);
@@ -497,12 +508,16 @@
       ogreRoot._fireFrameStarted(evt);
 
-      ogreRoot._updateAllRenderTargets(); // only render in non-server mode
-
       // get current time
       now = timer_->getMilliseconds();
+      calculateEventTime(now, eventTimes[2]);
+
+      ogreRoot._updateAllRenderTargets(); // only render in non-server mode
+
+      // get current time
+      now = timer_->getMilliseconds();
 
       // create an event to pass to the frameEnded method in ogre
       evt.timeSinceLastEvent = calculateEventTime(now, eventTimes[0]);
-      evt.timeSinceLastFrame = calculateEventTime(now, eventTimes[2]);
+      renderTime += calculateEventTime(now, eventTimes[2]);
 
       // again, just to be sure ogre works fine
Index: code/branches/network/src/orxonox/hud/HUD.cc
===================================================================
--- code/branches/network/src/orxonox/hud/HUD.cc	(revision 1421)
+++ code/branches/network/src/orxonox/hud/HUD.cc	(revision 1422)
@@ -75,4 +75,14 @@
         fpsText->setCaption("init");
 
+        // creating text to display render time ratio
+        rTRText = static_cast<TextAreaOverlayElement*>(om->createOverlayElement("TextArea", "rTRText"));
+        rTRText->show();
+        rTRText->setMetricsMode(Ogre::GMM_PIXELS);
+        rTRText->setDimensions(0.001, 0.001);
+        rTRText->setPosition(10, 30);
+        rTRText->setFontName("Console");
+        rTRText->setCharHeight(20);
+        rTRText->setCaption("init");
+
         // create energy bar
         energyBar = static_cast<BarOverlayElement*>(om->createOverlayElement("Bar", "energyBar"));
@@ -99,4 +109,5 @@
         container->setMetricsMode(Ogre::GMM_RELATIVE);
         container->addChild(fpsText);
+        container->addChild(rTRText);
 
         energyBar->init(0.01, 0.94, 0.4, container);
@@ -133,4 +144,9 @@
         float fps = GraphicsEngine::getSingleton().getAverageFPS();
         fpsText->setCaption("FPS: " + Ogre::StringConverter::toString(fps));
+    }
+
+    void HUD::setRenderTimeRatio(float ratio)
+    {
+      rTRText->setCaption("Render time ratio: " + Ogre::StringConverter::toString(ratio));
     }
 
Index: code/branches/network/src/orxonox/hud/HUD.h
===================================================================
--- code/branches/network/src/orxonox/hud/HUD.h	(revision 1421)
+++ code/branches/network/src/orxonox/hud/HUD.h	(revision 1422)
@@ -49,4 +49,5 @@
         Ogre::OverlayContainer* container;
         Ogre::TextAreaOverlayElement* fpsText;
+        Ogre::TextAreaOverlayElement* rTRText;
         BarOverlayElement* energyBar;
         BarOverlayElement* speedoBar;
@@ -60,4 +61,5 @@
         void addRadarObject(Vector3 pos);
         RadarObject* getFirstRadarObject();
+        void setRenderTimeRatio(float ratio);
 
         static HUD* instance_s;
