]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_commands.cxx
Improve timing statistics
[flightgear.git] / src / Main / fg_commands.cxx
index c17a19c4f73d88a5320b6123db0b37ccfe09ca54..8f7a1c18cab9ebb2ca620b7188244e0c520152fe 100644 (file)
@@ -8,38 +8,36 @@
 
 #include <simgear/compiler.h>
 
-#include STL_STRING
-#include STL_FSTREAM
+#include <string>
+#include <fstream>
 
 #include <simgear/sg_inlines.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/scene/material/mat.hxx>
+#include <simgear/scene/material/matlib.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/structure/commands.hxx>
 #include <simgear/props/props.hxx>
+#include <simgear/structure/event_mgr.hxx>
+#include <simgear/sound/soundmgr_openal.hxx>
+#include <simgear/timing/sg_time.hxx>
 
 #include <Cockpit/panel.hxx>
 #include <Cockpit/panel_io.hxx>
-#include <Cockpit/hud.hxx>
-#include <Environment/environment.hxx>
 #include <FDM/flight.hxx>
 #include <GUI/gui.h>
 #include <GUI/new_gui.hxx>
 #include <GUI/dialog.hxx>
 #include <Aircraft/replay.hxx>
-#include <Scenery/tilemgr.hxx>
 #include <Scenery/scenery.hxx>
-#if defined(HAVE_PLIB_PSL)
-#  include <Scripting/scriptmgr.hxx>
-#endif
 #include <Scripting/NasalSys.hxx>
-#include <Sound/fg_fx.hxx>
+#include <Sound/sample_queue.hxx>
 #include <Time/sunsolver.hxx>
-#include <Time/tmp.hxx>
 
 #include "fg_init.hxx"
 #include "fg_io.hxx"
+#include "fg_os.hxx"
 #include "fg_commands.hxx"
 #include "fg_props.hxx"
 #include "globals.hxx"
 #include "util.hxx"
 #include "viewmgr.hxx"
 #include "main.hxx"
+#include <Main/viewer.hxx>
+#include <Environment/presets.hxx>
 
-SG_USING_STD(string);
-SG_USING_STD(ifstream);
-SG_USING_STD(ofstream);
+using std::string;
+using std::ifstream;
+using std::ofstream;
 
 
 \f
@@ -135,15 +135,15 @@ static bool
 compare_values (SGPropertyNode * value1, SGPropertyNode * value2)
 {
     switch (value1->getType()) {
-    case SGPropertyNode::BOOL:
+    case simgear::props::BOOL:
         return (value1->getBoolValue() == value2->getBoolValue());
-    case SGPropertyNode::INT:
+    case simgear::props::INT:
         return (value1->getIntValue() == value2->getIntValue());
-    case SGPropertyNode::LONG:
+    case simgear::props::LONG:
         return (value1->getLongValue() == value2->getLongValue());
-    case SGPropertyNode::FLOAT:
+    case simgear::props::FLOAT:
         return (value1->getFloatValue() == value2->getFloatValue());
-    case SGPropertyNode::DOUBLE:
+    case simgear::props::DOUBLE:
         return (value1->getDoubleValue() == value2->getDoubleValue());
     default:
         return !strcmp(value1->getStringValue(), value2->getStringValue());
@@ -166,20 +166,6 @@ do_null (const SGPropertyNode * arg)
   return true;
 }
 
-#if defined(HAVE_PLIB_PSL)
-/**
- * Built-in command: run a PSL script.
- *
- * script: the PSL script to execute
- */
-static bool
-do_script (const SGPropertyNode * arg)
-{
-    FGScriptMgr * mgr = (FGScriptMgr *)globals->get_subsystem("scripting");
-    return mgr->run(arg->getStringValue("script"));
-}
-#endif // HAVE_PLIB_PSL
-
 /**
  * Built-in command: run a Nasal script.
  */
@@ -201,7 +187,7 @@ do_exit (const SGPropertyNode * arg)
     fgSetBool("/sim/signals/exit", true);
 
     if (fgGetBool("/sim/startup/save-on-exit")) {
-#ifdef _MSC_VER
+#ifdef _WIN32
         char* envp = ::getenv( "APPDATA" );
         if ( envp != NULL ) {
             SGPath config( envp );
@@ -223,7 +209,19 @@ do_exit (const SGPropertyNode * arg)
             SG_LOG(SG_INPUT, SG_DEBUG, "Finished Saving user settings");
         }
     }
-    fgExit(arg->getIntValue("status", 0));
+    
+    fgOSExit(arg->getIntValue("status", 0));
+    return true;
+}
+
+
+/**
+ * Reset FlightGear (Shift-Escape or Menu->File->Reset)
+ */
+static bool
+do_reset (const SGPropertyNode * arg)
+{
+    fgReInitSubsystems();
     return true;
 }
 
