2001-07-02 22:14:09 +00:00
|
|
|
// fg_init.cxx -- Flight Gear top level initialization routines
|
1998-04-25 15:11:10 +00:00
|
|
|
//
|
|
|
|
// Written by Curtis Olson, started August 1997.
|
|
|
|
//
|
|
|
|
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// $Id$
|
1997-08-23 01:46:20 +00:00
|
|
|
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
1998-04-22 13:25:39 +00:00
|
|
|
|
1999-05-08 02:33:13 +00:00
|
|
|
// For BC 5.01 this must be included before OpenGL includes.
|
2001-03-23 22:42:49 +00:00
|
|
|
#ifdef SG_MATH_EXCEPTION_CLASH
|
1999-05-08 02:33:13 +00:00
|
|
|
# include <math.h>
|
|
|
|
#endif
|
|
|
|
|
2001-04-22 17:00:08 +00:00
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2002-12-10 20:50:48 +00:00
|
|
|
#include GLUT_H
|
1999-03-11 23:09:26 +00:00
|
|
|
|
1997-08-23 01:46:20 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2002-10-04 13:20:53 +00:00
|
|
|
#include <string.h> // strcmp()
|
1998-07-22 21:40:43 +00:00
|
|
|
|
2001-03-22 04:02:11 +00:00
|
|
|
|
|
|
|
#if defined( unix ) || defined( __CYGWIN__ )
|
2002-10-04 13:20:53 +00:00
|
|
|
# include <unistd.h> // for gethostname()
|
2001-03-22 04:02:11 +00:00
|
|
|
#endif
|
|
|
|
|
1998-07-22 21:40:43 +00:00
|
|
|
// work around a stdc++ lib bug in some versions of linux, but doesn't
|
|
|
|
// seem to hurt to have this here for all versions of Linux.
|
|
|
|
#ifdef linux
|
|
|
|
# define _G_NO_EXTERN_TEMPLATES
|
|
|
|
#endif
|
|
|
|
|
2000-02-15 03:30:01 +00:00
|
|
|
#include <simgear/compiler.h>
|
2001-07-19 04:53:13 +00:00
|
|
|
#include <simgear/misc/exception.hxx>
|
1999-02-26 22:08:34 +00:00
|
|
|
|
|
|
|
#include STL_STRING
|
1997-08-23 01:46:20 +00:00
|
|
|
|
2000-02-15 03:30:01 +00:00
|
|
|
#include <simgear/constants.h>
|
2000-02-16 23:01:03 +00:00
|
|
|
#include <simgear/debug/logstream.hxx>
|
|
|
|
#include <simgear/math/point3d.hxx>
|
|
|
|
#include <simgear/math/polar3d.hxx>
|
2000-09-27 20:16:22 +00:00
|
|
|
#include <simgear/math/sg_geodesy.hxx>
|
2001-03-25 14:20:12 +00:00
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2002-12-10 19:25:12 +00:00
|
|
|
#ifdef FG_USE_CLOUDS_3D
|
|
|
|
# include <simgear/sky/clouds3d/SkySceneLoader.hpp>
|
|
|
|
# include <simgear/sky/clouds3d/SkyUtil.hpp>
|
|
|
|
#endif
|
2000-07-06 22:13:24 +00:00
|
|
|
#include <simgear/timing/sg_time.hxx>
|
2002-02-06 23:31:33 +00:00
|
|
|
#include <simgear/timing/lowleveltime.h>
|
2000-02-15 03:30:01 +00:00
|
|
|
|
1998-10-17 01:33:52 +00:00
|
|
|
#include <Aircraft/aircraft.hxx>
|
2001-03-06 19:11:28 +00:00
|
|
|
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
|
2000-08-16 00:09:03 +00:00
|
|
|
#include <Airports/runways.hxx>
|
1998-08-25 16:59:08 +00:00
|
|
|
#include <Airports/simple.hxx>
|
2001-11-07 17:55:28 +00:00
|
|
|
#include <ATC/ATCdisplay.hxx>
|
2002-03-01 17:39:52 +00:00
|
|
|
#include <ATC/ATCmgr.hxx>
|
|
|
|
#include <ATC/atislist.hxx>
|
2002-04-03 23:54:44 +00:00
|
|
|
#include <ATC/towerlist.hxx>
|
|
|
|
#include <ATC/approachlist.hxx>
|
|
|
|
#include <ATC/AIMgr.hxx>
|
2000-04-30 06:51:49 +00:00
|
|
|
#include <Autopilot/auto_gui.hxx>
|
|
|
|
#include <Autopilot/newauto.hxx>
|
1998-04-24 00:49:17 +00:00
|
|
|
#include <Cockpit/cockpit.hxx>
|
2000-04-25 03:09:26 +00:00
|
|
|
#include <Cockpit/radiostack.hxx>
|
2002-07-07 15:45:56 +00:00
|
|
|
#include <Cockpit/steam.hxx>
|
User-visible
- knobs now continue to rotate when you hold down the mouse
- the middle mouse button makes knobs rotate much faster
- there are NAV1, NAV2, and ADF radios that can be tuned using the mouse
- there are standby frequencies for NAV1 and NAV2, and buttons to swap
- there is a crude, rather silly-looking DME, hard-wired to NAV1
- there is a crude, rather silly-looking autopilot that can lock
the heading (to the bug on the gyro), can lock to NAV1, and can lock
the current altitude
- the knobs for changing the radials on NAV1 and NAV2 look much better
and are in the right place
- tuning into an ILS frequency doesn't change the displayed radial for
NAV1
Code
- I've created a new module, sp_panel.[ch]xx, that constructs the
default single-prop panel; this works entirely outside of FGPanel,
so it is possible to construct similar modules for other sorts of
panels; all code specific to the default panel has been removed from
panel.cxx
- current_panel is now a pointer
- radiostack.[ch]xx keeps track both of the actual radial and of the
selected radial (they will differ with ILS); the NAV gauges should
not spin around automatically to show the actual radial (we need to
do something similar with the autopilot)
- the panel is initialized fairly early
- make sure that standby frequencies also get initialized
- I've started combining and clipping small textures to save texture
memory; there's a lot more to do, but at least I've made a start
2000-05-02 18:26:00 +00:00
|
|
|
#include <Cockpit/panel.hxx>
|
2000-09-22 17:20:56 +00:00
|
|
|
#include <Cockpit/panel_io.hxx>
|
The following changes were made to flightgear-0.7.5 code to implement the follow
ing features:
a) ADA Flight model - ADA.cxx, ADA.hxx, flight.hxx
b) Fighter a/c HUD - flight.hxx, hud.hxx, hud.cxx, cockpit.cxx, hud_ladr.c
xx, hud_card.cxx
c) 3-window display - options.hxx, options.cxx, viewer.cxx
d) Moving objects (ship) - main.cxx
e) Patches - main.cxx
ADA.cxx, ADA.hxx
--------------------------
Interface to the external ADA flight dynamics package.
flight.hxx
----------
Included prototypes for accepting additional data fron the External flight
model for fighter aircraft HUD
Hud.hxx
-------
Included prototypes for accepting additional data for fighter HUD from Exernal F
light model.
Defined FIGHTER_HUD pre-processor directive to enable compilation of fighter hud
code.
hud.cxx, cockpit.cxx, hud_ladr.cxx, hud_card.cxx
---------------------------------------
Included code to initialise additional reticles/text for fighter HUD which is co
nditionally
compiled if FIGHTER_HUD is defined.
options.hxx
-----------
Added window_offset, and function to retrieve its value for 3 windows
options.cxx
-----------
Changed few options to suit ADA/CEF projection system/screens and checks for win
dow offset.
views.cxx
---------
Added code to retrieve view offset for window.
Main.cxx
--------
Added code to load and move an aircraft carrier.
Patch to enable clouds from command line until Curtis fixes it. By default cloud
s are disabled.
2000-10-19 19:46:13 +00:00
|
|
|
#include <FDM/ADA.hxx>
|
1999-10-15 22:21:09 +00:00
|
|
|
#include <FDM/Balloon.h>
|
2002-09-28 21:42:03 +00:00
|
|
|
#include <FDM/ExternalNet/ExternalNet.hxx>
|
2002-02-25 03:22:03 +00:00
|
|
|
#include <FDM/JSBSim/JSBSim.hxx>
|
1999-10-14 01:53:43 +00:00
|
|
|
#include <FDM/LaRCsim.hxx>
|
|
|
|
#include <FDM/MagicCarpet.hxx>
|
2002-04-25 16:23:16 +00:00
|
|
|
#include <FDM/UFO.hxx>
|
2001-11-12 04:49:06 +00:00
|
|
|
#include <FDM/NullFDM.hxx>
|
2001-12-01 06:22:49 +00:00
|
|
|
#include <FDM/YASim/YASim.hxx>
|
2002-11-07 16:27:47 +00:00
|
|
|
#include <GUI/new_gui.hxx>
|
1999-03-11 23:09:26 +00:00
|
|
|
#include <Include/general.hxx>
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
#include <Input/input.hxx>
|
2002-09-24 14:51:37 +00:00
|
|
|
#include <Instrumentation/instrument_mgr.hxx>
|
2001-06-04 21:07:27 +00:00
|
|
|
// #include <Joystick/joystick.hxx>
|
2000-06-23 00:30:04 +00:00
|
|
|
#include <Objects/matlib.hxx>
|
2002-04-09 18:58:24 +00:00
|
|
|
#include <Model/acmodel.hxx>
|
2000-04-24 23:51:26 +00:00
|
|
|
#include <Navaids/fixlist.hxx>
|
|
|
|
#include <Navaids/ilslist.hxx>
|
2001-03-16 23:59:02 +00:00
|
|
|
#include <Navaids/mkrbeacons.hxx>
|
2000-04-24 23:51:26 +00:00
|
|
|
#include <Navaids/navlist.hxx>
|
1998-04-30 12:34:17 +00:00
|
|
|
#include <Scenery/scenery.hxx>
|
1998-04-22 13:25:39 +00:00
|
|
|
#include <Scenery/tilemgr.hxx>
|
2003-01-11 16:30:32 +00:00
|
|
|
#include <Scripting/scriptmgr.hxx>
|
2001-10-29 04:39:05 +00:00
|
|
|
#include <Sound/fg_fx.hxx>
|
|
|
|
#include <Sound/soundmgr.hxx>
|
2002-09-23 19:55:10 +00:00
|
|
|
#include <Systems/system_mgr.hxx>
|
2002-04-05 20:03:49 +00:00
|
|
|
#include <Time/FGEventMgr.hxx>
|
1998-04-22 13:25:39 +00:00
|
|
|
#include <Time/light.hxx>
|
|
|
|
#include <Time/sunpos.hxx>
|
1999-03-22 02:08:05 +00:00
|
|
|
#include <Time/moonpos.hxx>
|
2000-07-05 02:39:30 +00:00
|
|
|
#include <Time/tmp.hxx>
|
1999-08-12 17:13:44 +00:00
|
|
|
|
2002-05-12 00:12:19 +00:00
|
|
|
#ifdef FG_WEATHERCM
|
1999-08-12 17:13:44 +00:00
|
|
|
# include <WeatherCM/FGLocalWeatherDatabase.h>
|
|
|
|
#else
|
2002-02-22 23:37:45 +00:00
|
|
|
# include <Environment/environment_mgr.hxx>
|
1999-08-12 17:13:44 +00:00
|
|
|
#endif
|
1997-08-23 01:46:20 +00:00
|
|
|
|
1998-04-22 13:25:39 +00:00
|
|
|
#include "fg_init.hxx"
|
1999-11-19 02:10:24 +00:00
|
|
|
#include "fg_io.hxx"
|
2001-06-01 17:52:28 +00:00
|
|
|
#include "fg_commands.hxx"
|
2001-06-05 22:12:08 +00:00
|
|
|
#include "fg_props.hxx"
|
2001-01-13 22:06:39 +00:00
|
|
|
#include "options.hxx"
|
2000-07-08 06:29:19 +00:00
|
|
|
#include "globals.hxx"
|
2002-03-12 16:29:00 +00:00
|
|
|
#include "logger.hxx"
|
2001-07-22 19:51:16 +00:00
|
|
|
#include "viewmgr.hxx"
|
1998-04-22 13:25:39 +00:00
|
|
|
|
1999-03-11 23:09:26 +00:00
|
|
|
#if defined(FX) && defined(XMESA)
|
|
|
|
#include <GL/xmesa.h>
|
|
|
|
#endif
|
|
|
|
|
2001-03-23 22:59:18 +00:00
|
|
|
SG_USING_STD(string);
|
1998-06-27 16:54:32 +00:00
|
|
|
|
1998-02-12 21:58:27 +00:00
|
|
|
extern const char *default_root;
|
1997-08-25 20:27:21 +00:00
|
|
|
|
2002-12-10 19:25:12 +00:00
|
|
|
#ifdef FG_USE_CLOUDS_3D
|
|
|
|
SkySceneLoader *sgCloud3d;
|
|
|
|
#endif
|
1997-08-23 01:46:20 +00:00
|
|
|
|
2002-11-16 20:17:11 +00:00
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
// Scan the command line options for the specified option and return
|
|
|
|
// the value.
|
|
|
|
static string fgScanForOption( const string& option, int argc, char **argv ) {
|
2002-11-16 20:17:11 +00:00
|
|
|
int i = 1;
|
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Scanning command line for: " << option );
|
|
|
|
|
|
|
|
int len = option.length();
|
2002-11-16 20:17:11 +00:00
|
|
|
|
|
|
|
while ( i < argc ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_DEBUG, "argv[" << i << "] = " << argv[i] );
|
|
|
|
|
|
|
|
string arg = argv[i];
|
2002-11-16 20:41:00 +00:00
|
|
|
if ( arg.find( option ) == 0 ) {
|
|
|
|
return arg.substr( len );
|
2002-11-16 20:17:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
// Scan the user config files for the specified option and return
|
|
|
|
// the value.
|
|
|
|
static string fgScanForOption( const string& option, const string& path ) {
|
2002-11-16 20:17:11 +00:00
|
|
|
sg_gzifstream in( path );
|
2002-11-16 20:41:00 +00:00
|
|
|
if ( !in.is_open() ) {
|
|
|
|
return "";
|
|
|
|
}
|
2002-11-16 20:17:11 +00:00
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Scanning " << path << " for: " << option );
|
|
|
|
|
|
|
|
int len = option.length();
|
2002-11-16 20:17:11 +00:00
|
|
|
|
|
|
|
in >> skipcomment;
|
|
|
|
#ifndef __MWERKS__
|
|
|
|
while ( ! in.eof() ) {
|
|
|
|
#else
|
|
|
|
char c = '\0';
|
|
|
|
while ( in.get(c) && c != '\0' ) {
|
|
|
|
in.putback(c);
|
|
|
|
#endif
|
|
|
|
string line;
|
|
|
|
|
|
|
|
#if defined( macintosh )
|
|
|
|
getline( in, line, '\r' );
|
|
|
|
#else
|
|
|
|
getline( in, line, '\n' );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// catch extraneous (DOS) line ending character
|
|
|
|
if ( line[line.length() - 1] < 32 ) {
|
|
|
|
line = line.substr( 0, line.length()-1 );
|
|
|
|
}
|
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
if ( line.find( option ) == 0 ) {
|
|
|
|
return line.substr( len );
|
2002-11-16 20:17:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
in >> skipcomment;
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Read in configuration (files and command line options) but only set
|
|
|
|
// fg_root
|
2000-10-04 22:52:34 +00:00
|
|
|
bool fgInitFGRoot ( int argc, char **argv ) {
|
2001-01-13 22:06:39 +00:00
|
|
|
string root;
|
|
|
|
char* envp;
|
|
|
|
|
2002-11-16 20:41:00 +00:00
|
|
|
// First parse command line options looking for --fg-root=, this
|
|
|
|
// will override anything specified in a config file
|
|
|
|
root = fgScanForOption( "--fg-root=", argc, argv);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
2001-03-22 04:02:11 +00:00
|
|
|
#if defined( unix ) || defined( __CYGWIN__ )
|
|
|
|
// Next check home directory for .fgfsrc.hostname file
|
2002-03-20 19:16:13 +00:00
|
|
|
if ( root.empty() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
envp = ::getenv( "HOME" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
SGPath config( envp );
|
|
|
|
config.append( ".fgfsrc" );
|
|
|
|
char name[256];
|
|
|
|
gethostname( name, 256 );
|
|
|
|
config.concat( "." );
|
|
|
|
config.concat( name );
|
2002-11-16 20:41:00 +00:00
|
|
|
root = fgScanForOption( "--fg-root=", config.str() );
|
2002-10-04 13:20:53 +00:00
|
|
|
}
|
2001-03-22 04:02:11 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-01-13 22:06:39 +00:00
|
|
|
// Next check home directory for .fgfsrc file
|
2002-03-20 19:16:13 +00:00
|
|
|
if ( root.empty() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
envp = ::getenv( "HOME" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
SGPath config( envp );
|
|
|
|
config.append( ".fgfsrc" );
|
2002-11-16 20:41:00 +00:00
|
|
|
root = fgScanForOption( "--fg-root=", config.str() );
|
2002-10-04 13:20:53 +00:00
|
|
|
}
|
2001-01-13 22:06:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next check if fg-root is set as an env variable
|
2002-03-20 19:16:13 +00:00
|
|
|
if ( root.empty() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
envp = ::getenv( "FG_ROOT" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
root = envp;
|
|
|
|
}
|
2001-01-13 22:06:39 +00:00
|
|
|
}
|
2000-10-04 22:52:34 +00:00
|
|
|
|
2001-01-13 22:06:39 +00:00
|
|
|
// Otherwise, default to a random compiled-in location if we can't
|
|
|
|
// find fg-root any other way.
|
2002-03-20 19:16:13 +00:00
|
|
|
if ( root.empty() ) {
|
2001-04-05 20:25:40 +00:00
|
|
|
#if defined( __CYGWIN__ )
|
|
|
|
root = "/FlightGear";
|
|
|
|
#elif defined( WIN32 )
|
2002-10-04 13:20:53 +00:00
|
|
|
root = "\\FlightGear";
|
2001-01-13 22:06:39 +00:00
|
|
|
#elif defined( macintosh )
|
2002-10-04 13:20:53 +00:00
|
|
|
root = "";
|
2001-01-13 22:06:39 +00:00
|
|
|
#else
|
2002-10-04 13:20:53 +00:00
|
|
|
root = PKGLIBDIR;
|
2001-01-13 22:06:39 +00:00
|
|
|
#endif
|
2000-10-04 22:52:34 +00:00
|
|
|
}
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "fg_root = " << root );
|
2001-01-13 22:06:39 +00:00
|
|
|
globals->set_fg_root(root);
|
2000-10-04 22:52:34 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-16 20:17:11 +00:00
|
|
|
// Read in configuration (files and command line options) but only set
|
|
|
|
// aircraft
|
|
|
|
bool fgInitFGAircraft ( int argc, char **argv ) {
|
|
|
|
string aircraft;
|
|
|
|
char* envp;
|
|
|
|
|
|
|
|
// First parse command line options looking for --aircraft=, this
|
|
|
|
// will override anything specified in a config file
|
2002-11-16 20:41:00 +00:00
|
|
|
aircraft = fgScanForOption( "--aircraft=", argc, argv );
|
2002-11-16 20:17:11 +00:00
|
|
|
|
|
|
|
#if defined( unix ) || defined( __CYGWIN__ )
|
|
|
|
// Next check home directory for .fgfsrc.hostname file
|
|
|
|
if ( aircraft.empty() ) {
|
|
|
|
envp = ::getenv( "HOME" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
SGPath config( envp );
|
|
|
|
config.append( ".fgfsrc" );
|
|
|
|
char name[256];
|
|
|
|
gethostname( name, 256 );
|
|
|
|
config.concat( "." );
|
|
|
|
config.concat( name );
|
2002-11-16 20:41:00 +00:00
|
|
|
aircraft = fgScanForOption( "--aircraft=", config.str() );
|
2002-11-16 20:17:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Next check home directory for .fgfsrc file
|
|
|
|
if ( aircraft.empty() ) {
|
|
|
|
envp = ::getenv( "HOME" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
SGPath config( envp );
|
|
|
|
config.append( ".fgfsrc" );
|
2002-11-16 20:41:00 +00:00
|
|
|
aircraft = fgScanForOption( "--aircraft=", config.str() );
|
2002-11-16 20:17:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if an aircraft was specified, set the property name
|
|
|
|
if ( !aircraft.empty() ) {
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "aircraft = " << aircraft );
|
|
|
|
fgSetString("/sim/aircraft", aircraft.c_str() );
|
|
|
|
} else {
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "No user specified aircraft, using default" );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-16 19:17:58 +00:00
|
|
|
// Return the current base package version
|
|
|
|
string fgBasePackageVersion() {
|
|
|
|
SGPath base_path( globals->get_fg_root() );
|
|
|
|
base_path.append("version");
|
|
|
|
|
|
|
|
sg_gzifstream in( base_path.str() );
|
|
|
|
if ( !in.is_open() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
SGPath old_path( globals->get_fg_root() );
|
|
|
|
old_path.append( "Thanks" );
|
|
|
|
sg_gzifstream old( old_path.str() );
|
|
|
|
if ( !old.is_open() ) {
|
|
|
|
return "[none]";
|
|
|
|
} else {
|
|
|
|
return "[old version]";
|
|
|
|
}
|
2001-07-16 19:17:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string version;
|
|
|
|
in >> version;
|
|
|
|
|
|
|
|
return version;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-07 15:45:00 +00:00
|
|
|
// Initialize the localization
|
|
|
|
SGPropertyNode *fgInitLocale(const char *language) {
|
|
|
|
SGPropertyNode *c_node = NULL, *d_node = NULL;
|
|
|
|
SGPropertyNode *intl = fgGetNode("/sim/intl");
|
|
|
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Selecting language: " << language );
|
|
|
|
|
|
|
|
// localization not defined
|
|
|
|
if (!intl)
|
|
|
|
return NULL;
|
2002-10-10 15:02:50 +00:00
|
|
|
|
2002-10-07 15:45:00 +00:00
|
|
|
//
|
|
|
|
// Select the proper language from the list
|
|
|
|
//
|
|
|
|
vector<SGPropertyNode_ptr> locale = intl->getChildren("locale");
|
|
|
|
for (unsigned int i = 0; i < locale.size(); i++) {
|
|
|
|
|
|
|
|
vector<SGPropertyNode_ptr> lang = locale[i]->getChildren("lang");
|
|
|
|
for (unsigned int j = 0; j < lang.size(); j++) {
|
|
|
|
|
|
|
|
if (!strcmp(lang[j]->getStringValue(), language)) {
|
|
|
|
c_node = locale[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get the defaults
|
|
|
|
d_node = intl->getChild("locale");
|
|
|
|
if (!c_node)
|
|
|
|
c_node = d_node;
|
|
|
|
|
|
|
|
// Check for localized font
|
|
|
|
SGPropertyNode *font_n = c_node->getNode("font", true);
|
|
|
|
if ( !strcmp(font_n->getStringValue(), "") )
|
|
|
|
font_n->setStringValue(d_node->getStringValue("font", "typewriter.txf"));
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Load the default strings
|
|
|
|
//
|
|
|
|
SGPath d_path( globals->get_fg_root() );
|
|
|
|
|
|
|
|
const char *d_path_str = d_node->getStringValue("strings");
|
|
|
|
if (!d_path_str) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
d_path.append(d_path_str);
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
|
|
|
<< d_path.str());
|
|
|
|
|
|
|
|
SGPropertyNode *strings = c_node->getNode("strings");
|
|
|
|
try {
|
|
|
|
readProperties(d_path.str(), strings);
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Load the language specific strings
|
|
|
|
//
|
|
|
|
if (c_node != d_node) {
|
|
|
|
SGPath c_path( globals->get_fg_root() );
|
|
|
|
|
|
|
|
const char *c_path_str = c_node->getStringValue("strings");
|
|
|
|
if (!c_path_str) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
c_path.append(c_path_str);
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
|
|
|
<< c_path.str());
|
|
|
|
|
|
|
|
try {
|
|
|
|
readProperties(c_path.str(), strings);
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return c_node;
|
|
|
|
}
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
|
2002-10-10 15:02:50 +00:00
|
|
|
|
|
|
|
// Initialize the localization routines
|
|
|
|
bool fgDetectLanguage() {
|
|
|
|
char *language = ::getenv("LANG");
|
|
|
|
|
|
|
|
if (language == NULL) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Unable to detect the language" );
|
|
|
|
language = "C";
|
|
|
|
}
|
|
|
|
|
|
|
|
SGPropertyNode *locale = fgInitLocale(language);
|
|
|
|
if (!locale) {
|
|
|
|
cerr << "No internationalization settings specified in preferences.xml"
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
globals->set_locale( locale );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-10-10 18:39:52 +00:00
|
|
|
// Attempt to locate and parse the various non-XML config files in order
|
|
|
|
// from least precidence to greatest precidence
|
|
|
|
static void
|
|
|
|
do_options (int argc, char ** argv)
|
|
|
|
{
|
|
|
|
// Check for $fg_root/system.fgfsrc
|
|
|
|
SGPath config( globals->get_fg_root() );
|
|
|
|
config.append( "system.fgfsrc" );
|
|
|
|
fgParseOptions(config.str());
|
|
|
|
|
|
|
|
#if defined( unix ) || defined( __CYGWIN__ )
|
|
|
|
char name[256];
|
|
|
|
// Check for $fg_root/system.fgfsrc.hostname
|
|
|
|
gethostname( name, 256 );
|
|
|
|
config.concat( "." );
|
|
|
|
config.concat( name );
|
|
|
|
fgParseOptions(config.str());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Check for ~/.fgfsrc
|
|
|
|
char* envp = ::getenv( "HOME" );
|
|
|
|
if ( envp != NULL ) {
|
|
|
|
config.set( envp );
|
|
|
|
config.append( ".fgfsrc" );
|
|
|
|
fgParseOptions(config.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined( unix ) || defined( __CYGWIN__ )
|
|
|
|
// Check for ~/.fgfsrc.hostname
|
|
|
|
gethostname( name, 256 );
|
|
|
|
config.concat( "." );
|
|
|
|
config.concat( name );
|
|
|
|
fgParseOptions(config.str());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Parse remaining command line options
|
|
|
|
// These will override anything specified in a config file
|
|
|
|
fgParseArgs(argc, argv);
|
|
|
|
}
|
|
|
|
|
2002-10-10 15:02:50 +00:00
|
|
|
|
|
|
|
// Read in configuration (file and command line)
|
|
|
|
bool fgInitConfig ( int argc, char **argv ) {
|
|
|
|
|
2002-11-16 20:17:11 +00:00
|
|
|
// First, set some sane default values
|
2002-10-10 15:02:50 +00:00
|
|
|
fgSetDefaults();
|
|
|
|
|
|
|
|
// Read global preferences from $FG_ROOT/preferences.xml
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Reading global preferences");
|
2002-11-06 18:57:31 +00:00
|
|
|
fgLoadProps("preferences.xml", globals->get_props());
|
2002-10-10 15:02:50 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
|
|
|
|
|
|
|
|
// Detect the required language as early as possible
|
2002-11-16 20:17:11 +00:00
|
|
|
if ( !fgDetectLanguage() ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scan user config files and command line for a specified aircraft.
|
|
|
|
fgInitFGAircraft(argc, argv);
|
2002-10-10 15:02:50 +00:00
|
|
|
|
|
|
|
string aircraft = fgGetString("/sim/aircraft", "");
|
2002-11-16 20:17:11 +00:00
|
|
|
if ( aircraft.size() > 0 ) {
|
|
|
|
SGPath aircraft_path(globals->get_fg_root());
|
|
|
|
aircraft_path.append("Aircraft");
|
|
|
|
aircraft_path.append(aircraft);
|
|
|
|
aircraft_path.concat("-set.xml");
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Reading default aircraft: " << aircraft
|
|
|
|
<< " from " << aircraft_path.str());
|
|
|
|
try {
|
|
|
|
readProperties(aircraft_path.str(), globals->get_props());
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
string message = "Error reading default aircraft: ";
|
|
|
|
message += e.getFormattedMessage();
|
|
|
|
SG_LOG(SG_INPUT, SG_ALERT, message);
|
|
|
|
exit(2);
|
|
|
|
}
|
2002-10-10 15:02:50 +00:00
|
|
|
} else {
|
2002-11-16 20:17:11 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_ALERT, "No default aircraft specified");
|
2002-10-10 15:02:50 +00:00
|
|
|
}
|
|
|
|
|
2002-11-16 20:17:11 +00:00
|
|
|
// parse options after loading aircraft to ensure any user
|
|
|
|
// overrides of defaults are honored.
|
2002-10-10 18:39:52 +00:00
|
|
|
do_options(argc, argv);
|
2002-10-10 15:02:50 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-10-12 01:08:09 +00:00
|
|
|
// find basic airport location info from airport database
|
|
|
|
bool fgFindAirportID( const string& id, FGAirport *a ) {
|
1998-08-27 17:01:55 +00:00
|
|
|
if ( id.length() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
SGPath path( globals->get_fg_root() );
|
|
|
|
path.append( "Airports" );
|
|
|
|
path.append( "simple.mk4" );
|
|
|
|
FGAirports airports( path.c_str() );
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Searching for airport code = " << id );
|
|
|
|
|
|
|
|
if ( ! airports.search( id, a ) ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"Failed to find " << id << " in " << path.str() );
|
|
|
|
return false;
|
|
|
|
}
|
1998-07-30 23:48:24 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
return false;
|
2000-07-21 22:54:14 +00:00
|
|
|
}
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-10-04 13:20:53 +00:00
|
|
|
"Position for " << id << " is ("
|
|
|
|
<< a->longitude << ", "
|
|
|
|
<< a->latitude << ")" );
|
1998-07-30 23:48:24 +00:00
|
|
|
|
2000-07-21 22:54:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2000-08-16 00:09:03 +00:00
|
|
|
|
2002-11-30 20:10:16 +00:00
|
|
|
// get airport elevation
|
|
|
|
static double fgGetAirportElev( const string& id ) {
|
|
|
|
FGAirport a;
|
|
|
|
// double lon, lat;
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Finding elevation for airport: " << id );
|
|
|
|
|
|
|
|
if ( fgFindAirportID( id, &a ) ) {
|
|
|
|
return a.elevation;
|
|
|
|
} else {
|
|
|
|
return -9999.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-15 21:13:29 +00:00
|
|
|
// Preset lon/lat given an airport id
|
2002-11-16 21:34:51 +00:00
|
|
|
static bool fgSetPosFromAirportID( const string& id ) {
|
2000-10-12 01:08:09 +00:00
|
|
|
FGAirport a;
|
2000-10-25 15:27:55 +00:00
|
|
|
// double lon, lat;
|
2000-10-12 01:08:09 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-10-04 13:20:53 +00:00
|
|
|
"Attempting to set starting position from airport code " << id );
|
2000-10-12 01:08:09 +00:00
|
|
|
|
|
|
|
if ( fgFindAirportID( id, &a ) ) {
|
2002-11-15 21:13:29 +00:00
|
|
|
// presets
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", a.longitude );
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", a.latitude );
|
|
|
|
|
|
|
|
// other code depends on the actual postition being set so set
|
|
|
|
// that as well
|
|
|
|
fgSetDouble("/position/longitude-deg", a.longitude );
|
|
|
|
fgSetDouble("/position/latitude-deg", a.latitude );
|
|
|
|
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-11-15 21:13:29 +00:00
|
|
|
"Position for " << id << " is (" << a.longitude
|
|
|
|
<< ", " << a.latitude << ")" );
|
2002-10-04 13:20:53 +00:00
|
|
|
|
|
|
|
return true;
|
2000-10-12 01:08:09 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
return false;
|
2000-10-12 01:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-06 17:23:18 +00:00
|
|
|
// Set current tower position lon/lat given an airport id
|
2002-11-16 21:34:51 +00:00
|
|
|
static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) {
|
2002-04-06 17:23:18 +00:00
|
|
|
FGAirport a;
|
|
|
|
// tower height hard coded for now...
|
|
|
|
float towerheight=50.0f;
|
|
|
|
|
|
|
|
// make a little off the heading for 1 runway airports...
|
|
|
|
float fudge_lon = fabs(sin(hdg)) * .003f;
|
|
|
|
float fudge_lat = .003f - fudge_lon;
|
|
|
|
|
|
|
|
if ( fgFindAirportID( id, &a ) ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
fgSetDouble("/sim/tower/longitude-deg", a.longitude + fudge_lon);
|
|
|
|
fgSetDouble("/sim/tower/latitude-deg", a.latitude + fudge_lat);
|
2002-04-06 17:23:18 +00:00
|
|
|
fgSetDouble("/sim/tower/altitude-ft", a.elevation + towerheight);
|
2002-10-04 13:20:53 +00:00
|
|
|
return true;
|
2002-04-06 17:23:18 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
return false;
|
2002-04-06 17:23:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-16 00:09:03 +00:00
|
|
|
// Set current_options lon/lat given an airport id and heading (degrees)
|
2002-11-16 21:34:51 +00:00
|
|
|
static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
|
2000-08-16 00:09:03 +00:00
|
|
|
FGRunway r;
|
|
|
|
FGRunway found_r;
|
2000-11-01 23:27:32 +00:00
|
|
|
double found_dir = 0.0;
|
2000-08-16 00:09:03 +00:00
|
|
|
|
|
|
|
if ( id.length() ) {
|
2002-02-05 20:54:08 +00:00
|
|
|
// set initial position from runway and heading
|
|
|
|
|
|
|
|
SGPath path( globals->get_fg_root() );
|
|
|
|
path.append( "Airports" );
|
|
|
|
path.append( "runways.mk4" );
|
|
|
|
FGRunways runways( path.c_str() );
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Attempting to set starting position from runway code "
|
|
|
|
<< id << " heading " << tgt_hdg );
|
|
|
|
|
|
|
|
if ( ! runways.search( id, &r ) ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"Failed to find " << id << " in database." );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double diff;
|
|
|
|
double min_diff = 360.0;
|
|
|
|
|
|
|
|
while ( r.id == id ) {
|
|
|
|
// forward direction
|
|
|
|
diff = tgt_hdg - r.heading;
|
|
|
|
while ( diff < -180.0 ) { diff += 360.0; }
|
|
|
|
while ( diff > 180.0 ) { diff -= 360.0; }
|
|
|
|
diff = fabs(diff);
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Runway " << r.rwy_no << " heading = " << r.heading <<
|
|
|
|
" diff = " << diff );
|
|
|
|
if ( diff < min_diff ) {
|
|
|
|
min_diff = diff;
|
|
|
|
found_r = r;
|
|
|
|
found_dir = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// reverse direction
|
|
|
|
diff = tgt_hdg - r.heading - 180.0;
|
|
|
|
while ( diff < -180.0 ) { diff += 360.0; }
|
|
|
|
while ( diff > 180.0 ) { diff -= 360.0; }
|
|
|
|
diff = fabs(diff);
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Runway -" << r.rwy_no << " heading = " <<
|
|
|
|
r.heading + 180.0 <<
|
|
|
|
" diff = " << diff );
|
|
|
|
if ( diff < min_diff ) {
|
|
|
|
min_diff = diff;
|
|
|
|
found_r = r;
|
|
|
|
found_dir = 180.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
runways.next( &r );
|
|
|
|
}
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << found_r.rwy_no
|
|
|
|
<< " + " << found_dir );
|
2000-08-16 00:09:03 +00:00
|
|
|
|
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
return false;
|
2000-08-16 00:09:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double heading = found_r.heading + found_dir;
|
|
|
|
while ( heading >= 360.0 ) { heading -= 360.0; }
|
|
|
|
|
|
|
|
double lat2, lon2, az2;
|
|
|
|
double azimuth = found_r.heading + found_dir + 180.0;
|
|
|
|
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-10-04 13:20:53 +00:00
|
|
|
"runway = " << found_r.lon << ", " << found_r.lat
|
|
|
|
<< " length = " << found_r.length * SG_FEET_TO_METER * 0.5
|
|
|
|
<< " heading = " << azimuth );
|
2001-03-02 23:27:22 +00:00
|
|
|
|
2000-08-16 00:09:03 +00:00
|
|
|
geo_direct_wgs_84 ( 0, found_r.lat, found_r.lon,
|
2002-10-04 13:20:53 +00:00
|
|
|
azimuth, found_r.length * SG_FEET_TO_METER * 0.5 - 5.0,
|
|
|
|
&lat2, &lon2, &az2 );
|
2001-03-02 23:27:22 +00:00
|
|
|
|
2002-11-15 21:13:29 +00:00
|
|
|
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
double olat, olon;
|
2002-11-15 21:13:29 +00:00
|
|
|
double odist = fgGetDouble("/sim/presets/offset-distance");
|
2002-10-04 13:20:53 +00:00
|
|
|
odist *= SG_NM_TO_METER;
|
|
|
|
double oaz = azimuth;
|
2002-11-15 21:13:29 +00:00
|
|
|
if ( fabs(fgGetDouble("/sim/presets/offset-azimuth")) > SG_EPSILON ) {
|
|
|
|
oaz = fgGetDouble("/sim/presets/offset-azimuth") + 180;
|
2002-10-04 13:20:53 +00:00
|
|
|
}
|
|
|
|
while ( oaz >= 360.0 ) { oaz -= 360.0; }
|
|
|
|
geo_direct_wgs_84 ( 0, lat2, lon2, oaz, odist, &olat, &olon, &az2 );
|
|
|
|
lat2=olat;
|
|
|
|
lon2=olon;
|
2001-03-02 23:27:22 +00:00
|
|
|
}
|
2002-11-15 21:13:29 +00:00
|
|
|
|
|
|
|
// presets
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", lon2 );
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", lat2 );
|
|
|
|
fgSetDouble("/sim/presets/heading-deg", heading );
|
|
|
|
|
|
|
|
// other code depends on the actual values being set ...
|
2001-07-02 22:27:24 +00:00
|
|
|
fgSetDouble("/position/longitude-deg", lon2 );
|
|
|
|
fgSetDouble("/position/latitude-deg", lat2 );
|
|
|
|
fgSetDouble("/orientation/heading-deg", heading );
|
2000-08-16 00:09:03 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-10-04 13:20:53 +00:00
|
|
|
"Position for " << id << " is ("
|
|
|
|
<< lon2 << ", "
|
|
|
|
<< lat2 << ") new heading is "
|
|
|
|
<< heading );
|
2000-08-16 00:09:03 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-05-14 05:22:52 +00:00
|
|
|
|
2002-11-17 04:04:21 +00:00
|
|
|
// Set current_options lon/lat given an airport id and heading (degrees)
|
|
|
|
static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy ) {
|
|
|
|
FGRunway r;
|
|
|
|
FGRunway found_r;
|
|
|
|
double heading = 0.0;
|
|
|
|
string runway;
|
2002-11-17 04:17:27 +00:00
|
|
|
bool match = false;
|
2002-11-17 04:04:21 +00:00
|
|
|
|
|
|
|
// standardize input number
|
|
|
|
string tmp = rwy.substr(1, 1);
|
|
|
|
if ( tmp == "L" || tmp == "R" || tmp == "C" ) {
|
|
|
|
runway = "0";
|
|
|
|
runway += rwy;
|
|
|
|
} else {
|
|
|
|
runway = rwy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( id.length() ) {
|
|
|
|
// set initial position from runway and heading
|
|
|
|
|
|
|
|
SGPath path( globals->get_fg_root() );
|
|
|
|
path.append( "Airports" );
|
|
|
|
path.append( "runways.mk4" );
|
|
|
|
FGRunways runways( path.c_str() );
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Attempting to set starting position for "
|
|
|
|
<< id << ":" << runway );
|
|
|
|
|
|
|
|
if ( ! runways.search( id, &r ) ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"Failed to find " << id << " in database." );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( r.id == id ) {
|
|
|
|
// forward direction
|
|
|
|
if ( r.rwy_no == runway ) {
|
|
|
|
found_r = r;
|
|
|
|
heading = r.heading;
|
2002-11-17 04:17:27 +00:00
|
|
|
match = true;
|
2002-11-17 04:04:21 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Runway " << r.rwy_no << " heading = " << heading );
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate reciprocal runway number
|
|
|
|
string snum = r.rwy_no;
|
|
|
|
int len = snum.length();
|
|
|
|
string letter = "";
|
|
|
|
string rev_letter = "";
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < len; ++i ) {
|
|
|
|
string tmp = snum.substr(i, 1);
|
|
|
|
if ( tmp == "L" ) {
|
|
|
|
letter = "L";
|
|
|
|
rev_letter = "R";
|
|
|
|
} else if ( tmp == "R" ) {
|
|
|
|
letter = "R";
|
|
|
|
rev_letter = "L";
|
|
|
|
} else if ( tmp == "C" ) {
|
|
|
|
letter == "C";
|
|
|
|
rev_letter = "C";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( i = 0; i < len; ++i ) {
|
|
|
|
string tmp = snum.substr(i, 1);
|
|
|
|
if ( tmp == "L" || tmp == "R" || tmp == "C" || tmp == " " ) {
|
|
|
|
snum = snum.substr(0, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway num = '" << snum << "'");
|
|
|
|
int num = atoi( snum.c_str() ) + 18;
|
|
|
|
while ( num > 36 ) { num -= 36; }
|
|
|
|
while ( num <= 0 ) { num += 36; }
|
|
|
|
|
|
|
|
char recip_no[10];
|
|
|
|
snprintf( recip_no, 10, "%02d%s", num, rev_letter.c_str() );
|
|
|
|
|
|
|
|
// reverse direction
|
|
|
|
if ( (string)recip_no == runway ) {
|
|
|
|
found_r = r;
|
|
|
|
heading = r.heading + 180;
|
|
|
|
while ( heading > 360.0 ) { heading -= 360; }
|
2002-11-17 04:17:27 +00:00
|
|
|
match = true;
|
2002-11-17 04:04:21 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Runway " << r.rwy_no << " heading = " << heading );
|
|
|
|
}
|
|
|
|
|
|
|
|
runways.next( &r );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
if ( match ) {
|
|
|
|
double lat2, lon2, az2;
|
|
|
|
double azimuth = heading + 180.0;
|
|
|
|
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
2002-11-17 04:04:21 +00:00
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"runway = " << found_r.lon << ", " << found_r.lat
|
|
|
|
<< " length = " << found_r.length * SG_FEET_TO_METER * 0.5
|
|
|
|
<< " heading = " << azimuth );
|
2002-11-17 04:04:21 +00:00
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
geo_direct_wgs_84 ( 0, found_r.lat, found_r.lon,
|
|
|
|
azimuth,
|
|
|
|
found_r.length * SG_FEET_TO_METER * 0.5 - 5.0,
|
|
|
|
&lat2, &lon2, &az2 );
|
|
|
|
|
|
|
|
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
|
|
|
|
{
|
|
|
|
double olat, olon;
|
|
|
|
double odist = fgGetDouble("/sim/presets/offset-distance");
|
|
|
|
odist *= SG_NM_TO_METER;
|
|
|
|
double oaz = azimuth;
|
|
|
|
if ( fabs(fgGetDouble("/sim/presets/offset-azimuth")) > SG_EPSILON )
|
|
|
|
{
|
|
|
|
oaz = fgGetDouble("/sim/presets/offset-azimuth") + 180;
|
|
|
|
}
|
|
|
|
while ( oaz >= 360.0 ) { oaz -= 360.0; }
|
|
|
|
geo_direct_wgs_84 ( 0, lat2, lon2, oaz, odist, &olat, &olon, &az2 );
|
|
|
|
lat2=olat;
|
|
|
|
lon2=olon;
|
2002-11-17 04:04:21 +00:00
|
|
|
}
|
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
// presets
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", lon2 );
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", lat2 );
|
|
|
|
fgSetDouble("/sim/presets/heading-deg", heading );
|
2002-11-17 04:04:21 +00:00
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
// other code depends on the actual values being set ...
|
|
|
|
fgSetDouble("/position/longitude-deg", lon2 );
|
|
|
|
fgSetDouble("/position/latitude-deg", lat2 );
|
|
|
|
fgSetDouble("/orientation/heading-deg", heading );
|
2002-11-17 04:04:21 +00:00
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Position for " << id << " is ("
|
|
|
|
<< lon2 << ", "
|
|
|
|
<< lat2 << ") new heading is "
|
|
|
|
<< heading );
|
2002-11-17 04:04:21 +00:00
|
|
|
|
2002-11-17 04:17:27 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2002-11-17 04:04:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-16 21:34:51 +00:00
|
|
|
static void fgSetDistOrAltFromGlideSlope() {
|
2002-11-30 20:10:16 +00:00
|
|
|
string apt_id = fgGetString("/sim/presets/airport-id");
|
2002-11-18 21:31:33 +00:00
|
|
|
double gs = fgGetDouble("/sim/presets/glideslope-deg")
|
|
|
|
* SG_DEGREES_TO_RADIANS ;
|
2002-11-15 21:13:29 +00:00
|
|
|
double od = fgGetDouble("/sim/presets/offset-distance");
|
|
|
|
double alt = fgGetDouble("/sim/presets/altitude-ft");
|
2002-11-30 20:10:16 +00:00
|
|
|
|
|
|
|
double apt_elev = 0.0;
|
|
|
|
if ( ! apt_id.empty() ) {
|
|
|
|
apt_elev = fgGetAirportElev( apt_id );
|
|
|
|
if ( apt_elev < -9990.0 ) {
|
|
|
|
apt_elev = 0.0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
apt_elev = 0.0;
|
|
|
|
}
|
|
|
|
|
2002-02-20 16:56:44 +00:00
|
|
|
if( fabs(gs) > 0.01 && fabs(od) > 0.1 && alt < -9990 ) {
|
2002-11-16 21:34:51 +00:00
|
|
|
// set altitude from glideslope and offset-distance
|
2002-10-04 13:20:53 +00:00
|
|
|
od *= SG_NM_TO_METER * SG_METER_TO_FEET;
|
2002-11-30 20:10:16 +00:00
|
|
|
alt = fabs(od*tan(gs)) + apt_elev;
|
2002-11-16 21:34:51 +00:00
|
|
|
fgSetDouble("/sim/presets/altitude-ft", alt);
|
2002-11-15 21:13:29 +00:00
|
|
|
fgSetBool("/sim/presets/onground", false);
|
2002-12-12 01:24:48 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Calculated altitude as: "
|
|
|
|
<< alt << " ft" );
|
2002-02-20 16:56:44 +00:00
|
|
|
} else if( fabs(gs) > 0.01 && alt > 0 && fabs(od) < 0.1) {
|
2002-11-16 21:34:51 +00:00
|
|
|
// set offset-distance from glideslope and altitude
|
2002-11-30 20:10:16 +00:00
|
|
|
od = (alt - apt_elev) / tan(gs);
|
2002-10-04 13:20:53 +00:00
|
|
|
od *= -1*SG_FEET_TO_METER * SG_METER_TO_NM;
|
2002-11-16 21:34:51 +00:00
|
|
|
fgSetDouble("/sim/presets/offset-distance", od);
|
2002-12-12 01:24:48 +00:00
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Calculated offset distance as: "
|
|
|
|
<< od << " nm" );
|
2002-02-20 16:56:44 +00:00
|
|
|
} else if( fabs(gs) > 0.01 ) {
|
2002-11-16 20:17:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"Glideslope given but not altitude or offset-distance." );
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Resetting glideslope to zero" );
|
2002-11-18 21:31:33 +00:00
|
|
|
fgSetDouble("/sim/presets/glideslope-deg", 0);
|
2002-11-30 20:10:16 +00:00
|
|
|
fgSetBool("/sim/presets/onground", true);
|
2002-10-04 13:20:53 +00:00
|
|
|
}
|
|
|
|
}
|
2000-08-16 00:09:03 +00:00
|
|
|
|
2002-11-16 20:17:11 +00:00
|
|
|
|
2003-01-05 00:10:36 +00:00
|
|
|
// Set current_options lon/lat given an airport id and heading (degrees)
|
|
|
|
static bool fgSetPosFromNAV( const string& id, const double& freq ) {
|
|
|
|
FGNav nav;
|
|
|
|
|
|
|
|
// set initial position from runway and heading
|
|
|
|
if ( current_navlist->findByIdentAndFreq( id.c_str(), freq, &nav ) ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
|
|
|
|
<< id << ":" << freq );
|
|
|
|
|
|
|
|
double lon = nav.get_lon();
|
|
|
|
double lat = nav.get_lat();
|
|
|
|
|
|
|
|
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
|
|
|
|
{
|
|
|
|
double odist = fgGetDouble("/sim/presets/offset-distance")
|
|
|
|
* SG_NM_TO_METER;
|
|
|
|
double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth"))
|
|
|
|
+ 180.0;
|
|
|
|
while ( oaz >= 360.0 ) { oaz -= 360.0; }
|
|
|
|
double olat, olon, az2;
|
|
|
|
geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 );
|
|
|
|
|
|
|
|
lat = olat;
|
|
|
|
lon = olon;
|
|
|
|
}
|
|
|
|
|
|
|
|
// presets
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", lon );
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", lat );
|
|
|
|
|
|
|
|
// other code depends on the actual values being set ...
|
|
|
|
fgSetDouble("/position/longitude-deg", lon );
|
|
|
|
fgSetDouble("/position/latitude-deg", lat );
|
|
|
|
fgSetDouble("/orientation/heading-deg",
|
|
|
|
fgGetDouble("/sim/presets/heading-deg") );
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Position for " << id << ":" << freq << " is ("
|
|
|
|
<< lon << ", "<< lat << ")" );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
|
|
|
|
<< id << ":" << freq );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set current_options lon/lat given an airport id and heading (degrees)
|
|
|
|
static bool fgSetPosFromFix( const string& id ) {
|
|
|
|
FGFix fix;
|
|
|
|
|
|
|
|
// set initial position from runway and heading
|
|
|
|
if ( current_fixlist->query( id.c_str(), &fix ) ) {
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
|
|
|
|
<< id );
|
|
|
|
|
|
|
|
double lon = fix.get_lon();
|
|
|
|
double lat = fix.get_lat();
|
|
|
|
|
|
|
|
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
|
|
|
|
{
|
|
|
|
double odist = fgGetDouble("/sim/presets/offset-distance")
|
|
|
|
* SG_NM_TO_METER;
|
|
|
|
double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth"))
|
|
|
|
+ 180.0;
|
|
|
|
while ( oaz >= 360.0 ) { oaz -= 360.0; }
|
|
|
|
double olat, olon, az2;
|
|
|
|
geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 );
|
|
|
|
|
|
|
|
lat = olat;
|
|
|
|
lon = olon;
|
|
|
|
}
|
|
|
|
|
|
|
|
// presets
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", lon );
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", lat );
|
|
|
|
|
|
|
|
// other code depends on the actual values being set ...
|
|
|
|
fgSetDouble("/position/longitude-deg", lon );
|
|
|
|
fgSetDouble("/position/latitude-deg", lat );
|
|
|
|
fgSetDouble("/orientation/heading-deg",
|
|
|
|
fgGetDouble("/sim/presets/heading-deg") );
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
|
|
|
"Position for " << id << " is ("
|
|
|
|
<< lon << ", "<< lat << ")" );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
|
|
|
|
<< id );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-16 21:34:51 +00:00
|
|
|
// Set the initial position based on presets (or defaults)
|
|
|
|
bool fgInitPosition() {
|
2002-11-17 04:04:21 +00:00
|
|
|
bool set_pos = false;
|
|
|
|
|
|
|
|
// If glideslope is specified, then calculate offset-distance or
|
|
|
|
// altitude relative to glide slope if either of those was not
|
|
|
|
// specified.
|
2002-11-16 21:34:51 +00:00
|
|
|
fgSetDistOrAltFromGlideSlope();
|
|
|
|
|
|
|
|
// If we have an explicit, in-range lon/lat, don't change it, just use it.
|
|
|
|
// If not, check for an airport-id and use that.
|
|
|
|
// If not, default to the middle of the KSFO field.
|
|
|
|
// The default values for lon/lat are deliberately out of range
|
|
|
|
// so that the airport-id can take effect; valid lon/lat will
|
|
|
|
// override airport-id, however.
|
|
|
|
double lon_deg = fgGetDouble("/sim/presets/longitude-deg");
|
|
|
|
double lat_deg = fgGetDouble("/sim/presets/latitude-deg");
|
|
|
|
if ( lon_deg >= -180.0 && lon_deg <= 180.0
|
|
|
|
&& lat_deg >= -90.0 && lat_deg <= 90.0 )
|
|
|
|
{
|
2002-11-17 04:04:21 +00:00
|
|
|
set_pos = true;
|
|
|
|
}
|
2002-11-16 21:34:51 +00:00
|
|
|
|
2002-11-17 04:04:21 +00:00
|
|
|
string apt = fgGetString("/sim/presets/airport-id");
|
|
|
|
string rwy_no = fgGetString("/sim/presets/runway");
|
|
|
|
double hdg = fgGetDouble("/sim/presets/heading-deg");
|
2003-01-05 00:10:36 +00:00
|
|
|
string vor = fgGetString("/sim/presets/vor-id");
|
|
|
|
double vor_freq = fgGetDouble("/sim/presets/vor-freq");
|
|
|
|
string ndb = fgGetString("/sim/presets/ndb-id");
|
|
|
|
double ndb_freq = fgGetDouble("/sim/presets/ndb-freq");
|
|
|
|
string fix = fgGetString("/sim/presets/fix");
|
2002-11-17 04:04:21 +00:00
|
|
|
if ( !set_pos && !apt.empty() && !rwy_no.empty() ) {
|
|
|
|
// An airport + runway is requested
|
|
|
|
if ( fgSetPosFromAirportIDandRwy( apt, rwy_no ) ) {
|
2003-01-05 00:10:36 +00:00
|
|
|
// set position (a little off the heading for single
|
2002-11-16 21:34:51 +00:00
|
|
|
// runway airports)
|
|
|
|
fgSetTowerPosFromAirportID( apt, hdg );
|
2002-11-17 04:04:21 +00:00
|
|
|
|
|
|
|
set_pos = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !set_pos && !apt.empty() ) {
|
2003-01-05 00:10:36 +00:00
|
|
|
// An airport is requested (find runway closest to hdg)
|
2002-11-17 04:04:21 +00:00
|
|
|
if ( fgSetPosFromAirportIDandHdg( apt, hdg ) ) {
|
2003-01-05 00:10:36 +00:00
|
|
|
// set position (a little off the heading for single
|
2002-11-17 04:04:21 +00:00
|
|
|
// runway airports)
|
|
|
|
fgSetTowerPosFromAirportID( apt, hdg );
|
|
|
|
|
|
|
|
set_pos = true;
|
2002-11-16 21:34:51 +00:00
|
|
|
}
|
|
|
|
}
|
2003-01-05 00:10:36 +00:00
|
|
|
if ( !set_pos && !vor.empty() ) {
|
|
|
|
// a VOR is requested
|
|
|
|
if ( fgSetPosFromNAV( vor, vor_freq ) ) {
|
|
|
|
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
|
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
} else {
|
|
|
|
fgSetBool("/sim/presets/onground", true);
|
|
|
|
}
|
|
|
|
set_pos = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !set_pos && !ndb.empty() ) {
|
|
|
|
// an NDB is requested
|
|
|
|
if ( fgSetPosFromNAV( ndb, ndb_freq ) ) {
|
|
|
|
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
|
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
} else {
|
|
|
|
fgSetBool("/sim/presets/onground", true);
|
|
|
|
}
|
|
|
|
set_pos = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !set_pos && !fix.empty() ) {
|
|
|
|
// a Fix is requested
|
|
|
|
if ( fgSetPosFromFix( fix ) ) {
|
|
|
|
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
|
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
} else {
|
|
|
|
fgSetBool("/sim/presets/onground", true);
|
|
|
|
}
|
|
|
|
set_pos = true;
|
|
|
|
}
|
|
|
|
}
|
2002-11-16 21:34:51 +00:00
|
|
|
|
2002-11-17 04:04:21 +00:00
|
|
|
if ( !set_pos ) {
|
|
|
|
// No lon/lat specified, no airport specified, default to
|
|
|
|
// middle of KSFO field.
|
|
|
|
fgSetDouble("/sim/presets/longitude-deg", -122.374843);
|
|
|
|
fgSetDouble("/sim/presets/latitude-deg", 37.619002);
|
|
|
|
}
|
|
|
|
|
2002-11-16 21:34:51 +00:00
|
|
|
fgSetDouble( "/position/longitude-deg",
|
|
|
|
fgGetDouble("/sim/presets/longitude-deg") );
|
|
|
|
fgSetDouble( "/position/latitude-deg",
|
|
|
|
fgGetDouble("/sim/presets/latitude-deg") );
|
|
|
|
fgSetDouble( "/orientation/heading-deg",
|
|
|
|
fgGetDouble("/sim/presets/heading-deg") );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-25 15:11:10 +00:00
|
|
|
// General house keeping initializations
|
2002-11-16 21:34:51 +00:00
|
|
|
bool fgInitGeneral() {
|
1998-08-27 17:01:55 +00:00
|
|
|
string root;
|
1999-11-19 02:10:24 +00:00
|
|
|
|
|
|
|
#if defined(FX) && defined(XMESA)
|
1999-03-11 23:09:26 +00:00
|
|
|
char *mesa_win_state;
|
1999-11-19 02:10:24 +00:00
|
|
|
#endif
|
1998-04-25 15:11:10 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "General Initialization" );
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "======= ==============" );
|
1998-04-25 20:24:00 +00:00
|
|
|
|
2001-01-13 22:06:39 +00:00
|
|
|
root = globals->get_fg_root();
|
1998-09-08 21:40:08 +00:00
|
|
|
if ( ! root.length() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
// No root path set? Then bail ...
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"Cannot continue without a path to the base package "
|
|
|
|
<< "being defined." );
|
|
|
|
exit(-1);
|
1998-04-25 15:11:10 +00:00
|
|
|
}
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "FG_ROOT = " << '"' << root << '"' << endl );
|
1998-04-25 15:11:10 +00:00
|
|
|
|
1999-03-11 23:09:26 +00:00
|
|
|
#if defined(FX) && defined(XMESA)
|
|
|
|
// initialize full screen flag
|
2002-01-06 16:51:31 +00:00
|
|
|
globals->set_fullscreen(false);
|
1999-03-11 23:09:26 +00:00
|
|
|
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
// Test for the MESA_GLX_FX env variable
|
|
|
|
if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
|
|
|
|
// test if we are fullscreen mesa/glide
|
|
|
|
if ( (mesa_win_state[0] == 'f') ||
|
|
|
|
(mesa_win_state[0] == 'F') ) {
|
|
|
|
globals->set_fullscreen(true);
|
|
|
|
}
|
|
|
|
}
|
1999-03-11 23:09:26 +00:00
|
|
|
}
|
|
|
|
#endif
|
1998-05-07 23:14:14 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
return true;
|
1998-04-25 15:11:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-02-05 20:54:08 +00:00
|
|
|
// Initialize the flight model subsystem. This just creates the
|
|
|
|
// object. The actual fdm initialization is delayed until we get a
|
|
|
|
// proper scenery elevation hit. This is checked for in main.cxx
|
|
|
|
|
|
|
|
void fgInitFDM() {
|
|
|
|
|
|
|
|
if ( cur_fdm_state ) {
|
|
|
|
delete cur_fdm_state;
|
|
|
|
cur_fdm_state = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
double dt = 1.0 / fgGetInt("/sim/model-hz");
|
|
|
|
aircraft_dir = fgGetString("/sim/aircraft-dir");
|
|
|
|
const string &model = fgGetString("/sim/flight-model");
|
|
|
|
|
|
|
|
try {
|
2002-10-04 13:20:53 +00:00
|
|
|
if ( model == "larcsim" ) {
|
|
|
|
cur_fdm_state = new FGLaRCsim( dt );
|
|
|
|
} else if ( model == "jsb" ) {
|
|
|
|
cur_fdm_state = new FGJSBsim( dt );
|
|
|
|
} else if ( model == "ada" ) {
|
|
|
|
cur_fdm_state = new FGADA( dt );
|
|
|
|
} else if ( model == "balloon" ) {
|
|
|
|
cur_fdm_state = new FGBalloonSim( dt );
|
|
|
|
} else if ( model == "magic" ) {
|
|
|
|
cur_fdm_state = new FGMagicCarpet( dt );
|
|
|
|
} else if ( model == "ufo" ) {
|
|
|
|
cur_fdm_state = new FGUFO( dt );
|
|
|
|
} else if ( model == "external" ) {
|
2002-09-28 21:42:03 +00:00
|
|
|
// external is a synonym for "--fdm=null" and is
|
|
|
|
// maintained here for backwards compatibility
|
2002-10-04 13:20:53 +00:00
|
|
|
cur_fdm_state = new FGNullFDM( dt );
|
|
|
|
} else if ( model.find("network") == 0 ) {
|
2002-04-11 05:40:34 +00:00
|
|
|
string host = "localhost";
|
|
|
|
int port1 = 5501;
|
|
|
|
int port2 = 5502;
|
|
|
|
int port3 = 5503;
|
|
|
|
string net_options = model.substr(8);
|
|
|
|
string::size_type begin, end;
|
|
|
|
begin = 0;
|
|
|
|
// host
|
|
|
|
end = net_options.find( ",", begin );
|
|
|
|
if ( end != string::npos ) {
|
|
|
|
host = net_options.substr(begin, end - begin);
|
|
|
|
begin = end + 1;
|
|
|
|
}
|
|
|
|
// port1
|
|
|
|
end = net_options.find( ",", begin );
|
|
|
|
if ( end != string::npos ) {
|
|
|
|
port1 = atoi( net_options.substr(begin, end - begin).c_str() );
|
|
|
|
begin = end + 1;
|
|
|
|
}
|
|
|
|
// port2
|
|
|
|
end = net_options.find( ",", begin );
|
|
|
|
if ( end != string::npos ) {
|
|
|
|
port2 = atoi( net_options.substr(begin, end - begin).c_str() );
|
|
|
|
begin = end + 1;
|
|
|
|
}
|
|
|
|
// port3
|
|
|
|
end = net_options.find( ",", begin );
|
|
|
|
if ( end != string::npos ) {
|
|
|
|
port3 = atoi( net_options.substr(begin, end - begin).c_str() );
|
|
|
|
begin = end + 1;
|
|
|
|
}
|
2002-10-04 13:20:53 +00:00
|
|
|
cur_fdm_state = new FGExternalNet( dt, host, port1, port2, port3 );
|
|
|
|
} else if ( model == "null" ) {
|
|
|
|
cur_fdm_state = new FGNullFDM( dt );
|
|
|
|
} else if ( model == "yasim" ) {
|
|
|
|
cur_fdm_state = new YASim( dt );
|
|
|
|
} else {
|
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT,
|
|
|
|
"Unrecognized flight model '" << model
|
|
|
|
<< "', cannot init flight dynamics model.");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2002-02-05 20:54:08 +00:00
|
|
|
} catch ( ... ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n");
|
|
|
|
exit(-1);
|
2002-02-05 20:54:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-18 14:57:20 +00:00
|
|
|
static void printMat(const sgVec4 *mat, char *name="")
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
cout << name << endl;
|
|
|
|
for(i=0; i<4; i++) {
|
|
|
|
cout <<" "<<mat[i][0]<<" "<<mat[i][1]<<" "<<mat[i][2]<<" "<<mat[i][3]<<endl;
|
|
|
|
}
|
|
|
|
cout << endl;
|
|
|
|
}
|
2002-02-05 20:54:08 +00:00
|
|
|
|
|
|
|
// Initialize view parameters
|
|
|
|
void fgInitView() {
|
2002-04-13 13:11:34 +00:00
|
|
|
// force update of model so that viewer can get some data...
|
|
|
|
globals->get_aircraft_model()->update(0);
|
2002-04-21 03:27:34 +00:00
|
|
|
// run update for current view so that data is current...
|
2002-03-14 00:29:20 +00:00
|
|
|
globals->get_viewmgr()->update(0);
|
2002-09-18 14:57:20 +00:00
|
|
|
|
|
|
|
printMat(globals->get_current_view()->get_VIEW(),"VIEW");
|
|
|
|
printMat(globals->get_current_view()->get_UP(),"UP");
|
|
|
|
// printMat(globals->get_current_view()->get_LOCAL(),"LOCAL");
|
|
|
|
|
2002-02-05 20:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-02-06 23:31:33 +00:00
|
|
|
SGTime *fgInitTime() {
|
|
|
|
// Initialize time
|
|
|
|
static const SGPropertyNode *longitude
|
2002-10-04 13:20:53 +00:00
|
|
|
= fgGetNode("/position/longitude-deg");
|
2002-02-06 23:31:33 +00:00
|
|
|
static const SGPropertyNode *latitude
|
2002-10-04 13:20:53 +00:00
|
|
|
= fgGetNode("/position/latitude-deg");
|
2002-02-11 23:33:20 +00:00
|
|
|
static const SGPropertyNode *cur_time_override
|
2002-10-04 13:20:53 +00:00
|
|
|
= fgGetNode("/sim/time/cur-time-override", true);
|
2002-02-11 23:33:20 +00:00
|
|
|
|
2002-02-06 23:31:33 +00:00
|
|
|
SGPath zone( globals->get_fg_root() );
|
|
|
|
zone.append( "Timezone" );
|
|
|
|
SGTime *t = new SGTime( longitude->getDoubleValue()
|
|
|
|
* SGD_DEGREES_TO_RADIANS,
|
|
|
|
latitude->getDoubleValue()
|
|
|
|
* SGD_DEGREES_TO_RADIANS,
|
2002-02-11 23:33:20 +00:00
|
|
|
zone.str(),
|
|
|
|
cur_time_override->getLongValue() );
|
2002-02-06 23:31:33 +00:00
|
|
|
|
|
|
|
// Handle potential user specified time offsets
|
|
|
|
time_t cur_time = t->get_cur_time();
|
|
|
|
time_t currGMT = sgTimeGetGMT( gmtime(&cur_time) );
|
|
|
|
time_t systemLocalTime = sgTimeGetGMT( localtime(&cur_time) );
|
|
|
|
time_t aircraftLocalTime =
|
|
|
|
sgTimeGetGMT( fgLocaltime(&cur_time, t->get_zonename() ) );
|
|
|
|
|
|
|
|
// Okay, we now have six possible scenarios
|
|
|
|
int offset = fgGetInt("/sim/startup/time-offset");
|
|
|
|
const string &offset_type = fgGetString("/sim/startup/time-offset-type");
|
|
|
|
if (offset_type == "system-offset") {
|
|
|
|
globals->set_warp( offset );
|
|
|
|
} else if (offset_type == "gmt-offset") {
|
|
|
|
globals->set_warp( offset - (currGMT - systemLocalTime) );
|
|
|
|
} else if (offset_type == "latitude-offset") {
|
|
|
|
globals->set_warp( offset - (aircraftLocalTime - systemLocalTime) );
|
|
|
|
} else if (offset_type == "system") {
|
|
|
|
globals->set_warp( offset - cur_time );
|
|
|
|
} else if (offset_type == "gmt") {
|
|
|
|
globals->set_warp( offset - currGMT );
|
|
|
|
} else if (offset_type == "latitude") {
|
|
|
|
globals->set_warp( offset - (aircraftLocalTime - systemLocalTime) -
|
|
|
|
cur_time );
|
|
|
|
} else {
|
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
|
|
"FG_TIME::Unsupported offset type " << offset_type );
|
|
|
|
exit( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "After time init, warp = "
|
|
|
|
<< globals->get_warp() );
|
|
|
|
|
|
|
|
globals->set_warp_delta( 0 );
|
|
|
|
|
2002-02-11 23:33:20 +00:00
|
|
|
t->update( 0.0, 0.0,
|
|
|
|
cur_time_override->getLongValue(),
|
|
|
|
globals->get_warp() );
|
2002-02-06 23:31:33 +00:00
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-25 15:11:10 +00:00
|
|
|
// This is the top level init routine which calls all the other
|
|
|
|
// initialization routines. If you are adding a subsystem to flight
|
|
|
|
// gear, its initialization call should located in this routine.
|
|
|
|
// Returns non-zero if a problem encountered.
|
2002-11-18 21:31:33 +00:00
|
|
|
bool fgInitSubsystems() {
|
2001-11-07 04:55:57 +00:00
|
|
|
static const SGPropertyNode *longitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/longitude-deg");
|
2001-11-07 04:55:57 +00:00
|
|
|
static const SGPropertyNode *latitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/latitude-deg");
|
2001-11-07 04:55:57 +00:00
|
|
|
static const SGPropertyNode *altitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/altitude-ft");
|
2001-11-07 04:55:57 +00:00
|
|
|
|
1998-12-09 18:50:12 +00:00
|
|
|
fgLIGHT *l = &cur_light_params;
|
1998-04-25 15:11:10 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "Initialize Subsystems");
|
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, "========== ==========");
|
1998-04-25 15:11:10 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the material property subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-03-25 14:20:12 +00:00
|
|
|
SGPath mpath( globals->get_fg_root() );
|
2001-12-28 23:33:32 +00:00
|
|
|
mpath.append( "materials.xml" );
|
2002-02-05 20:54:08 +00:00
|
|
|
if ( ! material_lib.load( mpath.str() ) ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" );
|
|
|
|
exit(-1);
|
2000-06-23 00:30:04 +00:00
|
|
|
}
|
|
|
|
|
From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the event manager subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
global_events.init();
|
|
|
|
|
|
|
|
// Output event stats every 60 seconds
|
|
|
|
global_events.Register( "FGEventMgr::print_stats()",
|
2002-10-04 13:20:53 +00:00
|
|
|
&global_events, &FGEventMgr::print_stats,
|
|
|
|
60000 );
|
From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the scenery management subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-12-06 22:29:46 +00:00
|
|
|
if ( globals->get_tile_mgr()->init() ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
// Load the local scenery data
|
|
|
|
double visibility_meters = fgGetDouble("/environment/visibility-m");
|
|
|
|
|
2002-12-06 22:29:46 +00:00
|
|
|
globals->get_tile_mgr()->update( visibility_meters );
|
1998-08-22 14:49:55 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" );
|
|
|
|
exit(-1);
|
1998-08-22 14:49:55 +00:00
|
|
|
}
|
|
|
|
|
From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
|
|
|
// cause refresh of viewer scenery timestamps every 15 seconds...
|
|
|
|
global_events.Register( "FGTileMgr::refresh_view_timestamps()",
|
2002-12-06 22:29:46 +00:00
|
|
|
globals->get_tile_mgr(),
|
|
|
|
&FGTileMgr::refresh_view_timestamps,
|
2002-10-04 13:20:53 +00:00
|
|
|
15000 );
|
From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_DEBUG,
|
2002-10-04 13:20:53 +00:00
|
|
|
"Current terrain elevation after tile mgr init " <<
|
|
|
|
globals->get_scenery()->get_cur_elev() );
|
1999-01-27 04:49:17 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the flight model subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-02-05 20:54:08 +00:00
|
|
|
fgInitFDM();
|
2002-10-04 13:20:53 +00:00
|
|
|
|
2000-07-23 21:32:59 +00:00
|
|
|
// allocates structures so must happen before any of the flight
|
|
|
|
// model or control parameters are set
|
|
|
|
fgAircraftInit(); // In the future this might not be the case.
|
|
|
|
|
1998-08-22 14:49:55 +00:00
|
|
|
|
2002-04-13 13:11:34 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the view manager subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
fgInitView();
|
|
|
|
|
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
|
|
|
// Initialize the lighting subsystem.
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
1998-04-25 20:24:00 +00:00
|
|
|
// fgUpdateSunPos() needs a few position and view parameters set
|
|
|
|
// so it can calculate local relative sun angle and a few other
|
|
|
|
// things for correctly orienting the sky.
|
|
|
|
fgUpdateSunPos();
|
1999-03-22 02:08:05 +00:00
|
|
|
fgUpdateMoonPos();
|
2002-04-05 20:03:49 +00:00
|
|
|
global_events.Register( "fgUpdateSunPos()", &fgUpdateSunPos,
|
2002-10-04 13:20:53 +00:00
|
|
|
60000);
|
2002-04-05 20:03:49 +00:00
|
|
|
global_events.Register( "fgUpdateMoonPos()", &fgUpdateMoonPos,
|
2002-10-04 13:20:53 +00:00
|
|
|
60000);
|
1998-04-25 20:24:00 +00:00
|
|
|
|
1998-04-22 13:25:39 +00:00
|
|
|
// Initialize Lighting interpolation tables
|
1998-05-20 20:51:33 +00:00
|
|
|
l->Init();
|
1998-04-22 13:25:39 +00:00
|
|
|
|
2002-04-13 13:11:34 +00:00
|
|
|
// force one lighting update to make it right to start with...
|
|
|
|
l->Update();
|
1998-04-22 13:25:39 +00:00
|
|
|
// update the lighting parameters (based on sun angle)
|
1998-08-29 13:09:25 +00:00
|
|
|
global_events.Register( "fgLight::Update()",
|
2002-10-04 13:20:53 +00:00
|
|
|
&cur_light_params, &fgLIGHT::Update,
|
|
|
|
30000 );
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
|
2002-03-12 16:29:00 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
2002-11-07 16:27:47 +00:00
|
|
|
// Create and register the logger.
|
2002-03-12 16:29:00 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("logger", new FGLogger);
|
2002-03-12 16:29:00 +00:00
|
|
|
|
2002-04-09 18:58:24 +00:00
|
|
|
|
2003-01-11 16:30:32 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Create and register the script manager.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("scripting", new FGScriptMgr);
|
2003-01-11 16:30:32 +00:00
|
|
|
|
|
|
|
|
2002-11-07 16:27:47 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Create and register the XML GUI.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("gui", new NewGUI, FGSubsystemMgr::INIT);
|
2002-11-07 16:27:47 +00:00
|
|
|
|
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the local time subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
1999-10-22 00:27:49 +00:00
|
|
|
// update the current timezone each 30 minutes
|
2002-04-05 20:03:49 +00:00
|
|
|
global_events.Register( "fgUpdateLocalTime()", &fgUpdateLocalTime,
|
2002-10-04 13:20:53 +00:00
|
|
|
30*60*1000 );
|
1998-04-22 13:25:39 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the weather subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
1998-04-22 13:25:39 +00:00
|
|
|
// Initialize the weather modeling subsystem
|
2002-05-12 00:12:19 +00:00
|
|
|
#ifdef FG_WEATHERCM
|
1999-08-10 03:44:47 +00:00
|
|
|
// Initialize the WeatherDatabase
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Creating LocalWeatherDatabase");
|
1999-10-21 22:53:12 +00:00
|
|
|
sgVec3 position;
|
|
|
|
sgSetVec3( position, current_aircraft.fdm_state->get_Latitude(),
|
2002-10-04 13:20:53 +00:00
|
|
|
current_aircraft.fdm_state->get_Longitude(),
|
|
|
|
current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER );
|
2001-07-19 22:10:14 +00:00
|
|
|
double init_vis = fgGetDouble("/environment/visibility-m");
|
|
|
|
|
|
|
|
FGLocalWeatherDatabase::DatabaseWorkingType working_type;
|
|
|
|
|
2002-03-26 02:38:11 +00:00
|
|
|
if (!strcmp(fgGetString("/environment/weather/working-type"), "internet"))
|
2001-07-19 22:10:14 +00:00
|
|
|
{
|
|
|
|
working_type = FGLocalWeatherDatabase::use_internet;
|
|
|
|
} else {
|
|
|
|
working_type = FGLocalWeatherDatabase::default_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( init_vis > 0 ) {
|
|
|
|
FGLocalWeatherDatabase::theFGLocalWeatherDatabase =
|
2002-10-04 13:20:53 +00:00
|
|
|
new FGLocalWeatherDatabase( position,
|
|
|
|
globals->get_fg_root(),
|
2001-07-19 22:10:14 +00:00
|
|
|
working_type,
|
|
|
|
init_vis );
|
|
|
|
} else {
|
|
|
|
FGLocalWeatherDatabase::theFGLocalWeatherDatabase =
|
2002-10-04 13:20:53 +00:00
|
|
|
new FGLocalWeatherDatabase( position,
|
|
|
|
globals->get_fg_root(),
|
2001-07-19 22:10:14 +00:00
|
|
|
working_type );
|
|
|
|
}
|
|
|
|
|
1999-10-21 22:53:12 +00:00
|
|
|
// cout << theFGLocalWeatherDatabase << endl;
|
|
|
|
// cout << "visibility = "
|
|
|
|
// << theFGLocalWeatherDatabase->getWeatherVisibility() << endl;
|
1999-08-10 03:44:47 +00:00
|
|
|
|
|
|
|
WeatherDatabase = FGLocalWeatherDatabase::theFGLocalWeatherDatabase;
|
2000-12-06 04:13:16 +00:00
|
|
|
|
1999-08-10 03:44:47 +00:00
|
|
|
// register the periodic update of the weather
|
2002-04-05 20:03:49 +00:00
|
|
|
global_events.Register( "weather update", &fgUpdateWeatherDatabase,
|
|
|
|
30000);
|
1999-08-12 17:13:44 +00:00
|
|
|
#else
|
2002-02-22 22:51:34 +00:00
|
|
|
globals->get_environment_mgr()->init();
|
|
|
|
globals->get_environment_mgr()->bind();
|
1999-08-12 17:13:44 +00:00
|
|
|
#endif
|
1997-08-23 01:46:20 +00:00
|
|
|
|
2002-12-10 19:25:12 +00:00
|
|
|
#ifdef FG_USE_CLOUDS_3D
|
2002-09-13 20:38:15 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the 3D cloud subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
if ( fgGetBool("/sim/rendering/clouds3d") ) {
|
|
|
|
SGPath cloud_path(globals->get_fg_root());
|
|
|
|
cloud_path.append("large.sky");
|
2002-09-18 14:57:20 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Loading CLOUDS3d from: " << cloud_path.c_str());
|
2002-10-03 03:19:35 +00:00
|
|
|
if ( !sgCloud3d->Load( cloud_path.str(),
|
|
|
|
latitude->getDoubleValue(),
|
|
|
|
longitude->getDoubleValue()) )
|
|
|
|
{
|
2002-09-13 20:38:15 +00:00
|
|
|
fgSetBool("/sim/rendering/clouds3d", false);
|
2002-09-18 14:57:20 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "CLOUDS3d FAILED: ");
|
2002-09-13 20:38:15 +00:00
|
|
|
}
|
2002-09-18 14:57:20 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "CLOUDS3d Loaded: ");
|
2002-09-13 20:38:15 +00:00
|
|
|
}
|
2002-12-10 19:25:12 +00:00
|
|
|
#endif
|
2002-09-13 20:38:15 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
2000-04-24 23:51:26 +00:00
|
|
|
// Initialize vor/ndb/ils/fix list management and query systems
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Loading Navaids");
|
2000-04-25 17:33:13 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB");
|
2000-04-24 23:51:26 +00:00
|
|
|
current_navlist = new FGNavList;
|
2001-03-25 14:20:12 +00:00
|
|
|
SGPath p_nav( globals->get_fg_root() );
|
2000-04-24 23:51:26 +00:00
|
|
|
p_nav.append( "Navaids/default.nav" );
|
|
|
|
current_navlist->init( p_nav );
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " ILS and Marker Beacons");
|
2001-03-16 23:59:02 +00:00
|
|
|
current_beacons = new FGMarkerBeacons;
|
|
|
|
current_beacons->init();
|
2000-04-24 23:51:26 +00:00
|
|
|
current_ilslist = new FGILSList;
|
2001-03-25 14:20:12 +00:00
|
|
|
SGPath p_ils( globals->get_fg_root() );
|
2000-04-24 23:51:26 +00:00
|
|
|
p_ils.append( "Navaids/default.ils" );
|
|
|
|
current_ilslist->init( p_ils );
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " Fixes");
|
2000-04-24 23:51:26 +00:00
|
|
|
current_fixlist = new FGFixList;
|
2001-03-25 14:20:12 +00:00
|
|
|
SGPath p_fix( globals->get_fg_root() );
|
2000-04-24 23:51:26 +00:00
|
|
|
p_fix.append( "Navaids/default.fix" );
|
|
|
|
current_fixlist->init( p_fix );
|
|
|
|
|
2001-11-07 17:55:28 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize ATC list management and query systems
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " ATIS");
|
|
|
|
current_atislist = new FGATISList;
|
|
|
|
SGPath p_atis( globals->get_fg_root() );
|
|
|
|
p_atis.append( "ATC/default.atis" );
|
|
|
|
current_atislist->init( p_atis );
|
|
|
|
|
2002-04-03 23:54:44 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " Tower");
|
|
|
|
current_towerlist = new FGTowerList;
|
|
|
|
SGPath p_tower( globals->get_fg_root() );
|
|
|
|
p_tower.append( "ATC/default.tower" );
|
|
|
|
current_towerlist->init( p_tower );
|
|
|
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " Approach");
|
|
|
|
current_approachlist = new FGApproachList;
|
|
|
|
SGPath p_approach( globals->get_fg_root() );
|
|
|
|
p_approach.append( "ATC/default.approach" );
|
|
|
|
current_approachlist->init( p_approach );
|
|
|
|
|
2001-11-07 17:55:28 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialise ATC display system
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " ATC Display");
|
2002-03-01 17:39:52 +00:00
|
|
|
globals->set_ATC_display(new FGATCDisplay);
|
|
|
|
globals->get_ATC_display()->init();
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialise the ATC Manager
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " ATC Manager");
|
|
|
|
globals->set_ATC_mgr(new FGATCMgr);
|
2002-04-03 23:54:44 +00:00
|
|
|
globals->get_ATC_mgr()->init();
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialise the AI Manager
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-10-02 15:25:58 +00:00
|
|
|
if (fgGetBool("/sim/ai-traffic/enabled")) {
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, " AI Manager");
|
|
|
|
globals->set_AI_mgr(new FGAIMgr);
|
|
|
|
globals->get_AI_mgr()->init();
|
|
|
|
}
|
2001-04-05 20:20:44 +00:00
|
|
|
|
2002-02-05 20:54:08 +00:00
|
|
|
#ifdef ENABLE_AUDIO_SUPPORT
|
2001-10-29 04:39:05 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the sound subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
globals->set_soundmgr(new FGSoundMgr);
|
|
|
|
globals->get_soundmgr()->init();
|
|
|
|
globals->get_soundmgr()->bind();
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the sound-effects subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("fx", new FGFX);
|
2002-10-03 21:20:56 +00:00
|
|
|
|
|
|
|
#endif
|
2002-09-23 19:55:10 +00:00
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("instrumentation", new FGInstrumentMgr);
|
|
|
|
globals->add_subsystem("systems", new FGSystemMgr);
|
2002-09-24 14:51:37 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the radio stack subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2000-04-25 03:09:26 +00:00
|
|
|
current_radiostack = new FGRadioStack;
|
2001-01-11 22:44:18 +00:00
|
|
|
current_radiostack->init();
|
|
|
|
current_radiostack->bind();
|
2000-05-04 01:18:45 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the cockpit subsystem
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
1998-02-12 21:58:27 +00:00
|
|
|
if( fgCockpitInit( ¤t_aircraft )) {
|
2002-10-04 13:20:53 +00:00
|
|
|
// Cockpit initialized ok.
|
1998-02-12 21:58:27 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_ALERT, "Error in Cockpit initialization!" );
|
|
|
|
exit(-1);
|
1997-09-04 02:17:18 +00:00
|
|
|
}
|
1997-08-25 20:27:21 +00:00
|
|
|
|
1998-02-12 21:58:27 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the autopilot subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-03-13 16:31:21 +00:00
|
|
|
globals->set_autopilot(new FGAutopilot);
|
|
|
|
globals->get_autopilot()->init();
|
|
|
|
globals->get_autopilot()->bind();
|
2000-04-30 06:51:49 +00:00
|
|
|
|
2002-10-04 13:20:53 +00:00
|
|
|
// FIXME: these should go in the
|
|
|
|
// GUI initialization code, not here.
|
2002-02-05 20:54:08 +00:00
|
|
|
fgAPAdjustInit();
|
2000-04-30 06:51:49 +00:00
|
|
|
NewTgtAirportInit();
|
|
|
|
NewHeadingInit();
|
|
|
|
NewAltitudeInit();
|
1998-11-16 13:59:58 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize I/O subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-08-25 20:56:16 +00:00
|
|
|
globals->get_io()->init();
|
|
|
|
globals->get_io()->bind();
|
1998-11-16 13:59:58 +00:00
|
|
|
|
User-visible
- knobs now continue to rotate when you hold down the mouse
- the middle mouse button makes knobs rotate much faster
- there are NAV1, NAV2, and ADF radios that can be tuned using the mouse
- there are standby frequencies for NAV1 and NAV2, and buttons to swap
- there is a crude, rather silly-looking DME, hard-wired to NAV1
- there is a crude, rather silly-looking autopilot that can lock
the heading (to the bug on the gyro), can lock to NAV1, and can lock
the current altitude
- the knobs for changing the radials on NAV1 and NAV2 look much better
and are in the right place
- tuning into an ILS frequency doesn't change the displayed radial for
NAV1
Code
- I've created a new module, sp_panel.[ch]xx, that constructs the
default single-prop panel; this works entirely outside of FGPanel,
so it is possible to construct similar modules for other sorts of
panels; all code specific to the default panel has been removed from
panel.cxx
- current_panel is now a pointer
- radiostack.[ch]xx keeps track both of the actual radial and of the
selected radial (they will differ with ILS); the NAV gauges should
not spin around automatically to show the actual radial (we need to
do something similar with the autopilot)
- the panel is initialized fairly early
- make sure that standby frequencies also get initialized
- I've started combining and clipping small textures to save texture
memory; there's a lot more to do, but at least I've made a start
2000-05-02 18:26:00 +00:00
|
|
|
// Initialize the 2D panel.
|
2001-01-13 22:06:39 +00:00
|
|
|
string panel_path = fgGetString("/sim/panel/path",
|
2002-10-04 13:20:53 +00:00
|
|
|
"Panels/Default/default.xml");
|
2000-09-22 17:20:56 +00:00
|
|
|
current_panel = fgReadPanel(panel_path);
|
|
|
|
if (current_panel == 0) {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_INPUT, SG_ALERT,
|
|
|
|
"Error reading new panel from " << panel_path );
|
2000-10-25 19:27:13 +00:00
|
|
|
} else {
|
2002-10-04 13:20:53 +00:00
|
|
|
SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
|
|
|
|
current_panel->init();
|
|
|
|
current_panel->bind();
|
2000-09-22 17:20:56 +00:00
|
|
|
}
|
User-visible
- knobs now continue to rotate when you hold down the mouse
- the middle mouse button makes knobs rotate much faster
- there are NAV1, NAV2, and ADF radios that can be tuned using the mouse
- there are standby frequencies for NAV1 and NAV2, and buttons to swap
- there is a crude, rather silly-looking DME, hard-wired to NAV1
- there is a crude, rather silly-looking autopilot that can lock
the heading (to the bug on the gyro), can lock to NAV1, and can lock
the current altitude
- the knobs for changing the radials on NAV1 and NAV2 look much better
and are in the right place
- tuning into an ILS frequency doesn't change the displayed radial for
NAV1
Code
- I've created a new module, sp_panel.[ch]xx, that constructs the
default single-prop panel; this works entirely outside of FGPanel,
so it is possible to construct similar modules for other sorts of
panels; all code specific to the default panel has been removed from
panel.cxx
- current_panel is now a pointer
- radiostack.[ch]xx keeps track both of the actual radial and of the
selected radial (they will differ with ILS); the NAV gauges should
not spin around automatically to show the actual radial (we need to
do something similar with the autopilot)
- the panel is initialized fairly early
- make sure that standby frequencies also get initialized
- I've started combining and clipping small textures to save texture
memory; there's a lot more to do, but at least I've made a start
2000-05-02 18:26:00 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
2001-06-05 22:12:08 +00:00
|
|
|
// Initialize the default (kludged) properties.
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-07-02 22:27:24 +00:00
|
|
|
fgInitProps();
|
2000-07-03 20:09:56 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the controls subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-07-22 19:51:16 +00:00
|
|
|
globals->get_controls()->init();
|
|
|
|
globals->get_controls()->bind();
|
2001-01-05 17:38:58 +00:00
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
|
2002-07-07 15:45:56 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the steam subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
globals->get_steam()->init();
|
|
|
|
globals->get_steam()->bind();
|
|
|
|
|
|
|
|
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize the input subsystem.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-01-16 16:01:26 +00:00
|
|
|
globals->add_subsystem("input", new FGInput);
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
|
|
|
|
2002-10-03 21:20:56 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// Bind and initialize subsystems.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
globals->get_subsystem_mgr()->bind();
|
|
|
|
globals->get_subsystem_mgr()->init();
|
|
|
|
|
|
|
|
|
2001-04-05 20:20:44 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// End of subsystem initialization.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO, endl);
|
1998-04-24 00:49:17 +00:00
|
|
|
|
2002-10-04 13:20:53 +00:00
|
|
|
// Save the initial state for future
|
|
|
|
// reference.
|
2001-01-19 22:57:24 +00:00
|
|
|
globals->saveInitialState();
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
return true;
|
1997-08-23 01:46:20 +00:00
|
|
|
}
|
1999-04-27 15:52:32 +00:00
|
|
|
|
|
|
|
|
2002-11-18 21:31:33 +00:00
|
|
|
void fgReInitSubsystems()
|
1999-04-27 15:52:32 +00:00
|
|
|
{
|
2001-10-28 16:16:30 +00:00
|
|
|
static const SGPropertyNode *longitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/longitude-deg");
|
2001-10-28 16:16:30 +00:00
|
|
|
static const SGPropertyNode *latitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/latitude-deg");
|
2001-10-28 16:16:30 +00:00
|
|
|
static const SGPropertyNode *altitude
|
2002-11-15 21:13:29 +00:00
|
|
|
= fgGetNode("/sim/presets/altitude-ft");
|
2002-01-20 03:52:36 +00:00
|
|
|
static const SGPropertyNode *master_freeze
|
2002-10-04 13:20:53 +00:00
|
|
|
= fgGetNode("/sim/freeze/master");
|
2001-10-28 16:16:30 +00:00
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_INFO,
|
2002-10-04 13:20:53 +00:00
|
|
|
"fgReInitSubsystems(): /position/altitude = "
|
2002-07-02 20:45:02 +00:00
|
|
|
<< altitude->getDoubleValue() );
|
2001-01-17 23:30:35 +00:00
|
|
|
|
2002-01-20 03:52:36 +00:00
|
|
|
bool freeze = master_freeze->getBoolValue();
|
|
|
|
if ( !freeze ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
fgSetBool("/sim/freeze/master", true);
|
2001-10-28 16:16:30 +00:00
|
|
|
}
|
2000-07-23 21:32:59 +00:00
|
|
|
|
2002-11-18 21:31:33 +00:00
|
|
|
// Initialize the FDM
|
2002-02-05 20:54:08 +00:00
|
|
|
fgInitFDM();
|
2002-02-17 21:05:27 +00:00
|
|
|
|
|
|
|
// allocates structures so must happen before any of the flight
|
|
|
|
// model or control parameters are set
|
|
|
|
fgAircraftInit(); // In the future this might not be the case.
|
2000-10-27 22:00:43 +00:00
|
|
|
|
2002-04-21 03:27:34 +00:00
|
|
|
// copy viewer settings into current-view path
|
|
|
|
globals->get_viewmgr()->copyToCurrent();
|
|
|
|
|
2002-02-05 20:54:08 +00:00
|
|
|
fgInitView();
|
1999-04-27 15:52:32 +00:00
|
|
|
|
2001-07-22 19:51:16 +00:00
|
|
|
globals->get_controls()->reset_all();
|
2002-03-13 16:31:21 +00:00
|
|
|
globals->get_autopilot()->reset();
|
1999-05-12 02:07:21 +00:00
|
|
|
|
2001-04-05 21:14:37 +00:00
|
|
|
fgUpdateSunPos();
|
|
|
|
fgUpdateMoonPos();
|
|
|
|
cur_light_params.Update();
|
|
|
|
fgUpdateLocalTime();
|
|
|
|
|
2002-01-20 03:52:36 +00:00
|
|
|
if ( !freeze ) {
|
2002-10-04 13:20:53 +00:00
|
|
|
fgSetBool("/sim/freeze/master", false);
|
2002-01-20 03:52:36 +00:00
|
|
|
}
|
1999-04-27 15:52:32 +00:00
|
|
|
}
|
2002-04-13 13:11:34 +00:00
|
|
|
|