]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/main.cxx
Added code to put aircraft at the end of the runway closest to the desired
[flightgear.git] / src / Main / main.cxx
index 93131002c2bb453076ead79167c76a58e7f16da6..4cd07e5a668198831b568f3a018719271c2a1b5f 100644 (file)
 #include <simgear/math/polar3d.hxx>
 #include <simgear/math/fg_random.h>
 #include <simgear/misc/fgpath.hxx>
+#include <simgear/sky/sky.hxx>
+#include <simgear/timing/sg_time.hxx>
+#include <simgear/timing/lowleveltime.h>
 
 #include <Include/general.hxx>
 
 #include <Aircraft/aircraft.hxx>
-#include <Ephemeris/ephemeris.hxx>
 
 #include <Autopilot/newauto.hxx>
 #include <Cockpit/cockpit.hxx>
 #include <Cockpit/radiostack.hxx>
 #include <Cockpit/steam.hxx>
-#include <FDM/UIUCModel/uiuc_aircraft.h>
+
 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
 #include <GUI/gui.h>
 #include <Joystick/joystick.hxx>
 #ifdef FG_NETWORK_OLK
 #include <NetworkOLK/network.h>
 #endif
-#include <Objects/materialmgr.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
-#include <Sky/sky.hxx>
 #include <Time/event.hxx>
-#include <Time/fg_time.hxx>
 #include <Time/fg_timer.hxx>
 #include <Time/sunpos.hxx>
+#include <Time/tmp.hxx>
 
 #ifndef FG_OLD_WEATHER
 #  include <WeatherCM/FGLocalWeatherDatabase.h>
 #  include <Weather/weather.hxx>
 #endif
 
+#include "bfi.hxx"
 #include "fg_init.hxx"
 #include "fg_io.hxx"
+#include "globals.hxx"
 #include "keyboard.hxx"
 #include "options.hxx"
 #include "splash.hxx"
@@ -158,7 +160,6 @@ ssgTransform *fgd_pos = NULL;
 FGInterface cur_view_fdm;
 
 // Sky structures
-FGEphemeris *ephem;
 SGSky *thesky;
 
 // hack
