]> git.mxchange.org Git - flightgear.git/commitdiff
Joystick updates from David Megginson to add the beginnings of button support.
authorcurt <curt>
Fri, 14 Jul 2000 15:46:27 +0000 (15:46 +0000)
committercurt <curt>
Fri, 14 Jul 2000 15:46:27 +0000 (15:46 +0000)
src/Joystick/joystick.cxx
src/Main/bfi.cxx
src/Main/bfi.hxx

index 49a1655d35bfaf5601ba3b4f0e55d6a261a4997a..d72c5cad4e43d2e1ccd39660d5e35d7eaac53d21 100644 (file)
@@ -41,6 +41,7 @@ using std::string;
 
 static const int MAX_JOYSTICKS = 10;
 static const int MAX_AXES = 10;
+static const int MAX_BUTTONS = 10;
 
 
 /**
@@ -54,6 +55,10 @@ static const char * axisNames[] = {
   "axis0", "axis1", "axis2", "axis3", "axis4",
   "axis5", "axis6", "axis7", "axis8", "axis9"
 };
+static const char * buttonNames[] = {
+  "button0", "button1", "button2", "button3", "button4",
+  "button5", "button6", "button7", "button8", "button9"
+};
 
 
 /**
@@ -70,6 +75,25 @@ struct axis {
 };
 
 
+/**
+ * Settings for a single button.
+ */
+struct button {
+  enum Action {
+    TOGGLE,
+    SWITCH,
+    ADJUST
+  };
+  button () : value(0), step(0.0), action(ADJUST), isRepeatable(true),
+             lastState(-1) {}
+  FGValue * value;
+  float step;
+  Action action;
+  bool isRepeatable;
+  int lastState;
+};
+
+
 /**
  * Settings for a single joystick.
  */
@@ -77,6 +101,7 @@ struct joystick {
   virtual ~joystick () { delete js; delete axes; }
   jsJoystick * js;
   axis * axes;
+  button * buttons;
 };
 
 
@@ -121,6 +146,61 @@ setupDefaults ()
   if (!props.getValue("/input/js0/axis3/control")) {
     props.setStringValue("/input/js0/axis3/control", "/controls/rudder");
     props.setFloatValue("/input/js0/axis3/dead-band", 0.3);
+  }
+
+                               // Default button 0 to all brakes
+  if (!props.getValue("/input/js0/button0/control")) {
+    props.setStringValue("/input/js0/button0/action", "switch");
+    props.setStringValue("/input/js0/button0/control", "/controls/brake");
+    props.setFloatValue("/input/js0/button0/step", 1.0);
+    props.setFloatValue("/input/js0/button0/repeatable", false);
+  }
+
+                               // Default button 1 to left brake.
+  if (!props.getValue("/input/js0/button1/control")) {
+    props.setStringValue("/input/js0/button1/action", "switch");
+    props.setStringValue("/input/js0/button1/control", "/controls/left-brake");
+    props.setFloatValue("/input/js0/button1/step", 1.0);
+    props.setFloatValue("/input/js0/button1/repeatable", false);
+  }
+
+                               // Default button 2 to right brake.
+  if (!props.getValue("/input/js0/button2/control")) {
+    props.setStringValue("/input/js0/button2/action", "switch");
+    props.setStringValue("/input/js0/button2/control",
+                        "/controls/right-brake");
+    props.setFloatValue("/input/js0/button2/step", 1.0);
+    props.setFloatValue("/input/js0/button2/repeatable", false);
+  }
+
+                               // Default buttons 3 and 4 to elevator trim
+  if (!props.getValue("/input/js0/button3/control")) {
+    props.setStringValue("/input/js0/button3/action", "adjust");
+    props.setStringValue("/input/js0/button3/control",
+                        "/controls/elevator-trim");
+    props.setFloatValue("/input/js0/button3/step", 0.001);
+    props.setBoolValue("/input/js0/button3/repeatable", true);
+  }
+  if (!props.getValue("/input/js0/button4/control")) {
+    props.setStringValue("/input/js0/button4/action", "adjust");
+    props.setStringValue("/input/js0/button4/control",
+                        "/controls/elevator-trim");
+    props.setFloatValue("/input/js0/button4/step", -0.001);
+    props.setBoolValue("/input/js0/button4/repeatable", true);
+  }
+
+                               // Default buttons 5 and 6 to flaps
+  if (!props.getValue("/input/js0/button5/control")) {
+    props.setStringValue("/input/js0/button5/action", "adjust");
+    props.setStringValue("/input/js0/button5/control", "/controls/flaps");
+    props.setFloatValue("/input/js0/button5/step", -0.34);
+    props.setBoolValue("/input/js0/button5/repeatable", false);
+  }
+  if (!props.getValue("/input/js0/button6/control")) {
+    props.setStringValue("/input/js0/button6/action", "adjust");
+    props.setStringValue("/input/js0/button6/control", "/controls/flaps");
+    props.setFloatValue("/input/js0/button6/step", 0.34);
+    props.setBoolValue("/input/js0/button6/repeatable", false);
   }
 }
 