@@ -249,7 +247,7 @@ do_reinit (const SGPropertyNode * arg)
             if (subsystem == 0) {
                 result = false;
                 SG_LOG( SG_GENERAL, SG_ALERT,
-                        "Subsystem " << name << "not found" );
+                        "Subsystem " << name << " not found" );
             } else {
                 subsystem->reinit();
             }
@@ -282,7 +280,7 @@ do_suspend (const SGPropertyNode * arg)
         SGSubsystem * subsystem = globals->get_subsystem(name);
         if (subsystem == 0) {
             result = false;
-            SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << "not found");
+            SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
         } else {
             subsystem->suspend();
         }
@@ -306,7 +304,7 @@ do_resume (const SGPropertyNode * arg)
         SGSubsystem * subsystem = globals->get_subsystem(name);
         if (subsystem == 0) {
             result = false;
-            SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << "not found");
+            SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
         } else {
             subsystem->resume();
         }
@@ -326,16 +324,25 @@ do_resume (const SGPropertyNode * arg)
 static bool
 do_load (const SGPropertyNode * arg)
 {
-  const string &file = arg->getStringValue("file", "fgfs.sav");
-  ifstream input(file.c_str());
-  if (input.good() && fgLoadFlight(input)) {
-    input.close();
-    SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
-    return true;
-  } else {
-    SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file);
-    return false;
-  }
+    string file = arg->getStringValue("file", "fgfs.sav");
+    if (file.size() < 4 || file.substr(file.size() - 4) != ".sav")
+        file += ".sav";
+
+    if (!fgValidatePath(file.c_str(), false)) {
+        SG_LOG(SG_IO, SG_ALERT, "load: reading '" << file << "' denied "
+                "(unauthorized access)");
+        return false;
+    }
+
+    ifstream input(file.c_str());
+    if (input.good() && fgLoadFlight(input)) {
+        input.close();
+        SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
+        return true;
+    } else {
+        SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file);
+        return false;
+    }
 }
 
 
@@ -348,18 +355,27 @@ do_load (const SGPropertyNode * arg)
 static bool
 do_save (const SGPropertyNode * arg)
 {
-  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, write_all)) {
-    output.close();
-    SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
-    return true;
-  } else {
-    SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file);
-    return false;
-  }
+    string file = arg->getStringValue("file", "fgfs.sav");
+    if (file.size() < 4 || file.substr(file.size() - 4) != ".sav")
+        file += ".sav";
+
+    if (!fgValidatePath(file.c_str(), false)) {
+        SG_LOG(SG_IO, SG_ALERT, "save: writing '" << file << "' denied "
+                "(unauthorized access)");
+        return false;
+    }
+
+    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, write_all)) {
+        output.close();
+        SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
+        return true;
+    } else {
+        SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file);
+        return false;
+    }
 }
 
 