@@ -199,16 +200,19 @@ void fgBuildRenderStates( void ) {
     default_state = new ssgSimpleState;
     default_state->disable( GL_TEXTURE_2D );
     default_state->enable( GL_CULL_FACE );
-    default_state->disable( GL_COLOR_MATERIAL );
+    default_state->enable( GL_COLOR_MATERIAL );
+    default_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
+    default_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
+    default_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
     default_state->disable( GL_BLEND );
     default_state->disable( GL_ALPHA_TEST );
     default_state->disable( GL_LIGHTING );
-    default_state->setMaterial( GL_AMBIENT_AND_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
 
     hud_and_panel = new ssgSimpleState;
     hud_and_panel->disable( GL_CULL_FACE );
     hud_and_panel->disable( GL_TEXTURE_2D );
     hud_and_panel->disable( GL_LIGHTING );
+    hud_and_panel->enable( GL_BLEND );
 
     menus = new ssgSimpleState;
     menus->disable( GL_CULL_FACE );
@@ -268,15 +272,11 @@ void fgInitVisuals( void ) {
 
 // Update all Visuals (redraws anything graphics related)
 void fgRenderFrame( void ) {
+    // Update the BFI.
+    FGBFI::update();
+
     fgLIGHT *l = &cur_light_params;
-    FGTime *t = FGTime::cur_time_params;
-    // FGView *v = &current_view;
     static double last_visibility = -9999;
-    static bool in_puff = false;
-    static double puff_length = 0;
-    static double puff_progression = 0;
-    const double ramp_up = 0.15;
-    const double ramp_down = 0.15;
 
     double angle;
     // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
@@ -315,9 +315,8 @@ void fgRenderFrame( void ) {
        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_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], 
@@ -335,7 +334,7 @@ void fgRenderFrame( void ) {
 
        // I really should create a derived ssg node or use a call
        // back or something so that I can draw the sky within the
-       // ssgCullandDraw() function, but for now I just mimic what
+       // ssgCullAndDraw() function, but for now I just mimic what
        // ssg does to set up the model view matrix
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
@@ -352,7 +351,41 @@ void fgRenderFrame( void ) {
        // set the opengl state to known default values
        default_state->force();
 
-       // draw sky dome
+       // update fog params if visibility has changed
+#ifndef FG_OLD_WEATHER
+       thesky->set_visibility( WeatherDatabase->getWeatherVisibility() );
+#else
+       thesky->set_visibility( current_weather.get_visibility() );
+#endif
+
+       thesky->modify_vis( cur_fdm_state->get_Altitude() * FEET_TO_METER,
+                               
+                           ( global_multi_loop * 
+                             current_options.get_speed_up() ) /
+                           (double)current_options.get_model_hz() );
+
+       double actual_visibility = thesky->get_visibility();
+       // cout << "actual visibility = " << actual_visibility << endl;
+
+       if ( actual_visibility != last_visibility ) {
+           last_visibility = actual_visibility;
+
+           // cout << "----> updating fog params" << endl;
+               
+           GLfloat fog_exp_density;
+           GLfloat fog_exp2_density;
+    
+           // for GL_FOG_EXP
+           fog_exp_density = -log(0.01 / actual_visibility);
+    
+           // for GL_FOG_EXP2
+           fog_exp2_density = sqrt( -log(0.01) ) / actual_visibility;
+    
+           // Set correct opengl fog density
+           glFogf (GL_FOG_DENSITY, fog_exp2_density);
+       }
+       // update the sky dome
        if ( current_options.get_skyblend() ) {
            sgVec3 view_pos;
            sgSetVec3( view_pos,
@@ -383,8 +416,10 @@ void fgRenderFrame( void ) {
                             cur_light_params.adj_fog_color,
                             cur_light_params.sun_angle,
                             cur_light_params.moon_angle,
-                            ephem->getNumPlanets(), ephem->getPlanets(),
-                            ephem->getNumStars(), ephem->getStars() );
+                            globals->get_ephem()->getNumPlanets(),
+                            globals->get_ephem()->getPlanets(),
+                            globals->get_ephem()->getNumStars(),
+                            globals->get_ephem()->getStars() );
  
            /* cout << "thesky->reposition( view_pos = " << view_pos[0] << " "
                 << view_pos[1] << " " << view_pos[2] << endl;
@@ -393,21 +428,25 @@ void fgRenderFrame( void ) {
                 << " lon = " << cur_fdm_state->get_Longitude()
                 << " lat = " << cur_fdm_state->get_Latitude() << endl;
            cout << "    sun_rot = " << cur_light_params.sun_rotation
-                << " gst = " << FGTime::cur_time_params->getGst() << endl;
-           cout << "    sun ra = " << ephem->getSunRightAscension()
-                << " sun dec = " << ephem->getSunDeclination() 
-                << " moon ra = " << ephem->getMoonRightAscension()
-                << " moon dec = " << ephem->getMoonDeclination() << endl; */
-
-           thesky->reposition( view_pos, zero_elev, 
+                << " gst = " << SGTime::cur_time_params->getGst() << endl;
+           cout << "    sun ra = " << globals->get_ephem()->getSunRightAscension()
+                << " sun dec = " << globals->get_ephem()->getSunDeclination() 
+                << " moon ra = " << globals->get_ephem()->getMoonRightAscension()
+                << " moon dec = " << globals->get_ephem()->getMoonDeclination() << endl; */
+
+           thesky->reposition( view_pos, zero_elev,
+                               current_view.get_local_up(),
                                cur_fdm_state->get_Longitude(),
                                cur_fdm_state->get_Latitude(),
+                               cur_fdm_state->get_Altitude() * FEET_TO_METER,
                                cur_light_params.sun_rotation,
-                               FGTime::cur_time_params->getGst(),
-                               ephem->getSunRightAscension(),
-                               ephem->getSunDeclination(), 50000.0,
-                               ephem->getMoonRightAscension(),
-                               ephem->getMoonDeclination(), 50000.0 );
+                               globals->get_time_params()->getGst(),
+                               globals->get_ephem()->getSunRightAscension(),
+                               globals->get_ephem()->getSunDeclination(),
+                               50000.0,
+                               globals->get_ephem()->getMoonRightAscension(),
+                               globals->get_ephem()->getMoonDeclination(),
+                               50000.0 );
        }
 
        glEnable( GL_DEPTH_TEST );
@@ -417,100 +456,10 @@ void fgRenderFrame( void ) {
            glFogfv( GL_FOG_COLOR, l->adj_fog_color );
        }
 
-       // update fog params if visibility has changed
-#ifndef FG_OLD_WEATHER
-       double cur_visibility = WeatherDatabase->getWeatherVisibility();
-#else
-       double cur_visibility = current_weather.get_visibility();
-#endif
-       double actual_visibility = cur_visibility;
-
-       if ( current_options.get_clouds() ) {
-           double diff = fabs( cur_fdm_state->get_Altitude() * FEET_TO_METER -
-                               current_options.get_clouds_asl() );
-           // cout << "altitude diff = " << diff << endl;
-           if ( diff < 75 ) {
-               if ( ! in_puff ) {
-                   // calc chance of entering cloud puff
-                   double rnd = fg_random();
-                   double chance = rnd * rnd * rnd;
-                   if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) {
-                       in_puff = true;
-                       do {
-                           puff_length = fg_random() * 2.0; // up to 2 seconds
-                       } while ( puff_length <= 0.0 );
-                       puff_progression = 0.0;
-                   }
-               }
-
-               actual_visibility = cur_visibility * (diff - 25) / 50.0;
-
-               if ( in_puff ) {
-                   // modify actual_visibility based on puff envelope
-
-                   if ( puff_progression <= ramp_up ) {
-                       double x = FG_PI_2 * puff_progression / ramp_up;
-                       double factor = 1.0 - sin( x );
-                       actual_visibility = actual_visibility * factor;
-                   } else if ( puff_progression >= ramp_up + puff_length ) {
-                       double x = FG_PI_2 * 
-                           (puff_progression - (ramp_up + puff_length)) /
-                           ramp_down;
-                       double factor = sin( x );
-                       actual_visibility = actual_visibility * factor;
-                   } else {
-                       actual_visibility = 0.0;
-                   }
-
-                   /* cout << "len = " << puff_length
-                        << "  x = " << x 
-                        << "  factor = " << factor
-                        << "  actual_visibility = " << actual_visibility 
-                        << endl; */
-
-                   puff_progression += ( global_multi_loop * 
-                                         current_options.get_speed_up() ) /
-                       (double)current_options.get_model_hz();
-
-                   /* cout << "gml = " << global_multi_loop 
-                        << "  speed up = " << current_options.get_speed_up()
-                        << "  hz = " << current_options.get_model_hz() << endl;
-                        */ 
-
-                   if ( puff_progression > puff_length + ramp_up + ramp_down) {
-                       in_puff = false; 
-                   }
-               }
-
-               // never let visibility drop below zero
-               if ( actual_visibility < 0 ) {
-                   actual_visibility = 0;
-               }
-           }
-       }
-
-       // cout << "actual visibility = " << actual_visibility << endl;
-
-       if ( actual_visibility != last_visibility ) {
-           last_visibility = actual_visibility;
-
-           // cout << "----> updating fog params" << endl;
-               
-           GLfloat fog_exp_density;
-           GLfloat fog_exp2_density;
-    
-           // for GL_FOG_EXP
-           fog_exp_density = -log(0.01 / actual_visibility);
-    
-           // for GL_FOG_EXP2
-           fog_exp2_density = sqrt( -log(0.01) ) / actual_visibility;
-    
-           // Set correct opengl fog density
-           glFogf (GL_FOG_DENSITY, fog_exp2_density);
-       }
        // set lighting parameters
-       glLightfv( GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
+       GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
+       glLightModelfv( GL_LIGHT_MODEL_AMBIENT, l->scene_ambient );
+       glLightfv( GL_LIGHT0, GL_AMBIENT, black );
        glLightfv( GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
        // glLightfv(GL_LIGHT0, GL_SPECULAR, white );
 
@@ -531,7 +480,8 @@ void fgRenderFrame( void ) {
        // glMatrixMode( GL_PROJECTION );
        // glLoadIdentity();
        float fov = current_options.get_fov();
-       ssgSetFOV(fov * current_view.get_win_ratio(), fov);
+       // ssgSetFOV(fov * current_view.get_win_ratio(), fov);
+       ssgSetFOV(fov, fov * current_view.get_win_ratio());
 
        double agl = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
            - scenery.cur_elev;
@@ -615,16 +565,23 @@ void fgRenderFrame( void ) {
        global_tile_mgr.prep_ssg_nodes();
 
        // force the default state so ssg can get back on track if
-       // we've changed things elsewhere
-       FGMaterialSlot m_slot;
-       FGMaterialSlot *m_ptr = &m_slot;
-       if ( material_mgr.find( "Default", m_ptr ) ) {
-           m_ptr->get_state()->force();
-       }
+       // we've changed things elsewhere (this is now handled
+       // differently)
+       // 
+       // FGMaterialSlot m_slot;
+       // FGMaterialSlot *m_ptr = &m_slot;
+       // if ( material_mgr.find( "Default", m_ptr ) ) {
+       //    m_ptr->get_state()->force();
+       // }
+
+       // draw the sky backdrop
+       thesky->preDraw();
 
        // draw the ssg scene
        ssgCullAndDraw( scene );
 
+       // draw the sky cloud layers
+       thesky->postDraw( cur_fdm_state->get_Altitude() * FEET_TO_METER );
 
        // display HUD && Panel
        glDisable( GL_FOG );
@@ -651,10 +608,7 @@ void fgRenderFrame( void ) {
 // Update internal time dependent calculations (i.e. flight model)
 void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
     static fdm_state_list fdm_list;
-    // FGInterface fdm_state;
     fgLIGHT *l = &cur_light_params;
-    FGTime *t = FGTime::cur_time_params;
-    // FGView *v = &current_view;
     int i;
 
     // update the flight model
@@ -662,7 +616,7 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
        multi_loop = 1;
     }
 
-    if ( !t->getPause() ) {
+    if ( !globals->get_freeze() ) {
        // run Autopilot system
        current_autopilot->run();
 
@@ -742,11 +696,13 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
     l->UpdateAdjFog();
 
     // Update solar system
-    ephem->update( t, cur_fdm_state->get_Latitude() );
+    globals->get_ephem()->update( globals->get_time_params()->getMjd(),
+                                 globals->get_time_params()->getLst(),
+                                 cur_fdm_state->get_Latitude() );
 
     // Update radio stack model
-    current_radiostack->update( cur_fdm_state->get_Longitude() * RAD_TO_DEG,
-                               cur_fdm_state->get_Latitude() * RAD_TO_DEG,
+    current_radiostack->update( cur_fdm_state->get_Longitude(),
+                               cur_fdm_state->get_Latitude(),
                                cur_fdm_state->get_Altitude() * FEET_TO_METER );
 }
 
@@ -768,7 +724,6 @@ 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 ) {
-    FGTime *t;
     static long remainder = 0;
     long elapsed;
 #ifdef FANCY_FRAME_COUNTER
@@ -779,7 +734,7 @@ static void fgMainLoop( void ) {
     static int frames = 0;
 #endif // FANCY_FRAME_COUNTER
 
-    t = FGTime::cur_time_params;
+    SGTime *t = globals->get_time_params();
 
     FG_LOG( FG_ALL, FG_DEBUG, "Running Main Loop");
     FG_LOG( FG_ALL, FG_DEBUG, "======= ==== ====");
@@ -842,9 +797,23 @@ static void fgMainLoop( void ) {
           cur_fdm_state->get_Altitude() * FEET_TO_METER); */
 
     // update "time"
+    if ( globals->get_warp_delta() != 0 ) {
+       globals->inc_warp( globals->get_warp_delta() );
+    }
+
     t->update( cur_fdm_state->get_Longitude(),
               cur_fdm_state->get_Latitude(),
-              cur_fdm_state->get_Altitude()* FEET_TO_METER );
+              globals->get_warp() );
+
+    if ( globals->get_warp_delta() != 0 ) {
+       fgUpdateSkyAndLightingParams();
+    }
+
+    // update magvar model
+    globals->get_mag()->update( cur_fdm_state->get_Longitude(),
+                               cur_fdm_state->get_Latitude(),
+                               cur_fdm_state->get_Altitude()* FEET_TO_METER,
+                               globals->get_time_params()->getJD() );
 
     // Get elapsed time (in usec) for this past frame
     elapsed = fgGetTimeInterval();
@@ -910,7 +879,8 @@ static void fgMainLoop( void ) {
 #endif
 
     // see if we need to load any new scenery tiles
-    global_tile_mgr.update();
+    global_tile_mgr.update( cur_fdm_state->get_Longitude() * RAD_TO_DEG,
+                           cur_fdm_state->get_Latitude() * RAD_TO_DEG );
 
     // Process/manage pending events
     global_events.Process();
@@ -921,6 +891,8 @@ static void fgMainLoop( void ) {
 
 #   ifdef MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
 
+       static double kts_to_fts = NM_TO_METER * METER_TO_FEET / 3600.0;
+
        // 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.
@@ -933,38 +905,40 @@ static void fgMainLoop( void ) {
 
        double pitch = log((controls.get_throttle(0) * 14.0) + 1.0);
        //fprintf(stderr, "pitch1: %f ", pitch);
-       if (controls.get_throttle(0) > 0.0 || cur_fdm_state->v_rel_wind > 40.0) {
-           //fprintf(stderr, "rel_wind: %f ", cur_fdm_state->v_rel_wind);
-           // 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(cur_fdm_state->v_rel_wind + 0.8)/2;
-           } else {
-               // prop tips breaking sound barrier
-               pitch += log(cur_fdm_state->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 = cur_fdm_state->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;
+       // if (controls.get_throttle(0) > 0.0 || 
+       //     cur_fdm_state->get_V_calibrated_kts() > 40.0) {
+
+       //fprintf(stderr, "rel_wind: %f ", cur_fdm_state->get_V_calibrated_kts());
+       // 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(cur_fdm_state->get_V_calibrated_kts() * kts_to_fts + 0.8)/2;
+       } else {
+           // prop tips breaking sound barrier
+           pitch += log(cur_fdm_state->get_V_calibrated_kts() * kts_to_fts + 0.8)/10;
        }
-       //fprintf(stderr, "pitch4: %f\n", pitch);
+       //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 = cur_fdm_state->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(cur_fdm_state->v_rel_wind + 1.0)/14.0;
+           log(cur_fdm_state->get_V_calibrated_kts() * kts_to_fts + 1.0)/14.0;
        // fprintf(stderr, "volume: %f\n", volume);
 
        pitch_envelope.setStep  ( 0, 0.01, pitch );
@@ -1140,14 +1114,13 @@ static void fgIdleFunction ( void ) {
 // options.cxx needs to see this for toggle_panel()
 // Handle new window size or exposure
 void fgReshape( int width, int height ) {
-    if ( ! current_options.get_panel_status() ) {
-       current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
+    if ( ! current_options.get_panel_status() || idle_state != 1000 ) {
+       current_view.set_win_ratio( height / width );
        glViewport(0, 0 , (GLint)(width), (GLint)(height) );
     } else {
-       current_view.set_win_ratio( (GLfloat) width / 
-                                   ((GLfloat) (height)*0.4232) );
-       glViewport(0, (GLint)((height)*0.5768), (GLint)(width), 
-                   (GLint)((height)*0.4232) );
+       current_view.set_win_ratio( (height*0.4232) / width );
+       glViewport(0, (GLint)((height)*0.5768),
+                  (GLint)(width), (GLint)((height)*0.4232) );
     }
 
     current_view.set_winWidth( width );
@@ -1155,13 +1128,16 @@ void fgReshape( int width, int height ) {
     current_view.force_update_fov_math();
 
     // set these fov to be the same as in fgRenderFrame()
-    float x_fov = current_options.get_fov();
-    float y_fov = x_fov * 1.0 / current_view.get_win_ratio();
-    ssgSetFOV( x_fov, y_fov );
+    // float x_fov = current_options.get_fov();
+    // float y_fov = x_fov * 1.0 / current_view.get_win_ratio();
+    // ssgSetFOV( x_fov, y_fov );
 
-    glViewport ( 0, 0, width, height );
+    // glViewport ( 0, 0, width, height );
     float fov = current_options.get_fov();
-    ssgSetFOV(fov * current_view.get_win_ratio(), fov);
+    // ssgSetFOV(fov * current_view.get_win_ratio(), fov);
+    ssgSetFOV(fov, fov * current_view.get_win_ratio());
+
+    fgHUDReshape();
 
     if ( idle_state == 1000 ) {
        // yes we've finished all our initializations and are running
@@ -1199,9 +1175,10 @@ int fgGlutInit( int *argc, char **argv ) {
     } else {
        // Open the cool new 'game mode' window
        char game_mode_str[256];
-       sprintf( game_mode_str, "width=%d height=%d bpp=32",
+       sprintf( game_mode_str, "width=%d height=%d bpp=%d",
                 current_options.get_xsize(),
-                current_options.get_ysize() );
+                current_options.get_ysize(),
+                current_options.get_bpp());
 
        FG_LOG( FG_GENERAL, FG_INFO, 
                "game mode params = " << game_mode_str );
@@ -1305,12 +1282,11 @@ int main( int argc, char **argv ) {
     // seed the random number generater
     fg_srandom();
 
-    // AIRCRAFT defined in uiuc_aircraft.h
-    // AIRCRAFTDIR defined in uiuc_aircraftdir.h
-    aircraft_ = new AIRCRAFT;
-    aircraftdir_ = new AIRCRAFTDIR;
     aircraft_dir = ""; // Initialize the Aircraft directory to "" (UIUC)
 
+    // needs to happen before we parse command line options
+    globals = new FGGlobals;
+
     // Load the configuration parameters
     if ( !fgInitConfig(argc, argv) ) {
        FG_LOG( FG_GENERAL, FG_ALERT, "Config option parsing failed ..." );
@@ -1339,13 +1315,65 @@ int main( int argc, char **argv ) {
     // fonts !!!
     guiInit();
 
+    // set current_options lon/lat if an airport id is specified
+    if ( current_options.get_airport_id().length() ) {
+       // fgSetPosFromAirportID( current_options.get_airport_id() );
+       fgSetPosFromAirportIDandHdg( current_options.get_airport_id(),
+                                    current_options.get_heading() );
+    }
+
     // Initialize time
-    FGTime::cur_time_params = new FGTime();
-    // FGTime::cur_time_params->init( cur_fdm_state->get_Longitude(), 
-    //                                cur_fdm_state->get_Latitude() );
-    // FGTime::cur_time_params->update( cur_fdm_state->get_Longitude() );
-    FGTime::cur_time_params->init( 0.0, 0.0 );
-    FGTime::cur_time_params->update( 0.0, 0.0, 0.0 );
+    FGPath zone( current_options.get_fg_root() );
+    zone.append( "Timezone" );
+    SGTime *t = new SGTime( current_options.get_lon() * DEG_TO_RAD,
+                           current_options.get_lat() * DEG_TO_RAD,
+                           zone.str() );
+
+    // Handle potential user specified time offsets
+    time_t cur_time = t->get_cur_time();
+    time_t currGMT = sgTimeGetGMT( gmtime(&cur_time) );
+    time_t systemLocalTime = sgTimeGetGMT( localtime(&cur_time) );
+    time_t aircraftLocalTime = 
+       sgTimeGetGMT( fgLocaltime(&cur_time, t->get_zonename() ) );
+
+    // Okay, we now have six possible scenarios
+    switch ( current_options.get_time_offset_type() ) {
+    case fgOPTIONS::FG_TIME_SYS_OFFSET:
+       globals->set_warp( current_options.get_time_offset() );
+       break;
+    case fgOPTIONS::FG_TIME_GMT_OFFSET:
+       globals->set_warp( current_options.get_time_offset() - 
+                          (currGMT - systemLocalTime) );
+       break;
+    case fgOPTIONS::FG_TIME_LAT_OFFSET:
+       globals->set_warp( current_options.get_time_offset() - 
+                          (aircraftLocalTime - systemLocalTime) );
+       break;
+    case fgOPTIONS::FG_TIME_SYS_ABSOLUTE:
+       globals->set_warp( current_options.get_time_offset() - cur_time );
+       //printf("warp = %d\n", warp); 
+       break;
+    case fgOPTIONS::FG_TIME_GMT_ABSOLUTE:
+       globals->set_warp( current_options.get_time_offset() - currGMT );
+       break;
+    case fgOPTIONS::FG_TIME_LAT_ABSOLUTE:
+       globals->set_warp( current_options.get_time_offset() - 
+                          (aircraftLocalTime - systemLocalTime) - 
+                          cur_time ); 
+       break;
+    default:
+       FG_LOG( FG_GENERAL, FG_ALERT, "Unsupported type" );
+       exit( -1 );
+    }
+
+    FG_LOG( FG_GENERAL, FG_INFO, "After time init, warp = " 
+           << globals->get_warp() );
+
+    globals->set_warp_delta( 0 );
+
+    t->update( 0.0, 0.0, globals->get_warp() );
+
+    globals->set_time_params( t );
 
     // Do some quick general initializations
     if( !fgInitGeneral()) {
@@ -1377,8 +1405,11 @@ int main( int argc, char **argv ) {
     // Initialize the sky
     FGPath ephem_data_path( current_options.get_fg_root() );
     ephem_data_path.append( "Astro" );
-    ephem = new FGEphemeris( ephem_data_path.c_str() );
-    ephem->update( FGTime::cur_time_params, 0.0 );
+    SGEphemeris *ephem = new SGEphemeris( ephem_data_path.c_str() );
+    ephem->update( globals->get_time_params()->getMjd(),
+                  globals->get_time_params()->getLst(),
+                  0.0 );
+    globals->set_ephem( ephem );
 
     FGPath sky_tex_path( current_options.get_fg_root() );
     sky_tex_path.append( "Textures" );
@@ -1386,12 +1417,24 @@ int main( int argc, char **argv ) {
     thesky = new SGSky;
     thesky->texture_path( sky_tex_path.str() );
 
-    ssgBranch *sky = thesky->build( 550.0, 550.0,
-                                   ephem->getNumPlanets(), 
-                                   ephem->getPlanets(), 60000.0,
-                                   ephem->getNumStars(),
-                                   ephem->getStars(), 60000.0 );
-    scene->addKid( sky );
+    thesky->build( 550.0, 550.0,
+                  globals->get_ephem()->getNumPlanets(), 
+                  globals->get_ephem()->getPlanets(), 60000.0,
+                  globals->get_ephem()->getNumStars(),
+                  globals->get_ephem()->getStars(), 60000.0 );
+
+    thesky->add_cloud_layer( 2600.0, 200.0, 50.0, 40000.0,
+                            SG_CLOUD_MOSTLY_SUNNY );
+    thesky->add_cloud_layer( 6000.0, 20.0, 10.0, 40000.0,
+                            SG_CLOUD_CIRRUS );
+
+    // thesky->add_cloud_layer( 1000.0, 200.0, 50.0, SG_CLOUD_MOSTLY_SUNNY );
+    // thesky->add_cloud_layer( 1800.0, 400.0, 100.0, SG_CLOUD_OVERCAST );
+    // thesky->add_cloud_layer( 5000.0, 20.0, 10.0, SG_CLOUD_CIRRUS );
+
+    // Initialize MagVar model
+    SGMagVar *magvar = new SGMagVar();
+    globals->set_mag( magvar );
 
     // Terrain branch
     terrain = new ssgBranch;