]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/main.cxx
Move the texture loader to SimGear
[flightgear.git] / src / Main / main.cxx
index 1ea7344e0acf9efb8839623827396dccd4d46ffc..048fb35687edb73fa903f75052890397324f806a 100644 (file)
 #include <simgear/compiler.h>
 
 #include STL_IOSTREAM
-#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
 SG_USING_STD(cerr);
 SG_USING_STD(endl);
-#endif
 
 #include <simgear/misc/exception.hxx>
 #include <simgear/ephemeris/ephemeris.hxx>
@@ -51,8 +49,7 @@ SG_USING_STD(endl);
 #  include <float.h>
 #endif
 
-#include <GL/glut.h>
-#include <GL/gl.h>
+#include GLUT_H
 
 #include <stdio.h>
 #include <string.h>            // for strcmp()
@@ -72,6 +69,7 @@ SG_USING_STD(endl);
 
 #include <plib/netChat.h>
 #include <plib/pu.h>
+#include <plib/sg.h>
 #include <plib/ssg.h>
 
 #include <simgear/constants.h>  // for VERSION
@@ -79,6 +77,10 @@ SG_USING_STD(endl);
 #include <simgear/math/polar3d.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
+#ifdef FG_USE_CLOUDS_3D
+#  include <simgear/sky/clouds3d/SkySceneLoader.hpp>
+#  include <simgear/sky/clouds3d/SkyUtil.hpp>
+#endif
 #include <simgear/sky/sky.hxx>
 #include <simgear/timing/sg_time.hxx>
 
@@ -90,19 +92,30 @@ SG_USING_STD(endl);
 #include <ATC/ATCdisplay.hxx>
 #include <ATC/AIMgr.hxx>
 
+
 #include <Autopilot/newauto.hxx>
 
+#include <Cockpit/hud.hxx>
 #include <Cockpit/cockpit.hxx>
 #include <Cockpit/radiostack.hxx>
-#include <Cockpit/steam.hxx>
 
 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
 #include <GUI/gui.h>
 #include <Model/acmodel.hxx>
+#include <Model/loader.hxx>
+#include <Model/model.hxx>
 #include <Model/modelmgr.hxx>
+#include <Main/location.hxx>
+#include <Model/panelnode.hxx>
 #ifdef FG_NETWORK_OLK
 #include <NetworkOLK/network.h>
 #endif
+
+#ifdef FG_MPLAYER_AS
+#include <MultiPlayer/multiplaytxmgr.hxx>
+#include <MultiPlayer/multiplayrxmgr.hxx>
+#endif
+
 #include <Objects/matlib.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
@@ -111,14 +124,14 @@ SG_USING_STD(endl);
 #  include <Sound/fg_fx.hxx>
 #  include <Sound/morse.hxx>
 #endif
+#include <Systems/system_mgr.hxx>
+#include <Instrumentation/instrument_mgr.hxx>
 #include <Time/FGEventMgr.hxx>
 #include <Time/fg_timer.hxx>
 #include <Time/light.hxx>
 #include <Time/sunpos.hxx>
 #include <Time/tmp.hxx>
 
-#include <Input/input.hxx>
-
 // ADA
 #include <simgear/misc/sgstream.hxx>
 #include <simgear/math/point3d.hxx>
@@ -126,10 +139,28 @@ SG_USING_STD(endl);
 #include <FDM/ADA.hxx>
 #include <Scenery/tileentry.hxx>
 
-#if !defined(sgi)
-// PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT = 0;
-// PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT = 0;
+#include "fg_commands.hxx"
+
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+#ifdef WIN32
+  typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC)(GLenum pname,
+                                                        GLfloat param);
+  typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC)(GLenum pname,
+                                                         const GLfloat *params);
+
+  PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT = 0;
+  PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT = 0;
+#elif linux
+  #include <GL/glx.h>
+
+  typedef void (* OpenGLFuncExt)(GLenum pname, GLfloat param);
+  typedef void (* OpenGLFuncExtv)(GLenum pname, const GLfloat *params);
+
+  OpenGLFuncExt glPointParameterfEXT = 0;
+  OpenGLFuncExtv glPointParameterfvEXT = 0;
 #endif
+#endif
+
 float default_attenuation[3] = {1.0, 0.0, 0.0};
 //Required for using GL_extensions
 void fgLoadDCS (void);
@@ -184,31 +215,29 @@ FGGeneral general;
 static int idle_state = 0;
 static long global_multi_loop;
 
-// forward declaration
-void fgReshape( int width, int height );
-
 // fog constants.  I'm a little nervous about putting actual code out
 // here but it seems to work (?)
 static const double m_log01 = -log( 0.01 );
 static const double sqrt_m_log01 = sqrt( m_log01 );
 static GLfloat fog_exp_density;
 static GLfloat fog_exp2_density;
-static GLfloat fog_exp2_punch_through;
-
-ssgRoot *lighting = NULL;
-// ssgBranch *airport = NULL;
+static GLfloat rwy_exp2_punch_through;
+static GLfloat taxi_exp2_punch_through;
+static GLfloat ground_exp2_punch_through;
 
 #ifdef FG_NETWORK_OLK
 ssgSelector *fgd_sel = NULL;
 ssgTransform *fgd_pos = NULL;
 #endif
 
-// current fdm/position used for view
-FGInterface cur_view_fdm;
-
 // Sky structures
 SGSky *thesky;
 