@@ -374,9 +390,11 @@ static bool
 do_panel_load (const SGPropertyNode * arg)
 {
   string panel_path =
-    arg->getStringValue("path",
-                       fgGetString("/sim/panel/path",
-                                   "Panels/Default/default.xml"));
+    arg->getStringValue("path", fgGetString("/sim/panel/path"));
+  if (panel_path.empty()) {
+    return false;
+  }
+  
   FGPanel * new_panel = fgReadPanel(panel_path);
   if (new_panel == 0) {
     SG_LOG(SG_INPUT, SG_ALERT,
@@ -434,24 +452,11 @@ do_preferences_load (const SGPropertyNode * arg)
   return true;
 }
 
-
-static void
-fix_hud_visibility()
-{
-  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 );
-      }
-  }
-}
-
 static void
 do_view_next( bool )
 {
     globals->get_current_view()->setHeadingOffset_deg(0.0);
     globals->get_viewmgr()->next_view();
-    fix_hud_visibility();
 }
 
 static void
@@ -459,7 +464,6 @@ do_view_prev( bool )
 {
     globals->get_current_view()->setHeadingOffset_deg(0.0);
     globals->get_viewmgr()->prev_view();
-    fix_hud_visibility();
 }
 
 /**
@@ -470,7 +474,6 @@ do_view_cycle (const SGPropertyNode * arg)
 {
   globals->get_current_view()->setHeadingOffset_deg(0.0);
   globals->get_viewmgr()->next_view();
-  fix_hud_visibility();
   return true;
 }
 
@@ -480,8 +483,14 @@ do_view_cycle (const SGPropertyNode * arg)
 static bool
 do_screen_capture (const SGPropertyNode * arg)
 {
-  fgDumpSnapShot();
-  return true;
+  return fgDumpSnapShot();
+}
+
+static bool
+do_reload_shaders (const SGPropertyNode*)
+{
+    simgear::reload_shaders();
+    return true;
 }
 
 static bool
@@ -508,6 +517,13 @@ do_dump_terrain_branch (const SGPropertyNode*)
     return true;
 }
 
+static bool
+do_print_visible_scene_info(const SGPropertyNode*)
+{
+    fgPrintVisibleSceneInfoCommand();
+    return true;
+}
+
 /**
  * Built-in command: hires capture screen.
  */
@@ -532,15 +548,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
     if ( !freeze ) {
        fgSetBool("/sim/freeze/master", true);
     }
-    if ( globals->get_tile_mgr()->init() ) {
-       // Load the local scenery data
-        double visibility_meters = fgGetDouble("/environment/visibility-m");
-       globals->get_tile_mgr()->update( visibility_meters );
-    } else {
-       SG_LOG( SG_GENERAL, SG_ALERT, 
-               "Error in Tile Manager initialization!" );
-       exit(-1);
-    }
+
+    globals->get_subsystem("tile-manager")->reinit();
+
     if ( !freeze ) {
        fgSetBool("/sim/freeze/master", false);
     }
@@ -548,15 +558,16 @@ do_tile_cache_reload (const SGPropertyNode * arg)
 }
 
 
+#if 0
+These do_set_(some-environment-parameters) are deprecated and no longer 
+useful/functional - Torsten Dreyer, January 2011
 /**
  * Set the sea level outside air temperature and assigning that to all
  * boundary and aloft environment layers.
  */
 static bool
-do_set_sea_level_degc (const SGPropertyNode * arg)
+do_set_sea_level_degc ( double temp_sea_level_degc)
 {
-    double temp_sea_level_degc = arg->getDoubleValue("temp-degc", 15.0);
-
     SGPropertyNode *node, *child;
 
     // boundary layers
@@ -584,6 +595,12 @@ do_set_sea_level_degc (const SGPropertyNode * arg)
     return true;
 }
 
