]> git.mxchange.org Git - flightgear.git/blobdiff - src/Input/FGMouseInput.cxx
Merge branch 'next' of gitorious.org:fg/flightgear into next
[flightgear.git] / src / Input / FGMouseInput.cxx
index c0b7e3f87620169f7b43131d094f24ae109a74af..927106f47c490543a4fa6425af1ca8318b931c0a 100644 (file)
 //
 // $Id$
 
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
 #include "FGMouseInput.hxx"
+#include "Main/globals.hxx"
+
+using std::ios_base;
 
-\f
-void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea ) 
+void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
 {
   // Get the list of hit callbacks. Take the first callback that
   // accepts the mouse button press and ignore the rest of them
@@ -33,7 +39,7 @@ void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
   // The nearest one is the first one and the deepest
   // (the most specialized one in the scenegraph) is the first.
   std::vector<SGSceneryPick> pickList;
-  if (FGRenderer::pick(pickList, ea)) {
+  if (globals->get_renderer()->pick(pickList, ea)) {
     std::vector<SGSceneryPick>::const_iterator i;
     for (i = pickList.begin(); i != pickList.end(); ++i) {
       if (i->callback->buttonPressed(b, i->info)) {
@@ -44,7 +50,7 @@ void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
   }
 }
 
-void ActivePickCallbacks::update( double dt ) 
+void ActivePickCallbacks::update( double dt )
 {
   // handle repeatable mouse press events
   for( iterator mi = begin(); mi != end(); ++mi ) {
@@ -74,7 +80,14 @@ const FGMouseInput::MouseCursorMap FGMouseInput::mouse_cursor_map[] = {
 
 FGMouseInput * FGMouseInput::mouseInput = NULL;
 
-FGMouseInput::FGMouseInput()
+FGMouseInput::FGMouseInput() :
+  haveWarped(false),
+  xSizeNode(fgGetNode("/sim/startup/xsize", false ) ),
+  ySizeNode(fgGetNode("/sim/startup/ysize", false ) ),
+  xAccelNode(fgGetNode("/devices/status/mice/mouse/accel-x", true ) ),
+  yAccelNode(fgGetNode("/devices/status/mice/mouse/accel-y", true ) ),
+  hideCursorNode(fgGetNode("/sim/mouse/hide-cursor", true ) ),
+  cursorTimeoutNode(fgGetNode("/sim/mouse/cursor-timeout-sec", true ) )
 {
   if( mouseInput == NULL )
     mouseInput = this;
@@ -103,16 +116,17 @@ void FGMouseInput::init()
     mouse &m = bindings[i];
 
                                 // Grab node pointers
-    char buf[64];
-    sprintf(buf, "/devices/status/mice/mouse[%d]/mode", i);
-    m.mode_node = fgGetNode(buf);
+    std::ostringstream buf;
+    buf <<  "/devices/status/mice/mouse[" << i << "]/mode";
+    m.mode_node = fgGetNode(buf.str().c_str());
     if (m.mode_node == NULL) {
-      m.mode_node = fgGetNode(buf, true);
+      m.mode_node = fgGetNode(buf.str().c_str(), true);
       m.mode_node->setIntValue(0);
     }
     for (j = 0; j < MAX_MOUSE_BUTTONS; j++) {
-      sprintf(buf, "/devices/status/mice/mouse[%d]/button[%d]", i, j);
-      m.mouse_button_nodes[j] = fgGetNode(buf, true);
+      buf.seekp(ios_base::beg);
+      buf << "/devices/status/mice/mouse["<< i << "]/button[" << j << "]";
+      m.mouse_button_nodes[j] = fgGetNode(buf.str().c_str(), true);
       m.mouse_button_nodes[j]->setBoolValue(false);
     }
 
@@ -141,11 +155,12 @@ void FGMouseInput::init()
 
                                 // Read the button bindings for this mode
       m.modes[j].buttons = new FGButton[MAX_MOUSE_BUTTONS];
-      char buf[32];
+      std::ostringstream buf;
       for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
-        sprintf(buf, "mouse button %d", k);
+        buf.seekp(ios_base::beg);
+        buf << "mouse button " << k;
         SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
-        m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf, module );
+        m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf.str(), module );
       }
 
                                 // Read the axis bindings for this mode
@@ -160,25 +175,28 @@ void FGMouseInput::init()
 
 void FGMouseInput::update ( double dt )
 {
+  double cursorTimeout = cursorTimeoutNode ? cursorTimeoutNode->getDoubleValue() : 10.0;
+
   mouse &m = bindings[0];
   int mode =  m.mode_node->getIntValue();
   if (mode != m.current_mode) {
     m.current_mode = mode;
-    m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
+    m.timeout = cursorTimeout;
     if (mode >= 0 && mode < m.nModes) {
       fgSetMouseCursor(m.modes[mode].cursor);
-      m.x = fgGetInt("/sim/startup/xsize", 800) / 2;
-      m.y = fgGetInt("/sim/startup/ysize", 600) / 2;
+      m.x = (xSizeNode ? xSizeNode->getIntValue() : 800) / 2;
+      m.y = (ySizeNode ? ySizeNode->getIntValue() : 600) / 2;
       fgWarpMouse(m.x, m.y);
+      haveWarped = true;
     } else {
       SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode " << mode << " out of range");
       fgSetMouseCursor(MOUSE_CURSOR_POINTER);
     }
   }
 
-  if ( fgGetBool( "/sim/mouse/hide-cursor", true ) ) {
+  if ( hideCursorNode ==NULL || hideCursorNode->getBoolValue() ) {
       if ( m.x != m.save_x || m.y != m.save_y ) {
-          m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
+          m.timeout = cursorTimeout;
           if (fgGetMouseCursor() == MOUSE_CURSOR_NONE)
               fgSetMouseCursor(m.modes[mode].cursor);
       } else {
@@ -202,6 +220,7 @@ FGMouseInput::mouse::mouse ()
     save_y(-1),
     nModes(1),
     current_mode(0),
+    timeout(0),
     modes(NULL)
 {
 }
@@ -291,8 +310,8 @@ void FGMouseInput::doMouseMotion (int x, int y)
   // callback.  Glut doesn't.
   int modifiers = KEYMOD_NONE;
 
-  int xsize = fgGetInt("/sim/startup/xsize", 800);
-  int ysize = fgGetInt("/sim/startup/ysize", 600);
+  int xsize = xSizeNode ? xSizeNode->getIntValue() : 800;
+  int ysize = ySizeNode ? ySizeNode->getIntValue() : 600;
 
   mouse &m = bindings[0];
 
@@ -310,35 +329,51 @@ void FGMouseInput::doMouseMotion (int x, int y)
       m.y = y;
       return;
   }
-
+  
+  if (haveWarped)
+  {
+      // don't fire mouse-movement events at the first update after warping the mouse,
+      // just remember the new mouse position
+      haveWarped = false;
+  }
+  else
+  {
                                 // OK, PUI didn't want the event,
                                 // so we can play with it.
-  if (x != m.x) {
-    int delta = x - m.x;
-    for (unsigned int i = 0; i < mode.x_bindings[modifiers].size(); i++)
-      mode.x_bindings[modifiers][i]->fire(double(delta), double(xsize));
-  }
-  if (y != m.y) {
-    int delta = y - m.y;
-    for (unsigned int i = 0; i < mode.y_bindings[modifiers].size(); i++)
-      mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
+      if (x != m.x) {
+        int delta = x - m.x;
+        xAccelNode->setIntValue( delta );
+        for (unsigned int i = 0; i < mode.x_bindings[modifiers].size(); i++)
+          mode.x_bindings[modifiers][i]->fire(double(delta), double(xsize));
+      }
+      if (y != m.y) {
+        int delta = y - m.y;
+        yAccelNode->setIntValue( -delta );
+        for (unsigned int i = 0; i < mode.y_bindings[modifiers].size(); i++)
+          mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
+      }
   }
-
                                 // Constrain the mouse if requested
   if (mode.constrained) {
+    int new_x=x,new_y=y;
+    
     bool need_warp = false;
     if (x <= (xsize * .25) || x >= (xsize * .75)) {
-      x = int(xsize * .5);
+      new_x = int(xsize * .5);
       need_warp = true;
     }
 
     if (y <= (ysize * .25) || y >= (ysize * .75)) {
-      y = int(ysize * .5);
+      new_y = int(ysize * .5);
       need_warp = true;
     }
 
     if (need_warp)
-      fgWarpMouse(x, y);
+    {
+      fgWarpMouse(new_x, new_y);
+      haveWarped = true;
+      SG_LOG(SG_INPUT, SG_DEBUG, "Mouse warp: " << x << ", " << y << " => " << new_x << ", " << new_y);
+    }
   }
 
   if (m.x != x)