#include <simgear/compiler.h>
#include <simgear/misc/exception.hxx>
-#include <math.h> // rint()
+#include <math.h> // rint()
#include <stdio.h>
-#include <stdlib.h> // atof(), atoi()
-#include <string.h>
+#include <stdlib.h> // atof(), atoi()
+#include <string.h> // strcmp()
#include STL_STRING
+#include <plib/ul.h>
+
+#include <simgear/math/sg_random.h>
#include <simgear/misc/sgstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/route/route.hxx>
{
FG_OPTIONS_OK = 0,
FG_OPTIONS_HELP = 1,
- FG_OPTIONS_ERROR = 2
+ FG_OPTIONS_ERROR = 2,
+ FG_OPTIONS_VERBOSE_HELP = 3,
+ FG_OPTIONS_SHOW_AIRCRAFT = 4
};
static double
// Otherwise, default to Scenery being in $FG_ROOT/Scenery
globals->set_fg_scenery("");
}
- // Position (Globe, AZ)
- fgSetDouble("/position/longitude-deg", -110.6642444);
- fgSetDouble("/position/latitude-deg", 33.3528917);
+ // Position (deliberately out of range)
+ fgSetDouble("/position/longitude-deg", 9999.0);
+ fgSetDouble("/position/latitude-deg", 9999.0);
fgSetDouble("/position/altitude-ft", -9999.0);
// Orientation
// Rendering options
fgSetString("/sim/rendering/fog", "nicest");
fgSetBool("/environment/clouds/status", true);
- fgSetDouble("/environment/clouds/altitude-ft", 5000);
fgSetBool("/sim/startup/fullscreen", false);
fgSetBool("/sim/rendering/shading", true);
fgSetBool("/sim/rendering/skyblend", true);
fgSetInt("/sim/startup/ysize", 600);
fgSetInt("/sim/rendering/bits-per-pixel", 16);
fgSetString("/sim/view-mode", "pilot");
- fgSetDouble("/sim/view/offset-deg", 0);
+ fgSetDouble("/sim/current-view/heading-offset-deg", 0);
fgSetDouble("/environment/visibility-m", 20000);
// HUD options
}
+static bool
+parse_wind (const string &wind, double * min_hdg, double * max_hdg,
+ double * speed, double * gust)
+{
+ string::size_type pos = wind.find('@');
+ if (pos == string::npos)
+ return false;
+ string dir = wind.substr(0, pos);
+ string spd = wind.substr(pos+1);
+ pos = dir.find(':');
+ if (pos == string::npos) {
+ *min_hdg = *max_hdg = atof(dir.c_str());
+ } else {
+ *min_hdg = atof(dir.substr(0,pos).c_str());
+ *max_hdg = atof(dir.substr(pos+1).c_str());
+ }
+ pos = spd.find(':');
+ if (pos == string::npos) {
+ *speed = *gust = atof(spd.c_str());
+ } else {
+ *speed = atof(spd.substr(0,pos).c_str());
+ *gust = atof(spd.substr(pos+1).c_str());
+ }
+ return true;
+}
+
// parse a time string ([+/-]%f[:%f[:%f]]) into hours
static double
parse_time(const string& time_in) {
if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
- fgSetDouble("/sim/field-of-view", fov);
+ fgSetDouble("/sim/current-view/field-of-view", fov);
// printf("parse_fov(): result = %.4f\n", fov);
}
+static void
+setup_wind (double min_hdg, double max_hdg, double speed, double gust)
+{
+ fgSetDouble("/environment/wind-from-heading-deg", min_hdg);
+ fgSetDouble("/environment/params/min-wind-from-heading-deg", min_hdg);
+ fgSetDouble("/environment/params/max-wind-from-heading-deg", max_hdg);
+ fgSetDouble("/environment/wind-speed-kt", speed);
+ fgSetDouble("/environment/params/base-wind-speed-kt", speed);
+ fgSetDouble("/environment/params/gust-wind-speed-kt", gust);
+
+ SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' <<
+ speed << " knots" << endl);
+
+#ifdef FG_WEATHERCM
+ // convert to fps
+ speed *= SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
+ while (min_hdg > 360)
+ min_hdg -= 360;
+ while (min_hdg <= 0)
+ min_hdg += 360;
+ min_hdg *= SGD_DEGREES_TO_RADIANS;
+ fgSetDouble("/environment/wind-from-north-fps", speed * cos(dir));
+ fgSetDouble("/environment/wind-from-east-fps", speed * sin(dir));
+#endif // FG_WEATHERCM
+}
+
+
// Parse --wp=ID[@alt]
static bool
parse_wp( const string& arg ) {
string id, alt_str;
double alt = 0.0;
- unsigned int pos = arg.find( "@" );
+ string::size_type pos = arg.find( "@" );
if ( pos != string::npos ) {
id = arg.substr( 0, pos );
alt_str = arg.substr( pos + 1 );
// cout << "id str = " << id << " alt str = " << alt_str << endl;
alt = atof( alt_str.c_str() );
- if ( fgGetString("/sim/startup/units") == "feet" ) {
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") ) {
alt *= SG_FEET_TO_METER;
}
} else {
if ( (arg == "--help") || (arg == "-h") ) {
// help/usage request
return(FG_OPTIONS_HELP);
+ } else if ( (arg == "--verbose") || (arg == "-v") ) {
+ // verbose help/usage request
+ return(FG_OPTIONS_VERBOSE_HELP);
} else if ( arg == "--disable-game-mode") {
fgSetBool("/sim/startup/game-mode", false);
} else if ( arg == "--enable-game-mode" ) {
fgSetString("/sim/startup/mouse-pointer", "disabled");
} else if ( arg == "--enable-mouse-pointer" ) {
fgSetString("/sim/startup/mouse-pointer", "enabled");
+ } else if ( arg == "--disable-random-objects" ) {
+ fgSetBool("/sim/rendering/random-objects", false);
+ } else if ( arg == "--enable-random-objects" ) {
+ fgSetBool("/sim/rendering/random-objects", true);
} else if ( arg == "--disable-freeze" ) {
fgSetBool("/sim/freeze/master", false);
} else if ( arg == "--enable-freeze" ) {
fgSetString("/sim/startup/airport-id", "");
} else if ( arg.find( "--altitude=" ) == 0 ) {
fgSetBool("/sim/startup/onground", false);
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/position/altitude-ft", atof(arg.substr(11)));
else
fgSetDouble("/position/altitude-ft",
atof(arg.substr(11)) * SG_METER_TO_FEET);
} else if ( arg.find( "--uBody=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "UVW");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/uBody-fps", atof(arg.substr(8)));
else
fgSetDouble("/velocities/uBody-fps",
atof(arg.substr(8)) * SG_METER_TO_FEET);
} else if ( arg.find( "--vBody=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "UVW");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/vBody-fps", atof(arg.substr(8)));
else
fgSetDouble("/velocities/vBody-fps",
atof(arg.substr(8)) * SG_METER_TO_FEET);
} else if ( arg.find( "--wBody=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "UVW");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/wBody-fps", atof(arg.substr(8)));
else
fgSetDouble("/velocities/wBody-fps",
atof(arg.substr(8)) * SG_METER_TO_FEET);
} else if ( arg.find( "--vNorth=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "NED");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/speed-north-fps", atof(arg.substr(9)));
else
fgSetDouble("/velocities/speed-north-fps",
atof(arg.substr(9)) * SG_METER_TO_FEET);
} else if ( arg.find( "--vEast=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "NED");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/speed-east-fps", atof(arg.substr(8)));
else
fgSetDouble("/velocities/speed-east-fps",
atof(arg.substr(8)) * SG_METER_TO_FEET);
} else if ( arg.find( "--vDown=" ) == 0 ) {
fgSetString("/sim/startup/speed-set", "NED");
- if ( fgGetString("/sim/startup/units") == "feet" )
+ if ( !strcmp(fgGetString("/sim/startup/units"), "feet") )
fgSetDouble("/velocities/speed-down-fps", atof(arg.substr(8)));
else
fgSetDouble("/velocities/speed-down-fps",
fgSetString("/sim/aero", arg.substr(7).c_str());
} else if ( arg.find( "--aircraft-dir=" ) == 0 ) {
fgSetString("/sim/aircraft-dir", arg.substr(15).c_str());
+ } else if ( arg.find( "--show-aircraft") == 0) {
+ return(FG_OPTIONS_SHOW_AIRCRAFT);
} else if ( arg.find( "--model-hz=" ) == 0 ) {
fgSetInt("/sim/model-hz", atoi(arg.substr(11)));
} else if ( arg.find( "--speed=" ) == 0 ) {
fgSetBool("/environment/clouds/status", false);
} else if ( arg == "--enable-clouds" ) {
fgSetBool("/environment/clouds/status", true);
- } else if ( arg.find( "--clouds-asl=" ) == 0 ) {
- // FIXME: check units
- if ( fgGetString("/sim/startup/units") == "feet" )
- fgSetDouble("/environment/clouds/altitude-ft",
- atof(arg.substr(13)));
- else
- fgSetDouble("/environment/clouds/altitude-ft",
- atof(arg.substr(13)) * SG_METER_TO_FEET);
+ } else if ( arg == "--disable-clouds3d" ) {
+ fgSetBool("/sim/rendering/clouds3d", false);
+ } else if ( arg == "--enable-clouds3d" ) {
+ fgSetBool("/sim/rendering/clouds3d", true);
} else if ( arg.find( "--fov=" ) == 0 ) {
parse_fov( arg.substr(6) );
} else if ( arg == "--disable-fullscreen" ) {
add_channel( "nmea", arg.substr(7) );
} else if ( arg.find( "--props=" ) == 0 ) {
add_channel( "props", arg.substr(8) );
+ } else if ( arg.find( "--telnet=" ) == 0 ) {
+ add_channel( "telnet", arg.substr(9) );
} else if ( arg.find( "--pve=" ) == 0 ) {
add_channel( "pve", arg.substr(6) );
} else if ( arg.find( "--ray=" ) == 0 ) {
#endif
} else if ( arg.find( "--prop:" ) == 0 ) {
string assign = arg.substr(7);
- unsigned int pos = assign.find('=');
+ string::size_type pos = assign.find('=');
if ( pos == arg.npos || pos == 0 ) {
SG_LOG( SG_GENERAL, SG_ALERT, "Bad property assignment: " << arg );
return FG_OPTIONS_ERROR;
} else {
default_view_offset = atof( woffset.c_str() ) * SGD_DEGREES_TO_RADIANS;
}
- FGViewer *pilot_view =
- (FGViewer *)globals->get_viewmgr()->get_view( 0 );
- pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
- pilot_view->set_goal_view_offset( default_view_offset * SGD_RADIANS_TO_DEGREES );
- fgSetDouble("/sim/view/offset-deg", default_view_offset * SGD_RADIANS_TO_DEGREES );
+ /* apparently not used (CLO, 11 Jun 2002)
+ FGViewer *pilot_view =
+ (FGViewer *)globals->get_viewmgr()->get_view( 0 ); */
+ // this will work without calls to the viewer...
+ fgSetDouble( "/sim/current-view/heading-offset-deg",
+ default_view_offset * SGD_RADIANS_TO_DEGREES );
// $$$ end - added VS Renganathan, 14 Oct 2K
} else if ( arg.find( "--visibility=" ) == 0 ) {
fgSetDouble("/environment/visibility-m", atof(arg.substr(13)));
} else if ( arg.find( "--visibility-miles=" ) == 0 ) {
double visibility = atof(arg.substr(19)) * 5280.0 * SG_FEET_TO_METER;
fgSetDouble("/environment/visibility-m", visibility);
+ } else if ( arg.find( "--random-wind" ) == 0 ) {
+ double min_hdg = sg_random() * 360.0;
+ double max_hdg = min_hdg + (20 - sqrt(sg_random() * 400));
+ double speed = 40 - sqrt(sg_random() * 1600.0);
+ double gust = speed + (10 - sqrt(sg_random() * 100));
+ setup_wind(min_hdg, max_hdg, speed, gust);
} else if ( arg.find( "--wind=" ) == 0 ) {
- string val = arg.substr(7);
- unsigned int pos = val.find('@');
- if ( pos == string::npos ) {
- SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << val );
+ double min_hdg, max_hdg, speed, gust;
+ if (!parse_wind(arg.substr(7), &min_hdg, &max_hdg, &speed, &gust)) {
+ SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg.substr(7) );
return FG_OPTIONS_ERROR;
}
- double dir = atof(val.substr(0,pos).c_str());
- double speed = atof(val.substr(pos+1).c_str());
- SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << dir << '@' <<
- speed << " knots" << endl);
- fgSetDouble("/environment/wind-from-heading-deg", dir);
- fgSetDouble("/environment/wind-speed-kt", speed);
-
-#if !defined (FG_NEW_ENVIRONMENT)
- // convert to fps
- speed *= SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
- while (dir > 360)
- dir -= 360;
- while (dir <= 0)
- dir += 360;
- dir *= SGD_DEGREES_TO_RADIANS;
- fgSetDouble("/environment/wind-from-north-fps",
- speed * cos(dir));
- fgSetDouble("/environment/wind-from-east-fps",
- speed * sin(dir));
-#endif // FG_NEW_ENVIRONMENT
+ setup_wind(min_hdg, max_hdg, speed, gust);
} else if ( arg.find( "--wp=" ) == 0 ) {
parse_wp( arg.substr( 5 ) );
} else if ( arg.find( "--flight-plan=") == 0) {
apath.concat( "-set.xml" );
SG_LOG(SG_INPUT, SG_INFO, "Reading aircraft: " << arg.substr(11)
<< " from " << apath.str());
- try {
- readProperties( apath.str(), globals->get_props() );
- } catch (const sg_exception &e) {
- string message = "Error loading aircraft file: ";
- message += e.getFormattedMessage();
- SG_LOG(SG_INPUT, SG_ALERT, message);
- exit(2);
- }
+ readProperties( apath.str(), globals->get_props() );
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Unknown option '" << arg << "'" );
return FG_OPTIONS_ERROR;
fgParseArgs (int argc, char **argv)
{
bool in_options = true;
+ bool verbose = false;
+ bool help = false;
SG_LOG(SG_GENERAL, SG_INFO, "Processing command line arguments");
in_options = false;
} else {
int result = parse_option(arg);
- if ( (result == FG_OPTIONS_HELP) ||
- (result == FG_OPTIONS_ERROR) ) {
- fgUsage();
- exit(-1);
- }
+ if ((result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR))
+ help = true;
+
+ else if (result == FG_OPTIONS_VERBOSE_HELP)
+ verbose = true;
+
+ else if (result == FG_OPTIONS_SHOW_AIRCRAFT) {
+ fgShowAircraft();
+ exit(0);
+ }
}
} else {
in_options = false;
}
}
+ if (help) {
+ fgUsage(verbose);
+ exit(0);
+ }
+
SG_LOG(SG_GENERAL, SG_INFO, "Finished command line arguments");
}
}
if ( parse_option( line ) == FG_OPTIONS_ERROR ) {
- SG_LOG( SG_GENERAL, SG_ALERT,
- "Config file parse error: " << path << " '"
- << line << "'" );
+ cout << endl << "Config file parse error: " << path << " '"
+ << line << "'" << endl;
fgUsage();
exit(-1);
}
// Print usage message
void
-fgUsage ()
+fgUsage (bool verbose)
{
- cout << "Usage: fgfs [ option ... ]" << endl
- << endl
-
- << "General Options:" << endl
- << " --help, -h Print usage" << endl
- << " --fg-root=path Specify the root data path" << endl
- << " --fg-scenery=path Specify the base scenery path;" << endl
- << " Defaults to $FG_ROOT/Scenery" << endl
- << " --disable-game-mode Disable full-screen game mode" << endl
- << " --enable-game-mode Enable full-screen game mode" << endl
- << " --disable-splash-screen Disable splash screen" << endl
- << " --enable-splash-screen Enable splash screen" << endl
- << " --disable-intro-music Disable introduction music" << endl
- << " --enable-intro-music Enable introduction music" << endl
- << " --disable-mouse-pointer Disable extra mouse pointer" << endl
- << " --enable-mouse-pointer Enable extra mouse pointer (i.e. for full-" << endl
- << " screen Voodoo based cards)" << endl
- << " --disable-freeze Start in a running state" << endl
- << " --enable-freeze Start in a frozen state" << endl
- << " --disable-fuel-freeze Fuel is consumed normally" << endl
- << " --enable-fuel-freeze Fuel tank quantity forced to remain constant" << endl
- << " --disable-clock-freeze Clock advances normally" << endl
- << " --enable-clock-freeze Do not advance clock" << endl
- << " --control=mode Primary control mode (joystick, keyboard," << endl
- << " mouse)" << endl
- << " --enable-auto-coordination Enable auto coordination" << endl
- << " --disable-auto-coordination Disable auto coordination" << endl
- << " --browser-app=path Specify path to your web browser" << endl
- << " --prop:name=value Set property <name> to <value>" << endl
- << " --config=path Load additional properties from path" << endl
- << " --units-feet Use feet for distances" << endl
- << " --units-meters Use meters for distances" << endl
- << endl
-
- << "Features:" << endl
- << " --disable-hud Disable Heads Up Display (HUD)" << endl
- << " --enable-hud Enable Heads Up Display (HUD)" << endl
- << " --disable-panel Disable instrument panel" << endl
- << " --enable-panel Enable instrument panel" << endl
- << " --disable-sound Disable sound effects" << endl
- << " --enable-sound Enable sound effects" << endl
- << " --disable-anti-alias-hud Disable anti-aliased HUD" << endl
- << " --enable-anti-alias-hud Enable anti-aliased HUD" << endl
- << endl
-
- << "Aircraft:" <<endl
- << " --aircraft=name Select an aircraft profile as defined by a" << endl
- << " top level <name>-set.xml" << endl
- << endl
-
- << "Flight Model:" << endl
- << " --fdm=name Select the core flight dynamics model" << endl
- << " Can be one of jsb, larcsim, yasim, magic," << endl
- << " balloon, ada, external, or null" << endl
- << " --aero=name Select aircraft aerodynamics model to load" << endl
- << " --model-hz=n Run the FDM this rate (iterations per" << endl
- << " second)" << endl
- << " --speed=n Run the FDM 'n' times faster than real time" << endl
- << " --notrim Do NOT attempt to trim the model (only with" << endl
- << " fdm=jsbsim)" << endl
- << " --on-ground Start at ground level (default)" << endl
- << " --in-air Start in air (implied when using --altitude)" << endl
- << " --wind=DIR@SPEED Specify wind coming from DIR (degrees) at" << endl
- << " SPEED (knots)" << endl
- << endl
-
- << "Aircraft model directory (UIUC FDM ONLY):" << endl
- << " --aircraft-dir=path Aircraft directory relative to the path of" << endl
- << " the executable" << endl
- << endl
-
- << "Initial Position and Orientation:" << endl
- << " --airport-id=ID Specify starting position by airport ID" << endl
- << " --offset-distance=nm Specify distance to threshold" << endl
- << " --offset-azimuth=degrees Specify heading to threshold" << endl
- << " --lon=degrees Starting longitude (west = -)" << endl
- << " --lat=degrees Starting latitude (south = -)" << endl
- << " --altitude=value Starting altitude (in feet unless" << endl
- << " --units-meters specified)" << endl
- << " --heading=degrees Specify heading (yaw) angle (Psi)" << endl
- << " --roll=degrees Specify roll angle (Phi)" << endl
- << " --pitch=degrees Specify pitch angle (Theta)" << endl
- << " --uBody=units_per_sec Specify velocity along the body X axis" << endl
- << " (in feet unless --units-meters specified)" << endl
- << " --vBody=units_per_sec Specify velocity along the body Y axis" << endl
- << " (in feet unless --units-meters specified)" << endl
- << " --wBody=units_per_sec Specify velocity along the body Z axis" << endl
- << " (in feet unless --units-meters specified)" << endl
- << " --vc=knots Specify initial airspeed" << endl
- << " --mach=num Specify initial mach number" << endl
- << " --glideslope=degreees Specify flight path angle (can be positive)" << endl
- << " --roc=fpm Specify initial climb rate (can be negative)" << endl
- << endl
-
- << "Rendering Options:" << endl
- << " --bpp=depth Specify the bits per pixel" << endl
- << " --fog-disable Disable fog/haze" << endl
- << " --fog-fastest Enable fastest fog/haze" << endl
- << " --fog-nicest Enable nicest fog/haze" << endl
- << " --enable-clouds Enable cloud layers" << endl
- << " --disable-clouds Disable cloud layers" << endl
- << " --clouds-asl=altitude Specify altitude of cloud layer above sea" << endl
- << " level" << endl
- << " --fov=degrees Specify field of view angle" << endl
- << " --disable-fullscreen Disable fullscreen mode" << endl
- << " --enable-fullscreen Enable fullscreen mode" << endl
- << " --shading-flat Enable flat shading" << endl
- << " --shading-smooth Enable smooth shading" << endl
- << " --disable-skyblend Disable sky blending" << endl
- << " --enable-skyblend Enable sky blending" << endl
- << " --disable-textures Disable textures" << endl
- << " --enable-textures Enable textures" << endl
- << " --disable-wireframe Disable wireframe drawing mode" << endl
- << " --enable-wireframe Enable wireframe drawing mode" << endl
- << " --geometry=WxH Specify window geometry (640x480, etc)" << endl
- << " --view-offset=value Specify the default forward view direction" << endl
- << " as an offset from straight ahead. Allowable" << endl
- << " values are LEFT, RIGHT, CENTER, or a specific" << endl
- << " number in degrees" << endl
- << " --visibility=meters Specify initial visibility" << endl
- << " --visibility-miles=miles Specify initial visibility in miles" << endl
- << endl
-
- << "Hud Options:" << endl
- << " --hud-tris Hud displays number of triangles rendered" << endl
- << " --hud-culled Hud displays percentage of triangles culled" << endl
- << endl
-
- << "Time Options:" << endl
- << " --time-offset=[+-]hh:mm:ss Add this time offset" << endl
- << " --time-match-real Synchronize time with real-world time" << endl
- << " --time-match-local Synchronize time with local real-world time" << endl
- << " --start-date-sys=yyyy:mm:dd:hh:mm:ss" << endl
- << " Specify a starting date/time with respect to" << endl
- << " system time" << endl
- << " --start-date-gmt=yyyy:mm:dd:hh:mm:ss" << endl
- << " Specify a starting date/time with respect to" << endl
- << " Greenwich Mean Time" << endl
- << " --start-date-lat=yyyy:mm:dd:hh:mm:ss" << endl
- << " Specify a starting date/time with respect to" << endl
- << " Local Aircraft Time" << endl
- << endl
-
- << "Network Options:" << endl
- << " --httpd=port Enable http server on the specified port" << endl
-#ifdef FG_JPEG_SERVER
- << " --jpg-httpd=port Enable screen shot http server on the" << endl
- << " specified port" << endl
-#endif
-#ifdef FG_NETWORK_OLK
- << " --disable-network-olk Disable Multipilot mode (default)" << endl
- << " --enable-network-olk Enable Multipilot mode" << endl
- << " --net-hud Hud displays network info" << endl
- << " --net-id=name Specify your own callsign" << endl
-#endif
- << endl
-
- << "Route/Way Point Options:" << endl
- << " --wp=ID[@alt] Specify a waypoint for the GC autopilot;" << endl
- << " multiple instances can be used to create a" << endl
- << " route" << endl
- << " --flight-plan=file Read all waypoints from a file" << endl
- << endl
-
- << "IO Options:" << endl
- << " --gamin=params Open connection using the Garmin GPS protocol" << endl
- << " --joyclient=params Open connection to an Agwagon joystick" << endl
- << " --native-ctrls=params Open connection using the FG Native Controls" << endl
- << " protocol" << endl
- << " --native-fdm=params Open connection using the FG Native FDM" << endl
- << " protocol" << endl
- << " --native=params Open connection using the FG Native protocol" << endl
- << " --nmea=params Open connection using the NMEA protocol" << endl
- << " --opengc=params Open connection using the OpenGC protocol" << endl
- << " --props=params Open connection using the interactive" << endl
- << " property manager" << endl
- << " --pve=params Open connection using the PVE protocol" << endl
- << " --ray=params Open connection using the RayWoodworth" << endl
- << " motion chair protocol" << endl
- << " --rul=params Open connection using the RUL protocol" << endl
- << endl
- << " --atc610x Enable atc610x interface." << endl
- << endl
-
- << "Debugging Options:" << endl
- << " --trace-read=property Trace the reads for a property; multiple" << endl
- << " instances allowed." << endl
- << " --trace-write=property Trace the writes for a property; multiple" << endl
- << " instances allowed." << endl
- << endl;
+ SGPropertyNode options_root;
+ SGPath opath( globals->get_fg_root() );
+ opath.append( "options.xml" );
+
+ cout << "" << endl;
+
+ try {
+ readProperties(opath.c_str(), &options_root);
+ } catch (const sg_exception &ex) {
+ cout << "Unable to read the help file." << endl;
+ cout << "Make sure the file options.xml is located in the FlightGear base directory," << endl;
+ cout << "and the location of the base directory is specified by setting $FG_ROOT or" << endl;
+ cout << "by adding --fg-root=path as a program argument." << endl;
+
+ exit(-1);
+ }
+
+ SGPropertyNode *options = options_root.getNode("options");
+ if (!options) {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Error reading options.xml: <options> directive not found." );
+ exit(-1);
+ }
+
+ SGPropertyNode *usage = options->getNode("usage");
+ if (usage) {
+ cout << "Usage: " << usage->getStringValue() << endl;
+ }
+
+ vector<SGPropertyNode_ptr>section = options->getChildren("section");
+ for (unsigned int j = 0; j < section.size(); j++) {
+ string msg = "";
+
+ vector<SGPropertyNode_ptr>option = section[j]->getChildren("option");
+ for (unsigned int k = 0; k < option.size(); k++) {
+
+ SGPropertyNode *name = option[k]->getNode("name");
+ SGPropertyNode *short_name = option[k]->getNode("short");
+ SGPropertyNode *key = option[k]->getNode("key");
+ SGPropertyNode *arg = option[k]->getNode("arg");
+ bool brief = option[k]->getNode("brief");
+
+ if ((brief || verbose) && name) {
+ string tmp = name->getStringValue();
+
+ if (key){
+ tmp.append(":");
+ tmp.append(key->getStringValue());
+ }
+ if (arg) {
+ tmp.append("=");
+ tmp.append(arg->getStringValue());
+ }
+ if (short_name) {
+ tmp.append(", -");
+ tmp.append(short_name->getStringValue());
+ }
+
+ char cstr[96];
+ if (tmp.size() <= 25) {
+ snprintf(cstr, 96, " --%-27s", tmp.c_str());
+ } else {
+ snprintf(cstr, 96, "\n --%s\n%32c", tmp.c_str(), ' ');
+ }
+
+ msg += cstr;
+ SGPropertyNode *desc = option[k]->getNode("description");
+ if (desc) {
+ msg += desc->getStringValue();
+
+ for ( unsigned int l = 1;
+ (desc = option[k]->getNode("description", l, false));
+ l++ )
+ {
+ snprintf(cstr, 96, "\n%32c%s", ' ',
+ desc->getStringValue());
+ msg += cstr;
+ }
+ msg += '\n';
+ }
+ }
+ }
+
+ SGPropertyNode *name = section[j]->getNode("name");
+ if (!msg.empty() && name) {
+ cout << endl << name->getStringValue() << ":" << endl;
+ cout << msg;
+ msg.erase();
+ }
+ }
+
+ if ( !verbose ) {
+ cout << endl;
+ cout << "For a complete list of options use --help --verbose" << endl;
+ }
}
+// Show available aircraft types
+void fgShowAircraft(void) {
+ SGPath path( globals->get_fg_root() );
+ path.append("Aircraft");
+
+ ulDirEnt* dire;
+ ulDir *dirp;
+ dirp = ulOpenDir(path.c_str());
+ if (dirp == NULL) {
+ cout << "Unable to open aircraft directory." << endl;
+ exit(-1);
+ }
+
+ cout << "Available aircraft:" << endl;
+ while ((dire = ulReadDir(dirp)) != NULL) {
+ char *ptr;
+
+ if ((ptr = strstr(dire->d_name, "-set.xml")) && ptr[8] == '\0' ) {
+ SGPath afile = path;
+ afile.append(dire->d_name);
+
+ *ptr = '\0';
+
+ SGPropertyNode root;
+ try {
+ readProperties(afile.str(), &root);
+ } catch (...) {
+ continue;
+ }
+
+ SGPropertyNode *desc, *node = root.getNode("sim");
+ if (node)
+ desc = node->getNode("description");
+
+ char cstr[96];
+ if (strlen(dire->d_name) <= 27)
+ snprintf(cstr, 96, " %-27s %s", dire->d_name,
+ (desc) ? desc->getStringValue() : "" );
+
+ else
+ snprintf(cstr, 96, " %-27s\n%32c%s", dire->d_name, ' ',
+ (desc) ? desc->getStringValue() : "" );
+
+ cout << cstr << endl;
+ }
+ }
+
+ ulCloseDir(dirp);
+}