# include <stdlib.h>
#endif
-#include <sys/stat.h> /* for stat() */
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h> /* for stat() */
+#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* for stat() */
#endif
#include <Include/fg_constants.h> // for VERSION
-#include <Include/general.h>
+#include <Include/general.hxx>
#include <Aircraft/aircraft.hxx>
#include <Astro/sky.hxx>
#include "views.hxx"
-// This is a record containing global housekeeping information
-fgGENERAL general;
+// This is a record containing a bit of global housekeeping information
+FGGeneral general;
// Specify our current idle function state. This is used to run all
// our initializations out of the glutIdleLoop() so that we can get a
// fgInitVisuals() -- Initialize various GL/view parameters
static void fgInitVisuals( void ) {
fgLIGHT *l;
- struct fgWEATHER *w;
l = &cur_light_params;
- w = ¤t_weather;
// Go full screen if requested ...
if ( current_options.get_fullscreen() ) {
exit(0);
- fgVIEW *v;
-
- v = ¤t_view;
+ fgVIEW *v = ¤t_view;
xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
// Update all Visuals (redraws anything graphics related)
static void fgRenderFrame( void ) {
- fgFLIGHT *f;
- fgLIGHT *l;
- fgTIME *t;
- fgVIEW *v;
+ fgLIGHT *l = &cur_light_params;
+ fgTIME *t = &cur_time_params;
+ FGView *v = ¤t_view;
+
double angle;
static int iteration = 0;
// GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
GLbitfield clear_mask;
- f = current_aircraft.flight;
- l = &cur_light_params;
- t = &cur_time_params;
- v = ¤t_view;
-
if ( idle_state != 1000 ) {
// still initializing, draw the splash screen
if ( current_options.get_splash_screen() == 1 ) {
// update view volume parameters
v->UpdateViewParams();
+ // set the sun position
+ xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+
clear_mask = GL_DEPTH_BUFFER_BIT;
if ( current_options.get_wireframe() ) {
clear_mask |= GL_COLOR_BUFFER_BIT;
// setup transformation for drawing astronomical objects
xglPushMatrix();
// Translate to view position
- xglTranslatef( v->view_pos.x(), v->view_pos.y(), v->view_pos.z() );
+ Point3D view_pos = v->get_view_pos();
+ xglTranslatef( view_pos.x(), view_pos.y(), view_pos.z() );
// Rotate based on gst (sidereal time)
// note: constant should be 15.041085, Curt thought it was 15
angle = t->gst * 15.041085;
fgTileMgrRender();
xglDisable( GL_TEXTURE_2D );
+ xglDisable( GL_FOG );
if ( (iteration == 0) && (current_options.get_panel_status()) ) {
// Did we run this loop before ?? ...and do we need the panel ??
xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
puDisplay();
xglDisable ( GL_BLEND ) ;
+ xglEnable( GL_FOG );
}
xglutSwapBuffers();
// Update internal time dependent calculations (i.e. flight model)
-void fgUpdateTimeDepCalcs(int multi_loop) {
- fgFLIGHT *f;
- fgLIGHT *l;
- fgTIME *t;
- fgVIEW *v;
+void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
+ FGState *f = current_aircraft.fdm_state;
+ fgLIGHT *l = &cur_light_params;
+ fgTIME *t = &cur_time_params;
+ FGView *v = ¤t_view;
int i;
- f = current_aircraft.flight;
- l = &cur_light_params;
- t = &cur_time_params;
- v = ¤t_view;
-
// update the flight model
if ( multi_loop < 0 ) {
multi_loop = DEFAULT_MULTILOOP;
fgAPRun();
// printf("updating flight model x %d\n", multi_loop);
- fgFlightModelUpdate(current_options.get_flight_model(), f, multi_loop);
+ fgFDMUpdate( current_options.get_flight_model(),
+ cur_fdm_state, multi_loop, remainder );
} else {
- fgFlightModelUpdate(current_options.get_flight_model(), f, 0);
+ fgFDMUpdate( current_options.get_flight_model(),
+ cur_fdm_state, 0, remainder );
}
// update the view angle
for ( i = 0; i < multi_loop; i++ ) {
- if ( fabs(v->goal_view_offset - v->view_offset) < 0.05 ) {
- v->view_offset = v->goal_view_offset;
+ if ( fabs(v->get_goal_view_offset() - v->get_view_offset()) < 0.05 ) {
+ v->set_view_offset( v->get_goal_view_offset() );
break;
} else {
// move v->view_offset towards v->goal_view_offset
- if ( v->goal_view_offset > v->view_offset ) {
- if ( v->goal_view_offset - v->view_offset < FG_PI ) {
- v->view_offset += 0.01;
+ if ( v->get_goal_view_offset() > v->get_view_offset() ) {
+ if ( v->get_goal_view_offset() - v->get_view_offset() < FG_PI ){
+ v->inc_view_offset( 0.01 );
} else {
- v->view_offset -= 0.01;
+ v->inc_view_offset( -0.01 );
}
} else {
- if ( v->view_offset - v->goal_view_offset < FG_PI ) {
- v->view_offset -= 0.01;
+ if ( v->get_view_offset() - v->get_goal_view_offset() < FG_PI ){
+ v->inc_view_offset( -0.01 );
} else {
- v->view_offset += 0.01;
+ v->inc_view_offset( 0.01 );
}
}
- if ( v->view_offset > FG_2PI ) {
- v->view_offset -= FG_2PI;
- } else if ( v->view_offset < 0 ) {
- v->view_offset += FG_2PI;
+ if ( v->get_view_offset() > FG_2PI ) {
+ v->inc_view_offset( -FG_2PI );
+ } else if ( v->get_view_offset() < 0 ) {
+ v->inc_view_offset( FG_2PI );
}
}
}
- double tmp = -(l->sun_rotation + FG_PI) - (FG_Psi - v->view_offset);
+ double tmp = -(l->sun_rotation + FG_PI)
+ - (f->get_Psi() - v->get_view_offset() );
while ( tmp < 0.0 ) {
tmp += FG_2PI;
}
void fgInitTimeDepCalcs( void ) {
// initialize timer
-#ifdef HAVE_SETITIMER
- fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
-#endif HAVE_SETITIMER
-
+ // #ifdef HAVE_SETITIMER
+ // fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
+ // #endif HAVE_SETITIMER
}
static const double alt_adjust_ft = 3.758099;
// What should we do when we have nothing else to do? Let's get ready
// for the next move and update the display?
static void fgMainLoop( void ) {
- fgFLIGHT *f;
- fgGENERAL *g;
+ FGState *f;
fgTIME *t;
- static int remainder = 0;
- int elapsed, multi_loop;
- int i;
- double accum;
-
- f = current_aircraft.flight;
- g = &general;
+ static long remainder = 0;
+ long elapsed, multi_loop;
+ // int i;
+ // double accum;
+ static time_t last_time = 0;
+ static int frames = 0;
+
+ f = current_aircraft.fdm_state;
t = &cur_time_params;
FG_LOG( FG_ALL, FG_DEBUG, "Running Main Loop");
FG_LOG( FG_ALL, FG_DEBUG, "======= ==== ====");
- fgWeatherUpdate();
+#if defined( ENABLE_LINUX_JOYSTICK )
+ // Read joystick and update control settings
+ fgJoystickRead();
+#elif defined( ENABLE_GLUT_JOYSTICK )
+ // Glut joystick support works by feeding a joystick handler
+ // function to glut. This is taken care of once in the joystick
+ // init routine and we don't have to worry about it again.
+#endif
+
+ current_weather.Update();
// Fix elevation. I'm just sticking this here for now, it should
// probably move eventually
/* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
+ f->get_Runway_altitude() * FEET_TO_METER,
+ f->get_Altitude() * FEET_TO_METER); */
if ( scenery.cur_elev > -9990 ) {
- if ( FG_Altitude * FEET_TO_METER <
+ if ( f->get_Altitude() * FEET_TO_METER <
(scenery.cur_elev + alt_adjust_m - 3.0) ) {
// now set aircraft altitude above ground
printf("Current Altitude = %.2f < %.2f forcing to %.2f\n",
- FG_Altitude * FEET_TO_METER,
+ f->get_Altitude() * FEET_TO_METER,
scenery.cur_elev + alt_adjust_m - 3.0,
scenery.cur_elev + alt_adjust_m );
- fgFlightModelSetAltitude( current_options.get_flight_model(), f,
- scenery.cur_elev + alt_adjust_m );
+ fgFDMForceAltitude( current_options.get_flight_model(),
+ scenery.cur_elev + alt_adjust_m );
- FG_LOG( FG_ALL, FG_BULK,
+ FG_LOG( FG_ALL, FG_DEBUG,
"<*> resetting altitude to "
- << FG_Altitude * FEET_TO_METER << " meters" );
+ << f->get_Altitude() * FEET_TO_METER << " meters" );
}
- FG_Runway_altitude = scenery.cur_elev * METER_TO_FEET;
+ fgFDMSetGroundElevation( current_options.get_flight_model(),
+ scenery.cur_elev ); // meters
}
/* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
+ f->get_Runway_altitude() * FEET_TO_METER,
+ f->get_Altitude() * FEET_TO_METER); */
// update "time"
fgTimeUpdate(f, t);
-#if defined( ENABLE_LINUX_JOYSTICK )
- // Read joystick and update control settings
- fgJoystickRead();
-#elif defined( ENABLE_GLUT_JOYSTICK )
- // Glut joystick support works by feeding a joystick handler
- // function to glut. This is taken care of once in the joystick
- // init routine and we don't have to worry about it again.
-#endif
-
- // Get elapsed time for this past frame
+ // Get elapsed time (in usec) for this past frame
elapsed = fgGetTimeInterval();
- FG_LOG( FG_ALL, FG_BULK,
- "Time interval is = " << elapsed
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "Elapsed time interval is = " << elapsed
<< ", previous remainder is = " << remainder );
// Calculate frame rate average
- if ( elapsed > 0.0 ) {
+ if ( (t->cur_time != last_time) && (last_time > 0) ) {
+ general.set_frame_rate( frames );
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "--> Frame rate is = " << general.get_frame_rate() );
+ frames = 0;
+ }
+ last_time = t->cur_time;
+ ++frames;
+
+ /* old fps calculation
+ if ( elapsed > 0 ) {
accum = 0.0;
for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
accum += g->frames[i];
g->frame_rate = accum / (float)FG_FRAME_RATE_HISTORY;
// printf("ave = %.2f\n", g->frame_rate);
}
-
- // Calculate model iterations needed for next frame
- FG_LOG( FG_ALL, FG_DEBUG,
- "--> Frame rate is = " << g->frame_rate );
- elapsed += remainder;
-
- multi_loop = (int)(((float)elapsed * 0.001) * DEFAULT_MODEL_HZ);
- remainder = elapsed - ((multi_loop*1000) / DEFAULT_MODEL_HZ);
- FG_LOG( FG_ALL, FG_BULK,
- "Model iterations needed = " << multi_loop
- << ", new remainder = " << remainder );
-
- /* printf("right before fm - ground = %.2f runway = %.2f alt = %.2f\n",
- scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
+ */
// Run flight model
if ( ! use_signals ) {
+ // Calculate model iterations needed for next frame
+ elapsed += remainder;
+
+ multi_loop = (int)(((double)elapsed * 0.000001) * DEFAULT_MODEL_HZ);
+ remainder = elapsed - ((multi_loop*1000000) / DEFAULT_MODEL_HZ);
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "Model iterations needed = " << multi_loop
+ << ", new remainder = " << remainder );
+
// flight model
- fgUpdateTimeDepCalcs(multi_loop);
+ if ( multi_loop > 0 ) {
+ fgUpdateTimeDepCalcs(multi_loop, remainder);
+ } else {
+ FG_LOG( FG_ALL, FG_INFO, "Elapsed time is zero ... we're zinging" );
+ }
}
- /* printf("After fm - ground = %.2f runway = %.2f alt = %.2f\n",
- scenery.cur_elev,
- FG_Runway_altitude * FEET_TO_METER,
- FG_Altitude * FEET_TO_METER); */
-
// Do any serial port work that might need to be done
fgSerialProcess();
// 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 = FG_Gamma_vert_rad * 2.2;
+ double aoa = f->get_Gamma_vert_rad() * 2.2;
double tmp = 3.0;
double aoa_adj = pow(-aoa, tmp) * pow(M_E, aoa);
if (aoa_adj < -0.8) aoa_adj = -0.8;
// then on.
static void fgIdleFunction ( void ) {
- fgGENERAL *g;
- g = &general;
-
// printf("idle state == %d\n", idle_state);
if ( idle_state == 0 ) {
// "subsystems" but still need to be initialized.
#ifdef USE_GLIDE
- if ( strstr ( g->glRenderer, "Glide" ) ) {
+ if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
}
#endif
// Handle new window size or exposure
static void fgReshape( int width, int height ) {
- fgVIEW *v;
-
- v = ¤t_view;
-
// Do this so we can call fgReshape(0,0) ourselves without having
// to know what the values of width & height are.
if ( (height > 0) && (width > 0) ) {
if ( ! current_options.get_panel_status() ) {
- v->win_ratio = (GLfloat) width / (GLfloat) height;
+ current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
} else {
- v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.4232);
+ current_view.set_win_ratio( (GLfloat) width /
+ ((GLfloat) (height)*0.4232) );
}
}
- v->winWidth = width;
- v->winHeight = height;
- v->update_fov = true;
+ current_view.set_winWidth( width );
+ current_view.set_winHeight( height );
+ current_view.force_update_fov_math();
// Inform gl of our view window size (now handled elsewhere)
// xglViewport(0, 0, (GLint)width, (GLint)height);
// yes we've finished all our initializations and are running
// the main loop, so this will now work without seg faulting
// the system.
- v->UpdateViewParams();
+ current_view.UpdateViewParams();
if ( current_options.get_panel_status() ) {
fgPanelReInit(0, 0, 1024, 768);
}
}
-
- // xglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
glutEnterGameMode();
}
+ // This seems to be the absolute earliest in the init sequence
+ // that these calls will return valid info. Too bad it's after
+ // we've already created and sized out window. :-(
+ general.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
+ general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
+ general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
+
+ FG_LOG ( FG_GENERAL, FG_INFO, general.get_glRenderer() );
+
+#if 0
+ // try to determine if we should adjust the initial default
+ // display resolution. The options class defaults (is
+ // initialized) to 640x480.
+ string renderer = general.glRenderer;
+
+ // currently we only know how to deal with Mesa/Glide/Voodoo cards
+ if ( renderer.find( "Glide" ) != string::npos ) {
+ FG_LOG( FG_GENERAL, FG_INFO, "Detected a Glide driver" );
+ if ( renderer.find( "FB/8" ) != string::npos ) {
+ // probably a voodoo-2
+ if ( renderer.find( "TMU/SLI" ) != string::npos ) {
+ // probably two SLI'd Voodoo-2's
+ current_options.set_xsize( 1024 );
+ current_options.set_ysize( 768 );
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "It looks like you have two sli'd voodoo-2's." << endl
+ << "upgrading your win resolution to 1024 x 768" );
+ glutReshapeWindow(1024, 768);
+ } else {
+ // probably a single non-SLI'd Voodoo-2
+ current_options.set_xsize( 800 );
+ current_options.set_ysize( 600 );
+ FG_LOG( FG_GENERAL, FG_INFO,
+ "It looks like you have a voodoo-2." << endl
+ << "upgrading your win resolution to 800 x 600" );
+ glutReshapeWindow(800, 600);
+ }
+ } else if ( renderer.find( "FB/2" ) != string::npos ) {
+ // probably a voodoo-1, stick with the default
+ }
+ } else {
+ // we have no special knowledge of this card, stick with the default
+ }
+#endif
+
return(1);
}
// Main ...
int main( int argc, char **argv ) {
- fgFLIGHT *f;
+ FGState *f;
- f = current_aircraft.flight;
+ f = current_aircraft.fdm_state;
#ifdef HAVE_BC5PLUS
_control87(MCW_EM, MCW_EM); /* defined in float.h */
FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear: Version " << VERSION << endl );
string root;
- int i;
FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
- // pull some basic driver info
- general.glVendor = (char *)glGetString ( GL_VENDOR );
- general.glRenderer = (char *)glGetString ( GL_RENDERER );
- general.glVersion = (char *)glGetString ( GL_VERSION );
-
- // try to determine if we should adjust the default display
- // resolution. The options class defaults (is initialized) to
- // 640x480.
- string renderer = general.glRenderer;
-
- // currently we only know how to deal with Mesa/Glide/Voodoo cards
- if ( renderer.find( "Glide" ) != string::npos ) {
- if ( renderer.find( "FB/8" ) != string::npos ) {
- // probably a voodoo-2
- if ( renderer.find( "TMU/SLI" ) != string::npos ) {
- // probably two SLI'd Voodoo-2's
- current_options.set_xsize( 1024 );
- current_options.set_ysize( 768 );
- } else {
- // probably a single non-SLI'd Voodoo-2
- current_options.set_xsize( 800 );
- current_options.set_ysize( 600 );
- }
- } else if ( renderer.find( "FB/2" ) != string::npos ) {
- // probably a voodoo-1, stick with the default
- }
- } else {
- // we have no special knowledge of this card, stick with the default
- }
-
// Attempt to locate and parse a config file
// First check fg_root
string config = current_options.get_fg_root() + "/system.fgfsrc";
// $Log$
+// Revision 1.82 1999/01/20 13:42:24 curt
+// Tweaked FDM interface.
+// Testing check sum support for NMEA serial output.
+//
+// Revision 1.81 1999/01/19 20:57:03 curt
+// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
+//
+// Revision 1.80 1999/01/09 13:37:40 curt
+// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
+//
+// Revision 1.79 1999/01/08 03:23:56 curt
+// Beginning work on compensating for sim time vs. real world time "jitter".
+//
+// Revision 1.78 1999/01/07 20:25:08 curt
+// Updated struct fgGENERAL to class FGGeneral.
+//
+// Revision 1.77 1998/12/18 23:40:55 curt
+// New frame rate counting mechanism.
+//
+// Revision 1.76 1998/12/11 20:26:26 curt
+// Fixed view frustum culling accuracy bug so we can look out the sides and
+// back without tri-stripes dropping out.
+//
+// Revision 1.75 1998/12/09 18:50:23 curt
+// Converted "class fgVIEW" to "class FGView" and updated to make data
+// members private and make required accessor functions.
+//
+// Revision 1.74 1998/12/06 14:52:54 curt
+// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
+// being calculated correctly at the beginning causing the first terrain
+// intersection to fail, returning a ground altitude of zero, causing the plane
+// to free fall for one frame, until the ground altitude was corrected, but now
+// being under the ground we got a big bounce and the plane always ended up
+// upside down.
+//
+// Revision 1.73 1998/12/06 13:51:22 curt
+// Turned "struct fgWEATHER" into "class FGWeather".
+//
+// Revision 1.72 1998/12/05 15:54:18 curt
+// Renamed class fgFLIGHT to class FGState as per request by JSB.
+//
+// Revision 1.71 1998/12/05 14:19:51 curt
+// Looking into a problem with cur_view_params.abs_view_pos initialization.
+//
+// Revision 1.70 1998/12/03 01:17:14 curt
+// Converted fgFLIGHT to a class.
+//
+// Revision 1.69 1998/11/23 20:51:26 curt
+// Fiddling with when I can get info from the opengl driver.
+//
// Revision 1.68 1998/11/20 01:02:35 curt
// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
//