+#ifdef FG_USE_CLOUDS_3D
+  SkySceneLoader *sgClouds3d;
+  bool _bcloud_orig = true;
+#endif
+
 // hack
 sgMat4 copy_of_ssgOpenGLAxisSwapMatrix =
 {
@@ -239,6 +268,7 @@ sgMat4 copy_of_ssgOpenGLAxisSwapMatrix =
 //
 
 
+ssgSimpleState *cloud3d_imposter_state;
 ssgSimpleState *default_state;
 ssgSimpleState *hud_and_panel;
 ssgSimpleState *menus;
@@ -246,6 +276,7 @@ ssgSimpleState *menus;
 SGTimeStamp last_time_stamp;
 SGTimeStamp current_time_stamp;
 
+
 void fgBuildRenderStates( void ) {
     default_state = new ssgSimpleState;
     default_state->ref();
@@ -259,6 +290,20 @@ void fgBuildRenderStates( void ) {
     default_state->disable( GL_ALPHA_TEST );
     default_state->disable( GL_LIGHTING );
 
+    cloud3d_imposter_state = new ssgSimpleState;
+    cloud3d_imposter_state->ref();
+    cloud3d_imposter_state->enable( GL_TEXTURE_2D );
+    cloud3d_imposter_state->enable( GL_CULL_FACE );
+    cloud3d_imposter_state->enable( GL_COLOR_MATERIAL );
+    cloud3d_imposter_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
+    cloud3d_imposter_state->setMaterial( GL_DIFFUSE, 1, 1, 1, 1 );
+    cloud3d_imposter_state->setMaterial( GL_AMBIENT, 1, 1, 1, 1 );
+    cloud3d_imposter_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
+    cloud3d_imposter_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
+    cloud3d_imposter_state->enable( GL_BLEND );
+    cloud3d_imposter_state->enable( GL_ALPHA_TEST );
+    cloud3d_imposter_state->disable( GL_LIGHTING );
+
     hud_and_panel = new ssgSimpleState;
     hud_and_panel->ref();
     hud_and_panel->disable( GL_CULL_FACE );
@@ -294,7 +339,7 @@ void fgInitVisuals( void ) {
 
     glEnable( GL_LIGHTING );
     glEnable( GL_LIGHT0 );
-    glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+    // glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );  // done later with ssg
 
     sgVec3 sunpos;
     sgSetVec3( sunpos, l->sun_vec[0], l->sun_vec[1], l->sun_vec[2] );
@@ -329,7 +374,7 @@ void trRenderFrame( void ) {
     if ( fgPanelVisible() ) {
         GLfloat height = fgGetInt("/sim/startup/ysize");
         GLfloat view_h =
-            (current_panel->getViewHeight() - current_panel->getYOffset())
+            (globals->get_current_panel()->getViewHeight() - globals->get_current_panel()->getYOffset())
             * (height / 768.0) + 1;
         glTranslatef( 0.0, view_h, 0.0 );
     }
@@ -357,6 +402,7 @@ void trRenderFrame( void ) {
     // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
     // explicitely to black.
     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
+    glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE );
 
     ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
 
@@ -376,25 +422,26 @@ void trRenderFrame( void ) {
     ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
 
     // draw the lights
-    glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
+    glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
     ssgSetNearFar( scene_nearplane, scene_farplane );
-    ssgCullAndDraw( lighting );
+    ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
+
+    ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
 
-    thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
+    if (fgGetBool("/environment/clouds/status"))
+        thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
 
     globals->get_model_mgr()->draw();
     globals->get_aircraft_model()->draw();
-
-    // need to do this here as hud_and_panel state is static to
-    // main.cxx  and HUD and Panel routines have to be called with
-    // knowledge of the the TR struct < see gui.cxx::HighResDump()
-    hud_and_panel->apply();
 }
 
 
 // Update all Visuals (redraws anything graphics related)
 void fgRenderFrame() {
-  
+
+    GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
+
     // Process/manage pending events
     global_events.update( delta_time_sec );
 
@@ -416,13 +463,24 @@ void fgRenderFrame() {
     static double last_visibility = -9999;
 
     // update fog params
-    double actual_visibility       = thesky->get_visibility();
+    double actual_visibility;
+    if (fgGetBool("/environment/clouds/status"))
+        actual_visibility = thesky->get_visibility();
+    else
+        actual_visibility = fgGetDouble("/environment/visibility-m");
     if ( actual_visibility != last_visibility ) {
         last_visibility = actual_visibility;
 
         fog_exp_density = m_log01 / actual_visibility;
         fog_exp2_density = sqrt_m_log01 / actual_visibility;
-        fog_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 2.5 );
+        ground_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 1.5);
+        if ( actual_visibility < 8000 ) {
+            rwy_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 2.5);
+            taxi_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 1.5);
+        } else {
+            rwy_exp2_punch_through = sqrt_m_log01 / ( 8000 * 2.5 );
+            taxi_exp2_punch_through = sqrt_m_log01 / ( 8000 * 1.5 );
+        }
     }
 
     // double angle;
@@ -431,11 +489,11 @@ void fgRenderFrame() {
     // GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
     // GLfloat mat_shininess[] = { 10.0 };
     GLbitfield clear_mask;
-    
+
     if ( idle_state != 1000 ) {
        // still initializing, draw the splash screen
        if ( fgGetBool("/sim/startup/splash-screen") ) {
-           fgSplashUpdate(0.0);
+           fgSplashUpdate(0.0, 1.0);
        }
         // Keep resetting sim time while the sim is initializing
        globals->set_sim_time_sec( 0.0 );
@@ -451,8 +509,26 @@ void fgRenderFrame() {
        fgReshape( fgGetInt("/sim/startup/xsize"),
                   fgGetInt("/sim/startup/ysize") );
 
-       // set the sun position
-       glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+        if ( fgGetBool("/sim/rendering/clouds3d") ) {
+            glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
+            cloud3d_imposter_state->force();
+            glDisable( GL_FOG );
+            glColor4f( 1.0, 1.0, 1.0, 1.0 );
+            glEnable(GL_DEPTH_TEST);
+            glEnable(GL_BLEND);
+            glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ) ;
+
+#ifdef FG_USE_CLOUDS_3D
+            if ( _bcloud_orig ) {
+                Point3D c = globals->get_scenery()->get_center();
+                sgClouds3d->Set_Cloud_Orig( &c );
+                _bcloud_orig = false;
+            }
+            sgClouds3d->Update( current__view->get_absolute_view_pos() );
+#endif
+            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+            glDisable(GL_DEPTH_TEST);
+        }
 
        clear_mask = GL_DEPTH_BUFFER_BIT;
        if ( fgGetBool("/sim/rendering/wireframe") ) {
@@ -462,12 +538,12 @@ void fgRenderFrame() {
        if ( fgGetBool("/sim/rendering/skyblend") ) {
            if ( fgGetBool("/sim/rendering/textures") ) {
                // glClearColor(black[0], black[1], black[2], black[3]);
-               glClearColor(l->adj_fog_color[0], l->adj_fog_color[1], 
+               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], 
+           glClearColor(l->sky_color[0], l->sky_color[1],
                         l->sky_color[2], l->sky_color[3]);
            clear_mask |= GL_COLOR_BUFFER_BIT;
        }
@@ -499,19 +575,21 @@ void fgRenderFrame() {
 
        // update the sky dome
        if ( fgGetBool("/sim/rendering/skyblend") ) {
-           /* cout << "thesky->repaint() sky_color = "
+           /*
+             SG_LOG( SG_GENERAL, SG_BULK, "thesky->repaint() sky_color = "
                 << cur_light_params.sky_color[0] << " "
                 << cur_light_params.sky_color[1] << " "
                 << cur_light_params.sky_color[2] << " "
-                << cur_light_params.sky_color[3] << endl;
-           cout << "    fog = "
+                << cur_light_params.sky_color[3] );
+           SG_LOG( SG_GENERAL, SG_BULK, "    fog = "
                 << cur_light_params.fog_color[0] << " "
                 << cur_light_params.fog_color[1] << " "
                 << cur_light_params.fog_color[2] << " "
-                << cur_light_params.fog_color[3] << endl;
-           cout << "    sun_angle = " << cur_light_params.sun_angle
-                << "    moon_angle = " << cur_light_params.moon_angle
-                 << endl; */
+                << cur_light_params.fog_color[3] ); 
+           SG_LOG( SG_GENERAL, SG_BULK,
+                    "    sun_angle = " << cur_light_params.sun_angle
+                << "    moon_angle = " << cur_light_params.moon_angle );
+            */
            thesky->repaint( cur_light_params.sky_color,
                             cur_light_params.adj_fog_color,
                             cur_light_params.sun_angle,
@@ -520,28 +598,34 @@ void fgRenderFrame() {
                             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;
-           cout << "    zero_elev = " << zero_elev[0] << " "
+
+           /*
+            SG_LOG( SG_GENERAL, SG_BULK,
+                    "thesky->reposition( view_pos = " << view_pos[0] << " "
+                << view_pos[1] << " " << view_pos[2] );
+           SG_LOG( SG_GENERAL, SG_BULK,
+                    "    zero_elev = " << zero_elev[0] << " "
                 << zero_elev[1] << " " << zero_elev[2]
                 << " lon = " << cur_fdm_state->get_Longitude()
-                << " lat = " << cur_fdm_state->get_Latitude() << endl;
-           cout << "    sun_rot = " << cur_light_params.sun_rotation
-                << " gst = " << 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; */
+                << " lat = " << cur_fdm_state->get_Latitude() );
+           SG_LOG( SG_GENERAL, SG_BULK,
+                    "    sun_rot = " << cur_light_params.sun_rotation
+                << " gst = " << SGTime::cur_time_params->getGst() );
+           SG_LOG( SG_GENERAL, SG_BULK,
+                 "    sun ra = " << globals->get_ephem()->getSunRightAscension()
+              << " sun dec = " << globals->get_ephem()->getSunDeclination()
+              << " moon ra = " << globals->get_ephem()->getMoonRightAscension()
+              << " moon dec = " << globals->get_ephem()->getMoonDeclination() );
+            */
 
            thesky->reposition( current__view->get_view_pos(),
                                current__view->get_zero_elev(),
                                current__view->get_world_up(),
-                               longitude->getDoubleValue()
+                               current__view->getLongitude_deg()
                                  * SGD_DEGREES_TO_RADIANS,
-                               latitude->getDoubleValue()
+                               current__view->getLatitude_deg()
                                  * SGD_DEGREES_TO_RADIANS,
-                               altitude->getDoubleValue() * SG_FEET_TO_METER,
+                               current__view->getAltitudeASL_ft() * SG_FEET_TO_METER,
                                cur_light_params.sun_rotation,
                                globals->get_time_params()->getGst(),
                                globals->get_ephem()->getSunRightAscension(),
@@ -566,13 +650,11 @@ void fgRenderFrame() {
         // we only update GL_AMBIENT for our lights we will never get
         // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
         // explicitely to black.
-       GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
-       GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
        glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
 
        ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
        ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
-       // ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_white );
+       ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular );
 
        // texture parameters
        // glEnable( GL_TEXTURE_2D );
@@ -624,10 +706,14 @@ void fgRenderFrame() {
        }
 # endif
 
-       // position tile nodes and update range selectors
-       global_tile_mgr.prep_ssg_nodes(visibility_meters);
+#ifdef FG_MPLAYER_AS
+        // Update any multiplayer models
+        globals->get_multiplayer_rx_mgr()->Update();
+#endif
 
-       if ( fgGetBool("/sim/rendering/skyblend") ) {
+        if ( fgGetBool("/sim/rendering/skyblend") &&
+             fgGetBool("/sim/rendering/draw-otw") )
+        {
            // draw the sky backdrop
 
             // we need a white diffuse light for the phase of the moon
@@ -643,74 +729,154 @@ void fgRenderFrame() {
        glEnable( GL_DEPTH_TEST );
 
         ssgSetNearFar( scene_nearplane, scene_farplane );
-       ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
+
+        if ( fgGetBool("/sim/rendering/wireframe") ) {
+            // draw wire frame
+            glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+        }
+        if ( fgGetBool("/sim/rendering/draw-otw") ) {
+            ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
+        }
+
+       // This is a bit kludgy.  Every 200 frames, do an extra
+       // traversal of the scene graph without drawing anything, but
+       // with the field-of-view set to 360x360 degrees.  This
+       // ensures that out-of-range random objects that are not in
+       // the current view frustum will still be freed properly.
+       static int counter = 0;
+       counter++;
+       if (counter == 200) {
+         sgFrustum f;
+         f.setFOV(360, 360);
+                               // No need to put the near plane too close;
+                               // this way, at least the aircraft can be
+                               // culled.
+         f.setNearFar(1000, 1000000);
+         sgMat4 m;
+         ssgGetModelviewMatrix(m);
+         globals->get_scenery()->get_scene_graph()->cull(&f, m, true);
+         counter = 0;
+       }
 
        // change state for lighting here
 
-       // draw lighting
-       // Set punch through fog density
-       glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
+       // draw runway lighting
+       glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
+        ssgSetNearFar( scene_nearplane, scene_farplane );
 
-#ifdef FG_EXPERIMENTAL_LIGHTING
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
         // Enable states for drawing points with GL_extension
-       if (glutExtensionSupported("GL_EXT_point_parameters")) {
-            glEnable(GL_POINT_SMOOTH);
-            float quadratic[3] = {1.0, 0.01, 0.0001};
-            // get the address of our OpenGL extensions
-#if !defined(sgi)
-            glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC) 
-                wglGetProcAddress("glPointParameterfEXT");
-            glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC) 
-                wglGetProcAddress("glPointParameterfvEXT");
-#endif
+        glEnable(GL_POINT_SMOOTH);
+
+        if ( fgGetBool("/sim/rendering/distance-attenuation")
+             && glutExtensionSupported("GL_EXT_point_parameters") )
+        {
+            float quadratic[3] = {1.0, 0.001, 0.0000001};
             // makes the points fade as they move away
             glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, quadratic);
             glPointParameterfEXT(GL_POINT_SIZE_MIN_EXT, 1.0); 
-            glPointSize(4.0);
-
-            // Enable states for drawing runway lights with spherical mapping
-            glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-            glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-            glEnable(GL_TEXTURE_GEN_S);
-            glEnable(GL_TEXTURE_GEN_T);
-
-            //Maybe this is not the best way, but it works !!
-            glPolygonMode(GL_FRONT, GL_POINT);
-            glCullFace(GL_BACK);
-            glEnable(GL_CULL_FACE);
-       }
+        }
+        glPointSize(4.0);
 
-       glDisable( GL_LIGHTING );
         // blending function for runway lights
         glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
-       glEnable(GL_BLEND);
 #endif
 
-        ssgSetNearFar( scene_nearplane, scene_farplane );
-       ssgCullAndDraw( lighting );
+        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+        glEnable(GL_TEXTURE_GEN_S);
+        glEnable(GL_TEXTURE_GEN_T);
+        glPolygonMode(GL_FRONT, GL_POINT);
 
+        // draw runway lighting
+        if ( fgGetBool("/sim/rendering/draw-otw") ) {
+            ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
+        }
+
+        // change punch through and then draw taxi lighting
+       glFogf ( GL_FOG_DENSITY, fog_exp2_density );
+        // sgVec3 taxi_fog;
+        // sgSetVec3( taxi_fog, 0.0, 0.0, 0.0 );
+        // glFogfv ( GL_FOG_COLOR, taxi_fog );
+        if ( fgGetBool("/sim/rendering/draw-otw") ) {
+            ssgCullAndDraw( globals->get_scenery()->get_taxi_lights_root() );
+        }
+
+        // clean up lighting
+        glPolygonMode(GL_FRONT, GL_FILL);
+        glDisable(GL_TEXTURE_GEN_S);
+        glDisable(GL_TEXTURE_GEN_T);
+
+       //static int _frame_count = 0;
+       //if (_frame_count % 30 == 0) {
+       //  printf("SSG: %s\n", ssgShowStats());
+       //}
+       //else {
+       //  ssgShowStats();
+       //}
+       //_frame_count++;
 
-#ifdef FG_EXPERIMENTAL_LIGHTING
-       if (glutExtensionSupported("GL_EXT_point_parameters")) {
-            // Disable states used for runway lighting
-            glPolygonMode(GL_FRONT, GL_FILL);
 
-            glDisable(GL_TEXTURE_GEN_S);
-            glDisable(GL_TEXTURE_GEN_T);
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+        if ( fgGetBool("/sim/rendering/distance-attenuation")
+             && glutExtensionSupported("GL_EXT_point_parameters") )
+        {
             glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT,
                                   default_attenuation);
-       }
+        }
 
         glPointSize(1.0);
+        glDisable(GL_POINT_SMOOTH);
 #endif
 
+        // draw ground lighting
+       glFogf (GL_FOG_DENSITY, ground_exp2_punch_through);
+        if ( fgGetBool("/sim/rendering/draw-otw") ) {
+            ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
+        }
+
        if ( fgGetBool("/sim/rendering/skyblend") ) {
            // draw the sky cloud layers
-           thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
+            if ( fgGetBool("/environment/clouds/status") &&
+                 fgGetBool("/sim/rendering/draw-otw") )
+            {
+                thesky->postDraw( cur_fdm_state->get_Altitude()
+                                  * SG_FEET_TO_METER );
+            }
        }
 
-       globals->get_model_mgr()->draw();
-       globals->get_aircraft_model()->draw();
+        if ( fgGetBool("/sim/rendering/clouds3d") &&
+             fgGetBool("/sim/rendering/draw-otw") )
+        {
+            glDisable( GL_FOG );
+            glDisable( GL_LIGHTING );
+            // cout << "drawing new clouds" << endl;
+
+            glEnable(GL_DEPTH_TEST);
+            glEnable(GL_BLEND);
+            glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ) ;
+
+            /*
+            glEnable( GL_TEXTURE_2D );
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+            */
+
+#ifdef FG_USE_CLOUDS_3D
+            sgClouds3d->Draw((sgVec4 *)current__view->get_VIEW());
+#endif
+            glEnable( GL_FOG );
+            glEnable( GL_LIGHTING );
+            glEnable( GL_DEPTH_TEST );
+            glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+        }
+
+        if ( fgGetBool("/sim/rendering/draw-otw") ) {
+            globals->get_model_mgr()->draw();
+            globals->get_aircraft_model()->draw();
+        }
 
        // display HUD && Panel
        glDisable( GL_FOG );
@@ -718,9 +884,6 @@ void fgRenderFrame() {
        // glDisable( GL_CULL_FACE );
        // glDisable( GL_TEXTURE_2D );
 
-       // update the input subsystem
-       current_input.update(delta_time_sec);
-
        // update the controls subsystem
        globals->get_controls()->update(delta_time_sec);
 
@@ -729,12 +892,14 @@ void fgRenderFrame() {
 
        // Use the hud_and_panel ssgSimpleState for rendering the ATC output
        // This only works properly if called before the panel call
-       globals->get_ATC_display()->update(delta_time_sec);
+       if((fgGetBool("/sim/ATC/enabled")) || (fgGetBool("/sim/ai-traffic/enabled")))
+           globals->get_ATC_display()->update(delta_time_sec);
 
        // update the panel subsystem
-       if ( current_panel != NULL ) {
-           current_panel->update(delta_time_sec);
+       if ( globals->get_current_panel() != NULL ) {
+           globals->get_current_panel()->update(delta_time_sec);
        }
+        fgUpdate3DPanels();
 
        // We can do translucent menus, so why not. :-)
        menus->apply();
@@ -742,9 +907,16 @@ void fgRenderFrame() {
        puDisplay();
        // glDisable ( GL_BLEND ) ;
 
-       // glEnable( GL_FOG );
+        glEnable( GL_DEPTH_TEST );
+        glEnable( GL_FOG );
 
-       globals->get_logger()->update(delta_time_sec);
+        // Fade out the splash screen over the first three seconds.
+        double t = globals->get_sim_time_sec();
+        if ( t <= 1.0 ) {
+            fgSplashUpdate(0.0, 1.0);
+        } else if ( t <= 3.0) {
+            fgSplashUpdate(0.0, (3.0 - t) / 2.0);
+        }
     }
 
     glutSwapBuffers();
@@ -760,9 +932,6 @@ void fgUpdateTimeDepCalcs() {
     //SG_LOG(SG_FLIGHT,SG_INFO, "Updating time dep calcs()");
 
     fgLIGHT *l = &cur_light_params;
-    int i;
-
-    long multi_loop = 1;
 
     // Initialize the FDM here if it hasn't been and if we have a
     // scenery elevation hit.
@@ -774,7 +943,6 @@ void fgUpdateTimeDepCalcs() {
          globals->get_scenery()->get_cur_elev() > -9990 )
     {
        SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm");  
-       
        cur_fdm_state->init();
        if ( cur_fdm_state->get_bound() ) {
            cur_fdm_state->unbind();
@@ -782,6 +950,10 @@ void fgUpdateTimeDepCalcs() {
        cur_fdm_state->bind();
     }
 
+#ifndef FG_WEATHERCM
+    globals->get_environment_mgr()->update(delta_time_sec);
+#endif
+
     // conceptually, the following block could be done for each fdm
     // instance ...
     if ( !cur_fdm_state->get_inited() ) {
@@ -795,12 +967,6 @@ void fgUpdateTimeDepCalcs() {
 
        globals->get_autopilot()->update(delta_time_sec);
        cur_fdm_state->update(delta_time_sec);
-       FGSteam::update(delta_time_sec);
-    }
-
-    if ( !strcmp(fgGetString("/sim/view-mode"), "pilot") ) {
-       cur_view_fdm = *cur_fdm_state;
-       // do nothing
     }
 
     globals->get_model_mgr()->update(delta_time_sec);
@@ -834,12 +1000,6 @@ static const double alt_adjust_m = alt_adjust_ft * SG_FEET_TO_METER;
 // for the next move and update the display?
 static void fgMainLoop( void ) {
 
-    // Update the elapsed time.
-    current_time_stamp.stamp();
-    delta_time_sec = double(current_time_stamp - last_time_stamp) / 1000000.0;
-    last_time_stamp = current_time_stamp;
-    globals->inc_sim_time_sec( delta_time_sec );
-
     static const SGPropertyNode *longitude
        = fgGetNode("/position/longitude-deg");
     static const SGPropertyNode *latitude
@@ -851,6 +1011,19 @@ static void fgMainLoop( void ) {
     static const SGPropertyNode *cur_time_override
        = fgGetNode("/sim/time/cur-time-override", true);
 
+    // Update the elapsed time.
+    static bool first_time = true;
+    if ( first_time ) {
+        last_time_stamp.stamp();
+        first_time = false;
+    }
+    current_time_stamp.stamp();
+    delta_time_sec = double(current_time_stamp - last_time_stamp) / 1000000.0;
+    if (clock_freeze->getBoolValue())
+        delta_time_sec = 0;
+    last_time_stamp = current_time_stamp;
+    globals->inc_sim_time_sec( delta_time_sec );
+
     static long remainder = 0;
     long elapsed;
 #ifdef FANCY_FRAME_COUNTER
@@ -863,6 +1036,13 @@ static void fgMainLoop( void ) {
 
     SGTime *t = globals->get_time_params();
 
+    sglog().setLogLevels( SG_ALL, (sgDebugPriority)fgGetInt("/sim/log-level") );
+
+    FGLocation * acmodel_location = 0;
+    if(cur_fdm_state->getACModel() != 0) {
+      acmodel_location = (FGLocation *)  cur_fdm_state->getACModel()->get3DModel()->getFGLocation();
+    }
+
     SG_LOG( SG_ALL, SG_DEBUG, "Running Main Loop");
     SG_LOG( SG_ALL, SG_DEBUG, "======= ==== ====");
 
@@ -888,10 +1068,6 @@ static void fgMainLoop( void ) {
     // init routine and we don't have to worry about it again.
 #endif
 
-#ifndef FG_WEATHERCM
-    globals->get_environment_mgr()->update(delta_time_sec);
-#endif
-
     // Fix elevation.  I'm just sticking this here for now, it should
     // probably move eventually
 
@@ -900,25 +1076,26 @@ static void fgMainLoop( void ) {
           cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
           cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
 
-    if ( globals->get_scenery()->get_cur_elev() > -9990
-         && cur_fdm_state->get_inited() )
-    {
-       if ( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER < 
-            (globals->get_scenery()->get_cur_elev() + alt_adjust_m - 3.0) ) {
+// Curt is this code used?  I don't see any problems when I comment it out.
+    if ( acmodel_location != 0 ) {
+      if ( acmodel_location->get_cur_elev_m() > -9990 && cur_fdm_state->get_inited() ) {
+       if ( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER < 
+            (acmodel_location->get_cur_elev_m() + alt_adjust_m - 3.0) ) {
            // now set aircraft altitude above ground
            printf("(*) Current Altitude = %.2f < %.2f forcing to %.2f\n", 
                   cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
-                  globals->get_scenery()->get_cur_elev() + alt_adjust_m - 3.0,
-                  globals->get_scenery()->get_cur_elev() + alt_adjust_m );
-           cur_fdm_state->set_Altitude( globals->get_scenery()->get_cur_elev() 
-                                         + alt_adjust_m );
-
+                  acmodel_location->get_cur_elev_m() + alt_adjust_m - 3.0,
+                  acmodel_location->get_cur_elev_m() + alt_adjust_m );
+           cur_fdm_state->set_Altitude( (acmodel_location->get_cur_elev_m() 
+                                                + alt_adjust_m) * SG_METER_TO_FEET );
            SG_LOG( SG_ALL, SG_DEBUG, 
                    "<*> resetting altitude to " 
                    << cur_fdm_state->get_Altitude() * SG_FEET_TO_METER
                    << " meters" );
        }
+      }
     }
+// End of code in question. (see Curt is this code used? above)
 
     /* printf("Adjustment - ground = %.2f  runway = %.2f  alt = %.2f\n",
           scenery.get_cur_elev(),
@@ -998,6 +1175,7 @@ static void fgMainLoop( void ) {
 #else
     if ( (t->get_cur_time() != last_time) && (last_time > 0) ) {
        general.set_frame_rate( frames );
+        fgSetInt("/sim/frame-rate", frames);
        SG_LOG( SG_ALL, SG_DEBUG, 
                "--> Frame rate is = " << general.get_frame_rate() );
        frames = 0;
@@ -1007,10 +1185,12 @@ static void fgMainLoop( void ) {
 #endif
 
     // Run ATC subsystem
-    globals->get_ATC_mgr()->update(delta_time_sec);
+    if (fgGetBool("/sim/ATC/enabled"))
+        globals->get_ATC_mgr()->update(delta_time_sec);
 
     // Run the AI subsystem
-    // globals->get_AI_mgr()->update(delta_time_sec);
+    if (fgGetBool("/sim/ai-traffic/enabled"))
+        globals->get_AI_mgr()->update(delta_time_sec);
 
     // Run flight model
 
@@ -1040,10 +1220,8 @@ static void fgMainLoop( void ) {
                "Elapsed time is zero ... we're zinging" );
     }
 
-#if ! defined( macintosh )
     // Do any I/O channel work that might need to be done
-    fgIOProcess();
-#endif
+    globals->get_io()->update( delta_time_sec );
 
     // see if we need to load any deferred-load textures
     material_lib.load_next_deferred();
@@ -1052,18 +1230,69 @@ static void fgMainLoop( void ) {
 #ifdef ENABLE_AUDIO_SUPPORT
     if ( fgGetBool("/sim/sound/audible")
            && globals->get_soundmgr()->is_working() ) {
-       globals->get_fx()->update(1); // FIXME: use dt
-       globals->get_soundmgr()->update(1); // FIXME: use dt
+        globals->get_soundmgr()->update( delta_time_sec );
     }
 #endif
 
-    // redraw display
-    fgRenderFrame();
+    globals->get_subsystem_mgr()->update(delta_time_sec);
 
-    // see if we need to load any new scenery tiles
+    //
+    // Tile Manager updates - see if we need to load any new scenery tiles.
+    //   this code ties together the fdm, viewer and scenery classes...
+    //   we may want to move this to it's own class at some point
+    //
     double visibility_meters = fgGetDouble("/environment/visibility-m");
-    global_tile_mgr.update( longitude->getDoubleValue(),
-                           latitude->getDoubleValue(), visibility_meters );
+    FGViewer *current_view = globals->get_current_view();
+
+    // update tile manager for FDM...
+    // ...only if location is different than the viewer (to avoid duplicating effort)
+    if( acmodel_location != current_view->getFGLocation() ) {
+      if( acmodel_location != 0 ) {
+        globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location,
+                                                 visibility_meters );
+        globals->get_tile_mgr()->
+            update( acmodel_location, visibility_meters,
+                    acmodel_location->get_absolute_view_pos() );
+        // save results of update in FGLocation for fdm...
+        if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
+          acmodel_location->
+              set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
+        }
+        acmodel_location->
+            set_tile_center( globals->get_scenery()->get_next_center() );
+      }
+    }
+
+    globals->get_tile_mgr()->prep_ssg_nodes( current_view->getFGLocation(),
+                                             visibility_meters );
+    // update tile manager for view...
+    // IMPORTANT!!! the tilemgr update for view location _must_ be done last 
+    // after the FDM's until all of Flight Gear code references the viewer's location
+    // for elevation instead of the "scenery's" current elevation.
+    FGLocation *view_location = globals->get_current_view()->getFGLocation();
+    globals->get_tile_mgr()->update( view_location, visibility_meters,
+                                     current_view->get_absolute_view_pos() );
+    // save results of update in FGLocation for fdm...
+    if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
+      current_view->getFGLocation()->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
+    }
+    current_view->getFGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
+
+    // If fdm location is same as viewer's then we didn't do the update for fdm location 
+    //   above so we need to save the viewer results in the fdm FGLocation as well...
+    if( acmodel_location == current_view->getFGLocation() ) {
+      if( acmodel_location != 0 ) {
+        if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
+          acmodel_location->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
+        }
+        acmodel_location->set_tile_center( globals->get_scenery()->get_next_center() );
+      }
+    }
+
+    // END Tile Manager udpates
+
+    // redraw display
+    fgRenderFrame();
 
     SG_LOG( SG_ALL, SG_DEBUG, "" );
 }
@@ -1108,26 +1337,6 @@ static void fgIdleFunction ( void ) {
 
            system ( command.c_str() );
        }
-
-        // This is an 'easter egg' which is kind of a hard thing to
-        // hide in an open source project -- so I won't try very hard
-        // to hide it.  If you are looking at this now, please, you
-        // don't want to ruin the surprise. :-) Just forget about it
-        // and don't look any further; unless it is causing an actual
-        // problem for you, which it shouldn't, and I hope it doesn't!
-        // :-)
-        if ( globals->get_time_params()->getGmt()->tm_mon == 4 
-             && globals->get_time_params()->getGmt()->tm_mday == 19 )
-        {
-            string url = "http://www.flightgear.org/Music/invasion.mp3";
-#if defined( __CYGWIN__ ) || defined( WIN32 )
-            string command = "start /m " + url;
-#else
-            string command = "mpg123 " + url + "> /dev/null 2>&1";
-#endif
-            system( command.c_str() );
-        }
-
 #endif
 
        idle_state++;
@@ -1158,6 +1367,9 @@ static void fgIdleFunction ( void ) {
        // setup OpenGL view parameters
        fgInitVisuals();
 
+        // Read the list of available aircrafts
+        fgReadAircraft();
+
        idle_state++;
     } else if ( idle_state == 5 ) {
 
@@ -1166,7 +1378,7 @@ static void fgIdleFunction ( void ) {
        // sleep(1);
        idle_state = 1000;
 
-       cout << "Panel visible = " << fgPanelVisible() << endl;
+       SG_LOG( SG_GENERAL, SG_INFO, "Panel visible = " << fgPanelVisible() );
        fgReshape( fgGetInt("/sim/startup/xsize"),
                   fgGetInt("/sim/startup/ysize") );
     } 
@@ -1178,7 +1390,7 @@ static void fgIdleFunction ( void ) {
        glutIdleFunc(fgMainLoop);
     } else {
        if ( fgGetBool("/sim/startup/splash-screen") ) {
-           fgSplashUpdate(0.0);
+           fgSplashUpdate(0.0, 1.0);
        }
     }
 }
@@ -1190,8 +1402,8 @@ void fgReshape( int width, int height ) {
 
     if ( (!fgGetBool("/sim/virtual-cockpit"))
         && fgPanelVisible() && idle_state == 1000 ) {
-       view_h = (int)(height * (current_panel->getViewHeight() -
-                                current_panel->getYOffset()) / 768.0);
+       view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
+                                globals->get_current_panel()->getYOffset()) / 768.0);
     } else {
        view_h = height;
     }
@@ -1213,10 +1425,16 @@ void fgReshape( int width, int height ) {
               viewmgr->get_current_view()->get_v_fov() );
 
     fgHUDReshape();
+
+#ifdef FG_USE_CLOUDS_3D
+    sgClouds3d->Resize( viewmgr->get_current_view()->get_h_fov(),
+                        viewmgr->get_current_view()->get_v_fov() );
+#endif
+
 }
 
 // Initialize GLUT and define a main window
-int fgGlutInit( int *argc, char **argv ) {
+static bool fgGlutInit( int *argc, char **argv ) {
 
 #if !defined( macintosh )
     // GLUT will extract all glut specific options so later on we only
@@ -1224,8 +1442,12 @@ int fgGlutInit( int *argc, char **argv ) {
     glutInit(argc, argv);
 #endif
 
-    // Define Display Parameters
-    glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+    // Define Display Parameters. Clouds3d works best with --bpp32 option
+    if ( fgGetBool("/sim/rendering/clouds3d") ) {
+        glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ALPHA );
+    } else {
+        glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+    }
 
     SG_LOG( SG_GENERAL, SG_INFO, "Opening a window: " <<
            fgGetInt("/sim/startup/xsize") << "x"
@@ -1294,12 +1516,12 @@ int fgGlutInit( int *argc, char **argv ) {
     general.set_glDepthBits( tmp );
     SG_LOG ( SG_GENERAL, SG_INFO, "Depth buffer bits = " << tmp );
 
-    return 1;
+    return true;
 }
 
 
 // Initialize GLUT event handlers
-int fgGlutInitEvents( void ) {
+static bool fgGlutInitEvents( void ) {
     // call fgReshape() on window resizes
     glutReshapeFunc( fgReshape );
 
@@ -1312,12 +1534,11 @@ int fgGlutInitEvents( void ) {
     // draw the scene
     glutDisplayFunc( fgRenderFrame );
 
-    return 1;
+    return true;
 }
 
-
-// Main loop
-int mainLoop( int argc, char **argv ) {
+// Main top level initialization
+static bool fgMainInit( int argc, char **argv ) {
 
 #if defined( macintosh )
     freopen ("stdout.txt", "w", stdout );
@@ -1326,7 +1547,7 @@ int mainLoop( int argc, char **argv ) {
 #endif
 
     // set default log levels
-     sglog().setLogLevels( SG_ALL, SG_INFO );
+    sglog().setLogLevels( SG_ALL, SG_INFO );
 
     string version;
 #ifdef FLIGHTGEAR_VERSION
@@ -1335,7 +1556,8 @@ int mainLoop( int argc, char **argv ) {
     version = "unknown version";
 #endif
     SG_LOG( SG_GENERAL, SG_INFO, "FlightGear:  Version "
-           << version << endl );
+           << version );
+    SG_LOG( SG_GENERAL, SG_INFO, "Built with " << SG_COMPILER_STR << endl );
 
     // Allocate global data structures.  This needs to happen before
     // we parse command line options
@@ -1363,22 +1585,24 @@ int mainLoop( int argc, char **argv ) {
     fgInitFGRoot(argc, argv);
 
     // Check for the correct base package version
+    static char required_version[] = "0.9.1";
     string base_version = fgBasePackageVersion();
-    if ( !(base_version == "0.7.9") ) {
+    if ( !(base_version == required_version) ) {
         // tell the operator how to use this application
-        fgUsage();
 
-       SG_LOG( SG_GENERAL, SG_ALERT, "Base package check failed ... "
-               << "Found version " << base_version << " at: "
-                << globals->get_fg_root() );
-        SG_LOG( SG_GENERAL, SG_ALERT, "Please upgrade to version 0.7.9" );
+       cerr << endl << "Base package check failed ... " \
+            << "Found version " << base_version << " at: " \
+             << globals->get_fg_root() << endl;
+        cerr << "Please upgrade to version: " << required_version << endl;
        exit(-1);
     }
 
     // Initialize the Aircraft directory to "" (UIUC)
     aircraft_dir = "";
 
-    // Load the configuration parameters
+    // Load the configuration parameters.  (Command line options
+    // overrides config file options.  Config file options override
+    // defaults.)
     if ( !fgInitConfig(argc, argv) ) {
        SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." );
        exit(-1);
@@ -1409,35 +1633,35 @@ int mainLoop( int argc, char **argv ) {
     // fonts !!!
     guiInit();
 
+    // Read the list of available aircrafts
+    fgReadAircraft();
+
 #ifdef GL_EXT_texture_lod_bias
     glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, -0.5 ) ;
 #endif
 
-    // Set position relative to glide slope if requested
-    fgSetPosFromGlideSlope();
-
-    // If we have an explicit, in-range lon/lat, use it.
-    // If not, check for an airport-id and use that.
-    // If not, default to the middle of the KSFO field.
-    // The default values for lon/lat are deliberately out of range
-    // so that the airport-id can take effect; valid lon/lat will
-    // override airport-id, however.
-    double lon_deg = fgGetDouble("/position/longitude-deg");
-    double lat_deg = fgGetDouble("/position/latitude-deg");
-    if (lon_deg < -180 || lon_deg > 180 || lat_deg < -90 || lat_deg > 90) {
-      if ( fgGetString("/sim/startup/airport-id")[0] != '\0' ) {
-       fgSetPosFromAirportIDandHdg( fgGetString("/sim/startup/airport-id"),
-                                    fgGetDouble("/orientation/heading-deg") );
-        // set tower position (a little off the heading for single 
-       // runway airports)
-        fgSetTowerPosFromAirportID( fgGetString("/sim/startup/airport-id"),
-                                   fgGetDouble("orientation/heading") );
-      } else {
-                               // Default to middle of KSFO field
-       fgSetDouble("/position/longitude-deg", -122.374843);
-       fgSetDouble("/position/latitude-deg", 37.619002);
-      }
-    }
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+            // get the address of our OpenGL extensions
+    if ( fgGetBool("/sim/rendering/distance-attenuation") )
+    {
+#ifdef WIN32
+        glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC) 
+            wglGetProcAddress("glPointParameterfEXT");
+        glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC) 
+            wglGetProcAddress("glPointParameterfvEXT");
+#elif linux
+        glPointParameterfEXT = (OpenGLFuncExt) 
+            glXGetProcAddressARB((GLubyte *)"glPointParameterfEXT");
+        glPointParameterfvEXT = (OpenGLFuncExtv) 
+            glXGetProcAddressARB((GLubyte *)"glPointParameterfvEXT");
+#endif
+   }
+#endif
+
+    // based on the requested presets, calculate the true starting
+    // lon, lat
+    fgInitNav();
+    fgInitPosition();
 
     SGTime *t = fgInitTime();
     globals->set_time_params( t );
@@ -1454,40 +1678,23 @@ int mainLoop( int argc, char **argv ) {
 
     // Initialize the global scenery manager
     globals->set_scenery( new FGScenery );
+    globals->get_scenery()->init();
+    globals->get_scenery()->bind();
 
-    // Scene graph root
-    globals->get_scenery()->set_scene_graph(new ssgRoot);
-    globals->get_scenery()->get_scene_graph()->setName( "Scene" );
-
-    lighting = new ssgRoot;
-    lighting->setName( "Lighting" );
-
-    // Terrain branch
-    globals->get_scenery()->set_terrain_branch(new ssgBranch);
-    globals->get_scenery()->get_terrain_branch()->setName( "Terrain" );
-    globals->get_scenery()->get_scene_graph()->addKid( globals->get_scenery()->get_terrain_branch() );
-
-    globals->get_scenery()->set_models_branch(new ssgBranch);
-    globals->get_scenery()->get_models_branch()->setName( "Models" );
-    globals->get_scenery()->get_scene_graph()->addKid( globals->get_scenery()->get_models_branch() );
-
-    globals->get_scenery()->set_aircraft_branch(new ssgBranch);
-    globals->get_scenery()->get_aircraft_branch()->setName( "Aircraft" );
-    globals->get_scenery()->get_scene_graph()->addKid( globals->get_scenery()->get_aircraft_branch() );
-
-    // Lighting
-    globals->get_scenery()->set_gnd_lights_branch(new ssgBranch);
-    globals->get_scenery()->get_gnd_lights_branch()->setName( "Ground Lighting" );
-    lighting->addKid( globals->get_scenery()->get_gnd_lights_branch() );
+    // Initialize the global tile manager
+    globals->set_tile_mgr( new FGTileMgr );
 
-    globals->get_scenery()->set_rwy_lights_branch(new ssgBranch);
-    globals->get_scenery()->get_rwy_lights_branch()->setName( "Runway Lighting" );
-    lighting->addKid( globals->get_scenery()->get_rwy_lights_branch() );
+    ////////////////////////////////////////////////////////////////////
+    // Initialize the property-based built-in commands
+    ////////////////////////////////////////////////////////////////////
+    fgInitCommands();
 
     ////////////////////////////////////////////////////////////////////
     // Initialize the general model subsystem.
     ////////////////////////////////////////////////////////////////////
 
+    globals->set_model_loader(new FGModelLoader);
+    globals->set_texture_loader(new FGTextureLoader);
     globals->set_model_mgr(new FGModelMgr);
     globals->get_model_mgr()->init();
     globals->get_model_mgr()->bind();
@@ -1519,7 +1726,16 @@ int mainLoop( int argc, char **argv ) {
                   0.0 );
     globals->set_ephem( ephem );
 
+                               // TODO: move to environment mgr
     thesky = new SGSky;
+    SGPath texture_path(globals->get_fg_root());
+    texture_path.append("Textures");
+    texture_path.append("Sky");
+    for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) {
+        SGCloudLayer * layer = new SGCloudLayer(texture_path.str());
+        thesky->add_cloud_layer(layer);
+    }
+
 
     SGPath sky_tex_path( globals->get_fg_root() );
     sky_tex_path.append( "Textures" );
@@ -1532,19 +1748,6 @@ int mainLoop( int argc, char **argv ) {
                   globals->get_ephem()->getNumStars(),
                   globals->get_ephem()->getStars(), 60000.0 );
 
-    if ( fgGetBool("/environment/clouds/status") ) {
-       // thesky->add_cloud_layer( 2000.0, 200.0, 50.0, 40000.0,
-        //                          SG_CLOUD_OVERCAST );
-       thesky->add_cloud_layer( fgGetDouble("/environment/clouds/altitude-ft") *
-                                SG_FEET_TO_METER,
-                                200.0, 50.0, 40000.0,
-                                SG_CLOUD_MOSTLY_CLOUDY );
-       // thesky->add_cloud_layer( 3000.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 );
-    }
-
     // Initialize MagVar model
     SGMagVar *magvar = new SGMagVar();
     globals->set_mag( magvar );
@@ -1573,7 +1776,7 @@ int mainLoop( int argc, char **argv ) {
 
     // we never actually get here ... but to avoid compiler warnings,
     // etc.
-    return 0;
+    return false;
 }
 
 
@@ -1607,6 +1810,25 @@ handleFPE (int num)
 }
 #endif
 
+#ifdef __APPLE__
+
+typedef struct
+{
+  int  lo;
+  int  hi;
+} PSN;
+
+extern "C" {
+  short CPSGetCurrentProcess(PSN *psn);
+  short CPSSetProcessName (PSN *psn, char *processname);
+  short CPSEnableForegroundOperation(PSN *psn, int _arg2, int _arg3, int _arg4, int _arg5);
+  short CPSSetFrontProcess(PSN *psn);
+};
+
+#define CPSEnableFG(psn) CPSEnableForegroundOperation(psn,0x03,0x3C,0x2C,0x1103)
+
+#endif
+
 // Main entry point; catch any exceptions that have made it this far.
 int main ( int argc, char **argv ) {
 
@@ -1625,10 +1847,24 @@ int main ( int argc, char **argv ) {
     _control87(MCW_EM, MCW_EM);  /* defined in float.h */
 #endif
 
+    // Keyboard focus hack
+#ifdef __APPLE__
+    {
+      PSN psn;
+
+      glutInit (&argc, argv);
+
+      CPSGetCurrentProcess(&psn);
+      CPSSetProcessName(&psn, "FlightGear");
+      CPSEnableFG(&psn);
+      CPSSetFrontProcess(&psn);
+    }
+#endif
+
     // FIXME: add other, more specific
     // exceptions.
     try {
-        mainLoop(argc, argv);
+        fgMainInit(argc, argv);
     } catch (sg_throwable &t) {
                                // We must use cerr rather than
                                // logging, since logging may be
@@ -1693,7 +1929,8 @@ void fgLoadDCS(void) {
                 // instance of the last object.
 
                 if ( strcmp(obj_filename,"repeat") != 0) {
-                    ship_obj = ssgLoad( obj_filename );
+                    ship_obj =
+                        globals->get_model_loader()->load_model( obj_filename );
                 }
       
                 if ( ship_obj != NULL ) {
@@ -1800,7 +2037,7 @@ void fgLoadDCS(void) {
                                                    //dummy_tile->lightmaps_sequence->setTraversalMaskBits( SSGTRAV_HOT );
                                                        lightpoints_transform->addKid( dummy_tile->lightmaps_sequence );
                                                        lightpoints_transform->ref();
-                                                       globals->get_scenery()->get_gnd_lights_branch()->addKid( lightpoints_transform );
+                                                       globals->get_scenery()->get_gnd_lights_root()->addKid( lightpoints_transform );
                                                } 
                                        } //if in1 
                 } //if objc