-
-//
// 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
// $Id$
// (Log is kept at end of this file)
+#define MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
#ifdef HAVE_CONFIG_H
# include <config.h>
#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 <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/fg_debug.h>
+#include <Debug/logstream.hxx>
#include <GUI/gui.h>
-#include <Joystick/joystick.h>
-#include <Math/fg_geodesy.h>
+#include <Joystick/joystick.hxx>
+#include <Math/fg_geodesy.hxx>
#include <Math/mat3.h>
#include <Math/polar3d.hxx>
#include <PUI/pu.h>
#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"
// 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;
}
-#ifdef IS_THIS_BETTER_THAN_A_ZERO_CHARLIE
+#if 0
// Draw a basic instrument panel
static void fgUpdateInstrViewParams( void ) {
// Update all Visuals (redraws anything graphics related)
static void fgRenderFrame( void ) {
- fgFLIGHT *f;
+ FGState *f;
fgLIGHT *l;
fgTIME *t;
fgVIEW *v;
GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
GLbitfield clear_mask;
- f = current_aircraft.flight;
+ f = current_aircraft.fdm_state;
l = &cur_light_params;
t = &cur_time_params;
v = ¤t_view;
// setup transformation for drawing astronomical objects
xglPushMatrix();
// Translate to view position
- xglTranslatef( v->view_pos.x, v->view_pos.y, v->view_pos.z );
+ 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;
// draw stars and planets
fgStarsRender();
- fgPlanetsRender();
-
- // draw the sun
- fgSunRender();
-
- // render the moon
- xglEnable( GL_LIGHTING );
- xglEnable( GL_LIGHT0 );
- // 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);
+ SolarSystem::theSolarSystem->draw();
xglPopMatrix();
if ( (iteration == 0) && (current_options.get_panel_status()) ) {
// Did we run this loop before ?? ...and do we need the panel ??
- fgPanelReInit();
+ fgPanelReInit(0, 0, 1024, 768);
}
// 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
// Update internal time dependent calculations (i.e. flight model)
void fgUpdateTimeDepCalcs(int multi_loop) {
- fgFLIGHT *f;
+ FGState *f;
fgLIGHT *l;
fgTIME *t;
fgVIEW *v;
int i;
- f = current_aircraft.flight;
+ f = current_aircraft.fdm_state;
l = &cur_light_params;
t = &cur_time_params;
v = ¤t_view;
}
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);
+ fgFlightModelUpdate( current_options.get_flight_model(),
+ cur_fdm_state, multi_loop );
} else {
- fgFlightModelUpdate(current_options.get_flight_model(), f, 0);
+ fgFlightModelUpdate( current_options.get_flight_model(),
+ cur_fdm_state, 0 );
}
// update the view angle
}
}
- double tmp = -(l->sun_rotation + FG_PI) - (FG_Psi - v->view_offset);
+ double tmp = -(l->sun_rotation + FG_PI) - (f->get_Psi() - v->view_offset);
while ( tmp < 0.0 ) {
tmp += FG_2PI;
}
// 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;
+ FGState *f;
fgGENERAL *g;
fgTIME *t;
static int remainder = 0;
int elapsed, multi_loop;
int i;
double accum;
- // double joy_x, joy_y;
- // int joy_b1, joy_b2;
- f = current_aircraft.flight;
+ f = current_aircraft.fdm_state;
g = &general;
t = &cur_time_params;
- fgPrintf( FG_ALL, FG_DEBUG, "Running Main Loop\n");
- fgPrintf( FG_ALL, FG_DEBUG, "======= ==== ====\n");
+ 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",
+ printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
+ f->get_Runway_altitude() * FEET_TO_METER,
+ f->get_Altitude() * FEET_TO_METER);
if ( scenery.cur_elev > -9990 ) {
- if ( FG_Altitude * FEET_TO_METER <
+ if ( f->get_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,
+ f->get_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,
+ fgFlightModelSetAltitude( current_options.get_flight_model(),
+ cur_fdm_state,
scenery.cur_elev + alt_adjust_m );
- fgPrintf( FG_ALL, FG_BULK,
- "<*> resetting altitude to %.0f meters\n",
- FG_Altitude * FEET_TO_METER);
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "<*> resetting altitude to "
+ << f->get_Altitude() * FEET_TO_METER << " meters" );
}
- FG_Runway_altitude = scenery.cur_elev * METER_TO_FEET;
+ f->set_Runway_altitude( scenery.cur_elev * METER_TO_FEET );
}
- /* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
+ printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
+ f->get_Runway_altitude() * FEET_TO_METER,
+ f->get_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
// 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);
+ FG_LOG( FG_ALL, FG_BULK,
+ "Time interval is = " << elapsed
+ << ", previous remainder is = " << remainder );
// Calculate frame rate average
if ( elapsed > 0.0 ) {
}
// Calculate model iterations needed for next frame
- fgPrintf( FG_ALL, FG_DEBUG,
- "--> Frame rate is = %.2f\n", g->frame_rate);
+ 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); */
- // fgAircraftOutputCurrent(a);
+ // Do any serial port work that might need to be done
+ fgSerialProcess();
// see if we need to load any new scenery tiles
fgTileMgrUpdate();
// Run audio scheduler
#ifdef ENABLE_AUDIO_SUPPORT
- if ( current_options.get_sound() ) {
+ if ( current_options.get_sound() && audio_sched->working() ) {
+
+# 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);
+ if (controls.get_throttle(0) > 0.0 || f->v_rel_wind > 40.0) {
+ //fprintf(stderr, "rel_wind: %f ", f->v_rel_wind);
+ // 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
+ pitch += log(f->v_rel_wind + 0.8)/2;
+ } else {
+ // prop tips breaking sound barrier
+ pitch += log(f->v_rel_wind + 0.8)/10;
+ }
+ //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
+ double aoa = f->get_Gamma_vert_rad() * 2.2;
+ double tmp = 3.0;
+ double aoa_adj = pow(-aoa, tmp) * pow(M_E, aoa);
+ 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 +
+ log(f->v_rel_wind + 1.0)/14.0;
+ // 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
+
audio_sched -> update();
}
#endif
// redraw display
fgRenderFrame();
- fgPrintf( FG_ALL, FG_DEBUG, "\n");
+ FG_LOG( FG_ALL, FG_DEBUG, "" );
}
"/Sounds/intro.mp3";
string command = "(touch " + lockfile + "; mpg123 " + mp3file +
"> /dev/null 2>&1; /bin/rm " + lockfile + ") &";
- fgPrintf( FG_GENERAL, FG_INFO,
- "Starting intro music: %s\n", mp3file.c_str() );
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "Starting intro music: " << mp3file );
system ( command.c_str() );
}
#endif
// a subsystem to flight gear, its initialization call should
// located in this routine.
if( !fgInitSubsystems()) {
- fgPrintf( FG_GENERAL, FG_EXIT,
- "Subsystem initializations failed ...\n" );
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "Subsystem initializations failed ..." );
+ exit(-1);
}
idle_state++;
string lockfile = "/tmp/mpg123.running";
struct stat stat_buf;
- fgPrintf( FG_GENERAL, FG_INFO,
- "Waiting for mpg123 player to finish ...\n" );
+ 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);
- fgPrintf( FG_GENERAL, FG_INFO, ".");
+ FG_LOG( FG_GENERAL, FG_INFO, ".");
}
- fgPrintf( FG_GENERAL, FG_INFO, "\n");
+ FG_LOG( FG_GENERAL, FG_INFO, "");
}
#endif // WIN32
audio_sched = new slScheduler ( 8000 );
audio_mixer = new smMixer;
- audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
+ 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());
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "Rate = " << s1 -> getRate()
+ << " Bps = " << s1 -> getBps()
+ << " Stereo = " << 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 );
if ( ! current_options.get_panel_status() ) {
v->win_ratio = (GLfloat) width / (GLfloat) height;
} else {
- v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.67);
+ v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.4232);
}
}
v->winWidth = width;
v->winHeight = height;
+ v->update_fov = true;
// Inform gl of our view window size (now handled elsewhere)
// xglViewport(0, 0, (GLint)width, (GLint)height);
// the system.
v->UpdateViewParams();
if ( current_options.get_panel_status() ) {
- fgPanelReInit();
+ fgPanelReInit(0, 0, 1024, 768);
}
}
xglutInit(argc, argv);
// Define Display Parameters
- if ( ! current_options.get_panel_status() ) {
- xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
- } else {
- xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE |
- GLUT_STENCIL);
- }
+ xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+
+ FG_LOG( FG_GENERAL, FG_INFO, "Opening a window: " <<
+ current_options.get_xsize() << "x" << current_options.get_ysize() );
// Define initial window size
- xglutInitWindowSize(640, 480);
+ xglutInitWindowSize( current_options.get_xsize(),
+ current_options.get_ysize() );
// Initialize windows
if ( current_options.get_game_mode() == 0 ) {
xglutCreateWindow("Flight Gear");
} else {
// Open the cool new 'game mode' window
- glutGameModeString("width=640 height=480 bpp=16");
+ string game_mode_params = "width=" + current_options.get_xsize();
+ game_mode_params += "height=" + current_options.get_ysize();
+ game_mode_params += " bpp=16";
+ cout << "game mode params = " << game_mode_params;
+ glutGameModeString( game_mode_params.c_str() );
glutEnterGameMode();
}
+ // 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. :-(
+ general.glVendor = (char *)glGetString ( GL_VENDOR );
+ general.glRenderer = (char *)glGetString ( GL_RENDERER );
+ general.glVersion = (char *)glGetString ( GL_VERSION );
+
+ FG_LOG ( FG_GENERAL, FG_INFO, general.glRenderer );
+
+#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
+
return(1);
}
// Main ...
int main( int argc, char **argv ) {
- fgFLIGHT *f;
+ FGState *f;
- f = current_aircraft.flight;
+ f = current_aircraft.fdm_state;
#ifdef HAVE_BC5PLUS
_control87(MCW_EM, MCW_EM); /* defined in float.h */
#endif
- // Initialize the debugging output system
- fgInitDebug();
+ // Initialize the [old] debugging output system
+ // fgInitDebug();
+
+ // set default log levels
+ fglog().setLogLevels( FG_ALL, FG_DEBUG );
- fgPrintf(FG_GENERAL, FG_INFO, "Flight Gear: Version %s\n\n", VERSION);
+ FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear: Version " << VERSION << endl );
+
+ string root;
+
+ FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
+ FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
// Attempt to locate and parse a config file
// First check fg_root
// Something must have gone horribly wrong with the command
// line parsing or maybe the user just requested help ... :-)
current_options.usage();
- fgPrintf( FG_GENERAL, FG_EXIT, "\nExiting ...\n");
+ // FG_LOG( FG_GENERAL, FG_ALERT, "\nExiting ...");
+ cout << endl << "Exiting ..." << endl;
+ exit(-1);
}
// Initialize the Window/Graphics environment.
if( !fgGlutInit(&argc, argv) ) {
- fgPrintf( FG_GENERAL, FG_EXIT, "GLUT initialization failed ...\n" );
+ FG_LOG( FG_GENERAL, FG_ALERT, "GLUT initialization failed ..." );
+ exit(-1);
}
// Initialize the various GLUT Event Handlers.
if( !fgGlutInitEvents() ) {
- fgPrintf( FG_GENERAL, FG_EXIT,
- "GLUT event handler initialization failed ...\n" );
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "GLUT event handler initialization failed ..." );
+ exit(-1);
}
// First do some quick general initializations
if( !fgInitGeneral()) {
- fgPrintf( FG_GENERAL, FG_EXIT,
- "General initializations failed ...\n" );
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "General initializations failed ..." );
+ exit(-1);
}
// Init the user interface (we need to do this before passing off
// $Log$
+// Revision 1.72 1998/12/05 15:54:18 curt
+// Renamed class fgFLIGHT to class FGState as per request by JSB.
+//
+// Revision 1.71 1998/12/05 14:19:51 curt
+// Looking into a problem with cur_view_params.abs_view_pos initialization.
+//
+// Revision 1.70 1998/12/03 01:17:14 curt
+// Converted fgFLIGHT to a class.
+//
+// Revision 1.69 1998/11/23 20:51:26 curt
+// Fiddling with when I can get info from the opengl driver.
+//
+// Revision 1.68 1998/11/20 01:02:35 curt
+// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
+//
+// Revision 1.67 1998/11/16 13:59:58 curt
+// Added pow() macro bug work around.
+// Added support for starting FGFS at various resolutions.
+// Added some initial serial port support.
+// Specify default log levels in main().
+//
+// Revision 1.66 1998/11/11 00:24:00 curt
+// Added Michael Johnson's audio patches for testing.
+// Also did a few tweaks to avoid numerical problems when starting at a place
+// with no (or bogus) scenery.
+//
+// Revision 1.65 1998/11/09 23:39:22 curt
+// Tweaks for the instrument panel.
+//
+// Revision 1.64 1998/11/07 19:07:09 curt
+// Enable release builds using the --without-logging option to the configure
+// script. Also a couple log message cleanups, plus some C to C++ comment
+// conversion.
+//
+// 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.