]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_commands.cxx
Erik Hofman:
[flightgear.git] / src / Main / fg_commands.cxx
index de48e81e8b79e3bc124dd3b575478893990f62dc..e86f7f849873674e86313d0dfc9699eecf3c8c24 100644 (file)
@@ -1,5 +1,7 @@
 // fg_commands.cxx - internal FGFS commands.
 
+#include <string.h>            // strcmp()
+
 #include <simgear/compiler.h>
 #include <simgear/misc/exception.hxx>
 
@@ -50,10 +52,17 @@ public:
   virtual SGPropertyNode * getProp2 () const { return _prop2; }
   virtual const SGPropertyNode * getValue () const
     { return _value ? _value : &_dummy_0; }
+  virtual const bool hasStep () const { return _step != 0; }
   virtual const SGPropertyNode * getStep () const 
     { return _step ? _step : &_dummy_0; }
+  virtual const SGPropertyNode * getMin () const { return _min; }
+  virtual const SGPropertyNode * getMax () const { return _max; }
+  virtual const SGPropertyNode * getWrap () const
+    { return _wrap ? _wrap : &_dummy_0; }
   virtual const SGPropertyNode * getFactor () const 
     { return _factor ? _factor : &_dummy_1; }
+  virtual const SGPropertyNode * getSquared () const 
+    { return _squared ? _squared : &_dummy_1; }
   virtual const SGPropertyNode * getSetting () const 
     { return _setting ? _setting : &_dummy_0; }
   virtual const SGPropertyNode * getOffset () const
@@ -65,7 +74,11 @@ private:
   mutable SGPropertyNode * _prop2;
   const SGPropertyNode * _value;
   const SGPropertyNode * _step;
+  const SGPropertyNode * _min;
+  const SGPropertyNode * _max;
+  const SGPropertyNode * _wrap;
   const SGPropertyNode * _factor;
+  const SGPropertyNode * _squared;
   const SGPropertyNode * _setting;
   const SGPropertyNode * _offset;
 };
@@ -79,7 +92,11 @@ PropertyCommandState::PropertyCommandState (const SGPropertyNode * arg)
     _prop2(fgGetNode(arg->getStringValue("property[1]", "/null"), true)),
     _value(arg->getNode("value")),
     _step(arg->getNode("step")),
+    _min(arg->getNode("min")),
+    _max(arg->getNode("max")),
+    _wrap(arg->getNode("wrap")),
     _factor(arg->getNode("factor")),