@@ -158,10 +238,17 @@ fgJoystickInit()
     js->getMaxRange(maxRange);
     js->getCenter(center);
 
-                               // Allocate axes
+                               // Allocate axes and buttons
     joysticks[i].axes = new axis[js->getNumAxes()];
+    joysticks[i].buttons = new button[MAX_BUTTONS];
+
 
+    //
+    // Initialize the axes.
+    //
     for (int j = 0; j < min(js->getNumAxes(), MAX_AXES); j++) {
+      axis &a = joysticks[i].axes[j];
+
       string base = "/input/";
       base += jsNames[i];
       base += '/';
@@ -177,7 +264,7 @@ fgJoystickInit()
        continue;
       }
       const string &control = value->getStringValue();
-      joysticks[i].axes[j].value = current_properties.getValue(control, true);
+      a.value = current_properties.getValue(control, true);
       FG_LOG(FG_INPUT, FG_INFO, "    using control " << control);
 
                                // Dead band
@@ -193,9 +280,8 @@ fgJoystickInit()
       name += "/offset";
       value = current_properties.getValue(name);
       if (value != 0)
-       joysticks[i].axes[j].offset = value->getFloatValue();
-      FG_LOG(FG_INPUT, FG_INFO, "    offset is "
-            << joysticks[i].axes[j].offset);
+       a.offset = value->getFloatValue();
+      FG_LOG(FG_INPUT, FG_INFO, "    offset is " << a.offset);
 
 
                                // Factor
@@ -203,9 +289,8 @@ fgJoystickInit()
       name += "/factor";
       value = current_properties.getValue(name);
       if (value != 0)
-       joysticks[i].axes[j].factor = value->getFloatValue();
-      FG_LOG(FG_INPUT, FG_INFO, "    factor is "
-            << joysticks[i].axes[j].factor);
+       a.factor = value->getFloatValue();
+      FG_LOG(FG_INPUT, FG_INFO, "    factor is " << a.factor);
 
 
                                // Tolerance
@@ -213,9 +298,8 @@ fgJoystickInit()
       name += "/tolerance";
       value = current_properties.getValue(name);
       if (value != 0)
-       joysticks[i].axes[j].tolerance = value->getFloatValue();
-      FG_LOG(FG_INPUT, FG_INFO, "    tolerance is "
-            << joysticks[i].axes[j].tolerance);
+       a.tolerance = value->getFloatValue();
+      FG_LOG(FG_INPUT, FG_INFO, "    tolerance is " << a.tolerance);
 
 
                                // Saturation
@@ -251,6 +335,74 @@ fgJoystickInit()
       FG_LOG(FG_INPUT, FG_INFO, "    center is " << center[j]);
     }
 
