1999-06-18 03:42:54 +00:00
|
|
|
// main.cxx -- top level sim routines
|
1998-04-21 17:02:27 +00:00
|
|
|
//
|
|
|
|
// Written by Curtis Olson for OpenGL, started May 1997.
|
|
|
|
//
|
1999-06-18 03:42:54 +00:00
|
|
|
// Copyright (C) 1997 - 1999 Curtis L. Olson - curt@flightgear.org
|
1998-04-21 17:02:27 +00:00
|
|
|
//
|
|
|
|
// 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$
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1998-11-11 00:24:00 +00:00
|
|
|
#define MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-05-08 02:33:13 +00:00
|
|
|
#ifdef FG_MATH_EXCEPTION_CLASH
|
|
|
|
# include <math.h>
|
|
|
|
#endif
|
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
|
|
# include <windows.h>
|
1998-05-07 23:14:14 +00:00
|
|
|
# include <float.h>
|
1998-04-21 17:02:27 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <GL/glut.h>
|
2000-02-16 23:01:03 +00:00
|
|
|
#include <simgear/xgl/xgl.h>
|
2000-02-15 03:30:01 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
#include <stdio.h>
|
1998-05-20 20:51:33 +00:00
|
|
|
#include <string.h>
|
1998-08-27 17:01:55 +00:00
|
|
|
#include <string>
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_STDLIB_H
|
|
|
|
# include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
1999-01-19 20:57:00 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
# include <sys/stat.h> /* for stat() */
|
|
|
|
#endif
|
1998-07-06 02:42:02 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-07-22 21:40:43 +00:00
|
|
|
# include <unistd.h> /* for stat() */
|
1998-07-06 02:42:02 +00:00
|
|
|
#endif
|
|
|
|
|
2000-02-04 22:50:04 +00:00
|
|
|
#include <plib/pu.h> // plib include
|
|
|
|
#include <plib/ssg.h> // plib include
|
1999-06-18 03:42:54 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_AUDIO_SUPPORT
|
2000-02-04 22:50:04 +00:00
|
|
|
# include <plib/sl.h> // plib include
|
|
|
|
# include <plib/sm.h> // plib include
|
1999-06-18 03:42:54 +00:00
|
|
|
#endif
|
|
|
|
|
2000-02-15 03:30:01 +00:00
|
|
|
#include <simgear/constants.h> // for VERSION
|
2000-02-16 23:01:03 +00:00
|
|
|
#include <simgear/debug/logstream.hxx>
|
|
|
|
#include <simgear/math/fg_geodesy.hxx>
|
|
|
|
#include <simgear/math/polar3d.hxx>
|
|
|
|
#include <simgear/math/fg_random.h>
|
|
|
|
#include <simgear/misc/fgpath.hxx>
|
2000-02-15 03:30:01 +00:00
|
|
|
|
1999-01-07 20:24:43 +00:00
|
|
|
#include <Include/general.hxx>
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-10-17 01:33:52 +00:00
|
|
|
#include <Aircraft/aircraft.hxx>
|
2000-03-16 23:19:39 +00:00
|
|
|
#include <Ephemeris/ephemeris.hxx>
|
1998-06-03 00:47:11 +00:00
|
|
|
|
2000-04-30 06:51:49 +00:00
|
|
|
#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>
|
2000-03-21 20:51:03 +00:00
|
|
|
#include <Cockpit/steam.hxx>
|
2000-05-16 18:21:08 +00:00
|
|
|
|
|
|
|
// bfi.hxx has to be included before uiuc_aircraft.h because of nasty
|
|
|
|
// #defines in uiuc_aircraft.h
|
|
|
|
#include "bfi.hxx"
|
|
|
|
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
q#include <FDM/UIUCModel/uiuc_aircraft.h>
|
2000-03-22 22:01:33 +00:00
|
|
|
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
|
1998-06-12 14:27:25 +00:00
|
|
|
#include <GUI/gui.h>
|
1998-10-27 02:14:21 +00:00
|
|
|
#include <Joystick/joystick.hxx>
|
1999-06-30 20:21:04 +00:00
|
|
|
#ifdef FG_NETWORK_OLK
|
2000-01-12 18:09:35 +00:00
|
|
|
#include <NetworkOLK/network.h>
|
1999-06-30 20:21:04 +00:00
|
|
|
#endif
|
1999-06-30 19:16:53 +00:00
|
|
|
#include <Objects/materialmgr.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>
|
2000-03-16 04:15:22 +00:00
|
|
|
#include <Sky/sky.hxx>
|
1998-04-24 00:49:17 +00:00
|
|
|
#include <Time/event.hxx>
|
|
|
|
#include <Time/fg_time.hxx>
|
|
|
|
#include <Time/fg_timer.hxx>
|
1998-04-22 13:25:39 +00:00
|
|
|
#include <Time/sunpos.hxx>
|
1999-08-12 17:13:44 +00:00
|
|
|
|
1999-10-22 00:27:49 +00:00
|
|
|
#ifndef FG_OLD_WEATHER
|
|
|
|
# include <WeatherCM/FGLocalWeatherDatabase.h>
|
|
|
|
#else
|
1999-08-12 17:13:44 +00:00
|
|
|
# include <Weather/weather.hxx>
|
|
|
|
#endif
|
1998-04-21 17:02:27 +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"
|
1999-06-18 03:42:54 +00:00
|
|
|
#include "keyboard.hxx"
|
1998-04-24 00:49:17 +00:00
|
|
|
#include "options.hxx"
|
1998-07-06 02:42:02 +00:00
|
|
|
#include "splash.hxx"
|
1998-04-22 13:25:39 +00:00
|
|
|
#include "views.hxx"
|
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-04-27 19:27:45 +00:00
|
|
|
// -dw- use custom sioux settings so I can see output window
|
|
|
|
#ifdef MACOS
|
|
|
|
# ifndef FG_NDEBUG
|
|
|
|
# include <sioux.h> // settings for output window
|
|
|
|
# endif
|
1999-06-02 22:22:47 +00:00
|
|
|
# include <console.h>
|
1999-04-27 19:27:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
1999-01-07 20:24:43 +00:00
|
|
|
// This is a record containing a bit of global housekeeping information
|
|
|
|
FGGeneral general;
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// Specify our current idle function state. This is used to run all
|
|
|
|
// our initializations out of the glutIdleLoop() so that we can get a
|
|
|
|
// splash screen up and running right away.
|
1998-09-15 02:09:24 +00:00
|
|
|
static int idle_state = 0;
|
1999-10-23 00:09:26 +00:00
|
|
|
static int global_multi_loop;
|
1998-07-06 02:42:02 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// Another hack
|
|
|
|
int use_signals = 0;
|
|
|
|
|
1998-06-01 17:54:40 +00:00
|
|
|
// Global structures for the Audio library
|
1998-07-16 17:33:34 +00:00
|
|
|
#ifdef ENABLE_AUDIO_SUPPORT
|
1998-09-25 16:02:07 +00:00
|
|
|
slEnvelope pitch_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
|
|
|
|
slEnvelope volume_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
|
1998-07-08 14:45:07 +00:00
|
|
|
slScheduler *audio_sched;
|
|
|
|
smMixer *audio_mixer;
|
1998-06-05 18:18:40 +00:00
|
|
|
slSample *s1;
|
|
|
|
slSample *s2;
|
1998-06-03 00:47:11 +00:00
|
|
|
#endif
|
1998-06-01 17:54:40 +00:00
|
|
|
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
// ssg variables
|
|
|
|
ssgRoot *scene = NULL;
|
1999-06-28 00:02:52 +00:00
|
|
|
ssgBranch *terrain = NULL;
|
1999-06-30 19:16:53 +00:00
|
|
|
ssgSelector *penguin_sel = NULL;
|
|
|
|
ssgTransform *penguin_pos = NULL;
|
1999-06-18 03:42:54 +00:00
|
|
|
|
2000-01-12 18:09:35 +00:00
|
|
|
#ifdef FG_NETWORK_OLK
|
|
|
|
ssgSelector *fgd_sel = NULL;
|
|
|
|
ssgTransform *fgd_pos = NULL;
|
|
|
|
//sgMat4 sgTUX;
|
|
|
|
#endif
|
|
|
|
|
1999-10-14 17:32:34 +00:00
|
|
|
// current fdm/position used for view
|
|
|
|
FGInterface cur_view_fdm;
|
|
|
|
|
2000-03-02 13:51:31 +00:00
|
|
|
// Sky structures
|
2000-03-16 04:15:22 +00:00
|
|
|
FGEphemeris *ephem;
|
|
|
|
SGSky *thesky;
|
2000-03-02 13:51:31 +00:00
|
|
|
|
1999-08-08 01:31:30 +00:00
|
|
|
// hack
|
|
|
|
sgMat4 copy_of_ssgOpenGLAxisSwapMatrix =
|
|
|
|
{
|
|
|
|
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
|
|
|
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
|
|
|
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
|
|
|
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
|
|
|
} ;
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// The following defines flight gear options. Because glutlib will also
|
|
|
|
// want to parse its own options, those options must not be included here
|
|
|
|
// or they will get parsed by the main program option parser. Hence case
|
|
|
|
// is significant for any option added that might be in conflict with
|
|
|
|
// glutlib's parser.
|
|
|
|
//
|
|
|
|
// glutlib parses for:
|
|
|
|
// -display
|
|
|
|
// -direct (invalid in Win32)
|
|
|
|
// -geometry
|
|
|
|
// -gldebug
|
|
|
|
// -iconized
|
|
|
|
// -indirect (invalid in Win32)
|
|
|
|
// -synce
|
|
|
|
//
|
|
|
|
// Note that glutlib depends upon strings while this program's
|
|
|
|
// option parser wants only initial characters followed by numbers
|
|
|
|
// or pathnames.
|
|
|
|
//
|
|
|
|
|
|
|
|
|
2000-03-02 03:03:16 +00:00
|
|
|
ssgSimpleState *default_state;
|
|
|
|
ssgSimpleState *hud_and_panel;
|
|
|
|
ssgSimpleState *menus;
|
|
|
|
|
|
|
|
void fgBuildRenderStates( void ) {
|
|
|
|
default_state = new ssgSimpleState;
|
|
|
|
default_state->disable( GL_TEXTURE_2D );
|
|
|
|
default_state->enable( GL_CULL_FACE );
|
|
|
|
default_state->disable( GL_COLOR_MATERIAL );
|
|
|
|
default_state->disable( GL_BLEND );
|
|
|
|
default_state->disable( GL_ALPHA_TEST );
|
|
|
|
default_state->disable( GL_LIGHTING );
|
2000-03-02 19:20:54 +00:00
|
|
|
default_state->setMaterial( GL_AMBIENT_AND_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
|
2000-03-02 03:03:16 +00:00
|
|
|
|
|
|
|
hud_and_panel = new ssgSimpleState;
|
|
|
|
hud_and_panel->disable( GL_CULL_FACE );
|
|
|
|
hud_and_panel->disable( GL_TEXTURE_2D );
|
|
|
|
hud_and_panel->disable( GL_LIGHTING );
|
|
|
|
|
|
|
|
menus = new ssgSimpleState;
|
|
|
|
menus->disable( GL_CULL_FACE );
|
|
|
|
menus->disable( GL_TEXTURE_2D );
|
|
|
|
menus->enable( GL_BLEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// fgInitVisuals() -- Initialize various GL/view parameters
|
1999-10-14 23:46:28 +00:00
|
|
|
void fgInitVisuals( void ) {
|
1998-04-26 05:10:00 +00:00
|
|
|
fgLIGHT *l;
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
l = &cur_light_params;
|
|
|
|
|
1999-04-27 19:27:45 +00:00
|
|
|
#ifndef GLUT_WRONG_VERSION
|
1998-05-03 00:47:31 +00:00
|
|
|
// Go full screen if requested ...
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_fullscreen() ) {
|
1998-05-03 00:47:31 +00:00
|
|
|
glutFullScreen();
|
|
|
|
}
|
1999-04-27 19:27:45 +00:00
|
|
|
#endif
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// If enabled, normal vectors specified with glNormal are scaled
|
|
|
|
// to unit length after transformation. See glNormal.
|
2000-03-17 06:16:15 +00:00
|
|
|
// glEnable( GL_NORMALIZE );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
glEnable( GL_LIGHTING );
|
|
|
|
glEnable( GL_LIGHT0 );
|
|
|
|
glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
sgVec3 sunpos;
|
|
|
|
sgSetVec3( sunpos, l->sun_vec[0], l->sun_vec[1], l->sun_vec[2] );
|
|
|
|
ssgGetLight( 0 ) -> setPosition( sunpos );
|
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
// glFogi (GL_FOG_MODE, GL_LINEAR);
|
|
|
|
glFogi (GL_FOG_MODE, GL_EXP2);
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( (current_options.get_fog() == 1) ||
|
|
|
|
(current_options.get_shading() == 0) ) {
|
1998-06-13 00:40:32 +00:00
|
|
|
// if fastest fog requested, or if flat shading force fastest
|
2000-03-17 06:16:15 +00:00
|
|
|
glHint ( GL_FOG_HINT, GL_FASTEST );
|
1998-07-13 21:00:09 +00:00
|
|
|
} else if ( current_options.get_fog() == 2 ) {
|
2000-03-17 06:16:15 +00:00
|
|
|
glHint ( GL_FOG_HINT, GL_NICEST );
|
1998-05-11 18:18:15 +00:00
|
|
|
}
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_wireframe() ) {
|
1998-04-30 12:34:17 +00:00
|
|
|
// draw wire frame
|
2000-03-17 06:16:15 +00:00
|
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
1998-04-30 12:34:17 +00:00
|
|
|
}
|
1998-05-20 20:51:33 +00:00
|
|
|
|
|
|
|
// This is the default anyways, but it can't hurt
|
2000-03-17 06:16:15 +00:00
|
|
|
glFrontFace ( GL_CCW );
|
1998-07-20 12:49:44 +00:00
|
|
|
|
|
|
|
// Just testing ...
|
2000-03-17 06:16:15 +00:00
|
|
|
// glEnable(GL_POINT_SMOOTH);
|
|
|
|
// glEnable(GL_LINE_SMOOTH);
|
|
|
|
// glEnable(GL_POLYGON_SMOOTH);
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update all Visuals (redraws anything graphics related)
|
1999-10-14 23:46:28 +00:00
|
|
|
void fgRenderFrame( void ) {
|
2000-05-16 18:21:08 +00:00
|
|
|
// Update the BFI.
|
|
|
|
FGBFI::update();
|
|
|
|
|
1998-12-09 18:50:12 +00:00
|
|
|
fgLIGHT *l = &cur_light_params;
|
1999-04-08 19:53:46 +00:00
|
|
|
FGTime *t = FGTime::cur_time_params;
|
1999-09-09 00:16:28 +00:00
|
|
|
// FGView *v = ¤t_view;
|
1999-10-22 00:27:49 +00:00
|
|
|
static double last_visibility = -9999;
|
1999-10-23 00:09:26 +00:00
|
|
|
static bool in_puff = false;
|
|
|
|
static double puff_length = 0;
|
|
|
|
static double puff_progression = 0;
|
|
|
|
const double ramp_up = 0.15;
|
|
|
|
const double ramp_down = 0.15;
|
1998-12-09 18:50:12 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
double angle;
|
1998-07-22 21:40:43 +00:00
|
|
|
// GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
|
1999-10-22 00:27:49 +00:00
|
|
|
// GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
|
|
|
|
// GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
|
1999-05-13 02:10:52 +00:00
|
|
|
// GLfloat mat_shininess[] = { 10.0 };
|
1998-07-13 15:32:37 +00:00
|
|
|
GLbitfield clear_mask;
|
1999-10-22 00:27:49 +00:00
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
if ( idle_state != 1000 ) {
|
|
|
|
// still initializing, draw the splash screen
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_splash_screen() == 1 ) {
|
1998-07-06 21:34:17 +00:00
|
|
|
fgSplashUpdate(0.0);
|
|
|
|
}
|
1998-04-30 12:34:17 +00:00
|
|
|
} else {
|
1998-07-06 02:42:02 +00:00
|
|
|
// idle_state is now 1000 meaning we've finished all our
|
|
|
|
// initializations and are running the main loop, so this will
|
|
|
|
// now work without seg faulting the system.
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-07-12 03:14:42 +00:00
|
|
|
// printf("Ground = %.2f Altitude = %.2f\n", scenery.cur_elev,
|
|
|
|
// FG_Altitude * FEET_TO_METER);
|
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// this is just a temporary hack, to make me understand Pui
|
1998-08-22 14:49:55 +00:00
|
|
|
// timerText -> setLabel (ctime (&t->cur_time));
|
1998-07-06 02:42:02 +00:00
|
|
|
// end of hack
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// update view volume parameters
|
1999-10-14 17:32:34 +00:00
|
|
|
// cout << "before pilot_view update" << endl;
|
|
|
|
pilot_view.UpdateViewParams(*cur_fdm_state);
|
|
|
|
// cout << "after pilot_view update" << endl;
|
|
|
|
current_view.UpdateViewParams(cur_view_fdm);
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-12-11 20:26:25 +00:00
|
|
|
// set the sun position
|
2000-03-17 06:16:15 +00:00
|
|
|
glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
|
1998-12-11 20:26:25 +00:00
|
|
|
|
1998-07-13 15:32:37 +00:00
|
|
|
clear_mask = GL_DEPTH_BUFFER_BIT;
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_wireframe() ) {
|
1998-07-13 15:32:37 +00:00
|
|
|
clear_mask |= GL_COLOR_BUFFER_BIT;
|
|
|
|
}
|
1998-08-28 18:14:39 +00:00
|
|
|
if ( current_options.get_panel_status() ) {
|
|
|
|
// we can't clear the screen when the panel is active
|
|
|
|
} else if ( current_options.get_skyblend() ) {
|
1998-07-20 12:49:44 +00:00
|
|
|
if ( current_options.get_textures() ) {
|
|
|
|
// glClearColor(black[0], black[1], black[2], black[3]);
|
1998-07-22 21:40:43 +00:00
|
|
|
glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
|
|
|
|
l->adj_fog_color[2], l->adj_fog_color[3]);
|
1999-05-12 01:11:17 +00:00
|
|
|
clear_mask |= GL_COLOR_BUFFER_BIT;
|
1998-07-20 12:49:44 +00:00
|
|
|
}
|
1998-07-06 02:42:02 +00:00
|
|
|
} else {
|
|
|
|
glClearColor(l->sky_color[0], l->sky_color[1],
|
|
|
|
l->sky_color[2], l->sky_color[3]);
|
1998-07-13 15:32:37 +00:00
|
|
|
clear_mask |= GL_COLOR_BUFFER_BIT;
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
2000-03-17 06:16:15 +00:00
|
|
|
glClear( clear_mask );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// Tell GL we are switching to model view parameters
|
1999-08-08 01:31:30 +00:00
|
|
|
|
|
|
|
// I really should create a derived ssg node or use a call
|
|
|
|
// back or something so that I can draw the sky within the
|
|
|
|
// ssgCullandDraw() function, but for now I just mimic what
|
|
|
|
// ssg does to set up the model view matrix
|
2000-03-17 06:16:15 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2000-03-02 03:03:16 +00:00
|
|
|
ssgSetCamera( current_view.VIEW );
|
2000-03-01 00:31:35 +00:00
|
|
|
|
|
|
|
/*
|
1999-08-08 01:31:30 +00:00
|
|
|
sgMat4 vm_tmp, view_mat;
|
1999-10-04 04:02:10 +00:00
|
|
|
sgTransposeNegateMat4 ( vm_tmp, current_view.VIEW ) ;
|
1999-08-08 01:31:30 +00:00
|
|
|
sgCopyMat4( view_mat, copy_of_ssgOpenGLAxisSwapMatrix ) ;
|
|
|
|
sgPreMultMat4( view_mat, vm_tmp ) ;
|
2000-03-17 06:16:15 +00:00
|
|
|
glLoadMatrixf( (float *)view_mat );
|
2000-03-01 00:31:35 +00:00
|
|
|
*/
|
1998-07-06 02:42:02 +00:00
|
|
|
|
2000-03-02 03:03:16 +00:00
|
|
|
// set the opengl state to known default values
|
|
|
|
default_state->force();
|
|
|
|
|
2000-03-02 13:51:31 +00:00
|
|
|
// draw sky dome
|
2000-03-02 03:03:16 +00:00
|
|
|
if ( current_options.get_skyblend() ) {
|
2000-03-16 04:15:22 +00:00
|
|
|
sgVec3 view_pos;
|
|
|
|
sgSetVec3( view_pos,
|
|
|
|
current_view.get_view_pos().x(),
|
|
|
|
current_view.get_view_pos().y(),
|
|
|
|
current_view.get_view_pos().z() );
|
|
|
|
|
2000-03-02 03:03:16 +00:00
|
|
|
sgVec3 zero_elev;
|
|
|
|
sgSetVec3( zero_elev,
|
|
|
|
current_view.get_cur_zero_elev().x(),
|
|
|
|
current_view.get_cur_zero_elev().y(),
|
|
|
|
current_view.get_cur_zero_elev().z() );
|
2000-03-01 00:31:35 +00:00
|
|
|
|
2000-03-16 04:15:22 +00:00
|
|
|
/* cout << "thesky->repaint() sky_color = "
|
|
|
|
<< cur_light_params.sky_color[0] << " "
|
|
|
|
<< cur_light_params.sky_color[1] << " "
|
|
|
|
<< cur_light_params.sky_color[2] << " "
|
|
|
|
<< cur_light_params.sky_color[3] << endl;
|
|
|
|
cout << " fog = "
|
|
|
|
<< cur_light_params.fog_color[0] << " "
|
|
|
|
<< cur_light_params.fog_color[1] << " "
|
|
|
|
<< cur_light_params.fog_color[2] << " "
|
|
|
|
<< cur_light_params.fog_color[3] << endl;
|
|
|
|
cout << " sun_angle = " << cur_light_params.sun_angle
|
|
|
|
<< " moon_angle = " << cur_light_params.moon_angle
|
|
|
|
<< endl; */
|
|
|
|
thesky->repaint( cur_light_params.sky_color,
|
2000-03-17 06:16:15 +00:00
|
|
|
cur_light_params.adj_fog_color,
|
2000-03-16 04:15:22 +00:00
|
|
|
cur_light_params.sun_angle,
|
|
|
|
cur_light_params.moon_angle,
|
2000-03-16 23:01:57 +00:00
|
|
|
ephem->getNumPlanets(), ephem->getPlanets(),
|
|
|
|
ephem->getNumStars(), ephem->getStars() );
|
|
|
|
|
2000-03-16 04:15:22 +00:00
|
|
|
/* cout << "thesky->reposition( view_pos = " << view_pos[0] << " "
|
|
|
|
<< view_pos[1] << " " << view_pos[2] << endl;
|
|
|
|
cout << " zero_elev = " << zero_elev[0] << " "
|
|
|
|
<< zero_elev[1] << " " << zero_elev[2]
|
|
|
|
<< " lon = " << cur_fdm_state->get_Longitude()
|
|
|
|
<< " lat = " << cur_fdm_state->get_Latitude() << endl;
|
|
|
|
cout << " sun_rot = " << cur_light_params.sun_rotation
|
|
|
|
<< " gst = " << FGTime::cur_time_params->getGst() << endl;
|
|
|
|
cout << " sun ra = " << ephem->getSunRightAscension()
|
|
|
|
<< " sun dec = " << ephem->getSunDeclination()
|
|
|
|
<< " moon ra = " << ephem->getMoonRightAscension()
|
|
|
|
<< " moon dec = " << ephem->getMoonDeclination() << endl; */
|
|
|
|
|
|
|
|
thesky->reposition( view_pos, zero_elev,
|
|
|
|
cur_fdm_state->get_Longitude(),
|
|
|
|
cur_fdm_state->get_Latitude(),
|
|
|
|
cur_light_params.sun_rotation,
|
|
|
|
FGTime::cur_time_params->getGst(),
|
|
|
|
ephem->getSunRightAscension(),
|
|
|
|
ephem->getSunDeclination(), 50000.0,
|
|
|
|
ephem->getMoonRightAscension(),
|
|
|
|
ephem->getMoonDeclination(), 50000.0 );
|
2000-03-02 03:03:16 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
glEnable( GL_DEPTH_TEST );
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_fog() > 0 ) {
|
2000-03-17 06:16:15 +00:00
|
|
|
glEnable( GL_FOG );
|
|
|
|
glFogi( GL_FOG_MODE, GL_EXP2 );
|
|
|
|
glFogfv( GL_FOG_COLOR, l->adj_fog_color );
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
1999-10-22 00:27:49 +00:00
|
|
|
|
|
|
|
// update fog params if visibility has changed
|
2000-01-12 18:09:35 +00:00
|
|
|
#ifndef FG_OLD_WEATHER
|
1999-10-22 00:27:49 +00:00
|
|
|
double cur_visibility = WeatherDatabase->getWeatherVisibility();
|
2000-01-12 18:09:35 +00:00
|
|
|
#else
|
|
|
|
double cur_visibility = current_weather.get_visibility();
|
|
|
|
#endif
|
1999-10-22 00:27:49 +00:00
|
|
|
double actual_visibility = cur_visibility;
|
|
|
|
|
|
|
|
if ( current_options.get_clouds() ) {
|
|
|
|
double diff = fabs( cur_fdm_state->get_Altitude() * FEET_TO_METER -
|
|
|
|
current_options.get_clouds_asl() );
|
1999-10-22 01:30:39 +00:00
|
|
|
// cout << "altitude diff = " << diff << endl;
|
1999-10-23 00:09:26 +00:00
|
|
|
if ( diff < 75 ) {
|
|
|
|
if ( ! in_puff ) {
|
|
|
|
// calc chance of entering cloud puff
|
|
|
|
double rnd = fg_random();
|
|
|
|
double chance = rnd * rnd * rnd;
|
|
|
|
if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) {
|
|
|
|
in_puff = true;
|
|
|
|
do {
|
|
|
|
puff_length = fg_random() * 2.0; // up to 2 seconds
|
|
|
|
} while ( puff_length <= 0.0 );
|
|
|
|
puff_progression = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
actual_visibility = cur_visibility * (diff - 25) / 50.0;
|
|
|
|
|
|
|
|
if ( in_puff ) {
|
|
|
|
// modify actual_visibility based on puff envelope
|
|
|
|
|
|
|
|
if ( puff_progression <= ramp_up ) {
|
|
|
|
double x = FG_PI_2 * puff_progression / ramp_up;
|
|
|
|
double factor = 1.0 - sin( x );
|
|
|
|
actual_visibility = actual_visibility * factor;
|
|
|
|
} else if ( puff_progression >= ramp_up + puff_length ) {
|
|
|
|
double x = FG_PI_2 *
|
|
|
|
(puff_progression - (ramp_up + puff_length)) /
|
|
|
|
ramp_down;
|
|
|
|
double factor = sin( x );
|
|
|
|
actual_visibility = actual_visibility * factor;
|
|
|
|
} else {
|
|
|
|
actual_visibility = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cout << "len = " << puff_length
|
|
|
|
<< " x = " << x
|
|
|
|
<< " factor = " << factor
|
|
|
|
<< " actual_visibility = " << actual_visibility
|
|
|
|
<< endl; */
|
|
|
|
|
|
|
|
puff_progression += ( global_multi_loop *
|
|
|
|
current_options.get_speed_up() ) /
|
|
|
|
(double)current_options.get_model_hz();
|
|
|
|
|
|
|
|
/* cout << "gml = " << global_multi_loop
|
|
|
|
<< " speed up = " << current_options.get_speed_up()
|
|
|
|
<< " hz = " << current_options.get_model_hz() << endl;
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( puff_progression > puff_length + ramp_up + ramp_down) {
|
|
|
|
in_puff = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// never let visibility drop below zero
|
1999-10-22 01:30:39 +00:00
|
|
|
if ( actual_visibility < 0 ) {
|
|
|
|
actual_visibility = 0;
|
|
|
|
}
|
1999-10-22 00:27:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-22 01:30:39 +00:00
|
|
|
// cout << "actual visibility = " << actual_visibility << endl;
|
1999-10-22 00:27:49 +00:00
|
|
|
|
|
|
|
if ( actual_visibility != last_visibility ) {
|
|
|
|
last_visibility = actual_visibility;
|
|
|
|
|
1999-10-22 01:30:39 +00:00
|
|
|
// cout << "----> updating fog params" << endl;
|
1999-10-22 00:27:49 +00:00
|
|
|
|
|
|
|
GLfloat fog_exp_density;
|
|
|
|
GLfloat fog_exp2_density;
|
|
|
|
|
|
|
|
// for GL_FOG_EXP
|
|
|
|
fog_exp_density = -log(0.01 / actual_visibility);
|
|
|
|
|
|
|
|
// for GL_FOG_EXP2
|
|
|
|
fog_exp2_density = sqrt( -log(0.01) ) / actual_visibility;
|
|
|
|
|
|
|
|
// Set correct opengl fog density
|
2000-03-17 06:16:15 +00:00
|
|
|
glFogf (GL_FOG_DENSITY, fog_exp2_density);
|
1999-10-22 00:27:49 +00:00
|
|
|
}
|
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// set lighting parameters
|
2000-03-17 06:16:15 +00:00
|
|
|
glLightfv( GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
|
|
|
|
glLightfv( GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
|
|
|
|
// glLightfv(GL_LIGHT0, GL_SPECULAR, white );
|
1999-10-20 22:18:54 +00:00
|
|
|
|
|
|
|
// texture parameters
|
2000-03-17 06:16:15 +00:00
|
|
|
// glEnable( GL_TEXTURE_2D );
|
|
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
|
|
|
|
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
|
1999-10-20 22:18:54 +00:00
|
|
|
// set base color (I don't think this is doing anything here)
|
2000-03-17 06:16:15 +00:00
|
|
|
// glMaterialfv (GL_FRONT, GL_AMBIENT, white);
|
1999-10-20 22:18:54 +00:00
|
|
|
// (GL_FRONT, GL_DIFFUSE, white);
|
2000-03-17 06:16:15 +00:00
|
|
|
// glMaterialfv (GL_FRONT, GL_SPECULAR, white);
|
|
|
|
// glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);
|
1999-10-20 22:18:54 +00:00
|
|
|
|
1999-08-15 15:35:07 +00:00
|
|
|
sgVec3 sunpos;
|
|
|
|
sgSetVec3( sunpos, l->sun_vec[0], l->sun_vec[1], l->sun_vec[2] );
|
|
|
|
ssgGetLight( 0 ) -> setPosition( sunpos );
|
1999-06-18 03:42:54 +00:00
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
// glMatrixMode( GL_PROJECTION );
|
|
|
|
// glLoadIdentity();
|
1999-09-28 22:43:52 +00:00
|
|
|
float fov = current_options.get_fov();
|
|
|
|
ssgSetFOV(fov * current_view.get_win_ratio(), fov);
|
1999-06-29 14:57:00 +00:00
|
|
|
|
|
|
|
double agl = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
|
|
|
|
- scenery.cur_elev;
|
|
|
|
|
1999-06-29 17:26:46 +00:00
|
|
|
// FG_LOG( FG_ALL, FG_INFO, "visibility is "
|
|
|
|
// << current_weather.get_visibility() );
|
1999-06-29 14:57:00 +00:00
|
|
|
|
|
|
|
if ( agl > 10.0 ) {
|
2000-03-01 00:31:35 +00:00
|
|
|
ssgSetNearFar( 10.0f, 120000.0f );
|
1999-06-29 14:57:00 +00:00
|
|
|
} else {
|
2000-03-01 00:31:35 +00:00
|
|
|
ssgSetNearFar( 0.5f, 120000.0f );
|
1999-06-29 14:57:00 +00:00
|
|
|
}
|
1999-06-19 04:48:07 +00:00
|
|
|
|
1999-09-09 00:16:28 +00:00
|
|
|
if ( current_options.get_view_mode() ==
|
1999-10-15 13:55:44 +00:00
|
|
|
fgOPTIONS::FG_VIEW_PILOT )
|
1999-09-09 00:16:28 +00:00
|
|
|
{
|
1999-06-30 19:16:53 +00:00
|
|
|
// disable TuX
|
|
|
|
penguin_sel->select(0);
|
1999-09-09 00:16:28 +00:00
|
|
|
} else if ( current_options.get_view_mode() ==
|
|
|
|
fgOPTIONS::FG_VIEW_FOLLOW )
|
|
|
|
{
|
1999-06-30 19:16:53 +00:00
|
|
|
// select view matrix from front of view matrix queue
|
1999-09-09 00:16:28 +00:00
|
|
|
// FGMat4Wrapper tmp = current_view.follow.front();
|
|
|
|
// sgCopyMat4( sgVIEW, tmp.m );
|
1999-06-30 19:16:53 +00:00
|
|
|
|
|
|
|
// enable TuX and set up his position and orientation
|
|
|
|
penguin_sel->select(1);
|
|
|
|
|
|
|
|
sgMat4 sgTRANS;
|
|
|
|
sgMakeTransMat4( sgTRANS,
|
1999-10-14 17:32:34 +00:00
|
|
|
pilot_view.view_pos.x(),
|
|
|
|
pilot_view.view_pos.y(),
|
|
|
|
pilot_view.view_pos.z() );
|
1999-06-30 19:16:53 +00:00
|
|
|
|
1999-07-01 01:17:43 +00:00
|
|
|
sgVec3 ownship_up;
|
|
|
|
sgSetVec3( ownship_up, 0.0, 0.0, 1.0);
|
|
|
|
|
|
|
|
sgMat4 sgROT;
|
|
|
|
sgMakeRotMat4( sgROT, -90.0, ownship_up );
|
|
|
|
|
2000-04-04 05:49:05 +00:00
|
|
|
// sgMat4 sgTMP;
|
|
|
|
// sgMat4 sgTUX;
|
|
|
|
// sgMultMat4( sgTMP, sgROT, pilot_view.VIEW_ROT );
|
|
|
|
// sgMultMat4( sgTUX, sgTMP, sgTRANS );
|
|
|
|
|
|
|
|
// sgTUX = ( sgROT * pilot_view.VIEW_ROT ) * sgTRANS
|
1999-06-30 19:16:53 +00:00
|
|
|
sgMat4 sgTUX;
|
2000-04-04 05:49:05 +00:00
|
|
|
sgCopyMat4( sgTUX, sgROT );
|
|
|
|
sgPostMultMat4( sgTUX, pilot_view.VIEW_ROT );
|
|
|
|
sgPostMultMat4( sgTUX, sgTRANS );
|
1999-06-30 19:16:53 +00:00
|
|
|
|
|
|
|
sgCoord tuxpos;
|
|
|
|
sgSetCoord( &tuxpos, sgTUX );
|
|
|
|
penguin_pos->setTransform( &tuxpos );
|
1999-06-30 14:35:01 +00:00
|
|
|
}
|
|
|
|
|
2000-01-12 18:09:35 +00:00
|
|
|
# ifdef FG_NETWORK_OLK
|
2000-02-28 04:16:12 +00:00
|
|
|
if ( current_options.get_network_olk() ) {
|
|
|
|
sgCoord fgdpos;
|
|
|
|
other = head->next; /* put listpointer to start */
|
|
|
|
while ( other != tail) { /* display all except myself */
|
|
|
|
if ( strcmp( other->ipadr, fgd_mcp_ip) != 0) {
|
|
|
|
other->fgd_sel->select(1);
|
|
|
|
sgSetCoord( &fgdpos, other->sgFGD_COORD );
|
|
|
|
other->fgd_pos->setTransform( &fgdpos );
|
|
|
|
}
|
|
|
|
other = other->next;
|
2000-01-12 18:09:35 +00:00
|
|
|
}
|
|
|
|
|
2000-02-28 04:16:12 +00:00
|
|
|
// fgd_sel->select(1);
|
|
|
|
// sgCopyMat4( sgTUX, current_view.sgVIEW);
|
|
|
|
// sgCoord fgdpos;
|
|
|
|
// sgSetCoord( &fgdpos, sgFGD_VIEW );
|
|
|
|
// fgd_pos->setTransform( &fgdpos);
|
|
|
|
}
|
2000-01-12 18:09:35 +00:00
|
|
|
# endif
|
|
|
|
|
2000-03-02 13:51:31 +00:00
|
|
|
// ssgSetCamera( current_view.VIEW );
|
1999-06-30 00:25:13 +00:00
|
|
|
|
1999-06-30 19:16:53 +00:00
|
|
|
// position tile nodes and update range selectors
|
1999-06-30 00:25:13 +00:00
|
|
|
global_tile_mgr.prep_ssg_nodes();
|
1999-06-30 19:16:53 +00:00
|
|
|
|
|
|
|
// force the default state so ssg can get back on track if
|
|
|
|
// we've changed things elsewhere
|
|
|
|
FGMaterialSlot m_slot;
|
|
|
|
FGMaterialSlot *m_ptr = &m_slot;
|
1999-10-11 23:09:07 +00:00
|
|
|
if ( material_mgr.find( "Default", m_ptr ) ) {
|
|
|
|
m_ptr->get_state()->force();
|
|
|
|
}
|
1999-06-30 19:16:53 +00:00
|
|
|
|
|
|
|
// draw the ssg scene
|
1999-06-28 00:02:52 +00:00
|
|
|
ssgCullAndDraw( scene );
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1999-06-28 05:47:02 +00:00
|
|
|
|
|
|
|
// display HUD && Panel
|
2000-03-17 06:16:15 +00:00
|
|
|
glDisable( GL_FOG );
|
|
|
|
glDisable( GL_DEPTH_TEST );
|
|
|
|
// glDisable( GL_CULL_FACE );
|
|
|
|
// glDisable( GL_TEXTURE_2D );
|
2000-03-02 03:03:16 +00:00
|
|
|
hud_and_panel->apply();
|
1999-06-28 05:47:02 +00:00
|
|
|
fgCockpitUpdate();
|
|
|
|
|
|
|
|
// We can do translucent menus, so why not. :-)
|
2000-03-17 06:16:15 +00:00
|
|
|
// glEnable ( GL_BLEND ) ;
|
2000-03-02 03:03:16 +00:00
|
|
|
menus->apply();
|
2000-03-17 06:16:15 +00:00
|
|
|
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
1999-06-28 05:47:02 +00:00
|
|
|
puDisplay();
|
2000-03-17 06:16:15 +00:00
|
|
|
// glDisable ( GL_BLEND ) ;
|
1999-06-28 05:47:02 +00:00
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
// glEnable( GL_FOG );
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
2000-03-17 06:16:15 +00:00
|
|
|
glutSwapBuffers();
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update internal time dependent calculations (i.e. flight model)
|
1999-01-08 03:23:51 +00:00
|
|
|
void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
|
1999-09-09 00:16:28 +00:00
|
|
|
static fdm_state_list fdm_list;
|
1999-10-11 23:09:07 +00:00
|
|
|
// FGInterface fdm_state;
|
1998-12-09 18:50:12 +00:00
|
|
|
fgLIGHT *l = &cur_light_params;
|
1999-04-08 19:53:46 +00:00
|
|
|
FGTime *t = FGTime::cur_time_params;
|
1999-09-09 00:16:28 +00:00
|
|
|
// FGView *v = ¤t_view;
|
1998-04-21 17:02:27 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
// update the flight model
|
|
|
|
if ( multi_loop < 0 ) {
|
1999-09-01 20:24:54 +00:00
|
|
|
multi_loop = 1;
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
1999-04-08 19:53:46 +00:00
|
|
|
if ( !t->getPause() ) {
|
1998-09-29 02:03:36 +00:00
|
|
|
// run Autopilot system
|
2000-04-30 06:51:49 +00:00
|
|
|
current_autopilot->run();
|
1998-09-29 02:03:36 +00:00
|
|
|
|
1998-07-27 18:41:23 +00:00
|
|
|
// printf("updating flight model x %d\n", multi_loop);
|
1999-10-11 23:09:07 +00:00
|
|
|
/* fgFDMUpdate( current_options.get_flight_model(),
|
1999-09-09 00:16:28 +00:00
|
|
|
fdm_state,
|
1999-08-10 03:44:47 +00:00
|
|
|
multi_loop * current_options.get_speed_up(),
|
1999-10-11 23:09:07 +00:00
|
|
|
remainder ); */
|
|
|
|
cur_fdm_state->update( multi_loop * current_options.get_speed_up() );
|
2000-03-21 20:51:03 +00:00
|
|
|
FGSteam::update( multi_loop * current_options.get_speed_up() );
|
1998-07-27 18:41:23 +00:00
|
|
|
} else {
|
1999-10-11 23:09:07 +00:00
|
|
|
// fgFDMUpdate( current_options.get_flight_model(),
|
|
|
|
// fdm_state, 0, remainder );
|
|
|
|
cur_fdm_state->update( 0 );
|
2000-03-21 20:51:03 +00:00
|
|
|
FGSteam::update( 0 );
|
1999-09-09 00:16:28 +00:00
|
|
|
}
|
|
|
|
|
1999-10-14 17:32:34 +00:00
|
|
|
fdm_list.push_back( *cur_fdm_state );
|
|
|
|
while ( fdm_list.size() > 15 ) {
|
1999-09-09 00:16:28 +00:00
|
|
|
fdm_list.pop_front();
|
|
|
|
}
|
|
|
|
|
1999-10-15 13:55:44 +00:00
|
|
|
if ( current_options.get_view_mode() == fgOPTIONS::FG_VIEW_PILOT ) {
|
1999-10-14 17:32:34 +00:00
|
|
|
cur_view_fdm = *cur_fdm_state;
|
|
|
|
// do nothing
|
1999-09-09 00:16:28 +00:00
|
|
|
} else if ( current_options.get_view_mode() == fgOPTIONS::FG_VIEW_FOLLOW ) {
|
1999-10-14 17:32:34 +00:00
|
|
|
cur_view_fdm = fdm_list.front();
|
1998-07-27 18:41:23 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// update the view angle
|
|
|
|
for ( i = 0; i < multi_loop; i++ ) {
|
1999-09-09 00:16:28 +00:00
|
|
|
if ( fabs(current_view.get_goal_view_offset() -
|
|
|
|
current_view.get_view_offset()) < 0.05 )
|
|
|
|
{
|
|
|
|
current_view.set_view_offset( current_view.get_goal_view_offset() );
|
1998-04-21 17:02:27 +00:00
|
|
|
break;
|
|
|
|
} else {
|
1999-09-09 00:16:28 +00:00
|
|
|
// move current_view.view_offset towards current_view.goal_view_offset
|
|
|
|
if ( current_view.get_goal_view_offset() >
|
|
|
|
current_view.get_view_offset() )
|
|
|
|
{
|
|
|
|
if ( current_view.get_goal_view_offset() -
|
|
|
|
current_view.get_view_offset() < FG_PI )
|
|
|
|
{
|
|
|
|
current_view.inc_view_offset( 0.01 );
|
1998-04-21 17:02:27 +00:00
|
|
|
} else {
|
1999-09-09 00:16:28 +00:00
|
|
|
current_view.inc_view_offset( -0.01 );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
1999-09-09 00:16:28 +00:00
|
|
|
if ( current_view.get_view_offset() -
|
|
|
|
current_view.get_goal_view_offset() < FG_PI )
|
|
|
|
{
|
|
|
|
current_view.inc_view_offset( -0.01 );
|
1998-04-21 17:02:27 +00:00
|
|
|
} else {
|
1999-09-09 00:16:28 +00:00
|
|
|
current_view.inc_view_offset( 0.01 );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
}
|
1999-09-09 00:16:28 +00:00
|
|
|
if ( current_view.get_view_offset() > FG_2PI ) {
|
|
|
|
current_view.inc_view_offset( -FG_2PI );
|
|
|
|
} else if ( current_view.get_view_offset() < 0 ) {
|
|
|
|
current_view.inc_view_offset( FG_2PI );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-07-22 21:40:43 +00:00
|
|
|
|
1998-12-09 18:50:12 +00:00
|
|
|
double tmp = -(l->sun_rotation + FG_PI)
|
1999-10-11 23:09:07 +00:00
|
|
|
- (cur_fdm_state->get_Psi() - current_view.get_view_offset() );
|
1998-07-22 21:40:43 +00:00
|
|
|
while ( tmp < 0.0 ) {
|
|
|
|
tmp += FG_2PI;
|
|
|
|
}
|
|
|
|
while ( tmp > FG_2PI ) {
|
|
|
|
tmp -= FG_2PI;
|
|
|
|
}
|
1998-07-24 21:39:08 +00:00
|
|
|
/* printf("Psi = %.2f, viewoffset = %.2f sunrot = %.2f rottosun = %.2f\n",
|
1999-09-09 00:16:28 +00:00
|
|
|
FG_Psi * RAD_TO_DEG, current_view.view_offset * RAD_TO_DEG,
|
1998-07-24 21:39:08 +00:00
|
|
|
-(l->sun_rotation+FG_PI) * RAD_TO_DEG, tmp * RAD_TO_DEG); */
|
1998-07-22 21:40:43 +00:00
|
|
|
l->UpdateAdjFog();
|
2000-03-02 13:51:31 +00:00
|
|
|
|
|
|
|
// Update solar system
|
2000-03-16 04:15:22 +00:00
|
|
|
ephem->update( t, cur_fdm_state->get_Latitude() );
|
2000-04-25 03:09:26 +00:00
|
|
|
|
|
|
|
// Update radio stack model
|
2000-05-04 01:18:45 +00:00
|
|
|
current_radiostack->update( cur_fdm_state->get_Longitude(),
|
|
|
|
cur_fdm_state->get_Latitude(),
|
2000-04-25 03:09:26 +00:00
|
|
|
cur_fdm_state->get_Altitude() * FEET_TO_METER );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void fgInitTimeDepCalcs( void ) {
|
|
|
|
// initialize timer
|
|
|
|
|
1999-01-08 03:23:51 +00:00
|
|
|
// #ifdef HAVE_SETITIMER
|
1999-09-01 20:24:54 +00:00
|
|
|
// fgTimerInit( 1.0 / current_options.get_model_hz(),
|
|
|
|
// fgUpdateTimeDepCalcs );
|
1999-01-08 03:23:51 +00:00
|
|
|
// #endif HAVE_SETITIMER
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
1999-09-01 20:24:54 +00:00
|
|
|
|
1998-08-27 17:01:55 +00:00
|
|
|
static const double alt_adjust_ft = 3.758099;
|
|
|
|
static const double alt_adjust_m = alt_adjust_ft * FEET_TO_METER;
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-09-01 20:24:54 +00:00
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// What should we do when we have nothing else to do? Let's get ready
|
|
|
|
// for the next move and update the display?
|
1998-04-21 17:02:27 +00:00
|
|
|
static void fgMainLoop( void ) {
|
1999-04-08 19:53:46 +00:00
|
|
|
FGTime *t;
|
1999-01-09 13:37:32 +00:00
|
|
|
static long remainder = 0;
|
1999-10-23 00:09:26 +00:00
|
|
|
long elapsed;
|
1999-05-06 21:14:06 +00:00
|
|
|
#ifdef FANCY_FRAME_COUNTER
|
|
|
|
int i;
|
|
|
|
double accum;
|
|
|
|
#else
|
1998-12-18 23:40:55 +00:00
|
|
|
static time_t last_time = 0;
|
|
|
|
static int frames = 0;
|
1999-05-06 21:14:06 +00:00
|
|
|
#endif // FANCY_FRAME_COUNTER
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-04-08 19:53:46 +00:00
|
|
|
t = FGTime::cur_time_params;
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG, "Running Main Loop");
|
|
|
|
FG_LOG( FG_ALL, FG_DEBUG, "======= ==== ====");
|
1998-05-06 03:16:23 +00:00
|
|
|
|
2000-01-12 18:09:35 +00:00
|
|
|
#ifdef FG_NETWORK_OLK
|
2000-02-28 04:16:12 +00:00
|
|
|
if ( current_options.get_network_olk() ) {
|
|
|
|
if ( net_is_registered == 0 ) { // We first have to reg. to fgd
|
|
|
|
// printf("FGD: Netupdate\n");
|
|
|
|
fgd_send_com( "A", FGFS_host); // Send Mat4 data
|
|
|
|
fgd_send_com( "B", FGFS_host); // Recv Mat4 data
|
|
|
|
}
|
2000-01-12 18:09:35 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-05-27 00:21:54 +00:00
|
|
|
#if defined( ENABLE_PLIB_JOYSTICK )
|
1998-12-18 23:40:55 +00:00
|
|
|
// Read joystick and update control settings
|
1999-08-10 03:44:47 +00:00
|
|
|
if ( current_options.get_control_mode() == fgOPTIONS::FG_JOYSTICK ) {
|
|
|
|
fgJoystickRead();
|
|
|
|
}
|
1998-12-18 23:40:55 +00:00
|
|
|
#elif defined( ENABLE_GLUT_JOYSTICK )
|
|
|
|
// Glut joystick support works by feeding a joystick handler
|
|
|
|
// function to glut. This is taken care of once in the joystick
|
|
|
|
// init routine and we don't have to worry about it again.
|
|
|
|
#endif
|
|
|
|
|
1999-10-14 20:30:54 +00:00
|
|
|
#ifdef FG_OLD_WEATHER
|
1999-08-12 17:13:44 +00:00
|
|
|
current_weather.Update();
|
|
|
|
#endif
|
1998-10-02 12:46:43 +00:00
|
|
|
|
1998-07-12 03:14:42 +00:00
|
|
|
// Fix elevation. I'm just sticking this here for now, it should
|
|
|
|
// probably move eventually
|
|
|
|
|
1998-12-06 14:52:54 +00:00
|
|
|
/* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
|
1998-07-12 03:14:42 +00:00
|
|
|
scenery.cur_elev,
|
1999-10-11 23:09:07 +00:00
|
|
|
cur_fdm_state->get_Runway_altitude() * FEET_TO_METER,
|
|
|
|
cur_fdm_state->get_Altitude() * FEET_TO_METER); */
|
1998-07-12 03:14:42 +00:00
|
|
|
|
|
|
|
if ( scenery.cur_elev > -9990 ) {
|
1999-10-11 23:09:07 +00:00
|
|
|
if ( cur_fdm_state->get_Altitude() * FEET_TO_METER <
|
1998-08-27 17:01:55 +00:00
|
|
|
(scenery.cur_elev + alt_adjust_m - 3.0) ) {
|
1998-07-12 03:14:42 +00:00
|
|
|
// now set aircraft altitude above ground
|
2000-01-13 20:12:16 +00:00
|
|
|
printf("(*) Current Altitude = %.2f < %.2f forcing to %.2f\n",
|
1999-10-11 23:09:07 +00:00
|
|
|
cur_fdm_state->get_Altitude() * FEET_TO_METER,
|
1998-08-27 17:01:55 +00:00
|
|
|
scenery.cur_elev + alt_adjust_m - 3.0,
|
|
|
|
scenery.cur_elev + alt_adjust_m );
|
1999-01-20 13:42:22 +00:00
|
|
|
fgFDMForceAltitude( current_options.get_flight_model(),
|
|
|
|
scenery.cur_elev + alt_adjust_m );
|
1998-07-12 03:14:42 +00:00
|
|
|
|
1998-12-05 14:19:51 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG,
|
1998-11-06 21:17:31 +00:00
|
|
|
"<*> resetting altitude to "
|
1999-10-11 23:09:07 +00:00
|
|
|
<< cur_fdm_state->get_Altitude() * FEET_TO_METER << " meters" );
|
1998-07-12 03:14:42 +00:00
|
|
|
}
|
1999-01-20 13:42:22 +00:00
|
|
|
fgFDMSetGroundElevation( current_options.get_flight_model(),
|
|
|
|
scenery.cur_elev ); // meters
|
1998-07-12 03:14:42 +00:00
|
|
|
}
|
|
|
|
|
1998-12-06 14:52:54 +00:00
|
|
|
/* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
|
1998-07-12 03:14:42 +00:00
|
|
|
scenery.cur_elev,
|
1999-10-11 23:09:07 +00:00
|
|
|
cur_fdm_state->get_Runway_altitude() * FEET_TO_METER,
|
|
|
|
cur_fdm_state->get_Altitude() * FEET_TO_METER); */
|
1998-07-12 03:14:42 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// update "time"
|
2000-03-29 00:15:58 +00:00
|
|
|
t->update( cur_fdm_state->get_Longitude(),
|
|
|
|
cur_fdm_state->get_Latitude(),
|
|
|
|
cur_fdm_state->get_Altitude()* FEET_TO_METER );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-01-09 13:37:32 +00:00
|
|
|
// Get elapsed time (in usec) for this past frame
|
1998-04-21 17:02:27 +00:00
|
|
|
elapsed = fgGetTimeInterval();
|
1999-01-09 13:37:32 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG,
|
|
|
|
"Elapsed time interval is = " << elapsed
|
1998-11-06 21:17:31 +00:00
|
|
|
<< ", previous remainder is = " << remainder );
|
1998-05-06 03:16:23 +00:00
|
|
|
|
|
|
|
// Calculate frame rate average
|
1999-05-06 21:14:06 +00:00
|
|
|
#ifdef FANCY_FRAME_COUNTER
|
|
|
|
/* old fps calculation */
|
|
|
|
if ( elapsed > 0 ) {
|
|
|
|
double tmp;
|
|
|
|
accum = 0.0;
|
|
|
|
for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
|
|
|
|
tmp = general.get_frame(i);
|
|
|
|
accum += tmp;
|
|
|
|
// printf("frame[%d] = %.2f\n", i, g->frames[i]);
|
|
|
|
general.set_frame(i+1,tmp);
|
|
|
|
}
|
|
|
|
tmp = 1000000.0 / (float)elapsed;
|
|
|
|
general.set_frame(0,tmp);
|
|
|
|
// printf("frame[0] = %.2f\n", general.frames[0]);
|
|
|
|
accum += tmp;
|
|
|
|
general.set_frame_rate(accum / (float)FG_FRAME_RATE_HISTORY);
|
|
|
|
// printf("ave = %.2f\n", general.frame_rate);
|
|
|
|
}
|
|
|
|
#else
|
1999-04-08 19:53:46 +00:00
|
|
|
if ( (t->get_cur_time() != last_time) && (last_time > 0) ) {
|
1999-01-07 20:24:43 +00:00
|
|
|
general.set_frame_rate( frames );
|
1999-01-09 13:37:32 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG,
|
|
|
|
"--> Frame rate is = " << general.get_frame_rate() );
|
1998-12-18 23:40:55 +00:00
|
|
|
frames = 0;
|
|
|
|
}
|
1999-04-08 19:53:46 +00:00
|
|
|
last_time = t->get_cur_time();
|
1998-12-18 23:40:55 +00:00
|
|
|
++frames;
|
1999-05-06 21:14:06 +00:00
|
|
|
#endif
|
1998-07-12 03:14:42 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// Run flight model
|
|
|
|
if ( ! use_signals ) {
|
1998-12-18 23:40:55 +00:00
|
|
|
// Calculate model iterations needed for next frame
|
|
|
|
elapsed += remainder;
|
|
|
|
|
1999-10-23 00:09:26 +00:00
|
|
|
global_multi_loop = (int)(((double)elapsed * 0.000001) *
|
1999-09-01 20:24:54 +00:00
|
|
|
current_options.get_model_hz());
|
1999-10-23 00:09:26 +00:00
|
|
|
remainder = elapsed - ( (global_multi_loop*1000000) /
|
1999-09-01 20:24:54 +00:00
|
|
|
current_options.get_model_hz() );
|
1999-01-09 13:37:32 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG,
|
1999-10-23 00:09:26 +00:00
|
|
|
"Model iterations needed = " << global_multi_loop
|
1998-12-18 23:40:55 +00:00
|
|
|
<< ", new remainder = " << remainder );
|
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// flight model
|
1999-10-23 00:09:26 +00:00
|
|
|
if ( global_multi_loop > 0 ) {
|
|
|
|
fgUpdateTimeDepCalcs(global_multi_loop, remainder);
|
1998-12-18 23:40:55 +00:00
|
|
|
} else {
|
1999-09-01 20:24:54 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG,
|
|
|
|
"Elapsed time is zero ... we're zinging" );
|
1998-12-18 23:40:55 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
1999-04-27 19:27:45 +00:00
|
|
|
#if ! defined( MACOS )
|
1999-11-19 02:10:24 +00:00
|
|
|
// Do any I/O channel work that might need to be done
|
|
|
|
fgIOProcess();
|
1999-04-27 19:27:45 +00:00
|
|
|
#endif
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// see if we need to load any new scenery tiles
|
1999-06-13 05:58:02 +00:00
|
|
|
global_tile_mgr.update();
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// Process/manage pending events
|
1998-05-22 21:28:52 +00:00
|
|
|
global_events.Process();
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-06-01 17:54:40 +00:00
|
|
|
// Run audio scheduler
|
1998-07-16 17:33:34 +00:00
|
|
|
#ifdef ENABLE_AUDIO_SUPPORT
|
1999-04-03 04:21:01 +00:00
|
|
|
if ( current_options.get_sound() && !audio_sched->not_working() ) {
|
1998-09-25 16:02:07 +00:00
|
|
|
|
1998-11-11 00:24:00 +00:00
|
|
|
# ifdef MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
|
|
|
|
|
|
|
|
// note: all these factors are relative to the sample. our
|
|
|
|
// sample format should really contain a conversion factor so
|
|
|
|
// that we can get prop speed right for arbitrary samples.
|
|
|
|
// Note that for normal-size props, there is a point at which
|
|
|
|
// the prop tips approach the speed of sound; that is a pretty
|
|
|
|
// strong limit to how fast the prop can go.
|
|
|
|
|
|
|
|
// multiplication factor is prime pitch control; add some log
|
|
|
|
// component for verisimilitude
|
|
|
|
|
|
|
|
double pitch = log((controls.get_throttle(0) * 14.0) + 1.0);
|
|
|
|
//fprintf(stderr, "pitch1: %f ", pitch);
|
1999-10-11 23:09:07 +00:00
|
|
|
if (controls.get_throttle(0) > 0.0 || cur_fdm_state->v_rel_wind > 40.0) {
|
|
|
|
//fprintf(stderr, "rel_wind: %f ", cur_fdm_state->v_rel_wind);
|
1998-11-11 00:24:00 +00:00
|
|
|
// only add relative wind and AoA if prop is moving
|
|
|
|
// or we're really flying at idle throttle
|
|
|
|
if (pitch < 5.4) { // this needs tuning
|
|
|
|
// prop tips not breaking sound barrier
|
1999-10-11 23:09:07 +00:00
|
|
|
pitch += log(cur_fdm_state->v_rel_wind + 0.8)/2;
|
1998-11-11 00:24:00 +00:00
|
|
|
} else {
|
|
|
|
// prop tips breaking sound barrier
|
1999-10-11 23:09:07 +00:00
|
|
|
pitch += log(cur_fdm_state->v_rel_wind + 0.8)/10;
|
1998-11-11 00:24:00 +00:00
|
|
|
}
|
|
|
|
//fprintf(stderr, "pitch2: %f ", pitch);
|
|
|
|
//fprintf(stderr, "AoA: %f ", FG_Gamma_vert_rad);
|
|
|
|
|
|
|
|
// Angle of Attack next... -x^3(e^x) is my best guess Just
|
|
|
|
// need to calculate some reasonable scaling factor and
|
|
|
|
// then clamp it on the positive aoa (neg adj) side
|
1999-10-11 23:09:07 +00:00
|
|
|
double aoa = cur_fdm_state->get_Gamma_vert_rad() * 2.2;
|
1998-11-16 13:59:58 +00:00
|
|
|
double tmp = 3.0;
|
|
|
|
double aoa_adj = pow(-aoa, tmp) * pow(M_E, aoa);
|
1998-11-11 00:24:00 +00:00
|
|
|
if (aoa_adj < -0.8) aoa_adj = -0.8;
|
|
|
|
pitch += aoa_adj;
|
|
|
|
//fprintf(stderr, "pitch3: %f ", pitch);
|
|
|
|
|
|
|
|
// don't run at absurdly slow rates -- not realistic
|
|
|
|
// and sounds bad to boot. :-)
|
|
|
|
if (pitch < 0.8) pitch = 0.8;
|
|
|
|
}
|
|
|
|
//fprintf(stderr, "pitch4: %f\n", pitch);
|
|
|
|
|
|
|
|
double volume = controls.get_throttle(0) * 1.15 + 0.3 +
|
1999-10-11 23:09:07 +00:00
|
|
|
log(cur_fdm_state->v_rel_wind + 1.0)/14.0;
|
1998-11-11 00:24:00 +00:00
|
|
|
// fprintf(stderr, "volume: %f\n", volume);
|
|
|
|
|
|
|
|
pitch_envelope.setStep ( 0, 0.01, pitch );
|
|
|
|
volume_envelope.setStep ( 0, 0.01, volume );
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
|
|
|
|
pitch_envelope.setStep ( 0, 0.01, param );
|
|
|
|
volume_envelope.setStep ( 0, 0.01, param );
|
|
|
|
|
|
|
|
# endif // experimental throttle patch
|
1998-09-25 16:02:07 +00:00
|
|
|
|
1998-07-27 18:41:23 +00:00
|
|
|
audio_sched -> update();
|
|
|
|
}
|
1998-06-03 00:47:11 +00:00
|
|
|
#endif
|
1998-06-01 17:54:40 +00:00
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// redraw display
|
|
|
|
fgRenderFrame();
|
|
|
|
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_ALL, FG_DEBUG, "" );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
// This is the top level master main function that is registered as
|
|
|
|
// our idle funciton
|
|
|
|
//
|
|
|
|
|
|
|
|
// The first few passes take care of initialization things (a couple
|
|
|
|
// per pass) and once everything has been initialized fgMainLoop from
|
|
|
|
// then on.
|
|
|
|
|
|
|
|
static void fgIdleFunction ( void ) {
|
|
|
|
// printf("idle state == %d\n", idle_state);
|
|
|
|
|
|
|
|
if ( idle_state == 0 ) {
|
|
|
|
// Initialize the splash screen right away
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_splash_screen() ) {
|
1998-07-06 21:34:17 +00:00
|
|
|
fgSplashInit();
|
|
|
|
}
|
1998-07-06 02:42:02 +00:00
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 1 ) {
|
|
|
|
// Start the intro music
|
1998-07-06 21:34:17 +00:00
|
|
|
#if !defined(WIN32)
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_intro_music() ) {
|
1998-08-27 17:01:55 +00:00
|
|
|
string lockfile = "/tmp/mpg123.running";
|
1999-04-27 19:27:45 +00:00
|
|
|
FGPath mp3file( current_options.get_fg_root() );
|
|
|
|
mp3file.append( "Sounds/intro.mp3" );
|
|
|
|
|
|
|
|
string command = "(touch " + lockfile + "; mpg123 "
|
|
|
|
+ mp3file.str() + "> /dev/null 2>&1; /bin/rm "
|
|
|
|
+ lockfile + ") &";
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
1999-04-27 19:27:45 +00:00
|
|
|
"Starting intro music: " << mp3file.str() );
|
1998-08-27 17:01:55 +00:00
|
|
|
system ( command.c_str() );
|
1998-07-06 21:34:17 +00:00
|
|
|
}
|
1998-07-06 02:42:02 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 2 ) {
|
|
|
|
// These are a few miscellaneous things that aren't really
|
|
|
|
// "subsystems" but still need to be initialized.
|
1998-07-27 18:41:23 +00:00
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
#ifdef USE_GLIDE
|
1999-01-07 20:24:43 +00:00
|
|
|
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
|
1998-07-06 02:42:02 +00:00
|
|
|
grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 3 ) {
|
|
|
|
// This is the top level init routine which calls all the
|
|
|
|
// other subsystem initialization routines. If you are adding
|
|
|
|
// a subsystem to flight gear, its initialization call should
|
|
|
|
// located in this routine.
|
|
|
|
if( !fgInitSubsystems()) {
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
|
|
"Subsystem initializations failed ..." );
|
|
|
|
exit(-1);
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 4 ) {
|
|
|
|
// setup OpenGL view parameters
|
|
|
|
fgInitVisuals();
|
|
|
|
|
|
|
|
if ( use_signals ) {
|
|
|
|
// init timer routines, signals, etc. Arrange for an alarm
|
|
|
|
// signal to be generated, etc.
|
|
|
|
fgInitTimeDepCalcs();
|
|
|
|
}
|
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 5 ) {
|
|
|
|
|
|
|
|
idle_state++;
|
|
|
|
} else if ( idle_state == 6 ) {
|
|
|
|
// Initialize audio support
|
1998-07-16 17:33:34 +00:00
|
|
|
#ifdef ENABLE_AUDIO_SUPPORT
|
1998-07-06 02:42:02 +00:00
|
|
|
|
1998-07-06 21:34:17 +00:00
|
|
|
#if !defined(WIN32)
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_intro_music() ) {
|
1998-07-06 21:34:17 +00:00
|
|
|
// Let's wait for mpg123 to finish
|
1998-08-27 17:01:55 +00:00
|
|
|
string lockfile = "/tmp/mpg123.running";
|
1998-07-20 12:49:44 +00:00
|
|
|
struct stat stat_buf;
|
1998-07-06 21:34:17 +00:00
|
|
|
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"Waiting for mpg123 player to finish ..." );
|
1998-08-27 17:01:55 +00:00
|
|
|
while ( stat(lockfile.c_str(), &stat_buf) == 0 ) {
|
1998-07-06 21:34:17 +00:00
|
|
|
// file exist, wait ...
|
|
|
|
sleep(1);
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, ".");
|
1998-07-06 21:34:17 +00:00
|
|
|
}
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "");
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
|
|
|
#endif // WIN32
|
|
|
|
|
1999-11-20 15:39:53 +00:00
|
|
|
if ( current_options.get_sound() ) {
|
|
|
|
audio_sched = new slScheduler ( 8000 );
|
|
|
|
audio_mixer = new smMixer;
|
|
|
|
audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
|
|
|
|
audio_sched -> setSafetyMargin ( 1.0 ) ;
|
|
|
|
|
|
|
|
FGPath slfile( current_options.get_fg_root() );
|
|
|
|
slfile.append( "Sounds/wasp.wav" );
|
|
|
|
|
|
|
|
s1 = new slSample ( (char *)slfile.c_str() );
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"Rate = " << s1 -> getRate()
|
|
|
|
<< " Bps = " << s1 -> getBps()
|
|
|
|
<< " Stereo = " << s1 -> getStereo() );
|
|
|
|
audio_sched -> loopSample ( s1 );
|
|
|
|
|
|
|
|
if ( audio_sched->not_working() ) {
|
|
|
|
// skip
|
|
|
|
} else {
|
|
|
|
pitch_envelope.setStep ( 0, 0.01, 0.6 );
|
|
|
|
volume_envelope.setStep ( 0, 0.01, 0.6 );
|
|
|
|
|
|
|
|
audio_sched -> addSampleEnvelope( s1, 0, 0,
|
|
|
|
&pitch_envelope,
|
|
|
|
SL_PITCH_ENVELOPE );
|
|
|
|
audio_sched -> addSampleEnvelope( s1, 0, 1,
|
|
|
|
&volume_envelope,
|
|
|
|
SL_VOLUME_ENVELOPE );
|
|
|
|
}
|
1998-09-25 16:02:07 +00:00
|
|
|
|
1999-11-20 15:39:53 +00:00
|
|
|
// strcpy(slfile, path);
|
|
|
|
// strcat(slfile, "thunder.wav");
|
|
|
|
// s2 -> loadFile ( slfile );
|
|
|
|
// s2 -> adjustVolume(0.5);
|
|
|
|
// audio_sched -> playSample ( s2 );
|
|
|
|
}
|
1998-07-06 02:42:02 +00:00
|
|
|
#endif
|
|
|
|
|
1998-07-27 18:41:23 +00:00
|
|
|
// sleep(1);
|
1998-07-06 02:42:02 +00:00
|
|
|
idle_state = 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( idle_state == 1000 ) {
|
|
|
|
// We've finished all our initialization steps, from now on we
|
|
|
|
// run the main loop.
|
|
|
|
|
|
|
|
fgMainLoop();
|
|
|
|
} else {
|
1998-07-13 21:00:09 +00:00
|
|
|
if ( current_options.get_splash_screen() == 1 ) {
|
1998-07-06 21:34:17 +00:00
|
|
|
fgSplashUpdate(0.0);
|
|
|
|
}
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-06 22:16:12 +00:00
|
|
|
// options.cxx needs to see this for toggle_panel()
|
1998-04-21 17:02:27 +00:00
|
|
|
// Handle new window size or exposure
|
1999-05-06 22:16:12 +00:00
|
|
|
void fgReshape( int width, int height ) {
|
1999-06-18 03:42:54 +00:00
|
|
|
if ( ! current_options.get_panel_status() ) {
|
1999-09-03 00:27:48 +00:00
|
|
|
current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
|
2000-03-17 06:16:15 +00:00
|
|
|
glViewport(0, 0 , (GLint)(width), (GLint)(height) );
|
1999-06-18 03:42:54 +00:00
|
|
|
} else {
|
1999-09-03 00:27:48 +00:00
|
|
|
current_view.set_win_ratio( (GLfloat) width /
|
|
|
|
((GLfloat) (height)*0.4232) );
|
2000-05-13 00:02:43 +00:00
|
|
|
glViewport(0, (GLint)((height)*0.5768),
|
|
|
|
(GLint)(width), (GLint)((height)*0.4232) );
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
1998-12-11 20:26:25 +00:00
|
|
|
current_view.set_winWidth( width );
|
|
|
|
current_view.set_winHeight( height );
|
|
|
|
current_view.force_update_fov_math();
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1999-09-28 22:43:52 +00:00
|
|
|
// set these fov to be the same as in fgRenderFrame()
|
2000-05-13 00:02:43 +00:00
|
|
|
// float x_fov = current_options.get_fov();
|
|
|
|
// float y_fov = x_fov * 1.0 / current_view.get_win_ratio();
|
|
|
|
// ssgSetFOV( x_fov, y_fov );
|
1999-09-28 22:43:52 +00:00
|
|
|
|
2000-05-13 00:02:43 +00:00
|
|
|
// glViewport ( 0, 0, width, height );
|
1999-10-09 13:09:16 +00:00
|
|
|
float fov = current_options.get_fov();
|
|
|
|
ssgSetFOV(fov * current_view.get_win_ratio(), fov);
|
1999-08-31 23:22:05 +00:00
|
|
|
|
2000-05-13 00:02:43 +00:00
|
|
|
fgHUDReshape();
|
|
|
|
|
1998-07-06 02:42:02 +00:00
|
|
|
if ( idle_state == 1000 ) {
|
|
|
|
// yes we've finished all our initializations and are running
|
|
|
|
// the main loop, so this will now work without seg faulting
|
|
|
|
// the system.
|
1999-10-14 17:32:34 +00:00
|
|
|
current_view.UpdateViewParams(cur_view_fdm);
|
1998-07-06 02:42:02 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// Initialize GLUT and define a main window
|
1998-05-06 03:16:23 +00:00
|
|
|
int fgGlutInit( int *argc, char **argv ) {
|
1999-06-02 22:22:47 +00:00
|
|
|
|
|
|
|
#if !defined( MACOS )
|
1998-04-24 00:49:17 +00:00
|
|
|
// GLUT will extract all glut specific options so later on we only
|
|
|
|
// need wory about our own.
|
2000-03-17 06:16:15 +00:00
|
|
|
glutInit(argc, argv);
|
1999-06-02 22:22:47 +00:00
|
|
|
#endif
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// Define Display Parameters
|
2000-03-17 06:16:15 +00:00
|
|
|
glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-11-16 13:59:58 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "Opening a window: " <<
|
|
|
|
current_options.get_xsize() << "x" << current_options.get_ysize() );
|
|
|
|
|
1998-04-21 17:02:27 +00:00
|
|
|
// Define initial window size
|
2000-03-17 06:16:15 +00:00
|
|
|
glutInitWindowSize( current_options.get_xsize(),
|
1998-11-16 13:59:58 +00:00
|
|
|
current_options.get_ysize() );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
// Initialize windows
|
1998-08-20 15:10:33 +00:00
|
|
|
if ( current_options.get_game_mode() == 0 ) {
|
|
|
|
// Open the regular window
|
2000-03-17 06:16:15 +00:00
|
|
|
glutCreateWindow("Flight Gear");
|
1999-04-27 19:27:45 +00:00
|
|
|
#ifndef GLUT_WRONG_VERSION
|
1998-08-20 15:10:33 +00:00
|
|
|
} else {
|
|
|
|
// Open the cool new 'game mode' window
|
1999-01-27 04:49:17 +00:00
|
|
|
char game_mode_str[256];
|
2000-05-13 00:02:43 +00:00
|
|
|
sprintf( game_mode_str, "width=%d height=%d bpp=%d",
|
1999-01-27 04:49:17 +00:00
|
|
|
current_options.get_xsize(),
|
2000-05-13 00:02:43 +00:00
|
|
|
current_options.get_ysize(),
|
|
|
|
current_options.get_bpp());
|
1999-01-27 04:49:17 +00:00
|
|
|
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"game mode params = " << game_mode_str );
|
|
|
|
glutGameModeString( game_mode_str );
|
1998-08-20 15:10:33 +00:00
|
|
|
glutEnterGameMode();
|
1999-04-27 19:27:45 +00:00
|
|
|
#endif
|
1998-08-20 15:10:33 +00:00
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-11-23 20:51:26 +00:00
|
|
|
// This seems to be the absolute earliest in the init sequence
|
|
|
|
// that these calls will return valid info. Too bad it's after
|
|
|
|
// we've already created and sized out window. :-(
|
1999-01-07 20:24:43 +00:00
|
|
|
general.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
|
|
|
|
general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
|
|
|
|
general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
|
1998-11-23 20:51:26 +00:00
|
|
|
|
1999-01-07 20:24:43 +00:00
|
|
|
FG_LOG ( FG_GENERAL, FG_INFO, general.get_glRenderer() );
|
1998-11-23 20:51:26 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
// try to determine if we should adjust the initial default
|
|
|
|
// display resolution. The options class defaults (is
|
|
|
|
// initialized) to 640x480.
|
|
|
|
string renderer = general.glRenderer;
|
|
|
|
|
|
|
|
// currently we only know how to deal with Mesa/Glide/Voodoo cards
|
|
|
|
if ( renderer.find( "Glide" ) != string::npos ) {
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "Detected a Glide driver" );
|
|
|
|
if ( renderer.find( "FB/8" ) != string::npos ) {
|
|
|
|
// probably a voodoo-2
|
|
|
|
if ( renderer.find( "TMU/SLI" ) != string::npos ) {
|
|
|
|
// probably two SLI'd Voodoo-2's
|
|
|
|
current_options.set_xsize( 1024 );
|
|
|
|
current_options.set_ysize( 768 );
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"It looks like you have two sli'd voodoo-2's." << endl
|
|
|
|
<< "upgrading your win resolution to 1024 x 768" );
|
|
|
|
glutReshapeWindow(1024, 768);
|
|
|
|
} else {
|
|
|
|
// probably a single non-SLI'd Voodoo-2
|
|
|
|
current_options.set_xsize( 800 );
|
|
|
|
current_options.set_ysize( 600 );
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"It looks like you have a voodoo-2." << endl
|
|
|
|
<< "upgrading your win resolution to 800 x 600" );
|
|
|
|
glutReshapeWindow(800, 600);
|
|
|
|
}
|
|
|
|
} else if ( renderer.find( "FB/2" ) != string::npos ) {
|
|
|
|
// probably a voodoo-1, stick with the default
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// we have no special knowledge of this card, stick with the default
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
return(1);
|
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// Initialize GLUT event handlers
|
|
|
|
int fgGlutInitEvents( void ) {
|
|
|
|
// call fgReshape() on window resizes
|
2000-03-17 06:16:15 +00:00
|
|
|
glutReshapeFunc( fgReshape );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// call GLUTkey() on keyboard event
|
2000-03-17 06:16:15 +00:00
|
|
|
glutKeyboardFunc( GLUTkey );
|
1998-04-24 00:49:17 +00:00
|
|
|
glutSpecialFunc( GLUTspecialkey );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-06-12 00:57:38 +00:00
|
|
|
// call guiMouseFunc() whenever our little rodent is used
|
|
|
|
glutMouseFunc ( guiMouseFunc );
|
|
|
|
glutMotionFunc (guiMotionFunc );
|
|
|
|
glutPassiveMotionFunc (guiMotionFunc );
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// call fgMainLoop() whenever there is
|
|
|
|
// nothing else to do
|
2000-03-17 06:16:15 +00:00
|
|
|
glutIdleFunc( fgIdleFunction );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// draw the scene
|
2000-03-17 06:16:15 +00:00
|
|
|
glutDisplayFunc( fgRenderFrame );
|
1998-04-21 17:02:27 +00:00
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
return(1);
|
|
|
|
}
|
1998-04-21 17:02:27 +00:00
|
|
|
|
|
|
|
|
1998-04-24 00:49:17 +00:00
|
|
|
// Main ...
|
|
|
|
int main( int argc, char **argv ) {
|
1999-04-27 19:27:45 +00:00
|
|
|
|
1999-06-02 22:22:47 +00:00
|
|
|
#if defined( MACOS )
|
2000-04-27 21:57:08 +00:00
|
|
|
freopen ("stdout.txt", "w", stdout );
|
|
|
|
freopen ("stderr.txt", "w", stderr );
|
1999-06-02 22:22:47 +00:00
|
|
|
argc = ccommand( &argv );
|
1999-04-27 19:27:45 +00:00
|
|
|
#endif
|
|
|
|
|
1998-05-07 23:14:14 +00:00
|
|
|
#ifdef HAVE_BC5PLUS
|
|
|
|
_control87(MCW_EM, MCW_EM); /* defined in float.h */
|
|
|
|
#endif
|
|
|
|
|
1998-11-16 13:59:58 +00:00
|
|
|
// set default log levels
|
1998-12-06 13:51:20 +00:00
|
|
|
fglog().setLogLevels( FG_ALL, FG_INFO );
|
1998-11-16 13:59:58 +00:00
|
|
|
|
1998-11-20 01:02:35 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear: Version " << VERSION << endl );
|
|
|
|
|
1999-03-08 21:56:37 +00:00
|
|
|
// seed the random number generater
|
|
|
|
fg_srandom();
|
|
|
|
|
2000-03-23 03:28:54 +00:00
|
|
|
// AIRCRAFT defined in uiuc_aircraft.h
|
2000-03-22 22:01:33 +00:00
|
|
|
// AIRCRAFTDIR defined in uiuc_aircraftdir.h
|
|
|
|
aircraft_ = new AIRCRAFT;
|
|
|
|
aircraftdir_ = new AIRCRAFTDIR;
|
2000-03-23 03:28:54 +00:00
|
|
|
aircraft_dir = ""; // Initialize the Aircraft directory to "" (UIUC)
|
2000-03-22 22:01:33 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
// Load the configuration parameters
|
|
|
|
if ( !fgInitConfig(argc, argv) ) {
|
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Config option parsing failed ..." );
|
1998-11-06 21:17:31 +00:00
|
|
|
exit(-1);
|
1998-04-24 00:49:17 +00:00
|
|
|
}
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1998-08-20 15:10:33 +00:00
|
|
|
// Initialize the Window/Graphics environment.
|
|
|
|
if( !fgGlutInit(&argc, argv) ) {
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "GLUT initialization failed ..." );
|
|
|
|
exit(-1);
|
1998-08-20 15:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize the various GLUT Event Handlers.
|
|
|
|
if( !fgGlutInitEvents() ) {
|
2000-04-19 21:22:16 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
|
|
"GLUT event handler initialization failed ..." );
|
|
|
|
exit(-1);
|
1998-08-20 15:10:33 +00:00
|
|
|
}
|
2000-04-19 21:22:16 +00:00
|
|
|
|
|
|
|
// Initialize ssg (from plib). Needs to come before we do any
|
|
|
|
// other ssg stuff, but after opengl/glut has been initialized.
|
|
|
|
ssgInit();
|
1998-08-20 15:10:33 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
// Initialize the user interface (we need to do this before
|
|
|
|
// passing off control to glut and before fgInitGeneral to get our
|
|
|
|
// fonts !!!
|
1999-05-12 01:11:17 +00:00
|
|
|
guiInit();
|
|
|
|
|
2000-03-16 04:15:22 +00:00
|
|
|
// Initialize time
|
|
|
|
FGTime::cur_time_params = new FGTime();
|
|
|
|
// FGTime::cur_time_params->init( cur_fdm_state->get_Longitude(),
|
|
|
|
// cur_fdm_state->get_Latitude() );
|
|
|
|
// FGTime::cur_time_params->update( cur_fdm_state->get_Longitude() );
|
|
|
|
FGTime::cur_time_params->init( 0.0, 0.0 );
|
2000-03-29 00:15:58 +00:00
|
|
|
FGTime::cur_time_params->update( 0.0, 0.0, 0.0 );
|
2000-03-16 04:15:22 +00:00
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
// Do some quick general initializations
|
1998-07-27 18:41:23 +00:00
|
|
|
if( !fgInitGeneral()) {
|
1998-11-06 21:17:31 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
|
|
"General initializations failed ..." );
|
|
|
|
exit(-1);
|
1998-07-27 18:41:23 +00:00
|
|
|
}
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
//
|
|
|
|
// some ssg test stuff (requires data from the plib source
|
|
|
|
// distribution) specifically from the ssg tux example
|
|
|
|
//
|
|
|
|
|
1999-07-01 01:17:43 +00:00
|
|
|
FGPath modelpath( current_options.get_fg_root() );
|
|
|
|
modelpath.append( "Models" );
|
|
|
|
modelpath.append( "Geometry" );
|
|
|
|
|
|
|
|
FGPath texturepath( current_options.get_fg_root() );
|
|
|
|
texturepath.append( "Models" );
|
|
|
|
texturepath.append( "Textures" );
|
|
|
|
|
|
|
|
ssgModelPath( (char *)modelpath.c_str() );
|
|
|
|
ssgTexturePath( (char *)texturepath.c_str() );
|
1999-06-18 03:42:54 +00:00
|
|
|
|
2000-02-29 17:13:02 +00:00
|
|
|
// Scene graph root
|
1999-06-18 03:42:54 +00:00
|
|
|
scene = new ssgRoot;
|
2000-02-29 17:13:02 +00:00
|
|
|
scene->setName( "Scene" );
|
|
|
|
|
2000-03-02 03:03:16 +00:00
|
|
|
// Initialize the sky
|
2000-03-16 23:01:57 +00:00
|
|
|
FGPath ephem_data_path( current_options.get_fg_root() );
|
|
|
|
ephem_data_path.append( "Astro" );
|
|
|
|
ephem = new FGEphemeris( ephem_data_path.c_str() );
|
2000-03-16 04:15:22 +00:00
|
|
|
ephem->update( FGTime::cur_time_params, 0.0 );
|
2000-03-16 23:01:57 +00:00
|
|
|
|
2000-03-06 23:28:43 +00:00
|
|
|
FGPath sky_tex_path( current_options.get_fg_root() );
|
|
|
|
sky_tex_path.append( "Textures" );
|
|
|
|
sky_tex_path.append( "Sky" );
|
2000-03-16 04:15:22 +00:00
|
|
|
thesky = new SGSky;
|
|
|
|
thesky->texture_path( sky_tex_path.str() );
|
2000-03-16 23:01:57 +00:00
|
|
|
|
2000-03-16 04:15:22 +00:00
|
|
|
ssgBranch *sky = thesky->build( 550.0, 550.0,
|
|
|
|
ephem->getNumPlanets(),
|
|
|
|
ephem->getPlanets(), 60000.0,
|
2000-03-16 23:01:57 +00:00
|
|
|
ephem->getNumStars(),
|
|
|
|
ephem->getStars(), 60000.0 );
|
2000-03-16 04:15:22 +00:00
|
|
|
scene->addKid( sky );
|
|
|
|
|
|
|
|
// Terrain branch
|
|
|
|
terrain = new ssgBranch;
|
|
|
|
terrain->setName( "Terrain" );
|
|
|
|
scene->addKid( terrain );
|
2000-02-29 17:13:02 +00:00
|
|
|
|
|
|
|
// temporary visible aircraft "own ship"
|
1999-06-30 19:16:53 +00:00
|
|
|
penguin_sel = new ssgSelector;
|
|
|
|
penguin_pos = new ssgTransform;
|
2000-03-02 13:51:31 +00:00
|
|
|
// ssgBranch *tux_obj = ssgMakeSphere( 10.0, 10, 10 );
|
|
|
|
ssgEntity *tux_obj = ssgLoadAC( "glider.ac" );
|
1999-07-31 05:01:04 +00:00
|
|
|
// ssgEntity *tux_obj = ssgLoadAC( "Tower1x.ac" );
|
2000-03-02 03:03:16 +00:00
|
|
|
|
1999-06-30 19:16:53 +00:00
|
|
|
penguin_pos->addKid( tux_obj );
|
|
|
|
penguin_sel->addKid( penguin_pos );
|
1999-06-18 03:42:54 +00:00
|
|
|
ssgFlatten( tux_obj );
|
1999-06-30 19:16:53 +00:00
|
|
|
ssgStripify( penguin_sel );
|
2000-01-13 20:12:16 +00:00
|
|
|
penguin_sel->clrTraversalMaskBits( SSGTRAV_HOT );
|
2000-02-29 17:13:02 +00:00
|
|
|
scene->addKid( penguin_sel );
|
1999-06-18 03:42:54 +00:00
|
|
|
|
1999-06-30 20:21:04 +00:00
|
|
|
#ifdef FG_NETWORK_OLK
|
|
|
|
// Do the network intialization
|
2000-02-28 04:16:12 +00:00
|
|
|
if ( current_options.get_network_olk() ) {
|
|
|
|
printf("Multipilot mode %s\n", fg_net_init( scene ) );
|
|
|
|
}
|
1999-06-30 20:21:04 +00:00
|
|
|
#endif
|
|
|
|
|
2000-03-02 03:03:16 +00:00
|
|
|
// build our custom render states
|
|
|
|
fgBuildRenderStates();
|
|
|
|
|
1998-04-24 14:19:29 +00:00
|
|
|
// pass control off to the master GLUT event handler
|
1998-04-24 00:49:17 +00:00
|
|
|
glutMainLoop();
|
|
|
|
|
1999-06-18 03:42:54 +00:00
|
|
|
// we never actually get here ... but to avoid compiler warnings,
|
|
|
|
// etc.
|
|
|
|
return 0;
|
1998-04-21 17:02:27 +00:00
|
|
|
}
|