#endif
#include <simgear/compiler.h>
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
#include <math.h> // rint()
// #include <Cockpit/cockpit.hxx>
// #include <FDM/flight.hxx>
// #include <FDM/UIUCModel/uiuc_aircraftdir.h>
-#ifdef FG_NETWORK_OLK
-# include <NetworkOLK/network.h>
-#endif
#include <GUI/gui.h>
#include "fg_init.hxx"
#include "fg_props.hxx"
#include "options.hxx"
+#include "util.hxx"
#include "viewmgr.hxx"
#else
fgSetString("/sim/startup/browser-app", "webrun.bat");
#endif
- fgSetInt("/sim/log-level", SG_WARN);
+ fgSetString("/sim/logging/priority", "alert");
// Features
+ fgSetBool("/sim/hud/antialiased", false);
+ fgSetBool("/sim/hud/enable3d", true);
fgSetBool("/sim/hud/visibility", false);
fgSetBool("/sim/panel/visibility", true);
fgSetBool("/sim/sound/audible", true);
- fgSetBool("/sim/hud/antialiased", false);
// Flight Model options
fgSetString("/sim/flight-model", "jsb");
fgSetBool("/sim/rendering/skyblend", true);
fgSetBool("/sim/rendering/textures", true);
fgSetBool("/sim/rendering/wireframe", false);
+ fgSetBool("/sim/rendering/horizon-effect", false);
+ fgSetBool("/sim/rendering/enhanced-lighting", false);
fgSetBool("/sim/rendering/distance-attenuation", false);
+ fgSetBool("/sim/rendering/specular-highlight", true);
fgSetInt("/sim/startup/xsize", 800);
fgSetInt("/sim/startup/ysize", 600);
fgSetInt("/sim/rendering/bits-per-pixel", 16);
fgSetString("/sim/view-mode", "pilot");
fgSetDouble("/sim/current-view/heading-offset-deg", 0);
- fgSetDouble("/environment/visibility-m", 20000);
// HUD options
fgSetString("/sim/startup/units", "feet");
fgSetString("/sim/startup/time-offset-type", "system-offset");
fgSetLong("/sim/time/cur-time-override", 0);
- fgSetBool("/sim/networking/network-olk", false);
- fgSetString("/sim/networking/call-sign", "Johnny");
-
// Freeze options
fgSetBool("/sim/freeze/master", false);
fgSetBool("/sim/freeze/position", false);
}
-
static bool
parse_wind (const string &wind, double * min_hdg, double * max_hdg,
double * speed, double * gust)
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);
+ // Initialize to a reasonable state
+ fgDefaultWeatherValue("wind-from-heading-deg", min_hdg);
+ fgDefaultWeatherValue("wind-speed-kt", speed);
SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' <<
speed << " knots" << endl);
+ // Now, add some variety to the layers
+ min_hdg += 10;
+ if (min_hdg > 360)
+ min_hdg -= 360;
+ speed *= 1.1;
+ fgSetDouble("/environment/config/boundary/entry[1]/wind-from-heading-deg",
+ min_hdg);
+ fgSetDouble("/environment/config/boundary/entry[1]/wind-speed-kt",
+ speed);
+
+ min_hdg += 20;
+ if (min_hdg > 360)
+ min_hdg -= 360;
+ speed *= 1.1;
+ fgSetDouble("/environment/config/aloft/entry[0]/wind-from-heading-deg",
+ min_hdg);
+ fgSetDouble("/environment/config/aloft/entry[0]/wind-speed-kt",
+ speed);
+
+ min_hdg += 10;
+ if (min_hdg > 360)
+ min_hdg -= 360;
+ speed *= 1.1;
+ fgSetDouble("/environment/config/aloft/entry[1]/wind-from-heading-deg",
+ min_hdg);
+ fgSetDouble("/environment/config/aloft/entry[1]/wind-speed-kt",
+ speed);
+
+ min_hdg += 10;
+ if (min_hdg > 360)
+ min_hdg -= 360;
+ speed *= 1.1;
+ fgSetDouble("/environment/config/aloft/entry[2]/wind-from-heading-deg",
+ min_hdg);
+ fgSetDouble("/environment/config/aloft/entry[2]/wind-speed-kt",
+ speed);
+
#ifdef FG_WEATHERCM
// convert to fps
speed *= SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
return FG_OPTIONS_OK;
}
-#ifdef FG_NETWORK_OLK
-static int
-fgOptNetHud( const char *arg )
-{
- fgSetBool("/sim/hud/net-display", true);
- net_hud_display = 1; // FIXME
- return FG_OPTIONS_OK;
-}
-#endif
-
static int
fgOptTraceRead( const char *arg )
{
return FG_OPTIONS_OK;
}
+static int
+fgOptLogLevel( const char *arg )
+{
+ fgSetString("/sim/logging/classes", "all");
+ fgSetString("/sim/logging/priority", arg);
+
+ string priority = arg;
+ logbuf::set_log_classes(SG_ALL);
+ if (priority == "bulk") {
+ logbuf::set_log_priority(SG_BULK);
+ } else if (priority == "debug") {
+ logbuf::set_log_priority(SG_DEBUG);
+ } else if (priority == "info") {
+ logbuf::set_log_priority(SG_INFO);
+ } else if (priority == "warn") {
+ logbuf::set_log_priority(SG_WARN);
+ } else if (priority == "alert") {
+ logbuf::set_log_priority(SG_ALERT);
+ } else {
+ SG_LOG(SG_GENERAL, SG_WARN, "Unknown logging priority " << priority);
+ }
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Logging priority is " << priority);
+
+ return FG_OPTIONS_OK;
+}
+
+
static int
fgOptTraceWrite( const char *arg )
{
return FG_OPTIONS_OK;
}
+static int
+fgOptVisibilityMeters( const char *arg )
+{
+ double visibility = atof( arg );
+ fgDefaultWeatherValue("visibility-m", visibility);
+ return FG_OPTIONS_OK;
+}
+
static int
fgOptVisibilityMiles( const char *arg )
{
double visibility = atof( arg ) * 5280.0 * SG_FEET_TO_METER;
- fgSetDouble("/environment/visibility-m", visibility);
+ fgDefaultWeatherValue("visibility-m", visibility);
return FG_OPTIONS_OK;
}
{
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 speed = sg_random() * sg_random() * 40;
double gust = speed + (10 - sqrt(sg_random() * 100));
setup_wind(min_hdg, max_hdg, speed, gust);
return FG_OPTIONS_OK;
return FG_OPTIONS_OK;
}
+static int
+fgOptTurbulence( const char *arg )
+{
+ fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg));
+ return FG_OPTIONS_OK;
+}
+
+static int
+fgOptCeiling( const char *arg )
+{
+ double elevation, thickness;
+ string spec = arg;
+ string::size_type pos = spec.find(':');
+ if (pos == string::npos) {
+ elevation = atof(spec.c_str());
+ thickness = 2000;
+ } else {
+ elevation = atof(spec.substr(0, pos).c_str());
+ thickness = atof(spec.substr(pos + 1).c_str());
+ }
+ fgSetDouble("/environment/clouds/layer[0]/elevation-ft", elevation);
+ fgSetDouble("/environment/clouds/layer[0]/thickness-ft", thickness);
+ fgSetString("/environment/clouds/layer[0]/coverage", "overcast");
+ return FG_OPTIONS_OK;
+}
+
static int
fgOptWp( const char *arg )
{
return FG_OPTIONS_OK;
}
+static bool
+parse_colon (const string &s, double * val1, double * val2)
+{
+ string::size_type pos = s.find(':');
+ if (pos == string::npos) {
+ *val2 = atof(s);
+ return false;
+ } else {
+ *val1 = atof(s.substr(0, pos).c_str());
+ *val2 = atof(s.substr(pos+1).c_str());
+ return true;
+ }
+}
+
+
+static int
+fgOptFailure( const char * arg )
+{
+ string a = arg;
+ if (a == "pitot") {
+ fgSetBool("/systems/pitot/serviceable", false);
+ } else if (a == "static") {
+ fgSetBool("/systems/static/serviceable", false);
+ } else if (a == "vacuum") {
+ fgSetBool("/systems/vacuum/serviceable", false);
+ } else if (a == "electrical") {
+ fgSetBool("/systems/electrical/serviceable", false);
+ } else {
+ SG_LOG(SG_INPUT, SG_ALERT, "Unknown failure mode: " << a);
+ return FG_OPTIONS_ERROR;
+ }
+
+ return FG_OPTIONS_OK;
+}
+
+
+static int
+fgOptNAV1( const char * arg )
+{
+ double radial, freq;
+ if (parse_colon(arg, &radial, &freq))
+ fgSetDouble("/radios/nav[0]/radials/selected-deg", radial);
+ fgSetDouble("/radios/nav[0]/frequencies/selected-mhz", freq);
+ return FG_OPTIONS_OK;
+}
+
+static int
+fgOptNAV2( const char * arg )
+{
+ double radial, freq;
+ if (parse_colon(arg, &radial, &freq))
+ fgSetDouble("/radios/nav[1]/radials/selected-deg", radial);
+ fgSetDouble("/radios/nav[1]/frequencies/selected-mhz", freq);
+ return FG_OPTIONS_OK;
+}
+
+static int
+fgOptADF( const char * arg )
+{
+ double rot, freq;
+ if (parse_colon(arg, &rot, &freq))
+ fgSetDouble("/instrumentation/adf/rotation-deg", rot);
+ fgSetDouble("/instrumentation/adf/frequencies/selected-khz", freq);
+ return FG_OPTIONS_OK;
+}
+
+static int
+fgOptDME( const char *arg )
+{
+ string opt = arg;
+ if (opt == "nav1") {
+ fgSetInt("/instrumentation/dme/switch-position", 1);
+ fgSetString("/instrumentation/dme/frequencies/source",
+ "/radios/nav[0]/frequencies/selected-mhz");
+ } else if (opt == "nav2") {
+ fgSetInt("/instrumentation/dme/switch-position", 3);
+ fgSetString("/instrumentation/dme/frequencies/source",
+ "/radios/nav[1]/frequencies/selected-mhz");
+ } else {
+ fgSetInt("/instrumentation/dme/switch-position", 2);
+ fgSetString("/instrumentation/dme/frequencies/source",
+ "/instrumentation/dme/frequencies/selected-mhz");
+ fgSetString("/instrumentation/dme/frequencies/selected-mhz", arg);
+ }
+ return FG_OPTIONS_OK;
+}
+
static map<string,size_t> fgOptionMap;
/*
{"enable-fuel-freeze", false, OPTION_BOOL, "/sim/freeze/fuel", true, "", 0 },
{"disable-clock-freeze", false, OPTION_BOOL, "/sim/freeze/clock", false, "", 0 },
{"enable-clock-freeze", false, OPTION_BOOL, "/sim/freeze/clock", true, "", 0 },
+ {"disable-hud-3d", false, OPTION_BOOL, "/sim/hud/enable3d", false, "", 0 },
+ {"enable-hud-3d", false, OPTION_BOOL, "/sim/hud/enable3d", true, "", 0 },
{"disable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/antialiased", false, "", 0 },
{"enable-anti-alias-hud", false, OPTION_BOOL, "/sim/hud/antialiased", true, "", 0 },
{"control", true, OPTION_STRING, "/sim/control-mode", false, "", 0 },
{"in-air", false, OPTION_BOOL, "/sim/presets/onground", false, "", 0 },
{"fog-disable", false, OPTION_STRING, "/sim/rendering/fog", false, "disabled", 0 },
{"fog-fastest", false, OPTION_STRING, "/sim/rendering/fog", false, "fastest", 0 },
- {"fog-nicest", false, OPTION_STRING, "/sim/fog", false, "nicest", 0 },
- {"disable-distance-attenuation", false, OPTION_BOOL, "/environment/distance-attenuation", false, "", 0 },
- {"enable-distance-attenuation", false, OPTION_BOOL, "/environment/distance-attenuation", true, "", 0 },
+ {"fog-nicest", false, OPTION_STRING, "/sim/rendering/fog", false, "nicest", 0 },
+ {"disable-horizon-effect", false, OPTION_BOOL, "/sim/rendering/horizon-effect", false, "", 0 },
+ {"enable-horizon-effect", false, OPTION_BOOL, "/sim/rendering/horizon-effect", true, "", 0 },
+ {"disable-enhanced-lighting", false, OPTION_BOOL, "/sim/rendering/enhanced-lighting", false, "", 0 },
+ {"enable-enhanced-lighting", false, OPTION_BOOL, "/sim/rendering/enhanced-lighting", true, "", 0 },
+ {"disable-distance-attenuation", false, OPTION_BOOL, "/sim/rendering/distance-attenuation", false, "", 0 },
+ {"enable-distance-attenuation", false, OPTION_BOOL, "/sim/rendering/distance-attenuation", true, "", 0 },
+ {"disable-specular-highlight", false, OPTION_BOOL, "/sim/rendering/specular-highlight", false, "", 0 },
+ {"enable-specular-highlight", false, OPTION_BOOL, "/sim/rendering/specular-highlight", true, "", 0 },
{"disable-clouds", false, OPTION_BOOL, "/environment/clouds/status", false, "", 0 },
{"enable-clouds", false, OPTION_BOOL, "/environment/clouds/status", true, "", 0 },
#ifdef FG_USE_CLOUDS_3D
{"bpp", true, OPTION_FUNC, "", false, "", fgOptBpp },
{"units-feet", false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 },
{"units-meters", false, OPTION_STRING, "/sim/startup/units", false, "meters", 0 },
+ {"timeofday", true, OPTION_STRING, "/sim/startup/time-offset-type", false, "noon", 0 },
{"time-offset", true, OPTION_FUNC, "", false, "", fgOptTimeOffset },
{"time-match-real", false, OPTION_STRING, "/sim/startup/time-offset-type", false, "system-offset", 0 },
{"time-match-local", false, OPTION_STRING, "/sim/startup/time-offset-type", false, "latitude-offset", 0 },
{"start-date-gmt", true, OPTION_FUNC, "", false, "", fgOptStartDateGmt },
{"hud-tris", false, OPTION_STRING, "/sim/hud/frame-stat-type", false, "tris", 0 },
{"hud-culled", false, OPTION_STRING, "/sim/hud/frame-stat-type", false, "culled", 0 },
- {"atc610x", false, OPTION_CHANNEL, "", false, "dummy", 0 },
+ {"atc610x", true, OPTION_CHANNEL, "", false, "dummy", 0 },
{"atlas", true, OPTION_CHANNEL, "", false, "", 0 },
{"httpd", true, OPTION_CHANNEL, "", false, "", 0 },
#ifdef FG_JPEG_SERVER
{"opengc", true, OPTION_CHANNEL, "", false, "", 0 },
{"garmin", true, OPTION_CHANNEL, "", false, "", 0 },
{"nmea", true, OPTION_CHANNEL, "", false, "", 0 },
+ {"generic", true, OPTION_CHANNEL, "", false, "", 0 },
{"props", true, OPTION_CHANNEL, "", false, "", 0 },
{"telnet", true, OPTION_CHANNEL, "", false, "", 0 },
{"pve", true, OPTION_CHANNEL, "", false, "", 0 },
{"ray", true, OPTION_CHANNEL, "", false, "", 0 },
{"rul", true, OPTION_CHANNEL, "", false, "", 0 },
{"joyclient", true, OPTION_CHANNEL, "", false, "", 0 },
-#ifdef FG_NETWORK_OLK
- {"disable-network-olk", false, OPTION_BOOL, "/sim/networking/olk", false, "", 0 },
- {"enable-network-olk", false, OPTION_BOOL, "/sim/networking/olk", true, "", 0 },
- {"net-hud", false, OPTION_FUNC, "", false, "", fgOptNetHud },
- {"net-id", true, OPTION_STRING, "sim/networking/call-sign", false, "", 0 },
-#endif
+ {"jsclient", true, OPTION_CHANNEL, "", false, "", 0 },
#ifdef FG_MPLAYER_AS
- {"callsign", false, OPTION_STRING, "sim/multiplay/callsign", false, "", 0 },
+ {"callsign", true, OPTION_STRING, "sim/multiplay/callsign", false, "", 0 },
{"multiplay", true, OPTION_CHANNEL, "", false, "", 0 },
#endif
{"trace-read", true, OPTION_FUNC, "", false, "", fgOptTraceRead },
{"trace-write", true, OPTION_FUNC, "", false, "", fgOptTraceWrite },
- {"log-level", true, OPTION_INT, "/sim/log-level", false, "", 0 },
+ {"log-level", true, OPTION_FUNC, "", false, "", fgOptLogLevel },
{"view-offset", true, OPTION_FUNC, "", false, "", fgOptViewOffset },
- {"visibility", true, OPTION_DOUBLE, "/environment/visibility-m", false, "", 0 },
+ {"visibility", true, OPTION_FUNC, "", false, "", fgOptVisibilityMeters },
{"visibility-miles", true, OPTION_FUNC, "", false, "", fgOptVisibilityMiles },
{"random-wind", false, OPTION_FUNC, "", false, "", fgOptRandomWind },
{"wind", true, OPTION_FUNC, "", false, "", fgOptWind },
- {"turbulence", true, OPTION_DOUBLE, "/environment/turbulence-norm", false, "", 0 },
+ {"turbulence", true, OPTION_FUNC, "", false, "", fgOptTurbulence },
+ {"ceiling", true, OPTION_FUNC, "", false, "", fgOptCeiling },
{"wp", true, OPTION_FUNC, "", false, "", fgOptWp },
{"flight-plan", true, OPTION_FUNC, "", false, "", fgOptFlightPlan },
{"config", true, OPTION_FUNC, "", false, "", fgOptConfig },
{"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
+ {"failure", true, OPTION_FUNC, "", false, "", fgOptFailure },
+ {"com1", true, OPTION_DOUBLE, "/radios/comm[0]/frequencies/selected-mhz", false, "", 0 },
+ {"com2", true, OPTION_DOUBLE, "/radios/comm[1]/frequencies/selected-mhz", false, "", 0 },
+ {"nav1", true, OPTION_FUNC, "", false, "", fgOptNAV1 },
+ {"nav2", true, OPTION_FUNC, "", false, "", fgOptNAV2 },
+ {"adf", true, OPTION_FUNC, "", false, "", fgOptADF },
+ {"dme", true, OPTION_FUNC, "", false, "", fgOptDME },
{0}
};
break;
case OPTION_FUNC:
if ( pt->has_param && pos != string::npos ) {
- pt->func( arg.substr( pos + 1 ).c_str() );
+ return pt->func( arg.substr( pos + 1 ).c_str() );
} else if ( !pt->has_param && pos == string::npos ) {
- pt->func( 0 );
+ return pt->func( 0 );
} else if ( pt->has_param ) {
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
return FG_OPTIONS_ERROR;
verbose = true;
else if (result == FG_OPTIONS_SHOW_AIRCRAFT) {
- fgShowAircraft();
+ fgOptLogLevel( "alert" );
+ SGPath path( globals->get_fg_root() );
+ path.append("Aircraft");
+ fgShowAircraft(path, true);
exit(0);
}
}
}
if (help) {
+ fgOptLogLevel( "alert" );
fgUsage(verbose);
exit(0);
}
}
}
-// Show available aircraft types
-void fgShowAircraft(void) {
- vector<string> aircraft;
-
- SGPath path( globals->get_fg_root() );
- path.append("Aircraft");
-
+static void fgSearchAircraft(const SGPath &path, string_list &aircraft,
+ bool recursive)
+{
ulDirEnt* dire;
- ulDir *dirp;
-
- dirp = ulOpenDir(path.c_str());
+ ulDir *dirp = ulOpenDir(path.str().c_str());
if (dirp == NULL) {
cerr << "Unable to open aircraft directory." << endl;
exit(-1);
while ((dire = ulReadDir(dirp)) != NULL) {
char *ptr;
- if ((ptr = strstr(dire->d_name, "-set.xml")) && ptr[8] == '\0' ) {
+ if (dire->d_isdir) {
+ if (recursive && strcmp("CVS", dire->d_name)
+ && strcmp(".", dire->d_name) && strcmp("..", dire->d_name))
+ {
+ SGPath next = path;
+ next.append(dire->d_name);
+
+ fgSearchAircraft(next, aircraft, true);
+ }
+ } else if ((ptr = strstr(dire->d_name, "-set.xml")) && (ptr[8] == '\0')) {
+
SGPath afile = path;
afile.append(dire->d_name);
}
char cstr[96];
- if (strlen(dire->d_name) <= 27)
+ if (strlen(dire->d_name) <= 27) {
snprintf(cstr, 96, " %-27s %s", dire->d_name,
(desc) ? desc->getStringValue() : "" );
- else
+ } else {
snprintf(cstr, 96, " %-27s\n%32c%s", dire->d_name, ' ',
(desc) ? desc->getStringValue() : "" );
+ }
aircraft.push_back(cstr);
}
}
- sort(aircraft.begin(), aircraft.end());
- cout << "Available aircraft:" << endl;
- for ( unsigned int i = 0; i < aircraft.size(); i++ ) {
- cout << aircraft[i] << endl;
- }
-
- aircraft.clear();
ulCloseDir(dirp);
}
+
+
+/*
+ * Search in the current directory, and in on directory deeper
+ * for <aircraft>-set.xml configuration files and show the aircaft name
+ * and the contents of the<description> tag in a sorted manner.
+ *
+ * @parampath the directory to search for configuration files
+ * @param recursive defines whether the directory should be searched recursively
+ */
+void fgShowAircraft(const SGPath &path, bool recursive) {
+ string_list aircraft;
+
+ fgSearchAircraft( path, aircraft, recursive );
+
+ sort(aircraft.begin(), aircraft.end());
+ cout << "Available aircraft:" << endl;
+ for ( unsigned int i = 0; i < aircraft.size(); i++ ) {
+ cout << aircraft[i] << endl;
+ }
+}