+static bool
+do_set_sea_level_degc (const SGPropertyNode * arg)
+{
+    return do_set_sea_level_degc( arg->getDoubleValue("temp-degc", 15.0) );
+}
+
 
 /**
  * Set the outside air temperature at the "current" altitude by first
@@ -593,8 +610,7 @@ do_set_sea_level_degc (const SGPropertyNode * arg)
 static bool
 do_set_oat_degc (const SGPropertyNode * arg)
 {
-    const string &temp_str = arg->getStringValue("temp-degc", "15.0");
-
+    double oat_degc = arg->getDoubleValue("temp-degc", 15.0);
     // check for an altitude specified in the arguments, otherwise use
     // current aircraft altitude.
     const SGPropertyNode *altitude_ft = arg->getChild("altitude-ft");
@@ -604,38 +620,8 @@ do_set_oat_degc (const SGPropertyNode * arg)
 
     FGEnvironment dummy;       // instantiate a dummy so we can leech a method
     dummy.set_elevation_ft( altitude_ft->getDoubleValue() );
-    dummy.set_temperature_degc( atof( temp_str.c_str() ) );
-    double temp_sea_level_degc = dummy.get_temperature_sea_level_degc();
-
-    //cout << "Altitude = " << altitude_ft->getDoubleValue() << endl;
-    //cout << "Temp at alt (C) = " << atof( temp_str.c_str() ) << endl;
-    //cout << "Temp sea level (C) = " << temp_sea_level_degc << endl;
-    SGPropertyNode *node, *child;
-
-    // boundary layers
-    node = fgGetNode( "/environment/config/boundary" );
-    if ( node != NULL ) {
-      int i = 0;
-      while ( ( child = node->getNode( "entry", i ) ) != NULL ) {
-       child->setDoubleValue( "temperature-sea-level-degc",
-                              temp_sea_level_degc );
-       ++i;
-      }
-    }
-
-    // aloft layers
-    node = fgGetNode( "/environment/config/aloft" );
-    if ( node != NULL ) {
-      int i = 0;
-      while ( ( child = node->getNode( "entry", i ) ) != NULL ) {
-       child->setDoubleValue( "temperature-sea-level-degc",
-                              temp_sea_level_degc );
-       ++i;
-      }
-    }
-
-    return true;
+    dummy.set_temperature_degc( oat_degc );
+    return do_set_sea_level_degc( dummy.get_temperature_sea_level_degc());
 }
 
 /**
@@ -643,9 +629,8 @@ do_set_oat_degc (const SGPropertyNode * arg)
  * boundary and aloft environment layers.
  */
 static bool
-do_set_dewpoint_sea_level_degc (const SGPropertyNode * arg)
+do_set_dewpoint_sea_level_degc (double dewpoint_sea_level_degc)
 {
-    double dewpoint_sea_level_degc = arg->getDoubleValue("dewpoint-degc", 5.0);
 
     SGPropertyNode *node, *child;
 
@@ -674,6 +659,11 @@ do_set_dewpoint_sea_level_degc (const SGPropertyNode * arg)
     return true;
 }
 
+static bool
+do_set_dewpoint_sea_level_degc (const SGPropertyNode * arg)
+{
+    return do_set_dewpoint_sea_level_degc(arg->getDoubleValue("dewpoint-degc", 5.0));
+}
 
 /**
  * Set the outside air dewpoint at the "current" altitude by first
@@ -683,7 +673,7 @@ do_set_dewpoint_sea_level_degc (const SGPropertyNode * arg)
 static bool
 do_set_dewpoint_degc (const SGPropertyNode * arg)
 {
-    const string &dewpoint_str = arg->getStringValue("dewpoint-degc", "5.0");
+    double dewpoint_degc = arg->getDoubleValue("dewpoint-degc", 5.0);
 
     // check for an altitude specified in the arguments, otherwise use
     // current aircraft altitude.
@@ -694,40 +684,10 @@ do_set_dewpoint_degc (const SGPropertyNode * arg)
 
     FGEnvironment dummy;       // instantiate a dummy so we can leech a method
     dummy.set_elevation_ft( altitude_ft->getDoubleValue() );
-    dummy.set_dewpoint_degc( atof( dewpoint_str.c_str() ) );
-    double dewpoint_sea_level_degc = dummy.get_dewpoint_sea_level_degc();
-
-    //cout << "Altitude = " << altitude_ft->getDoubleValue() << endl;
-    //cout << "Dewpoint at alt (C) = " << atof( dewpoint_str.c_str() ) << endl;
-    //cout << "Dewpoint at sea level (C) = " << dewpoint_sea_level_degc << endl;
-    SGPropertyNode *node, *child;
-
-    // boundary layers
-    node = fgGetNode( "/environment/config/boundary" );
-    if ( node != NULL ) {
-      int i = 0;
-      while ( ( child = node->getNode( "entry", i ) ) != NULL ) {
-       child->setDoubleValue( "dewpoint-sea-level-degc",
-                              dewpoint_sea_level_degc );
-       ++i;
-      }
-    }
-
-    // aloft layers
-    node = fgGetNode( "/environment/config/aloft" );
-    if ( node != NULL ) {
-      int i = 0;
-      while ( ( child = node->getNode( "entry", i ) ) != NULL ) {
-       child->setDoubleValue( "dewpoint-sea-level-degc",
-                              dewpoint_sea_level_degc );
-       ++i;
-      }
-    }
-
-    return true;
+    dummy.set_dewpoint_degc( dewpoint_degc );
+    return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
 }
-
+#endif
 /**
  * Update the lighting manually.
  */
