28ee2efbf9
GUI improvements contributed by Norman Vine. 3dfx.sh wrapper script now sets voodoo2 variables as well. Start of support for user defined texture scale. Start of support for precalculated texture coordinates.
520 lines
16 KiB
C++
520 lines
16 KiB
C++
//
|
|
// fg_init.cxx -- Flight Gear top level initialization routines
|
|
//
|
|
// 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$
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
// For BC 5.01 this must be included before OpenGL includes.
|
|
#ifdef FG_MATH_EXCEPTION_CLASH
|
|
# include <math.h>
|
|
#endif
|
|
|
|
#include <GL/glut.h>
|
|
#include <XGL/xgl.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
// 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
|
|
|
|
#include <Include/compiler.h>
|
|
|
|
#include STL_STRING
|
|
|
|
#include <Debug/logstream.hxx>
|
|
#include <Aircraft/aircraft.hxx>
|
|
#include <Airports/simple.hxx>
|
|
#include <Astro/sky.hxx>
|
|
#include <Astro/stars.hxx>
|
|
#include <Astro/solarsystem.hxx>
|
|
#include <Autopilot/autopilot.hxx>
|
|
#include <Cockpit/cockpit.hxx>
|
|
#include <Include/fg_constants.h>
|
|
#include <Include/general.hxx>
|
|
#include <Joystick/joystick.hxx>
|
|
#include <Math/fg_geodesy.hxx>
|
|
#include <Math/point3d.hxx>
|
|
#include <Math/polar3d.hxx>
|
|
#include <Scenery/scenery.hxx>
|
|
#include <Scenery/tilemgr.hxx>
|
|
#include <Time/event.hxx>
|
|
#include <Time/fg_time.hxx>
|
|
#include <Time/light.hxx>
|
|
#include <Time/sunpos.hxx>
|
|
#include <Time/moonpos.hxx>
|
|
#include <Weather/weather.hxx>
|
|
|
|
#include "fg_init.hxx"
|
|
#include "options.hxx"
|
|
#include "views.hxx"
|
|
#include "fg_serial.hxx"
|
|
|
|
#if defined(FX) && defined(XMESA)
|
|
#include <GL/xmesa.h>
|
|
#endif
|
|
|
|
FG_USING_STD(string);
|
|
|
|
extern const char *default_root;
|
|
|
|
|
|
// Set initial position and orientation
|
|
int fgInitPosition( void ) {
|
|
string id;
|
|
FGInterface *f;
|
|
|
|
f = current_aircraft.fdm_state;
|
|
|
|
id = current_options.get_airport_id();
|
|
if ( id.length() ) {
|
|
// set initial position from airport id
|
|
|
|
fgAIRPORTS airports;
|
|
fgAIRPORT a;
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
"Attempting to set starting position from airport code "
|
|
<< id );
|
|
|
|
airports.load("apt_simple");
|
|
if ( ! airports.search( id, &a ) ) {
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
"Failed to find " << id << " in database." );
|
|
exit(-1);
|
|
} else {
|
|
f->set_Longitude( a.longitude * DEG_TO_RAD );
|
|
f->set_Latitude( a.latitude * DEG_TO_RAD );
|
|
}
|
|
} else {
|
|
// set initial position from default or command line coordinates
|
|
|
|
f->set_Longitude( current_options.get_lon() * DEG_TO_RAD );
|
|
f->set_Latitude( current_options.get_lat() * DEG_TO_RAD );
|
|
}
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
"starting altitude is = " << current_options.get_altitude() );
|
|
|
|
f->set_Altitude( current_options.get_altitude() * METER_TO_FEET );
|
|
fgFDMSetGroundElevation( current_options.get_flight_model(),
|
|
(f->get_Altitude() - 3.758099) * FEET_TO_METER );
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
"Initial position is: ("
|
|
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
// General house keeping initializations
|
|
int fgInitGeneral( void ) {
|
|
string root;
|
|
char *mesa_win_state;
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
|
|
FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
|
|
|
|
root = current_options.get_fg_root();
|
|
if ( ! root.length() ) {
|
|
// No root path set? Then bail ...
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
"Cannot continue without environment variable FG_ROOT"
|
|
<< "being defined." );
|
|
exit(-1);
|
|
}
|
|
FG_LOG( FG_GENERAL, FG_INFO, "FG_ROOT = " << root << endl );
|
|
|
|
#if defined(FX) && defined(XMESA)
|
|
// initialize full screen flag
|
|
global_fullscreen = false;
|
|
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
|
|
// 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') ) {
|
|
global_fullscreen = true;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
// 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.
|
|
int fgInitSubsystems( void )
|
|
{
|
|
FGTime::cur_time_params = new FGTime();
|
|
|
|
FGInterface *f; // assigned later
|
|
fgLIGHT *l = &cur_light_params;
|
|
FGTime *t = FGTime::cur_time_params;
|
|
FGView *v = ¤t_view;
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
|
|
FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
|
|
|
|
// 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.
|
|
f = current_aircraft.fdm_state;
|
|
|
|
// set the initial position
|
|
fgInitPosition();
|
|
|
|
// Initialize the Scenery Management subsystem
|
|
if ( fgSceneryInit() ) {
|
|
// Scenery initialized ok.
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
|
|
exit(-1);
|
|
}
|
|
|
|
if( fgTileMgrInit() ) {
|
|
// Load the local scenery data
|
|
fgTileMgrUpdate();
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
|
|
exit(-1);
|
|
}
|
|
|
|
FG_LOG( FG_GENERAL, FG_DEBUG,
|
|
"Current terrain elevation after tile mgr init " <<
|
|
scenery.cur_elev );
|
|
|
|
// Calculate ground elevation at starting point (we didn't have
|
|
// tmp_abs_view_pos calculated when fgTileMgrUpdate() was called above
|
|
//
|
|
// calculalate a cartesian point somewhere along the line between
|
|
// the center of the earth and our view position. Doesn't have to
|
|
// be the exact elevation (this is good because we don't know it
|
|
// yet :-)
|
|
|
|
// now handled inside of the fgTileMgrUpdate()
|
|
|
|
/*
|
|
geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
|
|
tmp_abs_view_pos = fgGeodToCart(geod_pos);
|
|
|
|
FG_LOG( FG_GENERAL, FG_DEBUG,
|
|
"Initial abs_view_pos = " << tmp_abs_view_pos );
|
|
scenery.cur_elev =
|
|
fgTileMgrCurElev( f->get_Longitude(), f->get_Latitude(),
|
|
tmp_abs_view_pos );
|
|
FG_LOG( FG_GENERAL, FG_DEBUG,
|
|
"Altitude after update " << scenery.cur_elev );
|
|
*/
|
|
|
|
fgFDMSetGroundElevation( current_options.get_flight_model(),
|
|
scenery.cur_elev );
|
|
|
|
// Reset our altitude if we are below ground
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << f->get_Altitude() );
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
|
|
f->get_Runway_altitude() );
|
|
|
|
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
|
|
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
|
|
}
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
"Updated position (after elevation adj): ("
|
|
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
|
|
|
|
// We need to calculate a few more values here that would normally
|
|
// be calculated by the FDM so that the v->UpdateViewMath()
|
|
// routine doesn't get hosed.
|
|
|
|
double sea_level_radius_meters;
|
|
double lat_geoc;
|
|
// Set the FG variables first
|
|
fgGeodToGeoc( f->get_Latitude(), f->get_Altitude(),
|
|
&sea_level_radius_meters, &lat_geoc);
|
|
f->set_Geocentric_Position( lat_geoc, f->get_Longitude(),
|
|
f->get_Altitude() +
|
|
(sea_level_radius_meters * METER_TO_FEET) );
|
|
f->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
|
|
|
|
f->set_sin_cos_longitude(f->get_Longitude());
|
|
f->set_sin_cos_latitude(f->get_Latitude());
|
|
|
|
f->set_sin_lat_geocentric(sin(lat_geoc));
|
|
f->set_cos_lat_geocentric(cos(lat_geoc));
|
|
|
|
// The following section sets up the flight model EOM parameters
|
|
// and should really be read in from one or more files.
|
|
|
|
// Initial Velocity
|
|
f->set_Velocities_Local( 0.0, 0.0, 0.0 );
|
|
|
|
// Initial Orientation
|
|
f->set_Euler_Angles( current_options.get_roll() * DEG_TO_RAD,
|
|
current_options.get_pitch() * DEG_TO_RAD,
|
|
current_options.get_heading() * DEG_TO_RAD );
|
|
|
|
// Initial Angular Body rates
|
|
f->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
|
|
|
|
f->set_Earth_position_angle( 0.0 );
|
|
|
|
// Mass properties and geometry values
|
|
f->set_Inertias( 8.547270E+01,
|
|
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
|
|
|
|
// CG position w.r.t. ref. point
|
|
f->set_CG_Position( 0.0, 0.0, 0.0 );
|
|
|
|
// Initialize the event manager
|
|
global_events.Init();
|
|
|
|
// Output event stats every 60 seconds
|
|
global_events.Register( "fgEVENT_MGR::PrintStats()",
|
|
fgMethodCallback<fgEVENT_MGR>( &global_events,
|
|
&fgEVENT_MGR::PrintStats),
|
|
fgEVENT::FG_EVENT_READY, 60000 );
|
|
|
|
// Initialize the time dependent variables
|
|
t->init();
|
|
t->update(f);
|
|
|
|
// Initialize view parameters
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Before v->init()");
|
|
v->Init();
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
|
|
v->UpdateViewMath(f);
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->get_abs_view_pos());
|
|
v->UpdateWorldToEye(f);
|
|
|
|
// Build the solar system
|
|
//fgSolarSystemInit(*t);
|
|
FG_LOG(FG_GENERAL, FG_INFO, "Building SolarSystem");
|
|
SolarSystem::theSolarSystem = new SolarSystem(t);
|
|
|
|
// Initialize the Stars subsystem
|
|
if( fgStarsInit() ) {
|
|
// Stars initialized ok.
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Stars initialization!" );
|
|
exit(-1);
|
|
}
|
|
|
|
// Initialize the planetary subsystem
|
|
// global_events.Register( "fgPlanetsInit()", fgPlanetsInit,
|
|
// fgEVENT::FG_EVENT_READY, 600000);
|
|
|
|
// Initialize the sun's position
|
|
// global_events.Register( "fgSunInit()", fgSunInit,
|
|
// fgEVENT::FG_EVENT_READY, 30000 );
|
|
|
|
// Intialize the moon's position
|
|
// global_events.Register( "fgMoonInit()", fgMoonInit,
|
|
// fgEVENT::FG_EVENT_READY, 600000 );
|
|
|
|
// register the periodic update of Sun, moon, and planets
|
|
global_events.Register( "ssolsysUpdate", solarSystemRebuild,
|
|
fgEVENT::FG_EVENT_READY, 600000);
|
|
|
|
// 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();
|
|
fgUpdateMoonPos();
|
|
global_events.Register( "fgUpdateSunPos()", fgUpdateSunPos,
|
|
fgEVENT::FG_EVENT_READY, 60000);
|
|
global_events.Register( "fgUpdateMoonPos()", fgUpdateMoonPos,
|
|
fgEVENT::FG_EVENT_READY, 60000);
|
|
|
|
// Initialize Lighting interpolation tables
|
|
l->Init();
|
|
|
|
// update the lighting parameters (based on sun angle)
|
|
global_events.Register( "fgLight::Update()",
|
|
fgMethodCallback<fgLIGHT>( &cur_light_params,
|
|
&fgLIGHT::Update),
|
|
fgEVENT::FG_EVENT_READY, 30000 );
|
|
|
|
// Initialize the weather modeling subsystem
|
|
current_weather.Init();
|
|
|
|
// Initialize the Cockpit subsystem
|
|
if( fgCockpitInit( ¤t_aircraft )) {
|
|
// Cockpit initialized ok.
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Cockpit initialization!" );
|
|
exit(-1);
|
|
}
|
|
|
|
// Initialize the "sky"
|
|
fgSkyInit();
|
|
|
|
// Initialize the flight model subsystem data structures base on
|
|
// above values
|
|
|
|
fgFDMInit( current_options.get_flight_model(), cur_fdm_state,
|
|
1.0 / DEFAULT_MODEL_HZ );
|
|
|
|
// I'm just sticking this here for now, it should probably move
|
|
// eventually
|
|
scenery.cur_elev = f->get_Runway_altitude() * FEET_TO_METER;
|
|
|
|
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
|
|
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
|
|
}
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
"Updated position (after elevation adj): ("
|
|
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
|
|
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
|
|
// end of thing that I just stuck in that I should probably move
|
|
|
|
// Joystick support
|
|
if ( fgJoystickInit() ) {
|
|
// Joystick initialized ok.
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" );
|
|
}
|
|
|
|
// Autopilot init added here, by Jeff Goeke-Smith
|
|
fgAPInit(¤t_aircraft);
|
|
|
|
// Initialize serial ports
|
|
#if ! defined( MACOS )
|
|
fgSerialInit();
|
|
#endif
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, endl);
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
void fgReInitSubsystems( void )
|
|
{
|
|
FGInterface *f = current_aircraft.fdm_state;
|
|
FGView *v = ¤t_view;
|
|
FGTime *t = FGTime::cur_time_params;
|
|
|
|
int toggle_pause = t->getPause();
|
|
|
|
if( !toggle_pause )
|
|
t->togglePauseMode();
|
|
|
|
fgInitPosition();
|
|
if( fgTileMgrInit() ) {
|
|
// Load the local scenery data
|
|
fgTileMgrUpdate();
|
|
} else {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
|
|
exit(-1);
|
|
}
|
|
fgFDMSetGroundElevation( current_options.get_flight_model(),
|
|
scenery.cur_elev );
|
|
|
|
// Reset our altitude if we are below ground
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << f->get_Altitude() );
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
|
|
f->get_Runway_altitude() );
|
|
|
|
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
|
|
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
|
|
}
|
|
double sea_level_radius_meters;
|
|
double lat_geoc;
|
|
// Set the FG variables first
|
|
fgGeodToGeoc( f->get_Latitude(), f->get_Altitude(),
|
|
&sea_level_radius_meters, &lat_geoc);
|
|
f->set_Geocentric_Position( lat_geoc, f->get_Longitude(),
|
|
f->get_Altitude() +
|
|
(sea_level_radius_meters * METER_TO_FEET) );
|
|
f->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
|
|
|
|
f->set_sin_cos_longitude(f->get_Longitude());
|
|
f->set_sin_cos_latitude(f->get_Latitude());
|
|
|
|
f->set_sin_lat_geocentric(sin(lat_geoc));
|
|
f->set_cos_lat_geocentric(cos(lat_geoc));
|
|
|
|
// The following section sets up the flight model EOM parameters
|
|
// and should really be read in from one or more files.
|
|
|
|
// Initial Velocity
|
|
f->set_Velocities_Local( 0.0, 0.0, 0.0 );
|
|
|
|
// Initial Orientation
|
|
f->set_Euler_Angles( current_options.get_roll() * DEG_TO_RAD,
|
|
current_options.get_pitch() * DEG_TO_RAD,
|
|
current_options.get_heading() * DEG_TO_RAD );
|
|
|
|
// Initial Angular Body rates
|
|
f->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
|
|
|
|
f->set_Earth_position_angle( 0.0 );
|
|
|
|
// Mass properties and geometry values
|
|
f->set_Inertias( 8.547270E+01,
|
|
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
|
|
|
|
// CG position w.r.t. ref. point
|
|
f->set_CG_Position( 0.0, 0.0, 0.0 );
|
|
|
|
// Initialize view parameters
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "Before v->init()");
|
|
v->Init();
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
|
|
v->UpdateViewMath(f);
|
|
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->get_abs_view_pos());
|
|
v->UpdateWorldToEye(f);
|
|
|
|
fgFDMInit( current_options.get_flight_model(), cur_fdm_state,
|
|
1.0 / DEFAULT_MODEL_HZ );
|
|
|
|
scenery.cur_elev = f->get_Runway_altitude() * FEET_TO_METER;
|
|
|
|
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
|
|
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
|
|
}
|
|
|
|
controls.reset_all();
|
|
fgAPReset();
|
|
|
|
if( !toggle_pause )
|
|
t->togglePauseMode();
|
|
}
|