# include <config.h>
#endif
+#include <simgear/compiler.h>
+#include <simgear/misc/exception.hxx>
+
#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#endif
#include <GL/glut.h>
-#include <simgear/xgl/xgl.h>
+#include <GL/gl.h>
#include <stdio.h>
#include <string.h>
# include <unistd.h> // for stat()
#endif
+// #ifdef HAVE_LIBX11
+// # include <GL/glext.h>
+// #endif
+
+#include <plib/netChat.h>
#include <plib/pu.h>
#include <plib/ssg.h>
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
#include <GUI/gui.h>
#include <GUI/sgVec3Slider.hxx>
-#include <Joystick/joystick.hxx>
+// #include <Joystick/joystick.hxx>
#ifdef FG_NETWORK_OLK
#include <NetworkOLK/network.h>
#endif
+#include <Objects/matlib.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#ifdef ENABLE_AUDIO_SUPPORT
#include <Time/sunpos.hxx>
#include <Time/tmp.hxx>
+#include <Input/input.hxx>
+
// begin - added Venky
// $$$ begin - added VS Renganathan
#include <simgear/misc/sgstream.hxx>
#include "version.h"
-#include "bfi.hxx"
#include "fg_init.hxx"
#include "fg_io.hxx"
+#include "fg_props.hxx"
#include "globals.hxx"
-#include "keyboard.hxx"
#include "splash.hxx"
+#include "viewmgr.hxx"
#ifdef macintosh
# include <console.h> // -dw- for command line dialog
}
+// For HiRes screen Dumps using Brian Pauls TR Library
+void trRenderFrame( void ) {
+
+ if ( fgPanelVisible() ) {
+ GLfloat height = fgGetInt("/sim/startup/ysize");
+ GLfloat view_h =
+ (current_panel->getViewHeight() - current_panel->getYOffset())
+ * (height / 768.0) + 1;
+ glTranslatef( 0.0, view_h, 0.0 );
+ }
+
+ static double m_log01 = -log( 0.01 );
+ static double sqrt_m_log01 = sqrt( m_log01 );
+
+ static GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
+ static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
+
+ fgLIGHT *l = &cur_light_params;
+
+ glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
+ l->adj_fog_color[2], l->adj_fog_color[3]);
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ // set the opengl state to known default values
+ default_state->force();
+
+ // update fog params
+ double actual_visibility = thesky->get_visibility();
+ // GLfloat fog_exp_density = m_log01 / actual_visibility;
+ GLfloat fog_exp2_density = sqrt_m_log01 / actual_visibility;
+ GLfloat fog_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 1.5 );
+
+ glEnable( GL_FOG );
+ glFogf ( GL_FOG_DENSITY, fog_exp2_density);
+ glFogi ( GL_FOG_MODE, GL_EXP2 );
+ glFogfv ( GL_FOG_COLOR, l->adj_fog_color );
+
+ // GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
+ // 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.
+ glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
+
+ ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
+
+ // texture parameters
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
+
+ // we need a white diffuse light for the phase of the moon
+ ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, white );
+ thesky->preDraw();
+
+ // draw the ssg scene
+ // return to the desired diffuse color
+ ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
+ glEnable( GL_DEPTH_TEST );
+ ssgCullAndDraw( scene );
+
+ // draw the lights
+ glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
+ ssgCullAndDraw( lighting );
+
+ thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
+
+ // 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( void ) {
- // Update the BFI.
- FGBFI::update();
+ // Update the default (kludged) properties.
+ fgUpdateProps();
fgLIGHT *l = &cur_light_params;
static double last_visibility = -9999;
sgVec3 po; // chase view pilot_offset
sgVec3 wup; // chase view world up
- sgSetVec3( po, 0.0, 0.0, 50.0 );
+ sgSetVec3( po, 0.0, 0.0, 100.0 );
sgCopyVec3( wup, pilot_view->get_world_up() );
sgMat4 CXFM; // chase view + pilot offset xform
sgMakeRotMat4( CXFM,
// cout << "----> updating fog params" << endl;
// for GL_FOG_EXP
- fog_exp_density = -log(0.01 / actual_visibility);
+ fog_exp_density = -log(0.01) / actual_visibility;
// for GL_FOG_EXP2
fog_exp2_density = sqrt( -log(0.01) ) / actual_visibility;
}
glEnable( GL_DEPTH_TEST );
- if ( fgGetString("/sim/rendering/fog") != "disabled" ) {
+ if ( fgGetString("/sim/rendering/fog") != (string)"disabled" ) {
glEnable( GL_FOG );
glFogi( GL_FOG_MODE, GL_EXP2 );
glFogfv( GL_FOG_COLOR, l->adj_fog_color );
ssgGetLight( 0 ) -> setPosition( l->sun_vec );
// GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
- // we only set GL_AMBIENT we will never get a completely dark
- // scene. Thus instead of playing with GL_AMBIENT, we just
- // set that to black and instead modify GL_LIGHT_MODEL_AMBIENT.
+ // 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 );
// set up moving parts
if (flaps_selector != NULL) {
- flaps_selector->select( (controls.get_flaps() > 0.5f) ? 1 : 2 );
+ flaps_selector->select( (globals->get_controls()->get_flaps() > 0.5f) ? 1 : 2 );
}
if (prop_selector != NULL) {
int propsel_mask = 0;
+ double rpm = fgGetDouble("/engines/engine[0]/rpm");
for (int i = 0; i < acmodel_npropsettings; i++) {
- if (FGBFI::getRPM() >= acmodel_proprpms[i][0] &&
- FGBFI::getRPM() <= acmodel_proprpms[i][1]) {
+ if (rpm >= acmodel_proprpms[i][0] &&
+ rpm <= acmodel_proprpms[i][1]) {
propsel_mask |= 1 << i;
}
}
// glDisable( GL_CULL_FACE );
// glDisable( GL_TEXTURE_2D );
+ // update the input subsystem
+ current_input.update();
+
// update the controls subsystem
- controls.update();
+ globals->get_controls()->update();
hud_and_panel->apply();
fgCockpitUpdate();
cur_fdm_state->update( 0 );
FGSteam::update( 0 );
- if ( global_tile_mgr.queue_size() == 0 ) {
+ //if ( global_tile_mgr.queue_size() == 0 ) {
initial_freeze = false;
- }
+ //}
}
if ( fgGetString("/sim/view-mode") == "pilot" ) {
#if defined( ENABLE_PLIB_JOYSTICK )
// Read joystick and update control settings
- if ( fgGetString("/sim/control-mode") == "joystick" )
- {
- fgJoystickRead();
- }
+ // if ( fgGetString("/sim/control-mode") == "joystick" )
+ // {
+ // 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
cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
+ // cout << "Warp = " << globals->get_warp() << endl;
+
// update "time"
if ( globals->get_warp_delta() != 0 ) {
globals->inc_warp( globals->get_warp_delta() );
#endif
// see if we need to load any new scenery tiles
- global_tile_mgr.update( cur_fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES,
- cur_fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES );
+ global_tile_mgr.update( cur_fdm_state->get_Longitude()
+ * SGD_RADIANS_TO_DEGREES,
+ cur_fdm_state->get_Latitude()
+ * SGD_RADIANS_TO_DEGREES );
+
+ // see if we need to load any deferred-load textures
+ material_lib.load_next_deferred();
// Process/manage pending events
global_events.Process();
s1->set_pitch( pitch );
s1->set_volume( volume );
} else {
- double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
+ double param
+ = globals->get_controls()->get_throttle( 0 ) * 2.0 + 1.0;
s1->set_pitch( param );
s1->set_volume( param );
}
idle_state++;
} else if ( idle_state == 1 ) {
+ // Initialize audio support
+#ifdef ENABLE_AUDIO_SUPPORT
+
// Start the intro music
#if !defined(WIN32)
if ( fgGetBool("/sim/startup/intro-music") ) {
- string lockfile = "/tmp/mpg123.running";
SGPath mp3file( globals->get_fg_root() );
mp3file.append( "Sounds/intro.mp3" );
- string command = "(touch " + lockfile + "; mpg123 "
- + mp3file.str() + "> /dev/null 2>&1; /bin/rm "
- + lockfile + ") &";
SG_LOG( SG_GENERAL, SG_INFO,
"Starting intro music: " << mp3file.str() );
+
+ string command = "mpg123 " + mp3file.str() + "> /dev/null 2>&1";
system ( command.c_str() );
}
+#endif // !WIN32
+
+ FGSoundMgr *soundmgr = new FGSoundMgr;
+ globals->set_soundmgr( soundmgr );
+
+ if ( fgGetBool("/sim/sound") ) {
+ globals->get_soundmgr()->init();
+
+ s1 = new FGSimpleSound( fgGetString("/sim/sounds/engine",
+ "Sounds/wasp.wav") );
+ globals->get_soundmgr()->add( s1, "engine loop" );
+ globals->get_soundmgr()->play_looped( "engine loop" );
+ SG_LOG( SG_GENERAL, SG_INFO,
+ "Rate = " << s1->get_sample()->getRate()
+ << " Bps = " << s1->get_sample()->getBps()
+ << " Stereo = " << s1->get_sample()->getStereo() );
+
+ // s2 = new FGSimpleSound( "Sounds/corflaps.wav" );
+ // s2->set_volume( 0.3 );
+ // globals->get_soundmgr()->add( s2, "flaps" );
+ }
#endif
idle_state++;
idle_state++;
} else if ( idle_state == 6 ) {
- // Initialize audio support
-#ifdef ENABLE_AUDIO_SUPPORT
-
-#if !defined(WIN32)
- if ( fgGetBool("/sim/startup/intro-music") ) {
- // Let's wait for mpg123 to finish
- string lockfile = "/tmp/mpg123.running";
- struct stat stat_buf;
-
- SG_LOG( SG_GENERAL, SG_INFO,
- "Waiting for mpg123 player to finish ..." );
- while ( stat(lockfile.c_str(), &stat_buf) == 0 ) {
- // file exist, wait ...
- sleep(1);
- SG_LOG( SG_GENERAL, SG_INFO, ".");
- }
- SG_LOG( SG_GENERAL, SG_INFO, "");
- }
-#endif // WIN32
-
- if ( fgGetBool("/sim/sound") ) {
- globals->get_soundmgr()->init();
-
- s1 = new FGSimpleSound( fgGetString("/sim/sounds/engine",
- "Sounds/wasp.wav") );
- globals->get_soundmgr()->add( s1, "engine loop" );
- globals->get_soundmgr()->play_looped( "engine loop" );
- SG_LOG( SG_GENERAL, SG_INFO,
- "Rate = " << s1->get_sample()->getRate()
- << " Bps = " << s1->get_sample()->getBps()
- << " Stereo = " << s1->get_sample()->getStereo() );
-
- s2 = new FGSimpleSound( "Sounds/corflaps.wav" );
- // FGMorse mmm;
- // mmm.init();
- // s2 = mmm.make_ident( "JLI" );
- s2->set_volume( 0.3 );
- globals->get_soundmgr()->add( s2, "flaps" );
- }
-#endif
-
// sleep(1);
idle_state = 1000;
glutReshapeFunc( fgReshape );
// call GLUTkey() on keyboard event
- glutKeyboardFunc( GLUTkey );
- glutSpecialFunc( GLUTspecialkey );
+ glutKeyboardFunc(GLUTkey);
+ glutKeyboardUpFunc(GLUTkeyup);
+ glutSpecialFunc(GLUTspecialkey);
+ glutSpecialUpFunc(GLUTspecialkeyup);
// call guiMouseFunc() whenever our little rodent is used
glutMouseFunc ( guiMouseFunc );
}
-// Main ...
-int main( int argc, char **argv ) {
+// Main loop
+int mainLoop( int argc, char **argv ) {
#if defined( macintosh )
freopen ("stdout.txt", "w", stdout );
// Allocate global data structures. This needs to happen before
// we parse command line options
- SGPropertyNode *props = new SGPropertyNode;
globals = new FGGlobals;
- globals->set_props( props );
// seed the random number generater
sg_srandom_time();
SGRoute *route = new SGRoute;
globals->set_route( route );
-#ifdef ENABLE_AUDIO_SUPPORT
- FGSoundMgr *soundmgr = new FGSoundMgr;
- globals->set_soundmgr( soundmgr );
-#endif
+ FGControls *controls = new FGControls;
+ globals->set_controls( controls );
FGViewMgr *viewmgr = new FGViewMgr;
globals->set_viewmgr( viewmgr );
// fg_root was specified (ignore all other options for now)
fgInitFGRoot(argc, argv);
+ // Check for the correct base package version
+ string base_version = fgBasePackageVersion();
+ if ( !(base_version == "0.7.9") ) {
+ SG_LOG( SG_GENERAL, SG_ALERT, "Base package check failed ... "
+ << "Found version " << base_version );
+ SG_LOG( SG_GENERAL, SG_ALERT, "Please upgrade to version 0.7.9" );
+ exit(-1);
+ }
+
// Initialize the Aircraft directory to "" (UIUC)
aircraft_dir = "";
"GLUT event handler initialization failed ..." );
exit(-1);
}
-
+
+ // Initialize plib net interface
+ netInit( &argc, argv );
+
// Initialize ssg (from plib). Needs to come before we do any
// other ssg stuff, but after opengl/glut has been initialized.
ssgInit();
// fonts !!!
guiInit();
+#ifdef GL_EXT_texture_lod_bias
+ glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, -0.5 ) ;
+#endif
+
+#if 0
+#ifdef GL_EXT_texture_filter_anisotropic
+ float max_anisotropy;
+ glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ max_anisotropy );
+ cout << "Max anisotropy = " << max_anisotropy << endl;
+#endif
+#endif
+
// set current_options lon/lat if an airport id is specified
// cout << "3. airport_id = " << fgGetString("/sim/startup/airport-id") << endl;
if ( fgGetString("/sim/startup/airport-id").length() ) {
// fgSetPosFromAirportID( fgGetString("/sim/startup/airport-id") );
fgSetPosFromAirportIDandHdg( fgGetString("/sim/startup/airport-id"),
- fgGetDouble("/orientation/heading") );
+ fgGetDouble("/orientation/heading-deg") );
}
// Initialize time
SGPath zone( globals->get_fg_root() );
zone.append( "Timezone" );
- SGTime *t = new SGTime( fgGetDouble("/position/longitude") * SGD_DEGREES_TO_RADIANS,
- fgGetDouble("/position/latitude") * SGD_DEGREES_TO_RADIANS,
+ SGTime *t = new SGTime( fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS,
+ fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS,
zone.str() );
// Handle potential user specified time offsets
0.0 );
globals->set_ephem( ephem );
+ thesky = new SGSky;
+
SGPath sky_tex_path( globals->get_fg_root() );
sky_tex_path.append( "Textures" );
sky_tex_path.append( "Sky" );
- thesky = new SGSky;
thesky->texture_path( sky_tex_path.str() );
thesky->build( 550.0, 550.0,
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( 2600.0, 200.0, 50.0, 40000.0,
- SG_CLOUD_MOSTLY_SUNNY );
+ 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 );
- // 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
acmodel_selector = new ssgSelector;
acmodel_pos = new ssgTransform;
+ // Get the model location, and load textures from the same
+ // directory. Use an absolute path for the model to avoid
+ // incompatibilities in different versions of PLIB.
string acmodel_path =
fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
+ SGPath full_model = globals->get_fg_root();
+ full_model.append(acmodel_path);
- string full_model = globals->get_fg_root() + "/"
- + acmodel_path;
- int pos = full_model.rfind("/");
-
- SGPath texturepath( full_model.substr(0, pos) );
- cout << "Texture path = " << texturepath.str() << endl;
- ssgTexturePath( (char *)texturepath.c_str() );
+#if !defined( PLIB_1_2_X )
+ // this should be redundant ... but it breaks for relative paths
+ // ssgModelPath( (char *)full_model.dir().c_str() );
+#endif
- ssgEntity *acmodel_obj = ssgLoad((char *)(acmodel_path.c_str()));
+ ssgTexturePath( (char *)full_model.dir().c_str() );
+ ssgEntity *acmodel_obj = ssgLoad( (char *)full_model.c_str() );
+ if( !acmodel_obj ) {
+ // fall back to default
+ acmodel_obj = ssgLoad( (char *)"Models/Geometry/glider.ac" );
+ if( !acmodel_obj ) {
+ SG_LOG( SG_GENERAL, SG_ALERT, "FAILED to LOAD an AC model! ..." );
+ exit(-1);
+ }
+ }
// find moving parts (if this is an MDL model)
flaps_selector = (ssgSelector*)fgFindNode( acmodel_obj, "FLAPS" );
sgMat4 rot_matrix;
sgMat4 off_matrix;
sgMat4 res_matrix;
- float h_rot = fgGetFloat("/sim/model/h-rotation", 0.0);
- float p_rot = fgGetFloat("/sim/model/p-rotation", 0.0);
- float r_rot = fgGetFloat("/sim/model/r-rotation", 0.0);
- float x_off = fgGetFloat("/sim/model/x-offset", 0.0);
- float y_off = fgGetFloat("/sim/model/y-offset", 0.0);
- float z_off = fgGetFloat("/sim/model/z-offset", 0.0);
+ float h_rot = fgGetFloat("/sim/model/heading-offset-deg", 0.0);
+ float p_rot = fgGetFloat("/sim/model/roll-offset-deg", 0.0);
+ float r_rot = fgGetFloat("/sim/model/pitch-offset-deg", 0.0);
+ float x_off = fgGetFloat("/sim/model/x-offset-m", 0.0);
+ float y_off = fgGetFloat("/sim/model/y-offset-m", 0.0);
+ float z_off = fgGetFloat("/sim/model/z-offset-m", 0.0);
sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot);
sgMakeTransMat4(off_matrix, x_off, y_off, z_off);
sgMultMat4(res_matrix, off_matrix, rot_matrix);
// $$$ end - added VS Renganathan, 15 Oct 2K
// - added Venky , 12 Nov 2K
+// Main entry point; catch any exceptions that have made it this far.
+int main ( int argc, char **argv ) {
+ // FIXME: add other, more specific
+ // exceptions.
+ try {
+ mainLoop(argc, argv);
+ } catch (sg_throwable &t) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "Fatal error: " << t.getFormattedMessage()
+ << "\n (received from " << t.getOrigin() << ')');
+ exit(1);
+ }
+}
+
+
void fgLoadDCS(void) {
ssgEntity *ship_obj = NULL;
SG_LOG ( SG_TERRAIN, SG_ALERT, "Finished object processing." );
ship_sel->clrTraversalMaskBits( SSGTRAV_HOT );
- scene->addKid( ship_sel ); //add selector node to root node
+ scene->addKid( ship_sel ); //add selector node to root node
}
return;