]> git.mxchange.org Git - flightgear.git/blobdiff - Main/GLUTmain.cxx
Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
[flightgear.git] / Main / GLUTmain.cxx
index cb3bc46622b5920b63a75ca7fcdf2f3bc82edc72..f1fba8050f92c08dde5f8b3c7267a8d440e41400 100644 (file)
@@ -1,10 +1,8 @@
-
-//
 // 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
@@ -23,6 +21,7 @@
 // $Id$
 // (Log is kept at end of this file)
 
+#define MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
 #include <Include/fg_constants.h>  // for VERSION
-#include <Include/general.h>
+#include <Include/general.hxx>
 
-#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>
@@ -78,7 +76,7 @@
 #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 "views.hxx"
 
 
-// This is a record containing global housekeeping information
-fgGENERAL general;
+// This is a record containing a bit of global housekeeping information
+FGGeneral general;
 
 // 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 idle_state = 0;
+static int idle_state = 0;
 
 // Another hack
 int use_signals = 0;
@@ -103,6 +101,8 @@ 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;
@@ -134,10 +134,8 @@ slSample *s2;
 // fgInitVisuals() -- Initialize various GL/view parameters
 static void fgInitVisuals( void ) {
     fgLIGHT *l;
-    struct fgWEATHER *w;
 
     l = &cur_light_params;
-    w = &current_weather;
 
     // Go full screen if requested ...
     if ( current_options.get_fullscreen() ) {
@@ -178,15 +176,13 @@ static void fgInitVisuals( void ) {
 }
 
 
-#ifdef IS_THIS_BETTER_THAN_A_ZERO_CHARLIE
+#if 0
 // Draw a basic instrument panel
 static void fgUpdateInstrViewParams( void ) {
 
     exit(0);
 
-    fgVIEW *v;
-
-    v = &current_view;
+    fgVIEW *v = &current_view;
 
     xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
   
@@ -228,10 +224,10 @@ static void fgUpdateInstrViewParams( void ) {
 
 // Update all Visuals (redraws anything graphics related)
 static void fgRenderFrame( void ) {
-    fgFLIGHT *f;
-    fgLIGHT *l;
-    fgTIME *t;
-    fgVIEW *v;
+    fgLIGHT *l = &cur_light_params;
+    fgTIME *t = &cur_time_params;
+    FGView *v = &current_view;
+
     double angle;
     static int iteration = 0;
     // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
@@ -239,11 +235,6 @@ static void fgRenderFrame( void ) {
     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 = &current_view;
-
     if ( idle_state != 1000 ) {
        // still initializing, draw the splash screen
        if ( current_options.get_splash_screen() == 1 ) {
@@ -264,6 +255,9 @@ static void fgRenderFrame( void ) {
        // update view volume parameters
        v->UpdateViewParams();
 
+       // set the sun position
+       xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+
        clear_mask = GL_DEPTH_BUFFER_BIT;
        if ( current_options.get_wireframe() ) {
            clear_mask |= GL_COLOR_BUFFER_BIT;
@@ -301,7 +295,8 @@ static void fgRenderFrame( void ) {
        // setup transformation for drawing astronomical objects
        xglPushMatrix();
        // Translate to view position
-       xglTranslatef( v->view_pos.x, v->view_pos.y, v->view_pos.z );
+       Point3D view_pos = v->get_view_pos();
+       xglTranslatef( view_pos.x(), view_pos.y(), 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;
@@ -310,24 +305,7 @@ static void fgRenderFrame( void ) {
 
        // 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();
 
@@ -365,16 +343,14 @@ static void fgRenderFrame( void ) {
        fgTileMgrRender();
 
        xglDisable( GL_TEXTURE_2D );
+       xglDisable( GL_FOG );
 
        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
 
@@ -383,6 +359,7 @@ static void fgRenderFrame( void ) {
        xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
        puDisplay();
        xglDisable   ( GL_BLEND ) ;
+       xglEnable( GL_FOG );
     }
 
     xglutSwapBuffers();
@@ -390,59 +367,60 @@ static void fgRenderFrame( void ) {
 
 
 // Update internal time dependent calculations (i.e. flight model)
-void fgUpdateTimeDepCalcs(int multi_loop) {
-    fgFLIGHT *f;
-    fgLIGHT *l;
-    fgTIME *t;
-    fgVIEW *v;
+void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
+    FGState *f = current_aircraft.fdm_state;
+    fgLIGHT *l = &cur_light_params;
+    fgTIME *t = &cur_time_params;
+    FGView *v = &current_view;
     int i;
 
-    f = current_aircraft.flight;
-    l = &cur_light_params;
-    t = &cur_time_params;
-    v = &current_view;
-
     // update the flight model
     if ( multi_loop < 0 ) {
        multi_loop = DEFAULT_MULTILOOP;
     }
 
     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, remainder );
     } else {
-       fgFlightModelUpdate(current_options.get_flight_model(), f, 0);
+       fgFlightModelUpdate( current_options.get_flight_model(), 
+                            cur_fdm_state, 0, remainder );
     }
 
     // update the view angle
     for ( i = 0; i < multi_loop; i++ ) {
-       if ( fabs(v->goal_view_offset - v->view_offset) < 0.05 ) {
-           v->view_offset = v->goal_view_offset;
+       if ( fabs(v->get_goal_view_offset() - v->get_view_offset()) < 0.05 ) {
+           v->set_view_offset( v->get_goal_view_offset() );
            break;
        } else {
            // move v->view_offset towards v->goal_view_offset
-           if ( v->goal_view_offset > v->view_offset ) {
-               if ( v->goal_view_offset - v->view_offset < FG_PI ) {
-                   v->view_offset += 0.01;
+           if ( v->get_goal_view_offset() > v->get_view_offset() ) {
+               if ( v->get_goal_view_offset() - v->get_view_offset() < FG_PI ){
+                   v->inc_view_offset( 0.01 );
                } else {
-                   v->view_offset -= 0.01;
+                   v->inc_view_offset( -0.01 );
                }
            } else {
-               if ( v->view_offset - v->goal_view_offset < FG_PI ) {
-                   v->view_offset -= 0.01;
+               if ( v->get_view_offset() - v->get_goal_view_offset() < FG_PI ){
+                   v->inc_view_offset( -0.01 );
                } else {
-                   v->view_offset += 0.01;
+                   v->inc_view_offset( 0.01 );
                }
            }
-           if ( v->view_offset > FG_2PI ) {
-               v->view_offset -= FG_2PI;
-           } else if ( v->view_offset < 0 ) {
-               v->view_offset += FG_2PI;
+           if ( v->get_view_offset() > FG_2PI ) {
+               v->inc_view_offset( -FG_2PI );
+           } else if ( v->get_view_offset() < 0 ) {
+               v->inc_view_offset( FG_2PI );
            }
        }
     }
 
-    double tmp = -(l->sun_rotation + FG_PI) - (FG_Psi - v->view_offset);
+    double tmp = -(l->sun_rotation + FG_PI) 
+       - (f->get_Psi() - v->get_view_offset() );
     while ( tmp < 0.0 ) {
        tmp += FG_2PI;
     }
@@ -459,10 +437,9 @@ void fgUpdateTimeDepCalcs(int multi_loop) {
 void fgInitTimeDepCalcs( void ) {
     // initialize timer
 
-#ifdef HAVE_SETITIMER
-    fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
-#endif HAVE_SETITIMER
-
+    // #ifdef HAVE_SETITIMER
+    //   fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
+    // #endif HAVE_SETITIMER
 }
 
 static const double alt_adjust_ft = 3.758099;
@@ -471,72 +448,84 @@ static const double alt_adjust_m = alt_adjust_ft * FEET_TO_METER;
 // 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;
+    FGState *f;
     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;
-    g = &general;
+    static long remainder = 0;
+    long elapsed, multi_loop;
+    // int i;
+    // double accum;
+    static time_t last_time = 0;
+    static int frames = 0;
+
+    f = current_aircraft.fdm_state;
     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, "======= ==== ====");
+
+#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
+
+    current_weather.Update();
 
     // 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); */
+          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(), 
                                      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",
           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 ); */
-
-    // Get elapsed time for this past frame
+    // Get elapsed time (in usec) 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_DEBUG
+           "Elapsed time interval is = " << elapsed 
+           << ", previous remainder is = " << remainder );
 
     // Calculate frame rate average
-    if ( elapsed > 0.0 ) {
+    if ( (t->cur_time != last_time) && (last_time > 0) ) {
+       general.set_frame_rate( frames );
+       FG_LOG( FG_ALL, FG_DEBUG, 
+               "--> Frame rate is = " << general.get_frame_rate() );
+       frames = 0;
+    }
+    last_time = t->cur_time;
+    ++frames;
+
+    /* old fps calculation
+    if ( elapsed > 0 ) {
        accum = 0.0;
        for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
            accum += g->frames[i];
@@ -549,35 +538,29 @@ static void fgMainLoop( void ) {
        g->frame_rate = accum / (float)FG_FRAME_RATE_HISTORY;
        // printf("ave = %.2f\n", g->frame_rate);
     }
-
-    // Calculate model iterations needed for next frame
-    fgPrintf( FG_ALL, FG_DEBUG, 
-             "--> Frame rate is = %.2f\n", 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);
-       
-    /* 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 ) {
+       // Calculate model iterations needed for next frame
+       elapsed += remainder;
+
+       multi_loop = (int)(((double)elapsed * 0.000001) * DEFAULT_MODEL_HZ);
+       remainder = elapsed - ((multi_loop*1000000) / DEFAULT_MODEL_HZ);
+       FG_LOG( FG_ALL, FG_DEBUG, 
+               "Model iterations needed = " << multi_loop
+               << ", new remainder = " << remainder );
+       
        // flight model
-       fgUpdateTimeDepCalcs(multi_loop);
+       if ( multi_loop > 0 ) {
+           fgUpdateTimeDepCalcs(multi_loop, remainder);
+       } else {
+           FG_LOG( FG_ALL, FG_INFO, "Elapsed time is zero ... we're zinging" );
+       }
     }
 
-    /* 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);
+    // Do any serial port work that might need to be done
+    fgSerialProcess();
 
     // see if we need to load any new scenery tiles
     fgTileMgrUpdate();
@@ -587,7 +570,67 @@ static void fgMainLoop( void ) {
 
     // 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
@@ -595,7 +638,7 @@ static void fgMainLoop( void ) {
     // redraw display
     fgRenderFrame();
 
-    fgPrintf( FG_ALL, FG_DEBUG, "\n");
+    FG_LOG( FG_ALL, FG_DEBUG, "" );
 }
 
 
@@ -608,10 +651,6 @@ static void fgMainLoop( void ) {
 // then on.
 
 static void fgIdleFunction ( void ) {
-    fgGENERAL *g;
-
-    g = &general;
-
     // printf("idle state == %d\n", idle_state);
 
     if ( idle_state == 0 ) {
@@ -630,8 +669,8 @@ static void fgIdleFunction ( void ) {
                "/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
@@ -642,7 +681,7 @@ static void fgIdleFunction ( void ) {
        // "subsystems" but still need to be initialized.
 
 #ifdef USE_GLIDE
-       if ( strstr ( g->glRenderer, "Glide" ) ) {
+       if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
            grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
        }
 #endif
@@ -654,8 +693,9 @@ static void fgIdleFunction ( void ) {
        // 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++;
@@ -683,28 +723,42 @@ static void fgIdleFunction ( void ) {
            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 );
@@ -731,22 +785,20 @@ static void fgIdleFunction ( void ) {
 
 // Handle new window size or exposure
 static void fgReshape( int width, int height ) {
-    fgVIEW *v;
-
-    v = &current_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) ) {
        if ( ! current_options.get_panel_status() ) {
-           v->win_ratio = (GLfloat) width / (GLfloat) height;
+           current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
        } else {
-           v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.67);
+           current_view.set_win_ratio( (GLfloat) width / 
+                                       ((GLfloat) (height)*0.4232) );
        }
     }
 
-    v->winWidth = width;
-    v->winHeight = height;
+    current_view.set_winWidth( width );
+    current_view.set_winHeight( height );
+    current_view.force_update_fov_math();
 
     // Inform gl of our view window size (now handled elsewhere)
     // xglViewport(0, 0, (GLint)width, (GLint)height);
@@ -754,13 +806,11 @@ static void fgReshape( int width, int height ) {
        // 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();
+       current_view.UpdateViewParams();
        if ( current_options.get_panel_status() ) {
-           fgPanelReInit();
+           fgPanelReInit(0, 0, 1024, 768);
        }
     }
-    
-    // xglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 }
 
 
@@ -771,10 +821,14 @@ int fgGlutInit( int *argc, char **argv ) {
     xglutInit(argc, argv);
 
     // Define Display Parameters
-    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 ) {
@@ -782,10 +836,59 @@ int fgGlutInit( int *argc, char **argv ) {
        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.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
+    general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
+    general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
+
+    FG_LOG ( FG_GENERAL, FG_INFO, general.get_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);
 }
 
@@ -817,18 +920,26 @@ int fgGlutInitEvents( void ) {
 
 // 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();
 
-    fgPrintf(FG_GENERAL, FG_INFO, "Flight Gear:  Version %s\n\n", VERSION);
+    // set default log levels
+    fglog().setLogLevels( FG_ALL, FG_INFO );
+
+    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
@@ -851,24 +962,29 @@ int main( int argc, char **argv ) {
        // 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
@@ -884,6 +1000,135 @@ int main( int argc, char **argv ) {
 
 
 // $Log$
+// Revision 1.80  1999/01/09 13:37:40  curt
+// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
+//
+// Revision 1.79  1999/01/08 03:23:56  curt
+// Beginning work on compensating for sim time vs. real world time "jitter".
+//
+// Revision 1.78  1999/01/07 20:25:08  curt
+// Updated struct fgGENERAL to class FGGeneral.
+//
+// Revision 1.77  1998/12/18 23:40:55  curt
+// New frame rate counting mechanism.
+//
+// Revision 1.76  1998/12/11 20:26:26  curt
+// Fixed view frustum culling accuracy bug so we can look out the sides and
+// back without tri-stripes dropping out.
+//
+// Revision 1.75  1998/12/09 18:50:23  curt
+// Converted "class fgVIEW" to "class FGView" and updated to make data
+// members private and make required accessor functions.
+//
+// Revision 1.74  1998/12/06 14:52:54  curt
+// Fixed a problem with the initial starting altitude.  "v->abs_view_pos" wasn't
+// being calculated correctly at the beginning causing the first terrain
+// intersection to fail, returning a ground altitude of zero, causing the plane
+// to free fall for one frame, until the ground altitude was corrected, but now
+// being under the ground we got a big bounce and the plane always ended up
+// upside down.
+//
+// Revision 1.73  1998/12/06 13:51:22  curt
+// Turned "struct fgWEATHER" into "class FGWeather".
+//
+// 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.
+//
+// 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>