+
+    //
+    // Initialize the buttons.
+    //
+    for (int j = 0; j < MAX_BUTTONS; j++) {
+      button &b = joysticks[i].buttons[j];
+      
+      string base = "/input/";
+      base += jsNames[i];
+      base += '/';
+      base += buttonNames[j];
+      FG_LOG(FG_INPUT, FG_INFO, "  Button " << j << ':');
+
+                               // Control property
+      string name = base;
+      name += "/control";
+      cout << "Trying name " << name << endl;
+      FGValue * value = current_properties.getValue(name);
+      if (value == 0) {
+       FG_LOG(FG_INPUT, FG_INFO, "    no control defined");
+       continue;
+      }
+      const string &control = value->getStringValue();
+      b.value = current_properties.getValue(control, true);
+      FG_LOG(FG_INPUT, FG_INFO, "    using control " << control);
+
+                               // Step
+      name = base;
+      name += "/step";
+      value = current_properties.getValue(name);
+      if (value != 0)
+       b.step = value->getFloatValue();
+      FG_LOG(FG_INPUT, FG_INFO, "    step is " << b.step);
+
+                               // Type
+      name = base;
+      name += "/action";
+      value = current_properties.getValue(name);
+      string action = "adjust";
+      if (value != 0)
+       action = value->getStringValue();
+      if (action == "toggle") {
+       b.action = button::TOGGLE;
+       b.isRepeatable = false;
+      } else if (action == "switch") {
+       b.action = button::SWITCH;
+       b.isRepeatable = false;
+      } else if (action == "adjust") {
+       b.action = button::ADJUST;
+       b.isRepeatable = true;
+      } else {
+       FG_LOG(FG_INPUT, FG_ALERT, "    unknown action " << action);
+       action = "adjust";
+       b.action = button::ADJUST;
+       b.isRepeatable = true;
+      }
+      FG_LOG(FG_INPUT, FG_INFO, "    action is " << action);
+
+                               // Repeatability.
+      name = base;
+      name += "/repeatable";
+      value = current_properties.getValue(name);
+      if (value != 0)
+       b.isRepeatable = value->getBoolValue();
+      FG_LOG(FG_INPUT, FG_INFO, (b.isRepeatable ?
+            "    repeatable" : "    not repeatable"));
+    }
+
     js->setMinRange(minRange);
     js->setMaxRange(maxRange);
     js->setCenter(center);
@@ -282,28 +434,101 @@ fgJoystickRead()
 
     js->read(&buttons, axis_values);
 
+    //
+    // Axes
+    //
     for (int j = 0; j < min(MAX_AXES, js->getNumAxes()); j++) {
+      bool flag = true;
+      axis &a = joysticks[i].axes[j];
 
                                // If the axis hasn't changed, don't
                                // force the value.
-      if (fabs(axis_values[j] - joysticks[i].axes[j].last_value) <=
-         joysticks[i].axes[j].tolerance)
+      if (fabs(axis_values[j] - a.last_value) <= a.tolerance)
        continue;
       else
-       joysticks[i].axes[j].last_value = axis_values[j];
-
-      FGValue * value = joysticks[i].axes[j].value;
-      if (value) {
-       if (!value->setDoubleValue((axis_values[j] +
-                                   joysticks[i].axes[j].offset) *
-                                  joysticks[i].axes[j].factor))
-         FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
-                << i << ", axis " << j);
+       a.last_value = axis_values[j];
+
+      if (a.value)
+       flag = a.value->setDoubleValue((axis_values[j] + a.offset) *
+                                      a.factor);
+      if (!flag)
+       FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
+              << i << ", axis " << j);
+    }
+
+    //
+    // Buttons
+    //
+    for (int j = 0; j < MAX_BUTTONS; j++) {
+      bool flag;
+      button &b = joysticks[i].buttons[j];
+      if (b.value == 0)
+       continue;
+
+                               // Button is on.
+      if ((buttons & (1 << j)) > 0) {
+                               // Repeating?
+       if (b.lastState == 1 && !b.isRepeatable)
+         continue;
+
+       switch (b.action) {
+       case button::TOGGLE:
+         if (b.step != 0.0) {
+           if (b.value->getDoubleValue() == 0.0)
+             flag = b.value->setDoubleValue(b.step);
+           else
+             flag = b.value->setDoubleValue(0.0);
+         } else {
+           if (b.value->getBoolValue())
+             flag = b.value->setBoolValue(false);
+           else
+             flag = b.value->setBoolValue(true);
+         }
+         break;
+       case button::SWITCH:
+         flag = b.value->setDoubleValue(b.step);
+         break;
+       case button::ADJUST:
+         if (!b.value->setDoubleValue(b.value->getDoubleValue() + b.step))
+           FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
+                  << i << ", axis " << j);
+         break;
+       default:
+         flag = false;
+         break;
+       }
+       b.lastState = 1;
+
+                               // Button is off
+      } else {
+                               // Repeating?
+       if (b.lastState == 0 && !b.isRepeatable)
+         continue;
+
+       switch (b.action) {
+       case button::TOGGLE:
+         // no op
+         break;
+       case button::SWITCH:
+         flag = b.value->setDoubleValue(0.0);
+         break;
+       case button::ADJUST:
+         // no op
+         break;
+       default:
+         flag = false;
+         break;
+       }
+
+       b.lastState = 0;
       }