@@ -740,8 +700,6 @@ do_timeofday (const SGPropertyNode * arg)
         = fgGetNode("/position/longitude-deg");
     static const SGPropertyNode *latitude
         = fgGetNode("/position/latitude-deg");
-    static const SGPropertyNode *cur_time_override
-        = fgGetNode("/sim/time/cur-time-override", true);
 
     int orig_warp = globals->get_warp();
     SGTime *t = globals->get_time_params();
@@ -802,14 +760,10 @@ do_timeofday (const SGPropertyNode * arg)
                                              * SGD_DEGREES_TO_RADIANS,
                                            180.0, false ); 
     }
-    // cout << "warp = " << warp << endl;
-    globals->set_warp( orig_warp + warp );
-
-    t->update( longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
-               latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
-               cur_time_override->getLongValue(),
-               globals->get_warp() );
+    
 
+    fgSetInt("/sim/time/warp", orig_warp + warp);
+    
     return true;
 }
 
@@ -1167,6 +1121,59 @@ do_gui_redraw (const SGPropertyNode * arg)
     return true;
 }
 
+
+/**
+ * Adds model to the scenery. The path to the added branch (/models/model[*])
+ * is returned in property "property".
+ */
+static bool
+do_add_model (const SGPropertyNode * arg)
+{
+    SGPropertyNode * model = fgGetNode("models", true);
+    for (int i = 0;; i++) {
+        if (i < 0)
+            return false;
+        if (!model->getChild("model", i, false)) {
+            model = model->getChild("model", i, true);
+            break;
+        }
+    }
+    copyProperties(arg, model);
+    if (model->hasValue("elevation-m"))
+        model->setDoubleValue("elevation-ft", model->getDoubleValue("elevation-m")
+                * SG_METER_TO_FEET);
+    model->getNode("load", true);
+    model->removeChildren("load");
+    const_cast<SGPropertyNode *>(arg)->setStringValue("property", model->getPath());
+    return true;
+}
+
+
+/**
+ * Set mouse cursor coordinates and cursor shape.
+ */
+static bool
+do_set_cursor (const SGPropertyNode * arg)
+{
+    if (arg->hasValue("x") || arg->hasValue("y")) {
+        SGPropertyNode *mx = fgGetNode("/devices/status/mice/mouse/x", true);
+        SGPropertyNode *my = fgGetNode("/devices/status/mice/mouse/y", true);
+        int x = arg->getIntValue("x", mx->getIntValue());
+        int y = arg->getIntValue("y", my->getIntValue());
+        fgWarpMouse(x, y);
+        mx->setIntValue(x);
+        my->setIntValue(y);
+    }
+
+    SGPropertyNode *cursor = const_cast<SGPropertyNode *>(arg)->getNode("cursor", true);
+    if (cursor->getType() != simgear::props::NONE)
+        fgSetMouseCursor(cursor->getIntValue());
+
+    cursor->setIntValue(fgGetMouseCursor());
+    return true;
+}
+
+
 /**
  * Built-in command: play an audio message (i.e. a wav file) This is
  * fire and forget.  Call this once per message and it will get dumped
@@ -1176,16 +1183,25 @@ do_gui_redraw (const SGPropertyNode * arg)
 static bool
 do_play_audio_sample (const SGPropertyNode * arg)
 {
-    FGFX *fx = (FGFX *)globals->get_subsystem("fx");
     string path = arg->getStringValue("path");
     string file = arg->getStringValue("file");
-    double volume = arg->getDoubleValue("volume");
+    float volume = arg->getFloatValue("volume");
     // cout << "playing " << path << " / " << file << endl;
     try {
-        fx->play_message( path, file, volume );
+        static FGSampleQueue *queue = 0;
+        if ( !queue ) {
+           SGSoundMgr *smgr = globals->get_soundmgr();
+           queue = new FGSampleQueue(smgr, "chatter");
+           queue->tie_to_listener();
+        }
+
+        SGSoundSample *msg = new SGSoundSample(file.c_str(), path);
+        msg->set_volume( volume );
+        queue->add( msg );
+
         return true;
 
-    } catch (const sg_io_exception& e) {
+    } catch (const sg_io_exception&) {
         SG_LOG(SG_GENERAL, SG_ALERT, "play-audio-sample: "
                 "failed to load" << path << '/' << file);
         return false;
@@ -1198,25 +1214,15 @@ do_play_audio_sample (const SGPropertyNode * arg)
 static bool
 do_presets_commit (const SGPropertyNode * arg)
 {
-    // unbind the current fdm state so property changes
-    // don't get lost when we subsequently delete this fdm
-    // and create a new one.
-    cur_fdm_state->unbind();
-
-    // set position from presets
-    fgInitPosition();
-
-    fgReInitSubsystems();
-
-    globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
-
-#if 0
-    if ( ! fgGetBool("/sim/presets/onground") ) {
-        fgSetBool( "/sim/freeze/master", true );
-        fgSetBool( "/sim/freeze/clock", true );
+    if (fgGetBool("/sim/initialized", false)) {
+      fgReInitSubsystems();
+    } else {
+      // Nasal can trigger this during initial init, which confuses
+      // the logic in ReInitSubsystems, since initial state has not been
+      // saved at that time. Short-circuit everything here.
+      fgInitPosition();
     }
-#endif
-
+    
     return true;
 }
 
@@ -1237,8 +1243,10 @@ do_log_level (const SGPropertyNode * arg)
 static bool
 do_replay (const SGPropertyNode * arg)
 {
-    // freeze the master fdm
+    // freeze the fdm, resume from sim pause 
     fgSetInt( "/sim/freeze/replay-state", 1 );
+    fgSetBool("/sim/freeze/master", 0 );
+    fgSetBool("/sim/freeze/clock", 0 );
 
     FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
 
@@ -1257,44 +1265,21 @@ do_replay (const SGPropertyNode * arg)
     return true;
 }
 
-
+/*
 static bool
 do_decrease_visibility (const SGPropertyNode * arg)
 {
-    double new_value = fgGetDouble("/environment/visibility-m") * 0.9;
-    fgSetDouble("/environment/visibility-m", new_value);
-    fgDefaultWeatherValue("visibility-m", new_value);
-    globals->get_subsystem("environment")->reinit();
-
+    Environment::Presets::VisibilitySingleton::instance()->adjust( 0.9 );
     return true;
 }
  
 static bool
 do_increase_visibility (const SGPropertyNode * arg)
 {
-    double new_value = fgGetDouble("/environment/visibility-m") * 1.1;
-    fgSetDouble("/environment/visibility-m", new_value);
-    fgDefaultWeatherValue("visibility-m", new_value);
-    globals->get_subsystem("environment")->reinit();
-
-    return true;
-}
-
-static bool
-do_hud_init(const SGPropertyNode *)
-{
-    fgHUDInit(0); // minimal HUD
-    return true;
-}
-
-static bool
-do_hud_init2(const SGPropertyNode *)
-{
-    fgHUDInit2(0);  // normal HUD
+    Environment::Presets::VisibilitySingleton::instance()->adjust( 1.1 );
     return true;
 }
-
-
+*/
 /**
  * An fgcommand to allow loading of xml files via nasal,
  * the xml file's structure will be made available within
@@ -1317,6 +1302,16 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
     if (file.extension() != "xml")
         file.concat(".xml");
 
+    if (file.isRelative()) {
+      file = globals->resolve_maybe_aircraft_path(file.str());
+    }
+
+    if (!fgValidatePath(file.c_str(), false)) {
+        SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
+                "(unauthorized access)");
+        return false;
+    }
+
     SGPropertyNode *targetnode;
     if (arg->hasValue("targetnode"))
         targetnode = fgGetNode(arg->getStringValue("targetnode"), true);
@@ -1330,7 +1325,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
         return false;
     }
 
-    return  true;
+    return true;
 }
 
 
@@ -1357,6 +1352,12 @@ do_save_xml_from_proptree(const SGPropertyNode * arg)
     if (file.extension() != "xml")
         file.concat(".xml");
 
+    if (!fgValidatePath(file.c_str(), true)) {
+        SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied "
+                "(unauthorized access)");
+        return false;
+    }
+
     SGPropertyNode *sourcenode;
     if (arg->hasValue("sourcenode"))
         sourcenode = fgGetNode(arg->getStringValue("sourcenode"), true);
@@ -1435,11 +1436,9 @@ static struct {
   SGCommandMgr::command_t command;
 } built_ins [] = {
     { "null", do_null },
-#if defined(HAVE_PLIB_PSL)
-    { "script", do_script },
-#endif // HAVE_PLIB_PSL
     { "nasal", do_nasal },
     { "exit", do_exit },
+    { "reset", do_reset },
     { "reinit", do_reinit },
     { "suspend", do_reinit },
     { "resume", do_reinit },
@@ -1452,10 +1451,12 @@ static struct {
     { "screen-capture", do_screen_capture },
     { "hires-screen-capture", do_hires_screen_capture },
     { "tile-cache-reload", do_tile_cache_reload },
+    /*
     { "set-sea-level-air-temp-degc", do_set_sea_level_degc },
     { "set-outside-air-temp-degc", do_set_oat_degc },
     { "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
     { "set-dewpoint-temp-degc", do_set_dewpoint_degc },
+    */
     { "timeofday", do_timeofday },
     { "property-toggle", do_property_toggle },
     { "property-assign", do_property_assign },