+    _squared(arg->getNode("squared")),
     _setting(arg->getNode("setting")),
     _offset(arg->getNode("offset"))
 {
@@ -154,9 +171,10 @@ static bool
 do_save (const SGPropertyNode * arg, SGCommandState ** state)
 {
   const string &file = arg->getStringValue("file", "fgfs.sav");
+  bool write_all = arg->getBoolValue("write-all", false);
   SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
   ofstream output(file.c_str());
-  if (output.good() && fgSaveFlight(output)) {
+  if (output.good() && fgSaveFlight(output, write_all)) {
     output.close();
     SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
     return true;
@@ -196,6 +214,28 @@ do_panel_load (const SGPropertyNode * arg, SGCommandState ** state)
 }
 
 
+/**
+ * Built-in command: pass a mouse click to the panel.
+ *
+ * button: the mouse button number, zero-based.
+ * is-down: true if the button is down, false if it is up.
+ * x-pos: the x position of the mouse click.
+ * y-pos: the y position of the mouse click.
+ */
+static bool
+do_panel_mouse_click (const SGPropertyNode * arg, SGCommandState ** state)
+{
+  if (current_panel != 0)
+    return current_panel
+      ->doMouseAction(arg->getIntValue("button"),
+                     arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
+                     arg->getIntValue("x-pos"),
+                     arg->getIntValue("y-pos"));
+  else
+    return false;
+}
+
+
 /**
  * Built-in command: (re)load preferences.
  *
@@ -212,13 +252,8 @@ do_preferences_load (const SGPropertyNode * arg, SGCommandState ** state)
         << props_path.str());
   try {
     readProperties(props_path.str(), globals->get_props());
-  } catch (const sg_io_exception &e) {
-    string message = "Error reading global preferences: ";
-    message += e.getMessage();
-    message += "\n at ";
-    message += e.getLocation().asString();
-    SG_LOG(SG_INPUT, SG_ALERT, message);
-    mkDialog(message.c_str());
+  } catch (const sg_exception &e) {
+    guiErrorMessage("Error reading global preferences: ", e);
     return false;
   }
   SG_LOG(SG_INPUT, SG_INFO, "Successfully read global preferences.");
@@ -232,8 +267,15 @@ do_preferences_load (const SGPropertyNode * arg, SGCommandState ** state)
 static bool
 do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
 {
-  globals->get_current_view()->set_view_offset(0.0);
-  globals->set_current_view(globals->get_viewmgr()->next_view());
+  globals->get_current_view()->setHeadingOffset_deg(0.0);
+  globals->get_viewmgr()->next_view();
+  if ( !strcmp(fgGetString("/sim/flight-model"), "ada") ) {
+      globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
+      if ( globals->get_viewmgr()->get_current() == 1 ) {
+          globals->get_props()->setBoolValue( "/sim/hud/visibility", false );
+      }
+  }
+  global_tile_mgr.refresh_view_timestamps();
 //   fgReshape(fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize"));
   return true;
 }
@@ -256,24 +298,30 @@ do_screen_capture (const SGPropertyNode * arg, SGCommandState ** state)
 static bool
 do_tile_cache_reload (const SGPropertyNode * arg, SGCommandState ** state)
 {
-  bool freeze = globals->get_freeze();
-  SG_LOG(SG_INPUT, SG_INFO, "ReIniting TileCache");
-  if ( !freeze ) 
-    globals->set_freeze( true );
-  BusyCursor(0);
-  if ( global_tile_mgr.init() ) {
-    // Load the local scenery data
-    global_tile_mgr.update(fgGetDouble("/position/longitude-deg"),
-                          fgGetDouble("/position/latitude-deg"));
-  } else {
-    SG_LOG( SG_GENERAL, SG_ALERT, 
-           "Error in Tile Manager initialization!" );
-    exit(-1);
-  }
-  BusyCursor(1);
-  if ( !freeze )
-    globals->set_freeze( false );
-  return true;
+    static const SGPropertyNode *master_freeze
+       = fgGetNode("/sim/freeze/master");
+    bool freeze = master_freeze->getBoolValue();
+    SG_LOG(SG_INPUT, SG_INFO, "ReIniting TileCache");
+    if ( !freeze ) {
+       fgSetBool("/sim/freeze/master", true);
+    }
+    // BusyCursor(0);
+    if ( global_tile_mgr.init() ) {
+       // Load the local scenery data
+        double visibility_meters = fgGetDouble("/environment/visibility-m");
+       global_tile_mgr.update(fgGetDouble("/position/longitude-deg"),
+                              fgGetDouble("/position/latitude-deg"),
+                              visibility_meters);
+    } else {
+       SG_LOG( SG_GENERAL, SG_ALERT, 
+               "Error in Tile Manager initialization!" );
+       exit(-1);
+    }
+    // BusyCursor(1);
+    if ( !freeze ) {
+       fgSetBool("/sim/freeze/master", false);
+    }
+    return true;
 }
 
 
@@ -341,36 +389,135 @@ do_property_assign (const SGPropertyNode * arg, SGCommandState ** state)
  * Built-in command: increment or decrement a property value.
  *
  * property: the name of the property to increment or decrement.
- * step: the amount of the increment or decrement.
+ * step: the amount of the increment or decrement (default: 0).
+ * offset: a normalized amount to offset by (if step is not present).
+ * factor: the amount by which to multiply the offset (if step is not present).
+ * min: the minimum allowed value (default: no minimum).
+ * max: the maximum allowed value (default: no maximum).
+ * wrap: true if the value should be wrapped when it passes min or max;
+ *       both min and max must be present for this to work (default:
+ *       false).
  */
 static bool
 do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
 {
   if (*state == 0)
     *state = new PropertyCommandState(arg);
+  bool hasStep = ((PropertyCommandState *)(*state))->hasStep();
   SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
   const SGPropertyNode * step = ((PropertyCommandState *)(*state))->getStep();
+  const SGPropertyNode * offset =
+    ((PropertyCommandState *)(*state))->getOffset();
+  const SGPropertyNode * factor =
+    ((PropertyCommandState *)(*state))->getFactor();
+  const SGPropertyNode * min = ((PropertyCommandState *)(*state))->getMin();
+  const SGPropertyNode * max = ((PropertyCommandState *)(*state))->getMax();
+  bool wrap = ((PropertyCommandState *)(*state))->getWrap()->getBoolValue();
+
+  double amount = 0;
+  if (!hasStep) {
+    amount = offset->getDoubleValue() * factor->getDoubleValue();
+  }
+
 
   switch (prop->getType()) {
   case SGPropertyNode::BOOL:
-    if (step->getBoolValue())
+    bool value;
+    if (hasStep)
+      value = step->getBoolValue();
+    else
+      value = (0.0 != amount);
+    if (value)
       return prop->setBoolValue(!prop->getBoolValue());
     else
       return true;
-  case SGPropertyNode::INT:
-    return prop->setIntValue(prop->getIntValue()
-                            + step->getIntValue());
-  case SGPropertyNode::LONG:
-    return prop->setLongValue(prop->getLongValue()
-                             + step->getLongValue());
-  case SGPropertyNode::FLOAT:
-    return prop->setFloatValue(prop->getFloatValue()
-                              + step->getFloatValue());
+  case SGPropertyNode::INT: {
+    int value;
+    if (hasStep)
+      value = prop->getIntValue() + step->getIntValue();
+    else
+      value = prop->getIntValue() + int(amount);
+    if (min && (value < min->getIntValue())) {
+      if (wrap && max)
+       value = max->getIntValue();
+      else
+       value = min->getIntValue();
+    }
+    if (max && value > max->getIntValue()) {
+      if (wrap && min)
+       value = min->getIntValue();
+      else
+       value = max->getIntValue();
+    }
+    return prop->setIntValue(value);
+  }
+  case SGPropertyNode::LONG: {
+    long value;
+    if (hasStep)
+      value = prop->getLongValue() + step->getLongValue();
+    else
+      value = prop->getLongValue() + long(amount);
+    if (min && (value < min->getLongValue())) {
+      if (wrap && max)
+       value = max->getLongValue();
+      else
+       value = min->getLongValue();
+    }
+    if (max && value > max->getLongValue()) {
+      if (wrap && min)
+       value = min->getLongValue();
+      else
+       value = max->getLongValue();
+    }
+    return prop->setLongValue(value);
+  }
+  case SGPropertyNode::FLOAT: {
+    float value;
+    if (hasStep)
+      value = prop->getFloatValue() + step->getFloatValue();
+    else
+      value = prop->getFloatValue() + float(amount);
+    if (min && (value < min->getFloatValue())) {
+      if (wrap && max)
+       value = max->getFloatValue();
+      else
+       value = min->getFloatValue();
+    }
+    if (max && value > max->getFloatValue()) {
+      if (wrap && min)
+       value = min->getFloatValue();
+      else
+       value = max->getFloatValue();
+    }
+    return prop->setFloatValue(value);
+  }
   case SGPropertyNode::DOUBLE:
   case SGPropertyNode::UNSPECIFIED:
-    return prop->setDoubleValue(prop->getDoubleValue()
-                               + step->getDoubleValue());
-  default:                     // doesn't make sense with strings
+  case SGPropertyNode::NONE: {
+    double value;
+    if (hasStep)
+      value = prop->getDoubleValue() + step->getDoubleValue();
+    else
+      value = prop->getDoubleValue() + amount;
+    if (min && (value < min->getDoubleValue())) {
+      if (wrap && max)
+       value = max->getDoubleValue();
+      else
+       value = min->getDoubleValue();
+    }
+    if (max && value > max->getDoubleValue()) {
+      if (wrap && min)
+       value = min->getDoubleValue();
+      else
+       value = max->getDoubleValue();
+    }
+    return prop->setDoubleValue(value);
+  }
+  case SGPropertyNode::STRING: // doesn't make sense with strings
+    SG_LOG(SG_INPUT, SG_ALERT, "Cannot adjust a string value");
+    return false;
+  default:
+    SG_LOG(SG_INPUT, SG_ALERT, "Unknown value type");
     return false;
   }
 }
@@ -406,6 +553,7 @@ do_property_multiply (const SGPropertyNode * arg, SGCommandState ** state)
                                     * factor->getDoubleValue()));
   case SGPropertyNode::DOUBLE:
   case SGPropertyNode::UNSPECIFIED:
+  case SGPropertyNode::NONE:
     return prop->setDoubleValue(prop->getDoubleValue()
                                * factor->getDoubleValue());
   default:                     // doesn't make sense with strings
@@ -431,7 +579,7 @@ do_property_swap (const SGPropertyNode * arg, SGCommandState ** state)
                                // FIXME: inefficient
   const string & tmp = prop1->getStringValue();
   return (prop1->setUnspecifiedValue(prop2->getStringValue()) &&
-         prop2->setUnspecifiedValue(tmp));
+         prop2->setUnspecifiedValue(tmp.c_str()));
 }
 
 
@@ -455,8 +603,14 @@ do_property_scale (const SGPropertyNode * arg, SGCommandState ** state)
     ((PropertyCommandState *)(*state))->getOffset()->getDoubleValue();
   double factor =
     ((PropertyCommandState *)(*state))->getFactor()->getDoubleValue();
+  bool squared =
+    ((PropertyCommandState *)(*state))->getSquared()->getBoolValue();
+
+  if (squared)
+    setting = (setting < 0 ? -1 : 1) * setting * setting;
+  double result = (setting + offset) * factor;
 
-  return prop->setDoubleValue((setting + offset) * factor);
+  return prop->setDoubleValue(result);
 }
 
 
@@ -481,6 +635,7 @@ static struct {
     { "load", do_load },
     { "save", do_save },
     { "panel-load", do_panel_load },
+    { "panel-mouse-click", do_panel_mouse_click },
     { "preferences-load", do_preferences_load },
     { "view-cycle", do_view_cycle },
     { "screen-capture", do_screen_capture },
@@ -512,4 +667,4 @@ fgInitCommands ()
   }
 }
 
-// end of fg_commands.hxx
+// end of fg_commands.cxx