+      if (!flag)
+       FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for "
+              << jsNames[i] << ' ' << buttonNames[j]);
     }
   }
 
-  return true;                 // FIXME
+  return true;
 }
 
 // end of joystick.cxx
index 5d1f23a953e28d2e711ced8ebbab192e7c06a587..aafa5cd1628a5a5af712855b541a43e5af37773e 100644 (file)
@@ -149,6 +149,10 @@ FGBFI::init ()
                               getElevatorTrim, setElevatorTrim);
   current_properties.tieDouble("/controls/brake",
                               getBrake, setBrake);
+  current_properties.tieDouble("/controls/left-brake",
+                              getLeftBrake, setLeftBrake);
+  current_properties.tieDouble("/controls/right-brake",
+                              getRightBrake, setRightBrake);
 
                                // Autopilot
   current_properties.tieBool("/autopilot/locks/altitude",
@@ -509,7 +513,7 @@ double
 FGBFI::getAGL ()
 {
   return current_aircraft.fdm_state->get_Altitude()
-        - scenery.cur_elev * METER_TO_FEET;
+        - (scenery.cur_elev * METER_TO_FEET);
 }
 
 
@@ -866,7 +870,7 @@ double
 FGBFI::getBrake ()
 {
                                // FIXME: add brake selector
-  return controls.get_brake(0);
+  return controls.get_brake(2);
 }
 
 
@@ -876,12 +880,52 @@ FGBFI::getBrake ()
 void
 FGBFI::setBrake (double brake)
 {
-                               // FIXME: clamp?
-                               // FIXME: allow brake selection
+  controls.set_brake(FGControls::ALL_WHEELS, brake);
+}
+
+
+/**
+ * Get the left brake, from 0.0 (none) to 1.0 (full).
+ */
+double
+FGBFI::getLeftBrake ()
+{
+  return controls.get_brake(0);
+}
+
+
+/**
+ * Set the left brake, from 0.0 (none) to 1.0 (full).
+ */
+void
+FGBFI::setLeftBrake (double brake)
+{
   controls.set_brake(0, brake);
 }
 
 
+/**
+ * Get the right brake, from 0.0 (none) to 1.0 (full).
+ */
+double
+FGBFI::getRightBrake ()
+{
+  return controls.get_brake(1);
+}
+
+
+/**
+ * Set the right brake, from 0.0 (none) to 1.0 (full).
+ */
+void
+FGBFI::setRightBrake (double brake)
+{
+  controls.set_brake(1, brake);
+}
+
+
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Autopilot
index cac3bb81214cebe3ea9149cc6f0c2bfd9b22ed17..d13a99567a4b3e5c607b05251e76300ead4e15ea 100644 (file)
@@ -111,6 +111,8 @@ public:
   static double getElevator ();
   static double getElevatorTrim ();
   static double getBrake ();
+  static double getLeftBrake ();
+  static double getRightBrake ();
 
   static void setThrottle (double throttle);
   static void setFlaps (double flaps);
@@ -119,6 +121,8 @@ public:
   static void setElevator (double elevator);
   static void setElevatorTrim (double trim);
   static void setBrake (double brake);
+  static void setLeftBrake (double brake);
+  static void setRightBrake (double brake);
 
 
                                // Autopilot