@@ -1472,20 +1473,24 @@ static struct {
     { "dialog-update", do_dialog_update },
     { "dialog-apply", do_dialog_apply },
     { "gui-redraw", do_gui_redraw },
+    { "add-model", do_add_model },
+    { "set-cursor", do_set_cursor },
     { "play-audio-sample", do_play_audio_sample },
     { "presets-commit", do_presets_commit },
     { "log-level", do_log_level },
     { "replay", do_replay },
+    /*
     { "decrease-visibility", do_decrease_visibility },
     { "increase-visibility", do_increase_visibility },
-    { "hud-init", do_hud_init },
-    { "hud-init2", do_hud_init2 },
+    */
     { "loadxml", do_load_xml_to_proptree},
     { "savexml", do_save_xml_from_proptree },
     { "press-cockpit-button", do_press_cockpit_button },
     { "release-cockpit-button", do_release_cockpit_button },
     { "dump-scenegraph", do_dump_scene_graph },
     { "dump-terrainbranch", do_dump_terrain_branch },
+    { "print-visible-scene", do_print_visible_scene_info },
+    { "reload-shaders", do_reload_shaders },
     { 0, 0 }                   // zero-terminated
 };
 
@@ -1498,9 +1503,9 @@ static struct {
 void
 fgInitCommands ()
 {
-  SG_LOG(SG_GENERAL, SG_INFO, "Initializing basic built-in commands:");
+  SG_LOG(SG_GENERAL, SG_BULK, "Initializing basic built-in commands:");
   for (int i = 0; built_ins[i].name != 0; i++) {
-    SG_LOG(SG_GENERAL, SG_INFO, "  " << built_ins[i].name);
+    SG_LOG(SG_GENERAL, SG_BULK, "  " << built_ins[i].name);
     globals->get_commands()->addCommand(built_ins[i].name,
                                        built_ins[i].command);
   }