-//
// GLUTmain.cxx -- top level sim routines
//
// Written by Curtis Olson for OpenGL, started May 1997.
//
-// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
+// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// (Log is kept at end of this file)
-#include <config.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
+# include <float.h>
#endif
#include <GL/glut.h>
#include <XGL/xgl.h>
#include <stdio.h>
+#include <string.h>
+#include <string>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
-#ifdef HAVE_GETOPT_H
-# include <getopt.h>
+
+#include <sys/stat.h> /* for stat() */
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h> /* for stat() */
#endif
-#include <Include/cmdargs.h> // Line to command line arguments
#include <Include/fg_constants.h> // for VERSION
#include <Include/general.h>
-#include <Aircraft/aircraft.h>
-#include <Astro/moon.hxx>
-#include <Astro/planets.hxx>
+#include <Aircraft/aircraft.hxx>
#include <Astro/sky.hxx>
#include <Astro/stars.hxx>
-#include <Astro/sun.hxx>
-#include <Cockpit/cockpit.h>
-#include <Debug/fg_debug.h>
-#include <Joystick/joystick.h>
-#include <Math/fg_geodesy.h>
+#include <Astro/solarsystem.hxx>
+
+#ifdef ENABLE_AUDIO_SUPPORT
+# include <Audio/src/sl.h>
+# include <Audio/src/sm.h>
+#endif
+
+#include <Autopilot/autopilot.hxx>
+#include <Cockpit/cockpit.hxx>
+#include <Debug/logstream.hxx>
+#include <GUI/gui.h>
+#include <Joystick/joystick.hxx>
+#include <Math/fg_geodesy.hxx>
#include <Math/mat3.h>
-#include <Math/polar.h>
-#include <Scenery/scenery.h>
+#include <Math/polar3d.hxx>
+#include <PUI/pu.h>
+#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
-#include <Time/event.h>
-#include <Time/fg_time.h>
-#include <Time/fg_timer.h>
+#include <Time/event.hxx>
+#include <Time/fg_time.hxx>
+#include <Time/fg_timer.hxx>
#include <Time/sunpos.hxx>
-#include <Weather/weather.h>
+#include <Weather/weather.hxx>
#include "GLUTkey.hxx"
#include "fg_init.hxx"
-#include "fg_getopt.h"
+#include "options.hxx"
+#include "splash.hxx"
#include "views.hxx"
// This is a record containing global housekeeping information
fgGENERAL general;
-// view parameters
-static GLfloat win_ratio = 1.0;
-static GLint winWidth, winHeight;
+// 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.
+static int idle_state = 0;
// Another hack
int use_signals = 0;
-// Yet another hack. This one used by the HUD code. Michele
-int show_hud;
+// Yet another hack, this time for the panel
+int panel_hist = 0;
+
+// Global structures for the Audio library
+#ifdef ENABLE_AUDIO_SUPPORT
+slEnvelope pitch_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
+slEnvelope volume_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
+slScheduler *audio_sched;
+smMixer *audio_mixer;
+slSample *s1;
+slSample *s2;
+#endif
-// Yet another other hack. Used for my prototype instrument code. (Durk)
-int displayInstruments;
// The following defines flight gear options. Because glutlib will also
// want to parse its own options, those options must not be included here
// option parser wants only initial characters followed by numbers
// or pathnames.
//
-const char *fg_cmdargopts = "a:c:Hhp:r:v:x:?";
-//
-// Where
-// -a aircraftfilename aircraft start over ride
-// -c0x0000 - 0xffffffff debug class setting
-// H,h.? help on command line use (does not need Option struct)
-// -p priority
-// -r flightgear root path to program support files
-// -v0 -v1 initial view mode (hud/no_hud currently)
-// -xlogpathname debug logfile name
-//
-// Defaults in arguments to indicate not set on command line.
-// Program defaults set variables from constants if neither command
-// options or environmental variables effect values.
-//
-
-char acArgbuf [ MAXPATH + 1] = "\0";
-int debugArgValue = -2;
-int priorityArgValue = -1;
-char rootArgbuf [ MAXPATH + 1] = "\0";
-int viewArg = -1;
-char logArgbuf [ MAXPATH + 1] = "\0";
-
-// There is a reason for defining the option structs by name and then
-// creating an array of pointers to options. C++ is unfriendly to
-// initializing arrays of objects that are not built in types. Always
-// look forward. (Besides, you can follow what is going on better and
-// add or modify with greater security. -ch
-//
-Option aircraftOption = { 'a',
- OPT_STRING,
- acArgbuf,
- "Startup aircraft pathname override"
- };
-Option debugOption = { 'c',
- OPT_LHEX, // Long int (32 bits)
- &debugArgValue,
- "Debug trace level"
- };
-Option priorityOption = { 'p',
- OPT_INTEGER,
- &priorityArgValue,
- "Debug priority Threshold"
- };
-Option rootOption = { 'r',
- OPT_STRING,
- rootArgbuf,
- "Root directory for execution"
- };
-Option hudOption = { 'v',
- OPT_INTEGER,
- &viewArg,
- "View mode start" // Naked,HUD,Panel,Chase,Tower...
- };
-
-// Only naked view and HUD are implemented at this time
-Option logfileOption = { 'x',
- OPT_STRING,
- logArgbuf,
- "Debug log file name"
- };
-
-#define OptsDefined 6
-Option *CmdLineOptions[ OptsDefined ] = {
- &aircraftOption,
- &debugOption,
- &hudOption,
- &priorityOption,
- &rootOption,
- &logfileOption
- };
-
-const char *DefaultRootDir = "\\Flightgear";
-const char *DefaultAircraft = "Navion.acf";
-const char *DefaultDebuglog = "fgdebug.log";
-const int DefaultViewMode = HUD_VIEW;
-
-// Debug defaults handled in fg_debug.c
+
// fgInitVisuals() -- Initialize various GL/view parameters
static void fgInitVisuals( void ) {
- struct fgLIGHT *l;
+ fgLIGHT *l;
struct fgWEATHER *w;
l = &cur_light_params;
w = ¤t_weather;
- // xglDisable( GL_DITHER );
+ // Go full screen if requested ...
+ if ( current_options.get_fullscreen() ) {
+ glutFullScreen();
+ }
// If enabled, normal vectors specified with glNormal are scaled
// to unit length after transformation. See glNormal.
- xglEnable( GL_NORMALIZE );
+ // xglEnable( GL_NORMALIZE );
xglEnable( GL_LIGHTING );
xglEnable( GL_LIGHT0 );
xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
- xglFogi (GL_FOG_MODE, GL_LINEAR);
- xglFogf (GL_FOG_START, 10.0);
- xglFogf (GL_FOG_END, w->visibility);
- // xglFogf (GL_FOG_DENSITY, w->visibility);
- xglHint (GL_FOG_HINT, GL_NICEST /* GL_FASTEST */ );
-
- // draw wire frame
- // xglPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
-}
+ // xglFogi (GL_FOG_MODE, GL_LINEAR);
+ xglFogi (GL_FOG_MODE, GL_EXP2);
+ // Fog density is now set when the weather system is initialized
+ // xglFogf (GL_FOG_DENSITY, w->fog_density);
+ if ( (current_options.get_fog() == 1) ||
+ (current_options.get_shading() == 0) ) {
+ // if fastest fog requested, or if flat shading force fastest
+ xglHint ( GL_FOG_HINT, GL_FASTEST );
+ } else if ( current_options.get_fog() == 2 ) {
+ xglHint ( GL_FOG_HINT, GL_NICEST );
+ }
+ if ( current_options.get_wireframe() ) {
+ // draw wire frame
+ xglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ }
+ // This is the default anyways, but it can't hurt
+ xglFrontFace ( GL_CCW );
-// Update the view volume, position, and orientation
-static void fgUpdateViewParams( void ) {
- fgFLIGHT *f;
- struct fgLIGHT *l;
- // struct fgTIME *t;
- struct fgVIEW *v;
+ // Just testing ...
+ // xglEnable(GL_POINT_SMOOTH);
+ // xglEnable(GL_LINE_SMOOTH);
+ // xglEnable(GL_POLYGON_SMOOTH);
+}
- f = current_aircraft.flight;
- l = &cur_light_params;
- // t = &cur_time_params;
- v = ¤t_view;
- fgViewUpdate(f, v, l);
+#ifdef IS_THIS_BETTER_THAN_A_ZERO_CHARLIE
+// Draw a basic instrument panel
+static void fgUpdateInstrViewParams( void ) {
- if (displayInstruments) {
- xglViewport( 0, (GLint)(winHeight / 2 ) ,
- (GLint)winWidth, (GLint)winHeight / 2 );
- // Tell GL we are about to modify the projection parameters
- xglMatrixMode(GL_PROJECTION);
- xglLoadIdentity();
- gluPerspective(65.0, 2.0/win_ratio, 1.0, 100000.0);
- } else {
- xglViewport(0, 0 , (GLint)winWidth, (GLint) winHeight);
- // Tell GL we are about to modify the projection parameters
- xglMatrixMode(GL_PROJECTION);
- xglLoadIdentity();
- gluPerspective(65.0, 1.0/win_ratio, 10.0, 100000.0);
- }
+ exit(0);
- xglMatrixMode(GL_MODELVIEW);
- xglLoadIdentity();
-
- // set up our view volume (default)
- gluLookAt(v->view_pos.x, v->view_pos.y, v->view_pos.z,
- v->view_pos.x + v->view_forward[0],
- v->view_pos.y + v->view_forward[1],
- v->view_pos.z + v->view_forward[2],
- v->view_up[0], v->view_up[1], v->view_up[2]);
-
- // look almost straight up (testing and eclipse watching)
- /* gluLookAt(v->view_pos.x, v->view_pos.y, v->view_pos.z,
- v->view_pos.x + v->view_up[0] + .001,
- v->view_pos.y + v->view_up[1] + .001,
- v->view_pos.z + v->view_up[2] + .001,
- v->view_up[0], v->view_up[1], v->view_up[2]); */
-
- // lock view horizontally towards sun (testing)
- /* gluLookAt(v->view_pos.x, v->view_pos.y, v->view_pos.z,
- v->view_pos.x + v->surface_to_sun[0],
- v->view_pos.y + v->surface_to_sun[1],
- v->view_pos.z + v->surface_to_sun[2],
- v->view_up[0], v->view_up[1], v->view_up[2]); */
-
- // lock view horizontally towards south (testing)
- /* gluLookAt(v->view_pos.x, v->view_pos.y, v->view_pos.z,
- v->view_pos.x + v->surface_south[0],
- v->view_pos.y + v->surface_south[1],
- v->view_pos.z + v->surface_south[2],
- v->view_up[0], v->view_up[1], v->view_up[2]); */
-
- // set the sun position
- xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
-}
+ fgVIEW *v;
+ v = ¤t_view;
-// Draw a basic instrument panel
-static void fgUpdateInstrViewParams( void ) {
- xglViewport(0, 0 , (GLint)winWidth, (GLint)winHeight / 2);
+ xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
xglMatrixMode(GL_PROJECTION);
xglPushMatrix();
xglMatrixMode(GL_MODELVIEW);
xglPopMatrix();
}
+#endif
// Update all Visuals (redraws anything graphics related)
static void fgRenderFrame( void ) {
- struct fgLIGHT *l;
- struct fgTIME *t;
- struct fgVIEW *v;
+ fgFLIGHT *f;
+ fgLIGHT *l;
+ fgTIME *t;
+ fgVIEW *v;
double angle;
+ static int iteration = 0;
+ // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
- GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
+ GLbitfield clear_mask;
+ f = current_aircraft.flight;
l = &cur_light_params;
t = &cur_time_params;
v = ¤t_view;
- // update view volume parameters
- fgUpdateViewParams();
+ if ( idle_state != 1000 ) {
+ // still initializing, draw the splash screen
+ if ( current_options.get_splash_screen() == 1 ) {
+ fgSplashUpdate(0.0);
+ }
+ } else {
+ // 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.
- xglClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
+ // printf("Ground = %.2f Altitude = %.2f\n", scenery.cur_elev,
+ // FG_Altitude * FEET_TO_METER);
+
+ // this is just a temporary hack, to make me understand Pui
+ // timerText -> setLabel (ctime (&t->cur_time));
+ // end of hack
- // Tell GL we are switching to model view parameters
- xglMatrixMode(GL_MODELVIEW);
- // xglLoadIdentity();
+ // update view volume parameters
+ v->UpdateViewParams();
- // draw sky
- xglDisable( GL_DEPTH_TEST );
- xglDisable( GL_LIGHTING );
- xglDisable( GL_CULL_FACE );
- xglDisable( GL_FOG );
- xglShadeModel( GL_SMOOTH );
- fgSkyRender();
+ clear_mask = GL_DEPTH_BUFFER_BIT;
+ if ( current_options.get_wireframe() ) {
+ clear_mask |= GL_COLOR_BUFFER_BIT;
+ }
+ if ( current_options.get_panel_status() ) {
+ // we can't clear the screen when the panel is active
+ } else if ( current_options.get_skyblend() ) {
+ if ( current_options.get_textures() ) {
+ // glClearColor(black[0], black[1], black[2], black[3]);
+ glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
+ l->adj_fog_color[2], l->adj_fog_color[3]);
+ clear_mask |= GL_COLOR_BUFFER_BIT;
+ }
+ } else {
+ glClearColor(l->sky_color[0], l->sky_color[1],
+ l->sky_color[2], l->sky_color[3]);
+ clear_mask |= GL_COLOR_BUFFER_BIT;
+ }
+ xglClear( clear_mask );
+
+ // Tell GL we are switching to model view parameters
+ xglMatrixMode(GL_MODELVIEW);
+ // xglLoadIdentity();
+
+ // draw sky
+ xglDisable( GL_DEPTH_TEST );
+ xglDisable( GL_LIGHTING );
+ xglDisable( GL_CULL_FACE );
+ xglDisable( GL_FOG );
+ xglShadeModel( GL_SMOOTH );
+ if ( current_options.get_skyblend() ) {
+ fgSkyRender();
+ }
- // setup transformation for drawing astronomical objects
- xglPushMatrix();
- // Translate to view position
- xglTranslatef( v->view_pos.x, v->view_pos.y, v->view_pos.z );
- // Rotate based on gst (sidereal time)
- angle = t->gst * 15.041085; /* should be 15.041085, Curt thought it was 15*/
- // printf("Rotating astro objects by %.2f degrees\n",angle);
- xglRotatef( angle, 0.0, 0.0, -1.0 );
+ // setup transformation for drawing astronomical objects
+ xglPushMatrix();
+ // Translate to view position
+ xglTranslatef( v->view_pos.x(), v->view_pos.y(), v->view_pos.z() );
+ // Rotate based on gst (sidereal time)
+ // note: constant should be 15.041085, Curt thought it was 15
+ angle = t->gst * 15.041085;
+ // printf("Rotating astro objects by %.2f degrees\n",angle);
+ xglRotatef( angle, 0.0, 0.0, -1.0 );
+
+ // draw stars and planets
+ fgStarsRender();
+ SolarSystem::theSolarSystem->draw();
+
+ xglPopMatrix();
+
+ // draw scenery
+ if ( current_options.get_shading() ) {
+ xglShadeModel( GL_SMOOTH );
+ } else {
+ xglShadeModel( GL_FLAT );
+ }
+ xglEnable( GL_DEPTH_TEST );
+ if ( current_options.get_fog() > 0 ) {
+ xglEnable( GL_FOG );
+ xglFogfv (GL_FOG_COLOR, l->adj_fog_color);
+ }
+ // set lighting parameters
+ xglLightfv(GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
+ xglLightfv(GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
+
+ if ( current_options.get_textures() ) {
+ // texture parameters
+ xglEnable( GL_TEXTURE_2D );
+ xglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
+ xglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
+ // set base color (I don't think this is doing anything here)
+ xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
+ xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
+ } else {
+ xglDisable( GL_TEXTURE_2D );
+ xglMaterialfv (GL_FRONT, GL_AMBIENT, terrain_color);
+ xglMaterialfv (GL_FRONT, GL_DIFFUSE, terrain_color);
+ // xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
+ // xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
+ }
- // draw stars and planets
- fgStarsRender();
- fgPlanetsRender();
+ fgTileMgrRender();
- // draw the sun
- fgSunRender();
+ xglDisable( GL_TEXTURE_2D );
- // render the moon
- xglEnable( GL_LIGHTING );
- // set lighting parameters
- xglLightfv(GL_LIGHT0, GL_AMBIENT, white );
- xglLightfv(GL_LIGHT0, GL_DIFFUSE, white );
- xglEnable( GL_CULL_FACE );
-
- // Let's try some blending technique's (Durk)
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
- fgMoonRender();
- glDisable(GL_BLEND);
-
- xglPopMatrix();
-
- // draw scenery
- xglShadeModel( /* GL_FLAT */ GL_SMOOTH );
- xglEnable( GL_DEPTH_TEST );
- xglEnable( GL_FOG );
- xglFogfv (GL_FOG_COLOR, l->fog_color);
- // set lighting parameters
- xglLightfv(GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
- xglLightfv(GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
- // texture parameters
- xglEnable( GL_TEXTURE_2D ); /* xglDisable( GL_TEXTURE_2D ); */
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) ;
- xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_LINEAR /* GL_LINEAR_MIPMAP_LINEAR */ ) ;
- xglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
- xglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
- // set base color (I don't think this is doing anything here)
- xglColor4fv(white);
-
- fgTileMgrRender();
-
- xglDisable( GL_TEXTURE_2D );
-
- // display HUD
- if( show_hud ) {
- fgCockpitUpdate();
- }
+ if ( (iteration == 0) && (current_options.get_panel_status()) ) {
+ // Did we run this loop before ?? ...and do we need the panel ??
+ fgPanelReInit();
+ }
- // display instruments
- if (displayInstruments) {
- fgUpdateInstrViewParams();
+ // display HUD && Panel
+ if ( current_options.get_panel_status() ) {
+ xglViewport(0, 0, v->winWidth, v->winHeight);
+ }
+ fgCockpitUpdate();
+ iteration = 1; // don't ReInit the panel in the future
+
+ // We can do translucent menus, so why not. :-)
+ xglEnable ( GL_BLEND ) ;
+ xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+ puDisplay();
+ xglDisable ( GL_BLEND ) ;
}
xglutSwapBuffers();
// Update internal time dependent calculations (i.e. flight model)
void fgUpdateTimeDepCalcs(int multi_loop) {
fgFLIGHT *f;
- struct fgTIME *t;
- struct fgVIEW *v;
+ fgLIGHT *l;
+ fgTIME *t;
+ fgVIEW *v;
int i;
f = current_aircraft.flight;
+ l = &cur_light_params;
t = &cur_time_params;
v = ¤t_view;
multi_loop = DEFAULT_MULTILOOP;
}
- // printf("updating flight model x %d\n", multi_loop);
- fgFlightModelUpdate(FG_LARCSIM, f, multi_loop);
+ if ( !t->pause ) {
+ // run Autopilot system
+ fgAPRun();
+
+ // printf("updating flight model x %d\n", multi_loop);
+ fgFlightModelUpdate(current_options.get_flight_model(), f, multi_loop);
+ } else {
+ fgFlightModelUpdate(current_options.get_flight_model(), f, 0);
+ }
// update the view angle
for ( i = 0; i < multi_loop; i++ ) {
}
}
}
+
+ double tmp = -(l->sun_rotation + FG_PI) - (FG_Psi - v->view_offset);
+ while ( tmp < 0.0 ) {
+ tmp += FG_2PI;
+ }
+ while ( tmp > FG_2PI ) {
+ tmp -= FG_2PI;
+ }
+ /* printf("Psi = %.2f, viewoffset = %.2f sunrot = %.2f rottosun = %.2f\n",
+ FG_Psi * RAD_TO_DEG, v->view_offset * RAD_TO_DEG,
+ -(l->sun_rotation+FG_PI) * RAD_TO_DEG, tmp * RAD_TO_DEG); */
+ l->UpdateAdjFog();
}
}
+static const double alt_adjust_ft = 3.758099;
+static const double alt_adjust_m = alt_adjust_ft * FEET_TO_METER;
-// Scenery management routines
-
-/* static void fgSceneryInit_OLD() { */
- /* make scenery */
-/* scenery = fgSceneryCompile_OLD();
- runway = fgRunwayHack_OLD(0.69, 53.07);
-} */
-
-
-/* create the scenery */
-/* GLint fgSceneryCompile_OLD() {
- GLint scenery;
-
- scenery = mesh2GL(mesh_ptr_OLD);
-
- return(scenery);
-}
-*/
-
-/* hack in a runway */
-/* GLint fgRunwayHack_OLD(double width, double length) {
- static GLfloat concrete[4] = { 0.5, 0.5, 0.5, 1.0 };
- static GLfloat line[4] = { 0.9, 0.9, 0.9, 1.0 };
- int i;
- int num_lines = 16;
- float line_len, line_width_2, cur_pos;
-
- runway = xglGenLists(1);
- xglNewList(runway, GL_COMPILE);
- */
- /* draw concrete */
-/* xglBegin(GL_POLYGON);
- xglMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, concrete );
- xglNormal3f(0.0, 0.0, 1.0);
-
- xglVertex3d( 0.0, -width/2.0, 0.0);
- xglVertex3d( 0.0, width/2.0, 0.0);
- xglVertex3d(length, width/2.0, 0.0);
- xglVertex3d(length, -width/2.0, 0.0);
- xglEnd();
- */
- /* draw center line */
-/* xglMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, line );
- line_len = length / ( 2 * num_lines + 1);
- printf("line_len = %.3f\n", line_len);
- line_width_2 = 0.02;
- cur_pos = line_len;
- for ( i = 0; i < num_lines; i++ ) {
- xglBegin(GL_POLYGON);
- xglVertex3d( cur_pos, -line_width_2, 0.005);
- xglVertex3d( cur_pos, line_width_2, 0.005);
- cur_pos += line_len;
- xglVertex3d( cur_pos, line_width_2, 0.005);
- xglVertex3d( cur_pos, -line_width_2, 0.005);
- cur_pos += line_len;
- xglEnd();
- }
-
- xglEndList();
-
- return(runway);
-}
-*/
-
-/* draw the scenery */
-/*static void fgSceneryDraw_OLD() {
- static float z = 32.35;
-
- xglPushMatrix();
-
- xglCallList(scenery);
-
- printf("*** Drawing runway at %.2f\n", z);
-
- xglTranslatef( -398391.28, 120070.41, 32.35);
- xglRotatef(170.0, 0.0, 0.0, 1.0);
- xglCallList(runway);
-
- xglPopMatrix();
-}
-*/
-
-
-// What should we do when we have nothing else to do? How about get
-// ready for the next move and update the display?
+// What should we do when we have nothing else to do? Let's get ready
+// for the next move and update the display?
static void fgMainLoop( void ) {
+ fgFLIGHT *f;
+ fgGENERAL *g;
+ fgTIME *t;
static int remainder = 0;
int elapsed, multi_loop;
- double cur_elev;
- // double joy_x, joy_y;
- // int joy_b1, joy_b2;
- fgAIRCRAFT *a;
- fgFLIGHT *f;
- struct fgTIME *t;
-
- fgPrintf( FG_ALL, FG_DEBUG, "Running Main Loop\n");
- fgPrintf( FG_ALL, FG_DEBUG, "======= ==== ====\n");
+ int i;
+ double accum;
- a = ¤t_aircraft;
- f = a->flight;
+ f = current_aircraft.flight;
+ g = &general;
t = &cur_time_params;
+ FG_LOG( FG_ALL, FG_DEBUG, "Running Main Loop");
+ FG_LOG( FG_ALL, FG_DEBUG, "======= ==== ====");
+
+ fgWeatherUpdate();
+
+ // Fix elevation. I'm just sticking this here for now, it should
+ // probably move eventually
+
+ /* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
+ scenery.cur_elev,
+ FG_Runway_altitude * FEET_TO_METER,
+ FG_Altitude * FEET_TO_METER); */
+
+ if ( scenery.cur_elev > -9990 ) {
+ if ( FG_Altitude * FEET_TO_METER <
+ (scenery.cur_elev + alt_adjust_m - 3.0) ) {
+ // now set aircraft altitude above ground
+ printf("Current Altitude = %.2f < %.2f forcing to %.2f\n",
+ FG_Altitude * FEET_TO_METER,
+ scenery.cur_elev + alt_adjust_m - 3.0,
+ scenery.cur_elev + alt_adjust_m );
+ fgFlightModelSetAltitude( current_options.get_flight_model(), f,
+ scenery.cur_elev + alt_adjust_m );
+
+ FG_LOG( FG_ALL, FG_BULK,
+ "<*> resetting altitude to "
+ << FG_Altitude * FEET_TO_METER << " meters" );
+ }
+ FG_Runway_altitude = scenery.cur_elev * METER_TO_FEET;
+ }
+
+ /* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
+ scenery.cur_elev,
+ FG_Runway_altitude * FEET_TO_METER,
+ FG_Altitude * FEET_TO_METER); */
+
// update "time"
fgTimeUpdate(f, t);
- // Read joystick
- /* fgJoystickRead( &joy_x, &joy_y, &joy_b1, &joy_b2 );
- printf( "Joystick X %f Y %f B1 %d B2 %d\n",
- joy_x, joy_y, joy_b1, joy_b2 );
- fgElevSet( -joy_y );
- fgAileronSet( joy_x ); */
+#if defined( ENABLE_LINUX_JOYSTICK )
+ // Read joystick and update control settings
+ fgJoystickRead();
+#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
- // Calculate model iterations needed
+ // Get elapsed time for this past frame
elapsed = fgGetTimeInterval();
- fgPrintf( FG_ALL, FG_BULK,
- "Time interval is = %d, previous remainder is = %d\n",
- elapsed, remainder);
- fgPrintf( FG_ALL, FG_BULK,
- "--> Frame rate is = %.2f\n", 1000.0 / (float)elapsed);
+ FG_LOG( FG_ALL, FG_BULK,
+ "Time interval is = " << elapsed
+ << ", previous remainder is = " << remainder );
+
+ // Calculate frame rate average
+ if ( elapsed > 0.0 ) {
+ accum = 0.0;
+ for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
+ accum += g->frames[i];
+ // printf("frame[%d] = %.2f\n", i, g->frames[i]);
+ g->frames[i+1] = g->frames[i];
+ }
+ g->frames[0] = 1000.0 / (float)elapsed;
+ // printf("frame[0] = %.2f\n", g->frames[0]);
+ accum += g->frames[0];
+ g->frame_rate = accum / (float)FG_FRAME_RATE_HISTORY;
+ // printf("ave = %.2f\n", g->frame_rate);
+ }
+
+ // Calculate model iterations needed for next frame
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "--> Frame rate is = " << g->frame_rate );
elapsed += remainder;
multi_loop = (int)(((float)elapsed * 0.001) * DEFAULT_MODEL_HZ);
remainder = elapsed - ((multi_loop*1000) / DEFAULT_MODEL_HZ);
- fgPrintf( FG_ALL, FG_BULK,
- "Model iterations needed = %d, new remainder = %d\n",
- multi_loop, remainder);
+ FG_LOG( FG_ALL, FG_BULK,
+ "Model iterations needed = " << multi_loop
+ << ", new remainder = " << remainder );
+ /* printf("right before fm - ground = %.2f runway = %.2f alt = %.2f\n",
+ scenery.cur_elev,
+ FG_Runway_altitude * FEET_TO_METER,
+ FG_Altitude * FEET_TO_METER); */
+
// Run flight model
if ( ! use_signals ) {
// flight model
fgUpdateTimeDepCalcs(multi_loop);
}
- // I'm just sticking this here for now, it should probably move
- // eventually
- /* cur_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC,
- FG_Latitude * RAD_TO_ARCSEC); */
- // there is no ground collision detection really, so for now I
- // just hard code the ground elevation to be 0 */
- cur_elev = 0;
-
- // printf("Ground elevation is %.2f meters here.\n", cur_elev);
- // FG_Runway_altitude = cur_elev * METER_TO_FEET;
-
- if ( FG_Altitude * FEET_TO_METER < cur_elev + 3.758099) {
- // set this here, otherwise if we set runway height above our
- // current height we get a really nasty bounce.
- FG_Runway_altitude = FG_Altitude - 3.758099;
-
- // now set aircraft altitude above ground
- FG_Altitude = cur_elev * METER_TO_FEET + 3.758099;
- fgPrintf( FG_ALL, FG_BULK, "<*> resetting altitude to %.0f meters\n",
- FG_Altitude * FEET_TO_METER);
- }
+ /* printf("After fm - ground = %.2f runway = %.2f alt = %.2f\n",
+ scenery.cur_elev,
+ FG_Runway_altitude * FEET_TO_METER,
+ FG_Altitude * FEET_TO_METER); */
- fgAircraftOutputCurrent(a);
+ // fgAircraftOutputCurrent(a);
// see if we need to load any new scenery tiles
fgTileMgrUpdate();
// Process/manage pending events
- fgEventProcess();
+ global_events.Process();
+
+ // Run audio scheduler
+#ifdef ENABLE_AUDIO_SUPPORT
+ if ( current_options.get_sound() && audio_sched->working() ) {
+ double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
+
+ pitch_envelope.setStep ( 0, 0.01, param );
+ volume_envelope.setStep ( 0, 0.01, param );
+
+ audio_sched -> update();
+ }
+#endif
// redraw display
fgRenderFrame();
- fgPrintf( FG_ALL, FG_DEBUG, "\n");
+ FG_LOG( FG_ALL, FG_DEBUG, "" );
+}
+
+
+// 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 ) {
+ fgGENERAL *g;
+ g = &general;
+
+ // printf("idle state == %d\n", idle_state);
+
+ if ( idle_state == 0 ) {
+ // Initialize the splash screen right away
+ if ( current_options.get_splash_screen() ) {
+ fgSplashInit();
+ }
+
+ idle_state++;
+ } else if ( idle_state == 1 ) {
+ // Start the intro music
+#if !defined(WIN32)
+ if ( current_options.get_intro_music() ) {
+ string lockfile = "/tmp/mpg123.running";
+ string mp3file = current_options.get_fg_root() +
+ "/Sounds/intro.mp3";
+ string command = "(touch " + lockfile + "; mpg123 " + mp3file +
+ "> /dev/null 2>&1; /bin/rm " + lockfile + ") &";
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "Starting intro music: " << mp3file );
+ system ( command.c_str() );
+ }
+#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.
+
+#ifdef USE_GLIDE
+ if ( strstr ( g->glRenderer, "Glide" ) ) {
+ 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()) {
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "Subsystem initializations failed ..." );
+ exit(-1);
+ }
+
+ 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
+#ifdef ENABLE_AUDIO_SUPPORT
+
+#if !defined(WIN32)
+ if ( current_options.get_intro_music() ) {
+ // Let's wait for mpg123 to finish
+ string lockfile = "/tmp/mpg123.running";
+ struct stat stat_buf;
+
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "Waiting for mpg123 player to finish ..." );
+ while ( stat(lockfile.c_str(), &stat_buf) == 0 ) {
+ // file exist, wait ...
+ sleep(1);
+ FG_LOG( FG_GENERAL, FG_INFO, ".");
+ }
+ FG_LOG( FG_GENERAL, FG_INFO, "");
+ }
+#endif // WIN32
+
+ audio_sched = new slScheduler ( 8000 );
+ audio_mixer = new smMixer;
+ audio_mixer -> setMasterVolume ( 50 ) ; /* 80% of max volume. */
+ audio_sched -> setSafetyMargin ( 1.0 ) ;
+ string slfile = current_options.get_fg_root() + "/Sounds/wasp.wav";
+
+ s1 = new slSample ( (char *)slfile.c_str() );
+ printf("Rate = %d Bps = %d Stereo = %d\n",
+ s1 -> getRate(), s1 -> getBps(), s1 -> getStereo());
+ audio_sched -> loopSample ( s1 );
+
+ if ( audio_sched->working() ) {
+ 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 );
+ }
+
+ // strcpy(slfile, path);
+ // strcat(slfile, "thunder.wav");
+ // s2 -> loadFile ( slfile );
+ // s2 -> adjustVolume(0.5);
+ // audio_sched -> playSample ( s2 );
+#endif
+
+ // sleep(1);
+ idle_state = 1000;
+ }
+
+ if ( idle_state == 1000 ) {
+ // We've finished all our initialization steps, from now on we
+ // run the main loop.
+
+ fgMainLoop();
+ } else {
+ if ( current_options.get_splash_screen() == 1 ) {
+ fgSplashUpdate(0.0);
+ }
+ }
}
// Handle new window size or exposure
static void fgReshape( int width, int height ) {
+ fgVIEW *v;
+
+ v = ¤t_view;
+
// Do this so we can call fgReshape(0,0) ourselves without having
// to know what the values of width & height are.
if ( (height > 0) && (width > 0) ) {
- win_ratio = (GLfloat) height / (GLfloat) width;
+ if ( ! current_options.get_panel_status() ) {
+ v->win_ratio = (GLfloat) width / (GLfloat) height;
+ } else {
+ v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.67);
+ }
}
- winWidth = width;
- winHeight = height;
+ v->winWidth = width;
+ v->winHeight = height;
// Inform gl of our view window size (now handled elsewhere)
// xglViewport(0, 0, (GLint)width, (GLint)height);
- fgUpdateViewParams();
+ 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.
+ v->UpdateViewParams();
+ if ( current_options.get_panel_status() ) {
+ fgPanelReInit();
+ }
+ }
// xglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
-// Main ...
-int main( int argc, char *argv[] ) {
- fgFLIGHT *f;
- int parse_result; // Used in command line argument.
-
- f = current_aircraft.flight;
- // First things first... We must have startup options dealt with.
-
- printf("Flight Gear: Version %s\n\n", VERSION);
-
- // Initialize the Window/Graphics environment.
-
- // initialize GLUT
- xglutInit(&argc, argv);
+// Initialize GLUT and define a main window
+int fgGlutInit( int *argc, char **argv ) {
+ // GLUT will extract all glut specific options so later on we only
+ // need wory about our own.
+ xglutInit(argc, argv);
// Define Display Parameters
- xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+ if ( ! current_options.get_panel_status() ) {
+ xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+ } else {
+ xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE |
+ GLUT_STENCIL);
+ }
// Define initial window size
xglutInitWindowSize(640, 480);
// Initialize windows
- xglutCreateWindow("Flight Gear");
-
- // xglutInit above will extract all non-general program command line.
- // We only need wory about our own.
-
- parse_result = getargs( argc, argv, OptsDefined, CmdLineOptions, NULL);
+ if ( current_options.get_game_mode() == 0 ) {
+ // Open the regular window
+ xglutCreateWindow("Flight Gear");
+ } else {
+ // Open the cool new 'game mode' window
+ glutGameModeString("width=640 height=480 bpp=16");
+ glutEnterGameMode();
+ }
- switch( parse_result ) {
- case ALLDONE:
- break;
+ return(1);
+}
- case HELP:
- print_desc( OptsDefined, CmdLineOptions );
- exit(0);
- case INVALID:
- default:
- printf( "Flight Gear: Command line invalid.");
- exit(0);
- }
+// Initialize GLUT event handlers
+int fgGlutInitEvents( void ) {
+ // call fgReshape() on window resizes
+ xglutReshapeFunc( fgReshape );
- // Deal with the effects of options no set by manipulating the command
- // line, or possibly set to invalid states.
+ // call GLUTkey() on keyboard event
+ xglutKeyboardFunc( GLUTkey );
+ glutSpecialFunc( GLUTspecialkey );
- if(( viewArg >= 0) && (viewArg <= 1)) {
- show_hud = viewArg; // For now view_mode TRUE - no HUD, else show_hud.
- } else {
- show_hud = DefaultViewMode;
- }
+ // call guiMouseFunc() whenever our little rodent is used
+ glutMouseFunc ( guiMouseFunc );
+ glutMotionFunc (guiMotionFunc );
+ glutPassiveMotionFunc (guiMotionFunc );
- // All other command line option responses are handled in the various
- // initialization routines (or ignored if not implemented.
+ // call fgMainLoop() whenever there is
+ // nothing else to do
+ xglutIdleFunc( fgIdleFunction );
- // This is the general house keeping init routine. It initializes the
- // debug trail scheme and then any other stuff.
+ // draw the scene
+ xglutDisplayFunc( fgRenderFrame );
- if( !fgInitGeneral()) {
+ return(1);
+}
- // 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()) {
- // setup view parameters, only makes GL calls
- fgInitVisuals();
+// Main ...
+int main( int argc, char **argv ) {
+ fgFLIGHT *f;
- if ( use_signals ) {
- // init timer routines, signals, etc. Arrange for an
- // alarm signal to be generated, etc.
- fgInitTimeDepCalcs();
- }
+ f = current_aircraft.flight;
- // Initialize the GLUT Event Handlers.
+#ifdef HAVE_BC5PLUS
+ _control87(MCW_EM, MCW_EM); /* defined in float.h */
+#endif
- // call fgReshape() on window resizes
- xglutReshapeFunc( fgReshape );
+ // Initialize the [old] debugging output system
+ // fgInitDebug();
- // call key() on keyboard event
- xglutKeyboardFunc( GLUTkey );
- glutSpecialFunc( GLUTspecialkey );
+ FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear: Version" << VERSION << endl );
- // call fgMainLoop() whenever there is
- // nothing else to do
- xglutIdleFunc( fgMainLoop );
+ // Attempt to locate and parse a config file
+ // First check fg_root
+ string config = current_options.get_fg_root() + "/system.fgfsrc";
+ current_options.parse_config_file( config );
- // draw the scene
- xglutDisplayFunc( fgRenderFrame );
+ // Next check home directory
+ char* envp = ::getenv( "HOME" );
+ if ( envp != NULL ) {
+ config = envp;
+ config += "/.fgfsrc";
+ current_options.parse_config_file( config );
+ }
- // pass control off to the GLUT event handler
- glutMainLoop();
+ // Parse remaining command line options
+ // These will override anything specified in a config file
+ if ( current_options.parse_command_line(argc, argv) !=
+ fgOPTIONS::FG_OPTIONS_OK )
+ {
+ // Something must have gone horribly wrong with the command
+ // line parsing or maybe the user just requested help ... :-)
+ current_options.usage();
+ FG_LOG( FG_GENERAL, FG_ALERT, "\nExiting ...");
+ exit(-1);
+ }
+
+ // Initialize the Window/Graphics environment.
+ if( !fgGlutInit(&argc, argv) ) {
+ FG_LOG( FG_GENERAL, FG_ALERT, "GLUT initialization failed ..." );
+ exit(-1);
+ }
- } // End if subsystems initialize ok
- } // End if general initializations went ok
+ // Initialize the various GLUT Event Handlers.
+ if( !fgGlutInitEvents() ) {
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "GLUT event handler initialization failed ..." );
+ exit(-1);
+ }
- if( fg_DebugOutput ) {
- fclose( fg_DebugOutput );
+ // First do some quick general initializations
+ if( !fgInitGeneral()) {
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "General initializations failed ..." );
+ exit(-1);
}
- return(0);
-}
+ // Init the user interface (we need to do this before passing off
+ // control to glut
+ guiInit();
-#ifdef __SUNPRO_CC
-extern "C" {
- void __eprintf( void ) {
- }
+ // pass control off to the master GLUT event handler
+ glutMainLoop();
+
+ // we never actually get here ... but just in case ... :-)
+ return(0);
}
-#endif
// $Log$
+// Revision 1.63 1998/11/06 21:18:08 curt
+// Converted to new logstream debugging facility. This allows release
+// builds with no messages at all (and no performance impact) by using
+// the -DFG_NDEBUG flag.
+//
+// Revision 1.62 1998/10/27 02:14:35 curt
+// Changes to support GLUT joystick routines as fall back.
+//
+// Revision 1.61 1998/10/25 14:08:47 curt
+// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
+//
+// Revision 1.60 1998/10/25 10:57:18 curt
+// Changes to use the new joystick library if it is available.
+//
+// Revision 1.59 1998/10/17 01:34:21 curt
+// C++ ifying ...
+//
+// Revision 1.58 1998/10/16 23:27:52 curt
+// C++-ifying.
+//
+// Revision 1.57 1998/10/16 00:54:00 curt
+// Converted to Point3D class.
+//
+// Revision 1.56 1998/10/02 12:46:47 curt
+// Added an "auto throttle"
+//
+// Revision 1.55 1998/09/29 14:58:18 curt
+// Use working() instead of !not_working() for audio.
+//
+// Revision 1.54 1998/09/29 02:03:38 curt
+// Autopilot mods.
+//
+// Revision 1.53 1998/09/26 13:18:35 curt
+// Check if audio "working()" before doing audio manipulations.
+//
+// Revision 1.52 1998/09/25 16:02:07 curt
+// Added support for pitch and volume envelopes and tied them to the
+// throttle setting.
+//
+// Revision 1.51 1998/09/15 04:27:28 curt
+// Changes for new Astro code.
+//
+// Revision 1.50 1998/09/15 02:09:24 curt
+// Include/fg_callback.hxx
+// Moved code inline to stop g++ 2.7 from complaining.
+//
+// Simulator/Time/event.[ch]xx
+// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
+// complain bitterly.
+//
+// Minor bugfix and changes.
+//
+// Simulator/Main/GLUTmain.cxx
+// Added missing type to idle_state definition - eliminates a warning.
+//
+// Simulator/Main/fg_init.cxx
+// Changes to airport lookup.
+//
+// Simulator/Main/options.cxx
+// Uses fg_gzifstream when loading config file.
+//
+// Revision 1.49 1998/09/09 16:25:39 curt
+// Only use GLUT_STENCIL if the instument panel has been requested.
+//
+// Revision 1.48 1998/08/28 18:15:03 curt
+// Added new cockpit code from Friedemann Reinhard
+// <mpt218@faupt212.physik.uni-erlangen.de>
+//
+// Revision 1.47 1998/08/27 17:02:04 curt
+// Contributions from Bernie Bright <bbright@c031.aone.net.au>
+// - use strings for fg_root and airport_id and added methods to return
+// them as strings,
+// - inlined all access methods,
+// - made the parsing functions private methods,
+// - deleted some unused functions.
+// - propogated some of these changes out a bit further.
+//
+// Revision 1.46 1998/08/22 14:49:56 curt
+// Attempting to iron out seg faults and crashes.
+// Did some shuffling to fix a initialization order problem between view
+// position, scenery elevation.
+//
+// Revision 1.45 1998/08/20 20:32:31 curt
+// Reshuffled some of the code in and around views.[ch]xx
+//
+// Revision 1.44 1998/08/20 15:10:33 curt
+// Added GameGLUT support.
+//
+// Revision 1.43 1998/08/12 21:01:47 curt
+// Master volume from 30% -> 80%
+//
+// Revision 1.42 1998/07/30 23:48:25 curt
+// Output position & orientation when pausing.
+// Eliminated libtool use.
+// Added options to specify initial position and orientation.
+// Changed default fov to 55 degrees.
+// Added command line option to start in paused or unpaused state.
+//
+// Revision 1.41 1998/07/27 18:41:24 curt
+// Added a pause command "p"
+// Fixed some initialization order problems between pui and glut.
+// Added an --enable/disable-sound option.
+//
+// Revision 1.40 1998/07/24 21:56:59 curt
+// Set near clip plane to 0.5 meters when close to the ground. Also, let the view get a bit closer to the ground before hitting the hard limit.
+//
+// Revision 1.39 1998/07/24 21:39:08 curt
+// Debugging output tweaks.
+// Cast glGetString to (char *) to avoid compiler errors.
+// Optimizations to fgGluLookAt() by Norman Vine.
+//
+// Revision 1.38 1998/07/22 21:40:43 curt
+// Clear to adjusted fog color (for sunrise/sunset effects)
+// Make call to fog sunrise/sunset adjustment method.
+// Add a stdc++ library bug work around to fg_init.cxx
+//
+// Revision 1.37 1998/07/20 12:49:44 curt
+// Tweaked color buffer clearing defaults. We clear the color buffer if we
+// are doing textures. Assumptions: If we are doing textures we have hardware
+// support that can clear the color buffer for "free." If we are doing software
+// rendering with textures, then the extra clear time gets lost in the noise.
+//
+// Revision 1.36 1998/07/16 17:33:35 curt
+// "H" / "h" now control hud brightness as well with off being one of the
+// states.
+// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
+// whether or not to build in the feature.
+// Translucent menu support.
+// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
+// Use fork() / wait() for playing mp3 init music in background under unix.
+// Changed default tile diameter to 5.
+//
+// Revision 1.35 1998/07/13 21:01:36 curt
+// Wrote access functions for current fgOPTIONS.
+//
+// Revision 1.34 1998/07/13 15:32:37 curt
+// Clear color buffer if drawing wireframe.
+// When specifying and airport, start elevation at -1000 and let the system
+// position you at ground level.
+//
+// Revision 1.33 1998/07/12 03:14:42 curt
+// Added ground collision detection.
+// Did some serious horsing around to be able to "hug" the ground properly
+// and still be able to take off.
+// Set the near clip plane to 1.0 meters when less than 10 meters above the
+// ground.
+// Did some serious horsing around getting the initial airplane position to be
+// correct based on rendered terrain elevation.
+// Added a little cheat/hack that will prevent the view position from ever
+// dropping below the terrain, even when the flight model doesn't quite
+// put you as high as you'd like.
+//
+// Revision 1.32 1998/07/08 14:45:07 curt
+// polar3d.h renamed to polar3d.hxx
+// vector.h renamed to vector.hxx
+// updated audio support so it waits to create audio classes (and tie up
+// /dev/dsp) until the mpg123 player is finished.
+//
+// Revision 1.31 1998/07/06 21:34:17 curt
+// Added an enable/disable splash screen option.
+// Added an enable/disable intro music option.
+// Added an enable/disable instrument panel option.
+// Added an enable/disable mouse pointer option.
+// Added using namespace std for compilers that support this.
+//
+// Revision 1.30 1998/07/06 02:42:03 curt
+// Added support for switching between fullscreen and window mode for
+// Mesa/3dfx/glide.
+//
+// Added a basic splash screen. Restructured the main loop and top level
+// initialization routines to do this.
+//
+// Hacked in some support for playing a startup mp3 sound file while rest
+// of sim initializes. Currently only works in Unix using the mpg123 player.
+// Waits for the mpg123 player to finish before initializing internal
+// sound drivers.
+//
+// Revision 1.29 1998/07/04 00:52:22 curt
+// Add my own version of gluLookAt() (which is nearly identical to the
+// Mesa/glu version.) But, by calculating the Model View matrix our selves
+// we can save this matrix without having to read it back in from the video
+// card. This hopefully allows us to save a few cpu cycles when rendering
+// out the fragments because we can just use glLoadMatrixd() with the
+// precalculated matrix for each tile rather than doing a push(), translate(),
+// pop() for every fragment.
+//
+// Panel status defaults to off for now until it gets a bit more developed.
+//
+// Extract OpenGL driver info on initialization.
+//
+// Revision 1.28 1998/06/27 16:54:32 curt
+// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
+// Don't change the view port when displaying the panel.
+//
+// Revision 1.27 1998/06/17 21:35:10 curt
+// Refined conditional audio support compilation.
+// Moved texture parameter setup calls to ../Scenery/materials.cxx
+// #include <string.h> before various STL includes.
+// Make HUD default state be enabled.
+//
+// Revision 1.26 1998/06/13 00:40:32 curt
+// Tweaked fog command line options.
+//
+// Revision 1.25 1998/06/12 14:27:26 curt
+// Pui -> PUI, Gui -> GUI.
+//
+// Revision 1.24 1998/06/12 00:57:39 curt
+// Added support for Pui/Gui.
+// Converted fog to GL_FOG_EXP2.
+// Link to static simulator parts.
+// Update runfg.bat to try to be a little smarter.
+//
+// Revision 1.23 1998/06/08 17:57:04 curt
+// Minor sound/startup position tweaks.
+//
+// Revision 1.22 1998/06/05 18:18:40 curt
+// A bit of fiddling with audio ...
+//
+// Revision 1.21 1998/06/03 22:01:06 curt
+// Tweaking sound library usage.
+//
+// Revision 1.20 1998/06/03 00:47:11 curt
+// Updated to compile in audio support if OSS available.
+// Updated for new version of Steve's audio library.
+// STL includes don't use .h
+// Small view optimizations.
+//
+// Revision 1.19 1998/06/01 17:54:40 curt
+// Added Linux audio support.
+// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
+// map stl tweaks.
+//
+// Revision 1.18 1998/05/29 20:37:19 curt
+// Tweaked material properties & lighting a bit in GLUTmain.cxx.
+// Read airport list into a "map" STL for dynamic list sizing and fast tree
+// based lookups.
+//
+// Revision 1.17 1998/05/22 21:28:52 curt
+// Modifications to use the new fgEVENT_MGR class.
+//
+// Revision 1.16 1998/05/20 20:51:33 curt
+// Tweaked smooth shaded texture lighting properties.
+// Converted fgLIGHT to a C++ class.
+//
+// Revision 1.15 1998/05/16 13:08:34 curt
+// C++ - ified views.[ch]xx
+// Shuffled some additional view parameters into the fgVIEW class.
+// Changed tile-radius to tile-diameter because it is a much better
+// name.
+// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
+// to transform world space to eye space for view frustum culling.
+//
+// Revision 1.14 1998/05/13 18:29:57 curt
+// Added a keyboard binding to dynamically adjust field of view.
+// Added a command line option to specify fov.
+// Adjusted terrain color.
+// Root path info moved to fgOPTIONS.
+// Added ability to parse options out of a config file.
+//
+// Revision 1.13 1998/05/11 18:18:15 curt
+// For flat shading use "glHint (GL_FOG_HINT, GL_FASTEST )"
+//
+// Revision 1.12 1998/05/07 23:14:15 curt
+// Added "D" key binding to set autopilot heading.
+// Made frame rate calculation average out over last 10 frames.
+// Borland C++ floating point exception workaround.
+// Added a --tile-radius=n option.
+//
+// Revision 1.11 1998/05/06 03:16:23 curt
+// Added an averaged global frame rate counter.
+// Added an option to control tile radius.
+//
+// Revision 1.10 1998/05/03 00:47:31 curt
+// Added an option to enable/disable full-screen mode.
+//
+// Revision 1.9 1998/04/30 12:34:17 curt
+// Added command line rendering options:
+// enable/disable fog/haze
+// specify smooth/flat shading
+// disable sky blending and just use a solid color
+// enable wireframe drawing mode
+//
+// Revision 1.8 1998/04/28 01:20:21 curt
+// Type-ified fgTIME and fgVIEW.
+// Added a command line option to disable textures.
+//
+// Revision 1.7 1998/04/26 05:10:02 curt
+// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
+//
+// Revision 1.6 1998/04/25 22:06:30 curt
+// Edited cvs log messages in source files ... bad bad bad!
+//
+// Revision 1.5 1998/04/25 20:24:01 curt
+// Cleaned up initialization sequence to eliminate interdependencies
+// between sun position, lighting, and view position. This creates a
+// valid single pass initialization path.
+//
+// Revision 1.4 1998/04/24 14:19:30 curt
+// Fog tweaks.
+//
+// Revision 1.3 1998/04/24 00:49:18 curt
+// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
+// Trying out some different option parsing code.
+// Some code reorganization.
+//
// Revision 1.2 1998/04/22 13:25:41 curt
// C++ - ifing the code.
// Starting a bit of reorganization of lighting code.
// Minor tweaks.
//
// Revision 1.52 1998/01/27 00:47:56 curt
-// Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
+// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
// system and commandline/config file processing code.
//
// Revision 1.51 1998/01/26 15:57:05 curt
// Changes due to changing sunpos interface.
//
// Revision 1.5 1997/08/06 21:08:32 curt
-// Sun position now//really* works (I think) ... I still have sun time warping
+// Sun position now really* works (I think) ... I still have sun time warping
// code in place, probably should remove it soon.
//
// Revision 1.4 1997/08/06 15:41:26 curt