]> git.mxchange.org Git - flightgear.git/commitdiff
Merge FG_Simulator as subdirectory
authorTim Moore <timoore@redhat.com>
Mon, 14 Sep 2009 11:38:55 +0000 (13:38 +0200)
committerTim Moore <timoore@redhat.com>
Mon, 14 Sep 2009 11:38:55 +0000 (13:38 +0200)
211 files changed:
1  2 
Simulator/Aircraft/Makefile.am
Simulator/Aircraft/aircraft.cxx
Simulator/Aircraft/aircraft.hxx
Simulator/Airports/Makefile.am
Simulator/Airports/genapt.cxx
Simulator/Airports/genapt.hxx
Simulator/Airports/simple.cxx
Simulator/Airports/simple.hxx
Simulator/Astro/Makefile.am
Simulator/Astro/celestialBody.cxx
Simulator/Astro/celestialBody.hxx
Simulator/Astro/jupiter.cxx
Simulator/Astro/jupiter.hxx
Simulator/Astro/mars.cxx
Simulator/Astro/mars.hxx
Simulator/Astro/mercury.cxx
Simulator/Astro/mercury.hxx
Simulator/Astro/moon.cxx
Simulator/Astro/moon.hxx
Simulator/Astro/neptune.cxx
Simulator/Astro/neptune.hxx
Simulator/Astro/pluto.hxx
Simulator/Astro/saturn.cxx
Simulator/Astro/saturn.hxx
Simulator/Astro/sky.cxx
Simulator/Astro/sky.hxx
Simulator/Astro/solarsystem.cxx
Simulator/Astro/solarsystem.hxx
Simulator/Astro/star.cxx
Simulator/Astro/star.hxx
Simulator/Astro/stars.cxx
Simulator/Astro/stars.hxx
Simulator/Astro/uranus.cxx
Simulator/Astro/uranus.hxx
Simulator/Astro/venus.cxx
Simulator/Astro/venus.hxx
Simulator/Autopilot/Makefile.am
Simulator/Autopilot/autopilot.cxx
Simulator/Autopilot/autopilot.hxx
Simulator/CVSROOT/checkoutlist
Simulator/CVSROOT/commitinfo
Simulator/CVSROOT/cvswrappers
Simulator/CVSROOT/editinfo
Simulator/CVSROOT/loginfo
Simulator/CVSROOT/modules
Simulator/CVSROOT/notify
Simulator/CVSROOT/rcsinfo
Simulator/CVSROOT/taginfo
Simulator/Cockpit/Makefile.am
Simulator/Cockpit/cockpit.cxx
Simulator/Cockpit/cockpit.hxx
Simulator/Cockpit/hud.cxx
Simulator/Cockpit/hud.hxx
Simulator/Cockpit/hud_card.cxx
Simulator/Cockpit/hud_dnst.cxx
Simulator/Cockpit/hud_guag.cxx
Simulator/Cockpit/hud_inst.cxx
Simulator/Cockpit/hud_labl.cxx
Simulator/Cockpit/hud_ladr.cxx
Simulator/Cockpit/hud_scal.cxx
Simulator/Cockpit/hud_tbi.cxx
Simulator/Cockpit/panel.cxx
Simulator/Cockpit/panel.hxx
Simulator/Controls/Makefile.am
Simulator/Controls/controls.cxx
Simulator/Controls/controls.hxx
Simulator/External/Makefile.am
Simulator/External/external.cxx
Simulator/External/external.hxx
Simulator/FDM/JSBsim.cxx
Simulator/FDM/JSBsim.hxx
Simulator/FDM/LaRCsim.cxx
Simulator/FDM/LaRCsim.hxx
Simulator/FDM/Makefile.am
Simulator/FDM/flight.cxx
Simulator/FDM/flight.hxx
Simulator/GUI/Makefile.am
Simulator/GUI/gui.cxx
Simulator/GUI/gui.h
Simulator/JSBsim/FGAircraft.cpp
Simulator/JSBsim/FGAircraft.h
Simulator/JSBsim/FGAtmosphere.cpp
Simulator/JSBsim/FGAtmosphere.h
Simulator/JSBsim/FGAuxiliary.cpp
Simulator/JSBsim/FGAuxiliary.h
Simulator/JSBsim/FGCoefficient.cpp
Simulator/JSBsim/FGCoefficient.h
Simulator/JSBsim/FGControls.cpp
Simulator/JSBsim/FGControls.h
Simulator/JSBsim/FGDefs.h
Simulator/JSBsim/FGEngine.cpp
Simulator/JSBsim/FGEngine.h
Simulator/JSBsim/FGFCS.cpp
Simulator/JSBsim/FGFCS.h
Simulator/JSBsim/FGFDMExec.cpp
Simulator/JSBsim/FGFDMExec.h
Simulator/JSBsim/FGMain.cpp
Simulator/JSBsim/FGMatrix.cpp
Simulator/JSBsim/FGMatrix.h
Simulator/JSBsim/FGModel.cpp
Simulator/JSBsim/FGModel.h
Simulator/JSBsim/FGOutput.cpp
Simulator/JSBsim/FGOutput.h
Simulator/JSBsim/FGPosition.cpp
Simulator/JSBsim/FGPosition.h
Simulator/JSBsim/FGRotation.cpp
Simulator/JSBsim/FGRotation.h
Simulator/JSBsim/FGState.cpp
Simulator/JSBsim/FGState.h
Simulator/JSBsim/FGTank.cpp
Simulator/JSBsim/FGTank.h
Simulator/JSBsim/FGTranslation.cpp
Simulator/JSBsim/FGTranslation.h
Simulator/JSBsim/FGUtility.cpp
Simulator/JSBsim/FGUtility.h
Simulator/JSBsim/Makefile.am
Simulator/Joystick/Makefile.am
Simulator/Joystick/joystick.cxx
Simulator/Joystick/joystick.hxx
Simulator/LaRCsim/Makefile.am
Simulator/LaRCsim/atmos_62.c
Simulator/LaRCsim/atmos_62.h
Simulator/LaRCsim/default_model_routines.c
Simulator/LaRCsim/default_model_routines.h
Simulator/LaRCsim/ls_accel.c
Simulator/LaRCsim/ls_accel.h
Simulator/LaRCsim/ls_aux.c
Simulator/LaRCsim/ls_aux.h
Simulator/LaRCsim/ls_cockpit.h
Simulator/LaRCsim/ls_constants.h
Simulator/LaRCsim/ls_generic.h
Simulator/LaRCsim/ls_geodesy.c
Simulator/LaRCsim/ls_geodesy.h
Simulator/LaRCsim/ls_gravity.c
Simulator/LaRCsim/ls_gravity.h
Simulator/LaRCsim/ls_init.c
Simulator/LaRCsim/ls_init.h
Simulator/LaRCsim/ls_interface.c
Simulator/LaRCsim/ls_interface.h
Simulator/LaRCsim/ls_matrix.c
Simulator/LaRCsim/ls_matrix.h
Simulator/LaRCsim/ls_model.c
Simulator/LaRCsim/ls_model.h
Simulator/LaRCsim/ls_sim_control.h
Simulator/LaRCsim/ls_step.c
Simulator/LaRCsim/ls_step.h
Simulator/LaRCsim/ls_sym.h
Simulator/LaRCsim/ls_types.h
Simulator/LaRCsim/mymain.c
Simulator/LaRCsim/navion_aero.c
Simulator/LaRCsim/navion_engine.c
Simulator/LaRCsim/navion_gear.c
Simulator/LaRCsim/navion_init.c
Simulator/LaRCsim/navion_init.h
Simulator/Main/GLUTkey.cxx
Simulator/Main/GLUTkey.hxx
Simulator/Main/GLUTmain.cxx
Simulator/Main/Makefile.am
Simulator/Main/fg_init.cxx
Simulator/Main/fg_init.hxx
Simulator/Main/fg_serial.cxx
Simulator/Main/fg_serial.hxx
Simulator/Main/options.cxx
Simulator/Main/options.hxx
Simulator/Main/runfgfs.bat.in
Simulator/Main/runfgfs.in
Simulator/Main/splash.cxx
Simulator/Main/splash.hxx
Simulator/Main/views.cxx
Simulator/Main/views.hxx
Simulator/Objects/Makefile.am
Simulator/Objects/fragment.cxx
Simulator/Objects/fragment.hxx
Simulator/Objects/material.cxx
Simulator/Objects/material.hxx
Simulator/Objects/obj.cxx
Simulator/Objects/obj.hxx
Simulator/Objects/texload.c
Simulator/Objects/texload.h
Simulator/Scenery/Makefile.am
Simulator/Scenery/scenery.cxx
Simulator/Scenery/scenery.hxx
Simulator/Scenery/tile.cxx
Simulator/Scenery/tile.hxx
Simulator/Scenery/tilecache.cxx
Simulator/Scenery/tilecache.hxx
Simulator/Scenery/tilemgr.cxx
Simulator/Scenery/tilemgr.hxx
Simulator/Simulator/Done
Simulator/Simulator/Makefile.am
Simulator/Simulator/Todo
Simulator/Slew/Makefile.am
Simulator/Slew/slew.cxx
Simulator/Slew/slew.hxx
Simulator/Time/Makefile.am
Simulator/Time/event.cxx
Simulator/Time/event.hxx
Simulator/Time/fg_time.cxx
Simulator/Time/fg_time.hxx
Simulator/Time/fg_timer.cxx
Simulator/Time/fg_timer.hxx
Simulator/Time/light.cxx
Simulator/Time/light.hxx
Simulator/Time/moonpos.cxx
Simulator/Time/moonpos.hxx
Simulator/Time/sunpos.cxx
Simulator/Time/sunpos.hxx
Simulator/Time/timestamp.hxx
Simulator/Weather/Makefile.am
Simulator/Weather/weather.cxx
Simulator/Weather/weather.hxx

index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9620f85e17297d2790ad0b4e92f80ebd55a10275
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++noinst_LIBRARIES = libAircraft.a
++
++libAircraft_a_SOURCES = aircraft.cxx aircraft.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ac4b067b08de0c18e3b36e85c4d54ba978ee4224
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,158 @@@
++// aircraft.cxx -- various aircraft routines
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <stdio.h>
++
++#include "aircraft.hxx"
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++
++// This is a record containing all the info for the aircraft currently
++// being operated
++fgAIRCRAFT current_aircraft;
++
++
++// Initialize an Aircraft structure
++void fgAircraftInit( void ) {
++    FG_LOG( FG_AIRCRAFT, FG_INFO, "Initializing Aircraft structure" );
++
++    current_aircraft.fdm_state   = &cur_fdm_state;
++    current_aircraft.controls = &controls;
++}
++
++
++// Display various parameters to stdout
++void fgAircraftOutputCurrent(fgAIRCRAFT *a) {
++    FGInterface *f;
++
++    f = a->fdm_state;
++
++    FG_LOG( FG_FLIGHT, FG_DEBUG,
++          "Pos = ("
++          << (f->get_Longitude() * 3600.0 * RAD_TO_DEG) << "," 
++          << (f->get_Latitude()  * 3600.0 * RAD_TO_DEG) << ","
++          << f->get_Altitude() 
++          << ")  (Phi,Theta,Psi)=("
++          << f->get_Phi() << "," 
++          << f->get_Theta() << "," 
++          << f->get_Psi() << ")" );
++
++    FG_LOG( FG_FLIGHT, FG_DEBUG,
++          "Kts = " << f->get_V_equiv_kts() 
++          << "  Elev = " << controls.get_elevator() 
++          << "  Aileron = " << controls.get_aileron() 
++          << "  Rudder = " << controls.get_rudder() 
++          << "  Power = " << controls.get_throttle( 0 ) );
++}
++
++
++// $Log$
++// Revision 1.7  1999/02/05 21:28:09  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.6  1998/12/05 15:53:59  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5  1998/12/03 01:14:58  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.4  1998/11/06 21:17:31  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.3  1998/10/25 14:08:37  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2  1998/10/17 01:33:52  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/16 23:26:47  curt
++// C++-ifying.
++//
++// Revision 1.19  1998/04/25 22:06:24  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.18  1998/04/18 04:13:56  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.17  1998/02/12 21:59:31  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.16  1998/02/07 15:29:31  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.15  1998/01/27 00:47:46  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.14  1998/01/19 19:26:56  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.13  1997/12/15 23:54:30  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.12  1997/12/10 22:37:37  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.11  1997/09/13 02:00:05  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.10  1997/08/27 03:29:56  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.9  1997/07/19 22:39:08  curt
++// Moved PI to ../constants.h
++//
++// Revision 1.8  1997/06/25 15:39:45  curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.7  1997/06/02 03:01:39  curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.6  1997/05/31 19:16:26  curt
++// Elevator trim added.
++//
++// Revision 1.5  1997/05/30 19:30:14  curt
++// The LaRCsim flight model is starting to look like it is working.
++//
++// Revision 1.4  1997/05/30 03:54:11  curt
++// Made a bit more progress towards integrating the LaRCsim flight model.
++//
++// Revision 1.3  1997/05/29 22:39:56  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.2  1997/05/23 15:40:29  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 15:58:24  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..02e7470eeb0d273da68e030e0fec5e0f67ffaa77
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,122 @@@
++//*************************************************************************
++// aircraft.hxx -- define shared aircraft parameters
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifndef _AIRCRAFT_HXX
++#define _AIRCRAFT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++
++
++// Define a structure containing all the parameters for an aircraft
++typedef struct{
++    FGInterface   *fdm_state;
++    FGControls *controls;
++} fgAIRCRAFT ;
++
++
++// current_aircraft contains all the parameters of the aircraft
++// currently being operated.
++extern fgAIRCRAFT current_aircraft;
++
++
++// Initialize an Aircraft structure
++void fgAircraftInit( void );
++
++
++// Display various parameters to stdout
++void fgAircraftOutputCurrent(fgAIRCRAFT *a);
++
++
++#endif // _AIRCRAFT_HXX
++
++
++// $Log$
++// Revision 1.6  1999/02/05 21:28:10  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5  1999/02/01 21:33:24  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.4  1998/12/05 16:13:10  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.3  1998/12/05 15:54:01  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2  1998/10/17 01:33:54  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/16 23:26:49  curt
++// C++-ifying.
++//
++// Revision 1.12  1998/04/22 13:26:15  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11  1998/04/21 17:02:27  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.10  1998/02/07 15:29:32  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9  1998/01/22 02:59:23  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8  1998/01/19 19:26:57  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.7  1997/12/10 22:37:38  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.6  1997/09/13 02:00:06  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.5  1997/08/27 03:29:58  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4  1997/07/23 21:52:17  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3  1997/06/21 17:12:42  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.2  1997/05/23 15:40:30  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 15:58:25  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..250420518eb220f4deb7b62c794f9a6ca49d043d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++noinst_LIBRARIES = libAirports.a
++
++libAirports_a_SOURCES = \
++      genapt.cxx genapt.hxx \
++      simple.cxx simple.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b8400997466ae7e4a529e7d8bd085aef26980210
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,345 @@@
++//
++// genapt.cxx -- generate airport scenery from the given definition file
++//
++// Written by Curtis Olson, started September 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <vector>
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#ifdef FG_HAVE_NATIVE_SGI_COMPILERS
++#  include <strings.h>
++#endif
++
++#include <Debug/logstream.hxx>
++// #include <Include/fg_types.h>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Misc/fgstream.hxx>
++#include <Objects/material.hxx>
++
++// #include <gpc/gpc.h>
++
++#include "genapt.hxx"
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++
++typedef vector < Point3D > container;
++typedef container::iterator iterator;
++typedef container::const_iterator const_iterator;
++
++
++#define FG_APT_BASE_TEX_CONSTANT 2000.0
++
++// Calculate texture coordinates for a given point.
++static Point3D calc_tex_coords(double *node, const Point3D& ref) {
++    Point3D cp;
++    Point3D pp;
++
++    cp = Point3D( node[0] + ref.x(), node[1] + ref.y(), node[2] + ref.z() );
++
++    pp = fgCartToPolar3d(cp);
++
++    pp.setx( fmod(FG_APT_BASE_TEX_CONSTANT * pp.x(), 10.0) );
++    pp.sety( fmod(FG_APT_BASE_TEX_CONSTANT * pp.y(), 10.0) );
++
++    if ( pp.x() < 0.0 ) {
++      pp.setx( pp.x() + 10.0 );
++    }
++
++    if ( pp.y() < 0.0 ) {
++      pp.sety( pp.y() + 10.0 );
++    }
++
++    return(pp);
++}
++
++
++// generate the actual base area for the airport
++static void
++gen_base( const Point3D& average, const container& perimeter, fgTILE *t)
++{
++    GLint display_list;
++    Point3D cart, cart_trans, tex;
++    MAT3vec normal;
++    double dist, max_dist, temp;
++    int center_num, i;
++
++    fgFRAGMENT fragment;
++
++    max_dist = 0.0;
++
++    FG_LOG( FG_TERRAIN, FG_INFO, 
++          "generating airport base for size = " << perimeter.size() );
++
++    fragment.init();
++    fragment.tile_ptr = t;
++
++    // find airport base material in the properties list
++    if ( ! material_mgr.find( APT_BASE_MATERIAL, fragment.material_ptr )) {
++      FG_LOG( FG_TERRAIN, FG_ALERT, 
++              "Ack! unknown material name = " << APT_BASE_MATERIAL 
++              << " in fgAptGenerat()" );
++    }
++
++    FG_LOG( FG_TERRAIN, FG_INFO, 
++          " tile center = " 
++          << t->center.x() << " " << t->center.y() << " " << t->center.z() );
++    FG_LOG( FG_TERRAIN, FG_INFO, 
++          " airport center = "
++          << average.x() << " " << average.y() << " " << average.z() );
++    fragment.center = average;
++
++    normal[0] = average.x();
++    normal[1] = average.y();
++    normal[2] = average.z();
++    MAT3_NORMALIZE_VEC(normal, temp);
++    
++    display_list = xglGenLists(1);
++    xglNewList(display_list, GL_COMPILE);
++    xglBegin(GL_TRIANGLE_FAN);
++
++    // first point center of fan
++    cart_trans = average - t->center;
++    t->nodes[t->ncount][0] = cart_trans.x();
++    t->nodes[t->ncount][1] = cart_trans.y();
++    t->nodes[t->ncount][2] = cart_trans.z();
++    center_num = t->ncount;
++    t->ncount++;
++
++    tex = calc_tex_coords( t->nodes[t->ncount-1], t->center );
++    xglTexCoord2f(tex.x(), tex.y());
++    xglNormal3dv(normal);
++    xglVertex3dv(t->nodes[t->ncount-1]);
++
++    // first point on perimeter
++    const_iterator current = perimeter.begin();
++    cart = fgGeodToCart( *current );
++    cart_trans = cart - t->center;
++    t->nodes[t->ncount][0] = cart_trans.x();
++    t->nodes[t->ncount][1] = cart_trans.y();
++    t->nodes[t->ncount][2] = cart_trans.z();
++    t->ncount++;
++
++    i = 1;
++    tex = calc_tex_coords( t->nodes[i], t->center );
++    dist = cart.distance3Dsquared(average);
++    if ( dist > max_dist ) {
++      max_dist = dist;
++    }
++    xglTexCoord2f(tex.x(), tex.y());
++    xglVertex3dv(t->nodes[i]);
++    ++current;
++    ++i;
++
++    const_iterator last = perimeter.end();
++    for ( ; current != last; ++current ) {
++      cart = fgGeodToCart( *current );
++      cart_trans = cart - t->center;
++      t->nodes[t->ncount][0] = cart_trans.x();
++      t->nodes[t->ncount][1] = cart_trans.y();
++      t->nodes[t->ncount][2] = cart_trans.z();
++      t->ncount++;
++      fragment.add_face(center_num, i - 1, i);
++
++      tex = calc_tex_coords( t->nodes[i], t->center );
++      dist = cart.distance3Dsquared(average);
++      if ( dist > max_dist ) {
++          max_dist = dist;
++      }
++      xglTexCoord2f(tex.x(), tex.y());
++      xglVertex3dv(t->nodes[i]);
++      i++;
++    }
++
++    // last point (first point in perimeter list)
++    current = perimeter.begin();
++    cart = fgGeodToCart( *current );
++    cart_trans = cart - t->center;
++    fragment.add_face(center_num, i - 1, 1);
++
++    tex = calc_tex_coords( t->nodes[1], t->center );
++    xglTexCoord2f(tex.x(), tex.y());
++    xglVertex3dv(t->nodes[1]);
++
++    xglEnd();
++    xglEndList();
++
++    fragment.bounding_radius = sqrt(max_dist);
++    fragment.display_list = display_list;
++
++    t->fragment_list.push_back(fragment);
++}
++
++
++// Load a .apt file and register the GL fragments with the
++// corresponding tile
++int
++fgAptGenerate(const string& path, fgTILE *tile)
++{
++    string token;
++    string apt_id, apt_name;
++    char c;
++    int i = 1;
++
++    // face list (this indexes into the master tile vertex list)
++    container perimeter;
++    Point3D p, average;
++    double avex = 0.0, avey = 0.0, avez = 0.0;
++    int size;
++
++    // gpc_vertex p_2d, list_2d[MAX_PERIMETER];
++    // gpc_vertex_list perimeter_2d;
++
++    fg_gzifstream in( path );
++    if ( !in ) {
++      // exit immediately assuming an airport file for this tile
++      // doesn't exist.
++      return 0;
++    }
++
++    apt_id = "";
++
++    // read in each line of the file
++    in >> skipcomment;
++    while ( ! in.eof() )
++    {
++      in >> token;
++
++      if ( token == "a" ) {
++          // airport info record (start of airport)
++
++          if ( apt_id.length() > 0 ) {
++              // we have just finished reading and airport record.
++              // process the info
++              gen_base(average, perimeter, tile);
++          }
++
++          FG_LOG( FG_TERRAIN, FG_INFO, "Reading airport record" );
++          in >> apt_id;
++          apt_name = "";
++          i = 1;
++          avex = avey = avez = 0.0;
++          perimeter.erase( perimeter.begin(), perimeter.end() );
++          // skip to end of line.
++          while ( in.get(c) && c != '\n' ) {
++              apt_name += c;
++          }
++          FG_LOG( FG_TERRAIN, FG_INFO, 
++                  "\tID = " << apt_id << "  Name = " << apt_name );
++      } else if ( token == "p" ) {
++          // airport area bounding polygon coordinate.  These
++          // specify a convex hull that should already have been cut
++          // out of the base terrain.  The points are given in
++          // counter clockwise order and are specified in lon/lat
++          // degrees.
++          in >> p;
++          avex += tile->nodes[i][0];
++          avey += tile->nodes[i][1];
++          avez += tile->nodes[i][2];
++          perimeter.push_back(p);
++          ++i;
++      } else if ( token == "r" ) {
++          // runway record
++          // skip for now
++          while ( in.get(c) && c != '\n' );
++      }
++
++      in >> skipcomment;
++    }
++
++    if ( apt_id.length() > 0 ) {
++      // we have just finished reading and airport record.
++      // process the info
++      size = perimeter.size();
++      average = Point3D( avex / (double)size + tile->center.x(),
++                         avey / (double)size + tile->center.y(),
++                         avez / (double)size + tile->center.z() );
++
++      gen_base(average, perimeter, tile);
++    }
++
++    return 1;
++}
++
++
++// $Log$
++// Revision 1.14  1999/03/02 01:02:31  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.13  1999/02/26 22:08:34  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.12  1999/02/01 21:08:33  curt
++// Optimizations from Norman Vine.
++//
++// Revision 1.11  1998/11/23 21:48:09  curt
++// Borland portability tweaks.
++//
++// Revision 1.10  1998/11/07 19:07:06  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.9  1998/11/06 21:17:32  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8  1998/11/06 14:46:59  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.7  1998/10/20 18:26:06  curt
++// Updates to point3d.hxx
++//
++// Revision 1.6  1998/10/18 01:17:16  curt
++// Point3D tweaks.
++//
++// Revision 1.5  1998/10/16 23:27:14  curt
++// C++-ifying.
++//
++// Revision 1.4  1998/10/16 00:51:46  curt
++// Converted to Point3D class.
++//
++// Revision 1.3  1998/09/21 20:55:00  curt
++// Used the cartesian form of the airport area coordinates to determine the
++// center.
++//
++// Revision 1.2  1998/09/14 12:44:30  curt
++// Don't recalculate perimeter points since it is not likely that they will match
++// exactly with the previously calculated points, which will leave an ugly gap
++// around the airport area.
++//
++// Revision 1.1  1998/09/14 02:14:01  curt
++// Initial revision of genapt.[ch]xx for generating airport scenery.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fa5c0dccfeab6bf51511532ce36ad184965711b3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,77 @@@
++//
++// getapt.hxx -- generate airport scenery from the given definition file
++//
++// Written by Curtis Olson, started September 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _GENAPT_HXX
++#define _GENAPT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <set>
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++
++#include <Scenery/tile.hxx>
++
++FG_USING_STD(string);
++FG_USING_STD(set);
++
++
++// maximum size of airport perimeter structure, even for complex
++// airports such as KORD this number is typically not very big.
++#define MAX_PERIMETER 20
++
++// name of the material to use for the airport base
++#define APT_BASE_MATERIAL "grass"
++
++
++// Load a .apt file and register the GL fragments with the
++// corresponding tile
++int
++fgAptGenerate(const string& path, fgTILE *tile);
++
++
++#endif /* _AIRPORTS_HXX */
++
++
++// $Log$
++// Revision 1.3  1999/03/02 01:02:32  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.2  1998/11/23 21:48:10  curt
++// Borland portability tweaks.
++//
++// Revision 1.1  1998/09/14 02:14:01  curt
++// Initial revision of genapt.[ch]xx for generating airport scenery.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eddc1c4ec5ba76da28ae482bdff41b611cce9796
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,236 @@@
++//
++// simple.cxx -- a really simplistic class to manage airport ID,
++//                 lat, lon of the center of one of it's runways, and 
++//                 elevation in feet.
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++
++#include STL_STRING
++#include STL_FUNCTIONAL
++#include STL_ALGORITHM
++
++#include "simple.hxx"
++
++
++fgAIRPORTS::fgAIRPORTS() {
++}
++
++
++// load the data
++int fgAIRPORTS::load( const string& file ) {
++    fgAIRPORT a;
++
++    // build the path name to the airport file
++    string path = current_options.get_fg_root() + "/Airports/" + file;
++
++    airports.erase( airports.begin(), airports.end() );
++
++    fg_gzifstream in( path );
++    if ( !in ) {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << path );
++      exit(-1);
++    }
++
++    /*
++    // We can use the STL copy algorithm because the input
++    // file doesn't contain and comments or blank lines.
++    copy( istream_iterator<fgAIRPORT,ptrdiff_t>(in.stream()),
++        istream_iterator<fgAIRPORT,ptrdiff_t>(),
++        inserter( airports, airports.begin() ) );
++    */
++
++    // read in each line of the file
++    in >> skipcomment;
++    while ( ! in.eof() )
++    {
++      in >> a;
++      airports.insert(a);
++      in >> skipcomment;
++    }
++
++    return 1;
++}
++
++
++// search for the specified id
++bool
++fgAIRPORTS::search( const string& id, fgAIRPORT* a ) const
++{
++    const_iterator it = airports.find( fgAIRPORT(id) );
++    if ( it != airports.end() )
++    {
++      *a = *it;
++      return true;
++    }
++    else
++    {
++      return false;
++    }
++}
++
++
++fgAIRPORT
++fgAIRPORTS::search( const string& id ) const
++{
++    fgAIRPORT a;
++    this->search( id, &a );
++    return a;
++}
++
++
++// Destructor
++fgAIRPORTS::~fgAIRPORTS( void ) {
++}
++
++
++// $Log$
++// Revision 1.10  1999/02/26 22:08:35  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.9  1998/11/06 21:17:34  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8  1998/11/06 14:47:01  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.7  1998/09/08 21:38:41  curt
++// Changes by Bernie Bright.
++//
++// Revision 1.6  1998/09/03 21:25:02  curt
++// tweaked in data file comment handling.
++//
++// Revision 1.5  1998/09/02 14:35:38  curt
++// Rewrote simple airport loader so it can deal with comments and blank lines.
++//
++// Revision 1.4  1998/09/01 19:02:53  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.3  1998/08/27 17:01:55  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.2  1998/08/25 20:53:24  curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.1  1998/08/25 17:19:13  curt
++// Moved from ../Main/
++//
++// Revision 1.8  1998/07/13 21:01:37  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.7  1998/06/03 22:01:07  curt
++// Tweaking sound library usage.
++//
++// Revision 1.6  1998/06/03 00:47:13  curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.5  1998/05/29 20:37:22  curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.4  1998/05/13 18:26:25  curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.3  1998/05/06 03:16:24  curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.2  1998/04/28 21:42:50  curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.1  1998/04/25 15:11:11  curt
++// Added an command line option to set starting position based on airport ID.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..38e4b8b6510b68350ad9bf4dc2fd5c61ea087966
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,238 @@@
++//
++// simple.hxx -- a really simplistic class to manage airport ID,
++//                 lat, lon of the center of one of it's runways, and 
++//                 elevation in feet.
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _AIRPORTS_HXX
++#define _AIRPORTS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Include/compiler.h>
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <istream>
++#else
++#  include <istream.h>
++#endif
++
++#include STL_STRING
++#include <set>
++
++FG_USING_STD(string);
++FG_USING_STD(set);
++FG_USING_STD(istream);
++
++
++class fgAIRPORT {
++public:
++    fgAIRPORT( const string& name = "",
++             double lon = 0.0,
++             double lat = 0.0,
++             double ele = 0.0 )
++      : id(name), longitude(lon), latitude(lat), elevation(ele) {}
++
++    bool operator < ( const fgAIRPORT& a ) const {
++      return id < a.id;
++    }
++
++public:
++    string id;
++    double longitude;
++    double latitude;
++    double elevation;
++};
++
++inline istream&
++operator >> ( istream& in, fgAIRPORT& a )
++{
++    return in >> a.id >> a.longitude >> a.latitude >> a.elevation;
++}
++
++class fgAIRPORTS {
++public:
++#ifdef FG_NO_DEFAULT_TEMPLATE_ARGS
++    typedef set< fgAIRPORT, less< fgAIRPORT > > container;
++#else
++    typedef set< fgAIRPORT > container;
++#endif
++    typedef container::iterator iterator;
++    typedef container::const_iterator const_iterator;
++
++private:
++    container airports;
++
++public:
++
++    // Constructor
++    fgAIRPORTS();
++
++    // Destructor
++    ~fgAIRPORTS();
++
++    // load the data
++    int load( const string& file );
++
++    // search for the specified id.
++    // Returns true if successful, otherwise returns false.
++    // On success, airport data is returned thru "airport" pointer.
++    // "airport" is not changed if "id" is not found.
++    bool search( const string& id, fgAIRPORT* airport ) const;
++    fgAIRPORT search( const string& id ) const;
++};
++
++
++#endif /* _AIRPORTS_HXX */
++
++
++// $Log$
++// Revision 1.8  1999/03/15 17:58:57  curt
++// MSVC++ portability tweaks contributed by Bernie Bright.
++//   Added using std::istream declaration.
++//
++// Revision 1.7  1999/03/02 01:02:33  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.6  1999/02/26 22:08:36  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.5  1998/11/02 18:25:34  curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.4  1998/09/08 21:38:43  curt
++// Changes by Bernie Bright.
++//
++// Revision 1.3  1998/09/01 19:02:54  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.2  1998/08/27 17:01:56  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.1  1998/08/25 17:19:14  curt
++// Moved from ../Main/
++//
++// Revision 1.7  1998/07/24 21:39:09  curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.6  1998/07/06 21:34:19  curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.5  1998/06/17 21:35:11  curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.4  1998/06/03 00:47:14  curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.3  1998/06/01 17:54:42  curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.2  1998/05/29 20:37:22  curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.1  1998/04/25 15:11:11  curt
++// Added an command line option to set starting position based on airport ID.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3d3af9f390035a741fe6c9590c287e05308126ac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++noinst_LIBRARIES = libAstro.a
++
++libAstro_a_SOURCES = \
++      celestialBody.cxx celestialBody.hxx \
++      jupiter.cxx jupiter.hxx \
++      mars.cxx mars.hxx \
++      mercury.cxx mercury.hxx \
++      moon.cxx moon.hxx \
++      neptune.cxx neptune.hxx \
++      pluto.hxx \
++      saturn.cxx saturn.hxx \
++      sky.cxx sky.hxx \
++      solarsystem.cxx solarsystem.hxx \
++      star.cxx star.hxx \
++      stars.cxx stars.hxx \
++      uranus.cxx uranus.hxx \
++      venus.cxx venus.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8af66d78b6cd7aaedc847d6fda7e6990fac5cbd5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,177 @@@
++/**************************************************************************
++ * celestialBody.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#include "celestialBody.hxx"
++#include "star.hxx"
++#include <Debug/logstream.hxx>
++
++#ifdef FG_MATH_EXCEPTION_CLASH
++#  define exception c_exception
++#endif
++#include <math.h>
++
++/**************************************************************************
++ * void CelestialBody::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * Basically, this member function provides a general interface for 
++ * calculating the right ascension and declinaion. This function is 
++ * used for calculating the planetary positions. For the planets, an 
++ * overloaded member function is provided to additionally calculate the
++ * planet's magnitude. 
++ * The sun and moon have their own overloaded updatePosition member, as their
++ * position is calculated an a slightly different manner.  
++ *
++ * arguments:
++ * fgTIME t: provides the current time.
++ * Star *ourSun: the sun's position is needed to convert heliocentric 
++ *               coordinates into geocentric coordinates.
++ *
++ * return value: none
++ *
++ *************************************************************************/
++void CelestialBody::updatePosition(fgTIME *t, Star *ourSun)
++{
++  double eccAnom, v, ecl, actTime, 
++    xv, yv, xh, yh, zh, xg, yg, zg, xe, ye, ze;
++
++  updateOrbElements(t);
++  actTime = fgCalcActTime(t);
++
++  // calcualate the angle bewteen ecliptic and equatorial coordinate system
++  ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 *actTime);
++  
++  eccAnom = fgCalcEccAnom(M, e);  //calculate the eccentric anomaly
++  xv = a * (cos(eccAnom) - e);
++  yv = a * (sqrt (1.0 - e*e) * sin(eccAnom));
++  v = atan2(yv, xv);           // the planet's true anomaly
++  r = sqrt (xv*xv + yv*yv);    // the planet's distance
++  
++  // calculate the planet's position in 3D space
++  xh = r * (cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i));
++  yh = r * (sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i));
++  zh = r * (sin(v+w) * sin(i));
++
++  // calculate the ecliptic longitude and latitude
++  xg = xh + ourSun->getxs();
++  yg = yh + ourSun->getys();
++  zg = zh;
++
++  lonEcl = atan2(yh, xh);
++  latEcl = atan2(zh, sqrt(xh*xh+yh*yh));
++
++  xe = xg;
++  ye = yg * cos(ecl) - zg * sin(ecl);
++  ze = yg * sin(ecl) + zg * cos(ecl);
++  rightAscension = atan2(ye, xe);
++  declination = atan2(ze, sqrt(xe*xe + ye*ye));
++  FG_LOG(FG_GENERAL, FG_INFO, "Planet found at : " 
++       << rightAscension << " (ra), " << declination << " (dec)" );
++
++  //calculate some variables specific to calculating the magnitude 
++  //of the planet
++  R = sqrt (xg*xg + yg*yg + zg*zg);
++  s = ourSun->getDistance();
++
++  // It is possible from these calculations for the argument to acos
++  // to exceed the valid range for acos(). So we do a little extra
++  // checking.
++
++  double tmp = (r*r + R*R - s*s) / (2*r*R);
++  if ( tmp > 1.0) { 
++      tmp = 1.0;
++  } else if ( tmp < -1.0) {
++      tmp = -1.0;
++  }
++
++  FV = RAD_TO_DEG * acos( tmp );
++};
++
++/****************************************************************************
++ * double CelestialBody::fgCalcEccAnom(double M, double e)
++ * this private member calculates the eccentric anomaly of a celestial body, 
++ * given its mean anomaly and eccentricity.
++ * 
++ * -Mean anomaly: the approximate angle between the perihelion and the current
++ *  position. this angle increases uniformly with time.
++ *
++ * True anomaly: the actual angle between perihelion and current position.
++ *
++ * Eccentric anomaly: this is an auxilary angle, used in calculating the true
++ * anomaly from the mean anomaly.
++ * 
++ * -eccentricity. Indicates the amount in which the orbit deviates from a 
++ *  circle (0 = circle, 0-1, is ellipse, 1 = parabola, > 1 = hyperbola).
++ *
++ * This function is also known as solveKeplersEquation()
++ *
++ * arguments: 
++ * M: the mean anomaly
++ * e: the eccentricity
++ *
++ * return value:
++ * the eccentric anomaly
++ *
++ ****************************************************************************/
++double CelestialBody::fgCalcEccAnom(double M, double e)
++{
++  double 
++    eccAnom, E0, E1, diff;
++  
++  eccAnom = M + e * sin(M) * (1.0 + e * cos (M));
++  // iterate to achieve a greater precision for larger eccentricities 
++  if (e > 0.05)
++    {
++      E0 = eccAnom;
++      do
++      {
++        E1 = E0 - (E0 - e * sin(E0) - M) / (1 - e *cos(E0));
++        diff = fabs(E0 - E1);
++        E0 = E1;
++      }
++      while (diff > (DEG_TO_RAD * 0.001));
++      return E0;
++    }
++  return eccAnom;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..946226d2e684c1deb74b5b347f300ed327a088ba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,196 @@@
++/**************************************************************************
++ * celestialBody.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _CELESTIALBODY_H_
++#define _CELESTIALBODY_H_
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Time/fg_time.hxx>
++#include <Include/fg_constants.h>
++
++class Star;
++
++class CelestialBody
++{
++protected:              // make the data protected, in order to give the inherited
++                        // classes direct access to the data
++  double NFirst;              /* longitude of the ascending node first part */
++  double NSec;                /* longitude of the ascending node second part */
++  double iFirst;              /* inclination to the ecliptic first part */
++  double iSec;                /* inclination to the ecliptic second part */
++  double wFirst;              /* first part of argument of perihelion */
++  double wSec;                /* second part of argument of perihelion */
++  double aFirst;              /* semimayor axis first part*/
++  double aSec;                /* semimayor axis second part */
++  double eFirst;              /* eccentricity first part */
++  double eSec;                /* eccentricity second part */
++  double MFirst;              /* Mean anomaly first part */
++  double MSec;                /* Mean anomaly second part */
++
++  double N, i, w, a, e, M; /* the resulting orbital elements, obtained from the former */
++
++  double rightAscension, declination;
++  double r, R, s, FV;
++  double magnitude;
++  double lonEcl, latEcl;
++
++  double fgCalcEccAnom(double M, double e);
++  double fgCalcActTime(fgTIME *t);
++  void updateOrbElements(fgTIME *t);
++
++public:
++  CelestialBody(double Nf, double Ns,
++              double If, double Is,
++              double wf, double ws,
++              double af, double as,
++              double ef, double es,
++              double Mf, double Ms, fgTIME *t);
++  void getPos(double *ra, double *dec);
++  void getPos(double *ra, double *dec, double *magnitude);
++  double getLon();
++  double getLat(); 
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++/*****************************************************************************
++ * inline CelestialBody::CelestialBody
++ * public constructor for a generic celestialBody object.
++ * initializes the 6 primary orbital elements. The elements are:
++ * N: longitude of the ascending node
++ * i: inclination to the ecliptic
++ * w: argument of perihelion
++ * a: semi-major axis, or mean distance from the sun
++ * e: eccenticity
++ * M: mean anomaly
++ * Each orbital element consists of a constant part and a variable part that 
++ * gradually changes over time. 
++ *
++ * Argumetns:
++ * the 13 arguments to the constructor constitute the first, constant 
++ * ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital 
++ * elements. The 13th argument is the current time. Note that the inclination
++ * is written with a capital (If, Is), because 'if' is a reserved word in the 
++ * C/C++ programming language.
++ ***************************************************************************/ 
++inline CelestialBody::CelestialBody(double Nf, double Ns,
++                                  double If, double Is,
++                                  double wf, double ws,
++                                  double af, double as,
++                                  double ef, double es,
++                                  double Mf, double Ms, fgTIME *t)
++{
++  NFirst = Nf;     NSec = Ns;
++  iFirst = If;     iSec = Is;
++  wFirst = wf;     wSec = ws;
++  aFirst = af;     aSec = as;
++  eFirst = ef;     eSec = es;
++  MFirst = Mf;     MSec = Ms;
++  updateOrbElements(t);
++};
++
++/****************************************************************************
++ * inline void CelestialBody::updateOrbElements(fgTIME *t)
++ * given the current time, this private member calculates the actual 
++ * orbital elements
++ *
++ * Arguments: fgTIME *t: the current time:
++ *
++ * return value: none
++ ***************************************************************************/
++inline void CelestialBody::updateOrbElements(fgTIME *t)
++{
++  double actTime = fgCalcActTime(t);
++   M = DEG_TO_RAD * (MFirst + (MSec * actTime));
++   w = DEG_TO_RAD * (wFirst + (wSec * actTime));
++   N = DEG_TO_RAD * (NFirst + (NSec * actTime));
++   i = DEG_TO_RAD * (iFirst + (iSec * actTime));
++   e = eFirst + (eSec * actTime);
++   a = aFirst + (aSec * actTime);
++}
++/*****************************************************************************
++ * inline double CelestialBody::fgCalcActTime(fgTIME *t)
++ * this private member function returns the offset in days from the epoch for
++ * wich the orbital elements are calculated (Jan, 1st, 2000).
++ * 
++ * Argument: the current time
++ *
++ * return value: the (fractional) number of days until Jan 1, 2000.
++ ****************************************************************************/
++inline double CelestialBody::fgCalcActTime(fgTIME *t)
++{
++  return (t->mjd - 36523.5);
++}
++
++/*****************************************************************************
++ * inline void CelestialBody::getPos(double* ra, double* dec)
++ * gives public access to Right Ascension and declination
++ *
++ ****************************************************************************/
++inline void CelestialBody::getPos(double* ra, double* dec)
++{
++  *ra  = rightAscension;
++  *dec = declination;
++}
++
++/*****************************************************************************
++ * inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
++ * gives public acces to the current Right ascension, declination, and 
++ * magnitude
++ ****************************************************************************/
++inline void CelestialBody::getPos(double* ra, double* dec, double* magn)
++{
++  *ra = rightAscension;
++  *dec = declination;
++  *magn = magnitude;
++}
++
++inline double CelestialBody::getLon()
++{
++  return lonEcl;
++}
++
++inline double CelestialBody::getLat()
++{
++  return latEcl;
++}
++
++#endif // _CELESTIALBODY_H_
++
++
++
++
++
++
++
++
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..caa0e50750264c492a75a03cc6fc68c53da67474
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,66 @@@
++/**************************************************************************
++ * jupiter.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "jupiter.hxx"
++
++/*************************************************************************
++ * Jupiter::Jupiter(fgTIME *t)
++ * Public constructor for class Jupiter
++ * Argument: The current time.
++ * the hard coded orbital elements for Jupiter are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Jupiter::Jupiter(fgTIME *t) :
++  CelestialBody(100.4542,  2.7685400E-5,      
++              1.3030,   -1.557E-7,
++              273.8777,  1.6450500E-5,
++              5.2025600, 0.000000,
++              0.048498,  4.469E-9,
++              19.89500,  0.08308530010, t)
++{
++}
++
++/*************************************************************************
++ * void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Jupiter, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Jupiter specific equation
++ *************************************************************************/
++void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -9.25 + 5*log10( r*R ) + 0.014 * FV;
++}
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..13cdd7642876d45d55f62723a6fc4b63b5624f45
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * jupiter.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _JUPITER_HXX_
++#define _JUPITER_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Jupiter : public CelestialBody
++{
++public:
++  Jupiter (fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _JUPITER_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5f430c870cb54d4fb7875825846dd2aa49b55f51
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,60 @@@
++/**************************************************************************
++ * mars.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "mars.hxx"
++
++/*************************************************************************
++ * Mars::Mars(fgTIME *t)
++ * Public constructor for class Mars
++ * Argument: The current time.
++ * the hard coded orbital elements for Mars are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Mars::Mars(fgTIME *t) :
++  CelestialBody(49.55740,  2.1108100E-5,
++              1.8497,   -1.78E-8,
++              286.5016,  2.9296100E-5,
++              1.5236880, 0.000000,
++              0.093405,  2.516E-9,
++              18.60210,  0.52402077660, t)
++{
++}
++/*************************************************************************
++ * void Mars::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Mars, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Mars specific equation
++ *************************************************************************/
++void Mars::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -1.51 + 5*log10( r*R ) + 0.016 * FV;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8b7c3264d71caff7f07c47a3e17d3400cfe52f0c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * mars.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MARS_HXX_
++#define _MARS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Mars : public CelestialBody
++{
++public:
++  Mars ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _MARS_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f8c3d67264a79541c8bde5a9f68c98bf39113daf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,62 @@@
++/**************************************************************************
++ * mercury.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "mercury.hxx"
++
++/*************************************************************************
++ * Mercury::Mercury(fgTIME *t)
++ * Public constructor for class Mercury
++ * Argument: The current time.
++ * the hard coded orbital elements for Mercury are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Mercury::Mercury(fgTIME *t) :
++  CelestialBody (48.33130,   3.2458700E-5,
++                  7.0047,    5.00E-8,
++                  29.12410,  1.0144400E-5,
++                  0.3870980, 0.000000,
++                  0.205635,  5.59E-10,
++                  168.6562,  4.09233443680, t)
++{
++}
++/*************************************************************************
++ * void Mercury::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Mercury, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Mercury specific equation
++ *************************************************************************/
++void Mercury::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -0.36 + 5*log10( r*R ) + 0.027 * FV + 2.2E-13 * pow(FV, 6); 
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c7fea4bdd68fdcdcd1a17515ab62db62b0f363ba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * mercury.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MERCURY_HXX_
++#define _MERCURY_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Mercury : public CelestialBody
++{
++public:
++  Mercury ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star* ourSun);
++};
++
++#endif // _MERURY_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..005f3b9d11cb8c3f9df9325a3d2164067c175941
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,394 @@@
++/**************************************************************************
++ * moon.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#include <FDM/flight.hxx>
++
++#include <string.h>
++#include "moon.hxx"
++
++#include <Debug/logstream.hxx>
++#include <Objects/texload.h>
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++
++/*************************************************************************
++ * Moon::Moon(fgTIME *t)
++ * Public constructor for class Moon. Initializes the orbital elements and 
++ * sets up the moon texture.
++ * Argument: The current time.
++ * the hard coded orbital elements for Moon are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Moon::Moon(fgTIME *t) :
++  CelestialBody(125.1228, -0.0529538083,
++              5.1454,    0.00000,
++              318.0634,  0.1643573223,
++              60.266600, 0.000000,
++              0.054900,  0.000000,
++              115.3654,  13.0649929509, t)
++{
++  string tpath, fg_tpath;
++  int width, height;
++  
++  FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
++#ifdef GL_VERSION_1_1
++  xglGenTextures(1, &moon_texid);
++  xglBindTexture(GL_TEXTURE_2D, moon_texid);
++#elif GL_EXT_texture_object
++  xglGenTexturesEXT(1, &moon_texid);
++  xglBindTextureEXT(GL_TEXTURE_2D, moon_texid);
++#else
++#  error port me
++#endif
++
++  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++  // load in the texture data
++  tpath = current_options.get_fg_root() + "/Textures/" + "moon.rgb";
++  
++  if ( (moon_texbuf = read_rgb_texture(tpath.c_str(), &width, &height)) 
++       == NULL )
++  {
++    // Try compressed
++    fg_tpath = tpath + ".gz";
++    if ( (moon_texbuf = read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
++       == NULL )
++    {
++      FG_LOG( FG_GENERAL, FG_ALERT, 
++              "Error in loading moon texture " << tpath );
++      exit(-1);
++    } 
++  } 
++
++  glTexImage2D( GL_TEXTURE_2D,
++              0,
++              GL_RGB,
++              256, 256,
++              0,
++              GL_RGB, GL_UNSIGNED_BYTE,
++              moon_texbuf);
++
++  // setup the halo texture
++  FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
++#ifdef GL_VERSION_1_1
++  xglGenTextures(1, &moon_halotexid);
++  xglBindTexture(GL_TEXTURE_2D, moon_halotexid);
++#elif GL_EXT_texture_object
++  xglGenTexturesEXT(1, &moon_halotexid);
++  xglBindTextureEXT(GL_TEXTURE_2D, moon_halotexid);
++#else
++#  error port me
++#endif
++
++  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++  setHalo();
++  glTexImage2D( GL_TEXTURE_2D,
++              0,
++              GL_RGBA,
++              256, 256,
++              0,
++              GL_RGBA, GL_UNSIGNED_BYTE,
++              moon_halotexbuf);
++  moonObject = gluNewQuadric();
++}
++
++Moon::~Moon()
++{
++  //delete moonObject;
++  delete moon_texbuf;
++  delete moon_halotexbuf;
++}
++
++
++static int texWidth = 256;    /* 64x64 is plenty */
++
++void Moon::setHalo()
++{
++  int texSize;
++  //void *textureBuf;
++  GLubyte *p;
++  int i,j;
++  double radius;
++  
++  texSize = texWidth*texWidth;
++  
++  moon_halotexbuf = new GLubyte[texSize*4];
++  if (!moon_halotexbuf) 
++    return;  // Ugly!
++  
++  p = moon_halotexbuf;
++  
++  radius = (double)(texWidth / 2);
++  
++  for (i=0; i < texWidth; i++) {
++    for (j=0; j < texWidth; j++) {
++      double x, y, d;
++          
++      x = fabs((double)(i - (texWidth / 2)));
++      y = fabs((double)(j - (texWidth / 2)));
++
++      d = sqrt((x * x) + (y * y));
++      if (d < radius) 
++      {
++        double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
++        // inverse square looks nice 
++        *p = (int)((double)0xff * (t * t));
++        *(p+1) = (int)((double) 0xff * (t*t));
++        *(p+2) = (int)((double) 0xff * (t*t));
++        *(p+3) = 0x11;
++      } 
++      else
++      {
++        *p = 0x00;
++        *(p+1) = 0x00;
++        *(p+2) = 0x00;
++        *(p+3) = 0x11;
++      }
++      p += 4;
++    }
++  }
++  //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth, 
++  //      GL_LUMINANCE,
++  //      GL_UNSIGNED_BYTE, textureBuf);
++  //free(textureBuf);
++}
++
++
++/*****************************************************************************
++ * void Moon::updatePosition(fgTIME *t, Star *ourSun)
++ * this member function calculates the actual topocentric position (i.e.) 
++ * the position of the moon as seen from the current position on the surface
++ * of the moon. 
++ ****************************************************************************/
++void Moon::updatePosition(fgTIME *t, Star *ourSun)
++{
++  double 
++    eccAnom, ecl, actTime,
++    xv, yv, v, r, xh, yh, zh, xg, yg, zg, xe, ye, ze,
++    Ls, Lm, D, F, mpar, gclat, rho, HA, g,
++    geoRa, geoDec;
++  
++  fgAIRCRAFT *air;
++  FGInterface *f;
++
++  air = &current_aircraft;
++  f = air->fdm_state;
++ 
++  updateOrbElements(t);
++  actTime = fgCalcActTime(t);
++
++  // calculate the angle between ecliptic and equatorial coordinate system
++  // in Radians
++  ecl = ((DEG_TO_RAD * 23.4393) - (DEG_TO_RAD * 3.563E-7) * actTime);  
++  eccAnom = fgCalcEccAnom(M, e);  // Calculate the eccentric anomaly
++  xv = a * (cos(eccAnom) - e);
++  yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
++  v = atan2(yv, xv);               // the moon's true anomaly
++  r = sqrt (xv*xv + yv*yv);       // and its distance
++  
++  // estimate the geocentric rectangular coordinates here
++  xh = r * (cos(N) * cos (v+w) - sin (N) * sin(v+w) * cos(i));
++  yh = r * (sin(N) * cos (v+w) + cos (N) * sin(v+w) * cos(i));
++  zh = r * (sin(v+w) * sin(i));
++
++  // calculate the ecliptic latitude and longitude here
++  lonEcl = atan2 (yh, xh);
++  latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
++
++  /* Calculate a number of perturbatioin, i.e. disturbances caused by the 
++   * gravitational infuence of the sun and the other major planets.
++   * The largest of these even have a name */
++  Ls = ourSun->getM() + ourSun->getw();
++  Lm = M + w + N;
++  D = Lm - Ls;
++  F = Lm - N;
++  
++  lonEcl += DEG_TO_RAD * (-1.274 * sin (M - 2*D)
++                        +0.658 * sin (2*D)
++                        -0.186 * sin(ourSun->getM())
++                        -0.059 * sin(2*M - 2*D)
++                        -0.057 * sin(M - 2*D + ourSun->getM())
++                        +0.053 * sin(M + 2*D)
++                        +0.046 * sin(2*D - ourSun->getM())
++                        +0.041 * sin(M - ourSun->getM())
++                        -0.035 * sin(D)
++                        -0.031 * sin(M + ourSun->getM())
++                        -0.015 * sin(2*F - 2*D)
++                        +0.011 * sin(M - 4*D)
++                        );
++  latEcl += DEG_TO_RAD * (-0.173 * sin(F-2*D)
++                        -0.055 * sin(M - F - 2*D)
++                        -0.046 * sin(M + F - 2*D)
++                        +0.033 * sin(F + 2*D)
++                        +0.017 * sin(2*M + F)
++                        );
++  r += (-0.58 * cos(M - 2*D)
++      -0.46 * cos(2*D)
++      );
++  FG_LOG(FG_GENERAL, FG_INFO, "Running moon update");
++  xg = r * cos(lonEcl) * cos(latEcl);
++  yg = r * sin(lonEcl) * cos(latEcl);
++  zg = r *               sin(latEcl);
++  
++  xe = xg;
++  ye = yg * cos(ecl) -zg * sin(ecl);
++  ze = yg * sin(ecl) +zg * cos(ecl);
++
++  geoRa  = atan2(ye, xe);
++  geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
++
++  // Given the moon's geocentric ra and dec, calculate its 
++  // topocentric ra and dec. i.e. the position as seen from the
++  // surface of the earth, instead of the center of the earth
++
++  // First calculate the moon's parrallax, that is, the apparent size of the 
++  // (equatorial) radius of the earth, as seen from the moon 
++  mpar = asin ( 1 / r);
++  gclat = f->get_Latitude() - 0.003358 * 
++      sin (2 * DEG_TO_RAD * f->get_Latitude() );
++  rho = 0.99883 + 0.00167 * cos(2 * DEG_TO_RAD * f->get_Latitude());
++  if (geoRa < 0)
++    geoRa += (2*FG_PI);
++  
++  HA = t->lst - (3.8197186 * geoRa);
++  g = atan (tan(gclat) / cos ((HA / 3.8197186)));
++  rightAscension = geoRa - mpar * rho * cos(gclat) * sin(HA) / cos (geoDec);
++  declination = geoDec - mpar * rho * sin (gclat) * sin (g - geoDec) / sin(g);
++}
++
++
++/************************************************************************
++ * void Moon::newImage()
++ *
++ * This function regenerates a new visual image of the moon, which is added to
++ * solarSystem display list.
++ *
++ * Arguments: Right Ascension and declination
++ *
++ * return value: none
++ **************************************************************************/
++void Moon::newImage()
++{
++  fgLIGHT *l = &cur_light_params;
++  float moon_angle = l->moon_angle;
++  
++  /*double x_2, x_4, x_8, x_10;
++  GLfloat ambient;
++  GLfloat amb[4];*/
++  int moonSize = 750;
++
++  GLfloat moonColor[4] = {0.85, 0.75, 0.35, 1.0};
++  GLfloat black[4] = {0.0, 0.0,0.0,1.0};
++  GLfloat white[4] = {1.0, 1.0,1.0,1.0};
++  
++  if( moon_angle*RAD_TO_DEG < 100 ) 
++    {
++      /*
++      x_2 = moon_angle * moon_angle;
++      x_4 = x_2 * x_2;
++      x_8 = x_4 * x_4;
++      x_10 = x_8 * x_2;
++      ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
++      if (ambient < 0.3) ambient = 0.3;
++      if (ambient > 1.0) ambient = 1.0;
++      
++      amb[0] = ((ambient * 6.0)  - 1.0); // minimum value = 0.8
++      amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
++      amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
++      amb[3] = 1.00;
++      
++      if (amb[0] > 1.0) amb[0] = 1.0;
++      if (amb[1] > 1.0) amb[1] = 1.0;
++      if (amb[2] > 1.0) amb[2] = 1.0;
++      xglColor3fv(amb);
++      xglColor3f(1.0, 1.0, 1.0); */
++      xglPushMatrix();
++      {
++      //xglRotatef(-90, 0.0, 0.0, 1.0);
++      xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++      xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++      
++      FG_LOG( FG_GENERAL, FG_INFO, 
++              "Ra = (" << (RAD_TO_DEG *rightAscension) 
++              << "), Dec= (" << (RAD_TO_DEG *declination) << ")" );
++      xglTranslatef(0.0, 58600.0, 0.0);
++      
++      glEnable(GL_TEXTURE_2D);                                             // TEXTURE ENABLED
++      glEnable(GL_BLEND);                                                  // BLEND ENABLED
++      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
++      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
++      glBindTexture(GL_TEXTURE_2D, moon_halotexid);
++      
++      glBegin(GL_QUADS);
++      glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
++      glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
++      glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0,  5000);
++      glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0,  5000);
++      glEnd();
++      
++      xglEnable(GL_LIGHTING);                                                // LIGHTING ENABLED
++      xglEnable( GL_LIGHT0 );
++      // set lighting parameters
++      xglLightfv(GL_LIGHT0, GL_AMBIENT, white );
++      xglLightfv(GL_LIGHT0, GL_DIFFUSE, white );
++      xglEnable( GL_CULL_FACE );
++      xglMaterialfv(GL_FRONT, GL_AMBIENT, black);
++      xglMaterialfv(GL_FRONT, GL_DIFFUSE, moonColor); 
++      
++      //glEnable(GL_TEXTURE_2D);
++      glBlendFunc(GL_ONE, GL_ONE);
++      
++      //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
++      glBindTexture(GL_TEXTURE_2D, moon_texid);                         
++      //glDisable(GL_LIGHTING);                                               // LIGHTING DISABLED
++      
++      gluQuadricTexture(moonObject, GL_TRUE );   
++      gluSphere(moonObject,  moonSize, 12, 12 );
++      glDisable(GL_TEXTURE_2D);                                             // TEXTURE DISABLED
++      glDisable(GL_BLEND);                                                  // BLEND DISABLED
++      }
++      xglPopMatrix();
++      glDisable(GL_LIGHTING);                                               // LIGHTING DISABLED
++
++    }
++  else
++    {
++    }
++}
++
++
++
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e69b3ff626a19386b02dbca448f0278009613ebf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,57 @@@
++/**************************************************************************
++ * moon.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MOON_HXX_
++#define _MOON_HXX_
++
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Time/fg_time.hxx>
++
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Moon : public CelestialBody
++{
++private:
++  void TexInit();  // This should move to the constructor eventually.
++
++  GLUquadricObj *moonObject;
++  GLuint Sphere;
++  GLuint moon_texid;
++  GLuint moon_halotexid;
++  GLubyte *moon_texbuf;
++  GLubyte *moon_halotexbuf;
++  
++  void setHalo();
++public:
++  Moon ( fgTIME *t);
++  ~Moon();
++  void updatePosition(fgTIME *t, Star *ourSun);
++  void newImage();
++};
++
++
++#endif // _MOON_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dce7190000b60b1c87391eb866a19020a3ae05b7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,60 @@@
++/**************************************************************************
++ * neptune.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "neptune.hxx"
++
++/*************************************************************************
++ * Neptune::Neptune(fgTIME *t)
++ * Public constructor for class Neptune
++ * Argument: The current time.
++ * the hard coded orbital elements for Neptune are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Neptune::Neptune(fgTIME *t) :
++  CelestialBody(131.7806,   3.0173000E-5,
++              1.7700,    -2.550E-7,
++              272.8461,  -6.027000E-6,        
++              30.058260,  3.313E-8,
++              0.008606,   2.150E-9,
++              260.2471,   0.00599514700, t)
++{
++}
++/*************************************************************************
++ * void Neptune::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Neptune, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Neptune specific equation
++ *************************************************************************/
++void Neptune::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -6.90 + 5*log10 (r*R) + 0.001 *FV;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6d23b95413ef718c47ff0d907874b1e8dbd75b9e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * neptune.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _NEPTUNE_HXX_
++#define _NEPTUNE_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Neptune : public CelestialBody
++{
++public:
++  Neptune ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _NEPTUNE_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..03a37e91cd3c951b0a057db48feeb13aededbdae
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,37 @@@
++/**************************************************************************
++ * pluto.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _PLUTO_HXX_
++#define _PLUTO_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++
++class Pluto : public CelestialBody
++{
++public:
++  Pluto ( fgTIME t);
++};
++
++#endif // _PLUTO_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5f643dc14467762513819f4b5d12f4906cfa3f7f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,70 @@@
++/**************************************************************************
++ * saturn.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "saturn.hxx"
++
++/*************************************************************************
++ * Saturn::Saturn(fgTIME *t)
++ * Public constructor for class Saturn
++ * Argument: The current time.
++ * the hard coded orbital elements for Saturn are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Saturn::Saturn(fgTIME *t) :
++  CelestialBody(113.6634,   2.3898000E-5,
++              2.4886,    -1.081E-7,
++              339.3939,   2.9766100E-5,
++              9.5547500,  0.000000,
++              0.055546,  -9.499E-9,
++              316.9670,   0.03344422820, t)
++{
++}
++
++/*************************************************************************
++ * void Saturn::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Saturn, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Saturn specific equation
++ *************************************************************************/
++void Saturn::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  
++  double actTime = fgCalcActTime(t);
++  double ir = 0.4897394;
++  double Nr = 2.9585076 + 6.6672E-7*actTime;
++  double B = asin (sin(declination) * cos(ir) - 
++                 cos(declination) * sin(ir) *
++                 sin(rightAscension - Nr));
++  double ring_magn = -2.6 * sin(fabs(B)) + 1.2 * pow(sin(B), 2);
++  magnitude = -9.0 + 5*log10(r*R) + 0.044 * FV + ring_magn;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..621ddf879da9ba5d5c6ea1fe9d9b7ddcdcd7a863
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,46 @@@
++/**************************************************************************
++ * saturn.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _SATURN_HXX_
++#define _SATURN_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Saturn : public CelestialBody
++{
++public:
++  Saturn ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _SATURN_HXX_
++
++
++
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d5e7730c7cd2876066d524d0d300f249dc0376d1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,516 @@@
++// sky.cxx -- model sky with an upside down "bowl"
++//
++// Written by Curtis Olson, started December 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <math.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_random.h>
++#include <Time/event.hxx>
++#include <Time/fg_time.hxx>
++
++#include "sky.hxx"
++
++
++// in meters of course
++#define CENTER_ELEV   25000.0
++
++#define INNER_RADIUS  50000.0
++#define INNER_ELEV    20000.0
++
++#define MIDDLE_RADIUS 70000.0
++#define MIDDLE_ELEV    8000.0
++
++#define OUTER_RADIUS  80000.0
++#define OUTER_ELEV        0.0
++
++#define BOTTOM_RADIUS 50000.0
++#define BOTTOM_ELEV   -2000.0
++
++
++static float inner_vertex[12][3];
++static float middle_vertex[12][3];
++static float outer_vertex[12][3];
++static float bottom_vertex[12][3];
++
++static float inner_color[12][4];
++static float middle_color[12][4];
++static float outer_color[12][4];
++
++
++// Calculate the sky structure vertices
++void fgSkyVerticesInit( void ) {
++    float theta;
++    int i;
++
++    FG_LOG(FG_ASTRO, FG_INFO, "  Generating the sky dome vertices.");
++
++    for ( i = 0; i < 12; i++ ) {
++      theta = (i * 30.0) * DEG_TO_RAD;
++      
++      inner_vertex[i][0] = cos(theta) * INNER_RADIUS;
++      inner_vertex[i][1] = sin(theta) * INNER_RADIUS;
++      inner_vertex[i][2] = INNER_ELEV;
++      
++      // printf("    %.2f %.2f\n", cos(theta) * INNER_RADIUS, 
++      //        sin(theta) * INNER_RADIUS);
++
++      middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
++      middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
++      middle_vertex[i][2] = MIDDLE_ELEV;
++          
++      outer_vertex[i][0] = cos((double)theta) * OUTER_RADIUS;
++      outer_vertex[i][1] = sin((double)theta) * OUTER_RADIUS;
++      outer_vertex[i][2] = OUTER_ELEV;
++          
++      bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
++      bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
++      bottom_vertex[i][2] = BOTTOM_ELEV;
++    }
++}
++
++
++// (Re)calculate the sky colors at each vertex
++void fgSkyColorsInit( void ) {
++    fgLIGHT *l;
++    double sun_angle, diff;
++    double outer_param[3], outer_amt[3], outer_diff[3];
++    double middle_param[3], middle_amt[3], middle_diff[3];
++    int i, j;
++
++    l = &cur_light_params;
++
++    FG_LOG( FG_ASTRO, FG_INFO, 
++          "  Generating the sky colors for each vertex." );
++
++    // setup for the possibility of sunset effects
++    sun_angle = l->sun_angle * RAD_TO_DEG;
++    // fgPrintf( FG_ASTRO, FG_INFO, 
++    //           "  Sun angle in degrees = %.2f\n", sun_angle);
++
++    if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
++      // 0.0 - 0.4
++      outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
++      outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
++      outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
++      // outer_param[2] = 0.0;
++
++      middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
++      middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
++      middle_param[2] = 0.0;
++
++      outer_diff[0] = outer_param[0] / 6.0;
++      outer_diff[1] = outer_param[1] / 6.0;
++      outer_diff[2] = outer_param[2] / 6.0;
++
++      middle_diff[0] = middle_param[0] / 6.0;
++      middle_diff[1] = middle_param[1] / 6.0;
++      middle_diff[2] = middle_param[2] / 6.0;
++    } else {
++      outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
++      middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
++
++      outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
++      middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
++    }
++    // printf("  outer_red_param = %.2f  outer_red_diff = %.2f\n", 
++    //        outer_red_param, outer_red_diff);
++
++    // calculate transition colors between sky and fog
++    for ( j = 0; j < 3; j++ ) {
++      outer_amt[j] = outer_param[j];
++      middle_amt[j] = middle_param[j];
++    }
++
++    for ( i = 0; i < 6; i++ ) {
++      for ( j = 0; j < 3; j++ ) {
++          diff = l->sky_color[j] - l->fog_color[j];
++
++          // printf("sky = %.2f  fog = %.2f  diff = %.2f\n", 
++          //        l->sky_color[j], l->fog_color[j], diff);
++
++          inner_color[i][j] = l->sky_color[j] - diff * 0.3;
++          middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
++          outer_color[i][j] = l->fog_color[j] + outer_amt[j];
++
++          if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
++          if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
++          if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
++          if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
++          if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
++          if ( outer_color[i][j] < 0.10 ) { outer_color[i][j] = 0.10; }
++      }
++      inner_color[i][3] = middle_color[i][3] = outer_color[i][3] = 
++          l->sky_color[3];
++
++      for ( j = 0; j < 3; j++ ) {
++          outer_amt[j] -= outer_diff[j];
++          middle_amt[j] -= middle_diff[j];
++      }
++
++      /*
++      printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0],
++             inner_color[i][1], inner_color[i][2], inner_color[i][3]);
++      printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++             middle_color[i][0], middle_color[i][1], middle_color[i][2], 
++             middle_color[i][3]);
++      printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++             outer_color[i][0], outer_color[i][1], outer_color[i][2], 
++             outer_color[i][3]);
++      */
++    }
++
++    for ( j = 0; j < 3; j++ ) {
++      outer_amt[j] = 0.0;
++      middle_amt[j] = 0.0;
++    }
++
++    for ( i = 6; i < 12; i++ ) {
++
++      for ( j = 0; j < 3; j++ ) {
++          diff = l->sky_color[j] - l->fog_color[j];
++
++          // printf("sky = %.2f  fog = %.2f  diff = %.2f\n", 
++          //        l->sky_color[j], l->fog_color[j], diff);
++
++          inner_color[i][j] = l->sky_color[j] - diff * 0.3;
++          middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
++          outer_color[i][j] = l->fog_color[j] + outer_amt[j];
++
++          if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
++          if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
++          if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
++          if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
++          if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
++          if ( outer_color[i][j] < 0.15 ) { outer_color[i][j] = 0.15; }
++      }
++      inner_color[i][3] = middle_color[i][3] = outer_color[i][3] = 
++          l->sky_color[3];
++
++      for ( j = 0; j < 3; j++ ) {
++          outer_amt[j] += outer_diff[j];
++          middle_amt[j] += middle_diff[j];
++      }
++
++      /*
++      printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0],
++             inner_color[i][1], inner_color[i][2], inner_color[i][3]);
++      printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++             middle_color[i][0], middle_color[i][1], middle_color[i][2], 
++             middle_color[i][3]);
++      printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++             outer_color[i][0], outer_color[i][1], outer_color[i][2], 
++             outer_color[i][3]);
++      */
++    }
++}
++
++
++// Initialize the sky structure and colors
++void fgSkyInit( void ) {
++    FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
++
++    fgSkyVerticesInit();
++
++    // regester fgSkyColorsInit() as an event to be run periodically
++    global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit, 
++                          fgEVENT::FG_EVENT_READY, 30000);
++}
++
++
++// Draw the Sky
++void fgSkyRender( void ) {
++    FGInterface *f;
++    fgLIGHT *l;
++    float inner_color[4];
++    float middle_color[4];
++    float outer_color[4];
++    double diff;
++    int i;
++
++    f = current_aircraft.fdm_state;
++    l = &cur_light_params;
++
++    // printf("Rendering the sky.\n");
++
++    // calculate the proper colors
++    for ( i = 0; i < 3; i++ ) {
++      diff = l->sky_color[i] - l->adj_fog_color[i];
++
++      // printf("sky = %.2f  fog = %.2f  diff = %.2f\n", 
++      //        l->sky_color[j], l->adj_fog_color[j], diff);
++
++      inner_color[i] = l->sky_color[i] - diff * 0.3;
++      middle_color[i] = l->sky_color[i] - diff * 0.9;
++      outer_color[i] = l->adj_fog_color[i];
++    }
++    inner_color[3] = middle_color[3] = outer_color[3] = l->adj_fog_color[3];
++
++    xglPushMatrix();
++
++    // Translate to view position
++    Point3D zero_elev = current_view.get_cur_zero_elev();
++    xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
++    // printf("  Translated to %.2f %.2f %.2f\n", 
++    //        zero_elev.x, zero_elev.y, zero_elev.z );
++
++    // Rotate to proper orientation
++    // printf("  lon = %.2f  lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
++    //        FG_Latitude * RAD_TO_DEG);
++    xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
++    xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
++    xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
++
++    // Draw inner/center section of sky*/
++    xglBegin( GL_TRIANGLE_FAN );
++    xglColor4fv(l->sky_color);
++    xglVertex3f(0.0, 0.0, CENTER_ELEV);
++    for ( i = 11; i >= 0; i-- ) {
++      xglColor4fv( inner_color );
++      xglVertex3fv( inner_vertex[i] );
++    }
++    xglColor4fv( inner_color );
++    xglVertex3fv( inner_vertex[11] );
++    xglEnd();
++
++    // Draw the middle ring
++    xglBegin( GL_TRIANGLE_STRIP );
++    for ( i = 0; i < 12; i++ ) {
++      xglColor4fv( middle_color );
++      // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++      //        middle_color[i][0], middle_color[i][1], middle_color[i][2], 
++      //        middle_color[i][3]);
++      // xglColor4f(1.0, 0.0, 0.0, 1.0);
++      xglVertex3fv( middle_vertex[i] );
++      xglColor4fv( inner_color );
++      // printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, 
++      //        inner_color[i][0], inner_color[i][1], inner_color[i][2], 
++      //        inner_color[i][3]);
++      // xglColor4f(0.0, 0.0, 1.0, 1.0);
++      xglVertex3fv( inner_vertex[i] );
++    }
++    xglColor4fv( middle_color );
++    // xglColor4f(1.0, 0.0, 0.0, 1.0);
++    xglVertex3fv( middle_vertex[0] );
++    xglColor4fv( inner_color );
++    // xglColor4f(0.0, 0.0, 1.0, 1.0);
++    xglVertex3fv( inner_vertex[0] );
++    xglEnd();
++
++    // Draw the outer ring
++    xglBegin( GL_TRIANGLE_STRIP );
++    for ( i = 0; i < 12; i++ ) {
++      xglColor4fv( outer_color );
++      xglVertex3fv( outer_vertex[i] );
++      xglColor4fv( middle_color );
++      xglVertex3fv( middle_vertex[i] );
++    }
++    xglColor4fv( outer_color );
++    xglVertex3fv( outer_vertex[0] );
++    xglColor4fv( middle_color );
++    xglVertex3fv( middle_vertex[0] );
++    xglEnd();
++
++    // Draw the bottom skirt
++    xglBegin( GL_TRIANGLE_STRIP );
++    xglColor4fv( outer_color );
++    for ( i = 0; i < 12; i++ ) {
++      xglVertex3fv( bottom_vertex[i] );
++      xglVertex3fv( outer_vertex[i] );
++    }
++    xglVertex3fv( bottom_vertex[0] );
++    xglVertex3fv( outer_vertex[0] );
++    xglEnd();
++
++    xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.21  1999/02/05 21:28:50  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.20  1999/02/02 20:13:29  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.19  1999/02/01 21:33:26  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.18  1999/02/01 21:09:00  curt
++// Bug fix in vertex order of inner disk (fan) of the sky dome.
++//
++// Revision 1.17  1998/12/09 18:50:12  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.16  1998/12/05 15:54:03  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.15  1998/12/03 01:15:36  curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun portability.
++//
++// Revision 1.14  1998/11/06 21:17:39  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.13  1998/10/20 18:28:30  curt
++// Tweaked sunset/sunrise colors.
++//
++// Revision 1.12  1998/10/16 23:27:18  curt
++// C++-ifying.
++//
++// Revision 1.11  1998/10/16 00:52:19  curt
++// Converted to Point3D class.
++//
++// Revision 1.10  1998/08/29 13:07:16  curt
++// Rewrite of event manager thanks to Bernie Bright.
++//
++// Revision 1.9  1998/08/22 01:18:59  curt
++// Minor tweaks to avoid using unitialized memory.
++//
++// Revision 1.8  1998/08/12 21:40:44  curt
++// Sky now tracks adjusted fog color so it blends well with terrain.
++//
++// Revision 1.7  1998/07/22 21:39:21  curt
++// Lower skirt tracks adjusted fog color, not fog color.
++//
++// Revision 1.6  1998/05/23 14:07:14  curt
++// Use new C++ events class.
++//
++// Revision 1.5  1998/04/28 01:19:02  curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.4  1998/04/26 05:10:01  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.3  1998/04/25 22:06:25  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:45:03  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fixed a bug when generating sky colors.
++//
++// Revision 1.1  1998/04/22 13:21:32  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.9  1998/04/03 21:52:50  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.8  1998/03/09 22:47:25  curt
++// Incorporated Durk's updates.
++//
++// Revision 1.7  1998/02/19 13:05:49  curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.6  1998/02/07 15:29:32  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.5  1998/01/27 00:47:48  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.4  1998/01/26 15:54:28  curt
++// Added a "skirt" to try to help hide gaps between scenery and sky.  This will
++// have to be revisited in the future.
++//
++// Revision 1.3  1998/01/19 19:26:59  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2  1998/01/19 18:40:17  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1  1998/01/07 03:16:19  curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.11  1997/12/30 22:22:38  curt
++// Further integration of event manager.
++//
++// Revision 1.10  1997/12/30 20:47:53  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.9  1997/12/30 13:06:57  curt
++// A couple lighting tweaks ...
++//
++// Revision 1.8  1997/12/23 04:58:38  curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.7  1997/12/22 23:45:48  curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.6  1997/12/22 04:14:34  curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.5  1997/12/19 23:34:59  curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.4  1997/12/19 16:45:02  curt
++// Working on scene rendering order and options.
++//
++// Revision 1.3  1997/12/18 23:32:36  curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.2  1997/12/18 04:07:03  curt
++// Worked on properly translating and positioning the sky dome.
++//
++// Revision 1.1  1997/12/17 23:14:30  curt
++// Initial revision.
++// Begin work on rendering the sky. (Rather than just using a clear screen.)
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d39528211628ff39c35c1bc8ba984c83739950fb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,73 @@@
++// sky.hxx -- model sky with an upside down "bowl"
++//
++// Written by Curtis Olson, started December 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _SKY_HXX
++#define _SKY_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// (Re)generate the display list
++void fgSkyInit( void );
++
++// (Re)calculate the sky colors at each vertex
++void fgSkyColorsInit( void );
++
++// Draw the Sky
++void fgSkyRender( void );
++
++
++#endif // _SKY_HXX
++
++
++// $Log$
++// Revision 1.2  1998/10/16 23:27:19  curt
++// C++-ifying.
++//
++// Revision 1.1  1998/04/22 13:21:33  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.4  1998/04/21 17:02:32  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.3  1998/01/22 02:59:28  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2  1998/01/19 18:40:17  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1  1998/01/07 03:16:19  curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.2  1997/12/22 23:45:49  curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.1  1997/12/17 23:14:31  curt
++// Initial revision.
++// Begin work on rendering the sky. (Rather than just using a clear screen.)
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f5448cde71c25966705c1a6c998909c2005b2f54
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,219 @@@
++/**************************************************************************
++ * solarsystem.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++#include <Debug/logstream.hxx>
++#include <Time/sunpos.hxx>
++#include <Time/moonpos.hxx>
++#include "solarsystem.hxx"
++
++/***************************************************************************
++ * default constructor for class  SolarSystem:   
++ * or course there can only be one way to create an entire solar system -:) )
++ * the fgTIME argument is needed to properly initialize the the current orbital
++ * elements
++ *************************************************************************/
++SolarSystem::SolarSystem(fgTIME *t)
++{
++  if (theSolarSystem)
++    {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error: only one solarsystem allowed" );
++      exit(-1);
++    }
++  theSolarSystem = this;
++  ourSun     = new Star(t);   
++  earthsMoon = new Moon(t);
++  mercury    = new Mercury(t);
++  venus      = new Venus(t);
++  mars       = new Mars(t);
++  jupiter    = new Jupiter(t);
++  saturn     = new Saturn(t);
++  uranus     = new Uranus(t);
++  neptune    = new Neptune(t);
++
++  displayList = 0;
++};
++
++/**************************************************************************
++ * the destructor for class SolarSystem;
++ **************************************************************************/
++SolarSystem::~SolarSystem()
++{
++  delete ourSun;
++  delete earthsMoon;
++  delete mercury;
++  delete venus;
++  delete mars;
++  delete jupiter;
++  delete saturn;
++  delete uranus;
++  delete neptune;
++}
++/****************************************************************************
++ * void SolarSystem::rebuild()
++ *
++ * this member function updates the positions for the sun, moon, and planets,
++ * and then rebuilds the display list. 
++ *
++ * arguments: none
++ * return value: none
++ ***************************************************************************/
++void SolarSystem::rebuild()
++{
++  //fgLIGHT *l = &cur_light_params;
++  fgTIME  *t = &cur_time_params;  
++  //float x, y, z;
++  //double sun_angle;
++  double ra, dec;
++  //double x_2, x_4, x_8, x_10;*/
++  double magnitude;
++  //GLfloat ambient;
++  //GLfloat amb[4];
++  
++  
++  glDisable(GL_LIGHTING);
++
++
++  // Step 1: update all the positions
++  ourSun->updatePosition(t);
++  earthsMoon->updatePosition(t, ourSun);
++  mercury->updatePosition(t, ourSun);
++  venus->updatePosition(t, ourSun);
++  mars->updatePosition(t, ourSun);
++  jupiter->updatePosition(t, ourSun);
++  saturn->updatePosition(t, ourSun);
++  uranus->updatePosition(t, ourSun);
++  neptune->updatePosition(t, ourSun);
++  
++  fgUpdateSunPos();   // get the right sun angle (especially important when 
++                      // running for the first time).
++  fgUpdateMoonPos();
++
++  if (displayList)
++    xglDeleteLists(displayList, 1);
++
++  displayList = xglGenLists(1);
++
++  // Step 2: rebuild the display list
++  xglNewList( displayList, GL_COMPILE);
++  {
++    // Step 2a: Add the moon...
++    // Not that it is preferred to draw the moon first, and the sun next, in order to mime a
++    // solar eclipse. This is yet untested though...
++
++    earthsMoon->newImage();
++    // Step 2b:  Add the sun
++    //xglPushMatrix();
++    //{
++      ourSun->newImage();
++      //}
++    //xglPopMatrix();
++    // Step 2c: Add the planets
++    xglBegin(GL_POINTS);
++    mercury->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    venus  ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    mars   ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    jupiter->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    saturn ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    uranus ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    neptune->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++    xglEnd();
++    xglEnable(GL_LIGHTING);
++  }
++  xglEndList();
++}
++
++/*****************************************************************************
++ * double SolarSystem::scaleMagnitude(double magn)
++ * This private member function rescales the original magnitude, as used in the
++ * astronomical sense of the word, into a value used by OpenGL to draw a 
++ * convincing Star or planet
++ * 
++ * Argument: the astronomical magnitude
++ *
++ * return value: the rescaled magnitude
++ ****************************************************************************/
++double SolarSystem::scaleMagnitude(double magn)
++{
++  double magnitude = (0.0 - magn) / 5.0 + 1.0;
++  magnitude = magnitude * 0.7 + (3 * 0.1);
++  if (magnitude > 1.0) magnitude = 1.0;
++  if (magnitude < 0.0) magnitude = 0.0;
++  return magnitude;
++}
++
++/***************************************************************************
++ * void SolarSytem::addPlanetToList(double ra, double dec, double magn);
++ *
++ * This private member function first causes the magnitude to be properly
++ * rescaled, and then adds the planet to the display list.
++ * 
++ * arguments: Right Ascension, declination, and magnitude
++ *
++ * return value: none
++ **************************************************************************/
++void SolarSystem::addPlanetToList(double ra, double dec, double magn)
++{
++  double
++    magnitude = scaleMagnitude ( magn );
++
++  fgLIGHT *l = &cur_light_params;
++
++  if ((double) (l->sun_angle - FG_PI_2) > 
++      ((magnitude - 1.0) * - 20 * DEG_TO_RAD)) 
++    {
++      xglColor3f (magnitude, magnitude, magnitude);
++      xglVertex3f( 50000.0 * cos (ra) * cos (dec),
++                 50000.0 * sin (ra) * cos (dec),
++                 50000.0 * sin (dec));
++    }
++}
++
++
++SolarSystem* SolarSystem::theSolarSystem = 0;
++
++/******************************************************************************
++ * void solarSystemRebuild()
++ * this a just a wrapper function, provided for use as an interface to the 
++ * event manager
++ *****************************************************************************/
++void solarSystemRebuild()
++{
++  SolarSystem::theSolarSystem->rebuild();
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c7c520bde0a4b1fbc3a6cc42e9691757ad0566e2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,92 @@@
++/**************************************************************************
++ * solarsystem.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _SOLARSYSTEM_H_
++#define _SOLARSYSTEM_H_
++
++#include <Time/light.hxx>
++#include <Time/fg_time.hxx>
++#include <Main/views.hxx>
++
++#include "star.hxx"
++#include "moon.hxx"
++#include "mercury.hxx"
++#include "venus.hxx"
++#include "mars.hxx"
++#include "jupiter.hxx"
++#include "saturn.hxx"
++#include "uranus.hxx"
++#include "neptune.hxx"
++#include "pluto.hxx"
++
++
++class SolarSystem
++{
++private:
++  Star*    ourSun;
++  Moon*    earthsMoon;
++  Mercury* mercury;
++  Venus*   venus;
++  Mars*    mars;
++  Jupiter* jupiter;
++  Saturn*  saturn;
++  Uranus*  uranus;
++  Neptune* neptune;
++  //Pluto*   pluto;
++  
++  GLint displayList;
++  double scaleMagnitude(double magn);
++  void addPlanetToList(double ra, double dec, double magn);
++
++
++public:
++  SolarSystem(fgTIME *t);
++  CelestialBody *getSun();
++  CelestialBody *getMoon();
++  ~SolarSystem();
++
++  static SolarSystem *theSolarSystem;  // thanks to Bernie Bright!
++  void rebuild();
++  friend void solarSystemRebuild();
++  void draw();
++};
++
++inline CelestialBody* SolarSystem::getSun()
++{
++  return ourSun;
++}
++
++inline CelestialBody* SolarSystem::getMoon()
++{
++  return earthsMoon;
++}
++
++inline void SolarSystem::draw()
++{
++  xglCallList(displayList);
++}
++  
++extern void solarSystemRebuild();
++
++#endif // _SOLARSYSTEM_H_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..12663c1f8bae366049b863777febdc3960ecc0be
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,272 @@@
++/**************************************************************************
++ * star.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++#include <Time/sunpos.hxx>
++#include <Debug/logstream.hxx>
++#include <Time/light.hxx>
++#include "star.hxx"
++
++/*************************************************************************
++ * Star::Star(fgTIME *t)
++ * Public constructor for class Star
++ * Argument: The current time.
++ * the hard coded orbital elements our sun are passed to 
++ * CelestialBody::CelestialBody();
++ * note that the word sun is avoided, in order to prevent some compilation
++ * problems on sun systems 
++ ************************************************************************/
++Star::Star(fgTIME *t) :
++  CelestialBody (0.000000,  0.0000000000,
++               0.0000,    0.00000,
++               282.9404,  4.7093500E-5,       
++               1.0000000, 0.000000,   
++               0.016709,  -1.151E-9,
++               356.0470,  0.98560025850, t)
++{
++    
++  FG_LOG( FG_GENERAL, FG_INFO, "Initializing Sun Texture");
++#ifdef GL_VERSION_1_1
++  xglGenTextures(1, &sun_texid);
++  xglBindTexture(GL_TEXTURE_2D, sun_texid);
++#elif GL_EXT_texture_object
++  xglGenTexturesEXT(1, &sun_texid);
++  xglBindTextureEXT(GL_TEXTURE_2D, sun_texid);
++#else
++#  error port me
++#endif
++
++  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++  setTexture();
++  glTexImage2D( GL_TEXTURE_2D,
++              0,
++              GL_RGBA,
++              256, 256,
++              0,
++              GL_RGBA, GL_UNSIGNED_BYTE,
++              sun_texbuf);
++     
++  SunObject = gluNewQuadric();
++  if(SunObject == NULL)
++    {
++      printf("gluNewQuadric(SunObject) failed  !\n");
++      exit(0);
++    }
++  
++  //SunList = 0;
++  distance = 0.0;
++}
++
++Star::~Star()
++{
++  //delete SunObject;
++  delete [] sun_texbuf;
++}
++
++
++
++static int texWidth = 256;    /* 64x64 is plenty */
++
++void Star::setTexture()
++{
++  int texSize;
++  //void *textureBuf;
++  GLubyte *p;
++  int i,j;
++  double radius;
++  
++  texSize = texWidth*texWidth;
++  
++  sun_texbuf = new GLubyte[texSize*4];
++  if (!sun_texbuf) 
++    return;  // Ugly!
++  
++  p = sun_texbuf;
++  
++  radius = (double)(texWidth / 2);
++  
++  for (i=0; i < texWidth; i++) {
++    for (j=0; j < texWidth; j++) {
++      double x, y, d;
++          
++      x = fabs((double)(i - (texWidth / 2)));
++      y = fabs((double)(j - (texWidth / 2)));
++
++      d = sqrt((x * x) + (y * y));
++      if (d < radius) 
++      {
++        double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
++        // inverse square looks nice 
++        *p = (int)((double)0xff * (t * t));
++        *(p+1) = (int)((double) 0xff * (t*t));
++        *(p+2) = (int)((double) 0xff * (t*t));
++        *(p+3) = (int)((double) 0xff * (t*t));
++      } 
++      else
++      {
++        *p = 0x00;
++        *(p+1) = 0x00;
++        *(p+2) = 0x00;
++        *(p+3) = 0x00;
++      }
++      p += 4;
++    }
++  }
++  //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth, 
++  //      GL_LUMINANCE,
++  //      GL_UNSIGNED_BYTE, textureBuf);
++  //free(textureBuf);
++}
++/*************************************************************************
++ * void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of our sun.
++ *************************************************************************/
++void Star::updatePosition(fgTIME *t)
++{
++  double 
++    actTime, eccAnom, 
++    xv, yv, v, r,
++    xe, ye, ze, ecl;
++
++  updateOrbElements(t);
++  
++  actTime = fgCalcActTime(t);
++  ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
++  eccAnom = fgCalcEccAnom(M, e);  // Calculate the eccentric Anomaly (also known as solving Kepler's equation)
++  
++  xv = cos(eccAnom) - e;
++  yv = sqrt (1.0 - e*e) * sin(eccAnom);
++  v = atan2 (yv, xv);                   // the sun's true anomaly
++  distance = r = sqrt (xv*xv + yv*yv);  // and its distance
++
++  lonEcl = v + w; // the sun's true longitude
++  latEcl = 0;
++
++  // convert the sun's true longitude to ecliptic rectangular 
++  // geocentric coordinates (xs, ys)
++  xs = r * cos (lonEcl);
++  ys = r * sin (lonEcl);
++
++  // convert ecliptic coordinates to equatorial rectangular
++  // geocentric coordinates
++
++  xe = xs;
++  ye = ys * cos (ecl);
++  ze = ys * sin (ecl);
++
++  // And finally, calculate right ascension and declination
++  rightAscension = atan2 (ye, xe);
++  declination = atan2 (ze, sqrt (xe*xe + ye*ye));
++}
++  
++void Star::newImage(void)
++{
++  /*static float stars[3];
++  stars[0] = 0.0;
++  stars[1] = 0.0;
++  stars[2] = 1.0;*/
++
++  fgLIGHT *l = &cur_light_params;
++  float sun_angle = l->sun_angle;
++  
++  if( sun_angle*RAD_TO_DEG < 100 ) { // else no need to draw sun
++    
++    
++    double x_2, x_4, x_8, x_10;
++    GLfloat ambient;
++    GLfloat amb[4];
++    int sun_size = 750;
++    
++    // daily variation sun gets larger near horizon
++    /*if(sun_angle*RAD_TO_DEG > 84.0 && sun_angle*RAD_TO_DEG < 95)
++      {
++      double sun_grow = 9*fabs(94-sun_angle*RAD_TO_DEG);
++      sun_size = (int)(sun_size + sun_size * cos(sun_grow*DEG_TO_RAD));
++      }*/
++    x_2 = sun_angle * sun_angle;
++    x_4 = x_2 * x_2;
++    x_8 = x_4 * x_4;
++    x_10 = x_8 * x_2;
++    ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
++    if (ambient < 0.3) ambient = 0.3;
++    if (ambient > 1.0) ambient = 1.0;
++    
++    amb[0] = ((ambient * 6.0)  - 1.0); // minimum value = 0.8
++    amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
++    amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
++    amb[3] = 1.00;
++    
++    if (amb[0] > 1.0) amb[0] = 1.0;
++    if (amb[1] > 1.0) amb[1] = 1.0;
++    if (amb[2] > 1.0) amb[2] = 1.0;
++    xglColor3fv(amb);
++    glPushMatrix();
++    {
++      xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++      xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++      xglTranslatef(0,60000,0);
++    
++      glEnable(GL_TEXTURE_2D);                                             // TEXTURE ENABLED
++      glEnable(GL_BLEND);                                                  // BLEND ENABLED
++  
++      //glEnable(GL_TEXTURE_2D);
++      //glEnable(GL_BLEND);
++      //glDisable(GL_LIGHTING);
++      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
++      //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
++      glBindTexture(GL_TEXTURE_2D, sun_texid);
++      
++      glBegin(GL_QUADS);
++      glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
++      glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
++      glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0,  5000);
++      glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0,  5000);
++      glEnd();
++    }
++    glPopMatrix();
++    xglDisable(GL_TEXTURE_2D);
++    glDisable(GL_BLEND);
++    glPushMatrix();
++    {
++      xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++      xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++      xglTranslatef(0,58600,0);
++      gluSphere( SunObject,  sun_size, 10, 10 );
++    }
++    glPopMatrix();
++    glDisable(GL_TEXTURE_2D);                                             // TEXTURE DISABLED
++    glDisable(GL_BLEND);                                                  // BLEND DISABLED  
++  }
++}
++
++  
++  
++  
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5e0ccc946bfe2b3611a5143ef8f4c51edb40bc0f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,99 @@@
++/**************************************************************************
++ * star.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _STAR_HXX_
++#define _STAR_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++
++
++class Star : public CelestialBody
++{
++private:
++  //double longitude;  // the sun's true longitude - this is depreciated by
++                       // CelestialBody::lonEcl 
++  double xs, ys;     // the sun's rectangular geocentric coordinates
++  double distance;   // the sun's distance to the earth
++   GLUquadricObj *SunObject;
++  GLuint sun_texid;
++  GLubyte *sun_texbuf;
++
++  void setTexture();
++public:
++  Star (fgTIME *t);
++  ~Star();
++  void updatePosition(fgTIME *t);
++  double getM();
++  double getw();
++  //double getLon();
++  double getxs();
++  double getys();
++  double getDistance();
++  void newImage();
++};
++
++
++
++inline double Star::getM()
++{
++  return M;
++}
++
++inline double Star::getw()
++{
++  return w;
++}
++
++inline double Star::getxs()
++{
++  return xs;
++}
++
++inline double Star::getys()
++{
++  return ys;
++}
++
++inline double Star::getDistance()
++{
++  return distance;
++}
++
++
++#endif // _STAR_HXX_
++
++
++
++
++
++
++
++
++
++
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8f7bdb23a391f1eba23e3341cbd0cf77085c3cd3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,545 @@@
++// stars.cxx -- data structures and routines for managing and rendering stars.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cmath>
++#  include <cstdio>
++#  include <cstring>
++#  include <ctime>
++#else
++#  include <math.h>
++#  include <stdio.h>
++#  include <string.h>
++#  include <time.h>
++#endif
++
++#include <string>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Misc/stopwatch.hxx>
++#include <Time/fg_time.hxx>
++#include "Misc/stopwatch.hxx"
++
++#include "stars.hxx"
++
++FG_USING_STD(getline);
++
++#define EpochStart           (631065600)
++#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
++#define FG_MAX_STARS 3500
++
++// Define four structures, each with varying amounts of stars
++static GLint stars[FG_STAR_LEVELS];
++
++
++// Initialize the Star Management Subsystem
++int fgStarsInit( void ) {
++    Point3D starlist[FG_MAX_STARS];
++    // struct CelestialCoord pltPos;
++    double right_ascension, declination, magnitude;
++    double min_magnitude[FG_STAR_LEVELS];
++    // double ra_save, decl_save;
++    // double ra_save1, decl_save1;
++    int i, j, starcount, count;
++
++    FG_LOG( FG_ASTRO, FG_INFO, "Initializing stars" );
++
++    if ( FG_STAR_LEVELS < 4 ) {
++      FG_LOG( FG_ASTRO, FG_ALERT, "Big whups in stars.cxx" );
++      exit(-1);
++    }
++
++    // build the full path name to the stars data base file
++    string path = current_options.get_fg_root() + "/Astro/stars" + ".gz";
++
++    FG_LOG( FG_ASTRO, FG_INFO, "  Loading stars from " << path );
++
++    fg_gzifstream in( path );
++    if ( ! in ) {
++      FG_LOG( FG_ASTRO, FG_ALERT, "Cannot open star file: " << path );
++      exit(-1);
++    }
++
++    starcount = 0;
++
++    StopWatch timer;
++    timer.start();
++
++    // read in each line of the file
++    while ( ! in.eof() && starcount < FG_MAX_STARS )
++    {
++      in >> skipcomment;
++      string name;
++      getline( in, name, ',' );
++      in >> starlist[starcount];
++      ++starcount;
++    }
++
++    timer.stop();
++    FG_LOG( FG_ASTRO, FG_INFO, 
++          "Loaded " << starcount << " stars in "
++          << timer.elapsedSeconds() << " seconds" );
++
++    min_magnitude[0] = 4.2;
++    min_magnitude[1] = 3.6;
++    min_magnitude[2] = 3.0;
++    min_magnitude[3] = 2.4;
++    min_magnitude[4] = 1.8;
++    min_magnitude[5] = 1.2;
++    min_magnitude[6] = 0.6;
++    min_magnitude[7] = 0.0;
++
++    // build the various star display lists
++    for ( i = 0; i < FG_STAR_LEVELS; i++ ) {
++
++      stars[i] = xglGenLists(1);
++      xglNewList( stars[i], GL_COMPILE );
++      xglBegin( GL_POINTS );
++
++      count = 0;
++
++      for ( j = 0; j < starcount; j++ ) {
++          magnitude = starlist[j].z();
++          // printf("magnitude = %.2f\n", magnitude);
++
++          if ( magnitude < min_magnitude[i] ) {
++              right_ascension = starlist[j].x();
++              declination = starlist[j].y();
++
++              count++;
++
++              // scale magnitudes to (0.0 - 1.0)
++              magnitude = (0.0 - magnitude) / 5.0 + 1.0;
++              
++              // scale magnitudes again so they look ok
++              if ( magnitude > 1.0 ) { magnitude = 1.0; }
++              if ( magnitude < 0.0 ) { magnitude = 0.0; }
++              // magnitude =
++              //     magnitude * 0.7 + (((FG_STAR_LEVELS - 1) - i) * 0.042);
++                
++              magnitude = magnitude * 0.9 + 
++                  (((FG_STAR_LEVELS - 1) - i) * 0.014);
++              // printf("  Found star: %d %s, %.3f %.3f %.3f\n", count,
++              //        name, right_ascension, declination, magnitude);
++                  
++              xglColor3f( magnitude, magnitude, magnitude );
++              //xglColor3f(0,0,0);*/
++              xglVertex3f( 50000.0*cos(right_ascension)*cos(declination),
++                           50000.0*sin(right_ascension)*cos(declination),
++                           50000.0*sin(declination) );
++          }
++      } // while
++
++      xglEnd();
++
++      /*
++      xglBegin(GL_LINE_LOOP);
++        xglColor3f(1.0, 0.0, 0.0);
++      xglVertex3f( 50000.0 * cos(ra_save-0.2) * cos(decl_save-0.2),
++                  50000.0 * sin(ra_save-0.2) * cos(decl_save-0.2),
++                  50000.0 * sin(decl_save-0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save+0.2) * cos(decl_save-0.2),
++                  50000.0 * sin(ra_save+0.2) * cos(decl_save-0.2),
++                  50000.0 * sin(decl_save-0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save+0.2) * cos(decl_save+0.2),
++                  50000.0 * sin(ra_save+0.2) * cos(decl_save+0.2),
++                  50000.0 * sin(decl_save+0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save-0.2) * cos(decl_save+0.2),
++                  50000.0 * sin(ra_save-0.2) * cos(decl_save+0.2),
++                  50000.0 * sin(decl_save+0.2) );
++      xglEnd();
++      */
++
++      /*
++      xglBegin(GL_LINE_LOOP);
++        xglColor3f(0.0, 1.0, 0.0);
++      xglVertex3f( 50000.0 * cos(ra_save1-0.2) * cos(decl_save1-0.2),
++                  50000.0 * sin(ra_save1-0.2) * cos(decl_save1-0.2),
++                  50000.0 * sin(decl_save1-0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save1+0.2) * cos(decl_save1-0.2),
++                  50000.0 * sin(ra_save1+0.2) * cos(decl_save1-0.2),
++                  50000.0 * sin(decl_save1-0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save1+0.2) * cos(decl_save1+0.2),
++                  50000.0 * sin(ra_save1+0.2) * cos(decl_save1+0.2),
++                  50000.0 * sin(decl_save1+0.2) );
++      xglVertex3f( 50000.0 * cos(ra_save1-0.2) * cos(decl_save1+0.2),
++                  50000.0 * sin(ra_save1-0.2) * cos(decl_save1+0.2),
++                  50000.0 * sin(decl_save1+0.2) );
++      xglEnd();
++      */
++
++      xglEndList();
++          
++      FG_LOG( FG_ASTRO, FG_INFO,
++              "  Loading " << count << " stars brighter than " 
++              << min_magnitude[i] );
++    }
++
++    return 1;  // OK, we got here because initialization worked.
++}
++
++
++// Draw the Stars
++void fgStarsRender( void ) {
++    FGInterface *f;
++    fgLIGHT *l;
++    fgTIME *t;
++    int i;
++
++    f = current_aircraft.fdm_state;
++    l = &cur_light_params;
++    t = &cur_time_params;
++
++    // FG_PI_2 + 0.1 is about 6 degrees after sundown and before sunrise
++
++    // t->sun_angle = 3.0; // to force stars to be drawn (for testing)
++
++    // render the stars
++    if ( l->sun_angle > (FG_PI_2 + 5 * DEG_TO_RAD ) ) {
++      // determine which star structure to draw
++      if ( l->sun_angle > (FG_PI_2 + 10.0 * DEG_TO_RAD ) ) {
++          i = 0;
++      } else if ( l->sun_angle > (FG_PI_2 + 8.8 * DEG_TO_RAD ) ) {
++          i = 1;
++      } else if ( l->sun_angle > (FG_PI_2 + 7.5 * DEG_TO_RAD ) ) {
++          i = 2;
++      } else if ( l->sun_angle > (FG_PI_2 + 7.0 * DEG_TO_RAD ) ) {
++          i = 3;
++      } else if ( l->sun_angle > (FG_PI_2 + 6.5 * DEG_TO_RAD ) ) {
++          i = 4;
++      } else if ( l->sun_angle > (FG_PI_2 + 6.0 * DEG_TO_RAD ) ) {
++          i = 5;
++      } else if ( l->sun_angle > (FG_PI_2 + 5.5 * DEG_TO_RAD ) ) {
++          i = 6;
++      } else {
++          i = 7;
++      }
++
++      // printf("RENDERING STARS = %d (night)\n", i);
++
++      xglCallList(stars[i]);
++    } else {
++      // printf("not RENDERING STARS (day)\n");
++    }
++}
++
++
++// $Log$
++// Revision 1.27  1999/02/05 21:28:52  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.26  1999/02/02 20:13:30  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.25  1998/12/09 18:50:15  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.24  1998/12/05 15:54:04  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.23  1998/11/23 21:48:28  curt
++// Borland portability tweaks.
++//
++// Revision 1.22  1998/11/07 19:07:07  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.21  1998/11/06 21:17:42  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.20  1998/11/06 14:47:02  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.19  1998/10/16 23:27:21  curt
++// C++-ifying.
++//
++// Revision 1.18  1998/10/16 00:52:20  curt
++// Converted to Point3D class.
++//
++// Revision 1.17  1998/09/24 15:36:19  curt
++// Converted to c++ style comments.
++//
++// Revision 1.16  1998/09/24 15:25:24  curt
++// Miscellaneous tweaks.
++//
++//
++// Revision 1.15  1998/09/17 18:25:12  curt
++// Fixed output message.
++//
++// Revision 1.14  1998/09/15 04:26:22  curt
++// New textured moon and rewritten/restructured Astro code contributed by Durk
++// Talsma.
++//
++// Revision 1.13  1998/09/01 19:03:04  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.12  1998/08/27 17:02:01  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.11  1998/08/25 20:53:29  curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.10  1998/08/10 20:33:09  curt
++// Rewrote star loading and rendering to:
++//   1. significantly improve load speed
++//   2. transition from no stars to stars through eight stages.
++//
++// Revision 1.9  1998/08/06 12:45:20  curt
++// Modified to bring in stars in 8 increments based on magnitude, not number
++// of stars.
++//
++// Revision 1.8  1998/07/13 21:00:10  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.7  1998/05/29 20:35:42  curt
++// Added zlib support for reading in compressed data files.
++//
++// Revision 1.6  1998/05/13 18:25:35  curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.5  1998/04/28 01:19:03  curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.4  1998/04/26 05:10:02  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.3  1998/04/25 22:06:26  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:45:03  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fixed a bug when generating sky colors.
++//
++// Revision 1.1  1998/04/22 13:21:34  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11  1998/04/18 04:13:58  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10  1998/04/03 21:52:51  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.9  1998/03/14 00:27:12  curt
++// Updated fgGENERAL to a "type" of struct.
++//
++// Revision 1.8  1998/02/12 21:59:38  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.7  1998/02/09 15:07:48  curt
++// Minor tweaks.
++//
++// Revision 1.6  1998/02/02 20:53:23  curt
++// To version 0.29
++//
++// Revision 1.5  1998/01/27 18:35:53  curt
++// Minor tweaks.
++//
++// Revision 1.4  1998/01/27 00:47:49  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.3  1998/01/19 19:26:59  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2  1998/01/19 18:40:18  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1  1998/01/07 03:16:20  curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.24  1997/12/30 22:22:39  curt
++// Further integration of event manager.
++//
++// Revision 1.23  1997/12/30 20:47:53  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.22  1997/12/30 16:36:53  curt
++// Merged in Durk's changes ...
++//
++// Revision 1.21  1997/12/19 23:35:00  curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.20  1997/12/15 23:55:03  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.19  1997/12/12  19:53:00  curt
++// Working on lightling and material properties.
++//
++// Revision 1.18  1997/12/10 22:37:52  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.17  1997/12/09 04:25:33  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.16  1997/11/25 19:25:38  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.15  1997/10/30 12:38:45  curt
++// Working on new scenery subsystem.
++//
++// Revision 1.14  1997/10/28 21:00:22  curt
++// Changing to new terrain format.
++//
++// Revision 1.13  1997/10/25 03:18:28  curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.12  1997/09/23 00:29:43  curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.11  1997/09/22 14:44:21  curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.10  1997/09/20 03:34:32  curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.9  1997/09/18 16:20:09  curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.8  1997/09/16 22:14:52  curt
++// Tweaked time of day lighting equations.  Don't draw stars during the day.
++//
++// Revision 1.7  1997/09/16 15:50:31  curt
++// Working on star alignment and time issues.
++//
++// Revision 1.6  1997/09/05 14:17:31  curt
++// More tweaking with stars.
++//
++// Revision 1.5  1997/09/05 01:35:59  curt
++// Working on getting stars right.
++//
++// Revision 1.4  1997/09/04 02:17:38  curt
++// Shufflin' stuff.
++//
++// Revision 1.3  1997/08/29 17:55:28  curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.2  1997/08/27 21:32:30  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.1  1997/08/27 03:34:48  curt
++// Initial revision.
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..212718d7eda46e70b282b9a84e232bb0cde5cba5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,114 @@@
++// stars.hxx -- data structures and routines for managing and rendering stars.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _STARS_HXX
++#define _STARS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#include <Time/fg_time.hxx>
++
++#define FG_STAR_LEVELS 8         // how many star transitions
++
++// Initialize the Star Management Subsystem
++int fgStarsInit( void );
++
++// Draw the Stars
++void fgStarsRender( void );
++
++// [no longer used?] extern struct OrbElements pltOrbElements[9];
++extern fgTIME cur_time_params;
++
++
++#endif // _STARS_HXX
++
++
++// $Log$
++// Revision 1.8  1999/01/19 20:57:00  curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.7  1998/09/24 15:36:20  curt
++// Converted to c++ style comments.
++//
++// Revision 1.6  1998/09/24 15:25:26  curt
++// Miscellaneous tweaks.
++//
++//
++// Revision 1.5  1998/09/17 18:25:13  curt
++// Fixed output message.
++//
++// Revision 1.4  1998/09/15 04:26:23  curt
++// New textured moon and rewritten/restructured Astro code contributed by Durk
++// Talsma.
++//
++// Revision 1.3  1998/08/06 12:45:20  curt
++// Modified to bring in stars in 8 increments based on magnitude, not number
++// of stars.
++//
++// Revision 1.2  1998/04/28 01:19:03  curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.1  1998/04/22 13:21:35  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.5  1998/04/21 17:02:33  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.4  1998/02/12 21:59:39  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.3  1998/01/22 02:59:28  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2  1998/01/19 18:40:18  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1  1998/01/07 03:16:20  curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.6  1997/10/25 03:18:29  curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.5  1997/09/18 16:20:09  curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.4  1997/09/05 01:36:00  curt
++// Working on getting stars right.
++//
++// Revision 1.3  1997/08/29 17:55:28  curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.2  1997/08/27 21:32:30  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.1  1997/08/27 03:34:50  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c20a9180709b15c5cd50f415b7d74da9acd919a0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++/**************************************************************************
++ * uranus.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "uranus.hxx"
++
++/*************************************************************************
++ * Uranus::Uranus(fgTIME *t)
++ * Public constructor for class Uranus
++ * Argument: The current time.
++ * the hard coded orbital elements for Uranus are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Uranus::Uranus(fgTIME *t) :
++  CelestialBody(74.00050,   1.3978000E-5,
++              0.7733,     1.900E-8,
++              96.66120,   3.0565000E-5,
++              19.181710, -1.55E-8,
++              0.047318,   7.450E-9,
++              142.5905,   0.01172580600, t)
++{
++}
++
++/*************************************************************************
++ * void Uranus::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Uranus, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Uranus specific equation
++ *************************************************************************/
++void Uranus::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -7.15 + 5*log10( r*R) + 0.001 * FV;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..35bb70373228dea6893a3c5ea2a66d2c29f6fd71
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * uranus.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _URANUS_HXX_
++#define _URANUS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Uranus : public CelestialBody
++{
++public:
++  Uranus ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _URANUS_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..81088ffd1930a4d0fd9276777043dcb19cd13582
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++/**************************************************************************
++ * venus.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include "venus.hxx"
++
++/*************************************************************************
++ * Venus::Venus(fgTIME *t)
++ * Public constructor for class Venus
++ * Argument: The current time.
++ * the hard coded orbital elements for Venus are passed to 
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Venus::Venus(fgTIME *t) :
++  CelestialBody(76.67990,  2.4659000E-5, 
++              3.3946,    2.75E-8,
++              54.89100,  1.3837400E-5,
++              0.7233300, 0.000000,
++              0.006773, -1.302E-9,
++              48.00520,  1.60213022440, t)
++{
++}
++
++/*************************************************************************
++ * void Venus::updatePosition(fgTIME *t, Star *ourSun)
++ * 
++ * calculates the current position of Venus, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using 
++ * a Venus specific equation
++ *************************************************************************/
++void Venus::updatePosition(fgTIME *t, Star *ourSun)
++{
++  CelestialBody::updatePosition(t, ourSun);
++  magnitude = -4.34 + 5*log10( r*R ) + 0.013 * FV + 4.2E-07 * pow(FV,3);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fb062de041d864f6669d704f3d0845dfabe74214
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**************************************************************************
++ * venus.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution  
++ * with the FlightGear project. Version 2 was written in August and 
++ * September 1998. This code is based upon algorithms and data kindly 
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _VENUS_HXX_
++#define _VENUS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Venus : public CelestialBody
++{
++public:
++  Venus ( fgTIME *t);
++  void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _VENUS_HXX_
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..02b62e771b785012e16327aad77fea8d2212aebe
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++noinst_LIBRARIES = libAutopilot.a
++
++libAutopilot_a_SOURCES = autopilot.cxx autopilot.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..76c8d37374c3e63d1f824c8cd9f3a9102d399cad
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,590 @@@
++// autopilot.cxx -- autopilot subsystem
++//
++// Written by Jeff Goeke-Smith, started April 1998.
++//
++// Copyright (C) 1998  Jeff Goeke-Smith, jgoeke@voyager.net
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <assert.h>
++#include <stdlib.h>
++
++#include <Scenery/scenery.hxx>
++
++#include "autopilot.hxx"
++
++#include <Include/fg_constants.h>
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++
++
++// The below routines were copied right from hud.c ( I hate reinventing
++// the wheel more than necessary)
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++
++static double get_speed( void )
++{
++    return( current_aircraft.fdm_state->get_V_equiv_kts() );
++}
++
++static double get_aoa( void )
++{
++    return( current_aircraft.fdm_state->get_Gamma_vert_rad() * RAD_TO_DEG );
++}
++
++static double fgAPget_roll( void )
++{
++    return( current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG );
++}
++
++static double get_pitch( void )
++{
++    return( current_aircraft.fdm_state->get_Theta() );
++}
++
++double fgAPget_heading( void )
++{
++    return( current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG );
++}
++
++static double fgAPget_altitude( void )
++{
++    return( current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER );
++}
++
++static double fgAPget_climb( void )
++{
++    // return in meters per minute
++    return( current_aircraft.fdm_state->get_Climb_Rate() * FEET_TO_METER * 60 );
++}
++
++static double get_sideslip( void )
++{
++    return( current_aircraft.fdm_state->get_Beta() );
++}
++
++static double fgAPget_agl( void )
++{
++        double agl;
++
++        agl = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
++          - scenery.cur_elev;
++
++        return( agl );
++}
++
++// End of copied section.  ( thanks for the wheel :-)
++
++// Local Prototype section
++
++double LinearExtrapolate( double x,double x1, double y1, double x2, double y2);
++double NormalizeDegrees( double Input);
++
++// End Local ProtoTypes
++
++fgAPDataPtr APDataGlobal;     // global variable holding the AP info
++                              // I want this gone.  Data should be in aircraft structure
++
++
++bool fgAPHeadingEnabled( void )
++{
++    fgAPDataPtr APData;
++      
++    APData = APDataGlobal;
++              
++    // heading hold enabled?
++    return APData->heading_hold;
++}
++
++bool fgAPAltitudeEnabled( void )
++{
++    fgAPDataPtr APData;
++      
++    APData = APDataGlobal;
++              
++    // altitude hold or terrain follow enabled?
++    return APData->altitude_hold || APData->terrain_follow ;
++}
++
++bool fgAPAutoThrottleEnabled( void )
++{
++    fgAPDataPtr APData;
++      
++    APData = APDataGlobal;
++
++    // autothrottle enabled?
++    return APData->auto_throttle;
++}
++
++void fgAPAltitudeAdjust( double inc )
++{
++    // Remove at a later date
++    fgAPDataPtr APData;
++    APData = APDataGlobal;
++    // end section
++
++    double target_alt, target_agl;
++
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      target_alt = APData->TargetAltitude * METER_TO_FEET;
++      target_agl = APData->TargetAGL * METER_TO_FEET;
++    } else {
++      target_alt = APData->TargetAltitude;
++      target_agl = APData->TargetAGL;
++    }
++
++    target_alt = (int)(target_alt / inc) * inc + inc;
++    target_agl = (int)(target_agl / inc) * inc + inc;
++
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      target_alt *= FEET_TO_METER;
++      target_agl *= FEET_TO_METER;
++    }
++
++    APData->TargetAltitude = target_alt;
++    APData->TargetAGL = target_agl;
++}
++
++void fgAPHeadingAdjust( double inc )
++{
++    fgAPDataPtr APData;
++    APData = APDataGlobal;
++
++    double target = (int)(APData->TargetHeading / inc) * inc + inc;
++
++    APData->TargetHeading = NormalizeDegrees(target);
++}
++
++void fgAPAutoThrottleAdjust( double inc )
++{
++    fgAPDataPtr APData;
++    APData = APDataGlobal;
++
++    double target = (int)(APData->TargetSpeed / inc) * inc + inc;
++
++    APData->TargetSpeed = target;
++}
++
++void fgAPInit( fgAIRCRAFT *current_aircraft )
++{
++      fgAPDataPtr APData ;
++
++      FG_LOG( FG_AUTOPILOT, FG_INFO, "Init AutoPilot Subsystem" );
++
++      APData  = (fgAPDataPtr)calloc(sizeof(fgAPData),1);
++      
++      if (APData == NULL) {
++          // I couldn't get the mem.  Dying
++          FG_LOG( FG_AUTOPILOT, FG_ALERT, "No ram for Autopilot. Dying.");
++          exit(-1);
++      }
++              
++      APData->heading_hold = false ;     // turn the heading hold off
++      APData->altitude_hold = false ;    // turn the altitude hold off
++
++      APData->TargetHeading = 0.0;    // default direction, due north
++      APData->TargetAltitude = 3000;  // default altitude in meters
++      APData->alt_error_accum = 0.0;
++
++      // These eventually need to be read from current_aircaft somehow.
++
++#if 0
++      // Original values
++      // the maximum roll, in Deg
++      APData->MaxRoll = 7;
++      // the deg from heading to start rolling out at, in Deg
++      APData->RollOut = 30;
++      // how far can I move the aleron from center.
++      APData->MaxAileron= .1;
++      // Smoothing distance for alerion control
++      APData->RollOutSmooth = 10;
++#endif
++
++      // the maximum roll, in Deg
++      APData->MaxRoll = 20;
++
++      // the deg from heading to start rolling out at, in Deg
++      APData->RollOut = 20;
++
++      // how far can I move the aleron from center.
++      APData->MaxAileron= .2;
++
++      // Smoothing distance for alerion control
++      APData->RollOutSmooth = 10;
++
++      //Remove at a later date
++      APDataGlobal = APData;
++      
++};
++
++int fgAPRun( void )
++{
++    // Remove the following lines when the calling funcitons start
++    // passing in the data pointer
++
++    fgAPDataPtr APData;
++      
++    APData = APDataGlobal;
++    // end section
++              
++    // heading hold enabled?
++    if ( APData->heading_hold == true ) {
++      double RelHeading;
++      double TargetRoll;
++      double RelRoll;
++      double AileronSet;
++              
++      RelHeading =  
++          NormalizeDegrees( APData->TargetHeading - fgAPget_heading());
++      // figure out how far off we are from desired heading
++                
++      // Now it is time to deterime how far we should be rolled.
++      FG_LOG( FG_AUTOPILOT, FG_DEBUG, "RelHeading: " << RelHeading );
++              
++              
++      // Check if we are further from heading than the roll out point
++      if ( fabs(RelHeading) > APData->RollOut ) {
++          // set Target Roll to Max in desired direction
++          if (RelHeading < 0 ) {
++              TargetRoll = 0-APData->MaxRoll;
++          } else {
++              TargetRoll = APData->MaxRoll;
++          }
++      } else {
++          // We have to calculate the Target roll
++
++          // This calculation engine thinks that the Target roll
++          // should be a line from (RollOut,MaxRoll) to (-RollOut,
++          // -MaxRoll) I hope this works well.  If I get ambitious
++          // some day this might become a fancier curve or
++          // something.
++
++          TargetRoll = LinearExtrapolate( RelHeading, -APData->RollOut,
++                                          -APData->MaxRoll, APData->RollOut,
++                                          APData->MaxRoll );
++      }
++              
++      // Target Roll has now been Found.
++
++      // Compare Target roll to Current Roll, Generate Rel Roll
++
++      FG_LOG( FG_COCKPIT, FG_BULK, "TargetRoll: " << TargetRoll );
++              
++      RelRoll = NormalizeDegrees(TargetRoll - fgAPget_roll());
++
++      // Check if we are further from heading than the roll out smooth point
++      if ( fabs(RelRoll) > APData->RollOutSmooth ) {
++          // set Target Roll to Max in desired direction
++          if (RelRoll < 0 ) {
++              AileronSet = 0-APData->MaxAileron;
++          } else {
++              AileronSet = APData->MaxAileron;
++          }
++      } else {
++          AileronSet = LinearExtrapolate( RelRoll, -APData->RollOutSmooth,
++                                          -APData->MaxAileron,
++                                          APData->RollOutSmooth,
++                                          APData->MaxAileron );
++      }
++              
++      controls.set_aileron( AileronSet );
++      controls.set_rudder( 0.0 );
++    }
++
++    // altitude hold or terrain follow enabled?
++    if ( APData->altitude_hold || APData->terrain_follow ) {
++      double speed, max_climb, error;
++      double prop_error, int_error;
++      double prop_adj, int_adj, total_adj;
++
++      if ( APData->altitude_hold ) {
++          // normal altitude hold
++          APData->TargetClimbRate = 
++              (APData->TargetAltitude - fgAPget_altitude()) * 8.0;
++      } else if ( APData->terrain_follow ) {
++          // brain dead ground hugging with no look ahead
++          APData->TargetClimbRate = 
++              ( APData->TargetAGL - fgAPget_agl() ) * 16.0;
++      } else {
++          // just try to zero out rate of climb ...
++          APData->TargetClimbRate = 0.0;
++      }
++
++      speed = get_speed();
++
++      if ( speed < 90.0 ) {
++          max_climb = 0.0;
++      } else if ( speed < 100.0 ) {
++          max_climb = (speed - 90.0) * 20;
++      } else {
++          max_climb = ( speed - 100.0 ) * 4.0 + 200.0;
++      }
++
++      if ( APData->TargetClimbRate > max_climb ) {
++          APData->TargetClimbRate = max_climb;
++      }
++
++      if ( APData->TargetClimbRate < -400.0 ) {
++          APData->TargetClimbRate = -400.0;
++      }
++
++      error = fgAPget_climb() - APData->TargetClimbRate;
++
++      // accumulate the error under the curve ... this really should
++      // be *= delta t
++      APData->alt_error_accum += error;
++
++      // calculate integral error, and adjustment amount
++      int_error = APData->alt_error_accum;
++      // printf("error = %.2f  int_error = %.2f\n", error, int_error);
++      int_adj = int_error / 8000.0;
++      
++      // caclulate proportional error
++      prop_error = error;
++      prop_adj = prop_error / 2000.0;
++
++      total_adj = 0.9 * prop_adj + 0.1 * int_adj;
++      if ( total_adj >  0.6 ) { total_adj =  0.6; }
++      if ( total_adj < -0.2 ) { total_adj = -0.2; }
++
++      controls.set_elevator( total_adj );
++    }
++
++    // auto throttle enabled?
++    if ( APData->auto_throttle ) {
++      double error;
++      double prop_error, int_error;
++      double prop_adj, int_adj, total_adj;
++
++      error = APData->TargetSpeed - get_speed();
++
++      // accumulate the error under the curve ... this really should
++      // be *= delta t
++      APData->speed_error_accum += error;
++      if ( APData->speed_error_accum > 2000.0 ) {
++          APData->speed_error_accum = 2000.0;
++      }
++      if ( APData->speed_error_accum < -2000.0 ) {
++          APData->speed_error_accum = -2000.0;
++      }
++
++      // calculate integral error, and adjustment amount
++      int_error = APData->speed_error_accum;
++
++      // printf("error = %.2f  int_error = %.2f\n", error, int_error);
++      int_adj = int_error / 200.0;
++      
++      // caclulate proportional error
++      prop_error = error;
++      prop_adj = 0.5 + prop_error / 50.0;
++
++      total_adj = 0.9 * prop_adj + 0.1 * int_adj;
++      if ( total_adj > 1.0 ) { total_adj = 1.0; }
++      if ( total_adj < 0.0 ) { total_adj = 0.0; }
++
++      controls.set_throttle( FGControls::ALL_ENGINES, total_adj );
++    }
++
++     /*
++    if (APData->Mode == 2) // Glide slope hold
++    {
++      double RelSlope;
++      double RelElevator;
++              
++      // First, calculate Relative slope and normalize it
++      RelSlope = NormalizeDegrees( APData->TargetSlope - get_pitch());
++      
++      // Now calculate the elevator offset from current angle
++      if ( abs(RelSlope) > APData->SlopeSmooth )
++      {
++          if ( RelSlope < 0 )         //  set RelElevator to max in the correct direction
++              RelElevator = -APData->MaxElevator;
++          else
++              RelElevator = APData->MaxElevator;
++      }
++              
++      else
++          RelElevator = LinearExtrapolate(RelSlope,-APData->SlopeSmooth,-APData->MaxElevator,APData->SlopeSmooth,APData->MaxElevator);
++              
++      // set the elevator
++      fgElevMove(RelElevator);
++              
++    }
++    */
++      
++    // Ok, we are done
++    return 0;
++
++}
++
++/*
++void fgAPSetMode( int mode)
++{
++    //Remove the following line when the calling funcitons start passing in the data pointer
++    fgAPDataPtr APData;
++       
++    APData = APDataGlobal;
++    // end section
++       
++    fgPrintf( FG_COCKPIT, FG_INFO, "APSetMode : %d\n", mode );
++       
++    APData->Mode = mode;  // set the new mode
++}
++*/
++
++void fgAPToggleHeading( void )
++{
++    // Remove at a later date
++    fgAPDataPtr APData;
++
++    APData = APDataGlobal;
++    // end section
++
++    if ( APData->heading_hold ) {
++      // turn off heading hold
++      APData->heading_hold = false;
++    } else {
++      // turn on heading hold, lock at current heading
++      APData->heading_hold = true;
++      APData->TargetHeading = fgAPget_heading();
++    }
++
++    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetHeading: (" 
++          << APData->heading_hold << ") " << APData->TargetHeading );
++}
++               
++
++void fgAPToggleAltitude( void )
++{
++    // Remove at a later date
++    fgAPDataPtr APData;
++
++    APData = APDataGlobal;
++    // end section
++
++    if ( APData->altitude_hold ) {
++      // turn off altitude hold
++      APData->altitude_hold = false;
++    } else {
++      // turn on altitude hold, lock at current altitude
++      APData->altitude_hold = true;
++      APData->terrain_follow = false;
++      APData->TargetAltitude = fgAPget_altitude();
++      APData->alt_error_accum = 0.0;
++      // alt_error_queue.erase( alt_error_queue.begin(), 
++      //                        alt_error_queue.end() );
++    }
++
++    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAltitude: (" 
++          << APData->altitude_hold << ") " << APData->TargetAltitude );
++}
++               
++
++void fgAPToggleAutoThrottle ( void )
++{
++    // Remove at a later date
++    fgAPDataPtr APData;
++
++    APData = APDataGlobal;
++    // end section
++
++    if ( APData->auto_throttle ) {
++      // turn off altitude hold
++      APData->auto_throttle = false;
++    } else {
++      // turn on terrain follow, lock at current agl
++      APData->auto_throttle = true;
++      APData->TargetSpeed = get_speed();
++      APData->speed_error_accum = 0.0;
++    }
++
++    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAutoThrottle: (" 
++          << APData->auto_throttle << ") " << APData->TargetSpeed );
++}
++
++void fgAPToggleTerrainFollow( void )
++{
++    // Remove at a later date
++    fgAPDataPtr APData;
++
++    APData = APDataGlobal;
++    // end section
++
++    if ( APData->terrain_follow ) {
++      // turn off altitude hold
++      APData->terrain_follow = false;
++    } else {
++      // turn on terrain follow, lock at current agl
++      APData->terrain_follow = true;
++      APData->altitude_hold = false;
++      APData->TargetAGL = fgAPget_agl();
++      APData->alt_error_accum = 0.0;
++    }
++
++    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetTerrainFollow: ("
++          << APData->terrain_follow << ") " << APData->TargetAGL );
++}
++
++double LinearExtrapolate( double x,double x1,double y1,double x2,double y2)
++{
++    // This procedure extrapolates the y value for the x posistion on a line defined by x1,y1; x2,y2
++    //assert(x1 != x2); // Divide by zero error.  Cold abort for now
++    
++    double m, b, y;           // the constants to find in y=mx+b
++      
++    m=(y2-y1)/(x2-x1);        // calculate the m
++      
++    b= y1- m * x1;            // calculate the b
++      
++    y = m * x + b;            // the final calculation
++      
++    return (y);
++      
++};
++
++double NormalizeDegrees(double Input)
++{
++    // normalize the input to the range (-180,180]
++    // Input should not be greater than -360 to 360.  Current rules send the output to an undefined state.
++    if (Input > 180)
++      Input -= 360;
++    if (Input <= -180)
++      Input += 360;
++    
++    return (Input);
++};
++
++
++// $Log$
++// Revision 1.15  1999/02/12 23:22:35  curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.14  1999/02/12 22:17:14  curt
++// Changes contributed by Norman Vine to allow adjustment of the autopilot
++// while it is activated.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..18235c73520cfe585fbb589dfb97d6b55d2a5a6d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,92 @@@
++// autopilot.hxx -- autopilot defines and prototypes (very alpha)
++//
++// Written by Jeff Goeke-Smith, started April 1998.
++//
++// Copyright (C) 1998 Jeff Goeke-Smith  - jgoeke@voyager.net
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++                       
++                       
++#ifndef _AUTOPILOT_HXX
++#define _AUTOPILOT_HXX
++                       
++
++#include <Aircraft/aircraft.hxx>
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++                       
++                       
++// Structures
++typedef struct {
++    bool heading_hold;   // the current state of the heading hold
++    bool altitude_hold;  // the current state of the altitude hold
++    bool terrain_follow; // the current state of the terrain follower
++    bool auto_throttle;  // the current state of the auto throttle
++
++    double TargetHeading;     // the heading the AP should steer to.
++    double TargetAltitude;    // altitude to hold
++    double TargetAGL;         // the terrain separation
++    double TargetClimbRate;   // climb rate to shoot for
++    double TargetSpeed;       // speed to shoot for
++    double alt_error_accum;   // altitude error accumulator
++    double speed_error_accum; // speed error accumulator
++
++    double TargetSlope; // the glide slope hold value
++    
++    double MaxRoll ; // the max the plane can roll for the turn
++    double RollOut;  // when the plane should roll out
++    // measured from Heading
++    double MaxAileron; // how far to move the aleroin from center
++    double RollOutSmooth; // deg to use for smoothing Aileron Control
++    double MaxElevator; // the maximum elevator allowed
++    double SlopeSmooth; // smoothing angle for elevator
++    
++} fgAPData, *fgAPDataPtr ;
++              
++
++// Defines
++#define AP_CURRENT_HEADING -1
++
++
++// prototypes
++void fgAPInit( fgAIRCRAFT *current_aircraft );
++int fgAPRun( void );
++void fgAPToggleHeading( void );
++void fgAPToggleAltitude( void );
++void fgAPToggleTerrainFollow( void );
++void fgAPToggleAutoThrottle( void );
++
++bool fgAPAltitudeEnabled( void );
++bool fgAPHeadingEnabled( void );
++bool fgAPAutoThrottleEnabled( void );
++void fgAPAltitudeAdjust( double inc );
++void fgAPHeadingAdjust( double inc );
++void fgAPAutoThrottleAdjust( double inc );
++
++
++#endif // _AUTOPILOT_HXX
++
++
++// $Log$
++// Revision 1.9  1999/02/12 23:22:36  curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.8  1999/02/12 22:17:15  curt
++// Changes contributed by Norman Vine to allow adjustment of the autopilot
++// while it is activated.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b04b3501f5efd94313942eb7439457bc82f5a2f5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++# The "checkoutlist" file is used to support additional version controlled
++# administrative files in $CVSROOT/CVSROOT, such as template files.
++#
++# The first entry on a line is a filename which will be checked out from
++# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
++# The remainder of the line is an error message to use if the file cannot
++# be checked out.
++#
++# File format:
++#
++#     [<whitespace>]<filename><whitespace><error message><end-of-line>
++#
++# comment lines begin with '#'
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b19e7b7a63e8e90cdb49c43f02035646c4a76e0a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++# The "commitinfo" file is used to control pre-commit checks.
++# The filter on the right is invoked with the repository and a list 
++# of files to check.  A non-zero exit of the filter program will 
++# cause the commit to be aborted.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being committed to, relative
++# to the $CVSROOT.  For the first match that is found, then the remainder
++# of the line is the name of the filter to run.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5047bf1c5a053ce46a0adc97b1698ea27cb51d99
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++# This file describes wrappers and other binary files to CVS.
++#
++# Wrappers are the concept where directories of files are to be
++# treated as a single file.  The intended use is to wrap up a wrapper
++# into a single tar such that the tar archive can be treated as a
++# single binary file in CVS.
++#
++# To solve the problem effectively, it was also necessary to be able to
++# prevent rcsmerge from merging these files.
++#
++# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
++#
++#  wildcard   [option value][option value]...
++#
++#  where option is one of
++#  -f         from cvs filter         value: path to filter
++#  -t         to cvs filter           value: path to filter
++#  -m         update methodology      value: MERGE or COPY
++#
++#  and value is a single-quote delimited value.
++#
++# For example:
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d78886c1522b6eae3470c13da218c3d8e197cf71
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++# The "editinfo" file is used to allow verification of logging
++# information.  It works best when a template (as specified in the
++# rcsinfo file) is provided for the logging procedure.  Given a
++# template with locations for, a bug-id number, a list of people who
++# reviewed the code before it can be checked in, and an external
++# process to catalog the differences that were code reviewed, the
++# following test can be applied to the code:
++#
++#   Making sure that the entered bug-id number is correct.
++#   Validating that the code that was reviewed is indeed the code being
++#       checked in (using the bug-id number or a seperate review
++#       number to identify this particular code set.).
++#
++# If any of the above test failed, then the commit would be aborted.
++#
++# Actions such as mailing a copy of the report to each reviewer are
++# better handled by an entry in the loginfo file.
++#
++# One thing that should be noted is the the ALL keyword is not
++# supported.  There can be only one entry that matches a given
++# repository.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..226e93771063fe5504eb2c55dd3bd629dd6c6e59
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++# The "loginfo" file is used to control where "cvs commit" log information is
++# sent.  The first entry on a line is a regular expression which is tested
++# against the directory that the change is being made to, relative to the
++# $CVSROOT.  For the first match that is found, the remainder of the line is a
++# filter program that should expect log information on its standard input
++#
++# If the repository name does not match any of the regular expressions in the
++# first field of this file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
++#
++# The filter program may use one and only one "%s" modifier (ala printf).  If
++# such a "%s" is specified in the filter program, a brief title is included
++# (as one argument, enclosed in single quotes) showing the relative directory
++# name and listing the modified file names.
++#
++# For example:
++#DEFAULT              (echo ""; who am i; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cb9e9efc94b342879a5fff24b425473fc11edd01
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,26 @@@
++# Three different line formats are valid:
++#     key     -a    aliases...
++#     key [options] directory
++#     key [options] directory files...
++#
++# Where "options" are composed of:
++#     -i prog         Run "prog" on "cvs commit" from top-level of module.
++#     -o prog         Run "prog" on "cvs checkout" of module.
++#     -e prog         Run "prog" on "cvs export" of module.
++#     -t prog         Run "prog" on "cvs rtag" of module.
++#     -u prog         Run "prog" on "cvs update" of module.
++#     -d dir          Place module in directory "dir" instead of module name.
++#     -l              Top-level directory only -- do not recurse.
++#
++# NOTE:  If you change any of the "Run" options above, you'll have to
++# release and re-checkout any working directories of these modules.
++#
++# And "directory" is a path to a directory relative to $CVSROOT.
++#
++# The "-a" option specifies an alias.  An alias is interpreted as if
++# everything on the right of the "-a" had been typed on the command line.
++#
++# You can encode a module within a module by using the special '&'
++# character to interpose another module into the current module.  This
++# can be useful for creating a module that consists of many directories
++# spread out over the entire source repository.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..34f0bc288808e56e499d0852a9bfc9a3214b02d9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++# The "notify" file controls where notifications from watches set by
++# "cvs watch add" or "cvs edit" are sent.  The first entry on a line is
++# a regular expression which is tested against the directory that the
++# change is being made to, relative to the $CVSROOT.  If it matches,
++# then the remainder of the line is a filter program that should contain
++# one occurrence of %s for the user to notify, and information on its
++# standard input.
++#
++# "ALL" or "DEFAULT" can be used in place of the regular expression.
++#
++# For example:
++#ALL mail %s -s "CVS notification"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..49e59f4d0df9b432c5b99c0b806378a77c9cd870
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++# The "rcsinfo" file is used to control templates with which the editor
++# is invoked on commit and import.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being made to, relative to the
++# $CVSROOT.  For the first match that is found, then the remainder of the
++# line is the name of the file that contains the template.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..274a46dd5b61069f1cea62395178b09aa3120248
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++# The "taginfo" file is used to control pre-tag checks.
++# The filter on the right is invoked with the following arguments:
++#
++# $1 -- tagname
++# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
++# $3 -- repository
++# $4->  file revision [file revision ...]
++#
++# A non-zero exit of the filter program will cause the tag to be aborted.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being committed to, relative
++# to the $CVSROOT.  For the first match that is found, then the remainder
++# of the line is the name of the filter to run.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4f16955e6eefd186e72379f4cca27ed5e6e2dd63
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,10 @@@
++noinst_LIBRARIES = libCockpit.a
++
++libCockpit_a_SOURCES = \
++      cockpit.cxx cockpit.hxx \
++      hud.cxx hud.hxx \
++      hud_card.cxx hud_dnst.cxx hud_guag.cxx hud_inst.cxx \
++      hud_labl.cxx hud_ladr.cxx hud_scal.cxx hud_tbi.cxx \
++      panel.cxx panel.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2b451c3112d8a8fe2ec16ac2d5e0b5e18299ffdf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,414 @@@
++//*************************************************************************
++// cockpit.cxx -- routines to draw a cockpit (initial draft)
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H          
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Include/general.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++#include "cockpit.hxx"
++#include "panel.hxx"
++
++
++// This is a structure that contains all data related to
++// cockpit/panel/hud system
++
++static pCockpit ac_cockpit;
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++double get_latitude( void )
++{
++    return((double)((int)( current_aircraft.fdm_state->get_Latitude() 
++                         * RAD_TO_DEG)) );
++}
++
++double get_lat_min( void )
++{
++    double a, d;
++
++    a = current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;      
++    if (a < 0.0) {
++      a = -a;
++    }
++    d = (double) ( (int) a);
++    return( (a - d) * 60.0);
++}
++
++double get_longitude( void )
++{
++    return( (double)((int) (current_aircraft.fdm_state->get_Longitude()
++                          * RAD_TO_DEG)) );
++}
++
++double get_long_min( void )
++{
++    double  a, d;
++    
++    a = current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;     
++    if (a < 0.0) {
++      a = -a;
++    }
++    d = (double) ( (int) a);
++    return( (a - d) * 60.0);
++}
++
++double get_throttleval( void )
++{
++    return controls.get_throttle( 0 );     // Hack limiting to one engine
++}
++
++double get_aileronval( void )
++{
++    return controls.get_aileron();
++}
++
++double get_elevatorval( void )
++{
++    return controls.get_elevator();
++}
++
++double get_elev_trimval( void )
++{
++    return controls.get_elevator_trim();
++}
++
++double get_rudderval( void )
++{
++    return controls.get_rudder();
++}
++
++double get_speed( void )
++{
++    return( current_aircraft.fdm_state->get_V_equiv_kts() );
++}
++
++double get_aoa( void )
++{
++    return( current_aircraft.fdm_state->get_Alpha() * RAD_TO_DEG );
++}
++
++double get_roll( void )
++{
++    return( current_aircraft.fdm_state->get_Phi() );
++}
++
++double get_pitch( void )
++{
++    return( current_aircraft.fdm_state->get_Theta() );
++}
++
++double get_heading( void )
++{
++    return( current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG );
++}
++
++double get_altitude( void )
++{
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      return current_aircraft.fdm_state->get_Altitude();
++    } else {
++      return current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
++    }
++}
++
++double get_agl( void )
++{
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      return current_aircraft.fdm_state->get_Altitude()
++          - scenery.cur_elev * METER_TO_FEET;
++    } else {
++      return current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
++          - scenery.cur_elev;
++    }
++}
++
++double get_sideslip( void )
++{
++    return( current_aircraft.fdm_state->get_Beta() );
++}
++
++double get_frame_rate( void )
++{
++    return (double) general.get_frame_rate();
++}
++
++double get_fov( void )
++{
++    return (current_options.get_fov()); 
++}
++
++double get_vfc_ratio( void )
++{
++    return current_view.get_vfc_ratio();
++}
++
++double get_vfc_tris_drawn   ( void )
++{
++    return current_view.get_tris_rendered();
++}
++
++double get_climb_rate( void )
++{
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
++    } else {
++      return current_aircraft.fdm_state->get_Climb_Rate()
++          * FEET_TO_METER * 60.0;
++    }
++}
++
++
++bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
++{
++    FG_LOG( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem" );
++
++    //        cockpit->code = 1;      /* It will be aircraft dependent */
++    //        cockpit->status = 0;
++
++    // If aircraft has HUD specified we will get the specs from its def
++    // file. For now we will depend upon hard coding in hud?
++    
++    // We must insure that the existing instrument link is purged.
++    // This is done by deleting the links in the list.
++    
++    // HI_Head is now a null pointer so we can generate a new list from the
++    // current aircraft.
++
++    fgHUDInit( cur_aircraft );
++    ac_cockpit = new fg_Cockpit();
++    
++    if ( current_options.get_panel_status() ) {
++        new FGPanel;
++    }
++
++    FG_LOG( FG_COCKPIT, FG_INFO,
++          "  Code " << ac_cockpit->code() << " Status " 
++          << ac_cockpit->status() );
++    
++    return true;
++}
++
++
++void fgCockpitUpdate( void ) {
++    FG_LOG( FG_COCKPIT, FG_DEBUG,
++          "Cockpit: code " << ac_cockpit->code() << " status " 
++          << ac_cockpit->status() );
++
++    if ( current_options.get_hud_status() ) {
++      // This will check the global hud linked list pointer.
++      // If these is anything to draw it will.
++      fgUpdateHUD();
++    }
++
++    if ( current_options.get_panel_status() && 
++       (fabs( current_view.get_view_offset() ) < 0.2) )
++    {
++      xglViewport( 0, 0, 
++                   current_view.get_winWidth(), 
++                   current_view.get_winHeight() );
++      FGPanel::OurPanel->Update();
++    }
++}
++
++
++// $Log$
++// Revision 1.31  1999/03/08 21:56:08  curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.30  1999/02/05 21:28:57  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.29  1999/01/08 19:27:34  curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.28  1999/01/07 20:24:17  curt
++// Update fgGENERAL to FGGeneral.
++//
++// Revision 1.27  1998/12/18 23:35:09  curt
++// Converted to a simpler frame rate counting method.
++//
++// Revision 1.26  1998/12/09 18:50:19  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.25  1998/12/05 15:54:07  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.24  1998/12/03 01:16:00  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.23  1998/11/09 23:38:50  curt
++// Panel updates from Friedemann.
++//
++// Revision 1.22  1998/11/06 21:17:45  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.21  1998/11/02 23:04:02  curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.20  1998/10/25 14:08:40  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.19  1998/10/17 01:33:56  curt
++// C++ ifying ...
++//
++// Revision 1.18  1998/10/16 23:27:23  curt
++// C++-ifying.
++//
++// Revision 1.17  1998/09/29 14:56:30  curt
++// c++-ified comments.
++//
++// Revision 1.16  1998/09/29 02:01:06  curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.15  1998/08/28 18:14:39  curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.14  1998/08/24 20:05:15  curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.13  1998/08/22 01:19:27  curt
++// Omit panel code because it's texture loading overruns array bounds.
++//
++// Revision 1.12  1998/07/13 21:28:00  curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.11  1998/07/13 21:00:45  curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10  1998/07/08 14:41:08  curt
++// Renamed polar3d.h to polar3d.hxx
++//
++// Revision 1.9  1998/06/27 16:47:53  curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++//
++// Revision 1.8  1998/05/17 16:58:12  curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.7  1998/05/16 13:04:13  curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.6  1998/05/13 18:27:53  curt
++// Added an fov to hud display.
++//
++// Revision 1.5  1998/05/11 18:13:10  curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.4  1998/05/03 00:46:45  curt
++// polar.h -> polar3d.h
++//
++// Revision 1.3  1998/04/30 12:36:02  curt
++// C++-ifying a couple source files.
++//
++// Revision 1.2  1998/04/25 22:06:26  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.1  1998/04/24 00:45:54  curt
++// C++-ifing the code a bit.
++//
++// Revision 1.13  1998/04/18 04:14:01  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.12  1998/04/14 02:23:09  curt
++// Code reorganizations.  Added a Lib/ directory for more general libraries.
++//
++// Revision 1.11  1998/03/14 00:32:13  curt
++// Changed a printf() to a fgPrintf().
++//
++// Revision 1.10  1998/02/07 15:29:33  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9  1998/02/03 23:20:14  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.8  1998/01/31 00:43:03  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.7  1998/01/27 00:47:51  curt
++// Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.6  1998/01/19 19:27:01  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5  1998/01/19 18:40:19  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4  1997/12/30 20:47:34  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.3  1997/12/15 23:54:33  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2  1997/12/10 22:37:38  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1  1997/08/29 18:03:20  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5f6ac4b8ba7bf035e7c59ca182cc3fe776f4f0a0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,105 @@@
++/**************************************************************************
++ * cockpit.hxx -- cockpit defines and prototypes (initial draft)
++ *
++ * Written by Michele America, started September 1997.
++ *
++ * Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++ 
++
++#ifndef _COCKPIT_HXX
++#define _COCKPIT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include "hud.hxx"
++#include "panel.hxx"
++
++// Class fg_Cockpit          This class is a holder for the heads up display
++//                          and is initialized with a
++class fg_Cockpit  {
++  private:
++    int  Code;
++    int  Status;
++
++  public:
++    fg_Cockpit   () : Code(1), Status(0) {};
++    int   code  ( void ) { return Code; }
++    int   status( void ) { return Status; }
++};
++
++
++typedef fg_Cockpit * pCockpit;
++
++bool fgCockpitInit( fgAIRCRAFT *cur_aircraft );
++void fgCockpitUpdate( void );
++
++
++#endif /* _COCKPIT_HXX */
++
++
++/* $Log$
++/* Revision 1.4  1998/07/13 21:00:46  curt
++/* Integrated Charlies latest HUD updates.
++/* Wrote access functions for current fgOPTIONS.
++/*
++ * Revision 1.3  1998/06/27 16:47:54  curt
++ * Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++ * first pass at an isntrument panel.
++ *
++ * Revision 1.2  1998/05/11 18:13:10  curt
++ * Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++ *
++ * Revision 1.1  1998/04/24 00:45:55  curt
++ * C++-ifing the code a bit.
++ *
++ * Revision 1.8  1998/04/22 13:26:19  curt
++ * C++ - ifing the code a bit.
++ *
++ * Revision 1.7  1998/04/21 17:02:34  curt
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.6  1998/02/07 15:29:33  curt
++ * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++ * <chotchkiss@namg.us.anritsu.com>
++ *
++ * Revision 1.5  1998/01/22 02:59:29  curt
++ * Changed #ifdef FILE_H to #ifdef _FILE_H
++ *
++ * Revision 1.4  1998/01/19 19:27:01  curt
++ * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++ * This should simplify things tremendously.
++ *
++ * Revision 1.3  1998/01/19 18:40:19  curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.2  1997/12/10 22:37:39  curt
++ * Prepended "fg" on the name of all global structures that didn't have it yet.
++ * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++ *
++ * Revision 1.1  1997/08/29 18:03:21  curt
++ * Initial revision.
++ *
++ */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eb59d8c24f5052294ea0c8f4eef65723e993ef5a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1008 @@@
++// hud.cxx -- hud defines and prototypes
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997  Michele F. America  - micheleamerica@geocities.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#ifdef __BORLANDC__
++#  define exception c_exception
++#endif
++#include <math.h>
++
++#include <GL/glut.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++#if defined ( __sun__ ) || defined ( __sgi )
++extern "C" {
++  extern void *memmove(void *, const void *, size_t);
++}
++#endif
++
++#include "hud.hxx"
++
++
++static char units[5];
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++HudContainerType HUD_deque;
++
++class locRECT {
++  public:
++    RECT rect;
++
++    locRECT( UINT left, UINT top, UINT right, UINT bottom);
++    RECT get_rect(void) { return rect;}
++};
++
++locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
++{
++  rect.left   =  left;
++  rect.top    =  top;
++  rect.right  =  right;
++  rect.bottom =  bottom;
++
++}
++// #define DEBUG
++
++void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
++{
++  glBegin(GL_LINES);
++  glVertex2f(x1, y1);
++  glVertex2f(x2, y2);
++  glEnd();
++}
++
++void drawOneLine( RECT &rect)
++{
++  glBegin(GL_LINES);
++  glVertex2f(rect.left, rect.top);
++  glVertex2f(rect.right, rect.bottom);
++  glEnd();
++}
++
++//
++// The following code deals with painting the "instrument" on the display
++//
++   /* textString - Bitmap font string */
++
++void textString( int x, int y, char *msg, void *font ){
++      glRasterPos2f(x, y);
++      while (*msg) {
++              glutBitmapCharacter(font, *msg);
++              msg++;
++    }
++}
++
++/* strokeString - Stroke font string */
++
++void strokeString(int x, int y, char *msg, void *font, float theta)
++{
++int xx;
++int yy;
++
++      glPushMatrix();
++  glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
++  xx = (int)(x * cos(theta) + y * sin( theta ));
++  yy = (int)(y * cos(theta) - x * sin( theta ));
++      glTranslatef( xx, yy, 0);
++      glScalef(.1, .1, 0.0);
++      while (*msg) {
++              glutStrokeCharacter(font, *msg);
++              msg++;
++      }
++      glPopMatrix();
++}
++
++//========================= End of Class Implementations===================
++// fgHUDInit
++//
++// Constructs a HUD object and then adds in instruments. At the present
++// the instruments are hard coded into the routine. Ultimately these need
++// to be defined by the aircraft's instrumentation records so that the
++// display for a Piper Cub doesn't show the speed range of a North American
++// mustange and the engine readouts of a B36!
++//
++
++#define INSTRDEFS 21
++
++int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
++{
++  instr_item *HIptr;
++  int index;
++
++  FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
++
++  HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());  // empty the HUD deque
++
++//  hud->code = 1;
++//  hud->status = 0;
++
++  // For now lets just hardcode the hud here.
++  // In the future, hud information has to come from the same place
++  // aircraft information came from.
++
++//  fgHUDSetTimeMode( hud, NIGHT );
++//  fgHUDSetBrightness( hud, BRT_LIGHT );
++
++  index = 0;
++
++  do {
++    switch ( index ) {
++      case 0:     // TBI
++        HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
++        break;
++
++      case 1:     // Artificial Horizon
++        HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
++        break;
++
++      case 2:    // KIAS
++        HIptr = (instr_item *) new hud_card( 130,
++                                             170,
++                                              28,
++                                             200,
++                                             get_speed,
++                                             HUDS_LEFT | HUDS_VERT,
++                                             200.0, 0.0,
++                                             1.0,
++                                             10,  5,
++                                             0,
++                                             0,
++                                             50.0,
++                                             true);
++
++        break;
++
++      case 3:    // Radio Altimeter
++        HIptr = (instr_item *) new hud_card( 420,
++                                             195,
++                                              25,
++                                             150,
++                                             get_agl,
++                                             HUDS_LEFT | HUDS_VERT,
++                                             1000, 0,
++                                             1.0,
++                                             25,    5,
++                                             0,
++                                             0,
++                                             200.0,
++                                             true);
++        break;
++
++      case 4:    // GYRO COMPASS
++        HIptr = (instr_item *) new hud_card( 200,
++                                             375,
++                                             200,
++                                              28,
++                                             get_heading,
++                                             HUDS_TOP,
++                                             360, 0,
++                                               1.0,
++                                               5,   1,
++                                             360,
++                                               0,
++                                              25,
++                                             true);
++        break;
++
++      case 5:    // AMSL
++        HIptr = (instr_item *) new hud_card( 460,
++                                             170,
++                                              35,
++                                             200,
++                                             get_altitude,
++                                             HUDS_RIGHT | HUDS_VERT,
++                                             15000, -500,
++                                             1.0,
++                                             100,  25,
++                                             0,
++                                             0,
++                                             250,
++                                             true);
++        break;
++
++      case 6:
++        HIptr = (instr_item *) new  guage_instr( 250,            // x
++                                                 350,            // y
++                                                 100,            // width
++                                                  20,            // height
++                                                 get_aileronval, // data source
++                                                 HUDS_BOTTOM | HUDS_NOTEXT,
++                                                 100.0,
++                                                 +1.0,
++                                                 -1.0);
++        break;
++
++      case 7:
++        HIptr = (instr_item *) new  guage_instr( 170,             // x
++                                                 225,             // y
++                                                  20,             // width
++                                                 100,             // height
++                                                 get_elevatorval, // data source
++                                                 HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
++                                                -100.0,           // Scale data
++                                                  +1.0,           // Data Range
++                                                  -1.0);
++        break;
++
++      case 8:
++        HIptr = (instr_item *) new  guage_instr( 250,             // x
++                                                 200,             // y
++                                                 100,             // width
++                                                  20,             // height
++                                                 get_rudderval,   // data source
++                                                 HUDS_TOP | HUDS_NOTEXT,
++                                                 100.0,
++                                                 +1.0,
++                                                 -1.0);
++        break;
++
++      case 9:
++        HIptr = (instr_item *) new  guage_instr( 100,             // x
++                                                 190,
++                                                  20,
++                                                 160,             // height
++                                                 get_throttleval, // data source
++                                                 HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
++                                                 100.0,
++                                                   1.0,
++                                                   0.0);
++        break;
++
++      case 10:    // Digital KIAS
++        HIptr = (instr_item *) new instr_label ( 110,
++                                                 150,
++                                                  40,
++                                                  30,
++                                                 get_speed,
++                                                 "%5.0f",
++                                                 NULL,
++                                                 " Kts",
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 11:    // Digital Rate of Climb
++        HIptr = (instr_item *) new instr_label ( 110,
++                                                 135,
++                                                  40,
++                                                  10,
++                                                 get_climb_rate,
++                                                 "%5.0f",
++                                                 " Climb",
++                                                 NULL,
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 12:    // Roll indication diagnostic
++        HIptr = (instr_item *) new instr_label ( 110,
++                                                 120,
++                                                  40,
++                                                  10,
++                                                 get_roll,
++                                                 "%5.2f",
++                                                 " Roll",
++                                                 " Deg",
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 13:    // Angle of attack diagnostic
++        HIptr = (instr_item *) new instr_label ( 440,
++                                                 150,
++                                                  60,
++                                                  10,
++                                                 get_aoa,
++                                                 "      %5.2f",
++                                                 "AOA",
++                                                 " Deg",
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 14:
++        HIptr = (instr_item *) new instr_label ( 440,
++                                                 135,
++                                                  60,
++                                                  10,
++                                                 get_heading,
++                                                 " %5.1f",
++                                                 "Heading ",
++                                                 " Deg",
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 15:
++        HIptr = (instr_item *) new instr_label ( 440,
++                                                 120,
++                                                  60,
++                                                  10,
++                                                 get_sideslip,
++                                                 "%5.2f",
++                                                 "Sideslip ",
++                                                 NULL,
++                                                 1.0,
++                                                 HUDS_TOP,
++                                                 RIGHT_JUST,
++                                                 SMALL,
++                                                 0,
++                                                 TRUE );
++        break;
++
++      case 16:
++        HIptr = (instr_item *) new instr_label( 440,
++                                                100,
++                                                 60,
++                                                 10,
++                                                get_throttleval,
++                                                "%5.2f",
++                                                "Throttle ",
++                                                NULL,
++                                                 1.0,
++                                                HUDS_TOP,
++                                                RIGHT_JUST,
++                                                SMALL,
++                                                0,
++                                                TRUE );
++        break;
++
++      case 17:
++        HIptr = (instr_item *) new instr_label( 440,
++                                                 85,
++                                                 60,
++                                                 10,
++                                                get_elevatorval,
++                                                "%5.2f",
++                                                "Elevator ",
++                                                NULL,
++                                                 1.0,
++                                                HUDS_TOP,
++                                                RIGHT_JUST,
++                                                SMALL,
++                                                0,
++                                                TRUE );
++        break;
++
++      case 18:
++        HIptr = (instr_item *) new instr_label( 440,
++                                                 60,
++                                                 60,
++                                                 10,
++                                                get_aileronval,
++                                                "%5.2f",
++                                                "Aileron  ",
++                                                NULL,
++                                                 1.0,
++                                                HUDS_TOP,
++                                                RIGHT_JUST,
++                                                SMALL,
++                                                0,
++                                                TRUE );
++        break;
++
++
++      case 19:
++        HIptr = (instr_item *) new instr_label( 10,
++                                                10,
++                                                60,
++                                                10,
++                                                 get_frame_rate,
++                                                "%.0f",
++                                                "Frame rate = ",
++                                                NULL,
++                                                 1.0,
++                                                HUDS_TOP,
++                                                RIGHT_JUST,
++                                                SMALL,
++                                                0,
++                                                TRUE );
++        break;
++
++      case 20:
++        switch( current_options.get_tris_or_culled() ) {
++        case 0:
++            HIptr = (instr_item *) new instr_label( 10,
++                                                    25,
++                                                    90,
++                                                    10,
++                                                    get_vfc_tris_drawn,
++                                                    "%.0f",
++                                                    "Tris Rendered = ",
++                                                    NULL,
++                                                    1.0,
++                                                    HUDS_TOP,
++                                                    RIGHT_JUST,
++                                                    SMALL,
++                                                    0,
++                                                    TRUE );
++            break;
++        case 1:
++            HIptr = (instr_item *) new instr_label( 10,
++                                                    25,
++                                                    90,
++                                                    10,
++                                                    get_vfc_ratio,
++                                                    "%.2f",
++                                                    "VFC Ratio = ",
++                                                    NULL,
++                                                    1.0,
++                                                    HUDS_TOP,
++                                                    RIGHT_JUST,
++                                                    SMALL,
++                                                    0,
++                                                    TRUE );
++            break;
++        }
++        break;
++
++      case 21:
++        HIptr = (instr_item *) new instr_label( 10,
++                                                40,
++                                                90,
++                                                10,
++                                                get_fov,
++                                                "%.1f",
++                                                "FOV = ",
++                                                NULL,
++                                              1.0,
++                                                HUDS_TOP,
++                                                RIGHT_JUST,
++                                                SMALL,
++                                                0,
++                                                TRUE );
++        break;
++
++      default:
++        HIptr = 0;;
++      }
++    if( HIptr ) {                   // Anything to install?
++      HUD_deque.insert( HUD_deque.begin(), HIptr);
++      }
++    index++;
++    }
++  while( HIptr );
++
++  return 0;  // For now. Later we may use this for an error code.
++}
++
++int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
++{
++    int index;
++
++    FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
++
++    HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
++
++    //  hud->code = 1;
++    //  hud->status = 0;
++
++    // For now lets just hardcode the hud here.
++    // In the future, hud information has to come from the same place
++    // aircraft information came from.
++
++    //  fgHUDSetTimeMode( hud, NIGHT );
++    //  fgHUDSetBrightness( hud, BRT_LIGHT );
++
++    //  index = 0;
++    index = 19;  
++
++    instr_item* p;
++
++    p = new instr_label( 10, 10, 60, 10,
++                       get_frame_rate,
++                       "%.0f",
++                       "Frame rate = ",
++                       NULL,
++                       1.0,
++                       HUDS_TOP,
++                       RIGHT_JUST,
++                       SMALL,
++                       0,
++                       TRUE );
++    HUD_deque.push_front( p );
++
++    if ( current_options.get_tris_or_culled() == 0 )
++      p = new instr_label( 10, 25, 90, 10,
++                           get_vfc_tris_drawn,
++                           "%.0f",
++                           "Tris Rendered = ",
++                           NULL,
++                           1.0,
++                           HUDS_TOP,
++                           RIGHT_JUST,
++                           SMALL,
++                           0,
++                           TRUE );
++    else
++      p = new instr_label( 10, 25, 90, 10,
++                           get_vfc_ratio,
++                           "%.2f",
++                           "VFC Ratio = ",
++                           NULL,
++                           1.0,
++                           HUDS_TOP,
++                           RIGHT_JUST,
++                           SMALL,
++                           0,
++                           TRUE );
++    HUD_deque.push_front( p );
++
++    p = new instr_label( 10, 40, 90, 10,
++                       get_fov,
++                       "%.1f",
++                       "FOV = ",
++                       NULL,
++                       1.0,
++                       HUDS_TOP,
++                       RIGHT_JUST,
++                       SMALL,
++                       0,
++                       TRUE );
++    HUD_deque.push_front( p );
++
++    const int x_pos = 480;
++    p = new instr_label( x_pos, 40, 40, 30,
++                       get_speed,
++                       "%5.0f",
++                       "Airspeed ",
++                       " Kts",
++                       1.0,
++                       HUDS_TOP,
++                       RIGHT_JUST,
++                       SMALL,
++                       0,
++                       TRUE );
++    HUD_deque.push_front( p );
++
++    if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++      strcpy(units, " ft");
++    } else {
++      strcpy(units, " m");
++    }
++    p = new instr_label( x_pos, 25, 40, 10,
++                       get_altitude,
++                       "%5.0f",
++                       "Altitude ",
++                       units,
++                       1.0,
++                       HUDS_TOP,
++                       RIGHT_JUST,
++                       SMALL,
++                       0,
++                       TRUE );
++    HUD_deque.push_front( p );
++
++    p = new instr_label( x_pos, 10, 60, 10,
++                       get_heading,
++                       "%5.1f",
++                       "Heading  ",
++                       " Deg",
++                       1.0,
++                       HUDS_TOP,
++                       RIGHT_JUST,
++                       SMALL,
++                       0,
++                       TRUE );
++    HUD_deque.push_front( p );
++
++    return 0;  // For now. Later we may use this for an error code.
++}
++
++int global_day_night_switch = DAY;
++
++void HUD_brightkey( bool incr_bright )
++{
++instr_item *pHUDInstr = HUD_deque[0];
++int brightness        = pHUDInstr->get_brightness();
++
++  if( current_options.get_hud_status() ) {
++    if( incr_bright ) {
++      switch (brightness) {
++        case BRT_LIGHT:
++            current_options.set_hud_status(0);
++          break;
++
++        case BRT_MEDIUM:
++          brightness = BRT_LIGHT;
++          break;
++
++        case BRT_DARK:
++          brightness = BRT_MEDIUM;
++          break;
++
++        case BRT_BLACK:
++          brightness = BRT_DARK;
++          break;
++
++        default:
++          brightness = BRT_BLACK;
++        }
++      }
++    else {
++      switch (brightness) {
++        case BRT_LIGHT:
++          brightness = BRT_MEDIUM;
++          break;
++
++        case BRT_MEDIUM:
++          brightness = BRT_DARK;
++          break;
++
++        case BRT_DARK:
++          brightness = BRT_BLACK;
++          break;
++
++        case BRT_BLACK:
++        default:
++            current_options.set_hud_status(0);
++        }
++      }
++    }
++  else {
++    current_options.set_hud_status(1);
++    if( incr_bright ) {
++      if( DAY == global_day_night_switch ) {
++        brightness = BRT_BLACK;
++        }
++      else {
++        brightness = BRT_DARK;
++        global_day_night_switch = DAY;
++        }
++      }
++    else {
++      if( NIGHT == global_day_night_switch ) {
++        brightness = BRT_DARK;
++        }
++      else {
++        brightness = BRT_MEDIUM;
++        global_day_night_switch = NIGHT;
++        }
++      }
++    }
++  pHUDInstr->SetBrightness( brightness );
++}
++
++// fgUpdateHUD
++//
++// Performs a once around the list of calls to instruments installed in
++// the HUD object with requests for redraw. Kinda. It will when this is
++// all C++.
++//
++void fgUpdateHUD( void ) {
++  int i;
++  int brightness;
++//  int day_night_sw = current_aircraft.controls->day_night_switch;
++  int day_night_sw = global_day_night_switch;
++  int hud_displays = HUD_deque.size();
++  instr_item *pHUDInstr;
++
++  if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
++    return;
++    }
++
++  pHUDInstr = HUD_deque[0];
++  brightness = pHUDInstr->get_brightness();
++//  brightness = HUD_deque.at(0)->get_brightness();
++
++  glMatrixMode(GL_PROJECTION);
++  glPushMatrix();
++
++  glLoadIdentity();
++  gluOrtho2D(0, 640, 0, 480);
++  glMatrixMode(GL_MODELVIEW);
++  glPushMatrix();
++  glLoadIdentity();
++
++  glColor3f(1.0, 1.0, 1.0);
++  glIndexi(7);
++
++  glDisable(GL_DEPTH_TEST);
++  glDisable(GL_LIGHTING);
++
++  glLineWidth(1);
++
++  HudIterator current = HUD_deque.begin();
++  HudIterator last = HUD_deque.end();
++
++  for ( ; current != last; ++current ) {
++    pHUDInstr = *current;
++
++    // for( i = hud_displays; i; --i) { // Draw everything
++    // if( HUD_deque.at(i)->enabled()) {
++    // pHUDInstr = HUD_deque[i - 1];
++    if( pHUDInstr->enabled()) {
++                                   // We should to respond to a dial instead
++                                   // or as well to the of time of day. Of
++                                   // course, we have no dial!
++      if( day_night_sw == DAY) {
++        switch (brightness) {
++          case BRT_LIGHT:
++            glColor3f (0.1, 0.9, 0.1);
++            break;
++
++          case BRT_MEDIUM:
++            glColor3f (0.1, 0.7, 0.0);
++            break;
++
++          case BRT_DARK:
++            glColor3f (0.0, 0.5, 0.0);
++            break;
++
++          case BRT_BLACK:
++            glColor3f( 0.0, 0.0, 0.0);
++            break;
++
++          default:;
++            }
++          }
++        else {
++          if( day_night_sw == NIGHT) {
++            switch (brightness) {
++              case BRT_LIGHT:
++                glColor3f (0.9, 0.1, 0.1);
++                break;
++
++              case BRT_MEDIUM:
++                glColor3f (0.7, 0.0, 0.1);
++                break;
++
++              case BRT_DARK:
++              default:
++                glColor3f (0.5, 0.0, 0.0);
++              }
++            }
++          else {     // Just in case default
++            glColor3f (0.1, 0.9, 0.1);
++            }
++          }
++    //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
++    //            hud->code, hud->status );
++      pHUDInstr->draw();
++//      HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
++                              // No broken displays honored just now.
++      }
++    }
++
++  glEnable(GL_DEPTH_TEST);
++  glEnable(GL_LIGHTING);
++  glMatrixMode(GL_PROJECTION);
++  glPopMatrix();
++  glMatrixMode(GL_MODELVIEW);
++  glPopMatrix();
++}
++
++// $Log$
++// Revision 1.32  1999/03/02 01:02:37  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.31  1999/02/02 20:13:31  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.30  1999/01/27 04:47:52  curt
++// Make lower end of altitude = -500 so the altimeter is guaged below zero (such
++// as in death valley.)
++//
++// Revision 1.29  1998/12/18 23:35:10  curt
++// Converted to a simpler frame rate counting method.
++//
++// Revision 1.28  1998/11/23 21:48:59  curt
++// Borland portability tweaks.
++//
++// Revision 1.27  1998/11/06 21:17:47  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.26  1998/11/03 12:33:11  curt
++// Display ft or m in mini-hud next to altitude.
++//
++// Revision 1.25  1998/10/17 01:33:57  curt
++// C++ ifying ...
++//
++// Revision 1.24  1998/10/16 23:27:25  curt
++// C++-ifying.
++//
++// Revision 1.23  1998/10/16 00:53:00  curt
++// Mods to display a bit more info when mini-hud is active.
++//
++// Revision 1.22  1998/09/29 14:56:31  curt
++// c++-ified comments.
++//
++// Revision 1.21  1998/09/29 02:01:07  curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.20  1998/08/24 20:05:16  curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.19  1998/07/30 23:44:05  curt
++// Tweaks for sgi building.
++//
++// Revision 1.18  1998/07/20 12:47:55  curt
++// Replace the hud rendering for loop (which linearly searches the the hud
++// list to find the entry with the proper position) with a simple linear
++// traversal using an "iterator."
++//
++// Revision 1.17  1998/07/13 21:28:02  curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.16  1998/07/13 21:00:47  curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15  1998/07/08 14:41:08  curt
++// Renamed polar3d.h to polar3d.hxx
++//
++// Revision 1.14  1998/07/06 21:31:20  curt
++// Removed an extraneous ^M.
++//
++// Revision 1.13  1998/07/03 13:16:28  curt
++// Added Charlie Hotchkiss's HUD updates and improvementes.
++//
++// Revision 1.11  1998/06/05 18:17:10  curt
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.10  1998/05/17 16:58:12  curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.9  1998/05/16 13:04:14  curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.8  1998/05/13 18:27:54  curt
++// Added an fov to hud display.
++//
++// Revision 1.7  1998/05/11 18:13:11  curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.22  1998/04/18 04:14:02  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.21  1998/04/03 21:55:28  curt
++// Converting to Gnu autoconf system.
++// Tweaks to hud.c
++//
++// Revision 1.20  1998/03/09 22:48:40  curt
++// Minor "formatting" tweaks.
++//
++// Revision 1.19  1998/02/23 20:18:28  curt
++// Incorporated Michele America's hud changes.
++//
++// Revision 1.18  1998/02/21 14:53:10  curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.17  1998/02/20 00:16:21  curt
++// Thursday's tweaks.
++//
++// Revision 1.16  1998/02/19 13:05:49  curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.15  1998/02/16 13:38:39  curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.14  1998/02/12 21:59:41  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12  1998/02/09 15:07:48  curt
++// Minor tweaks.
++//
++// Revision 1.11  1998/02/07 15:29:34  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10  1998/02/03 23:20:14  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.9  1998/01/31 00:43:04  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.8  1998/01/27 00:47:51  curt
++// Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7  1998/01/19 18:40:20  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6  1997/12/15 23:54:34  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.5  1997/12/10 22:37:39  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.4  1997/09/23 00:29:32  curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.3  1997/09/05 14:17:26  curt
++// More tweaking with stars.
++//
++// Revision 1.2  1997/09/04 02:17:30  curt
++// Shufflin' stuff.
++//
++// Revision 1.1  1997/08/29 18:03:22  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dfee1928d7cb37d2e17e544152e55c3038d49284
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,639 @@@
++// hud.hxx -- hud defines and prototypes (initial draft)
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _HUD_HXX
++#define _HUD_HXX
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <stdlib.h>
++#include <string.h>
++
++#ifdef HAVE_VALUES_H
++#  include <values.h>  // for MAXINT
++#endif
++
++#include <deque>        // STL double ended queue
++
++#include <fg_typedefs.h>
++#include <fg_constants.h>
++#include <Aircraft/aircraft.hxx>
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++
++FG_USING_STD(deque);
++
++#ifndef WIN32
++  typedef struct {
++      int x, y;
++  } POINT;
++ 
++  typedef struct {
++      int top, bottom, left, right;
++  } RECT;
++#endif
++
++// View mode definitions
++
++enum VIEW_MODES{ HUD_VIEW, PANEL_VIEW, CHASE_VIEW, TOWER_VIEW };
++
++// DAY, NIGHT and brightness levels need to be visible where dialogs and
++// controls can be used to set intensity and appropriate color. This will
++// be moved.
++// Hud general constants
++#define DAY                1
++#define NIGHT              2
++#define BRT_BLACK          3
++#define BRT_DARK           4
++#define BRT_MEDIUM         5
++#define BRT_LIGHT          6
++#define SIZE_SMALL         7
++#define SIZE_LARGE         8
++
++// Label constants
++#define SMALL              1
++#define LARGE              2
++
++#define BLINK              3
++#define NOBLINK            4
++
++enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ;
++
++// Ladder constants
++#define NONE               1
++#define UPPER_LEFT         2
++#define UPPER_CENTER       3
++#define UPPER_RIGHT        4
++#define CENTER_RIGHT       5
++#define LOWER_RIGHT        6
++#define LOWER_CENTER       7
++#define LOWER_LEFT         8
++#define CENTER_LEFT        9
++#define SOLID_LINES       10
++#define DASHED_LINES      11
++#define DASHED_NEG_LINES  12
++
++
++#define HORIZON_FIXED 1
++#define HORIZON_MOVING        2
++#define LABEL_COUNTER 1
++#define LABEL_WARNING 2
++
++#define HUDS_AUTOTICKS           0x0001
++#define HUDS_VERT                0x0002
++#define HUDS_HORZ                0x0000
++#define HUDS_TOP                 0x0004
++#define HUDS_BOTTOM              0x0008
++#define HUDS_LEFT     HUDS_TOP
++#define HUDS_RIGHT    HUDS_BOTTOM
++#define HUDS_BOTH     (HUDS_LEFT | HUDS_RIGHT)
++#define HUDS_NOTICKS             0x0010
++#define HUDS_ARITHTIC            0x0020
++#define HUDS_DECITICS            0x0040
++#define HUDS_NOTEXT              0x0080
++
++// Ladder orientaion
++// #define HUD_VERTICAL        1
++// #define HUD_HORIZONTAL             2
++// #define HUD_FREEFLOAT              3
++
++// Ladder orientation modes
++// #define HUD_LEFT                   1
++// #define HUD_RIGHT          2
++// #define HUD_TOP            1
++// #define HUD_BOTTOM         2
++// #define HUD_V_LEFT                 1
++// #define HUD_V_RIGHT                2
++// #define HUD_H_TOP                  1
++// #define HUD_H_BOTTOM               2
++
++
++// Ladder sub-types
++// #define HUD_LIM                            1
++// #define HUD_NOLIM                  2
++// #define HUD_CIRC                   3
++
++// #define HUD_INSTR_LADDER   1
++// #define HUD_INSTR_CLADDER  2
++// #define HUD_INSTR_HORIZON  3
++// #define HUD_INSTR_LABEL            4
++
++extern double get_throttleval ( void );
++extern double get_aileronval  ( void );
++extern double get_elevatorval ( void );
++extern double get_elev_trimval( void );
++extern double get_rudderval   ( void );
++extern double get_speed       ( void );
++extern double get_aoa         ( void );
++extern double get_roll        ( void );
++extern double get_pitch       ( void );
++extern double get_heading     ( void );
++extern double get_altitude    ( void );
++extern double get_agl         ( void );
++extern double get_sideslip    ( void );
++extern double get_frame_rate  ( void );
++extern double get_latitude    ( void );
++extern double get_lat_min     ( void );
++extern double get_longitude   ( void );
++extern double get_long_min    ( void );
++extern double get_fov         ( void );
++extern double get_vfc_ratio   ( void );
++extern double get_vfc_tris_drawn   ( void );
++extern double get_climb_rate  ( void );
++
++enum  hudinstype{ HUDno_instr,
++              HUDscale,
++              HUDlabel,
++              HUDladder,
++              HUDcirc_ladder,
++              HUDhorizon,
++              HUDguage,
++              HUDdual_inst,
++              HUDmoving_scale,
++              HUDtbi
++              };
++
++typedef struct gltagRGBTRIPLE { // rgbt
++    GLfloat Blue;
++    GLfloat Green;
++    GLfloat Red;
++} glRGBTRIPLE;
++
++class instr_item {  // An Abstract Base Class (ABC)
++  private:
++    static UINT        instances;     // More than 64K instruments? Nah!
++    static int         brightness;
++    static glRGBTRIPLE color;
++
++    UINT               handle;
++    RECT               scrn_pos;      // Framing - affects scale dimensions
++                                    // and orientation. Vert vs Horz, etc.
++    DBLFNPTR           load_value_fn;
++    double             disp_factor;   // Multiply by to get numbers shown on scale.
++    UINT               opts;
++    bool               is_enabled;
++    bool               broken;
++    UINT               scr_span;      // Working values for draw;
++    POINT              mid_span;      //
++
++  public:
++    instr_item( int            x,
++                int            y,
++                UINT           height,
++                UINT           width,
++                DBLFNPTR       data_source,
++                double         data_scaling,
++                UINT           options,
++                bool           working      = true);
++
++    instr_item( const instr_item & image );
++
++    instr_item & operator = ( const instr_item & rhs );
++    virtual ~instr_item ();
++
++    int          get_brightness  ( void ) { return brightness;}
++    RECT         get_location    ( void ) { return scrn_pos;  }
++    bool         is_broken       ( void ) { return broken;    }
++    bool         enabled         ( void ) { return is_enabled;}
++    bool         data_available  ( void ) { return !!load_value_fn; }
++    double       get_value       ( void ) { return load_value_fn(); }
++    double       data_scaling    ( void ) { return disp_factor; }
++    UINT         get_span        ( void ) { return scr_span;  }
++    POINT        get_centroid    ( void ) { return mid_span;  }
++    UINT         get_options     ( void ) { return opts;      }
++
++    virtual void display_enable( bool working ) { is_enabled = !! working;}
++
++
++    virtual void update( void );
++    virtual void break_display ( bool bad );
++    virtual void SetBrightness( int illumination_level ); // fgHUDSetBright...
++    void         SetPosition  ( int x, int y, UINT width, UINT height );
++    UINT    get_Handle( void );
++    virtual void draw( void ) = 0;   // Required method in derived classes
++};
++
++typedef deque< instr_item * > HudContainerType;
++typedef HudContainerType::iterator HudIterator;
++
++typedef instr_item *HIptr;
++extern HudContainerType HUD_deque;
++
++// instr_item           This class has no other purpose than to maintain
++//                      a linked list of instrument and derived class
++// object pointers.
++
++
++class instr_label : public instr_item {
++  private:
++    const char *pformat;
++    const char *pre_str;
++    const char *post_str;
++    fgLabelJust justify;
++    int         fontSize;
++    int         blink;
++
++  public:
++    instr_label( int          x,
++                 int          y,
++                 UINT         width,
++                 UINT         height,
++                 DBLFNPTR     data_source,
++                 const char  *label_format,
++                 const char  *pre_label_string  = 0,
++                 const char  *post_label_string = 0,
++                 double       scale_data        = 1.0,
++                 UINT         options           = HUDS_TOP,
++                 fgLabelJust  justification     = CENTER_JUST,
++                 int          font_size         = SMALL,
++                 int          blinking          = NOBLINK,
++                 bool         working           = true);
++
++    ~instr_label();
++
++    instr_label( const instr_label & image);
++    instr_label & operator = (const instr_label & rhs );
++    virtual void draw( void );       // Required method in base class
++};
++
++typedef instr_label * pInstlabel;
++
++//
++// instr_scale           This class is an abstract base class for both moving
++//                       scale and moving needle (fixed scale) indicators. It
++// does not draw itself, but is not instanciable.
++//
++
++class instr_scale : public instr_item {
++  private:
++    double range_shown;   // Width Units.
++    double Maximum_value; //                ceiling.
++    double Minimum_value; // Representation floor.
++    double scale_factor;  // factor => screen units/range values.
++    UINT   Maj_div;       // major division marker units
++    UINT   Min_div;       // minor division marker units
++    UINT   Modulo;        // Roll over point
++    int    signif_digits; // digits to show to the right.
++
++  public:
++    instr_scale( int          x,
++                 int          y,
++                 UINT         width,
++                 UINT         height,
++                 DBLFNPTR     load_fn,
++                 UINT         options,
++                 double       show_range,
++                 double       max_value    = 100.0,
++                 double       min_value    =   0.0,
++                 double       disp_scaling =   1.0,
++                 UINT         major_divs   =    10,
++                 UINT         minor_divs   =     5,
++                 UINT         rollover     =     0,
++                 int          dp_showing   =     2,
++                 bool         working      =  true);
++
++    virtual ~instr_scale();
++    instr_scale( const instr_scale & image);
++    instr_scale & operator = (const instr_scale & rhs);
++
++    virtual void draw   ( void ) {}; // No-op here. Defined in derived classes.
++    UINT   div_min      ( void ) { return Min_div;}
++    UINT   div_max      ( void ) { return Maj_div;}
++    double min_val      ( void ) { return Minimum_value;}
++    double max_val      ( void ) { return Maximum_value;}
++    UINT   modulo       ( void ) { return Modulo; }
++    double factor       ( void ) { return scale_factor;}
++    double range_to_show( void ) { return range_shown;}
++};
++
++// hud_card_               This class displays the indicated quantity on
++//                         a scale that moves past the pointer. It may be
++// horizontal or vertical, read above(left) or below(right) of the base
++// line.
++
++class hud_card : public instr_scale {
++  private:
++    double val_span;
++    double half_width_units;
++
++  public:
++    hud_card( int      x,
++              int      y,
++              UINT     width,
++              UINT     height,
++              DBLFNPTR load_fn,
++              UINT     options,
++              double   maxValue      = 100.0,
++              double   minValue      =   0.0,
++              double   disp_scaling  =   1.0,
++              UINT     major_divs    =  10,
++              UINT     minor_divs    =   5,
++              UINT     modulator     = 100,
++              int      dp_showing    =   2,
++              double   value_span    = 100.0,
++              bool     working       = true);
++
++    ~hud_card();
++    hud_card( const hud_card & image);
++    hud_card & operator = (const hud_card & rhs );
++//    virtual void display_enable( bool setting );
++    virtual void draw( void );       // Required method in base class
++};
++
++typedef hud_card * pCardScale;
++
++class guage_instr : public instr_scale {
++  private:
++
++  public:
++    guage_instr( int       x,
++                 int       y,
++                 UINT      width,
++                 UINT      height,
++                 DBLFNPTR  load_fn,
++                 UINT      options,
++                 double    disp_scaling = 1.0,
++                 double    maxValue     = 100,
++                 double    minValue     =   0,
++                 UINT      major_divs   =  50,
++                 UINT      minor_divs   =   0,
++                 int       dp_showing   =   2,
++                 UINT      modulus      =   0,
++                 bool      working      = true);
++
++    ~guage_instr();
++    guage_instr( const guage_instr & image);
++    guage_instr & operator = (const guage_instr & rhs );
++    virtual void draw( void );       // Required method in base class
++};
++
++typedef guage_instr * pGuageInst;
++//
++// dual_instr_item         This class was created to form the base class
++//                         for both panel and HUD Turn Bank Indicators.
++
++class dual_instr_item : public instr_item {
++  private:
++    DBLFNPTR alt_data_source;
++
++  public:
++    dual_instr_item ( int       x,
++                      int       y,
++                      UINT      width,
++                      UINT      height,
++                      DBLFNPTR  chn1_source,
++                      DBLFNPTR  chn2_source,
++                      bool      working     = true,
++                      UINT      options  = HUDS_TOP);
++
++    virtual ~dual_instr_item() {};
++    dual_instr_item( const dual_instr_item & image);
++    dual_instr_item & operator = (const dual_instr_item & rhs );
++
++    double current_ch1( void ) { return alt_data_source();}
++    double current_ch2( void ) { return get_value();}
++    virtual void draw ( void ) { }
++};
++
++class fgTBI_instr : public dual_instr_item {
++  private:
++    UINT BankLimit;
++    UINT SlewLimit;
++    UINT scr_hole;
++
++  public:
++    fgTBI_instr( int       x,
++                 int       y,
++                 UINT      width,
++                 UINT      height,
++                 DBLFNPTR  chn1_source  = get_roll,
++                 DBLFNPTR  chn2_source  = get_sideslip,
++                 double    maxBankAngle = 45.0,
++                 double    maxSlipAngle =  5.0,
++                 UINT      gap_width    =  5.0,
++                 bool      working      =  true);
++
++    fgTBI_instr( const fgTBI_instr & image);
++    fgTBI_instr & operator = (const fgTBI_instr & rhs );
++
++    ~fgTBI_instr();
++
++    UINT bank_limit( void ) { return BankLimit;}
++    UINT slew_limit( void ) { return SlewLimit;}
++
++    virtual void draw( void );       // Required method in base class
++};
++
++typedef fgTBI_instr * pTBI;
++
++class HudLadder : public dual_instr_item {
++  private:
++    UINT   width_units;
++    int    div_units;
++    UINT   minor_div;
++    UINT   label_pos;
++    UINT   scr_hole;
++    double vmax;
++    double vmin;
++    double factor;
++
++  public:
++    HudLadder( int       x,
++               int       y,
++               UINT      width,
++               UINT      height,
++               DBLFNPTR  ptch_source    = get_roll,
++               DBLFNPTR  roll_source    = get_pitch,
++               double    span_units     = 45.0,
++               double    division_units = 10.0,
++               double    minor_division =  0.0,
++               UINT      screen_hole    =   70,
++               UINT      lbl_pos        =    0,
++               bool      working        = true );
++
++    ~HudLadder();
++
++    HudLadder( const HudLadder & image );
++    HudLadder & operator = ( const HudLadder & rhs );
++    virtual void draw( void );
++};
++
++
++//using namespace std;
++//deque <instr_item>  * Hdeque_ptr;
++
++extern void HUD_brightkey( bool incr_bright );
++extern int  fgHUDInit( fgAIRCRAFT * /* current_aircraft */ );
++extern int  fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ );
++extern void fgUpdateHUD( void );
++
++extern void drawOneLine ( UINT x1, UINT y1, UINT x2, UINT y2);
++extern void drawOneLine ( RECT &rect);
++extern void textString  ( int x,
++                          int y,
++                          char *msg,
++                          void *font = GLUT_BITMAP_8_BY_13);
++extern void strokeString( int x,
++                          int y,
++                          char *msg,
++                          void *font = GLUT_STROKE_ROMAN,
++                          float theta = 0);
++/*
++bool AddHUDInstrument( instr_item *pBlackBox );
++void DrawHUD ( void );
++bool DamageInstrument( INSTR_HANDLE unit );
++bool RepairInstrument( INSTR_HANDLE unit );
++
++
++void fgUpdateHUD ( Hptr hud );
++void fgUpdateHUD2( Hptr hud ); // Future use?
++void fgHUDSetTimeMode( Hptr hud, int time_of_day );
++*/
++
++#endif // _HUD_H
++
++// $Log$
++// Revision 1.19  1999/03/02 01:02:38  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.18  1999/02/26 22:08:45  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.17  1999/02/01 21:33:28  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.16  1998/10/17 01:33:59  curt
++// C++ ifying ...
++//
++// Revision 1.15  1998/10/16 23:27:27  curt
++// C++-ifying.
++//
++// Revision 1.14  1998/09/29 14:56:33  curt
++// c++-ified comments.
++//
++// Revision 1.13  1998/09/29 02:01:09  curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.12  1998/08/24 20:05:17  curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.11  1998/07/24 21:36:55  curt
++// Ran dos2unix to get rid of extraneous ^M's.  Tweaked parameter in
++// ImageGetRawData() to match usage.
++//
++// Revision 1.10  1998/07/13 21:28:02  curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.9  1998/07/13 21:00:48  curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.8  1998/07/03 13:16:29  curt
++// Added Charlie Hotchkiss's HUD updates and improvementes.
++//
++// Revision 1.6  1998/06/03 00:43:28  curt
++// No .h when including stl stuff.
++//
++// Revision 1.5  1998/05/17 16:58:13  curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.4  1998/05/16 13:04:15  curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.3  1998/05/13 18:27:55  curt
++// Added an fov to hud display.
++//
++// Revision 1.2  1998/05/11 18:13:12  curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.15  1998/02/23 19:07:57  curt
++// Incorporated Durk's Astro/ tweaks.  Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.14  1998/02/21 14:53:14  curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.13  1998/02/20 00:16:22  curt
++// Thursday's tweaks.
++//
++// Revision 1.12  1998/02/19 13:05:52  curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.11  1998/02/16 13:38:42  curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.11  1998/02/16 13:38:42  curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.10  1998/02/12 21:59:42  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.8  1998/02/07 15:29:35  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.7  1998/02/03 23:20:15  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.6  1998/01/22 02:59:30  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.5  1998/01/19 19:27:01  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4  1998/01/19 18:40:21  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3  1997/12/30 16:36:41  curt
++// Merged in Durk's changes ...
++//
++// Revision 1.2  1997/12/10 22:37:40  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1  1997/08/29 18:03:22  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a43f343f5d305b6fcb8259b272d49de78ea465b7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,386 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//========== Top of hud_card class member definitions =============
++
++hud_card ::
++hud_card( int       x,
++          int       y,
++          UINT      width,
++          UINT      height,
++          DBLFNPTR  data_source,
++          UINT      options,
++          double    max_value,
++          double    min_value,
++          double    disp_scaling,
++          UINT      major_divs,
++          UINT      minor_divs,
++          UINT      modulus,
++          int       dp_showing,
++          double    value_span,
++          bool      working) :
++                instr_scale( x,y,width,height,
++                             data_source, options,
++                             value_span,
++                             max_value, min_value, disp_scaling,
++                             major_divs, minor_divs, modulus,
++                             working),
++                val_span   ( value_span)
++{
++  half_width_units = range_to_show() / 2.0;
++}
++
++hud_card ::
++~hud_card() { }
++
++hud_card ::
++hud_card( const hud_card & image):
++      instr_scale( (const instr_scale & ) image),
++      val_span( image.val_span),
++      half_width_units (image.half_width_units)
++{
++}
++
++hud_card & hud_card ::
++operator = (const hud_card & rhs )
++{
++  if( !( this == &rhs)){
++    instr_scale::operator = (rhs);
++    val_span = rhs.val_span;
++    half_width_units = rhs.half_width_units;
++    }
++  return *this;
++}
++
++void hud_card ::
++draw( void ) //  (HUD_scale * pscale )
++{
++  double vmin, vmax;
++  int marker_xs;
++  int marker_xe;
++  int marker_ys;
++  int marker_ye;
++  /* register */ int i;
++  char TextScale[80];
++  bool condition;
++  int disp_val = 0;
++  POINT mid_scr    = get_centroid();
++  double cur_value = get_value();
++  RECT   scrn_rect = get_location();
++  UINT options     = get_options();
++
++  vmin = cur_value - half_width_units; // width units == needle travel
++  vmax = cur_value + half_width_units; // or picture unit span.
++    // Draw the basic markings for the scale...
++
++  if( options & HUDS_VERT ) { // Vertical scale
++    drawOneLine( scrn_rect.left,     // Bottom tick bar
++                 scrn_rect.top,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top);
++
++    drawOneLine( scrn_rect.left,    // Top tick bar
++                 scrn_rect.top  + scrn_rect.bottom,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top  + scrn_rect.bottom );
++
++    marker_xs = scrn_rect.left;
++    marker_xe = scrn_rect.left + scrn_rect.right;
++
++    // We do not use else in the following so that combining the two
++    // options produces a "caged" display with double carrots. The
++    // same is done for horizontal card indicators.
++
++    if( options & HUDS_LEFT ) {    // Calculate x marker offset
++      drawOneLine( scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top + scrn_rect.bottom); // Cap right side
++
++      marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
++                                                      // Indicator carrot
++      drawOneLine( marker_xs, mid_scr.y,
++                   marker_xe, mid_scr.y + scrn_rect.right / 6);
++      drawOneLine( marker_xs, mid_scr.y,
++                   marker_xe, mid_scr.y - scrn_rect.right / 6);
++
++      }
++    if( options & HUDS_RIGHT ) {  // We'll default this for now.
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top,
++                   scrn_rect.left,
++                   scrn_rect.top + scrn_rect.bottom);  // Cap left side
++
++      marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
++                                                       // Indicator carrot
++      drawOneLine( scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
++                   marker_xe, mid_scr.y );
++      drawOneLine( scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
++                   marker_xe, mid_scr.y);
++      }
++
++    // At this point marker x_start and x_end values are transposed.
++    // To keep this from confusing things they are now interchanged.
++    if(( options & HUDS_BOTH) == HUDS_BOTH) {
++      marker_ye = marker_xs;
++      marker_xs = marker_xe;
++      marker_xe = marker_ye;
++      }
++
++    // Work through from bottom to top of scale. Calculating where to put
++    // minor and major ticks.
++
++    for( i = (int)vmin; i <= (int)vmax; i++ )      {
++      condition = true;
++      if( !modulo()) {
++        if( i < min_val()) {
++          condition = false;
++          }
++        }
++
++      if( condition ) {  // Show a tick if necessary
++                         // Calculate the location of this tick
++        marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
++
++        // Block calculation artifact from drawing ticks below min coordinate.
++        // Calculation here accounts for text height.
++
++        if(( marker_ys < (scrn_rect.top + 4)) |
++           ( marker_ys > (scrn_rect.top + scrn_rect.bottom - 4))) {
++            // Magic numbers!!!
++          continue;
++          }
++        if( div_min()) {
++          if( (i%div_min()) == 0) {
++            if((( marker_ys - 5) > scrn_rect.top ) &&
++               (( marker_ys + 5) < (scrn_rect.top + scrn_rect.bottom))){
++              if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++                drawOneLine( scrn_rect.left, marker_ys,
++                             marker_xs,      marker_ys );
++                drawOneLine( marker_xe,      marker_ys,
++                             scrn_rect.left + scrn_rect.right,  marker_ys );
++                }
++              else {
++                if( options & HUDS_LEFT ) {
++                  drawOneLine( marker_xs + 4, marker_ys,
++                               marker_xe,     marker_ys );
++                  }
++                else {
++                  drawOneLine( marker_xs,     marker_ys,
++                               marker_xe - 4, marker_ys );
++                  }
++                }
++              }
++            }
++          }
++        if( div_max()) {
++          if( !(i%(int)div_max())){
++            if(modulo()) {
++              if( disp_val < 0) {
++                disp_val += modulo();
++                }
++              else {
++                disp_val = i % modulo();
++                }
++              }
++            else {
++              disp_val = i;
++              }
++            sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
++            if(( (marker_ys - 8 ) > scrn_rect.top ) &&
++               ( (marker_ys + 8) < (scrn_rect.top + scrn_rect.bottom))){
++              if( (options & HUDS_BOTH) == HUDS_BOTH) {
++                drawOneLine( scrn_rect.left, marker_ys,
++                             marker_xs,      marker_ys);
++                drawOneLine( marker_xs,                  marker_ys,
++                             scrn_rect.left + scrn_rect.right,
++                             marker_ys);
++                if( !(options & HUDS_NOTEXT)) {
++                  textString ( marker_xs + 2,  marker_ys,
++                               TextScale,  GLUT_BITMAP_8_BY_13 );
++                  }
++                }
++              else {
++                drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
++                if( !(options & HUDS_NOTEXT)) {
++                  if( options & HUDS_LEFT )              {
++                    textString( marker_xs -  8 * strlen(TextScale) - 2,
++                                marker_ys - 4,
++                                TextScale, GLUT_BITMAP_8_BY_13 );
++                    }
++                  else  {
++                    textString( marker_xe + 3 * strlen(TextScale),
++                                marker_ys - 4,
++                                TextScale, GLUT_BITMAP_8_BY_13 );
++                    }
++                  }
++                }
++              } // Else read oriented right
++            } // End if modulo division by major interval is zero
++          }  // End if major interval divisor non-zero
++        } // End if condition
++      } // End for range of i from vmin to vmax
++    }  // End if VERTICAL SCALE TYPE
++  else {                                // Horizontal scale by default
++    drawOneLine( scrn_rect.left,     // left tick bar
++                 scrn_rect.top,
++                 scrn_rect.left,
++                 scrn_rect.top + scrn_rect.bottom);
++
++    drawOneLine( scrn_rect.left + scrn_rect.right,    // right tick bar
++                 scrn_rect.top,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top  + scrn_rect.bottom );
++
++    marker_ys = scrn_rect.top;                       // Starting point for
++    marker_ye = scrn_rect.top + scrn_rect.bottom;    // tick y location calcs
++
++    if( options & HUDS_TOP ) {
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top);                    // Bottom box line
++
++      marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;   // Tick point adjust
++                                                      // Bottom arrow
++      drawOneLine( mid_scr.x, marker_ye,
++                   mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
++      drawOneLine( mid_scr.x, marker_ye,
++                   mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
++      }
++    if( options & HUDS_BOTTOM) {
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top + scrn_rect.bottom,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top + scrn_rect.bottom);  // Top box line
++                                                       // Tick point adjust
++      marker_ys = scrn_rect.top +
++                  scrn_rect.bottom - scrn_rect.bottom  / 2;
++                                                       // Top arrow
++      drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
++                          scrn_rect.top + scrn_rect.bottom,
++                   mid_scr.x ,
++                          marker_ys );
++      drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
++                          scrn_rect.top + scrn_rect.bottom,
++                   mid_scr.x ,
++                          marker_ys );
++      }
++
++//    if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
++//      marker_xe = marker_ys;
++//      marker_ys = marker_ye;
++//      marker_ye = marker_xe;
++//      }
++
++    // printf("vmin = %d  vmax = %d\n", (int)vmin, (int)vmax);
++    for( i = (int)vmin; i <= (int)vmax; i++ )     {
++      // printf("<*> i = %d\n", i);
++      condition = true;
++      if( !modulo()) {
++        if( i < min_val()) {
++          condition = false;
++          }
++        }
++      // printf("<**> i = %d\n", i);
++      if( condition )        {
++        marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
++        if( div_min()){
++          if( (i%(int)div_min()) == 0 ) {
++            // draw in ticks only if they aren't too close to the edge.
++            if((( marker_xs - 5) > scrn_rect.left ) &&
++               (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
++
++              if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++                drawOneLine( marker_xs, scrn_rect.top,
++                             marker_xs, marker_ys - 4);
++                drawOneLine( marker_xs, marker_ye + 4,
++                             marker_xs, scrn_rect.top + scrn_rect.bottom);
++                }
++              else {
++                if( options & HUDS_TOP) {
++                  drawOneLine( marker_xs, marker_ys,
++                               marker_xs, marker_ye - 4);
++                  }
++                else {
++                  drawOneLine( marker_xs, marker_ys + 4,
++                               marker_xs, marker_ye);
++                  }
++                }
++              }
++            }
++          }
++      // printf("<***> i = %d\n", i);
++        if( div_max()) {
++        // printf("i = %d\n", i);
++          if( (i%(int)div_max())==0 ) {
++            if(modulo()) {
++              if( disp_val < 0) {
++                disp_val += modulo();
++                }
++              else {
++                disp_val = i % modulo();
++                }
++              }
++            else {
++              disp_val = i;
++              }
++          // printf("disp_val = %d\n", disp_val);
++          // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
++            sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
++            // Draw major ticks and text only if far enough from the edge.
++            if(( (marker_xs - 10)> scrn_rect.left ) &&
++               ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
++              if( (options & HUDS_BOTH) == HUDS_BOTH) {
++                drawOneLine( marker_xs, scrn_rect.top,
++                             marker_xs, marker_ys);
++                drawOneLine( marker_xs, marker_ye,
++                             marker_xs, scrn_rect.top + scrn_rect.bottom);
++
++                if( !(options & HUDS_NOTEXT)) {
++                  textString ( marker_xs - 4 * strlen(TextScale),
++                               marker_ys + 4,
++                               TextScale,  GLUT_BITMAP_8_BY_13 );
++                  }
++                }
++              else {
++                drawOneLine( marker_xs, marker_ys,
++                             marker_xs, marker_ye );
++                if( !(options & HUDS_NOTEXT)) {
++                  if( options & HUDS_TOP )              {
++                    textString ( marker_xs - 4 * strlen(TextScale),
++                                 scrn_rect.top + scrn_rect.bottom - 10,
++                                 TextScale, GLUT_BITMAP_8_BY_13 );
++                    }
++                  else  {
++                    textString( marker_xs - 4 * strlen(TextScale),
++                                scrn_rect.top,
++                                TextScale, GLUT_BITMAP_8_BY_13 );
++                    }
++                  }
++                }
++              }
++            }
++        }
++      // printf("<****> i = %d\n", i);
++        }
++      }
++    }
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f66d5706cd006024a41ce05dc23e9393d2dfed19
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,56 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++     
++//============ Top of dual_instr_item class member definitions ============
++
++dual_instr_item ::
++  dual_instr_item ( int          x,
++                    int          y,
++                    UINT         width,
++                    UINT         height,
++                    DBLFNPTR     chn1_source,
++                    DBLFNPTR     chn2_source,
++                    bool         working,
++                    UINT         options ):
++                  instr_item( x, y, width, height,
++                              chn1_source, options, working),
++                  alt_data_source( chn2_source )
++{
++}
++
++dual_instr_item ::
++  dual_instr_item( const dual_instr_item & image) :
++                 instr_item ((instr_item &) image ),
++                 alt_data_source( image.alt_data_source)
++{
++}
++
++dual_instr_item & dual_instr_item ::
++  operator = (const dual_instr_item & rhs )
++{
++  if( !(this == &rhs)) {
++    instr_item::operator = (rhs);
++    alt_data_source = rhs.alt_data_source;
++    }
++  return *this;
++}
++
++// End of hud_dnst.cxx
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d6077e8e30c1c59886878718496416c17da538d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,356 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============== Top of guage_instr class member definitions ==============
++
++guage_instr ::
++    guage_instr( int          x,
++                 int          y,
++                 UINT         width,
++                 UINT         height,
++                 DBLFNPTR     load_fn,
++                 UINT         options,
++                 double       disp_scale,
++                 double       maxValue,
++                 double       minValue,
++                 UINT         major_divs,
++                 UINT         minor_divs,
++                 int          dp_showing,
++                 UINT         modulus,
++                 bool         working) :
++           instr_scale( x, y, width, height,
++                        load_fn, options,
++                        (maxValue - minValue), // Always shows span?
++                        maxValue, minValue,
++                        disp_scale,
++                        major_divs, minor_divs,
++                        modulus, dp_showing,
++                        working)
++{
++}
++
++guage_instr ::
++   ~guage_instr()
++{
++}
++
++guage_instr ::
++    guage_instr( const guage_instr & image):
++       instr_scale( (instr_scale &) image)
++{
++}
++
++guage_instr & guage_instr ::
++    operator = (const guage_instr & rhs )
++{
++  if( !(this == &rhs)) {
++    instr_scale::operator = (rhs);
++    }
++  return *this;
++}
++
++// As implemented, draw only correctly draws a horizontal or vertical
++// scale. It should contain a variation that permits clock type displays.
++// Now is supports "tickless" displays such as control surface indicators.
++// This routine should be worked over before using. Current value would be
++// fetched and not used if not commented out. Clearly that is intollerable.
++
++void guage_instr :: draw (void)
++{
++  int marker_xs, marker_xe;
++  int marker_ys, marker_ye;
++  int text_x, text_y;
++  int i;
++  char TextScale[80];
++  bool condition;
++  int disp_val;
++  double vmin         = min_val();
++  double vmax         = max_val();
++  POINT mid_scr       = get_centroid();
++  double cur_value    = get_value();
++  RECT   scrn_rect    = get_location();
++  UINT options        = get_options();
++
++    // Draw the basic markings for the scale...
++
++  if( options & HUDS_VERT ) { // Vertical scale
++    drawOneLine( scrn_rect.left,     // Bottom tick bar
++                 scrn_rect.top,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top);
++
++    drawOneLine( scrn_rect.left,    // Top tick bar
++                 scrn_rect.top  + scrn_rect.bottom,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top  + scrn_rect.bottom );
++
++    marker_xs = scrn_rect.left;
++    marker_xe = scrn_rect.left + scrn_rect.right;
++
++    if( options & HUDS_LEFT ) {     // Read left, so line down right side
++      drawOneLine( scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top + scrn_rect.bottom);
++
++      marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
++      }
++    if( options & HUDS_RIGHT ) {     // Read  right, so down left sides
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top,
++                   scrn_rect.left,
++                   scrn_rect.top + scrn_rect.bottom);
++      marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
++      }
++
++    // At this point marker x_start and x_end values are transposed.
++    // To keep this from confusing things they are now interchanged.
++    if(( options & HUDS_BOTH) == HUDS_BOTH) {
++      marker_ye = marker_xs;
++      marker_xs = marker_xe;
++      marker_xe = marker_ye;
++      }
++
++    // Work through from bottom to top of scale. Calculating where to put
++    // minor and major ticks.
++
++    if( !(options & HUDS_NOTICKS )) {    // If not no ticks...:)
++                                          // Calculate x marker offsets
++      for( i = (int)vmin; i <= (int)vmax; i++ ) {
++
++        // Calculate the location of this tick
++        marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
++
++        // We compute marker_ys even though we don't know if we will use
++        // either major or minor divisions. Simpler.
++
++        if( div_min()) {                  // Minor tick marks
++          if( (i%div_min()) == 0) {
++            if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++                drawOneLine( scrn_rect.left, marker_ys,
++                             marker_xs - 3, marker_ys );
++                drawOneLine( marker_xe + 3, marker_ys,
++                             scrn_rect.left + scrn_rect.right, marker_ys );
++              }
++            else {
++              if( options & HUDS_LEFT) {
++                drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
++                }
++              else {
++                drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
++               }
++              }
++            }
++          }
++
++          // Now we work on the major divisions. Since these are also labeled
++          // and no labels are drawn otherwise, we label inside this if
++          // statement.
++
++        if( div_max()) {                  // Major tick mark
++          if( (i%div_max()) == 0 )            {
++            if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++
++                drawOneLine( scrn_rect.left, marker_ys,
++                             marker_xs, marker_ys );
++                drawOneLine( marker_xe, marker_ys,
++                             scrn_rect.left + scrn_rect.right, marker_ys );
++              }
++            else {
++              drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
++              }
++
++            if( !(options & HUDS_NOTEXT)) {
++              disp_val = i;
++              sprintf( TextScale, "%d",disp_val  * (int)(data_scaling() +.5));
++
++              if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++                text_x = mid_scr.x -  2 - ((3 * strlen( TextScale ))>>1);
++                }
++              else {
++                if( options & HUDS_LEFT )              {
++                  text_x = marker_xs - 2 - 3 * strlen( TextScale);
++                  }
++                else {
++                  text_x = marker_xe + 10 - strlen( TextScale );
++                  }
++                }
++              // Now we know where to put the text.
++              text_y = marker_ys;
++              textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 );
++              }
++            }
++          }  //
++        }  //
++      }  //
++    // Now that the scale is drawn, we draw in the pointer(s). Since labels
++    // have been drawn, text_x and text_y may be recycled. This is used
++    // with the marker start stops to produce a pointer for each side reading
++
++    text_y = scrn_rect.top + (int)((cur_value - vmin) * factor() + .5);
++//    text_x = marker_xs - scrn_rect.left;
++
++    if( options & HUDS_RIGHT ) {
++      drawOneLine(scrn_rect.left, text_y + 5,
++                  marker_xe,      text_y);
++      drawOneLine(scrn_rect.left, text_y - 5,
++                  marker_xe,      text_y);
++      }
++    if( options & HUDS_LEFT ) {
++      drawOneLine(scrn_rect.left + scrn_rect.right, text_y + 5,
++                  marker_xs,                        text_y);
++      drawOneLine(scrn_rect.left + scrn_rect.right, text_y - 5,
++                  marker_xs,                        text_y);
++      }
++    }  // End if VERTICAL SCALE TYPE
++  else {                                // Horizontal scale by default
++    drawOneLine( scrn_rect.left,     // left tick bar
++                 scrn_rect.top,
++                 scrn_rect.left,
++                 scrn_rect.top + scrn_rect.bottom);
++
++    drawOneLine( scrn_rect.left + scrn_rect.right,    // right tick bar
++                 scrn_rect.top,
++                 scrn_rect.left + scrn_rect.right,
++                 scrn_rect.top  + scrn_rect.bottom );
++
++    marker_ys = scrn_rect.top;                       // Starting point for
++    marker_ye = scrn_rect.top + scrn_rect.bottom;    // tick y location calcs
++    marker_xs = scrn_rect.left + (int)((cur_value - vmin) * factor() + .5);
++
++    if( options & HUDS_TOP ) {
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top);                    // Bottom box line
++
++      marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;   // Tick point adjust
++                                                      // Bottom arrow
++      drawOneLine( marker_xs, marker_ye,
++                   marker_xs - scrn_rect.bottom / 4, scrn_rect.top);
++      drawOneLine( marker_xs, marker_ye,
++                   marker_xs + scrn_rect.bottom / 4, scrn_rect.top);
++      }
++    if( options & HUDS_BOTTOM) {
++      drawOneLine( scrn_rect.left,
++                   scrn_rect.top + scrn_rect.bottom,
++                   scrn_rect.left + scrn_rect.right,
++                   scrn_rect.top + scrn_rect.bottom);  // Top box line
++                                                       // Tick point adjust
++      marker_ys = scrn_rect.top +
++                  scrn_rect.bottom - scrn_rect.bottom  / 2;
++                                                       // Top arrow
++      drawOneLine( marker_xs + scrn_rect.bottom / 4,
++                          scrn_rect.top + scrn_rect.bottom,
++                   marker_xs,
++                          marker_ys );
++      drawOneLine( marker_xs - scrn_rect.bottom / 4,
++                          scrn_rect.top + scrn_rect.bottom,
++                   marker_xs ,
++                          marker_ys );
++      }
++
++    for( i = (int)vmin; i <= (int)vmax; i++ )   {
++      condition = true;
++      if( !modulo()) {
++        if( i < min_val()) {
++          condition = false;
++          }
++        }
++      if( condition )        {
++        marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
++        if( div_min()){
++          if( (i%(int)div_min()) == 0 ) {
++            // draw in ticks only if they aren't too close to the edge.
++            if((( marker_xs + 5) > scrn_rect.left ) ||
++               (( marker_xs - 5 )< (scrn_rect.left + scrn_rect.right))){
++
++              if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++                drawOneLine( marker_xs, scrn_rect.top,
++                             marker_xs, marker_ys - 4);
++                drawOneLine( marker_xs, marker_ye + 4,
++                             marker_xs, scrn_rect.top + scrn_rect.bottom);
++                }
++              else {
++                if( options & HUDS_TOP) {
++                  drawOneLine( marker_xs, marker_ys,
++                               marker_xs, marker_ye - 4);
++                  }
++                else {
++                  drawOneLine( marker_xs, marker_ys + 4,
++                               marker_xs, marker_ye);
++                  }
++                }
++              }
++            }
++          }
++        if( div_max()) {
++          if( (i%(int)div_max())==0 ) {
++            if(modulo()) {
++              if( disp_val < 0) {
++                disp_val += modulo();
++                }
++              else {
++                disp_val = i % modulo();
++                }
++              }
++            else {
++              disp_val = i;
++              }
++            sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
++            // Draw major ticks and text only if far enough from the edge.
++            if(( (marker_xs - 10)> scrn_rect.left ) &&
++               ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
++              if( (options & HUDS_BOTH) == HUDS_BOTH) {
++                drawOneLine( marker_xs, scrn_rect.top,
++                             marker_xs, marker_ys);
++                drawOneLine( marker_xs, marker_ye,
++                             marker_xs, scrn_rect.top + scrn_rect.bottom);
++
++                if( !(options & HUDS_NOTEXT)) {
++                  textString ( marker_xs - 4 * strlen(TextScale),
++                               marker_ys + 4,
++                               TextScale,  GLUT_BITMAP_8_BY_13 );
++                  }
++                }
++              else {
++                drawOneLine( marker_xs, marker_ys,
++                             marker_xs, marker_ye );
++                if( !(options & HUDS_NOTEXT)) {
++                  if( options & HUDS_TOP )              {
++                  textString ( marker_xs - 4 * strlen(TextScale),
++                               scrn_rect.top + scrn_rect.bottom - 10,
++                               TextScale, GLUT_BITMAP_8_BY_13 );
++                    }
++                  else  {
++                    textString( marker_xs - 4 * strlen(TextScale),
++                                scrn_rect.top,
++                                TextScale, GLUT_BITMAP_8_BY_13 );
++                    }            
++                  }
++                }
++              }
++            }
++          }
++        }
++      }
++    }
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5de09845d4474d1ad85fcb9c3152c59ac011f058
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,144 @@@
++// Abstract Base Class instr_item
++//
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++
++UINT instr_item :: instances = 0;  // Initial value of zero
++int  instr_item :: brightness = BRT_MEDIUM;
++glRGBTRIPLE instr_item :: color = {0.1, 0.7, 0.0};
++
++// constructor    ( No default provided )
++instr_item  ::
++   instr_item( int              x,
++               int              y,
++               UINT             width,
++               UINT             height,
++               DBLFNPTR         data_source,
++               double           data_scaling,
++               UINT             options,
++               bool             working) :
++                      handle         ( ++instances  ),
++                      load_value_fn  ( data_source  ),
++                      disp_factor    ( data_scaling ),
++                      opts           ( options      ),
++                      is_enabled     ( working      ),
++                      broken         ( FALSE        )
++{
++  scrn_pos.left   = x;
++  scrn_pos.top    = y;
++  scrn_pos.right  = width;
++  scrn_pos.bottom = height;
++
++         // Set up convenience values for centroid of the box and
++         // the span values according to orientation
++
++  if( opts & HUDS_VERT) { // Vertical style
++         // Insure that the midpoint marker will fall exactly at the
++         // middle of the bar.
++    if( !(scrn_pos.bottom % 2)) {
++      scrn_pos.bottom++;
++      }
++    scr_span = scrn_pos.bottom;
++    }
++  else {
++         // Insure that the midpoint marker will fall exactly at the
++         // middle of the bar.
++    if( !(scrn_pos.right % 2)) {
++      scrn_pos.right++;
++      }
++    scr_span = scrn_pos.right;
++    }
++         // Here we work out the centroid for the corrected box.
++  mid_span.x = scrn_pos.left   + (scrn_pos.right  >> 1);
++  mid_span.y = scrn_pos.top + (scrn_pos.bottom >> 1);
++}
++
++
++// copy constructor
++instr_item  ::
++     instr_item ( const instr_item & image ):
++                         handle       ( ++instances        ),
++                         scrn_pos     ( image.scrn_pos     ),
++                         load_value_fn( image.load_value_fn),
++                         disp_factor  ( image.disp_factor  ),
++                         opts         ( image.opts         ),
++                         is_enabled   ( image.is_enabled   ),
++                         broken       ( image.broken       ),
++                         scr_span     ( image.scr_span     ),
++                         mid_span     ( image.mid_span     )
++{
++}
++
++// assignment operator
++
++instr_item & instr_item :: operator = ( const instr_item & rhs )
++{
++  if( !(this == &rhs )) { // Not an identity assignment
++    scrn_pos      = rhs.scrn_pos;
++    load_value_fn = rhs.load_value_fn;
++    disp_factor   = rhs.disp_factor;
++    opts          = rhs.opts;
++    is_enabled    = rhs.is_enabled;
++    broken        = rhs.broken;
++    }
++  return *this;
++}
++
++// destructor
++
++instr_item :: ~instr_item ()
++{
++  if( instances ) {
++    instances--;
++    }
++}
++
++void instr_item ::
++    update( void )
++{
++}
++
++// break_display       This is emplaced to provide hooks for making
++//                     instruments unreliable. The default behavior is
++// to simply not display, but more sophisticated behavior is available
++// by over riding the function which is virtual in this class.
++
++void instr_item ::
++    break_display ( bool bad )
++{
++  broken = !!bad;
++  is_enabled = FALSE;
++}
++
++void instr_item ::
++    SetBrightness  ( int level  )
++{
++  brightness = level;   // This is all we will do for now. Later the
++                        // brightness levels will be sensitive both to
++                        // the control knob and the outside light levels
++                        // to emulated night vision effects.
++}
++
++UINT instr_item :: get_Handle( void )
++{
++  return handle;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7ef1890164c787904763b05f20dcd9f90240aefa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,144 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++
++//======================= Top of instr_label class =========================
++instr_label ::
++         instr_label( int           x,
++                      int           y,
++                      UINT          width,
++                      UINT          height,
++                      DBLFNPTR      data_source,
++                      const char   *label_format,
++                      const char   *pre_label_string,
++                      const char   *post_label_string,
++                      double        scale_data,
++                      UINT          options,
++                      fgLabelJust   justification,
++                      int           font_size,
++                      int           blinking,
++                      bool          working ):
++                           instr_item( x, y, width, height,
++                                       data_source, scale_data,options, working ),
++                           pformat  ( label_format      ),
++                           pre_str  ( pre_label_string  ),
++                           post_str ( post_label_string ),
++                           justify  ( justification     ),
++                           fontSize ( font_size         ),
++                           blink    ( blinking          )
++{
++}
++
++// I put this in to make it easy to construct a class member using the current
++// C code.
++
++
++instr_label :: ~instr_label()
++{
++}
++
++// Copy constructor
++instr_label :: instr_label( const instr_label & image) :
++                              instr_item((const instr_item &)image),
++                              pformat    ( image.pformat    ),
++                              pre_str  ( image.pre_str  ),
++                              post_str ( image.post_str ),
++                              blink    ( image.blink    )
++{
++}
++
++instr_label & instr_label ::operator = (const instr_label & rhs )
++{
++  if( !(this == &rhs)) {
++    instr_item::operator = (rhs);
++    pformat      = rhs.pformat;
++    fontSize   = rhs.fontSize;
++    blink      = rhs.blink;
++    justify    = rhs.justify;
++    pre_str    = rhs.pre_str;
++    post_str   = rhs.post_str;
++    }
++      return *this;
++}
++
++//
++// draw                    Draws a label anywhere in the HUD
++//
++//
++void instr_label ::
++draw( void )       // Required method in base class
++{
++  char format_buffer[80];
++  char label_buffer[80];
++  int posincr;
++  int lenstr;
++  RECT  scrn_rect = get_location();
++
++  if( pre_str != NULL) {
++    if( post_str != NULL ) {
++      sprintf( format_buffer, "%s%s%s", pre_str, pformat, post_str );
++      }
++    else {
++      sprintf( format_buffer, "%s%s",   pre_str, pformat );
++      }
++    }
++  else {
++    if( post_str != NULL ) {
++      sprintf( format_buffer, "%s%s",   pformat, post_str );
++      }
++    } // else do nothing if both pre and post strings are nulls. Interesting.
++
++  if( data_available() ) {
++    sprintf( label_buffer, format_buffer, get_value() );
++    }
++  else {
++    sprintf( label_buffer, format_buffer );
++    }
++    
++#ifdef DEBUGHUD
++      fgPrintf( FG_COCKPIT, FG_DEBUG,  format_buffer );
++      fgPrintf( FG_COCKPIT, FG_DEBUG,  "\n" );
++      fgPrintf( FG_COCKPIT, FG_DEBUG, label_buffer );
++      fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" );
++#endif
++  lenstr = strlen( label_buffer );
++
++  posincr = 0;   //  default to RIGHT_JUST ... center located calc: -lenstr*8;
++
++  if( justify == CENTER_JUST ) {
++    posincr =  - (lenstr << 2); //  -lenstr*4;
++    }
++  else {
++    if( justify == LEFT_JUST ) {
++      posincr = - (lenstr << 8);  // 0;
++      }
++    }
++
++  if( fontSize == SMALL ) {
++    textString( scrn_rect.left + posincr, scrn_rect.top,
++                label_buffer, GLUT_BITMAP_8_BY_13);
++    }
++  else  {
++    if( fontSize == LARGE ) {
++      textString( scrn_rect.left + posincr, scrn_rect.top,
++                  label_buffer, GLUT_BITMAP_9_BY_15);
++      }
++    }
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..51468b80de5bae67467daf280153e4f149ae3beb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,299 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//====================== Top of HudLadder Class =======================
++HudLadder ::
++  HudLadder(  int       x,
++              int       y,
++              UINT      width,
++              UINT      height,
++              DBLFNPTR  ptch_source,
++              DBLFNPTR  roll_source,
++              double    span_units,
++              double    major_div,
++              double    minor_div,
++              UINT      screen_hole,
++              UINT      lbl_pos,
++              bool      working) :
++               dual_instr_item( x, y, width, height,
++                                ptch_source,
++                                roll_source,
++                                working,
++                                HUDS_RIGHT),
++               width_units    ( span_units   ),
++               div_units      ( major_div < 0? -major_div: major_div ),
++               minor_div      ( minor_div    ),
++               label_pos      ( lbl_pos      ),
++               scr_hole       ( screen_hole  ),
++               vmax           ( span_units/2 ),
++               vmin           ( -vmax        )
++{
++  if( !width_units ) {
++    width_units = 45;
++    }
++  factor = (double)get_span() / (double) width_units;
++}
++
++HudLadder ::
++  ~HudLadder()
++{
++}
++
++HudLadder ::
++  HudLadder( const HudLadder & image ) :
++        dual_instr_item( (dual_instr_item &) image),
++        width_units    ( image.width_units   ),
++        div_units      ( image.div_units     ),
++        label_pos      ( image.label_pos     ),
++        scr_hole       ( image.scr_hole      ),
++        vmax           ( image.vmax ),
++        vmin           ( image.vmin ),
++        factor         ( image.factor        )
++{
++}
++HudLadder & HudLadder ::
++  operator = ( const HudLadder & rhs )
++{
++  if( !(this == &rhs)) {
++    (dual_instr_item &)(*this) = (dual_instr_item &)rhs;
++    width_units  = rhs.width_units;
++    div_units    = rhs.div_units;
++    label_pos    = rhs.label_pos;
++    scr_hole     = rhs.scr_hole;
++    vmax         = rhs.vmax;
++    vmin         = rhs.vmin;
++    factor       = rhs.factor;
++    }
++  return *this;
++}
++
++//
++//    Draws a climb ladder in the center of the HUD
++//
++
++void HudLadder :: draw( void )
++{
++  double roll_value;
++  double pitch_value;
++  int    marker_y;
++  int    x_ini;
++  int    x_end;
++  int    y_ini;
++  int    y_end;
++  int    new_x_ini;
++  int    new_x_end;
++  int    new_y_ini;
++  int    new_y_end;
++  int    i;
++  POINT  centroid   = get_centroid();
++  RECT   box        = get_location();
++  int    scr_min    = box.top;
++  int    half_span  = box.right >> 1;
++  char   TextLadder[80];
++  int    condition;
++  int    label_length;
++  roll_value        = current_ch2();
++  GLfloat sinRoll   = sin( roll_value );
++  GLfloat cosRoll   = cos( roll_value );
++
++  pitch_value       = current_ch1() * RAD_TO_DEG;
++  vmin              = pitch_value - (double)width_units/2.0;
++  vmax              = pitch_value + (double)width_units/2.0;
++
++// Box the target.
++  drawOneLine( centroid.x - 5, centroid.y,     centroid.x,     centroid.y + 5);
++  drawOneLine( centroid.x,     centroid.y + 5, centroid.x + 5, centroid.y);
++  drawOneLine( centroid.x + 5, centroid.y,     centroid.x,     centroid.y - 5);
++  drawOneLine( centroid.x,     centroid.y - 5, centroid.x - 5, centroid.y);
++
++  for( i=(int)vmin; i<=(int)vmax; i++ )  {  // Through integer pitch values...
++    condition = 1;
++    if( condition )      {
++      marker_y = centroid.y + (int)(((double)(i - pitch_value) * factor) + .5);
++      if( div_units ) {
++        if( !(i % div_units ))    {        //  At integral multiple of div
++          sprintf( TextLadder, "%d", i );
++          label_length = strlen( TextLadder );
++          if( scr_hole == 0 )           {
++            if( i ) {
++              x_ini = centroid.x - half_span;
++              }
++            else {                         // Make zero point wider on left
++              x_ini = centroid.x - half_span - 10;
++              }
++            y_ini = marker_y;
++            x_end = centroid.x + half_span;
++            y_end = marker_y;
++            new_x_ini = centroid.x + (int)(
++                       (x_ini - centroid.x) * cosRoll -
++                       (y_ini - centroid.y) * sinRoll);
++            new_y_ini = centroid.y + (int)(             \
++                       (x_ini - centroid.x) * sinRoll + \
++                       (y_ini - centroid.y) * cosRoll);
++            new_x_end = centroid.x + (int)(             \
++                       (x_end - centroid.x) * cosRoll - \
++                       (y_end - centroid.y) * sinRoll);
++            new_y_end = centroid.y + (int)(             \
++                       (x_end - centroid.x) * sinRoll + \
++                       (y_end - centroid.y) * cosRoll);
++
++            if( i >= 0 ) { // Above zero draw solid lines
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              }
++            else         { // Below zero draw dashed lines.
++              glEnable(GL_LINE_STIPPLE);
++              glLineStipple( 1, 0x00FF );
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              glDisable(GL_LINE_STIPPLE);
++              }
++            // Calculate the position of the left text and write it.
++            new_x_ini = centroid.x + (int)(
++                        (x_ini - 8 * label_length- 4 - centroid.x) * cosRoll -
++                        (y_ini - 4 ) * sinRoll);
++            new_y_ini = centroid.y + (int)(
++                        (x_ini - 8 * label_length- 4 - centroid.x) * sinRoll +
++                        (y_ini - 4 - centroid.y) * cosRoll);
++            strokeString( new_x_ini , new_y_ini ,
++                        TextLadder, GLUT_STROKE_ROMAN,
++                        roll_value );
++
++            // Calculate the position of the right text and write it.
++            new_x_end = centroid.x + (int)(                  \
++                       (x_end + 24 - 8 * label_length - centroid.x) * cosRoll - \
++                       (y_end -  4 - centroid.y) * sinRoll);
++            new_y_end = centroid.y + (int)(                  \
++                       (x_end + 24 - 8 * label_length - centroid.x) * sinRoll + \
++                       (y_end -  4 - centroid.y) * cosRoll);
++            strokeString( new_x_end,  new_y_end,
++                          TextLadder, GLUT_STROKE_ROMAN,
++                          roll_value );
++            }
++          else   {  // Draw ladder with space in the middle of the lines
++                    // Start by calculating the points and drawing the
++                    // left side lines.
++            if( i != 0 )  {
++              x_ini = centroid.x - half_span;
++              }
++            else          {
++              x_ini = centroid.x - half_span - 10;
++              }
++            y_ini = marker_y;
++            x_end = centroid.x - half_span + scr_hole/2;
++            y_end = marker_y;
++
++            new_x_end = centroid.x+  (int)(             \
++                        (x_end - centroid.x) * cosRoll -\
++                        (y_end - centroid.y) * sinRoll);
++            new_y_end = centroid.y+ (int)(              \
++                        (x_end - centroid.x) * sinRoll +\
++                        (y_end - centroid.y) * cosRoll);
++            new_x_ini = centroid.x + (int)(              \
++                        (x_ini - centroid.x) * cosRoll -\
++                        (y_ini - centroid.y) * sinRoll);
++            new_y_ini = centroid.y + (int)(             \
++                        (x_ini - centroid.x) * sinRoll +\
++                        (y_ini - centroid.y) * cosRoll);
++
++            if( i >= 0 )
++              {
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              }
++            else  {
++              glEnable(GL_LINE_STIPPLE);
++              glLineStipple( 1, 0x00FF );
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              glDisable(GL_LINE_STIPPLE);
++              }
++            // Now calculate the location of the left side label using
++            // the previously calculated start of the left side line.
++
++            x_ini = x_ini - (label_length + 32 + centroid.x);
++            if( i < 0) {
++              x_ini -= 8;
++              }
++            else {
++              if( i == 0 ) {
++                x_ini += 20;
++                }
++              }
++            y_ini = y_ini - ( 4 + centroid.y);
++
++            new_x_ini = centroid.x + (int)(x_ini * cosRoll - y_ini * sinRoll);
++            new_y_ini = centroid.y + (int)(x_ini * sinRoll + y_ini * cosRoll);
++            strokeString( new_x_ini , new_y_ini ,
++                          TextLadder, GLUT_STROKE_MONO_ROMAN,
++                          roll_value );
++
++            // Now calculate and draw the right side line location
++            x_ini = centroid.x + half_span - scr_hole/2;
++            y_ini = marker_y;
++            if( i != 0 )  {
++              x_end = centroid.x + half_span;
++              }
++            else          {
++              x_end = centroid.x + half_span + 10;
++              }
++            y_end = marker_y;
++
++            new_x_ini = centroid.x + (int)(         \
++                        (x_ini-centroid.x)*cosRoll -\
++                        (y_ini-centroid.y)*sinRoll);
++            new_y_ini = centroid.y + (int)(         \
++                        (x_ini-centroid.x)*sinRoll +\
++                        (y_ini-centroid.y)*cosRoll);
++            new_x_end = centroid.x + (int)(         \
++                        (x_end-centroid.x)*cosRoll -\
++                        (y_end-centroid.y)*sinRoll);
++            new_y_end = centroid.y +  (int)(        \
++                        (x_end-centroid.x)*sinRoll +\
++                        (y_end-centroid.y)*cosRoll);
++
++            if( i >= 0 )
++              {
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              }
++            else
++              {
++              glEnable(GL_LINE_STIPPLE);
++              glLineStipple( 1, 0x00FF );
++              drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++              glDisable(GL_LINE_STIPPLE);
++              }
++
++            // Calculate the location and draw the right side label
++            // using the end of the line as previously calculated.
++            x_end -= centroid.x + label_length - 24;
++            if( i < 0 ) {
++              x_end -= 8;
++              }
++            y_end  = marker_y - ( 4 + centroid.y);
++            new_x_end = centroid.x + (int)( (GLfloat)x_end * cosRoll -
++                                            (GLfloat)y_end * sinRoll);
++            new_y_end = centroid.y + (int)( (GLfloat)x_end * sinRoll +
++                                            (GLfloat)y_end * cosRoll);
++            strokeString( new_x_end,  new_y_end,
++                          TextLadder, GLUT_STROKE_MONO_ROMAN,
++                          roll_value );
++            }
++          }
++        }
++      }
++    }
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0b582d0580994a0b62337410090a6f0b9ce8e5bb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,101 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============== Top of instr_scale class memeber definitions ===============
++//
++// Notes:
++// 1. instr_scales divide the specified location into half and then
++//    the half opposite the read direction in half again. A bar is
++//    then drawn along the second divider. Scale ticks are drawn
++//    between the middle and quarter section lines (minor division
++//    markers) or just over the middle line.
++//
++// 2.  This class was not intended to be instanciated. See moving_scale
++//     and guage_instr classes.
++//============================================================================
++instr_scale ::
++instr_scale ( int       x,
++              int       y,
++              UINT      width,
++              UINT      height,
++              DBLFNPTR  load_fn,
++              UINT      options,
++              double    show_range,
++              double    maxValue,
++              double    minValue,
++              double    disp_scale,
++              UINT      major_divs,
++              UINT      minor_divs,
++              UINT      rollover,
++              int       dp_showing,
++              bool      working ) :
++                instr_item( x, y, width, height,
++                            load_fn, disp_scale, options, working),
++                range_shown  ( show_range ),
++                Maximum_value( maxValue   ),
++                Minimum_value( minValue   ),
++                Maj_div      ( major_divs ),
++                Min_div      ( minor_divs ),
++                Modulo       ( rollover   ),
++                signif_digits( dp_showing )
++{
++int temp;
++
++  scale_factor   = (double)get_span() / range_shown;
++  if( show_range < 0 ) {
++    range_shown = -range_shown;
++    }
++  temp = (Maximum_value - Minimum_value) / 100;
++  if( range_shown < temp ) {
++    range_shown = temp;
++    }
++}
++
++instr_scale ::
++  instr_scale( const instr_scale & image ) :
++            instr_item( (const instr_item &) image),
++            range_shown  ( image.range_shown   ),
++            Maximum_value( image.Maximum_value ),
++            Minimum_value( image.Minimum_value ),
++            scale_factor ( image.scale_factor  ),
++            Maj_div      ( image.Maj_div       ),
++            Min_div      ( image.Min_div       ),
++            Modulo       ( image.Modulo        ),
++            signif_digits( image.signif_digits )
++{
++}
++
++instr_scale & instr_scale :: operator = (const instr_scale & rhs )
++{
++  if( !(this == &rhs)) {
++    instr_item::operator = (rhs);
++    range_shown   = rhs.range_shown;
++    scale_factor  = rhs.scale_factor;
++    Maximum_value = rhs.Maximum_value;
++    Minimum_value = rhs.Minimum_value;
++    Maj_div       = rhs.Maj_div;
++    Min_div       = rhs.Min_div;
++    Modulo        = rhs.Modulo;
++    signif_digits = rhs.signif_digits;
++    }
++  return *this;
++}
++
++instr_scale :: ~ instr_scale () {}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..299e08dd41360469d29f46b6cb0e0c08adf53c81
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,190 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============ Top of fgTBI_instr class member definitions ==============
++
++fgTBI_instr ::
++fgTBI_instr( int              x,
++             int              y,
++             UINT             width,
++             UINT             height,
++             DBLFNPTR  chn1_source,
++             DBLFNPTR  chn2_source,
++             double    maxBankAngle,
++             double    maxSlipAngle,
++             UINT      gap_width,
++             bool      working ) :
++               dual_instr_item( x, y, width, height,
++                                chn1_source,
++                                chn2_source,
++                                working,
++                                HUDS_TOP),
++               BankLimit      (maxBankAngle),
++               SlewLimit      (maxSlipAngle),
++               scr_hole       (gap_width   )
++{
++}
++
++fgTBI_instr :: ~fgTBI_instr() {}
++
++fgTBI_instr :: fgTBI_instr( const fgTBI_instr & image):
++                 dual_instr_item( (const dual_instr_item &) image),
++                 BankLimit( image.BankLimit),
++                 SlewLimit( image.SlewLimit),
++                 scr_hole ( image.scr_hole )
++{
++}
++
++fgTBI_instr & fgTBI_instr ::
++operator = (const fgTBI_instr & rhs )
++{
++  if( !(this == &rhs)) {
++    dual_instr_item::operator = (rhs);
++    BankLimit = rhs.BankLimit;
++    SlewLimit = rhs.SlewLimit;
++    scr_hole  = rhs.scr_hole;
++    }
++   return *this;
++}
++
++//
++//    Draws a Turn Bank Indicator on the screen
++//
++
++ void fgTBI_instr :: draw( void )
++{
++  int x_inc1, y_inc1;
++  int x_inc2, y_inc2;
++  int x_t_inc1, y_t_inc1;
++
++  int d_bottom_x, d_bottom_y;
++  int d_right_x, d_right_y;
++  int d_top_x, d_top_y;
++  int d_left_x, d_left_y;
++
++  int inc_b_x, inc_b_y;
++  int inc_r_x, inc_r_y;
++  int inc_t_x, inc_t_y;
++  int inc_l_x, inc_l_y;
++  RECT My_box = get_location();
++  POINT centroid = get_centroid();
++  int tee_height = My_box.bottom;
++
++//    struct fgFLIGHT *f = &current_aircraft.flight;
++  double sin_bank, cos_bank;
++  double bank_angle, sideslip_angle;
++  double ss_const; // sideslip angle pixels per rad
++
++  bank_angle     = current_ch2();  // Roll limit +/- 30 degrees
++  if( bank_angle < -FG_PI_2/3 ) {
++    bank_angle = -FG_PI_2/3;
++    }
++  else
++    if( bank_angle > FG_PI_2/3 ) {
++      bank_angle = FG_PI_2/3;
++      }
++  sideslip_angle = current_ch1(); // Sideslip limit +/- 20 degrees
++  if( sideslip_angle < -FG_PI/9 ) {
++    sideslip_angle = -FG_PI/9;
++    }
++  else
++    if( sideslip_angle > FG_PI/9 ) {
++      sideslip_angle = FG_PI/9;
++      }
++
++      // sin_bank = sin( FG_2PI-FG_Phi );
++      // cos_bank = cos( FG_2PI-FG_Phi );
++  sin_bank = sin(FG_2PI-bank_angle);
++  cos_bank = cos(FG_2PI-bank_angle);
++
++  x_inc1 = (int)(get_span() * cos_bank);
++  y_inc1 = (int)(get_span() * sin_bank);
++  x_inc2 = (int)(scr_hole  * cos_bank);
++  y_inc2 = (int)(scr_hole  * sin_bank);
++
++  x_t_inc1 = (int)(tee_height * sin_bank);
++  y_t_inc1 = (int)(tee_height * cos_bank);
++
++  d_bottom_x = 0;
++  d_bottom_y = (int)(-scr_hole);
++  d_right_x  = (int)(scr_hole);
++  d_right_y  = 0;
++  d_top_x    = 0;
++  d_top_y    = (int)(scr_hole);
++  d_left_x   = (int)(-scr_hole);
++  d_left_y   = 0;
++
++  ss_const = (get_span()*2)/(FG_2PI/9);  // width represents 40 degrees
++
++  d_bottom_x += (int)(sideslip_angle*ss_const);
++  d_right_x  += (int)(sideslip_angle*ss_const);
++  d_left_x   += (int)(sideslip_angle*ss_const);
++  d_top_x    += (int)(sideslip_angle*ss_const);
++
++  inc_b_x = (int)(d_bottom_x*cos_bank-d_bottom_y*sin_bank);
++  inc_b_y = (int)(d_bottom_x*sin_bank+d_bottom_y*cos_bank);
++  inc_r_x = (int)(d_right_x*cos_bank-d_right_y*sin_bank);
++  inc_r_y = (int)(d_right_x*sin_bank+d_right_y*cos_bank);
++  inc_t_x = (int)(d_top_x*cos_bank-d_top_y*sin_bank);
++  inc_t_y = (int)(d_top_x*sin_bank+d_top_y*cos_bank);
++  inc_l_x = (int)(d_left_x*cos_bank-d_left_y*sin_bank);
++  inc_l_y = (int)(d_left_x*sin_bank+d_left_y*cos_bank);
++
++  if( scr_hole == 0 )
++    {
++    drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \
++                 centroid.x + x_inc1, centroid.y + y_inc1 );
++    }
++  else
++    {
++    drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \
++                 centroid.x - x_inc2, centroid.y - y_inc2 );
++    drawOneLine( centroid.x + x_inc2, centroid.y + y_inc2, \
++                 centroid.x + x_inc1, centroid.y + y_inc1 );
++    }
++
++  // draw teemarks
++  drawOneLine( centroid.x + x_inc2,            \
++                 centroid.y + y_inc2,          \
++               centroid.x + x_inc2 + x_t_inc1, \
++                 centroid.y + y_inc2 - y_t_inc1 );
++  drawOneLine( centroid.x - x_inc2,            \
++                 centroid.y - y_inc2,          \
++               centroid.x - x_inc2 + x_t_inc1, \
++                 centroid.y - y_inc2 - y_t_inc1 );
++
++  // draw sideslip diamond (it is not yet positioned correctly )
++  drawOneLine( centroid.x + inc_b_x, \
++               centroid.y + inc_b_y, \
++               centroid.x + inc_r_x, \
++               centroid.y + inc_r_y );
++  drawOneLine( centroid.x + inc_r_x, \
++               centroid.y + inc_r_y, \
++               centroid.x + inc_t_x, \
++               centroid.y + inc_t_y );
++  drawOneLine( centroid.x + inc_t_x, \
++               centroid.y + inc_t_y, \
++               centroid.x + inc_l_x, \
++               centroid.y + inc_l_y );
++  drawOneLine( centroid.x + inc_l_x, \
++               centroid.y + inc_l_y, \
++               centroid.x + inc_b_x, \
++               centroid.y + inc_b_y );
++
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f70639fc0dc9649fe26698b4576268cc66f54359
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1097 @@@
++// panel.cxx -- routines to draw an instrument panel
++//
++// Written by Friedemann Reinhard, started June 1998.
++//
++// Copyright(C)1998 Friedemann Reinhard-reinhard@theorie2.physik.uni-erlangen.de
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H          
++#  include <windows.h>
++#endif
++
++#define FILLED true
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <string>
++#include <math.h>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Objects/texload.h>
++
++#include "panel.hxx"
++#include "cockpit.hxx"
++#include "hud.hxx"
++
++GLubyte *imag;
++int imag_width, imag_height;
++
++GLubyte *img;
++int img_width, img_height;
++
++static float value[4];
++static GLuint panel_tex_id[2];
++static GLubyte tex[32][128][3];
++static float alphahist;
++static float Xzoom, Yzoom;
++static Pointer pointer[20];
++static int NumPoint = 4;
++static int i = 0;
++static GLdouble mvmatrix[16];
++static GLdouble matrix[16];
++static double var[20];
++static double offset;
++static float alpha;
++static int n1;
++static int n2;
++
++static GLfloat Wings[] = {-1.25, -28.125, 1.255, -28.125, 1.255, 28.125,                                  -1.25, 28.125};
++static GLfloat Elevator[] = { 3.0, -10.9375, 4.5, -10.9375, 4.5, 10.9375,                                  3.0, 10.9375};
++static GLfloat Rudder[] = {2.0, -0.45, 10.625, -0.45, 10.625, 0.55,                                           2.0, 0.55};
++
++FGPanel* FGPanel::OurPanel = 0;
++
++// FGPanel::FGPanel() - constructor to initialize the panel.                 
++FGPanel::FGPanel(void){
++
++    string tpath;
++    int x, y;
++    FILE *f;
++    char line[256];
++    GLint test;
++    GLubyte tex[262144];
++
++OurPanel = this;   
++
++    Xzoom = (float)((float)(current_view.get_winWidth())/1024);
++    Yzoom = (float)((float)(current_view.get_winHeight())/768);
++
++test_instr[3] = new FGTexInstrument(144.375, 166.875, 4, 32, 3, 30, 15.0,                                           260.0, -20.0, 360, 65, 193, 0);
++test_instr[4] = new FGTexInstrument(358, 52, 4, 30, 3, 30, -3.0, 3.0, 100,                                          440, 66.15, 66, 2);
++test_instr[5] = new FGTexInstrument(357.5, 167, 5, 25, 4, 30, 0, 10000, 0,                                          360, 194, 191, 1);
++test_instr[6] = new FGTexInstrument(357.5, 167, 5, 32, 3, 30, 0, 3000, 0,                                           1080, 194, 191, 1);
++test_instr[0] = new FGHorizon(251, 166.75);
++test_instr[1] = new FGTurnCoordinator(143.75, 51.75);
++//test_instr[2] = new FGRpmGauge(462.5, 133);
++test_instr[2] = new FGTexInstrument(462.5, 133, 10, 20, 5.5, 60, 0.0, 1.0,                                            -67, 180, 174, 83, 3); 
++
++// FontList = glGenLists (256);
++// glListBase(FontList);
++// InitLists();
++
++#ifdef GL_VERSION_1_1
++    xglGenTextures(2, panel_tex_id);
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++#elif GL_EXT_texture_object
++    xglGenTexturesEXT(2, panel_tex_id);
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++#else
++#  error port me
++#endif
++
++    xglMatrixMode(GL_PROJECTION);
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglViewport(0, 0, 640, 480);
++    xglOrtho(0, 640, 0, 480, 1, -1);
++    xglMatrixMode(GL_MODELVIEW);
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++    // load in the texture data 
++    
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++    tpath = current_options.get_fg_root() + "/Textures/gauges.rgb";
++    if((img = read_rgb_texture( (char *)tpath.c_str(), &img_width,                      &img_height ))==NULL){
++    }
++
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++    tpath = current_options.get_fg_root() + "/Textures/gauges2.rgb";
++    if((imag = read_rgb_texture( (char *)tpath.c_str(), &imag_width,                     &imag_height ))==NULL){
++    }
++
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++
++    tpath = current_options.get_fg_root() + "/Textures/Fullone.rgb";
++    if ((background = read_rgb_texture( (char *)tpath.c_str(), &width,                         &height ))==NULL ){
++        }
++
++//    for(y=0;y<256;y++){
++//            for(x=0;x<256;x++){
++//            tex[(y+x*256)*3] = imag[(y+x*256)*3];
++//            tex[(y+x*256)*3 + 1] = imag[(y+x*256)*3 + 1];
++//            tex[(y+x*256)*3 + 2] = imag[(y+x*256)*3 + 2];
++//            tex[(y+x*256)*3 + 3] = (imag[(y+x*256)*3 + 1] + imag[(y+x*256)*3 + 2]   //                               + imag[(y+x*256)*3 + 0])/3;
++//            
++//    if((imag[(y+x*256)*3] < 150) && (imag[(y+x*256)*3 +1] < 150) &&         //             (imag[(y+x*256)*3 + 2] < 150) ){
++//              tex[(y+x*256)*3 + 3] = 0x0;
++//               }
++//           else{
++//             tex[(y+x*256)*3 + 3] = 0xff;
++//             }
++//             }
++// }
++
++    xglPixelZoom(Xzoom, Yzoom);
++    xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++      xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++    xglRasterPos2i(0,0);
++    xglPixelZoom(Xzoom, Yzoom);
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++    xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB,                                   GL_UNSIGNED_BYTE, imag);
++                
++#ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[0]);
++#elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[0]);
++#else
++#  error port me
++#endif
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++   xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB,                                  GL_UNSIGNED_BYTE, (GLvoid *)(img)); 
++                
++    xglMatrixMode(GL_MODELVIEW);
++    xglPopMatrix();
++}
++
++void FGPanel::ReInit( int x, int y, int finx, int finy){
++    fgOPTIONS *o;
++    int i;
++    GLint buffer;
++    
++    o = &current_options;
++    
++    xglDisable(GL_DEPTH_TEST);
++    
++    Xzoom = (float)((float)(current_view.get_winWidth())/1024);
++    Yzoom = (float)((float)(current_view.get_winHeight())/768);
++    
++    // save the current buffer state
++    xglGetIntegerv(GL_DRAW_BUFFER, &buffer);
++    
++    // and enable both buffers for writing
++    xglDrawBuffer(GL_FRONT_AND_BACK);
++    
++    xglMatrixMode(GL_PROJECTION);
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglViewport(0, 0, 640, 480);
++    xglOrtho(0, 640, 0, 480, 1, -1);
++    xglMatrixMode(GL_MODELVIEW);
++    xglPushMatrix();
++    xglLoadIdentity();
++     xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++    xglPixelZoom(Xzoom, Yzoom);
++    xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++    xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++    xglPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
++    xglPixelStorei(GL_UNPACK_SKIP_ROWS, y);
++    xglRasterPos2i(x, y);
++    xglPixelZoom(Xzoom, Yzoom);
++    xglDrawPixels(finx - x, finy - y, GL_RGB, GL_UNSIGNED_BYTE,                     (GLvoid *)(background));
++
++    // restore original buffer state
++    xglDrawBuffer( buffer );
++    xglEnable(GL_DEPTH_TEST);
++}
++
++void FGPanel::Update ( void ) {
++
++    float alpha;
++    double pitch;
++    double roll;
++    float alpharad;
++    double speed;
++    int i;
++    
++//    static bool beech_drawn = false;
++//    char *test = "ALM 100";
++                          
++    var[0] = get_speed() /* * 1.4 */; // We have to multiply the airspeed by a 
++                                // factor, to simulate flying a Bonanza 
++    var[1] = get_altitude();
++    var[2] = get_climb_rate() / 1000.0; 
++    var[3] = get_throttleval();
++
++    xglMatrixMode(GL_PROJECTION);
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglOrtho(0, 640, 0, 480, 10, -10);
++    xglMatrixMode(GL_MODELVIEW);
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglDisable(GL_DEPTH_TEST);
++    xglEnable(GL_LIGHTING);
++    xglEnable(GL_TEXTURE_2D);
++    xglDisable(GL_BLEND);
++
++    xglMatrixMode(GL_MODELVIEW);
++    xglPopMatrix();
++    xglPushMatrix();
++
++    xglDisable(GL_LIGHTING);
++     test_instr[3]->Render();
++     test_instr[4]->Render();
++     test_instr[5]->Render();
++     test_instr[6]->Render();
++    xglPopMatrix();
++    xglPushMatrix();
++    
++    test_instr[1]->Render();
++    test_instr[2]->Render();
++
++//   DrawBeechcraftLogo(230, 235, 30, 10);
++//   DrawScale(144.375, 166.875, 38, 41.0, 18, 340, 44, 2.0, 1.0, 1.0, 1.0);
++    
++    xglEnable(GL_LIGHTING);
++            
++    test_instr[0]->Render();
++    
++    
++    xglDisable(GL_TEXTURE_2D);
++    xglPopMatrix();   
++    xglEnable(GL_DEPTH_TEST);
++    xglEnable(GL_LIGHTING);
++    xglDisable(GL_TEXTURE_2D);
++    xglDisable(GL_BLEND);
++    xglMatrixMode(GL_PROJECTION);
++    xglPopMatrix();
++    xglMatrixMode(GL_MODELVIEW);
++    xglPopMatrix();
++}
++
++// horizon - Let's draw an artificial horizon using both texture mapping and 
++//           primitive drawing
++ 
++void FGHorizon::Render(void){ 
++    double pitch;
++    double roll;
++    float shifted, alpha, theta;
++    float epsi = 360 / 180;
++    GLboolean Light;
++    GLfloat normal[2];
++    
++   static int n, dn, rot, tmp1, tmp2;
++   float a;
++    
++    GLfloat material[] = { 0.714844, 0.265625, 0.056875 ,1.0};
++    GLfloat material2[] = {0.6640625, 0.921875, 0.984375, 1.0};
++    GLfloat material3[] = {0.2, 0.2, 0.2, 1.0};
++    GLfloat material4[] = {0.8, 0.8, 0.8, 1.0};
++    GLfloat material5[] = {0.0, 0.0, 0.0, 1.0};
++    GLfloat direction[] = {0.0, 0.0, 0.0};
++    GLfloat light_position[4];
++    GLfloat light_ambient[] = {0.7, 0.7, 0.7, 1.0};
++    GLfloat light_ambient2[] = {0.7, 0.7, 0.7, 1.0};
++    GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
++    GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
++    
++    pitch = get_pitch() * RAD_TO_DEG;
++    if(pitch > 45)
++    pitch = 45;
++    
++    if(pitch < -45)
++    pitch = -45;
++    
++    roll = get_roll() * RAD_TO_DEG;
++    
++    xglEnable(GL_NORMALIZE);
++    xglEnable(GL_LIGHTING);
++    xglEnable(GL_TEXTURE_2D);
++    xglEnable(GL_LIGHT1);
++    xglDisable(GL_LIGHT2);
++    xglDisable(GL_LIGHT0);
++    xglMatrixMode(GL_MODELVIEW);
++    xglLoadIdentity();
++    xglTranslatef(XPos, YPos, 0);
++    xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++    xglMatrixMode(GL_TEXTURE);
++    xglPushMatrix();
++        
++    // computations for the non-textured parts of the AH
++    
++    shifted = -((pitch / 10) * 7.0588235);
++        
++    if(shifted > (bottom - radius)){
++    theta = (180 - (acos((bottom - shifted) / radius)*RAD_TO_DEG));
++    n = (int)(theta / epsi) - 1;
++    n1 = n;
++    n2 = (180 - n1) + 2;
++    dn = n2 - n1;
++    rot = (int)(roll / epsi);
++    n1 += rot + 45;
++    n2 += rot + 45;
++    }
++    
++    if(shifted < (-top + radius)){
++    theta = ((acos((-top - shifted) / radius)*RAD_TO_DEG));
++    n = (int)(theta / epsi) + 1;
++    n1 = n;
++    n2 = (180 - n1) + 2;
++    dn = n2 - n1;
++    rot = (int)(roll / epsi);
++    n1 += rot - 45;
++    n2 += rot - 45;
++    if(n1 < 0){ n1 += 180; n2 +=180;}
++    }
++    
++    // end of computations  
++       
++    light_position[0] = 0.0;
++    light_position[1] = 0.0; 
++    light_position[2] = 1.5;
++    light_position[3] = 0.0;
++    xglLightfv(GL_LIGHT1, GL_POSITION, light_position);
++    xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);  
++    xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
++    xglLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
++    xglLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction);
++
++    #ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++    #elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++    #else
++    #  error port me
++    #endif
++
++    xglLoadIdentity();
++    xglTranslatef(0.0, ((pitch / 10) * 0.046875), 0.0);
++    xglTranslatef((texXPos/256), (texYPos/256), 0.0);
++    xglRotatef(-roll, 0.0, 0.0, 1.0);
++    xglScalef(1.7, 1.7, 0.0);
++
++    // the following loop draws the textured part of the AH
++    
++   xglMaterialf(GL_FRONT, GL_SHININESS, 85.0);
++    
++   xglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material4);
++   xglMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material5);
++   xglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material3);
++   
++    xglMatrixMode(GL_MODELVIEW);
++    xglBegin(GL_TRIANGLES);
++         for(i=45;i<225;i++){
++                     xglTexCoord2f(0.0, 0.0);
++                     xglNormal3f(0.0, 0.0, 0.6);
++                     xglVertex3f(0.0, 0.0, 0.0);
++                   xglTexCoord2f(texCoord[i % 180][0], texCoord[i % 180][1]);
++                   xglNormal3f(normals[i % 180][0], normals[i % 180][1], 0.6);
++                   xglVertex3f(vertices[i % 180][0], vertices[i % 180][1],                                     0.0);
++                   n = (i + 1) % 180;
++                   xglTexCoord2f(texCoord[n][0], texCoord[n][1]);
++                   xglNormal3f(normals[n][0], normals[n][1], 0.6);
++                   xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++                      }
++     xglEnd();
++    
++            
++    if((shifted > (bottom - radius)) && (n1 < 1000) && (n1 > 0)){
++    
++    a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
++light_ambient2[0] = a;
++light_ambient2[1] = a;
++light_ambient2[2] = a;
++    
++ xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2); 
++ xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
++        
++    xglBegin(GL_TRIANGLES);
++    
++    tmp1 = n1; tmp2 = n2;
++        
++          for(i = tmp1; i < tmp2 + 1; i++){
++                   n = i % 180;
++            xglNormal3f(0.0, 0.0, 1.5);
++              xglTexCoord2f((56 / 256), (140 / 256));
++            xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2),                            ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2),                             0.0);
++                                                
++             xglTexCoord2f((57 / 256), (139 / 256));        
++           xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
++                   xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++                   
++                   n = (i + 1) % 180;
++      xglTexCoord2f((57 / 256), (139 / 256));      
++      xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
++                   xglVertex3f(vertices[n][0], vertices[n][1], 0.0);       
++                      }
++     xglEnd();
++    }
++            
++    if((shifted < (-top + radius)) && (n1 < 1000) && (n1 > 0)){
++    a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
++light_ambient2[0] = a;
++light_ambient2[1] = a;
++light_ambient2[2] = a;
++     
++ xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2); 
++ xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
++ xglMaterialf(GL_FRONT, GL_SHININESS, a * 85);
++    xglBegin(GL_TRIANGLES);
++    tmp1 = n1; tmp2 = n2;
++          for(i = tmp1; i <= tmp2; i++){
++                   n = i % 180;
++          xglNormal3f(0.0, 0.0, 1.5);
++          xglTexCoord2f((73 / 256), (237 / 256));
++          xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2),                            ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2),                             0.0); 
++                      
++                     xglTexCoord2f((73 / 256), (236 / 256));
++                   xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
++                   xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++                   
++                   n = (i + 1) % 180;
++                  xglTexCoord2f((73 / 256), (236 / 256)); 
++                  xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
++                  xglVertex3f(vertices[n][0], vertices[n][1], 0.0); 
++                      }
++     xglEnd();
++    }
++    
++    // Now we will have to draw the small triangle indicating the roll value
++
++    xglDisable(GL_LIGHTING);
++    xglDisable(GL_TEXTURE_2D);
++    
++    xglRotatef(roll, 0.0, 0.0, 1.0);
++    
++    xglBegin(GL_TRIANGLES);
++    xglColor3f(1.0, 1.0, 1.0);
++    xglVertex3f(0.0, radius, 0.0);
++    xglVertex3f(-3.0, (radius - 7.0), 0.0);
++    xglVertex3f(3.0, (radius - 7.0), 0.0);    
++    xglEnd();
++    
++    xglLoadIdentity();
++
++    xglBegin(GL_POLYGON);
++    xglColor3f(0.2109375, 0.23046875, 0.203125);
++    xglVertex2f(275.625, 138.0);
++    xglVertex2f(275.625, 148.125);
++    xglVertex2f(258.125, 151.25);
++    xglVertex2f(246.875, 151.25);
++    xglVertex2f(226.875, 147.5);
++    xglVertex2f(226.875, 138.0);
++    xglVertex2f(275.625, 138.0);
++    xglEnd();
++
++    xglLoadIdentity();
++    
++    xglMatrixMode(GL_TEXTURE);
++    xglPopMatrix();
++    xglMatrixMode(GL_PROJECTION);
++    xglPopMatrix();
++    xglDisable(GL_TEXTURE_2D);
++    xglDisable(GL_NORMALIZE);
++    xglDisable(GL_LIGHTING);
++    xglDisable(GL_LIGHT1);
++    xglEnable(GL_LIGHT0);
++    }
++
++// fgHorizonInit - initialize values for the AH
++
++void FGHorizon::Init(void){
++      radius = 28.9;
++      texXPos = 56;
++      texYPos = 174;
++      bottom = 36.5;
++      top = 36.5;
++      int n;
++
++float step = (360*DEG_TO_RAD)/180;
++
++for(n=0;n<180;n++){
++         vertices[n][0] = cos(n * step) * radius;
++         vertices[n][1] = sin(n * step) * radius;
++           texCoord[n][0] = (cos(n * step) * radius)/256;
++           texCoord[n][1] = (sin(n * step) * radius)/256;
++         normals[n][0] = cos(n * step) * radius + sin(n * step);
++         normals[n][1] = sin(n * step) * radius + cos(n * step);
++           normals[n][2] = 0.0;
++           }
++}
++
++void FGTexInstrument::UpdatePointer(void){
++    double pitch;
++    double roll;
++    float alpharad;
++    double speed;    
++    glEnableClientState(GL_VERTEX_ARRAY);
++    glVertexPointer(2, GL_FLOAT, 0, vertices);
++
++    alpha=((((float)((var[variable]) - (value1))) /                                        (value2 - value1))*                                                             (alpha2 - alpha1) + alpha1);
++    
++      if (alpha < alpha1)
++                      alpha = alpha1;
++      if (alpha > alpha2)
++              alpha = alpha2;
++    xglMatrixMode(GL_MODELVIEW);  
++    xglPushMatrix();
++    xglLoadIdentity();
++    xglDisable(GL_TEXTURE_2D);
++    xglTranslatef(XPos, YPos, 0);
++    xglRotatef(-alpha, 0.0, 0.0, 1.0);
++    xglColor4f(1.0, 1.0, 1.0, 1.0);
++    glDrawArrays(GL_POLYGON, 0, 10);
++    tape[0] = tape[1];
++    tape[1] = alpha;
++    xglEnable(GL_TEXTURE_2D);
++    glDisableClientState(GL_VERTEX_ARRAY);
++}
++
++// fgEraseArea - 'Erases' a drawn Polygon by overlaying it with a textured 
++//                 area. Shall be a method of a panel class once.
++
++void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos,                                  GLfloat texYPos, GLfloat XPos, GLfloat YPos,                                    int Texid, float ScaleFactor){
++int i, j;
++int n;
++float a;
++float ififth;
++
++xglEnable(GL_TEXTURE_2D);
++xglEnable(GL_TEXTURE_GEN_S);
++xglEnable(GL_TEXTURE_GEN_T);
++glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
++glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
++xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
++xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++xglMatrixMode(GL_TEXTURE);
++xglLoadIdentity();
++        
++    #ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[Texid]);
++    #elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[Texid]);
++    #else
++    #  error port me
++    #endif
++
++xglMatrixMode(GL_TEXTURE);
++xglLoadIdentity();
++xglTranslatef(-((float)((XPos/0.625)/256)),                                                   -((float)((YPos/0.625)/256)), 0.0);
++xglTranslatef(texXPos/256 , texYPos/256, 0.0);
++xglScalef(0.00625, 0.00625, 1.0);
++                      
++      xglBegin(GL_POLYGON);
++for(n=0;n<NumVerti;n += 2){   
++xglVertex2f(array[n] * ScaleFactor, array[n + 1] * ScaleFactor);
++} 
++      xglEnd();
++ 
++        xglLoadIdentity();
++        xglMatrixMode(GL_MODELVIEW);
++        xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
++        xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
++        xglDisable(GL_TEXTURE_2D);
++      xglDisable(GL_TEXTURE_GEN_S);
++      xglDisable(GL_TEXTURE_GEN_T);
++        
++}
++
++// CreatePointer - calculate the vertices of a pointer 
++
++void FGTexInstrument::CreatePointer(void){
++int i;
++float alpha;
++float alphastep;
++float r = radius;
++
++vertices[0] = 0;
++vertices[1] = length;
++vertices[2] = -(width/2);
++vertices[3] = length - ((width/2)/(tan(angle*DEG_TO_RAD/2)));
++vertices[4] = -(width/2);
++vertices[5] = cos(asin((width/2)/r))*r;
++
++alphastep = (asin((width/2)/r)+asin((width/2)/r))/5;
++alpha = asin(-(width/2)/r);
++
++for(i=0;i<5;i++){
++alpha += alphastep;
++vertices[(i*2)+6] = sin(alpha)*r;
++   }
++
++alpha = asin(-(width/2)/r);
++
++for(i=0;i<5;i++){
++alpha +=alphastep;
++vertices[(i*2)+7]= cos(alpha)*r;
++   }
++
++vertices[16] = - vertices[4];
++vertices[17] = vertices[5];
++vertices[18] = - vertices[2];
++vertices[19] = vertices[3];
++
++}
++
++// fgUpdateTurnCoordinator - draws turn coordinator related stuff
++
++void FGTurnCoordinator::Render(void){
++int n;
++
++xglDisable(GL_LIGHTING);
++xglDisable(GL_BLEND);
++xglEnable(GL_TEXTURE_2D);
++
++ alpha = (get_sideslip() / 1.5) * 560;
++ if(alpha > 56){
++ alpha = 56;
++ }
++ if(alpha < -56){
++ alpha = -56;
++ }
++ 
++ PlaneAlpha = get_roll();
++
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++     xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(BallXPos, BallYPos, 0.0);
++xglTranslatef(0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31,                                     0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39)),                             0.0);
++fgEraseArea(vertices, 72, BallTexXPos +                                                     ((0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31) / 0.625),                         BallTexYPos + ((0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD)                                  * 39))) / 0.625),                                                   BallXPos + (0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31),                       BallYPos + (0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD)                         * 39))), 1, 1);
++xglDisable(GL_TEXTURE_2D);
++xglEnable(GL_BLEND);
++xglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(BallXPos, BallYPos, 0.0);
++xglTranslatef(0.75 * sin(alpha * DEG_TO_RAD) * 31,                                            0.3 * (39 - (cos(alpha * DEG_TO_RAD) * 39)), 0.0);
++xglBegin(GL_POLYGON);
++xglColor3f(0.8, 0.8, 0.8);
++for(i=0;i<36;i++){
++xglVertex2f(vertices[2 * i],                                                                vertices[(2 * i) + 1]);
++}
++xglEnd(); 
++
++xglDisable(GL_TEXTURE_2D);
++xglDisable(GL_BLEND);
++
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(XPos, YPos, 0.0);
++xglRotatef(rollhist[0] * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
++
++fgEraseArea(Wings, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
++fgEraseArea(Elevator, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
++fgEraseArea(Rudder, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
++
++xglLoadIdentity();
++xglTranslatef(XPos, YPos, 0.0);
++xglRotatef(-get_roll() * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
++
++xglBegin(GL_POLYGON);
++xglColor3f(1.0, 1.0, 1.0);
++for(i=0;i<90;i++){
++xglVertex2f(cos(i * 4 * DEG_TO_RAD) * 5, sin(i * 4 * DEG_TO_RAD) * 5);
++}
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Wings[0], Wings[1]);
++xglVertex2f(Wings[2], Wings[3]);
++xglVertex2f(Wings[4], Wings[5]);
++xglVertex2f(Wings[6], Wings[7]);
++xglVertex2f(Wings[0], Wings[1]);
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Elevator[0], Elevator[1]);
++xglVertex2f(Elevator[2], Elevator[3]);
++xglVertex2f(Elevator[4], Elevator[5]);
++xglVertex2f(Elevator[6], Elevator[7]);
++xglVertex2f(Elevator[0], Elevator[1]);
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Rudder[0], Rudder[1]);
++xglVertex2f(Rudder[2], Rudder[3]);
++xglVertex2f(Rudder[4], Rudder[5]);
++xglVertex2f(Rudder[6], Rudder[7]);
++xglVertex2f(Rudder[0], Rudder[1]);
++xglEnd();
++
++
++alphahist[0] = alphahist[1];
++alphahist[1] = alpha;
++rollhist[0] = rollhist[1];
++rollhist[1] = -get_roll();
++
++xglDisable(GL_BLEND);
++}
++
++void FGTurnCoordinator::Init(void){
++int n;
++PlaneTexXPos = 49;
++PlaneTexYPos = 59.75;
++BallXPos = 145;
++BallYPos = 24;
++BallTexXPos = 49;
++BallTexYPos = 16;
++BallRadius = 3.5;
++
++for(n=0;n<36;n++){
++vertices[2 * n] = cos(10 * n * DEG_TO_RAD) * BallRadius;
++vertices[(2 * n) + 1] = sin(10 * n * DEG_TO_RAD) * BallRadius;
++      }       
++}
++
++void DrawScale(float XPos, float YPos, float InnerRadius, float OuterRadius,                   float alpha1, float alpha2, int steps, float LineWidth,                       float red, float green, float blue, bool filled){
++     int i;
++     float diff = (alpha2 - alpha1) / (float)(steps - 1);
++     
++     #define ANTIALIASED_INSTRUMENTS
++
++     #ifdef ANTIALIASED_INSTRUMENTS
++     xglEnable(GL_LINE_SMOOTH);
++     xglEnable(GL_BLEND);
++     xglHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
++     #endif
++     
++     xglMatrixMode(GL_MODELVIEW);
++     xglLoadIdentity();
++     
++     xglTranslatef(XPos, YPos, 0.0);
++     xglRotatef(-alpha1, 0.0, 0.0, 1.0);
++     
++     xglLineWidth(LineWidth);
++     xglColor3f(red, green, blue);
++     
++     if(!filled){
++     xglBegin(GL_LINES);
++     }
++     else{
++     xglBegin(GL_QUAD_STRIP);
++     }
++     
++     for(i=0;i < steps; i++){
++     xglVertex3f(sin(i * diff * DEG_TO_RAD) * OuterRadius,                                       cos(i * diff * DEG_TO_RAD) * OuterRadius, 0.0);
++     xglVertex3f(sin(i * diff * DEG_TO_RAD) * InnerRadius,                                       cos(i * diff * DEG_TO_RAD) * InnerRadius, 0.0);
++        }
++     xglEnd();
++     
++     xglLoadIdentity();
++     xglDisable(GL_LINE_SMOOTH);
++     xglDisable(GL_BLEND);
++     }
++
++void DrawBeechcraftLogo(float XPos, float YPos, float width, float height){
++     xglMatrixMode(GL_MODELVIEW);
++     xglLoadIdentity();
++     xglTranslatef(XPos, YPos, 0.0);
++     xglEnable(GL_BLEND);
++     xglEnable(GL_TEXTURE_2D);
++//   xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
++//   xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
++
++    #ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++    #elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++    #else
++    #  error port me
++    #endif
++
++    xglBegin(GL_POLYGON);
++    
++    xglTexCoord2f(.39844, .01953);
++    xglVertex2f(0.0, 0.0);
++    xglTexCoord2f(.58594, .01953);
++    xglVertex2f(width, 0.0);
++    xglTexCoord2f(.58594, .074219);
++    xglVertex2f(width, height);
++    xglTexCoord2f(.39844, .074219);
++    xglVertex2f(0.0, height);
++    
++    xglEnd();
++    
++    xglDisable(GL_BLEND);
++    xglDisable(GL_TEXTURE_2D);
++ }
++    
++
++// PrintMatrix - routine to print the current modelview matrix.                 
++
++void PrintMatrix( void){
++xglGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
++printf("matrix2 = %f %f %f %f \n", mvmatrix[0], mvmatrix[1], mvmatrix[2], mvmatrix[3]);
++printf("         %f %f %f %f \n", mvmatrix[4], mvmatrix[5], mvmatrix[6], mvmatrix[7]);
++printf("         %f %f %f %f \n", mvmatrix[8], mvmatrix[9], mvmatrix[10], mvmatrix[11]);
++printf("         %f %f %f %f \n", mvmatrix[12], mvmatrix[13], mvmatrix[14], mvmatrix[15]);
++}
++
++void FGRpmGauge::Init(void){
++     list = xglGenLists (1);
++     int n;
++     
++     xglNewList(list, GL_COMPILE);
++     
++     xglColor3f(.26, .289, .3281);
++     xglBegin(GL_POLYGON);
++     for(n = 0; n < 180; n++){
++     xglVertex2f(cos(n * 0.0349066) * 24.5, sin(n * 0.0349066) * 24.5);
++     }
++     xglEnd();
++     
++DrawScale(XPos, YPos, 22.5, 25.625, 50, 135, 10, 1.0, 0.0, 0.7,                           0.0,FILLED);
++DrawScale(XPos, YPos, 21.0, 25.625, -70, 180, 8, 1.8, 0.88, 0.88, 0.88, false);
++DrawScale(XPos, YPos, 22.5, 25.0, -70, 180, 40, 0.6, 0.5, 0.5, 0.5, false);
++          
++     xglEndList();
++     }
++     
++void FGRpmGauge::Render(void){
++     xglMatrixMode(GL_MODELVIEW);
++     xglLoadIdentity();
++     xglTranslatef(XPos, YPos, 0.0);
++     
++     xglCallList(list);
++          
++     }
++     
++void FGPanel::DrawTestLetter(float X, float Y){
++     xglEnable(GL_TEXTURE_2D);
++     xglEnable(GL_BLEND);
++     
++     xglMatrixMode(GL_TEXTURE);
++     xglLoadIdentity();
++     xglTranslatef(X, Y, 0.0);
++     
++    DrawLetter();
++    
++     xglMatrixMode(GL_MODELVIEW); 
++     xglTranslatef(6.0, 0.0, 0.0);
++     xglDisable(GL_TEXTURE_2D);
++     xglDisable(GL_BLEND);
++     }
++    
++void FGPanel::InitLists(void){
++     xglNewList(FontList + 'A', GL_COMPILE);
++     DrawTestLetter(0.391625, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'B', GL_COMPILE);
++     DrawTestLetter(0.391625 + 1 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'C', GL_COMPILE);
++     DrawTestLetter(0.391625 + 2 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'D', GL_COMPILE);
++     DrawTestLetter(0.391625 + 3 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'E', GL_COMPILE);
++     DrawTestLetter(0.391625 + 4 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'F', GL_COMPILE);
++     DrawTestLetter(0.391625 + 5 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'G', GL_COMPILE);
++     DrawTestLetter(0.391625 + 6 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'H', GL_COMPILE);
++     DrawTestLetter(0.391625 + 7 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'I', GL_COMPILE);
++     DrawTestLetter(0.391625 + 8 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'J', GL_COMPILE);
++     DrawTestLetter(0.391625 + 9 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'K', GL_COMPILE);
++     DrawTestLetter(0.391625 + 9.7 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'L', GL_COMPILE);
++     DrawTestLetter(0.399625 + 10.6 * LETTER_OFFSET, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'M', GL_COMPILE);
++     DrawTestLetter(0.80459375, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'N', GL_COMPILE);
++     DrawTestLetter(0.83975, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'O', GL_COMPILE);
++     DrawTestLetter(0.871, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'P', GL_COMPILE);
++     DrawTestLetter(0.90715625, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + 'Q', GL_COMPILE);
++     DrawTestLetter(0.9413125, 0.29296875);
++     xglEndList();
++     
++     xglNewList(FontList + '1', GL_COMPILE);
++     DrawTestLetter(0.390625, 0.35546875);
++     xglEndList();
++     
++     xglNewList(FontList + '2', GL_COMPILE);
++     DrawTestLetter(0.390625 + 1*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '3', GL_COMPILE);
++     DrawTestLetter(0.390625 + 2*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '4', GL_COMPILE);
++     DrawTestLetter(0.390625 + 3*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '5', GL_COMPILE);
++     DrawTestLetter(0.390625 + 4*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '6', GL_COMPILE);
++     DrawTestLetter(0.390625 + 5*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '7', GL_COMPILE);
++     DrawTestLetter(0.390625 + 6*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '8', GL_COMPILE);
++     DrawTestLetter(0.390625 + 7*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '9', GL_COMPILE);
++     DrawTestLetter(0.390625 + 8*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + '0', GL_COMPILE);
++     DrawTestLetter(0.383625 + 9*LETTER_OFFSET, 0.3515625); 
++     xglEndList();
++     
++     xglNewList(FontList + ' ', GL_COMPILE);
++     xglTranslatef(8.0, 0.0, 0.0);
++     xglEndList();
++     }
++    
++void FGPanel::TexString(char *s, float XPos, float YPos, float size){
++     xglMatrixMode(GL_MODELVIEW);
++     xglLoadIdentity();
++     xglTranslatef(XPos, YPos, 0.0);
++     xglScalef(size, size, 1.0);
++     
++    #ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++    #elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++    #else
++    #  error port me
++    #endif
++    
++     while((*s) != '\0'){
++     xglCallList(FontList + (*s));
++     s++;
++      }
++      xglLoadIdentity();
++     }
++     
++void FGTexInstrument::Init(void){
++     CreatePointer();
++     }
++     
++void FGTexInstrument::Render(void){
++xglEnable(GL_TEXTURE_2D);
++     xglLoadIdentity();
++     xglTranslatef(XPos, YPos, 0.0);
++     xglRotatef(-tape[0], 0.0, 0.0, 1.0);
++    fgEraseArea(vertices, 20, (GLfloat)(teXpos),                                               (GLfloat)(texYpos), (GLfloat)(XPos),                                            (GLfloat)(YPos), 0, 1);
++     
++     UpdatePointer();
++     
++     xglDisable(GL_TEXTURE_2D);
++     }
++     
++// $Log$
++// Revision 1.18  1999/03/09 20:58:17  curt
++// Tweaks for compiling under native Irix compilers.
++//
++// Revision 1.17  1999/03/08 21:56:09  curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.13  1999/01/07 19:25:53  curt
++// Updates from Friedemann Reinhard.
++//
++// Revision 1.11  1998/11/11 00:19:27  curt
++// Updated comment delimeter to C++ style.
++//
++// Revision 1.10  1998/11/09 23:38:52  curt
++// Panel updates from Friedemann.
++//
++// Revision 1.9  1998/11/06 21:18:01  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8  1998/10/16 23:27:37  curt
++// C++-ifying.
++//
++// Revision 1.7  1998/08/31 20:45:31  curt
++// Tweaks from Friedemann.
++//
++// Revision 1.6  1998/08/28 18:14:40  curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.1  1998/06/27 16:47:54  curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++//
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1809e7fbc38fc34dc763e3eb43822b59dedb7088
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,280 @@@
++//  panel.hxx -- instrument panel defines and prototypes
++// 
++//  Written by Friedemann Reinhard, started June 1998.
++// 
++//  This program is free software; you can redistribute it and/or
++//  modify it under the terms of the GNU General Public License as
++//  published by the Free Software Foundation; either version 2 of the
++//  License, or (at your option) any later version.
++// 
++//  This program is distributed in the hope that it will be useful, but
++//  WITHOUT ANY WARRANTY; without even the implied warranty of
++//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++//  General Public License for more details.
++// 
++//  You should have received a copy of the GNU General Public License
++//  along with this program; if not, write to the Free Software
++//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++//  $Id$
++//  (Log is kept at end of this file)
++ 
++#define LETTER_OFFSET 0.03515625 
++
++#ifndef _PANEL_HXX
++#define _PANEL_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H          
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++class FGInstrument;
++
++class FGPanel{
++
++private:
++int height, width;
++GLuint FontList;
++
++GLubyte *background;
++
++// FGInstrument **instr_list;
++FGInstrument *test_instr[7];
++
++void GetData(void);
++
++public:
++static FGPanel *OurPanel;
++
++      FGPanel(void);
++
++float   get_height(void){
++      return height;
++      }
++
++void    ReInit( int x, int y, int finx, int finy);
++void    Update(void);
++
++void    DrawLetter(void){
++        glBegin(GL_POLYGON);
++        glTexCoord2f(0.0, 0.0);
++        glVertex2f(0.0, 0.0);
++        glTexCoord2f(LETTER_OFFSET + 0.004, 0.0);
++        glVertex2f(7.0, 0.0);
++        glTexCoord2f(LETTER_OFFSET + 0.004, 0.0390625);
++        glVertex2f(7.0, 9.0);
++        glTexCoord2f(0.0, 0.0390625);
++        glVertex2f(0.0, 9.0);
++        glEnd();
++        }
++        
++void DrawTestLetter(float X, float Y);
++void InitLists(void);
++void TexString(char *s, float XPos, float YPos, float size);
++
++};
++
++class FGInstrument{
++friend class FGPanel;
++
++protected:
++float XPos, YPos;
++
++public:
++      FGInstrument(void){
++      }
++      
++      virtual ~FGInstrument(void){}
++      
++virtual void Init(void) = 0;
++virtual void Render(void) = 0;
++};
++
++class FGHorizon : public FGInstrument {
++private:
++    float texXPos;
++    float texYPos;
++    float radius;
++    float bottom;   // tell the program the offset between midpoint and bottom 
++    float top;      // guess what ;-)
++    float vertices[180][2];
++    float normals[180][3];
++    float texCoord[180][2];
++    
++public:
++      FGHorizon(void){
++      XPos = 0.0; YPos = 0.0;
++      Init();
++      }
++
++        FGHorizon(float inXPos, float inYPos){
++        XPos = inXPos; YPos = inYPos;
++        Init();
++        }
++        
++virtual void Init(void);
++virtual void Render(void);
++
++};
++
++class FGTurnCoordinator : public FGInstrument {
++private:
++    float PlaneTexXPos;
++    float PlaneTexYPos;
++    float alpha;
++    float PlaneAlpha;
++    float alphahist[2];
++    float rollhist[2];
++    float BallXPos;
++    float BallYPos;
++    float BallTexXPos;
++    float BallTexYPos;
++    float BallRadius;
++  GLfloat vertices[72];
++
++public:
++      FGTurnCoordinator(void){
++      XPos = 0.0; YPos = 0.0;
++      Init();
++      }
++
++      FGTurnCoordinator(float inXPos, float inYPos){
++      XPos = inXPos; YPos = inYPos;
++      Init();
++      }       
++
++virtual void Init (void);
++virtual void Render(void);
++
++};
++
++class FGRpmGauge : public FGInstrument {
++private:
++    GLuint list;
++    
++public:
++      FGRpmGauge(void){
++      XPos = 0.0; YPos = 0.0;
++      Init();
++      }
++
++      FGRpmGauge(float inXPos, float inYPos){
++      XPos = inXPos; YPos = inYPos;
++      Init();
++      }       
++
++virtual void Init(void);
++virtual void Render(void);
++};
++
++// temporary class until I get the software-only routines for the 
++// instruments run
++
++class FGTexInstrument : public FGInstrument {
++
++private:
++    float radius;
++    float length;
++    float width;
++    float angle;
++    float tape[2];
++    float value1;
++    float value2;
++    float alpha1;
++    float alpha2;
++    float teXpos;
++    float texYpos;
++    int variable;
++    GLfloat vertices[20];
++    
++public:
++      FGTexInstrument(void){
++      XPos = 0.0; YPos = 0.0;
++      Init();
++      }
++
++      FGTexInstrument(float inXPos, float inYPos, float inradius,                                     float inlength, float inwidth, float inangle,                                   float invalue1, float invalue2, float inalpha1,                                 float inalpha2, float intexXPos, float intexYPos,                               int invariable){
++
++      XPos = inXPos; YPos = inYPos;
++      radius = inradius; angle = inangle;
++      length = inlength; width = inwidth;
++      value1 = invalue1; value2 = invalue2;
++      alpha1 = inalpha1; alpha2 = inalpha2;
++      teXpos = intexXPos; texYpos = intexYPos;
++      variable = invariable; 
++      Init();
++      }
++
++   void CreatePointer(void);
++   void UpdatePointer(void);
++
++   void Init(void);
++   void Render(void);
++};
++
++typedef struct{
++float XPos;
++float YPos;
++    float radius;
++    float length;
++    float width;
++    float angle;
++    float tape[2];
++    float value1;
++    float value2;
++    float alpha1;
++    float alpha2;
++    float teXpos;
++    float texYpos;
++    int variable;
++    GLfloat vertices[20];
++}Pointer;
++
++void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos,                                  GLfloat texYPos, GLfloat XPos, GLfloat YPos,                                    int Texid, float ScaleFactor);
++void DrawScale(float XPos, float YPos, float InnerRadius, float OuterRadius,                   float alpha1, float alpha2, int steps, float LineWidth,                       float red, float green, float blue, bool filled);
++void DrawBeechcraftLogo(float XPos, float YPos, float Width, float Height);
++
++void PrintMatrix( void);
++
++#endif // _PANEL_HXX 
++
++
++
++// $Log$
++// Revision 1.9  1999/03/09 20:58:18  curt
++// Tweaks for compiling under native Irix compilers.
++//
++// Revision 1.8  1999/03/08 21:56:10  curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.5  1999/01/07 19:25:55  curt
++// Updates from Friedemann Reinhard.
++//
++// Revision 1.4  1998/11/11 00:19:29  curt
++// Updated comment delimeter to C++ style.
++//
++// Revision 1.3  1998/11/09 23:38:54  curt
++// Panel updates from Friedemann.
++//
++// Revision 1.2  1998/08/28 18:14:41  curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.1  1998/06/27 16:47:55  curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8327dc84c230419641819c93cfc5c2b124ad6221
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++noinst_LIBRARIES = libControls.a
++
++libControls_a_SOURCES = controls.cxx controls.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..62e4cc8ed97a83f78b286ff76bac11a183d493ad
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,91 @@@
++// controls.cxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include "controls.hxx"
++
++
++FGControls controls;
++
++
++// Constructor
++FGControls::FGControls() :
++    aileron( 0.0 ),
++    elevator( 0.0 ),
++    elevator_trim( 1.969572E-03 ),
++    rudder( 0.0 )
++{
++    for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
++      throttle[engine] = 0.0;
++    }
++
++    for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
++        brake[wheel] = 0.0;
++    }
++}
++
++
++// Destructor
++FGControls::~FGControls() {
++}
++
++
++// $Log$
++// Revision 1.3  1998/12/05 16:13:12  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2  1998/10/25 14:08:41  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1  1998/10/18 01:51:05  curt
++// c++-ifying ...
++//
++// Revision 1.8  1998/09/29 02:01:31  curt
++// Added a brake.
++//
++// Revision 1.7  1998/02/07 15:29:36  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6  1998/01/19 19:27:02  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5  1998/01/19 18:40:22  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4  1997/12/10 22:37:41  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3  1997/08/27 03:30:01  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2  1997/06/21 17:12:48  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.1  1997/05/31 19:24:04  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..286cc86e8ada9e6572e43e4c80ca7c8a098b81e0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,252 @@@
++// controls.hxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _CONTROLS_HXX
++#define _CONTROLS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// Define a structure containing the control parameters
++
++class FGControls {
++
++public:
++
++    enum
++    {
++      ALL_ENGINES = -1,
++      MAX_ENGINES = 10
++    };
++
++    enum
++    {
++      ALL_WHEELS = -1,
++      MAX_WHEELS = 3
++    };
++
++private:
++
++    double aileron;
++    double elevator;
++    double elevator_trim;
++    double rudder;
++    double throttle[MAX_ENGINES];
++    double brake[MAX_WHEELS];
++
++public:
++
++    FGControls();
++    ~FGControls();
++
++    // Query functions
++    inline double get_aileron() const { return aileron; }
++    inline double get_elevator() const { return elevator; }
++    inline double get_elevator_trim() const { return elevator_trim; }
++    inline double get_rudder() const { return rudder; }
++    inline double get_throttle(int engine) const { return throttle[engine]; }
++    inline double get_brake(int wheel) const { return brake[wheel]; }
++
++    // Update functions
++    inline void set_aileron( double pos ) {
++      aileron = pos;
++      if ( aileron < -1.0 ) aileron = -1.0;
++      if ( aileron >  1.0 ) aileron =  1.0;
++    }
++    inline void move_aileron( double amt ) {
++      aileron += amt;
++      if ( aileron < -1.0 ) aileron = -1.0;
++      if ( aileron >  1.0 ) aileron =  1.0;
++    }
++    inline void set_elevator( double pos ) {
++      elevator = pos;
++      if ( elevator < -1.0 ) elevator = -1.0;
++      if ( elevator >  1.0 ) elevator =  1.0;
++    }
++    inline void move_elevator( double amt ) {
++      elevator += amt;
++      if ( elevator < -1.0 ) elevator = -1.0;
++      if ( elevator >  1.0 ) elevator =  1.0;
++    }
++    inline void set_elevator_trim( double pos ) {
++      elevator_trim = pos;
++      if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++      if ( elevator_trim >  1.0 ) elevator_trim =  1.0;
++    }
++    inline void move_elevator_trim( double amt ) {
++      elevator_trim += amt;
++      if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++      if ( elevator_trim >  1.0 ) elevator_trim =  1.0;
++    }
++    inline void set_rudder( double pos ) {
++      rudder = pos;
++      if ( rudder < -1.0 ) rudder = -1.0;
++      if ( rudder >  1.0 ) rudder =  1.0;
++    }
++    inline void move_rudder( double amt ) {
++      rudder += amt;
++      if ( rudder < -1.0 ) rudder = -1.0;
++      if ( rudder >  1.0 ) rudder =  1.0;
++    }
++    inline void set_throttle( int engine, double pos ) {
++      if ( engine == ALL_ENGINES ) {
++          for ( int i = 0; i < MAX_ENGINES; i++ ) {
++              throttle[i] = pos;
++              if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++              if ( throttle[i] >  1.0 ) throttle[i] =  1.0;
++          }
++      } else {
++          if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++              throttle[engine] = pos;
++              if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++              if ( throttle[engine] >  1.0 ) throttle[engine] =  1.0;
++          }
++      }
++    }
++    inline void move_throttle( int engine, double amt ) {
++      if ( engine == ALL_ENGINES ) {
++          for ( int i = 0; i < MAX_ENGINES; i++ ) {
++              throttle[i] += amt;
++              if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++              if ( throttle[i] >  1.0 ) throttle[i] =  1.0;
++          }
++      } else {
++          if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++              throttle[engine] += amt;
++              if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++              if ( throttle[engine] >  1.0 ) throttle[engine] =  1.0;
++          }
++      }
++    }
++    inline void set_brake( int wheel, double pos ) {
++      if ( wheel == ALL_WHEELS ) {
++          for ( int i = 0; i < MAX_WHEELS; i++ ) {
++              brake[i] = pos;
++              if ( brake[i] < 0.0 ) brake[i] = 0.0;
++              if ( brake[i] >  1.0 ) brake[i] =  1.0;
++          }
++      } else {
++          if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++              brake[wheel] = pos;
++              if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++              if ( brake[wheel] >  1.0 ) brake[wheel] =  1.0;
++          }
++      }
++    }
++    inline void move_brake( int wheel, double amt ) {
++      if ( wheel == ALL_WHEELS ) {
++          for ( int i = 0; i < MAX_WHEELS; i++ ) {
++              brake[i] += amt;
++              if ( brake[i] < 0.0 ) brake[i] = 0.0;
++              if ( brake[i] >  1.0 ) brake[i] =  1.0;
++          }
++      } else {
++          if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++              brake[wheel] += amt;
++              if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++              if ( brake[wheel] >  1.0 ) brake[wheel] =  1.0;
++          }
++      }
++    }
++};
++
++
++extern FGControls controls;
++
++
++#endif // _CONTROLS_HXX
++
++
++// $Log$
++// Revision 1.4  1999/01/27 04:48:13  curt
++// C++ style refinements by Bernie Bright.
++//
++// Revision 1.3  1998/12/05 16:13:13  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2  1998/10/25 14:08:42  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1  1998/10/18 01:51:07  curt
++// c++-ifying ...
++//
++// Revision 1.17  1998/09/29 14:57:00  curt
++// c++-ified some comments.
++//
++// Revision 1.16  1998/09/29 02:01:32  curt
++// Added a brake.
++//
++// Revision 1.15  1998/04/25 22:06:27  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14  1998/04/22 13:26:19  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.13  1998/04/21 17:02:35  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.12  1998/02/09 22:56:48  curt
++// Removed "depend" files from cvs control.  Other minor make tweaks.
++//
++// Revision 1.11  1998/02/07 15:29:36  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10  1998/01/27 00:47:52  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9  1998/01/22 02:59:31  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8  1998/01/19 18:40:22  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7  1997/12/15 23:54:36  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6  1997/12/10 22:37:41  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.5  1997/08/27 03:30:02  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4  1997/07/23 21:52:18  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3  1997/05/31 19:16:27  curt
++// Elevator trim added.
++//
++// Revision 1.2  1997/05/23 15:40:33  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 15:59:48  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..54f3b28f9b6593f6bc662c3f28b9b5d82a9114a3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++noinst_LIBRARIES = libExternal.a
++
++libExternal_a_SOURCES = external.cxx external.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2325f1052e749521bb10f5c32c4a01bdfae7ef2f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++// external.cxx -- externally driven flight model
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <math.h>
++
++#include "external.hxx"
++
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++
++
++// reset flight params to a specific position
++void fgExternalInit( FGInterface &f ) {
++}
++
++
++// update position based on inputs, positions, velocities, etc.
++void fgExternalUpdate( FGInterface& f, int multiloop ) {
++
++}
++
++
++// $Log$
++// Revision 1.5  1999/02/05 21:29:03  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.4  1999/02/01 21:33:32  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.3  1999/01/19 17:52:11  curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.2  1998/12/05 15:54:13  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.1  1998/12/04 01:28:49  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ba7023fdb09e24b4968f9eaec4f149eadff01e53
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,104 @@@
++// external.hxx -- the "external" flight model (driven from other
++//                 external input)
++//
++// Written by Curtis Olson, started December 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _EXTERNAL_HXX
++#define _EXTERNAL_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Time/fg_time.hxx>
++#include <Time/timestamp.hxx>
++
++
++/*
++class fgFDM_EXTERNAL {
++
++public:
++
++    // Time Stamp
++
++    // The time at which these values are correct (for extrapolating
++    // later frames between position updates)
++    FGTimeStamp t;
++
++    // Positions
++
++    // placement in geodetic coordinates
++    double Latitude;
++    double Longitude;
++    double Altitude;
++
++    // orientation in euler angles relative to local frame (or ground
++    // position)
++    double Phi;       // roll
++    double Theta;     // pitch
++    double Psi;       // heading
++
++    // Velocities
++
++    // velocities in geodetic coordinates
++    double Latitude_dot;   // rad/sec
++    double Longitude_dot;  // rad/sec
++    double Altitude_dot;   // feet/sec
++
++    // rotational rates
++    double Phi_dot;
++    double Theta_dot;
++    double Psi_dot;
++};
++*/
++
++
++// reset flight params to a specific position 
++void fgExternalInit( FGInterface& f );
++
++
++#endif // _EXTERNAL_HXX
++
++
++// $Log$
++// Revision 1.6  1999/02/05 21:29:04  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5  1999/01/19 17:52:12  curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.4  1999/01/09 13:37:37  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.3  1998/12/05 15:54:14  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2  1998/12/05 14:18:47  curt
++// added an fgTIMESTAMP to define when this record is valid.
++//
++// Revision 1.1  1998/12/04 01:28:49  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b8aa1dff0ea7f16726be002b349e2f7c02a9e9ba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,273 @@@
++// JSBsim.cxx -- interface to the JSBsim flight model
++//
++// Written by Curtis Olson, started February 1999.
++//
++// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/fg_geodesy.hxx>
++
++#include <FDM/JSBsim/FGFDMExec.h>
++#include <FDM/JSBsim/FGAircraft.h>
++#include <FDM/JSBsim/FGFCS.h>
++#include <FDM/JSBsim/FGPosition.h>
++#include <FDM/JSBsim/FGRotation.h>
++#include <FDM/JSBsim/FGState.h>
++#include <FDM/JSBsim/FGTranslation.h>
++
++#include "JSBsim.hxx"
++
++
++// The default aircraft
++FGFDMExec FDMExec;
++
++
++// Initialize the JSBsim flight model, dt is the time increment for
++// each subsequent iteration through the EOM
++int fgJSBsimInit(double dt) {
++    FG_LOG( FG_FLIGHT, FG_INFO, "Starting initializing JSBsim" );
++
++    FG_LOG( FG_FLIGHT, FG_INFO, "  created FDMExec" );
++
++    string aircraft_path = current_options.get_fg_root() + "/Aircraft";
++    string engine_path = current_options.get_fg_root() + "/Engine";
++
++    FDMExec.GetAircraft()->LoadAircraft(aircraft_path, engine_path, "X15");
++    FG_LOG( FG_FLIGHT, FG_INFO, "  loaded aircraft" );
++
++    FDMExec.GetState()->Reset(aircraft_path, "Reset00");
++    FG_LOG( FG_FLIGHT, FG_INFO, "  loaded initial conditions" );
++
++    FDMExec.GetState()->Setdt(dt);
++    FG_LOG( FG_FLIGHT, FG_INFO, "  set dt" );
++
++    FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBsim" );
++
++    return 1;
++}
++
++
++// Run an iteration of the EOM (equations of motion)
++int fgJSBsimUpdate(FGInterface& f, int multiloop) {
++    double save_alt = 0.0;
++
++    // lets try to avoid really screwing up the JSBsim model
++    if ( f.get_Altitude() < -9000 ) {
++      save_alt = f.get_Altitude();
++      f.set_Altitude( 0.0 );
++    }
++
++    // copy control positions into the JSBsim structure
++    FDMExec.GetFCS()->SetDa( controls.get_aileron() );
++    FDMExec.GetFCS()->SetDe( controls.get_elevator() 
++                           + controls.get_elevator_trim() );
++    FDMExec.GetFCS()->SetDr( controls.get_rudder() );
++    FDMExec.GetFCS()->SetDf( 0.0 );
++    FDMExec.GetFCS()->SetDs( 0.0 );
++    FDMExec.GetFCS()->SetThrottle( FGControls::ALL_ENGINES, 
++                                 controls.get_throttle( 0 ) );
++    // FCS->SetBrake( controls.get_brake( 0 ) );
++
++    // Inform JSBsim of the local terrain altitude
++    // Runway_altitude =   f.get_Runway_altitude();
++
++    // old -- FGInterface_2_JSBsim() not needed except for Init()
++    // translate FG to JSBsim structure
++    // FGInterface_2_JSBsim(f);
++    // printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048);
++    // printf("Altitude = %.2f\n", Altitude * 0.3048);
++    // printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048);
++
++    /* FDMExec.GetState()->Setsim_time(State->Getsim_time() 
++                                  + State->Getdt() * multiloop); */
++
++    for ( int i = 0; i < multiloop; i++ ) {
++      FDMExec.Run();
++    }
++
++    // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
++    // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
++    
++    // translate JSBsim back to FG structure so that the
++    // autopilot (and the rest of the sim can use the updated
++    // values
++
++    fgJSBsim_2_FGInterface(f);
++
++    // but lets restore our original bogus altitude when we are done
++    if ( save_alt < -9000.0 ) {
++      f.set_Altitude( save_alt );
++    }
++
++    return 1;
++}
++
++
++// Convert from the FGInterface struct to the JSBsim generic_ struct
++int FGInterface_2_JSBsim (FGInterface& f) {
++
++    return 1;
++}
++
++
++// Convert from the JSBsim generic_ struct to the FGInterface struct
++int fgJSBsim_2_FGInterface (FGInterface& f) {
++
++    // Velocities
++    f.set_Velocities_Local( FDMExec.GetPosition()->GetVn(), 
++                          FDMExec.GetPosition()->GetVe(), 
++                          FDMExec.GetPosition()->GetVd() );
++    // f.set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground, 
++    //                     V_down_rel_ground );
++    // f.set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
++    //                            V_down_airmass );
++    // f.set_Velocities_Local_Rel_Airmass( V_north_rel_airmass, 
++    //                          V_east_rel_airmass, V_down_rel_airmass );
++    // f.set_Velocities_Gust( U_gust, V_gust, W_gust );
++    // f.set_Velocities_Wind_Body( U_body, V_body, W_body );
++
++    // f.set_V_rel_wind( V_rel_wind );
++    // f.set_V_true_kts( V_true_kts );
++    // f.set_V_rel_ground( V_rel_ground );
++    // f.set_V_inertial( V_inertial );
++    // f.set_V_ground_speed( V_ground_speed );
++    // f.set_V_equiv( V_equiv );
++
++    /* ***FIXME*** */ f.set_V_equiv_kts( FDMExec.GetState()->GetVt() );
++    // f.set_V_calibrated( V_calibrated );
++    // f.set_V_calibrated_kts( V_calibrated_kts );
++
++    f.set_Omega_Body( FDMExec.GetRotation()->GetP(), 
++                    FDMExec.GetRotation()->GetQ(), 
++                    FDMExec.GetRotation()->GetR() );
++    // f.set_Omega_Local( P_local, Q_local, R_local );
++    // f.set_Omega_Total( P_total, Q_total, R_total );
++    
++    // f.set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
++    // ***FIXME*** f.set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
++
++    // Positions
++    double lat_geoc = FDMExec.GetState()->Getlatitude();
++    double lon = FDMExec.GetState()->Getlongitude();
++    double alt = FDMExec.GetState()->Geth();
++    double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc;
++    fgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER,
++                &lat_geod, &tmp_alt, &sl_radius1 );
++    fgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc );
++
++    FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod
++          << " lat_geoc = " << lat_geoc
++          << " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET
++          << " sl_radius1 = " << sl_radius1 * METER_TO_FEET
++          << " sl_radius2 = " << sl_radius2 * METER_TO_FEET
++          << " Equator = " << EQUATORIAL_RADIUS_FT );
++          
++    f.set_Geocentric_Position( lat_geoc, lon, 
++                             sl_radius2 * METER_TO_FEET + alt );
++    f.set_Geodetic_Position( lat_geod, lon, alt );
++    f.set_Euler_Angles( FDMExec.GetRotation()->Getphi(), 
++                      FDMExec.GetRotation()->Gettht(),
++                      FDMExec.GetRotation()->Getpsi() );
++
++    // Miscellaneous quantities
++    // f.set_T_Local_to_Body(T_local_to_body_m);
++    // f.set_Gravity( Gravity );
++    // f.set_Centrifugal_relief( Centrifugal_relief );
++
++    f.set_Alpha( FDMExec.GetTranslation()->Getalpha() );
++    f.set_Beta( FDMExec.GetTranslation()->Getbeta() );
++    // f.set_Alpha_dot( Alpha_dot );
++    // f.set_Beta_dot( Beta_dot );
++
++    // f.set_Cos_alpha( Cos_alpha );
++    // f.set_Sin_alpha( Sin_alpha );
++    // f.set_Cos_beta( Cos_beta );
++    // f.set_Sin_beta( Sin_beta );
++
++    // f.set_Cos_phi( Cos_phi );
++    // f.set_Sin_phi( Sin_phi );
++    // f.set_Cos_theta( Cos_theta );
++    // f.set_Sin_theta( Sin_theta );
++    // f.set_Cos_psi( Cos_psi );
++    // f.set_Sin_psi( Sin_psi );
++
++    // ***ATTENDTOME*** f.set_Gamma_vert_rad( Gamma_vert_rad );
++    // f.set_Gamma_horiz_rad( Gamma_horiz_rad );
++
++    // f.set_Sigma( Sigma );
++    // f.set_Density( Density );
++    // f.set_V_sound( V_sound );
++    // f.set_Mach_number( Mach_number );
++
++    // f.set_Static_pressure( Static_pressure );
++    // f.set_Total_pressure( Total_pressure );
++    // f.set_Impact_pressure( Impact_pressure );
++    // f.set_Dynamic_pressure( Dynamic_pressure );
++
++    // f.set_Static_temperature( Static_temperature );
++    // f.set_Total_temperature( Total_temperature );
++
++    /* **FIXME*** */ f.set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
++    /* **FIXME*** */ f.set_Earth_position_angle( 0.0 );
++
++    /* ***FIXME*** */ f.set_Runway_altitude( 0.0 );
++    // f.set_Runway_latitude( Runway_latitude );
++    // f.set_Runway_longitude( Runway_longitude );
++    // f.set_Runway_heading( Runway_heading );
++    // f.set_Radius_to_rwy( Radius_to_rwy );
++
++    // f.set_CG_Rwy_Local( D_cg_north_of_rwy, D_cg_east_of_rwy, D_cg_above_rwy);
++    // f.set_CG_Rwy_Rwy( X_cg_rwy, Y_cg_rwy, H_cg_rwy );
++    // f.set_Pilot_Rwy_Local( D_pilot_north_of_rwy, D_pilot_east_of_rwy, 
++    //                        D_pilot_above_rwy );
++    // f.set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy );
++
++    f.set_sin_lat_geocentric( lat_geoc );
++    f.set_cos_lat_geocentric( lat_geoc );
++    f.set_sin_cos_longitude( lon );
++    f.set_sin_cos_latitude( lat_geod );
++
++    return 0;
++}
++
++
++// $Log$
++// Revision 1.4  1999/04/03 04:20:01  curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.3  1999/02/26 22:09:10  curt
++// Added initial support for native SGI compilers.
++// Integrated Jon's next version of JSBsim.
++//
++// Revision 1.2  1999/02/11 21:09:40  curt
++// Interface with Jon's submitted JSBsim changes.
++//
++// Revision 1.1  1999/02/05 21:29:38  curt
++// Incorporating Jon S. Berndt's flight model code.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1901b2f6f52537f54a78f1e48dc42f5c59c81bb8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,56 @@@
++// JSBsim.hxx -- interface to the "JSBsim" flight model
++//
++// Written by Curtis Olson, started February 1999.
++//
++// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _JSBSIM_HXX
++#define _JSBSIM_HXX
++
++#include <FDM/JSBsim/FGFDMExec.h>
++#undef MAX_ENGINES
++
++#include <Aircraft/aircraft.hxx>
++
++
++// reset flight params to a specific position 
++int fgJSBsimInit(double dt);
++
++// update position based on inputs, positions, velocities, etc.
++int fgJSBsimUpdate(FGInterface& f, int multiloop);
++
++// Convert from the FGInterface struct to the JSBsim generic_ struct
++int FGInterface_2_JSBsim (FGInterface& f);
++
++// Convert from the JSBsim generic_ struct to the FGInterface struct
++int fgJSBsim_2_FGInterface (FGInterface& f);
++
++
++#endif // _JSBSIM_HXX
++
++
++// $Log$
++// Revision 1.2  1999/02/11 21:09:41  curt
++// Interface with Jon's submitted JSBsim changes.
++//
++// Revision 1.1  1999/02/05 21:29:38  curt
++// Incorporating Jon S. Berndt's flight model code.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b647f034006152081245ef400d4dff810bccb991
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,455 @@@
++// LaRCsim.cxx -- interface to the LaRCsim flight model
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include "LaRCsim.hxx"
++
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Debug/logstream.hxx>
++#include <FDM/flight.hxx>
++#include <FDM/LaRCsim/ls_cockpit.h>
++#include <FDM/LaRCsim/ls_generic.h>
++#include <FDM/LaRCsim/ls_interface.h>
++
++
++// Initialize the LaRCsim flight model, dt is the time increment for
++// each subsequent iteration through the EOM
++int fgLaRCsimInit(double dt) {
++    ls_toplevel_init(dt);
++
++    return(1);
++}
++
++
++// Run an iteration of the EOM (equations of motion)
++int fgLaRCsimUpdate(FGInterface& f, int multiloop) {
++    double save_alt = 0.0;
++
++    // lets try to avoid really screwing up the LaRCsim model
++    if ( f.get_Altitude() < -9000.0 ) {
++      save_alt = f.get_Altitude();
++      f.set_Altitude( 0.0 );
++    }
++
++    // copy control positions into the LaRCsim structure
++    Lat_control = controls.get_aileron();
++    Long_control = controls.get_elevator();
++    Long_trim = controls.get_elevator_trim();
++    Rudder_pedal = controls.get_rudder();
++    Throttle_pct = controls.get_throttle( 0 );
++    Brake_pct = controls.get_brake( 0 );
++
++    // Inform LaRCsim of the local terrain altitude
++    Runway_altitude =   f.get_Runway_altitude();
++
++    // old -- FGInterface_2_LaRCsim() not needed except for Init()
++    // translate FG to LaRCsim structure
++    // FGInterface_2_LaRCsim(f);
++    // printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048);
++    // printf("Altitude = %.2f\n", Altitude * 0.3048);
++    // printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048);
++
++    ls_update(multiloop);
++
++    // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
++    // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
++    
++    // translate LaRCsim back to FG structure so that the
++    // autopilot (and the rest of the sim can use the updated
++    // values
++    fgLaRCsim_2_FGInterface(f);
++
++    // but lets restore our original bogus altitude when we are done
++    if ( save_alt < -9000.0 ) {
++      f.set_Altitude( save_alt );
++    }
++
++    return 1;
++}
++
++
++// Convert from the FGInterface struct to the LaRCsim generic_ struct
++int FGInterface_2_LaRCsim (FGInterface& f) {
++
++    Mass =      f.get_Mass();
++    I_xx =      f.get_I_xx();
++    I_yy =      f.get_I_yy();
++    I_zz =      f.get_I_zz();
++    I_xz =      f.get_I_xz();
++    // Dx_pilot =  f.get_Dx_pilot();
++    // Dy_pilot =  f.get_Dy_pilot();
++    // Dz_pilot =  f.get_Dz_pilot();
++    Dx_cg =     f.get_Dx_cg();
++    Dy_cg =     f.get_Dy_cg();
++    Dz_cg =     f.get_Dz_cg();
++    // F_X =       f.get_F_X();
++    // F_Y =       f.get_F_Y();
++    // F_Z =       f.get_F_Z();
++    // F_north =   f.get_F_north();
++    // F_east =    f.get_F_east();
++    // F_down =    f.get_F_down();
++    // F_X_aero =  f.get_F_X_aero();
++    // F_Y_aero =  f.get_F_Y_aero();
++    // F_Z_aero =  f.get_F_Z_aero();
++    // F_X_engine =        f.get_F_X_engine();
++    // F_Y_engine =        f.get_F_Y_engine();
++    // F_Z_engine =        f.get_F_Z_engine();
++    // F_X_gear =  f.get_F_X_gear();
++    // F_Y_gear =  f.get_F_Y_gear();
++    // F_Z_gear =  f.get_F_Z_gear();
++    // M_l_rp =    f.get_M_l_rp();
++    // M_m_rp =    f.get_M_m_rp();
++    // M_n_rp =    f.get_M_n_rp();
++    // M_l_cg =    f.get_M_l_cg();
++    // M_m_cg =    f.get_M_m_cg();
++    // M_n_cg =    f.get_M_n_cg();
++    // M_l_aero =  f.get_M_l_aero();
++    // M_m_aero =  f.get_M_m_aero();
++    // M_n_aero =  f.get_M_n_aero();
++    // M_l_engine =        f.get_M_l_engine();
++    // M_m_engine =        f.get_M_m_engine();
++    // M_n_engine =        f.get_M_n_engine();
++    // M_l_gear =  f.get_M_l_gear();
++    // M_m_gear =  f.get_M_m_gear();
++    // M_n_gear =  f.get_M_n_gear();
++    // V_dot_north =       f.get_V_dot_north();
++    // V_dot_east =        f.get_V_dot_east();
++    // V_dot_down =        f.get_V_dot_down();
++    // U_dot_body =        f.get_U_dot_body();
++    // V_dot_body =        f.get_V_dot_body();
++    // W_dot_body =        f.get_W_dot_body();
++    // A_X_cg =    f.get_A_X_cg();
++    // A_Y_cg =    f.get_A_Y_cg();
++    // A_Z_cg =    f.get_A_Z_cg();
++    // A_X_pilot = f.get_A_X_pilot();
++    // A_Y_pilot = f.get_A_Y_pilot();
++    // A_Z_pilot = f.get_A_Z_pilot();
++    // N_X_cg =    f.get_N_X_cg();
++    // N_Y_cg =    f.get_N_Y_cg();
++    // N_Z_cg =    f.get_N_Z_cg();
++    // N_X_pilot = f.get_N_X_pilot();
++    // N_Y_pilot = f.get_N_Y_pilot();
++    // N_Z_pilot = f.get_N_Z_pilot();
++    // P_dot_body =        f.get_P_dot_body();
++    // Q_dot_body =        f.get_Q_dot_body();
++    // R_dot_body =        f.get_R_dot_body();
++    V_north =   f.get_V_north();
++    V_east =    f.get_V_east();
++    V_down =    f.get_V_down();
++    // V_north_rel_ground =        f.get_V_north_rel_ground();
++    // V_east_rel_ground = f.get_V_east_rel_ground();
++    // V_down_rel_ground = f.get_V_down_rel_ground();
++    // V_north_airmass =   f.get_V_north_airmass();
++    // V_east_airmass =    f.get_V_east_airmass();
++    // V_down_airmass =    f.get_V_down_airmass();
++    // V_north_rel_airmass =       f.get_V_north_rel_airmass();
++    // V_east_rel_airmass =        f.get_V_east_rel_airmass();
++    // V_down_rel_airmass =        f.get_V_down_rel_airmass();
++    // U_gust =    f.get_U_gust();
++    // V_gust =    f.get_V_gust();
++    // W_gust =    f.get_W_gust();
++    // U_body =    f.get_U_body();
++    // V_body =    f.get_V_body();
++    // W_body =    f.get_W_body();
++    // V_rel_wind =        f.get_V_rel_wind();
++    // V_true_kts =        f.get_V_true_kts();
++    // V_rel_ground =      f.get_V_rel_ground();
++    // V_inertial =        f.get_V_inertial();
++    // V_ground_speed =    f.get_V_ground_speed();
++    // V_equiv =   f.get_V_equiv();
++    // V_equiv_kts =       f.get_V_equiv_kts();
++    // V_calibrated =      f.get_V_calibrated();
++    // V_calibrated_kts =  f.get_V_calibrated_kts();
++    P_body =    f.get_P_body();
++    Q_body =    f.get_Q_body();
++    R_body =    f.get_R_body();
++    // P_local =   f.get_P_local();
++    // Q_local =   f.get_Q_local();
++    // R_local =   f.get_R_local();
++    // P_total =   f.get_P_total();
++    // Q_total =   f.get_Q_total();
++    // R_total =   f.get_R_total();
++    // Phi_dot =   f.get_Phi_dot();
++    // Theta_dot = f.get_Theta_dot();
++    // Psi_dot =   f.get_Psi_dot();
++    // Latitude_dot =      f.get_Latitude_dot();
++    // Longitude_dot =     f.get_Longitude_dot();
++    // Radius_dot =        f.get_Radius_dot();
++    Lat_geocentric =    f.get_Lat_geocentric();
++    Lon_geocentric =    f.get_Lon_geocentric();
++    Radius_to_vehicle = f.get_Radius_to_vehicle();
++    Latitude =  f.get_Latitude();
++    Longitude = f.get_Longitude();
++    Altitude =  f.get_Altitude();
++    Phi =       f.get_Phi();
++    Theta =     f.get_Theta();
++    Psi =       f.get_Psi();
++    // T_local_to_body_11 =        f.get_T_local_to_body_11();
++    // T_local_to_body_12 =        f.get_T_local_to_body_12();
++    // T_local_to_body_13 =        f.get_T_local_to_body_13();
++    // T_local_to_body_21 =        f.get_T_local_to_body_21();
++    // T_local_to_body_22 =        f.get_T_local_to_body_22();
++    // T_local_to_body_23 =        f.get_T_local_to_body_23();
++    // T_local_to_body_31 =        f.get_T_local_to_body_31();
++    // T_local_to_body_32 =        f.get_T_local_to_body_32();
++    // T_local_to_body_33 =        f.get_T_local_to_body_33();
++    // Gravity =   f.get_Gravity();
++    // Centrifugal_relief =        f.get_Centrifugal_relief();
++    // Alpha =     f.get_Alpha();
++    // Beta =      f.get_Beta();
++    // Alpha_dot = f.get_Alpha_dot();
++    // Beta_dot =  f.get_Beta_dot();
++    // Cos_alpha = f.get_Cos_alpha();
++    // Sin_alpha = f.get_Sin_alpha();
++    // Cos_beta =  f.get_Cos_beta();
++    // Sin_beta =  f.get_Sin_beta();
++    // Cos_phi =   f.get_Cos_phi();
++    // Sin_phi =   f.get_Sin_phi();
++    // Cos_theta = f.get_Cos_theta();
++    // Sin_theta = f.get_Sin_theta();
++    // Cos_psi =   f.get_Cos_psi();
++    // Sin_psi =   f.get_Sin_psi();
++    // Gamma_vert_rad =    f.get_Gamma_vert_rad();
++    // Gamma_horiz_rad =   f.get_Gamma_horiz_rad();
++    // Sigma =     f.get_Sigma();
++    // Density =   f.get_Density();
++    // V_sound =   f.get_V_sound();
++    // Mach_number =       f.get_Mach_number();
++    // Static_pressure =   f.get_Static_pressure();
++    // Total_pressure =    f.get_Total_pressure();
++    // Impact_pressure =   f.get_Impact_pressure();
++    // Dynamic_pressure =  f.get_Dynamic_pressure();
++    // Static_temperature =        f.get_Static_temperature();
++    // Total_temperature = f.get_Total_temperature();
++    Sea_level_radius =  f.get_Sea_level_radius();
++    Earth_position_angle =      f.get_Earth_position_angle();
++    Runway_altitude =   f.get_Runway_altitude();
++    // Runway_latitude =   f.get_Runway_latitude();
++    // Runway_longitude =  f.get_Runway_longitude();
++    // Runway_heading =    f.get_Runway_heading();
++    // Radius_to_rwy =     f.get_Radius_to_rwy();
++    // D_cg_north_of_rwy = f.get_D_cg_north_of_rwy();
++    // D_cg_east_of_rwy =  f.get_D_cg_east_of_rwy();
++    // D_cg_above_rwy =    f.get_D_cg_above_rwy();
++    // X_cg_rwy =  f.get_X_cg_rwy();
++    // Y_cg_rwy =  f.get_Y_cg_rwy();
++    // H_cg_rwy =  f.get_H_cg_rwy();
++    // D_pilot_north_of_rwy =      f.get_D_pilot_north_of_rwy();
++    // D_pilot_east_of_rwy =       f.get_D_pilot_east_of_rwy();
++    // D_pilot_above_rwy = f.get_D_pilot_above_rwy();
++    // X_pilot_rwy =       f.get_X_pilot_rwy();
++    // Y_pilot_rwy =       f.get_Y_pilot_rwy();
++    // H_pilot_rwy =       f.get_H_pilot_rwy();
++
++    return( 0 );
++}
++
++
++// Convert from the LaRCsim generic_ struct to the FGInterface struct
++int fgLaRCsim_2_FGInterface (FGInterface& f) {
++
++    // Mass properties and geometry values
++    f.set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz );
++    // f.set_Pilot_Location( Dx_pilot, Dy_pilot, Dz_pilot );
++    f.set_CG_Position( Dx_cg, Dy_cg, Dz_cg );
++
++    // Forces
++    // f.set_Forces_Body_Total( F_X, F_Y, F_Z );
++    // f.set_Forces_Local_Total( F_north, F_east, F_down );
++    // f.set_Forces_Aero( F_X_aero, F_Y_aero, F_Z_aero );
++    // f.set_Forces_Engine( F_X_engine, F_Y_engine, F_Z_engine );
++    // f.set_Forces_Gear( F_X_gear, F_Y_gear, F_Z_gear );
++
++    // Moments
++    // f.set_Moments_Total_RP( M_l_rp, M_m_rp, M_n_rp );
++    // f.set_Moments_Total_CG( M_l_cg, M_m_cg, M_n_cg );
++    // f.set_Moments_Aero( M_l_aero, M_m_aero, M_n_aero );
++    // f.set_Moments_Engine( M_l_engine, M_m_engine, M_n_engine );
++    // f.set_Moments_Gear( M_l_gear, M_m_gear, M_n_gear );
++
++    // Accelerations
++    // f.set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
++    // f.set_Accels_Body( U_dot_body, V_dot_body, W_dot_body );
++    // f.set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg );
++    // f.set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot );
++    // f.set_Accels_CG_Body_N( N_X_cg, N_Y_cg, N_Z_cg );
++    // f.set_Accels_Pilot_Body_N( N_X_pilot, N_Y_pilot, N_Z_pilot );
++    // f.set_Accels_Omega( P_dot_body, Q_dot_body, R_dot_body );
++
++    // Velocities
++    f.set_Velocities_Local( V_north, V_east, V_down );
++    // f.set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground, 
++    //                     V_down_rel_ground );
++    // f.set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
++    //                            V_down_airmass );
++    // f.set_Velocities_Local_Rel_Airmass( V_north_rel_airmass, 
++    //                          V_east_rel_airmass, V_down_rel_airmass );
++    // f.set_Velocities_Gust( U_gust, V_gust, W_gust );
++    // f.set_Velocities_Wind_Body( U_body, V_body, W_body );
++
++    // f.set_V_rel_wind( V_rel_wind );
++    // f.set_V_true_kts( V_true_kts );
++    // f.set_V_rel_ground( V_rel_ground );
++    // f.set_V_inertial( V_inertial );
++    // f.set_V_ground_speed( V_ground_speed );
++    // f.set_V_equiv( V_equiv );
++    f.set_V_equiv_kts( V_equiv_kts );
++    // f.set_V_calibrated( V_calibrated );
++    // f.set_V_calibrated_kts( V_calibrated_kts );
++
++    f.set_Omega_Body( P_body, Q_body, R_body );
++    // f.set_Omega_Local( P_local, Q_local, R_local );
++    // f.set_Omega_Total( P_total, Q_total, R_total );
++    
++    // f.set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
++    f.set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
++
++    FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude 
++          << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude 
++          << " alt = " << Altitude << " sl_radius = " << Sea_level_radius 
++          << " radius_to_vehicle = " << Radius_to_vehicle );
++          
++    // Positions
++    f.set_Geocentric_Position( Lat_geocentric, Lon_geocentric, 
++                               Radius_to_vehicle );
++    f.set_Geodetic_Position( Latitude, Longitude, Altitude );
++    f.set_Euler_Angles( Phi, Theta, Psi );
++
++    // Miscellaneous quantities
++    f.set_T_Local_to_Body(T_local_to_body_m);
++    // f.set_Gravity( Gravity );
++    // f.set_Centrifugal_relief( Centrifugal_relief );
++
++    f.set_Alpha( Alpha );
++    f.set_Beta( Beta );
++    // f.set_Alpha_dot( Alpha_dot );
++    // f.set_Beta_dot( Beta_dot );
++
++    // f.set_Cos_alpha( Cos_alpha );
++    // f.set_Sin_alpha( Sin_alpha );
++    // f.set_Cos_beta( Cos_beta );
++    // f.set_Sin_beta( Sin_beta );
++
++    // f.set_Cos_phi( Cos_phi );
++    // f.set_Sin_phi( Sin_phi );
++    // f.set_Cos_theta( Cos_theta );
++    // f.set_Sin_theta( Sin_theta );
++    // f.set_Cos_psi( Cos_psi );
++    // f.set_Sin_psi( Sin_psi );
++
++    f.set_Gamma_vert_rad( Gamma_vert_rad );
++    // f.set_Gamma_horiz_rad( Gamma_horiz_rad );
++
++    // f.set_Sigma( Sigma );
++    // f.set_Density( Density );
++    // f.set_V_sound( V_sound );
++    // f.set_Mach_number( Mach_number );
++
++    // f.set_Static_pressure( Static_pressure );
++    // f.set_Total_pressure( Total_pressure );
++    // f.set_Impact_pressure( Impact_pressure );
++    // f.set_Dynamic_pressure( Dynamic_pressure );
++
++    // f.set_Static_temperature( Static_temperature );
++    // f.set_Total_temperature( Total_temperature );
++
++    f.set_Sea_level_radius( Sea_level_radius );
++    f.set_Earth_position_angle( Earth_position_angle );
++
++    f.set_Runway_altitude( Runway_altitude );
++    // f.set_Runway_latitude( Runway_latitude );
++    // f.set_Runway_longitude( Runway_longitude );
++    // f.set_Runway_heading( Runway_heading );
++    // f.set_Radius_to_rwy( Radius_to_rwy );
++
++    // f.set_CG_Rwy_Local( D_cg_north_of_rwy, D_cg_east_of_rwy, D_cg_above_rwy);
++    // f.set_CG_Rwy_Rwy( X_cg_rwy, Y_cg_rwy, H_cg_rwy );
++    // f.set_Pilot_Rwy_Local( D_pilot_north_of_rwy, D_pilot_east_of_rwy, 
++    //                        D_pilot_above_rwy );
++    // f.set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy );
++
++    f.set_sin_lat_geocentric(Lat_geocentric);
++    f.set_cos_lat_geocentric(Lat_geocentric);
++    f.set_sin_cos_longitude(Longitude);
++    f.set_sin_cos_latitude(Latitude);
++
++    // printf("sin_lat_geo %f  cos_lat_geo %f\n", sin_Lat_geoc, cos_Lat_geoc);
++    // printf("sin_lat     %f  cos_lat     %f\n", 
++    //        f.get_sin_latitude(), f.get_cos_latitude());
++    // printf("sin_lon     %f  cos_lon     %f\n",
++    //        f.get_sin_longitude(), f.get_cos_longitude());
++
++    return 0;
++}
++
++
++// $Log$
++// Revision 1.12  1999/04/03 04:20:02  curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.11  1999/02/05 21:28:58  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.10  1999/02/01 21:33:30  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.9  1999/01/08 19:27:36  curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8  1998/12/18 23:37:06  curt
++// Collapsed out the FGState variables not currently needed.  They are just
++// commented out and can be readded easily at any time.  The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.7  1998/12/14 13:31:06  curt
++// LaRCsim maintains all it's variables internally.  I had been copying all of
++// them back and forth to the FG struture everytime I updated the flight model.
++// However, I have realized that this is not necessary.  I just need to copy
++// the control positions and environmental parameters into the LaRCsim structure
++// before updating the FDM, then copy every thing back out into the publick FGFS
++// structure afterwords.  This seems to solve (or at least help) a westward
++// drift problem some poeple had been observing.
++//
++// Revision 1.6  1998/12/05 15:54:08  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5  1998/12/03 04:25:02  curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.4  1998/12/03 01:16:37  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.3  1998/10/25 14:08:43  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2  1998/10/17 01:34:11  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/17 00:43:58  curt
++// Initial revision.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0231834c0b69c023722428a034e3c40aed79da9c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,65 @@@
++//*************************************************************************
++// LaRCsim.hxx -- interface to the "LaRCsim" flight model
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifndef _LARCSIM_HXX
++#define _LARCSIM_HXX
++
++
++#include "flight.hxx"
++
++
++// reset flight params to a specific position 
++int fgLaRCsimInit(double dt);
++
++// update position based on inputs, positions, velocities, etc.
++int fgLaRCsimUpdate(FGInterface& f, int multiloop);
++
++// Convert from the FGInterface struct to the LaRCsim generic_ struct
++int FGInterface_2_LaRCsim (FGInterface& f);
++
++// Convert from the LaRCsim generic_ struct to the FGInterface struct
++int fgLaRCsim_2_FGInterface (FGInterface& f);
++
++
++#endif // _LARCSIM_HXX
++
++
++// $Log$
++// Revision 1.5  1999/02/05 21:28:59  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.4  1998/12/05 15:54:09  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.3  1998/12/03 01:16:38  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.2  1998/10/17 01:34:13  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/17 00:43:58  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c876188badf9a33f5b155b9d577211c832629be5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++SUBDIRS       = External JSBsim LaRCsim Slew
++
++noinst_LIBRARIES = libFlight.a
++
++libFlight_a_SOURCES = flight.cxx flight.hxx \
++      JSBsim.cxx JSBsim.hxx \
++      LaRCsim.cxx LaRCsim.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
++
++DEFS += -DFGFS
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f173426876366280ec99e5fe1b18e8206ab554c3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,326 @@@
++// flight.c -- a general interface to the various flight models
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <stdio.h>
++
++#include <Debug/logstream.hxx>
++#include <FDM/External/external.hxx>
++#include <FDM/LaRCsim/ls_interface.h>
++#include <Include/fg_constants.h>
++#include <Math/fg_geodesy.hxx>
++#include <Time/timestamp.hxx>
++
++#include "flight.hxx"
++#include "JSBsim.hxx"
++#include "LaRCsim.hxx"
++
++
++// base_fdm_state is the internal state that is updated in integer
++// multiples of "dt".  This leads to "jitter" with respect to the real
++// world time, so we introduce cur_fdm_state which is extrapolated by
++// the difference between sim time and real world time
++
++FGInterface cur_fdm_state;
++FGInterface base_fdm_state;
++
++
++// Extrapolate fdm based on time_offset (in usec)
++void FGInterface::extrapolate( int time_offset ) {
++    double dt = time_offset / 1000000.0;
++    cout << "extrapolating FDM by dt = " << dt << endl;
++
++    double lat = geodetic_position_v[0] + geocentric_rates_v[0] * dt;
++    double lat_geoc = geocentric_position_v[0] + geocentric_rates_v[0] * dt;
++
++    double lon = geodetic_position_v[1] + geocentric_rates_v[1] * dt;
++    double lon_geoc = geocentric_position_v[1] + geocentric_rates_v[1] * dt;
++
++    double alt = geodetic_position_v[2] + geocentric_rates_v[2] * dt;
++    double radius = geocentric_position_v[2] + geocentric_rates_v[2] * dt;
++
++    geodetic_position_v[0] = lat;
++    geocentric_position_v[0] = lat_geoc;
++
++    geodetic_position_v[1] = lon;
++    geocentric_position_v[1] = lon_geoc;
++
++    geodetic_position_v[2] = alt;
++    geocentric_position_v[2] = radius;
++}
++
++
++// Initialize the flight model parameters
++int fgFDMInit(int model, FGInterface& f, double dt) {
++    double save_alt = 0.0;
++
++    FG_LOG( FG_FLIGHT ,FG_INFO, "Initializing flight model" );
++
++    base_fdm_state = f;
++
++    if ( model == FGInterface::FG_SLEW ) {
++      // fgSlewInit(dt);
++    } else if ( model == FGInterface::FG_JSBSIM ) {
++      fgJSBsimInit(dt);
++      fgJSBsim_2_FGInterface(base_fdm_state);
++    } else if ( model == FGInterface::FG_LARCSIM ) {
++      // lets try to avoid really screwing up the LaRCsim model
++      if ( base_fdm_state.get_Altitude() < -9000.0 ) {
++          save_alt = base_fdm_state.get_Altitude();
++          base_fdm_state.set_Altitude( 0.0 );
++      }
++
++      // translate FG to LaRCsim structure
++      FGInterface_2_LaRCsim(base_fdm_state);
++
++      // initialize LaRCsim
++      fgLaRCsimInit(dt);
++
++      FG_LOG( FG_FLIGHT, FG_INFO, "FG pos = " << 
++              base_fdm_state.get_Latitude() );
++
++      // translate LaRCsim back to FG structure
++      fgLaRCsim_2_FGInterface(base_fdm_state);
++
++      // but lets restore our original bogus altitude when we are done
++      if ( save_alt < -9000.0 ) {
++          base_fdm_state.set_Altitude( save_alt );
++      }
++    } else if ( model == FGInterface::FG_EXTERNAL ) {
++      fgExternalInit(base_fdm_state);
++    } else {
++      FG_LOG( FG_FLIGHT, FG_WARN,
++              "Unimplemented flight model == " << model );
++    }
++
++    // set valid time for this record
++    base_fdm_state.stamp_time();
++      
++    f = base_fdm_state;
++
++    return 1;
++}
++
++
++// Run multiloop iterations of the flight model
++int fgFDMUpdate(int model, FGInterface& f, int multiloop, int time_offset) {
++    double time_step, start_elev, end_elev;
++
++    // printf("Altitude = %.2f\n", FG_Altitude * 0.3048);
++
++    // set valid time for this record
++    base_fdm_state.stamp_time();
++
++    time_step = (1.0 / DEFAULT_MODEL_HZ) * multiloop;
++    start_elev = base_fdm_state.get_Altitude();
++
++    if ( model == FGInterface::FG_SLEW ) {
++      // fgSlewUpdate(f, multiloop);
++    } else if ( model == FGInterface::FG_JSBSIM ) {
++      fgJSBsimUpdate(base_fdm_state, multiloop);
++      f = base_fdm_state;
++    } else if ( model == FGInterface::FG_LARCSIM ) {
++      fgLaRCsimUpdate(base_fdm_state, multiloop);
++      // extrapolate position based on actual time
++      // f = extrapolate_fdm( base_fdm_state, time_offset );
++      f = base_fdm_state;
++    } else if ( model == FGInterface::FG_EXTERNAL ) {
++      // fgExternalUpdate(f, multiloop);
++      FGTimeStamp current;
++      current.stamp();
++      f = base_fdm_state;
++      f.extrapolate( current - base_fdm_state.get_time_stamp() );
++    } else {
++      FG_LOG( FG_FLIGHT, FG_WARN,
++              "Unimplemented flight model == " <<  model );
++    }
++
++    end_elev = base_fdm_state.get_Altitude();
++
++    if ( time_step > 0.0 ) {
++      // feet per second
++      base_fdm_state.set_Climb_Rate( (end_elev - start_elev) / time_step );
++    }
++
++    return 1;
++}
++
++
++// Set the altitude (force)
++void fgFDMForceAltitude(int model, double alt_meters) {
++    double sea_level_radius_meters;
++    double lat_geoc;
++
++    // Set the FG variables first
++    fgGeodToGeoc( base_fdm_state.get_Latitude(), alt_meters, 
++                &sea_level_radius_meters, &lat_geoc);
++
++    base_fdm_state.set_Altitude( alt_meters * METER_TO_FEET );
++    base_fdm_state.set_Radius_to_vehicle( base_fdm_state.get_Altitude() + 
++                                        (sea_level_radius_meters * 
++                                         METER_TO_FEET) );
++
++    // additional work needed for some flight models
++    if ( model == FGInterface::FG_LARCSIM ) {
++      ls_ForceAltitude( base_fdm_state.get_Altitude() );
++    }
++}
++
++
++// Set the local ground elevation
++void fgFDMSetGroundElevation(int model, double ground_meters) {
++    base_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET );
++    cur_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET );
++}
++
++
++// $Log$
++// Revision 1.17  1999/04/03 04:20:03  curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.16  1999/02/26 22:09:12  curt
++// Added initial support for native SGI compilers.
++// Integrated Jon's next version of JSBsim.
++//
++// Revision 1.15  1999/02/05 21:29:01  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.14  1999/02/01 21:33:31  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.13  1999/01/27 04:48:39  curt
++// Set the runway height in cur_fdm_state as well as base_fdm_state.
++//
++// Revision 1.12  1999/01/20 13:42:22  curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.11  1999/01/19 17:52:06  curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.10  1999/01/09 13:37:32  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.9  1999/01/08 19:27:37  curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8  1999/01/08 03:23:51  curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.7  1998/12/18 23:37:07  curt
++// Collapsed out the FGState variables not currently needed.  They are just
++// commented out and can be readded easily at any time.  The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.6  1998/12/05 15:54:11  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5  1998/12/04 01:29:39  curt
++// Stubbed in a new flight model called "External" which is expected to be driven
++// from some external source.
++//
++// Revision 1.4  1998/12/03 01:16:40  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.3  1998/11/06 21:18:03  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUGNDEBUG flag.
++//
++// Revision 1.2  1998/10/16 23:27:40  curt
++// C++-ifying.
++//
++// Revision 1.1  1998/10/16 20:16:41  curt
++// Renamed flight.[ch] to flight.[ch]xx
++//
++// Revision 1.19  1998/09/29 14:57:38  curt
++// c++-ified comments.
++//
++// Revision 1.18  1998/09/29 02:02:40  curt
++// Added a rate of climb calculation.
++//
++// Revision 1.17  1998/08/24 20:09:07  curt
++// .
++//
++// Revision 1.16  1998/08/22  14:49:55  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.15  1998/07/30 23:44:36  curt
++// Beginning to add support for multiple flight models.
++//
++// Revision 1.14  1998/07/12 03:08:27  curt
++// Added fgFlightModelSetAltitude() to force the altitude to something
++// other than the current altitude.  LaRCsim doesn't let you do this by just
++// changing FG_Altitude.
++//
++// Revision 1.13  1998/04/25 22:06:28  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.12  1998/04/21 16:59:33  curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.11  1998/04/18 04:14:04  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10  1998/02/07 15:29:37  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9  1998/01/27 00:47:53  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.8  1998/01/19 19:27:03  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.7  1998/01/19 18:40:23  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6  1998/01/19 18:35:43  curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.5  1997/12/30 20:47:37  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.4  1997/12/10 22:37:42  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3  1997/08/27 03:30:04  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2  1997/05/29 22:39:57  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.1  1997/05/29 02:35:04  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d73f37389ff2b42aa2a920e5d123af2be4affcb5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,978 @@@
++// flight.hxx -- define shared flight model parameters
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _FLIGHT_HXX
++#define _FLIGHT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++/* Required get_()
++
++   `FGInterface::get_Longitude ()'
++   `FGInterface::get_Latitude ()'
++   `FGInterface::get_Altitude ()'
++   `FGInterface::get_Phi ()'
++   `FGInterface::get_Theta ()'
++   `FGInterface::get_Psi ()'
++   `FGInterface::get_V_equiv_kts ()'
++
++   `FGInterface::get_Mass ()'
++   `FGInterface::get_I_xx ()'
++   `FGInterface::get_I_yy ()'
++   `FGInterface::get_I_zz ()'
++   `FGInterface::get_I_xz ()'
++   
++   `FGInterface::get_V_north ()'
++   `FGInterface::get_V_east ()'
++   `FGInterface::get_V_down ()'
++
++   `FGInterface::get_P_Body ()'
++   `FGInterface::get_Q_Body ()'
++   `FGInterface::get_R_Body ()'
++
++   `FGInterface::get_Gamma_vert_rad ()'
++   `FGInterface::get_Climb_Rate ()'
++   `FGInterface::get_Alpha ()'
++   `FGInterface::get_Beta ()'
++
++   `FGInterface::get_Runway_altitude ()'
++
++   `FGInterface::get_Lon_geocentric ()'
++   `FGInterface::get_Lat_geocentric ()'
++   `FGInterface::get_Sea_level_radius ()'
++   `FGInterface::get_Earth_position_angle ()'
++
++   `FGInterface::get_Latitude_dot()'
++   `FGInterface::get_Longitude_dot()'
++   `FGInterface::get_Radius_dot()'
++
++   `FGInterface::get_Dx_cg ()'
++   `FGInterface::get_Dy_cg ()'
++   `FGInterface::get_Dz_cg ()'
++
++   `FGInterface::get_T_local_to_body_11 ()' ... `FGInterface::get_T_local_to_body_33 ()'
++
++   `FGInterface::get_Radius_to_vehicle ()'
++
++ */
++
++
++#include <Time/timestamp.hxx>
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++typedef double FG_VECTOR_3[3];
++
++
++// This is based heavily on LaRCsim/ls_generic.h
++class FGInterface {
++
++public:
++
++    // Define the various supported flight models (many not yet implemented)
++    enum {
++      // Slew (in MS terminology)
++      FG_SLEW = 0,
++      
++      // The NASA LaRCsim (Navion) flight model
++      FG_LARCSIM = 1,
++
++      // Jon S. Berndt's new FDM written from the ground up in C++
++      FG_JSBSIM = 2,
++
++      // The following aren't implemented but are here to spark
++      // thoughts and discussions, and maybe even action.
++      FG_ACM = 3,
++      FG_SUPER_SONIC = 4,
++      FG_HELICOPTER = 5,
++      FG_AUTOGYRO = 6,
++      FG_BALLOON = 7,
++      FG_PARACHUTE = 8,
++
++      // Driven externally via a serial port, net, file, etc.
++      FG_EXTERNAL = 9
++    };
++
++/*================== Mass properties and geometry values ==================*/
++
++    // Inertias
++    double mass, i_xx, i_yy, i_zz, i_xz;
++    inline double get_Mass() const { return mass; }
++    inline double get_I_xx() const { return i_xx; }
++    inline double get_I_yy() const { return i_yy; }
++    inline double get_I_zz() const { return i_zz; }
++    inline double get_I_xz() const { return i_xz; }
++    inline void set_Inertias( double m, double xx, double yy, 
++                            double zz, double xz)
++    {
++      mass = m;
++      i_xx = xx;
++      i_yy = yy;
++      i_zz = zz;
++      i_xz = xz;
++    }
++    
++    // Pilot location rel to ref pt
++    FG_VECTOR_3 d_pilot_rp_body_v;
++    // inline double * get_D_pilot_rp_body_v() { 
++    //  return d_pilot_rp_body_v; 
++    // }
++    // inline double get_Dx_pilot() const { return d_pilot_rp_body_v[0]; }
++    // inline double get_Dy_pilot() const { return d_pilot_rp_body_v[1]; }
++    // inline double get_Dz_pilot() const { return d_pilot_rp_body_v[2]; }
++    /* inline void set_Pilot_Location( double dx, double dy, double dz ) {
++      d_pilot_rp_body_v[0] = dx;
++      d_pilot_rp_body_v[1] = dy;
++      d_pilot_rp_body_v[2] = dz;
++    } */
++
++    // CG position w.r.t. ref. point
++    FG_VECTOR_3 d_cg_rp_body_v;
++    // inline double * get_D_cg_rp_body_v() { return d_cg_rp_body_v; }
++    inline double get_Dx_cg() const { return d_cg_rp_body_v[0]; }
++    inline double get_Dy_cg() const { return d_cg_rp_body_v[1]; }
++    inline double get_Dz_cg() const { return d_cg_rp_body_v[2]; }
++    inline void set_CG_Position( double dx, double dy, double dz ) {
++      d_cg_rp_body_v[0] = dx;
++      d_cg_rp_body_v[1] = dy;
++      d_cg_rp_body_v[2] = dz;
++    }
++
++/*================================ Forces =================================*/
++
++    FG_VECTOR_3 f_body_total_v;
++    // inline double * get_F_body_total_v() { return f_body_total_v; }
++    // inline double get_F_X() const { return f_body_total_v[0]; }
++    // inline double get_F_Y() const { return f_body_total_v[1]; }
++    // inline double get_F_Z() const { return f_body_total_v[2]; }
++    /* inline void set_Forces_Body_Total( double x, double y, double z ) {
++      f_body_total_v[0] = x;
++      f_body_total_v[1] = y;
++      f_body_total_v[2] = z;
++    } */
++
++    FG_VECTOR_3 f_local_total_v;
++    // inline double * get_F_local_total_v() { return f_local_total_v; }
++    // inline double get_F_north() const { return f_local_total_v[0]; }
++    // inline double get_F_east() const { return f_local_total_v[1]; }
++    // inline double get_F_down() const { return f_local_total_v[2]; }
++    /* inline void set_Forces_Local_Total( double x, double y, double z ) {
++      f_local_total_v[0] = x;
++      f_local_total_v[1] = y;
++      f_local_total_v[2] = z;
++    } */
++
++    FG_VECTOR_3 f_aero_v;
++    // inline double * get_F_aero_v() { return f_aero_v; }
++    // inline double get_F_X_aero() const { return f_aero_v[0]; }
++    // inline double get_F_Y_aero() const { return f_aero_v[1]; }
++    // inline double get_F_Z_aero() const { return f_aero_v[2]; }
++    /* inline void set_Forces_Aero( double x, double y, double z ) {
++      f_aero_v[0] = x;
++      f_aero_v[1] = y;
++      f_aero_v[2] = z;
++    } */
++    
++    FG_VECTOR_3 f_engine_v;
++    // inline double * get_F_engine_v() { return f_engine_v; }
++    // inline double get_F_X_engine() const { return f_engine_v[0]; }
++    // inline double get_F_Y_engine() const { return f_engine_v[1]; }
++    // inline double get_F_Z_engine() const { return f_engine_v[2]; }
++    /* inline void set_Forces_Engine( double x, double y, double z ) {
++      f_engine_v[0] = x;
++      f_engine_v[1] = y;
++      f_engine_v[2] = z;
++    } */
++
++    FG_VECTOR_3 f_gear_v;
++    // inline double * get_F_gear_v() { return f_gear_v; }
++    // inline double get_F_X_gear() const { return f_gear_v[0]; }
++    // inline double get_F_Y_gear() const { return f_gear_v[1]; }
++    // inline double get_F_Z_gear() const { return f_gear_v[2]; }
++    /* inline void set_Forces_Gear( double x, double y, double z ) {
++      f_gear_v[0] = x;
++      f_gear_v[1] = y;
++      f_gear_v[2] = z;
++    } */
++
++    /*================================ Moments ================================*/
++
++    FG_VECTOR_3 m_total_rp_v;
++    // inline double * get_M_total_rp_v() { return m_total_rp_v; }
++    // inline double get_M_l_rp() const { return m_total_rp_v[0]; }
++    // inline double get_M_m_rp() const { return m_total_rp_v[1]; }
++    // inline double get_M_n_rp() const { return m_total_rp_v[2]; }
++    /* inline void set_Moments_Total_RP( double l, double m, double n ) {
++      m_total_rp_v[0] = l;
++      m_total_rp_v[1] = m;
++      m_total_rp_v[2] = n;
++    } */
++
++    FG_VECTOR_3 m_total_cg_v;
++    // inline double * get_M_total_cg_v() { return m_total_cg_v; }
++    // inline double get_M_l_cg() const { return m_total_cg_v[0]; }
++    // inline double get_M_m_cg() const { return m_total_cg_v[1]; }
++    // inline double get_M_n_cg() const { return m_total_cg_v[2]; }
++    /* inline void set_Moments_Total_CG( double l, double m, double n ) {
++      m_total_cg_v[0] = l;
++      m_total_cg_v[1] = m;
++      m_total_cg_v[2] = n;
++    } */
++
++    FG_VECTOR_3 m_aero_v;
++    // inline double * get_M_aero_v() { return m_aero_v; }
++    // inline double get_M_l_aero() const { return m_aero_v[0]; }
++    // inline double get_M_m_aero() const { return m_aero_v[1]; }
++    // inline double get_M_n_aero() const { return m_aero_v[2]; }
++    /* inline void set_Moments_Aero( double l, double m, double n ) {
++      m_aero_v[0] = l;
++      m_aero_v[1] = m;
++      m_aero_v[2] = n;
++    } */
++
++    FG_VECTOR_3    m_engine_v;
++    // inline double * get_M_engine_v() { return m_engine_v; }
++    // inline double get_M_l_engine() const { return m_engine_v[0]; }
++    // inline double get_M_m_engine() const { return m_engine_v[1]; }
++    // inline double get_M_n_engine() const { return m_engine_v[2]; }
++    /* inline void set_Moments_Engine( double l, double m, double n ) {
++      m_engine_v[0] = l;
++      m_engine_v[1] = m;
++      m_engine_v[2] = n;
++    } */
++
++    FG_VECTOR_3    m_gear_v;
++    // inline double * get_M_gear_v() { return m_gear_v; }
++    // inline double get_M_l_gear() const { return m_gear_v[0]; }
++    // inline double get_M_m_gear() const { return m_gear_v[1]; }
++    // inline double get_M_n_gear() const { return m_gear_v[2]; }
++    /* inline void set_Moments_Gear( double l, double m, double n ) {
++      m_gear_v[0] = l;
++      m_gear_v[1] = m;
++      m_gear_v[2] = n;
++    } */
++
++    /*============================== Accelerations ============================*/
++
++    FG_VECTOR_3    v_dot_local_v;
++    // inline double * get_V_dot_local_v() { return v_dot_local_v; }
++    // inline double get_V_dot_north() const { return v_dot_local_v[0]; }
++    // inline double get_V_dot_east() const { return v_dot_local_v[1]; }
++    // inline double get_V_dot_down() const { return v_dot_local_v[2]; }
++    /* inline void set_Accels_Local( double north, double east, double down ) {
++      v_dot_local_v[0] = north;
++      v_dot_local_v[1] = east;
++      v_dot_local_v[2] = down;
++    } */
++
++    FG_VECTOR_3    v_dot_body_v;
++    // inline double * get_V_dot_body_v() { return v_dot_body_v; }
++    // inline double get_U_dot_body() const { return v_dot_body_v[0]; }
++    // inline double get_V_dot_body() const { return v_dot_body_v[1]; }
++    // inline double get_W_dot_body() const { return v_dot_body_v[2]; }
++    /* inline void set_Accels_Body( double u, double v, double w ) {
++      v_dot_local_v[0] = u;
++      v_dot_local_v[1] = v;
++      v_dot_local_v[2] = w;
++    } */
++
++    FG_VECTOR_3    a_cg_body_v;
++    // inline double * get_A_cg_body_v() { return a_cg_body_v; }
++    // inline double get_A_X_cg() const { return a_cg_body_v[0]; }
++    // inline double get_A_Y_cg() const { return a_cg_body_v[1]; }
++    // inline double get_A_Z_cg() const { return a_cg_body_v[2]; }
++    /* inline void set_Accels_CG_Body( double x, double y, double z ) {
++      a_cg_body_v[0] = x;
++      a_cg_body_v[1] = y;
++      a_cg_body_v[2] = z;
++    } */
++
++    FG_VECTOR_3    a_pilot_body_v;
++    // inline double * get_A_pilot_body_v() { return a_pilot_body_v; }
++    // inline double get_A_X_pilot() const { return a_pilot_body_v[0]; }
++    // inline double get_A_Y_pilot() const { return a_pilot_body_v[1]; }
++    // inline double get_A_Z_pilot() const { return a_pilot_body_v[2]; }
++    /* inline void set_Accels_Pilot_Body( double x, double y, double z ) {
++      a_pilot_body_v[0] = x;
++      a_pilot_body_v[1] = y;
++      a_pilot_body_v[2] = z;
++    } */
++
++    FG_VECTOR_3    n_cg_body_v;
++    // inline double * get_N_cg_body_v() { return n_cg_body_v; }
++    // inline double get_N_X_cg() const { return n_cg_body_v[0]; }
++    // inline double get_N_Y_cg() const { return n_cg_body_v[1]; }
++    // inline double get_N_Z_cg() const { return n_cg_body_v[2]; }
++    /* inline void set_Accels_CG_Body_N( double x, double y, double z ) {
++      n_cg_body_v[0] = x;
++      n_cg_body_v[1] = y;
++      n_cg_body_v[2] = z;
++    } */
++
++    FG_VECTOR_3    n_pilot_body_v;
++    // inline double * get_N_pilot_body_v() { return n_pilot_body_v; }
++    // inline double get_N_X_pilot() const { return n_pilot_body_v[0]; }
++    // inline double get_N_Y_pilot() const { return n_pilot_body_v[1]; }
++    // inline double get_N_Z_pilot() const { return n_pilot_body_v[2]; }
++    /* inline void set_Accels_Pilot_Body_N( double x, double y, double z ) {
++      n_pilot_body_v[0] = x;
++      n_pilot_body_v[1] = y;
++      n_pilot_body_v[2] = z;
++    } */
++
++    FG_VECTOR_3    omega_dot_body_v;
++    // inline double * get_Omega_dot_body_v() { return omega_dot_body_v; }
++    // inline double get_P_dot_body() const { return omega_dot_body_v[0]; }
++    // inline double get_Q_dot_body() const { return omega_dot_body_v[1]; }
++    // inline double get_R_dot_body() const { return omega_dot_body_v[2]; }
++    /* inline void set_Accels_Omega( double p, double q, double r ) {
++      omega_dot_body_v[0] = p;
++      omega_dot_body_v[1] = q;
++      omega_dot_body_v[2] = r;
++    } */
++
++
++    /*============================== Velocities ===============================*/
++
++    FG_VECTOR_3    v_local_v;
++    // inline double * get_V_local_v() { return v_local_v; }
++    inline double get_V_north() const { return v_local_v[0]; }
++    inline double get_V_east() const { return v_local_v[1]; }
++    inline double get_V_down() const { return v_local_v[2]; }
++    inline void set_Velocities_Local( double north, double east, double down ) {
++      v_local_v[0] = north;
++      v_local_v[1] = east;
++      v_local_v[2] = down;
++    }
++
++    FG_VECTOR_3    v_local_rel_ground_v; // V rel w.r.t. earth surface  
++    // inline double * get_V_local_rel_ground_v() { return v_local_rel_ground_v; }
++    // inline double get_V_north_rel_ground() const {
++    //        return v_local_rel_ground_v[0];
++    //    }
++    // inline double get_V_east_rel_ground() const {
++    //        return v_local_rel_ground_v[1];
++    //    }
++    // inline double get_V_down_rel_ground() const {
++    //        return v_local_rel_ground_v[2];
++    //    }
++    /* inline void set_Velocities_Ground(double north, double east, double down) {
++      v_local_rel_ground_v[0] = north;
++      v_local_rel_ground_v[1] = east;
++      v_local_rel_ground_v[2] = down;
++    } */
++
++    FG_VECTOR_3    v_local_airmass_v;   // velocity of airmass (steady winds)
++    // inline double * get_V_local_airmass_v() { return v_local_airmass_v; }
++    // inline double get_V_north_airmass() const { return v_local_airmass_v[0]; }
++    // inline double get_V_east_airmass() const { return v_local_airmass_v[1]; }
++    // inline double get_V_down_airmass() const { return v_local_airmass_v[2]; }
++    /* inline void set_Velocities_Local_Airmass( double north, double east, 
++                                            double down)
++    {
++      v_local_airmass_v[0] = north;
++      v_local_airmass_v[1] = east;
++      v_local_airmass_v[2] = down;
++    } */
++
++    FG_VECTOR_3    v_local_rel_airmass_v;  // velocity of veh. relative to
++    // airmass
++    // inline double * get_V_local_rel_airmass_v() {
++      //return v_local_rel_airmass_v;
++    //}
++    // inline double get_V_north_rel_airmass() const {
++      //return v_local_rel_airmass_v[0];
++    //}
++    // inline double get_V_east_rel_airmass() const {
++      //return v_local_rel_airmass_v[1];
++    //}
++    // inline double get_V_down_rel_airmass() const {
++      //return v_local_rel_airmass_v[2];
++    //}
++    /* inline void set_Velocities_Local_Rel_Airmass( double north, double east, 
++                                                double down)
++    {
++      v_local_rel_airmass_v[0] = north;
++      v_local_rel_airmass_v[1] = east;
++      v_local_rel_airmass_v[2] = down;
++    } */
++
++    FG_VECTOR_3    v_local_gust_v; // linear turbulence components, L frame
++    // inline double * get_V_local_gust_v() { return v_local_gust_v; }
++    // inline double get_U_gust() const { return v_local_gust_v[0]; }
++    // inline double get_V_gust() const { return v_local_gust_v[1]; }
++    // inline double get_W_gust() const { return v_local_gust_v[2]; }
++    /* inline void set_Velocities_Gust( double u, double v, double w)
++    {
++      v_local_gust_v[0] = u;
++      v_local_gust_v[1] = v;
++      v_local_gust_v[2] = w;
++    } */
++    
++    FG_VECTOR_3    v_wind_body_v;  // Wind-relative velocities in body axis
++    // inline double * get_V_wind_body_v() { return v_wind_body_v; }
++    // inline double get_U_body() const { return v_wind_body_v[0]; }
++    // inline double get_V_body() const { return v_wind_body_v[1]; }
++    // inline double get_W_body() const { return v_wind_body_v[2]; }
++    /* inline void set_Velocities_Wind_Body( double u, double v, double w)
++    {
++      v_wind_body_v[0] = u;
++      v_wind_body_v[1] = v;
++      v_wind_body_v[2] = w;
++    } */
++
++    double    v_rel_wind, v_true_kts, v_rel_ground, v_inertial;
++    double    v_ground_speed, v_equiv, v_equiv_kts;
++    double    v_calibrated, v_calibrated_kts;
++
++    // inline double get_V_rel_wind() const { return v_rel_wind; }
++    // inline void set_V_rel_wind(double wind) { v_rel_wind = wind; }
++
++    // inline double get_V_true_kts() const { return v_true_kts; }
++    // inline void set_V_true_kts(double kts) { v_true_kts = kts; }
++
++    // inline double get_V_rel_ground() const { return v_rel_ground; }
++    // inline void set_V_rel_ground( double v ) { v_rel_ground = v; }
++
++    // inline double get_V_inertial() const { return v_inertial; }
++    // inline void set_V_inertial(double v) { v_inertial = v; }
++
++    // inline double get_V_ground_speed() const { return v_ground_speed; }
++    // inline void set_V_ground_speed( double v) { v_ground_speed = v; }
++
++    // inline double get_V_equiv() const { return v_equiv; }
++    // inline void set_V_equiv( double v ) { v_equiv = v; }
++
++    inline double get_V_equiv_kts() const { return v_equiv_kts; }
++    inline void set_V_equiv_kts( double kts ) { v_equiv_kts = kts; }
++
++    // inline double get_V_calibrated() const { return v_calibrated; }
++    // inline void set_V_calibrated( double v ) { v_calibrated = v; }
++
++    // inline double get_V_calibrated_kts() const { return v_calibrated_kts; }
++    // inline void set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; }
++
++    FG_VECTOR_3    omega_body_v;   // Angular B rates     
++    // inline double * get_Omega_body_v() { return omega_body_v; }
++    inline double get_P_body() const { return omega_body_v[0]; }
++    inline double get_Q_body() const { return omega_body_v[1]; }
++    inline double get_R_body() const { return omega_body_v[2]; }
++    inline void set_Omega_Body( double p, double q, double r ) {
++      omega_body_v[0] = p;
++      omega_body_v[1] = q;
++      omega_body_v[2] = r;
++    }
++
++    FG_VECTOR_3    omega_local_v;  // Angular L rates     
++    // inline double * get_Omega_local_v() { return omega_local_v; }
++    // inline double get_P_local() const { return omega_local_v[0]; }
++    // inline double get_Q_local() const { return omega_local_v[1]; }
++    // inline double get_R_local() const { return omega_local_v[2]; }
++    /* inline void set_Omega_Local( double p, double q, double r ) {
++      omega_local_v[0] = p;
++      omega_local_v[1] = q;
++      omega_local_v[2] = r;
++    } */
++
++    FG_VECTOR_3    omega_total_v;  // Diff btw B & L      
++    // inline double * get_Omega_total_v() { return omega_total_v; }
++    // inline double get_P_total() const { return omega_total_v[0]; }
++    // inline double get_Q_total() const { return omega_total_v[1]; }
++    // inline double get_R_total() const { return omega_total_v[2]; }
++    /* inline void set_Omega_Total( double p, double q, double r ) {
++      omega_total_v[0] = p;
++      omega_total_v[1] = q;
++      omega_total_v[2] = r;
++    } */
++
++    FG_VECTOR_3    euler_rates_v;
++    // inline double * get_Euler_rates_v() { return euler_rates_v; }
++    // inline double get_Phi_dot() const { return euler_rates_v[0]; }
++    // inline double get_Theta_dot() const { return euler_rates_v[1]; }
++    // inline double get_Psi_dot() const { return euler_rates_v[2]; }
++    /* inline void set_Euler_Rates( double phi, double theta, double psi ) {
++      euler_rates_v[0] = phi;
++      euler_rates_v[1] = theta;
++      euler_rates_v[2] = psi;
++    } */
++
++    FG_VECTOR_3    geocentric_rates_v;     // Geocentric linear velocities
++    // inline double * get_Geocentric_rates_v() { return geocentric_rates_v; }
++    inline double get_Latitude_dot() const { return geocentric_rates_v[0]; }
++    inline double get_Longitude_dot() const { return geocentric_rates_v[1]; }
++    inline double get_Radius_dot() const { return geocentric_rates_v[2]; }
++    inline void set_Geocentric_Rates( double lat, double lon, double rad ) {
++      geocentric_rates_v[0] = lat;
++      geocentric_rates_v[1] = lon;
++      geocentric_rates_v[2] = rad;
++    }
++    
++    /*=============================== Positions ===============================*/
++
++    FG_VECTOR_3    geocentric_position_v;
++    // inline double * get_Geocentric_position_v() {
++    //    return geocentric_position_v;
++    // }
++    inline double get_Lat_geocentric() const {
++      return geocentric_position_v[0];
++    }
++    inline double get_Lon_geocentric() const { 
++      return geocentric_position_v[1];
++    }
++    inline double get_Radius_to_vehicle() const {
++      return geocentric_position_v[2];
++    }
++    inline void set_Radius_to_vehicle(double radius) {
++      geocentric_position_v[2] = radius;
++    }
++
++    inline void set_Geocentric_Position( double lat, double lon, double rad ) {
++      geocentric_position_v[0] = lat;
++      geocentric_position_v[1] = lon;
++      geocentric_position_v[2] = rad;
++    }
++
++    FG_VECTOR_3    geodetic_position_v;
++    // inline double * get_Geodetic_position_v() { return geodetic_position_v; }
++    inline double get_Latitude() const { return geodetic_position_v[0]; }
++    inline void set_Latitude(double lat) { geodetic_position_v[0] = lat; }
++    inline double get_Longitude() const { return geodetic_position_v[1]; }
++    inline void set_Longitude(double lon) { geodetic_position_v[1] = lon; }
++    inline double get_Altitude() const { return geodetic_position_v[2]; }
++    inline void set_Altitude(double altitude) {
++      geodetic_position_v[2] = altitude;
++    }
++    inline void set_Geodetic_Position( double lat, double lon, double alt ) {
++      geodetic_position_v[0] = lat;
++      geodetic_position_v[1] = lon;
++      geodetic_position_v[2] = alt;
++    }
++
++    FG_VECTOR_3 euler_angles_v;
++    // inline double * get_Euler_angles_v() { return euler_angles_v; }
++    inline double get_Phi() const { return euler_angles_v[0]; }
++    inline double get_Theta() const { return euler_angles_v[1]; }
++    inline double get_Psi() const { return euler_angles_v[2]; }
++    inline void set_Euler_Angles( double phi, double theta, double psi ) {
++      euler_angles_v[0] = phi;
++      euler_angles_v[1] = theta;
++      euler_angles_v[2] = psi;
++    }
++
++
++    /*======================= Miscellaneous quantities ========================*/
++
++    double    t_local_to_body_m[3][3];    // Transformation matrix L to B
++    // inline double * get_T_local_to_body_m() { return t_local_to_body_m; }
++    inline double get_T_local_to_body_11() const {
++      return t_local_to_body_m[0][0];
++    }
++    inline double get_T_local_to_body_12() const {
++      return t_local_to_body_m[0][1];
++    }
++    inline double get_T_local_to_body_13() const {
++      return t_local_to_body_m[0][2];
++    }
++    inline double get_T_local_to_body_21() const {
++      return t_local_to_body_m[1][0];
++    }
++    inline double get_T_local_to_body_22() const {
++      return t_local_to_body_m[1][1];
++    }
++    inline double get_T_local_to_body_23() const {
++      return t_local_to_body_m[1][2];
++    }
++    inline double get_T_local_to_body_31() const {
++      return t_local_to_body_m[2][0];
++    }
++    inline double get_T_local_to_body_32() const {
++      return t_local_to_body_m[2][1];
++    }
++    inline double get_T_local_to_body_33() const {
++      return t_local_to_body_m[2][2];
++    }
++    inline void set_T_Local_to_Body( double m[3][3] ) {
++      int i, j;
++      for ( i = 0; i < 3; i++ ) {
++          for ( j = 0; j < 3; j++ ) {
++              t_local_to_body_m[i][j] = m[i][j];
++          }
++      }
++    }
++
++    double    gravity;            // Local acceleration due to G 
++    // inline double get_Gravity() const { return gravity; }
++    // inline void set_Gravity(double g) { gravity = g; }
++    
++    double    centrifugal_relief; // load factor reduction due to speed
++    // inline double get_Centrifugal_relief() const { return centrifugal_relief; }
++    // inline void set_Centrifugal_relief(double cr) { centrifugal_relief = cr; }
++
++    double    alpha, beta, alpha_dot, beta_dot;   // in radians  
++    inline double get_Alpha() const { return alpha; }
++    inline void set_Alpha( double a ) { alpha = a; }
++    inline double get_Beta() const { return beta; }
++    inline void set_Beta( double b ) { beta = b; }
++    // inline double get_Alpha_dot() const { return alpha_dot; }
++    // inline void set_Alpha_dot( double ad ) { alpha_dot = ad; }
++    // inline double get_Beta_dot() const { return beta_dot; }
++    // inline void set_Beta_dot( double bd ) { beta_dot = bd; }
++
++    double    cos_alpha, sin_alpha, cos_beta, sin_beta;
++    // inline double get_Cos_alpha() const { return cos_alpha; }
++    // inline void set_Cos_alpha( double ca ) { cos_alpha = ca; }
++    // inline double get_Sin_alpha() const { return sin_alpha; }
++    // inline void set_Sin_alpha( double sa ) { sin_alpha = sa; }
++    // inline double get_Cos_beta() const { return cos_beta; }
++    // inline void set_Cos_beta( double cb ) { cos_beta = cb; }
++    // inline double get_Sin_beta() const { return sin_beta; }
++    // inline void set_Sin_beta( double sb ) { sin_beta = sb; }
++
++    double    cos_phi, sin_phi, cos_theta, sin_theta, cos_psi, sin_psi;
++    // inline double get_Cos_phi() const { return cos_phi; }
++    // inline void set_Cos_phi( double cp ) { cos_phi = cp; }
++    // inline double get_Sin_phi() const { return sin_phi; }
++    // inline void set_Sin_phi( double sp ) { sin_phi = sp; }
++    // inline double get_Cos_theta() const { return cos_theta; }
++    // inline void set_Cos_theta( double ct ) { cos_theta = ct; }
++    // inline double get_Sin_theta() const { return sin_theta; }
++    // inline void set_Sin_theta( double st ) { sin_theta = st; }
++    // inline double get_Cos_psi() const { return cos_psi; }
++    // inline void set_Cos_psi( double cp ) { cos_psi = cp; }
++    // inline double get_Sin_psi() const { return sin_psi; }
++    // inline void set_Sin_psi( double sp ) { sin_psi = sp; }
++
++    double    gamma_vert_rad, gamma_horiz_rad;    // Flight path angles  
++    inline double get_Gamma_vert_rad() const { return gamma_vert_rad; }
++    inline void set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; }
++    // inline double get_Gamma_horiz_rad() const { return gamma_horiz_rad; }
++    // inline void set_Gamma_horiz_rad( double gh ) { gamma_horiz_rad = gh; }
++
++    double    sigma, density, v_sound, mach_number;
++    // inline double get_Sigma() const { return sigma; }
++    // inline void set_Sigma( double s ) { sigma = s; }
++    // inline double get_Density() const { return density; }
++    // inline void set_Density( double d ) { density = d; }
++    // inline double get_V_sound() const { return v_sound; }
++    // inline void set_V_sound( double v ) { v_sound = v; }
++    // inline double get_Mach_number() const { return mach_number; }
++    // inline void set_Mach_number( double m ) { mach_number = m; }
++
++    double    static_pressure, total_pressure, impact_pressure;
++    double    dynamic_pressure;
++    // inline double get_Static_pressure() const { return static_pressure; }
++    // inline void set_Static_pressure( double sp ) { static_pressure = sp; }
++    // inline double get_Total_pressure() const { return total_pressure; }
++    // inline void set_Total_pressure( double tp ) { total_pressure = tp; }
++    // inline double get_Impact_pressure() const { return impact_pressure; }
++    // inline void set_Impact_pressure( double ip ) { impact_pressure = ip; }
++    // inline double get_Dynamic_pressure() const { return dynamic_pressure; }
++    // inline void set_Dynamic_pressure( double dp ) { dynamic_pressure = dp; }
++
++    double    static_temperature, total_temperature;
++    // inline double get_Static_temperature() const { return static_temperature; }
++    // inline void set_Static_temperature( double t ) { static_temperature = t; }
++    // inline double get_Total_temperature() const { return total_temperature; }
++    // inline void set_Total_temperature( double t ) { total_temperature = t; }
++
++    double    sea_level_radius, earth_position_angle;
++    inline double get_Sea_level_radius() const { return sea_level_radius; }
++    inline void set_Sea_level_radius( double r ) { sea_level_radius = r; }
++    inline double get_Earth_position_angle() const {
++      return earth_position_angle;
++    }
++    inline void set_Earth_position_angle(double a) { 
++      earth_position_angle = a;
++    }
++
++    double    runway_altitude, runway_latitude, runway_longitude;
++    double    runway_heading;
++    inline double get_Runway_altitude() const { return runway_altitude; }
++    inline void set_Runway_altitude( double alt ) { runway_altitude = alt; }
++    // inline double get_Runway_latitude() const { return runway_latitude; }
++    // inline void set_Runway_latitude( double lat ) { runway_latitude = lat; }
++    // inline double get_Runway_longitude() const { return runway_longitude; }
++    // inline void set_Runway_longitude( double lon ) { runway_longitude = lon; }
++    // inline double get_Runway_heading() const { return runway_heading; }
++    // inline void set_Runway_heading( double h ) { runway_heading = h; }
++
++    double    radius_to_rwy;
++    // inline double get_Radius_to_rwy() const { return radius_to_rwy; }
++    // inline void set_Radius_to_rwy( double r ) { radius_to_rwy = r; }
++
++    FG_VECTOR_3    d_cg_rwy_local_v;       // CG rel. to rwy in local coords
++    // inline double * get_D_cg_rwy_local_v() { return d_cg_rwy_local_v; }
++    // inline double get_D_cg_north_of_rwy() const { return d_cg_rwy_local_v[0]; }
++    // inline double get_D_cg_east_of_rwy() const { return d_cg_rwy_local_v[1]; }
++    // inline double get_D_cg_above_rwy() const { return d_cg_rwy_local_v[2]; }
++    /* inline void set_CG_Rwy_Local( double north, double east, double above )
++    {
++      d_cg_rwy_local_v[0] = north;
++      d_cg_rwy_local_v[1] = east;
++      d_cg_rwy_local_v[2] = above;
++    } */
++
++    FG_VECTOR_3    d_cg_rwy_rwy_v; // CG relative to rwy, in rwy coordinates
++    // inline double * get_D_cg_rwy_rwy_v() { return d_cg_rwy_rwy_v; }
++    // inline double get_X_cg_rwy() const { return d_cg_rwy_rwy_v[0]; }
++    // inline double get_Y_cg_rwy() const { return d_cg_rwy_rwy_v[1]; }
++    // inline double get_H_cg_rwy() const { return d_cg_rwy_rwy_v[2]; }
++    /* inline void set_CG_Rwy_Rwy( double x, double y, double h )
++    {
++      d_cg_rwy_rwy_v[0] = x;
++      d_cg_rwy_rwy_v[1] = y;
++      d_cg_rwy_rwy_v[2] = h;
++    } */
++
++    FG_VECTOR_3    d_pilot_rwy_local_v;  // pilot rel. to rwy in local coords
++    // inline double * get_D_pilot_rwy_local_v() { return d_pilot_rwy_local_v; }
++    // inline double get_D_pilot_north_of_rwy() const {
++      //return d_pilot_rwy_local_v[0];
++  //  }
++    // inline double get_D_pilot_east_of_rwy() const {
++//    return d_pilot_rwy_local_v[1];
++//    }
++    // inline double get_D_pilot_above_rwy() const {
++      //return d_pilot_rwy_local_v[2];
++ //   }
++    /* inline void set_Pilot_Rwy_Local( double north, double east, double above )
++    {
++      d_pilot_rwy_local_v[0] = north;
++      d_pilot_rwy_local_v[1] = east;
++      d_pilot_rwy_local_v[2] = above;
++    } */
++
++    FG_VECTOR_3   d_pilot_rwy_rwy_v;   // pilot rel. to rwy, in rwy coords.
++    // inline double * get_D_pilot_rwy_rwy_v() { return d_pilot_rwy_rwy_v; }
++    // inline double get_X_pilot_rwy() const { return d_pilot_rwy_rwy_v[0]; }
++    // inline double get_Y_pilot_rwy() const { return d_pilot_rwy_rwy_v[1]; }
++    // inline double get_H_pilot_rwy() const { return d_pilot_rwy_rwy_v[2]; }
++    /* inline void set_Pilot_Rwy_Rwy( double x, double y, double h )
++    {
++      d_pilot_rwy_rwy_v[0] = x;
++      d_pilot_rwy_rwy_v[1] = y;
++      d_pilot_rwy_rwy_v[2] = h;
++    } */
++
++    double        climb_rate;           // in feet per second
++    inline double get_Climb_Rate() const { return climb_rate; }
++    inline void set_Climb_Rate(double rate) { climb_rate = rate; }
++
++    FGTimeStamp valid_stamp;       // time this record is valid
++    FGTimeStamp next_stamp;       // time this record is valid
++    inline FGTimeStamp get_time_stamp() const { return valid_stamp; }
++    inline void stamp_time() { valid_stamp = next_stamp; next_stamp.stamp(); }
++
++    // Extrapolate FDM based on time_offset (in usec)
++    void extrapolate( int time_offset );
++
++    // sin/cos lat_geocentric
++    double sin_lat_geocentric;
++    double cos_lat_geocentric;
++    inline void set_sin_lat_geocentric(double parm) {
++      sin_lat_geocentric = sin(parm);
++    }
++    inline void set_cos_lat_geocentric(double parm) {
++      cos_lat_geocentric = cos(parm);
++    }
++    inline double get_sin_lat_geocentric(void) const {
++      return sin_lat_geocentric;
++    }
++    inline double get_cos_lat_geocentric(void) const {
++      return cos_lat_geocentric;
++    }
++
++    double sin_longitude;
++    double cos_longitude;
++    inline void set_sin_cos_longitude(double parm) {
++      sin_longitude = sin(parm);
++      cos_longitude = cos(parm);
++    }
++    inline double get_sin_longitude(void) const {
++      return sin_longitude;
++    }
++    inline double get_cos_longitude(void) const {
++      return cos_longitude;
++    }
++      
++    double sin_latitude;
++    double cos_latitude;
++    inline void set_sin_cos_latitude(double parm) {
++      sin_latitude = sin(parm);
++      cos_latitude = cos(parm);
++    }
++    inline double get_sin_latitude(void) const {
++      return sin_latitude;
++    }
++    inline double get_cos_latitude(void) const {
++      return cos_latitude;
++    }
++};
++
++
++extern FGInterface cur_fdm_state;
++
++
++// General interface to the flight model routines
++
++// Initialize the flight model parameters
++int fgFDMInit(int model, FGInterface& f, double dt);
++
++// Run multiloop iterations of the flight model
++int fgFDMUpdate(int model, FGInterface& f, int multiloop, int jitter);
++
++// Set the altitude (force)
++void fgFDMForceAltitude(int model, double alt_meters);
++
++// Set the local ground elevation
++void fgFDMSetGroundElevation(int model, double alt_meters);
++
++
++#endif // _FLIGHT_HXX
++
++
++// $Log$
++// Revision 1.14  1999/04/03 04:20:04  curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.13  1999/02/05 21:29:02  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.12  1999/01/20 13:42:23  curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.11  1999/01/19 17:52:07  curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.10  1999/01/09 13:37:33  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.9  1999/01/08 19:27:38  curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8  1999/01/08 03:23:52  curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.7  1998/12/18 23:37:09  curt
++// Collapsed out the FGState variables not currently needed.  They are just
++// commented out and can be readded easily at any time.  The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.6  1998/12/05 15:54:12  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5  1998/12/04 01:29:40  curt
++// Stubbed in a new flight model called "External" which is expected to be driven
++// from some external source.
++//
++// Revision 1.4  1998/12/03 04:25:03  curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.3  1998/12/03 01:16:41  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.2  1998/10/16 23:27:41  curt
++// C++-ifying.
++//
++// Revision 1.1  1998/10/16 20:16:44  curt
++// Renamed flight.[ch] to flight.[ch]xx
++//
++// Revision 1.20  1998/09/29 14:57:39  curt
++// c++-ified comments.
++//
++// Revision 1.19  1998/09/29 02:02:41  curt
++// Added a rate of climb calculation.
++//
++// Revision 1.18  1998/07/30 23:44:36  curt
++// Beginning to add support for multiple flight models.
++//
++// Revision 1.17  1998/07/12 03:08:28  curt
++// Added fgFlightModelSetAltitude() to force the altitude to something
++// other than the current altitude.  LaRCsim doesn't let you do this by just
++// changing FG_Altitude.
++//
++// Revision 1.16  1998/04/22 13:26:20  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.15  1998/04/21 16:59:33  curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.14  1998/02/07 15:29:37  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.13  1998/01/24 00:04:59  curt
++// misc. tweaks.
++//
++// Revision 1.12  1998/01/22 02:59:32  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.11  1998/01/19 19:27:03  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.10  1997/12/10 22:37:43  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.9  1997/09/04 02:17:33  curt
++// Shufflin' stuff.
++//
++// Revision 1.8  1997/08/27 03:30:06  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.7  1997/07/23 21:52:19  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.6  1997/06/21 17:52:22  curt
++// Continue directory shuffling ... everything should be compilable/runnable
++// again.
++//
++// Revision 1.5  1997/06/21 17:12:49  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.4  1997/05/29 22:39:57  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.3  1997/05/29 02:32:25  curt
++// Starting to build generic flight model interface.
++//
++// Revision 1.2  1997/05/23 15:40:37  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 16:04:45  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b2b473bd5c3ac8a7af384edb5ef6d4413573727e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++if ENABLE_XMESA_FX                                                              
++DEFS += -DXMESA -DFX
++endif                                                                           
++                                                                                
++noinst_LIBRARIES = libGUI.a
++
++libGUI_a_SOURCES = gui.cxx gui.h
++
++INCLUDES += -I$(top_builddir) \
++      -I$(top_builddir)/Lib \
++      -I$(top_builddir)/Lib/plib/include \
++      -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d2869f812c8298375f6bef9b966e83a38c99bd23
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,242 @@@
++/**************************************************************************
++ * gui.cxx
++ *
++ * Written 1998 by Durk Talsma, started Juni, 1998.  For the flight gear
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#endif
++
++#include <Include/compiler.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++#  include <GL/xmesa.h>
++#endif
++
++#include STL_STRING
++
++#include <stdlib.h>
++#include <string.h>
++
++#include <Include/general.hxx>
++#include <Main/options.hxx>
++
++#include "gui.h"
++
++FG_USING_STD(string);
++
++
++puMenuBar    *mainMenuBar;
++puButton     *hideMenuButton;
++puDialogBox  *dialogBox;
++puText       *dialogBoxMessage;
++puOneShot    *dialogBoxOkButton;
++puText       *timerText;
++
++/* --------------------------------------------------------------------
++       Mouse stuff 
++  ---------------------------------------------------------------------*/
++
++void guiMotionFunc ( int x, int y )
++{
++  puMouse ( x, y ) ;
++  glutPostRedisplay () ;
++}
++
++
++void guiMouseFunc(int button, int updown, int x, int y)
++{
++    puMouse (button, updown, x,y);
++    glutPostRedisplay ();
++}
++
++/* -----------------------------------------------------------------------
++  the Gui callback functions 
++  ____________________________________________________________________*/
++
++void hideMenuCb (puObject *cb)
++{
++  if (cb -> getValue () )
++    {
++      mainMenuBar -> reveal();
++      printf("Showing Menu");
++      hideMenuButton -> setLegend ("Hide Menu");
++    }
++  else
++    {
++      mainMenuBar -> hide  ();
++      printf("Hiding Menu");
++      hideMenuButton -> setLegend ("Show Menu");
++    }
++}
++
++ void goAwayCb (puObject *)
++{
++  delete dialogBox;
++  dialogBox = NULL;
++}
++
++void mkDialog (char *txt)
++{
++  dialogBox = new puDialogBox (150, 50);
++  {
++    new puFrame (0,0,400, 100);
++    dialogBoxMessage =   new puText         (10, 70);
++    dialogBoxMessage ->  setLabel           (txt);
++    dialogBoxOkButton =  new puOneShot      (180, 10, 240, 50);
++    dialogBoxOkButton -> setLegend          ("OK");
++    dialogBoxOkButton -> makeReturnDefault  (TRUE );
++    dialogBoxOkButton -> setCallback        (goAwayCb);
++  }
++  dialogBox -> close();
++  dialogBox -> reveal();
++}
++
++void notCb (puObject *)
++{
++  mkDialog ("This function isn't implemented yet");
++}
++
++void helpCb (puObject *)
++{
++#if defined(FX) && !defined(WIN32)
++#  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
++    if ( global_fullscreen ) {
++      global_fullscreen = false;
++      XMesaSetFXmode( XMESA_FX_WINDOW );
++    }
++#  endif
++#endif
++
++#if !defined(WIN32)
++    string url = "http://www.flightgear.org/Docs/InstallGuide/getstart.html";
++    string command;
++
++    if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
++      command = "netscape -remote \"openURL(" + url + ")\" &";
++    } else {
++      command = "netscape " + url + " &";
++    }
++
++    system( command.c_str() );
++    string text = "Help started in netscape window.";
++#else
++    string text = "Help not yet implimented for Win32.";
++#endif
++
++    mkDialog ( (char*)text.c_str() );
++}
++
++/* -----------------------------------------------------------------------
++   The menu stuff 
++   ---------------------------------------------------------------------*/
++char *fileSubmenu        [] = { "Exit", "Close", "---------", "Print", "---------", "Save", "New", NULL };
++char *editSubmenu        [] = { "Edit text", NULL };
++char *viewSubmenu        [] = { "Cockpit View > ", "View >","------------", "View options...", NULL };
++char *aircraftSubmenu    [] = { "Autopilot ...", "Engine ...", "Navigation", "Communication", NULL};
++char *environmentSubmenu [] = { "Time & Date...", "Terrain ...", "Weather", NULL};
++char *optionsSubmenu     [] = { "Preferences", "Realism & Reliablity...", NULL};
++char *helpSubmenu        [] = { "About...", "Help", NULL };
++
++puCallback fileSubmenuCb        [] = { notCb, notCb, NULL, notCb, NULL, notCb, notCb, NULL};
++puCallback editSubmenuCb        [] = { notCb, NULL };
++puCallback viewSubmenuCb        [] = { notCb, notCb, NULL, notCb, NULL };
++puCallback aircraftSubmenuCb    [] = { notCb, notCb, notCb,notCb, NULL };
++puCallback environmentSubmenuCb [] = { notCb, notCb, notCb, NULL };
++puCallback optionsSubmenuCb     [] = { notCb, notCb, NULL};
++puCallback helpSubmenuCb        [] = { notCb, helpCb, NULL };
++
++ 
++
++/* -------------------------------------------------------------------------
++   init the gui
++   _____________________________________________________________________*/
++
++
++
++void guiInit()
++{
++    char *mesa_win_state;
++
++    // Initialize PUI
++    puInit();
++
++    if ( current_options.get_mouse_pointer() == 0 ) {
++      // no preference specified for mouse pointer, attempt to autodetect...
++      // Determine if we need to render the cursor, or if the windowing
++      // system will do it.  First test if we are rendering with glide.
++      if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
++          // Test for the MESA_GLX_FX env variable
++          if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
++              // test if we are fullscreen mesa/glide
++              if ( (mesa_win_state[0] == 'f') || 
++                   (mesa_win_state[0] == 'F') ) {
++                  puShowCursor ();
++              }
++          }
++      }
++    } else if ( current_options.get_mouse_pointer() == 1 ) {
++      // don't show pointer
++    } else if ( current_options.get_mouse_pointer() == 2 ) {
++      // force showing pointer
++      puShowCursor();
++    }
++
++    // puSetDefaultStyle         ( PUSTYLE_SMALL_BEVELLED );
++    puSetDefaultStyle         ( PUSTYLE_DEFAULT );
++    // puSetDefaultColourScheme  (0.2, 0.4, 0.8, 0.5);
++    puSetDefaultColourScheme  (0.8, 0.8, 0.8, 0.5);
++      
++    /* OK the rest is largerly put in here to mimick Steve Baker's
++       "complex" example It should change in future versions */
++      
++    // timerText = new puText (300, 10);
++    // timerText -> setColour (PUCOL_LABEL, 1.0, 1.0, 1.0);
++
++    /* Make a button to hide the menu bar */
++    hideMenuButton = new puButton       (10,10, 150, 50);
++    hideMenuButton -> setValue          (TRUE);
++    hideMenuButton -> setLegend         ("Hide Menu");
++    hideMenuButton -> setCallback       (hideMenuCb);
++    hideMenuButton -> makeReturnDefault (TRUE);
++    hideMenuButton -> hide();
++
++    // Make the menu bar
++    mainMenuBar = new puMenuBar ();
++    mainMenuBar -> add_submenu ("File", fileSubmenu, fileSubmenuCb);
++    mainMenuBar -> add_submenu ("Edit", editSubmenu, editSubmenuCb);
++    mainMenuBar -> add_submenu ("View", viewSubmenu, viewSubmenuCb);
++    mainMenuBar -> add_submenu ("Aircraft", aircraftSubmenu, aircraftSubmenuCb);
++    mainMenuBar -> add_submenu ("Environment", environmentSubmenu, 
++                              environmentSubmenuCb);
++    mainMenuBar -> add_submenu ("Options", optionsSubmenu, optionsSubmenuCb);
++    mainMenuBar -> add_submenu ("Help", helpSubmenu, helpSubmenuCb);
++    mainMenuBar-> close ();
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..449ad03c1e612d4d0c788f2fa2f817d0933ba034
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,44 @@@
++/**************************************************************************
++ * gui.h
++ *
++ * Written 1998 by Durk Talsma, started Juni, 1998.  For the flight gear
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _GUI_H_
++#define _GUI_H_
++
++#include <pu.h>
++
++extern puMenuBar    *mainMenuBar;
++extern puButton     *hideMenuButton;
++extern puDialogBox  *dialogBox;
++extern puText       *dialogBoxMessage;
++extern puOneShot    *dialogBoxOkButton;
++extern puText       *timerText;
++
++extern void guiMotionFunc ( int x, int y );
++extern void guiMouseFunc(int button, int updown, int x, int y);
++extern void guiInit();
++
++extern void mkDialog (char *txt);
++
++#endif // _GUI_H_ 
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d32ac26c0ffb54070a2b5734710a69dbf8e4ba01
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,464 @@@
++/*******************************************************************************
++
++ Module:       FGAircraft.cpp
++ Author:       Jon S. Berndt
++ Date started: 12/12/98                                   
++ Purpose:      Encapsulates an aircraft
++ Called by:    FGFDMExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++Models the aircraft reactions and forces. This class is instantiated by the
++FGFDMExec class and scheduled as an FDM entry. LoadAircraft() is supplied with a
++name of a valid, registered aircraft, and the data file is parsed.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++      Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++      School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++      JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++      NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++      Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++      1982 ISBN 0-471-08936-2
++
++The aerodynamic coefficients used in this model are:
++
++Longitudinal
++  CL0 - Reference lift at zero alpha
++  CD0 - Reference drag at zero alpha
++  CDM - Drag due to Mach
++  CLa - Lift curve slope (w.r.t. alpha)
++  CDa - Drag curve slope (w.r.t. alpha)
++  CLq - Lift due to pitch rate
++  CLM - Lift due to Mach
++  CLadt - Lift due to alpha rate
++
++  Cmadt - Pitching Moment due to alpha rate
++  Cm0 - Reference Pitching moment at zero alpha
++  Cma - Pitching moment slope (w.r.t. alpha)
++  Cmq - Pitch damping (pitch moment due to pitch rate)
++  CmM - Pitch Moment due to Mach
++
++Lateral
++  Cyb - Side force due to sideslip
++  Cyr - Side force due to yaw rate
++
++  Clb - Dihedral effect (roll moment due to sideslip)
++  Clp - Roll damping (roll moment due to roll rate)
++  Clr - Roll moment due to yaw rate
++  Cnb - Weathercocking stability (yaw moment due to sideslip)
++  Cnp - Rudder adverse yaw (yaw moment due to roll rate)
++  Cnr - Yaw damping (yaw moment due to yaw rate)
++
++Control
++  CLDe - Lift due to elevator
++  CDDe - Drag due to elevator
++  CyDr - Side force due to rudder
++  CyDa - Side force due to aileron
++
++  CmDe - Pitch moment due to elevator
++  ClDa - Roll moment due to aileron
++  ClDr - Roll moment due to rudder
++  CnDr - Yaw moment due to rudder
++  CnDa - Yaw moment due to aileron
++
++This class expects to be run in a directory which contains the subdirectory
++structure shown below (where example aircraft X-15 is shown):
++
++aircraft/
++         X-15/
++              X-15.dat reset00 reset01 reset02 ...
++              CDRAG/
++                 a0 a M De
++              CSIDE/
++                 b r Dr Da
++              CLIFT/
++                 a0 a M adt De
++              CROLL/
++                 b p r Da Dr
++              CPITCH/
++                 a0 a adt q M De
++              CYAW/
++                 b p r Dr Da
++         F-16/
++              F-16.dat reset00 reset01 ...
++              CDRAG/
++                 a0 a M De
++              ...
++
++The General Idea
++
++The file structure is arranged so that various modeled aircraft are stored in
++their own subdirectory. Each aircraft subdirectory is named after the aircraft.
++There should be a file present in the specific aircraft subdirectory (e.g.
++aircraft/X-15) with the same name as the directory with a .dat appended. This
++file contains mass properties information, name of aircraft, etc. for the
++aircraft. In that same directory are reset files numbered starting from 0 (two
++digit numbers), e.g. reset03. Within each reset file are values for important
++state variables for specific flight conditions (altitude, airspeed, etc.). Also
++within this directory are the directories containing lookup tables for the
++stability derivatives for the aircraft.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++#include <dirent.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  int i;
++
++  Name = "FGAircraft";
++
++  for (i=0;i<6;i++) coeff_ctr[i] = 0;
++
++  Axis[LiftCoeff]  = "CLIFT";
++  Axis[DragCoeff]  = "CDRAG";
++  Axis[SideCoeff]  = "CSIDE";
++  Axis[RollCoeff]  = "CROLL";
++  Axis[PitchCoeff] = "CPITCH";
++  Axis[YawCoeff]   = "CYAW";
++}
++
++
++FGAircraft::~FGAircraft(void)
++{
++}
++
++
++bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, string fname)
++{
++  string path;
++  string fullpath;
++  string filename;
++  string aircraftDef;
++  string tag;
++  DIR* dir;
++  DIR* coeffdir;
++  struct dirent* dirEntry;
++  struct dirent* coeffdirEntry;
++  struct stat st;
++  struct stat st2;
++  ifstream coeffInFile;
++
++  aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".dat";
++  ifstream aircraftfile(aircraftDef.c_str());
++
++  if (aircraftfile) {
++    aircraftfile >> AircraftName;   // String with no embedded spaces
++    aircraftfile >> WingArea;       // square feet
++    aircraftfile >> WingSpan;       // feet
++    aircraftfile >> cbar;           // feet
++    aircraftfile >> Ixx;            // slug ft^2
++    aircraftfile >> Iyy;            // "
++    aircraftfile >> Izz;            // "
++    aircraftfile >> Ixz;            // "
++    aircraftfile >> EmptyWeight;    // pounds
++    EmptyMass = EmptyWeight / GRAVITY;
++    aircraftfile >> tag;
++
++    numTanks = numEngines = 0;
++    numSelectedOxiTanks = numSelectedFuelTanks = 0;
++
++    while ( !(tag == "EOF") ) {
++      if (tag == "CGLOC") {
++        aircraftfile >> Xcg;        // inches
++        aircraftfile >> Ycg;        // inches
++        aircraftfile >> Zcg;        // inches
++      } else if (tag == "EYEPOINTLOC") {
++        aircraftfile >> Xep;        // inches
++        aircraftfile >> Yep;        // inches
++        aircraftfile >> Zep;        // inches
++      } else if (tag == "TANK") {
++        Tank[numTanks] = new FGTank(aircraftfile);
++        switch(Tank[numTanks]->GetType()) {
++        case FGTank::ttFUEL:
++          numSelectedFuelTanks++;
++          break;
++        case FGTank::ttOXIDIZER:
++          numSelectedOxiTanks++;
++          break;
++        }
++        numTanks++;
++      } else if (tag == "ENGINE") {
++        aircraftfile >> tag;
++        Engine[numEngines] = new FGEngine(FDMExec, engine_path, tag, numEngines);
++        numEngines++;
++      }
++      aircraftfile >> tag;
++    }
++    aircraftfile.close();
++    PutState();
++
++    // Read subdirectory for this aircraft for stability derivative lookup tables:
++    //
++    // Build up the path name to the aircraft file by appending the aircraft
++    // name to the "aircraft/" initial path. Initialize the directory entry
++    // structure dirEntry in preparation for reading through the directory.
++    // Build up a path to each file in the directory sequentially and "stat" it
++    // to see if the entry is a directory or a file. If the entry is a file, then
++    // compare it to each string in the Axis[] array to see which axis the
++    // directory represents: Lift, Drag, Side, Roll, Pitch, Yaw. When the match
++    // is found, go into that directory and search for any coefficient files.
++    // Build a new coefficient by passing the full pathname to the coefficient
++    // file to the FGCoefficient constructor.
++    //
++    // Note: axis_ctr=0 for the Lift "axis", 1 for Drag, 2 for Side force, 3 for
++    //       Roll, 4 for Pitch, and 5 for Yaw. The term coeff_ctr merely keeps
++    //       track of the number of coefficients registered for each of the
++    //       previously mentioned axis.
++
++    path = aircraft_path + "/" + AircraftName + "/";
++    if (dir = opendir(path.c_str())) {
++
++      while (dirEntry = readdir(dir)) {
++        fullpath = path + dirEntry->d_name;
++        stat(fullpath.c_str(),&st);
++        if ((st.st_mode & S_IFMT) == S_IFDIR) {
++          for (int axis_ctr=0; axis_ctr < 6; axis_ctr++) {
++            if (dirEntry->d_name == Axis[axis_ctr]) {
++              if (coeffdir = opendir(fullpath.c_str())) {
++                while (coeffdirEntry = readdir(coeffdir)) {
++                  if (coeffdirEntry->d_name[0] != '.') {
++                    filename = path + Axis[axis_ctr] + "/" + coeffdirEntry->d_name;
++                    stat(filename.c_str(),&st2);
++                    if (st2.st_size > 6) {
++                      Coeff[axis_ctr][coeff_ctr[axis_ctr]] = new FGCoefficient(FDMExec, filename);
++                      coeff_ctr[axis_ctr]++;
++                    }
++                  }
++                }
++              }
++            }
++          }
++        }
++      }
++    } else {
++      cerr << "Could not open directory " << path << " for reading" << endl;
++    }
++    return true;
++
++  } else {
++    cerr << "Unable to open aircraft definition file " << fname << endl;
++    return false;
++  }
++
++}
++
++
++bool FGAircraft::Run(void)
++{
++  if (!FGModel::Run()) {                 // if false then execute this Run()
++    GetState();
++
++    for (int i = 0; i < 3; i++)  Forces[i] = Moments[i] = 0.0;
++
++    MassChange();
++
++    FProp(); FAero(); FGear(); FMass();
++    MProp(); MAero(); MGear(); MMass();
++
++    PutState();
++  } else {                               // skip Run() execution this time
++  }
++  return false;
++}
++
++
++void FGAircraft::MassChange()
++{
++  // UPDATE TANK CONTENTS
++  //
++  // For each engine, cycle through the tanks and draw an equal amount of
++  // fuel (or oxidizer) from each active tank. The needed amount of fuel is
++  // determined by the engine in the FGEngine class. If more fuel is needed
++  // than is available in the tank, then that amount is considered a shortage,
++  // and will be drawn from the next tank. If the engine cannot be fed what it
++  // needs, it will be considered to be starved, and will shut down.
++
++  float Oshortage, Fshortage;
++
++  for (int e=0; e<numEngines; e++) {
++    Fshortage = Oshortage = 0.0;
++    for (int t=0; t<numTanks; t++) {
++      switch(Engine[e]->GetType()) {
++      case FGEngine::etRocket:
++
++        switch(Tank[t]->GetType()) {
++        case FGTank::ttFUEL:
++          if (Tank[t]->GetSelected()) {
++            Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
++                                   numSelectedFuelTanks)*(dt*rate) + Fshortage);
++          }
++          break;
++        case FGTank::ttOXIDIZER:
++          if (Tank[t]->GetSelected()) {
++            Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/
++                                    numSelectedOxiTanks)*(dt*rate) + Oshortage);
++          }
++          break;
++        }
++        break;
++
++      case FGEngine::etPiston:
++      case FGEngine::etTurboJet:
++      case FGEngine::etTurboProp:
++
++        if (Tank[t]->GetSelected()) {
++          Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
++                                   numSelectedFuelTanks)*(dt*rate) + Fshortage);
++        }
++        break;
++      }
++    }
++    if ((Fshortage <= 0.0) || (Oshortage <= 0.0)) Engine[e]->SetStarved();
++    else Engine[e]->SetStarved(false);
++  }
++
++  Weight = EmptyWeight;
++  for (int t=0; t<numTanks; t++)
++    Weight += Tank[t]->GetContents();
++
++  Mass = Weight / GRAVITY;
++}
++
++
++void FGAircraft::FAero(void)
++{
++  float F[3];
++
++  F[0] = F[1] = F[2] = 0.0;
++
++  for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
++    for (int ctr=0; ctr < coeff_ctr[axis_ctr]; ctr++)
++      F[axis_ctr] += Coeff[axis_ctr][ctr]->Value();
++
++  Forces[0] +=  F[LiftCoeff]*sin(alpha) - F[DragCoeff]*cos(alpha) - F[SideCoeff]*sin(beta);
++  Forces[1] +=  F[SideCoeff]*cos(beta);
++  Forces[2] += -F[LiftCoeff]*cos(alpha) - F[DragCoeff]*sin(alpha);
++}
++
++
++void FGAircraft::FGear(void)
++{
++  if (GearUp) {
++  } else {
++  }
++}
++
++
++void FGAircraft::FMass(void)
++{
++  Forces[0] += -GRAVITY*sin(tht) * Mass;
++  Forces[1] +=  GRAVITY*sin(phi)*cos(tht) * Mass;
++  Forces[2] +=  GRAVITY*cos(phi)*cos(tht) * Mass;
++}
++
++
++void FGAircraft::FProp(void)
++{
++  for (int i=0;i<numEngines;i++) {
++    Forces[0] += Engine[i]->CalcThrust();
++  }
++}
++
++
++void FGAircraft::MAero(void)
++{
++  for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
++    for (int ctr = 0; ctr < coeff_ctr[axis_ctr+3]; ctr++)
++      Moments[axis_ctr] += Coeff[axis_ctr+3][ctr]->Value();
++}
++
++
++void FGAircraft::MGear(void)
++{
++  if (GearUp) {
++  } else {
++  }
++}
++
++
++void FGAircraft::MMass(void)
++{
++}
++
++
++void FGAircraft::MProp(void)
++{
++}
++
++
++void FGAircraft::GetState(void)
++{
++  dt = State->Getdt();
++
++  alpha = Translation->Getalpha();
++  beta = Translation->Getbeta();
++  phi = Rotation->Getphi();
++  tht = Rotation->Gettht();
++  psi = Rotation->Getpsi();
++}
++
++
++void FGAircraft::PutState(void)
++{
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..235b7c0b858f48cfcc45fad478457153182f2f57
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,491 @@@
++/*******************************************************************************
++
++ Header:       FGAircraft.h
++ Author:       Jon S. Berndt
++ Date started: 12/12/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGAIRCRAFT_H
++#define FGAIRCRAFT_H
++
++/*******************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++*******************************************************************************/
++/**
++The aerodynamic coefficients used in this model typically are:
++<PRE>
++<b>Longitudinal</b>
++  CL0 - Reference lift at zero alpha
++  CD0 - Reference drag at zero alpha
++  CDM - Drag due to Mach
++  CLa - Lift curve slope (w.r.t. alpha)
++  CDa - Drag curve slope (w.r.t. alpha)
++  CLq - Lift due to pitch rate
++  CLM - Lift due to Mach
++  CLadt - Lift due to alpha rate
++
++  Cmadt - Pitching Moment due to alpha rate
++  Cm0 - Reference Pitching moment at zero alpha
++  Cma - Pitching moment slope (w.r.t. alpha)
++  Cmq - Pitch damping (pitch moment due to pitch rate)
++  CmM - Pitch Moment due to Mach
++
++<b>Lateral</b>
++  Cyb - Side force due to sideslip
++  Cyr - Side force due to yaw rate
++
++  Clb - Dihedral effect (roll moment due to sideslip)
++  Clp - Roll damping (roll moment due to roll rate)
++  Clr - Roll moment due to yaw rate
++  Cnb - Weathercocking stability (yaw moment due to sideslip)
++  Cnp - Rudder adverse yaw (yaw moment due to roll rate)
++  Cnr - Yaw damping (yaw moment due to yaw rate)
++
++<b>Control</b>
++  CLDe - Lift due to elevator
++  CDDe - Drag due to elevator
++  CyDr - Side force due to rudder
++  CyDa - Side force due to aileron
++
++  CmDe - Pitch moment due to elevator
++  ClDa - Roll moment due to aileron
++  ClDr - Roll moment due to rudder
++  CnDr - Yaw moment due to rudder
++  CnDa - Yaw moment due to aileron
++</PRE>
++This class expects to be run in a directory which contains the subdirectory
++structure shown below (where example aircraft X-15 is shown):
++
++<PRE>
++aircraft/
++  X-15/
++    X-15.dat reset00 reset01 reset02 ...
++      CDRAG/
++        a0 a M De
++      CSIDE/
++        b r Dr Da
++      CLIFT/
++        a0 a M adt De
++      CROLL/
++        b p r Da Dr
++      CPITCH/
++        a0 a adt q M De
++      CYAW/
++        b p r Dr Da
++  F-16/
++    F-16.dat reset00 reset01 ...
++      CDRAG/
++        a0 a M De
++      ...
++</PRE>
++
++The General Idea
++
++The file structure is arranged so that various modeled aircraft are stored in
++their own subdirectory. Each aircraft subdirectory is named after the aircraft.
++There should be a file present in the specific aircraft subdirectory (e.g.
++aircraft/X-15) with the same name as the directory with a .dat appended. This
++file contains mass properties information, name of aircraft, etc. for the
++aircraft. In that same directory are reset files numbered starting from 0 (two
++digit numbers), e.g. reset03. Within each reset file are values for important
++state variables for specific flight conditions (altitude, airspeed, etc.). Also
++within this directory are the directories containing lookup tables for the
++stability derivatives for the aircraft.
++@author Jon S. Berndt
++@memo  Encompasses all aircraft functionality and objects
++@see <ll>
++<li>[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++       Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++       School, January 1994</li>
++<li>[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++       JSC 12960, July 1977</li>
++<li>[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++       NASA-Ames", NASA CR-2497, January 1975</li>
++<li>[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++       Wiley & Sons, 1979 ISBN 0-471-03032-5</li>
++<li>[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++       1982 ISBN 0-471-08936-2</li>
++</ll>
++*/
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <fstream>
++#  else
++#    include <fstream.h>
++#  endif
++#else
++#  include <fstream>
++#endif
++
++#include "FGModel.h"
++#include "FGCoefficient.h"
++#include "FGEngine.h"
++#include "FGTank.h"
++
++/*******************************************************************************
++DEFINITIONS
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAircraft : public FGModel
++{
++public:
++  // ***************************************************************************
++  /** @memo Constructor
++      @param FGFDMExec* - a pointer to the "owning" FDM Executive
++  */
++  FGAircraft(FGFDMExec*);
++  
++  // ***************************************************************************
++  /** Destructor */
++  ~FGAircraft(void);
++
++  // ***************************************************************************
++  /** This must be called for each dt to execute the model algorithm */
++  bool Run(void);
++
++  // ***************************************************************************
++  /** This function must be called with the name of an aircraft which
++      has an associated .dat file in the appropriate subdirectory. The paths
++      to the appropriate subdirectories are given as the first two parameters. 
++      @memo Loads the given aircraft.
++      @param string Path to the aircraft files
++      @param string Path to the engine files
++      @param string The name of the aircraft to be loaded, e.g. "X15".
++      @return True - if successful
++  */
++  bool LoadAircraft(string, string, string);
++
++  // ***************************************************************************
++  /** @memo Gets the aircraft name as defined in the aircraft config file.
++      @param
++      @return string Aircraft name.
++  */
++  inline string GetAircraftName(void) {return AircraftName;}
++
++  // ***************************************************************************
++  /** @memo Sets the GearUp flag
++      @param boolean true or false
++      @return
++  */
++  inline void SetGearUp(bool tt) {GearUp = tt;}
++
++  // ***************************************************************************
++  /** @memo Returns the state of the GearUp flag
++      @param
++      @return boolean true or false
++  */
++  inline bool GetGearUp(void) {return GearUp;}
++
++  // ***************************************************************************
++  /** @memo Returns the area of the wing
++      @param
++      @return float wing area S, in square feet
++  */
++  inline float GetWingArea(void) {return WingArea;}
++
++  // ***************************************************************************
++  /** @memo Returns the wing span
++      @param
++      @return float wing span in feet
++  */
++  inline float GetWingSpan(void) {return WingSpan;}
++
++  // ***************************************************************************
++  /** @memo Returns the average wing chord
++      @param
++      @return float wing chord in feet
++  */
++  inline float Getcbar(void) {return cbar;}
++
++  // ***************************************************************************
++  /** @memo Returns an engine object
++      @param int The engine number
++      @return FGEengine* The pointer to the requested engine object.
++  */
++  inline FGEngine* GetEngine(int tt) {return Engine[tt];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline FGTank* GetTank(int tt) {return Tank[tt];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetWeight(void) {return Weight;}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetMass(void) {return Mass;}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetL(void) {return Moments[0];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetM(void) {return Moments[1];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetN(void) {return Moments[2];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetFx(void) {return Forces[0];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetFy(void) {return Forces[1];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetFz(void) {return Forces[2];}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetIxx(void) {return Ixx;}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetIyy(void) {return Iyy;}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetIzz(void) {return Izz;}
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  inline float GetIxz(void) {return Ixz;}
++
++private:
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void GetState(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void PutState(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void FAero(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void FGear(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void FMass(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void FProp(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void MAero(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void MGear(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void MMass(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void MProp(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  void MassChange(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  float Moments[3];
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  float Forces[3];
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  string AircraftName;
++
++  // ***************************************************************************
++  ///
++  float Ixx, Iyy, Izz, Ixz, EmptyMass, Mass;
++  ///
++  float Xcg, Ycg, Zcg;
++  ///
++  float Xep, Yep, Zep;
++  ///
++  float rho, qbar, Vt;
++  ///
++  float alpha, beta;
++  ///
++  float WingArea, WingSpan, cbar;
++  ///
++  float phi, tht, psi;
++  ///
++  float Weight, EmptyWeight;
++  ///
++  float dt;
++
++  ///
++  int numTanks;
++  ///
++  int numEngines;
++  ///
++  int numSelectedOxiTanks;
++  ///
++  int numSelectedFuelTanks;
++  ///
++  FGTank* Tank[MAX_TANKS];
++  ///
++  FGEngine *Engine[MAX_ENGINES];
++
++  ///
++  FGCoefficient *Coeff[6][10];
++  ///
++  int coeff_ctr[6];
++
++  ///
++  bool GearUp;
++
++  ///
++  enum Param {LiftCoeff,
++              DragCoeff,
++              SideCoeff,
++              RollCoeff,
++              PitchCoeff,
++              YawCoeff,
++              numCoeffs};
++
++  ///
++  string Axis[6];
++
++protected:
++
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a066b30469d80283cb08c1d7ebc8ce2a9ae11fba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++/*******************************************************************************
++
++ Module:       FGAtmosphere.cpp
++ Author:       Jon Berndt
++ Date started: 11/24/98
++ Purpose:      Models the atmosphere
++ Called by:    FGSimExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++Models the atmosphere. The equation used below was determined by a third order
++curve fit using Excel. The data is from the ICAO atmosphere model.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/24/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGAtmosphere";
++}
++
++
++FGAtmosphere::~FGAtmosphere()
++{
++}
++
++
++bool FGAtmosphere::Run(void)
++{
++  if (!FGModel::Run()) {                 // if false then execute this Run()
++    rho = 0.002377 - 7.0E-08*State->Geth()
++        + 7.0E-13*State->Geth()*State->Geth()
++        - 2.0E-18*State->Geth()*State->Geth()*State->Geth();
++
++    State->SetMach(State->GetVt()/State->Geta()); 
++  } else {                               // skip Run() execution this time
++  }
++  return false;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9993d25206ec68e7ad7791610650b145b546a4ea
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,87 @@@
++/*******************************************************************************
++
++ Header:       FGAtmosphere.h
++ Author:       Jon Berndt
++ Date started: 11/24/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/24/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGATMOSPHERE_H
++#define FGATMOSPHERE_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++*******************************************************************************/
++/**
++The equation used in this model was determined by a third order curve fit using
++Excel. The data is from the ICAO atmosphere model.
++@memo Models the atmosphere.
++@author Jon S. Berndt
++*/
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAtmosphere : public FGModel
++{
++public:
++  // ***************************************************************************
++  /** @memo Constructor
++      @param FGFDMExec* - a pointer to the "owning" FDM Executive
++  */
++  FGAtmosphere(FGFDMExec*);
++
++  // ***************************************************************************
++  /** @memo Destructor
++  */
++  ~FGAtmosphere(void);
++
++  // ***************************************************************************
++  /** This must be called for each dt to execute the model algorithm */
++  bool Run(void);
++
++  // ***************************************************************************
++  /** @memo Returns the air density
++      @return float air density in slugs/cubic foot
++  */
++  inline float Getrho(void) {return rho;}
++
++protected:
++
++private:
++  float rho;
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..232e05f09fcbc94c7fcb74db04056a54d9a4ecda
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,75 @@@
++/*******************************************************************************
++
++ Module:       FGAuxiliary.cpp
++ Author:       Jon Berndt
++ Date started: 01/26/99
++ Purpose:      Calculates additional parameters needed by the visual system, etc.
++ Called by:    FGSimExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class calculates various auxiliary parameters, mostly used by the visual
++system
++
++HISTORY
++--------------------------------------------------------------------------------
++01/26/99   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGAuxiliary.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGPosition.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGAuxiliary";
++}
++
++
++FGAuxiliary::~FGAuxiliary()
++{
++}
++
++
++bool FGAuxiliary::Run()
++{
++  if (!FGModel::Run()) {
++  } else {
++  }
++  return false;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9a369cb74f81234bf87402fd31dacec1cad2025d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,65 @@@
++/*******************************************************************************
++
++ Header:       FGAuxiliary.h
++ Author:       Jon Berndt
++ Date started: 01/26/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/22/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGAUXILIARY_H
++#define FGAUXILIARY_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGModel.h"
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAuxiliary : public FGModel
++{
++public:
++  FGAuxiliary(FGFDMExec*);
++  ~FGAuxiliary(void);
++   
++  bool Run(void);
++  
++protected:
++
++private:
++
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..89c1ca1ef25ed4b05cd6274f405c2617dee633cb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,457 @@@
++/*******************************************************************************
++
++ Module:       FGCoefficient.cpp
++ Author:       Jon S. Berndt
++ Date started: 12/28/98
++ Purpose:      Encapsulates the stability derivative class FGCoefficient;
++ Called by:    FGAircraft
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class models the stability derivative coefficient lookup tables or
++equations. Note that the coefficients need not be calculated each delta-t.
++
++The coefficient files are located in the axis subdirectory for each aircraft.
++For instance, for the X-15, you would find subdirectories under the
++aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
++each of these directories would be files named a, a0, q, and so on. The file
++named "a" under the CLIFT directory would contain data for the stability
++derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
++for additional information. The coefficient files have the following format:
++
++<name of coefficient>
++<short description of coefficient with no embedded spaces>
++<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
++  <parameter identifier for table row (if required)>
++  <parameter identifier for table column (if required)>
++<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
++<number of rows in table (if required)>
++<number of columns in table (if required)>
++
++<value of parameter indexing into the column of a table or vector - or value
++  itself for a VALUE coefficient>
++<values of parameter indexing into row of a table if TABLE type> <Value of
++  coefficient at this row and column>
++
++<... repeat above for each column of data in table ...>
++
++As an example for the X-15, for the lift due to mach:
++
++CLa0
++Lift_at_zero_alpha
++Table 8 3
++16384
++32768
++16387
++
++0.00
++0.0 0.0
++0.5 0.4
++0.9 0.9
++1.0 1.6
++1.1 1.3
++1.4 1.0
++2.0 0.5
++3.0 0.5
++
++30000.00
++0.0 0.0
++0.5 0.5
++0.9 1.0
++1.0 1.7
++1.1 1.4
++1.4 1.1
++2.0 0.6
++3.0 0.6
++
++70000.00
++0.0 0.0
++0.5 0.6
++0.9 1.1
++1.0 1.7
++1.1 1.5
++1.4 1.2
++2.0 0.7
++3.0 0.7
++
++Note that the values in a row which index into the table must be the same value
++for each column of data, so the first column of numbers for each altitude are
++seen to be equal, and there are the same number of values for each altitude.
++
++See the header file FGCoefficient.h for the values of the identifiers.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/28/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGCoefficient.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex)
++{
++  FDMExec     = fdex;
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  rows = columns = 0;
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, string fname)
++{
++  int r, c;
++  float ftrashcan;
++
++  FDMExec     = fdex;
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  ifstream coeffDefFile(fname.c_str());
++
++  if (coeffDefFile) {
++    if (!coeffDefFile.fail()) {
++      coeffDefFile >> name;
++      coeffDefFile >> description;
++      coeffDefFile >> method;
++
++      if      (method == "EQUATION") type = EQUATION;
++      else if (method == "TABLE")    type = TABLE;
++      else if (method == "VECTOR")   type = VECTOR;
++      else if (method == "VALUE")    type = VALUE;
++      else                           type = UNKNOWN;
++
++      if (type == VECTOR || type == TABLE) {
++        coeffDefFile >> rows;
++        if (type == TABLE) {
++          coeffDefFile >> columns;
++        }
++        coeffDefFile >> LookupR;
++      }
++
++      if (type == TABLE) {
++        coeffDefFile >> LookupC;
++      }
++
++      coeffDefFile >> multipliers;
++
++      mult_count = 0;
++      if (multipliers & FG_QBAR) {
++        mult_idx[mult_count] = FG_QBAR;
++        mult_count++;
++      }
++      if (multipliers & FG_WINGAREA) {
++        mult_idx[mult_count] = FG_WINGAREA;
++        mult_count++;
++      }
++      if (multipliers & FG_WINGSPAN) {
++        mult_idx[mult_count] = FG_WINGSPAN;
++        mult_count++;
++      }
++      if (multipliers & FG_CBAR) {
++        mult_idx[mult_count] = FG_CBAR;
++        mult_count++;
++      }
++      if (multipliers & FG_ALPHA) {
++        mult_idx[mult_count] = FG_ALPHA;
++        mult_count++;
++      }
++      if (multipliers & FG_ALPHADOT) {
++        mult_idx[mult_count] = FG_ALPHADOT;
++        mult_count++;
++      }
++      if (multipliers & FG_BETA) {
++        mult_idx[mult_count] = FG_BETA;
++        mult_count++;
++      }
++      if (multipliers & FG_BETADOT) {
++        mult_idx[mult_count] = FG_BETADOT;
++        mult_count++;
++      }
++      if (multipliers & FG_PITCHRATE) {
++        mult_idx[mult_count] = FG_PITCHRATE;
++        mult_count++;
++      }
++      if (multipliers & FG_ROLLRATE) {
++        mult_idx[mult_count] = FG_ROLLRATE;
++        mult_count++;
++      }
++      if (multipliers & FG_YAWRATE) {
++        mult_idx[mult_count] = FG_YAWRATE;
++        mult_count++;
++      }
++      if (multipliers & FG_ELEVATOR) {
++        mult_idx[mult_count] = FG_ELEVATOR;
++        mult_count++;
++      }
++      if (multipliers & FG_AILERON) {
++        mult_idx[mult_count] = FG_AILERON;
++        mult_count++;
++      }
++      if (multipliers & FG_RUDDER) {
++        mult_idx[mult_count] = FG_RUDDER;
++        mult_count++;
++      }
++      if (multipliers & FG_MACH) {
++        mult_idx[mult_count] = FG_MACH;
++        mult_count++;
++      }
++      if (multipliers & FG_ALTITUDE) {
++        mult_idx[mult_count] = FG_ALTITUDE;
++        mult_count++;
++      }
++
++      switch(type) {
++      case VALUE:
++        coeffDefFile >> StaticValue;
++        break;
++      case VECTOR:
++        Allocate(rows,2);
++
++        for (r=1;r<=rows;r++) {
++          coeffDefFile >> Table3D[r][0];
++          coeffDefFile >> Table3D[r][1];
++        }
++        break;
++      case TABLE:
++        Allocate(rows, columns);
++
++        for (c=1;c<=columns;c++) {
++          coeffDefFile >> Table3D[0][c];
++          for (r=1;r<=rows;r++) {
++            if ( c==1 ) coeffDefFile >> Table3D[r][0];
++            else coeffDefFile >> ftrashcan;
++            coeffDefFile >> Table3D[r][c];
++          }
++        }
++        break;
++      }
++    } else {
++      cerr << "Empty file" << endl;
++    }
++    coeffDefFile.close();
++  }
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, int r, int c)
++{
++  FDMExec     = fdex;
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  rows = r;
++  columns = c;
++  Allocate(r,c);
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, int n)
++{
++  FDMExec     = fdex;
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  rows = n;
++  columns = 0;
++  Allocate(n);
++}
++
++
++FGCoefficient::~FGCoefficient(void)
++{
++}
++
++
++bool FGCoefficient::Allocate(int r, int c)
++{
++  rows = r;
++  columns = c;
++  Table3D = new float*[r+1];
++  for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
++  return true;
++}
++
++
++bool FGCoefficient::Allocate(int n)
++{
++  rows = n;
++  columns = 0;
++  Table2D = new float[n+1];
++  return true;
++}
++
++
++float FGCoefficient::Value(float rVal, float cVal)
++{
++  float rFactor, cFactor, col1temp, col2temp, Value;
++  int r, c, midx;
++
++  if (rows < 2 || columns < 2) return 0.0;
++
++  for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
++  for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
++
++  c = c < 2 ? 2 : (c > columns ? columns : c);
++  r = r < 2 ? 2 : (r > rows    ? rows    : r);
++
++  rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
++  cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
++
++  col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
++  col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
++
++  Value = col1temp + cFactor*(col2temp - col1temp);
++
++  for (midx=0;midx<mult_count;midx++) {
++    Value *= GetCoeffVal(mult_idx[midx]);
++  }
++
++  return Value;
++}
++
++
++float FGCoefficient::Value(float Val)
++{
++  float Factor, Value;
++  int r, midx;
++
++  if (rows < 2) return 0.0;
++  
++  for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
++  r = r < 2 ? 2 : (r > rows    ? rows    : r);
++
++  // make sure denominator below does not go to zero.
++  if (Table3D[r][0] != Table3D[r-1][0]) {
++    Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
++  } else {
++    Factor = 1.0;
++  }
++  Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
++
++  for (midx=0;midx<mult_count;midx++) {
++    Value *= GetCoeffVal(mult_idx[midx]);
++  }
++
++  return Value;
++}
++
++
++float FGCoefficient::Value()
++{
++  switch(type) {
++  case 0:
++    return -1;
++  case 1:
++    return (StaticValue);
++  case 2:
++    return (Value(GetCoeffVal(LookupR)));
++  case 3:
++    return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
++  case 4:
++    return 0.0;
++  }
++  return 0;
++}
++
++float FGCoefficient::GetCoeffVal(int val_idx)
++{
++  switch(val_idx) {
++  case FG_QBAR:
++    return State->Getqbar();
++  case FG_WINGAREA:
++    return Aircraft->GetWingArea();
++  case FG_WINGSPAN:
++    return Aircraft->GetWingSpan();
++  case FG_CBAR:
++    return Aircraft->Getcbar();
++  case FG_ALPHA:
++    return Translation->Getalpha();
++  case FG_ALPHADOT:
++    return State->Getadot();
++  case FG_BETA:
++    return Translation->Getbeta();
++  case FG_BETADOT:
++    return State->Getbdot();
++  case FG_PITCHRATE:
++    return Rotation->GetQ();
++  case FG_ROLLRATE:
++    return Rotation->GetP();
++  case FG_YAWRATE:
++    return Rotation->GetR();
++  case FG_ELEVATOR:
++    return FCS->GetDe();
++  case FG_AILERON:
++    return FCS->GetDa();
++  case FG_RUDDER:
++    return FCS->GetDr();
++  case FG_MACH:
++    return State->GetMach();
++  case FG_ALTITUDE:
++    return State->Geth();
++  }
++  return 0;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..918e4c2015bec3de8f82bef91ad5ba6cbd7aa164
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,300 @@@
++/*******************************************************************************
++
++ Header:       FGCoefficient.h
++ Author:       Jon Berndt
++ Date started: 12/28/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/28/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGCOEFFICIENT_H
++#define FGCOEFFICIENT_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  include STL_STRING
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <fstream>
++#  else
++#    include <fstream.h>
++#  endif
++   FG_USING_STD(string);
++#else
++#  include <string>
++#  include <fstream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++#define FG_QBAR         1
++#define FG_WINGAREA     2
++#define FG_WINGSPAN     4
++#define FG_CBAR         8
++#define FG_ALPHA       16
++#define FG_ALPHADOT    32
++#define FG_BETA        64
++#define FG_BETADOT    128
++#define FG_PITCHRATE  256
++#define FG_ROLLRATE   512
++#define FG_YAWRATE   1024
++#define FG_ELEVATOR  2048
++#define FG_AILERON   4096
++#define FG_RUDDER    8192
++#define FG_MACH     16384
++#define FG_ALTITUDE 32768L
++
++/*******************************************************************************
++FORWARD DECLARATIONS
++*******************************************************************************/
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++/*******************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++*******************************************************************************/
++/**
++This class models the stability derivative coefficient lookup tables or 
++equations. Note that the coefficients need not be calculated each delta-t.
++
++The coefficient files are located in the axis subdirectory for each aircraft.
++For instance, for the X-15, you would find subdirectories under the
++aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
++each of these directories would be files named a, a0, q, and so on. The file
++named "a" under the CLIFT directory would contain data for the stability
++derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
++for additional information. The coefficient files have the following format:
++
++<name of coefficient>
++<short description of coefficient with no embedded spaces>
++<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
++  <parameter identifier for table row (if required)>
++  <parameter identifier for table column (if required)>
++<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
++<number of rows in table (if required)>
++<number of columns in table (if required)>
++
++<value of parameter indexing into the column of a table or vector - or value
++  itself for a VALUE coefficient>
++<values of parameter indexing into row of a table if TABLE type> <Value of
++  coefficient at this row and column>
++
++<... repeat above for each column of data in table ...>
++
++As an example for the X-15, for the lift due to mach:
++<PRE>
++
++CLa0
++Lift_at_zero_alpha
++Table 8 3
++16384
++32768
++16387
++
++0.00
++0.0 0.0
++0.5 0.4
++0.9 0.9
++1.0 1.6
++1.1 1.3
++1.4 1.0
++2.0 0.5
++3.0 0.5
++
++30000.00
++0.0 0.0
++0.5 0.5
++0.9 1.0
++1.0 1.7
++1.1 1.4
++1.4 1.1
++2.0 0.6
++3.0 0.6
++
++70000.00
++0.0 0.0
++0.5 0.6
++0.9 1.1
++1.0 1.7
++1.1 1.5
++1.4 1.2
++2.0 0.7
++3.0 0.7
++</PRE>
++
++Note that the values in a row which index into the table must be the same value
++for each column of data, so the first column of numbers for each altitude are
++seen to be equal, and there are the same number of values for each altitude.
++
++<PRE>
++FG_QBAR         1
++FG_WINGAREA     2
++FG_WINGSPAN     4
++FG_CBAR         8
++FG_ALPHA       16
++FG_ALPHADOT    32
++FG_BETA        64
++FG_BETADOT    128
++FG_PITCHRATE  256
++FG_ROLLRATE   512
++FG_YAWRATE   1024
++FG_ELEVATOR  2048
++FG_AILERON   4096
++FG_RUDDER    8192
++FG_MACH     16384
++FG_ALTITUDE 32768L
++</PRE>
++@author Jon S. Berndt
++@memo This class models the stability derivative coefficient lookup tables or equations.
++*/
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGCoefficient
++{
++public:
++  // ***************************************************************************
++  /** @memo Constructor
++      @param FGFDMExec* - pointer to owning simulation executive
++  */
++  FGCoefficient(FGFDMExec*);
++
++  // ***************************************************************************
++  /** @memo Constructor for two independent variable table
++      @param
++      @return
++  */
++  FGCoefficient(FGFDMExec*, int, int);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  FGCoefficient(FGFDMExec*, int);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  FGCoefficient(FGFDMExec*, string);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  ~FGCoefficient(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  bool Allocate(int);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  bool Allocate(int, int);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  float Value(float, float);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  float Value(float);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  float Value(void);
++
++  // ***************************************************************************
++  /** @memo
++      @param
++      @return
++  */
++  enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
++
++protected:
++
++private:
++  string filename;
++  string description;
++  string name;
++  string method;
++  float StaticValue;
++  float *Table2D;
++  float **Table3D;
++  float LookupR, LookupC;
++  long int mult_idx[10];
++  int rows, columns;
++  Type type;
++  int multipliers;
++  int mult_count;
++
++  float GetCoeffVal(int);
++
++  FGFDMExec*      FDMExec;
++  FGState*        State;
++  FGAtmosphere*   Atmosphere;
++  FGFCS*          FCS;
++  FGAircraft*     Aircraft;
++  FGTranslation*  Translation;
++  FGRotation*     Rotation;
++  FGPosition*     Position;
++  FGAuxiliary*    Auxiliary;
++  FGOutput*       Output;
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e79535986b589a25c689786d57e85da08cb57bc7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,97 @@@
++// controls.cxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include "controls.hxx"
++
++
++FGControls controls;
++
++
++// Constructor
++FGControls::FGControls() :
++    aileron( 0.0 ),
++    elevator( 0.0 ),
++    elevator_trim( 1.969572E-03 ),
++    rudder( 0.0 )
++{
++    for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
++      throttle[engine] = 0.0;
++    }
++
++    for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
++        brake[wheel] = 0.0;
++    }
++}
++
++
++// Destructor
++FGControls::~FGControls() {
++}
++
++
++// $Log$
++// Revision 1.1  1999/02/13 01:12:03  curt
++// Initial Revision.
++//
++// Revision 1.1  1999/02/09 04:51:32  jon
++// Initial revision
++//
++// Revision 1.3  1998/12/05 16:13:12  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2  1998/10/25 14:08:41  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1  1998/10/18 01:51:05  curt
++// c++-ifying ...
++//
++// Revision 1.8  1998/09/29 02:01:31  curt
++// Added a brake.
++//
++// Revision 1.7  1998/02/07 15:29:36  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6  1998/01/19 19:27:02  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5  1998/01/19 18:40:22  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4  1997/12/10 22:37:41  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3  1997/08/27 03:30:01  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2  1997/06/21 17:12:48  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.1  1997/05/31 19:24:04  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e347b6b2be6aaa020fc0720a2a61dcc1aff296a3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,246 @@@
++// controls.hxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _CONTROLS_HXX
++#define _CONTROLS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// Define a structure containing the control parameters
++
++class FGControls {
++
++public:
++
++    static const int ALL_ENGINES = -1;
++    static const int MAX_ENGINES = 10;
++
++    static const int ALL_WHEELS = -1;
++    static const int MAX_WHEELS = 3;
++
++private:
++
++    double aileron;
++    double elevator;
++    double elevator_trim;
++    double rudder;
++    double throttle[MAX_ENGINES];
++    double brake[MAX_WHEELS];
++
++public:
++
++    FGControls();
++    ~FGControls();
++
++    // Query functions
++    inline double get_aileron() const { return aileron; }
++    inline double get_elevator() const { return elevator; }
++    inline double get_elevator_trim() const { return elevator_trim; }
++    inline double get_rudder() const { return rudder; }
++    inline double get_throttle(int engine) const { return throttle[engine]; }
++    inline double get_brake(int wheel) const { return brake[wheel]; }
++
++    // Update functions
++    inline void set_aileron( double pos ) {
++      aileron = pos;
++      if ( aileron < -1.0 ) aileron = -1.0;
++      if ( aileron >  1.0 ) aileron =  1.0;
++    }
++    inline void move_aileron( double amt ) {
++      aileron += amt;
++      if ( aileron < -1.0 ) aileron = -1.0;
++      if ( aileron >  1.0 ) aileron =  1.0;
++    }
++    inline void set_elevator( double pos ) {
++      elevator = pos;
++      if ( elevator < -1.0 ) elevator = -1.0;
++      if ( elevator >  1.0 ) elevator =  1.0;
++    }
++    inline void move_elevator( double amt ) {
++      elevator += amt;
++      if ( elevator < -1.0 ) elevator = -1.0;
++      if ( elevator >  1.0 ) elevator =  1.0;
++    }
++    inline void set_elevator_trim( double pos ) {
++      elevator_trim = pos;
++      if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++      if ( elevator_trim >  1.0 ) elevator_trim =  1.0;
++    }
++    inline void move_elevator_trim( double amt ) {
++      elevator_trim += amt;
++      if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++      if ( elevator_trim >  1.0 ) elevator_trim =  1.0;
++    }
++    inline void set_rudder( double pos ) {
++      rudder = pos;
++      if ( rudder < -1.0 ) rudder = -1.0;
++      if ( rudder >  1.0 ) rudder =  1.0;
++    }
++    inline void move_rudder( double amt ) {
++      rudder += amt;
++      if ( rudder < -1.0 ) rudder = -1.0;
++      if ( rudder >  1.0 ) rudder =  1.0;
++    }
++    inline void set_throttle( int engine, double pos ) {
++      if ( engine == ALL_ENGINES ) {
++          for ( int i = 0; i < MAX_ENGINES; i++ ) {
++              throttle[i] = pos;
++              if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++              if ( throttle[i] >  1.0 ) throttle[i] =  1.0;
++          }
++      } else {
++          if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++              throttle[engine] = pos;
++              if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++              if ( throttle[engine] >  1.0 ) throttle[engine] =  1.0;
++          }
++      }
++    }
++    inline void move_throttle( int engine, double amt ) {
++      if ( engine == ALL_ENGINES ) {
++          for ( int i = 0; i < MAX_ENGINES; i++ ) {
++              throttle[i] += amt;
++              if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++              if ( throttle[i] >  1.0 ) throttle[i] =  1.0;
++          }
++      } else {
++          if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++              throttle[engine] += amt;
++              if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++              if ( throttle[engine] >  1.0 ) throttle[engine] =  1.0;
++          }
++      }
++    }
++    inline void set_brake( int wheel, double pos ) {
++      if ( wheel == ALL_WHEELS ) {
++          for ( int i = 0; i < MAX_WHEELS; i++ ) {
++              brake[i] = pos;
++              if ( brake[i] < 0.0 ) brake[i] = 0.0;
++              if ( brake[i] >  1.0 ) brake[i] =  1.0;
++          }
++      } else {
++          if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++              brake[wheel] = pos;
++              if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++              if ( brake[wheel] >  1.0 ) brake[wheel] =  1.0;
++          }
++      }
++    }
++    inline void move_brake( int wheel, double amt ) {
++      if ( wheel == ALL_WHEELS ) {
++          for ( int i = 0; i < MAX_WHEELS; i++ ) {
++              brake[i] += amt;
++              if ( brake[i] < 0.0 ) brake[i] = 0.0;
++              if ( brake[i] >  1.0 ) brake[i] =  1.0;
++          }
++      } else {
++          if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++              brake[wheel] += amt;
++              if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++              if ( brake[wheel] >  1.0 ) brake[wheel] =  1.0;
++          }
++      }
++    }
++};
++
++
++extern FGControls controls;
++
++
++#endif // _CONTROLS_HXX
++
++
++// $Log$
++// Revision 1.1  1999/02/13 01:12:03  curt
++// Initial Revision.
++//
++// Revision 1.3  1998/12/05 16:13:13  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2  1998/10/25 14:08:42  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1  1998/10/18 01:51:07  curt
++// c++-ifying ...
++//
++// Revision 1.17  1998/09/29 14:57:00  curt
++// c++-ified some comments.
++//
++// Revision 1.16  1998/09/29 02:01:32  curt
++// Added a brake.
++//
++// Revision 1.15  1998/04/25 22:06:27  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14  1998/04/22 13:26:19  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.13  1998/04/21 17:02:35  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.12  1998/02/09 22:56:48  curt
++// Removed "depend" files from cvs control.  Other minor make tweaks.
++//
++// Revision 1.11  1998/02/07 15:29:36  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10  1998/01/27 00:47:52  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9  1998/01/22 02:59:31  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8  1998/01/19 18:40:22  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7  1997/12/15 23:54:36  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6  1997/12/10 22:37:41  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.5  1997/08/27 03:30:02  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4  1997/07/23 21:52:18  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3  1997/05/31 19:16:27  curt
++// Elevator trim added.
++//
++// Revision 1.2  1997/05/23 15:40:33  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 15:59:48  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..92cae474beada3d2b88e3ac57608bbc8b536c249
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,52 @@@
++/*******************************************************************************
++
++ Header:       FGDefs.h
++ Author:       Jon S. Berndt
++ Date started: 02/01/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++02/01/99  JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGDEFS_H
++#define FGDEFS_H
++
++#define MAX_ENGINES     10
++#define MAX_TANKS       30
++#define GRAVITY         32.174
++#define EARTHRAD        20898908.00       // feet
++#define OMEGAEARTH      7.2685E-3         // rad/sec
++#define EARTHRADSQRD    437882827922500.0
++#define ONESECOND       4.848136811E-6
++#define ECCENT          0.996647186
++#define ECCENTSQRD      0.99330561
++#define INVECCENTSQRD   1.0067395
++#define INVECCENTSQRDM1 0.0067395
++#define EPS             0.081819221
++
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..275d793e511bb59643157ea07ef759d6d283aa68
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,177 @@@
++/*******************************************************************************
++
++ Module:       FGEngine.cpp
++ Author:       Jon Berndt
++ Date started: 01/21/99
++ Called by:    FGAircraft
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <fstream>
++#  else
++#    include <fstream.h>
++#  endif
++#else
++#  include <fstream>
++#endif
++
++#include "FGEngine.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int num)
++{
++  string fullpath;
++  string tag;
++
++  FDMExec = fdex;
++
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  Name = engineName;
++  fullpath = enginePath + "/" + engineName + ".dat";
++  ifstream enginefile(fullpath.c_str());
++
++  if (enginefile) {
++    enginefile >> tag;
++
++    if      (tag == "ROCKET")    Type = etRocket;
++    else if (tag == "PISTON")    Type = etPiston;
++    else if (tag == "TURBOPROP") Type = etTurboProp;
++    else if (tag == "TURBOJET")  Type = etTurboJet;
++    else                         Type = etUnknown;
++
++    enginefile >> X;
++    enginefile >> Y;
++    enginefile >> Z;
++    enginefile >> SLThrustMax;
++    enginefile >> VacThrustMax;
++    enginefile >> MaxThrottle;
++    enginefile >> MinThrottle;
++    enginefile >> SLFuelFlowMax;
++    if (Type == 1)
++      enginefile >> SLOxiFlowMax;
++    enginefile.close();
++  } else {
++    cerr << "Unable to open engine definition file " << engineName << endl;
++  }
++
++  EngineNumber = num;
++  Thrust = 0.0;
++  Starved = Flameout = false;
++}
++
++
++FGEngine::~FGEngine(void)
++{
++}
++
++
++float FGEngine::CalcRocketThrust(void)
++{
++  float lastThrust;
++
++  Throttle = FCS->GetThrottle(EngineNumber);
++  lastThrust = Thrust;                 // last actual thrust
++
++  if (Throttle < MinThrottle || Starved) {
++    PctPower = Thrust = 0.0; // desired thrust
++    Flameout = true;
++  } else {
++    PctPower = Throttle / MaxThrottle;
++    Thrust = PctPower*((1.0 - Atmosphere->Getrho() / 0.002378)*(VacThrustMax - SLThrustMax) +
++                             SLThrustMax); // desired thrust
++    Flameout = false;
++  }
++
++  Thrust += 0.8*(Thrust - lastThrust); // actual thrust
++
++  return Thrust;
++}
++
++
++float FGEngine::CalcPistonThrust(void)
++{
++  return Thrust;
++}
++
++
++float FGEngine::CalcThrust(void)
++{
++  switch(Type) {
++  case etRocket:
++    return CalcRocketThrust();
++    // break;
++  case etPiston:
++    return CalcPistonThrust();
++    // break;
++  default:
++    return 9999.0;
++    // break;
++  }
++}
++
++float FGEngine::CalcFuelNeed() {
++  FuelNeed = SLFuelFlowMax*PctPower;
++  return FuelNeed;
++}
++
++
++float FGEngine::CalcOxidizerNeed() {
++  OxidizerNeed = SLOxiFlowMax*PctPower;
++  return OxidizerNeed;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8ea2dada3f4c2914ffe19bfca61e42fc1692e403
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,133 @@@
++/*******************************************************************************
++
++ Header:       FGEngine.h
++ Author:       Jon S. Berndt
++ Date started: 01/21/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class simulates
++a generic engine.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGEngine_H
++#define FGEngine_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  include STL_STRING
++   FG_USING_STD(string);
++#else
++#  include <string>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGEngine
++{
++public:
++  FGEngine(FGFDMExec*, string, string, int);
++  ~FGEngine(void);
++
++  enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet};
++
++  float  GetThrottle(void) {return Throttle;}
++  float  GetThrust(void) {return Thrust;}
++  bool   GetStarved(void) {return Starved;}
++  bool   GetFlameout(void) {return Flameout;}
++  int    GetType(void) {return Type;}
++  string GetName() {return Name;}
++
++  void SetStarved(bool tt) {Starved = tt;}
++  void SetStarved(void) {Starved = true;}
++
++  float CalcThrust(void);
++  float CalcFuelNeed(void);
++  float CalcOxidizerNeed(void);
++
++private:
++  string Name;
++  EngineType Type;
++  float X, Y, Z;
++  float SLThrustMax;
++  float VacThrustMax;
++  float SLFuelFlowMax;
++  float SLOxiFlowMax;
++  float MaxThrottle;
++  float MinThrottle;
++
++  float Thrust;
++  float Throttle;
++  float FuelNeed, OxidizerNeed;
++  bool  Starved;
++  bool  Flameout;
++  float PctPower;
++  int   EngineNumber;
++
++  FGFDMExec*      FDMExec;
++  FGState*        State;
++  FGAtmosphere*   Atmosphere;
++  FGFCS*          FCS;
++  FGAircraft*     Aircraft;
++  FGTranslation*  Translation;
++  FGRotation*     Rotation;
++  FGPosition*     Position;
++  FGAuxiliary*    Auxiliary;
++  FGOutput*       Output;
++
++protected:
++  float CalcRocketThrust(void);
++  float CalcPistonThrust(void);
++
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..04bfb388035b327636af0248083333f8c83a30a9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,74 @@@
++/*******************************************************************************
++
++ Module:       FGFCS.cpp
++ Author:       Jon Berndt
++ Date started: 12/12/98
++ Purpose:      Model the flight controls
++ Called by:    FDMExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class models the flight controls for a specific airplane
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGFCS.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGFCS";
++}
++
++
++FGFCS::~FGFCS(void)
++{
++}
++
++
++bool FGFCS::Run(void)
++{
++  if (!FGModel::Run()) {
++    
++  } else {
++  }
++  return false;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..809980042a8ff098d055b626f33c8c5dae3c4389
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++/*******************************************************************************
++
++ Header:       FGGFCS.h
++ Author:       Jon S. Berndt
++ Date started: 12/12/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGFCS_H
++#define FGFCS_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++
++class FGFCS : public FGModel
++{
++public:
++      FGFCS(FGFDMExec*);
++      ~FGFCS(void);
++
++      bool Run(void);
++  
++      inline float GetDa(void) {return Da;}
++      inline float GetDe(void) {return De;}
++      inline float GetDr(void) {return Dr;}
++      inline float GetDf(void) {return Df;}
++      inline float GetDs(void) {return Ds;}
++      inline float GetThrottle(int ii) {return Throttle[ii];}
++
++      inline void SetDa(float tt) {Da = tt;}
++      inline void SetDe(float tt) {De = tt;}
++      inline void SetDr(float tt) {Dr = tt;}
++      inline void SetDf(float tt) {Df = tt;}
++      inline void SetDs(float tt) {Ds = tt;}
++      inline void SetThrottle(int ii, float tt) {Throttle[ii] = tt;}
++
++protected:
++
++private:
++  float Da, De, Dr, Df, Ds;
++  float Throttle[MAX_ENGINES];
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9f4adfa80eaabe15242519689b812d81b70220d7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,174 @@@
++/*******************************************************************************
++
++ Module:       FGFDMExec.cpp
++ Author:       Jon S. Berndt
++ Date started: 11/17/98
++ Purpose:      Schedules and runs the model routines.
++ Called by:    The GUI.
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++This class wraps up the simulation scheduling routines.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <iostream>
++#    include <ctime>
++#  else
++#    include <iostream.h>
++#    include <time.h>
++#  endif
++#else
++#  include <iostream>
++#  include <ctime>
++#endif
++
++#include "FGFDMExec.h"
++#include "FGState.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++// Constructor
++
++FGFDMExec::FGFDMExec(void)
++{
++  FirstModel  = 0;
++  Error       = 0;
++  State       = 0;
++  Atmosphere  = 0;
++  FCS         = 0;
++  Aircraft    = 0;
++  Translation = 0;
++  Rotation    = 0;
++  Position    = 0;
++  Auxiliary   = 0;
++  Output      = 0;
++
++  // Instantiate this FDM Executive's Models
++
++  Atmosphere  = new FGAtmosphere(this);
++  FCS         = new FGFCS(this);
++  Aircraft    = new FGAircraft(this);
++  Translation = new FGTranslation(this);
++  Rotation    = new FGRotation(this);
++  Position    = new FGPosition(this);
++  Auxiliary   = new FGAuxiliary(this);
++  Output      = new FGOutput(this);
++
++  State       = new FGState(this);
++
++  // Initialize models so they can communicate with each other
++
++  if (!Atmosphere->InitModel()) {cerr << "Atmosphere model init failed"; Error+=1;}
++  if (!FCS->InitModel())        {cerr << "FCS model init failed"; Error+=2;}
++  if (!Aircraft->InitModel())   {cerr << "Aircraft model init failed"; Error+=4;}
++  if (!Translation->InitModel()){cerr << "Translation model init failed"; Error+=8;}
++  if (!Rotation->InitModel())   {cerr << "Rotation model init failed"; Error+=16;}
++  if (!Position->InitModel())   {cerr << "Position model init failed"; Error+=32;}
++  if (!Auxiliary->InitModel())  {cerr << "Auxiliary model init failed"; Error+=64;}
++  if (!Output->InitModel())     {cerr << "Output model init failed"; Error+=128;}
++
++  Schedule(Atmosphere,  5);
++  Schedule(FCS,         1);
++  Schedule(Aircraft,    1);
++  Schedule(Rotation,    1);
++  Schedule(Translation, 1);
++  Schedule(Position,    1);
++  Schedule(Auxiliary,   1);
++  Schedule(Output,      5);
++
++  terminate = false;
++  frozen = false;
++}
++
++
++FGFDMExec::~FGFDMExec(void)
++{
++}
++
++
++int FGFDMExec::Schedule(FGModel* model, int rate)
++{
++  FGModel* model_iterator;
++
++  model_iterator = FirstModel;
++
++  if (model_iterator == 0L) {                  // this is the first model
++
++    FirstModel = model;
++    FirstModel->NextModel = 0L;
++    FirstModel->SetRate(rate);
++
++  } else {                                     // subsequent model
++
++    while (model_iterator->NextModel != 0L) {
++      model_iterator = model_iterator->NextModel;
++    }
++    model_iterator->NextModel = model;
++    model_iterator->NextModel->SetRate(rate);
++
++  }
++  return 0;
++}
++
++
++bool FGFDMExec::Run(void)
++{
++  FGModel* model_iterator;
++
++  if (frozen) return true;
++
++  model_iterator = FirstModel;
++  if (model_iterator == 0L) return false;
++
++  while (!model_iterator->Run())
++  {
++    model_iterator = model_iterator->NextModel;
++    if (model_iterator == 0L) break;
++  }
++
++  State->IncrTime();
++
++  return true;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7997a1cfebd3a1539e965e9caed87dd1cc66c982
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,100 @@@
++/*******************************************************************************
++
++ Header:       FGFDMExec.h
++ Author:       Jon Berndt
++ Date started: 11/17/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGFDMEXEC_HEADER_H
++#define FGFDMEXEC_HEADER_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGFDMExec
++{
++public:
++  FGFDMExec::FGFDMExec(void);
++  FGFDMExec::~FGFDMExec(void);
++
++  FGModel* FirstModel;
++
++  bool Initialize(void);
++  int  Schedule(FGModel* model, int rate);
++  bool Run(void);
++  void Freeze(void) {frozen = true;}
++  void Resume(void) {frozen = false;}
++
++  inline FGState* GetState(void)             {return State;}
++  inline FGAtmosphere* GetAtmosphere(void)   {return Atmosphere;}
++  inline FGFCS* GetFCS(void)                 {return FCS;}
++  inline FGAircraft* GetAircraft(void)       {return Aircraft;}
++  inline FGTranslation* GetTranslation(void) {return Translation;}
++  inline FGRotation* GetRotation(void)       {return Rotation;}
++  inline FGPosition* GetPosition(void)       {return Position;}
++  inline FGAuxiliary* GetAuxiliary(void)     {return Auxiliary;}
++  inline FGOutput* GetOutput(void)           {return Output;}
++
++private:
++  bool frozen;
++  bool terminate;
++  int Error;
++
++  FGState*       State;
++  FGAtmosphere*  Atmosphere;
++  FGFCS*         FCS;
++  FGAircraft*    Aircraft;
++  FGTranslation* Translation;
++  FGRotation*    Rotation;
++  FGPosition*    Position;
++  FGAuxiliary*   Auxiliary;
++  FGOutput*      Output;
++
++protected:
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93ac279ef8ac9296aa476c14e826e97f8250b698
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,41 @@@
++#include "FGFDMExec.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++#include <iostream>
++#include <ctime>
++
++void main(int argc, char** argv)
++{
++      FGFDMExec* FDMExec;
++      
++  struct timespec short_wait = {0,100000000};
++  struct timespec no_wait    = {0,100000000};
++
++  if (argc != 3) {
++    cout << endl
++         << "  You must enter the name of a registered aircraft and reset point:"
++         << endl << endl << "  FDM <aircraft name> <reset file>" << endl;
++    exit(0);
++  }
++
++  FDMExec = new FGFDMExec();
++
++  FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
++  FDMExec->GetState()->Reset("aircraft", string(argv[2]));
++
++  while (FDMExec->GetState()->Getsim_time() <= 25.0)
++  {
++    FDMExec->Run();
++    nanosleep(&short_wait,&no_wait);
++  }
++
++  delete FDMExec;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..680ca1a20a54a74ba3ff8611c6f6dcec6891d9cc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,397 @@@
++/*******************************************************************************
++
++Module: FGMatrix.cpp
++Author: Tony Peden [formatted here by JSB]
++Date started: ??
++Purpose: FGMatrix class
++Called by: Various
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++
++ARGUMENTS
++--------------------------------------------------------------------------------
++
++
++HISTORY
++--------------------------------------------------------------------------------
++??/??/??   TP   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include <stdlib.h>
++#include "FGMatrix.h"
++#include <iostream.h>
++#include <iomanip.h>
++#include <fstream.h>
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++#pragma warn -use
++
++/*******************************************************************************
++CONSTANTS
++*******************************************************************************/
++
++
++/*******************************************************************************
++TYPEDEFS
++*******************************************************************************/
++
++
++/*******************************************************************************
++GLOBALS
++*******************************************************************************/
++
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++double** alloc(int rows,int cols)
++{
++  double **A;
++
++  A = new double *[rows+1];
++  if (!A)     return NULL;
++
++  for (int i=0;i<=rows;i++){
++    A[i]=new double[cols+1];
++    if (!A[i]) return NULL;
++  }
++  return A;
++}
++
++
++void dealloc(double **A, int rows, int cols)
++{
++  for(int i=0;i<=rows;i++){
++    delete[] A[i];
++  }
++
++  delete[] A;
++}
++
++
++FGMatrix::FGMatrix(unsigned rows, unsigned cols)
++{
++  this->rows=rows;
++  this->cols=cols;
++  keep=false;
++  data=alloc(rows,cols);
++}
++
++
++FGMatrix::FGMatrix(const FGMatrix& A)
++{
++  data=NULL;
++  *this=A;
++}
++
++
++FGMatrix::~FGMatrix(void)
++{
++  if (keep == false) {
++    dealloc(data,rows,cols);
++    rows=cols=0;
++  }
++}
++
++
++FGMatrix& FGMatrix::operator=(const FGMatrix& A)
++{
++  if (&A != this) {
++    if (data != NULL) dealloc(data,rows,cols);
++    
++    width  = A.width;
++    prec   = A.prec;
++    delim  = A.delim;
++    origin = A.origin;
++    rows   = A.rows;
++    cols   = A.cols;
++    keep   = false;
++    
++    if (A.keep  == true) {
++      data = A.data;
++    } else {
++      data = alloc(rows,cols);
++      for (int i=0; i<=rows; i++) {
++            for (int j=0; j<=cols; j++) {
++                    data[i][j] = A.data[i][j];
++            }
++      }
++    }
++  }
++  return *this;
++}
++
++
++double& FGMatrix::operator()(unsigned row, unsigned col)
++{
++  return data[row][col];
++}
++
++
++unsigned FGMatrix::Rows(void) const
++{
++  return rows;
++}
++
++
++unsigned FGMatrix::Cols(void) const
++{
++  return cols;
++}
++
++
++void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
++{
++  FGMatrix::delim=delim;
++  FGMatrix::width=width;
++  FGMatrix::prec=prec;
++  FGMatrix::origin=origin;
++}
++
++
++void FGMatrix::InitMatrix(double value)
++{
++  if (data) {
++    for (int i=0;i<=rows;i++) {
++                      for (int j=0;j<=cols;j++) {
++              operator()(i,j) = value;
++                      }
++              }
++      }
++}
++
++
++void FGMatrix::InitMatrix(void)
++{
++      this->InitMatrix(0);
++}
++
++
++FGMatrix operator-(FGMatrix& A, FGMatrix& B)
++{
++      if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++              cout << endl << "FGMatrix::operator-" << endl << '\t';
++              cout << "Subtraction not defined for matrices of different sizes";
++    cout << endl;
++              exit(1);
++      }
++
++  FGMatrix Diff(A.Rows(),A.Cols());
++  Diff.keep=true;
++  for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++                      Diff(i,j)=A(i,j)-B(i,j);
++              }
++      }
++      return Diff;
++}
++
++
++void operator-=(FGMatrix &A,FGMatrix &B)
++{
++      if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++              cout << endl << "FGMatrix::operator-" << endl << '\t';
++              cout << "Subtraction not defined for matrices of different sizes";
++    cout << endl;
++              exit(1);
++      }
++
++  for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++                      A(i,j)-=B(i,j);
++              }
++      }
++}
++
++
++FGMatrix operator+(FGMatrix& A, FGMatrix& B)
++{
++      if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++              cout << endl << "FGMatrix::operator+" << endl << '\t';
++              cout << "Addition not defined for matrices of different sizes";
++    cout << endl;
++              exit(1);
++      }
++
++  FGMatrix Sum(A.Rows(),A.Cols());
++  Sum.keep = true;
++      for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++                      Sum(i,j)=A(i,j)+B(i,j);
++              }
++      }
++      return Sum;
++}
++
++
++void operator+=(FGMatrix &A,FGMatrix &B)
++{
++      if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++              cout << endl << "FGMatrix::operator+" << endl << '\t';
++              cout << "Addition not defined for matrices of different sizes";
++    cout << endl;
++              exit(1);
++      }
++  for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++                      A(i,j)+=B(i,j);
++              }
++      }
++}
++
++
++FGMatrix operator*(double scalar,FGMatrix &A)
++{
++      FGMatrix Product(A.Rows(),A.Cols());
++  Product.keep = true;
++      for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++      Product(i,j) = scalar*A(i,j);
++    }
++      }
++      return Product;
++}
++
++
++void operator*=(FGMatrix &A,double scalar)
++{
++      for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++) {
++      A(i,j)*=scalar;
++    }
++  }
++}
++
++
++FGMatrix operator*(FGMatrix &Left, FGMatrix &Right)
++{
++      if (Left.Cols() != Right.Rows()) {
++              cout << endl << "FGMatrix::operator*" << endl << '\t';
++              cout << "The number of rows in the right matrix must match the number";
++              cout << endl << '\t' << "of columns in the left." << endl;
++              cout << '\t' << "Multiplication not defined." << endl;
++              exit(1);
++      }
++
++      FGMatrix Product(Left.Rows(),Right.Cols());
++      Product.keep = true;
++      for (int i=1;i<=Left.Rows();i++) {
++              for (int j=1;j<=Right.Cols();j++)       {
++      Product(i,j) = 0;
++      for (int k=1;k<=Left.Cols();k++) {
++                      Product(i,j)+=Left(i,k)*Right(k,j);
++      }
++              }
++      }
++      return Product;
++}
++
++
++void operator*=(FGMatrix &Left,FGMatrix &Right)
++{
++      if (Left.Cols() != Right.Rows()) {
++              cout << endl << "FGMatrix::operator*" << endl << '\t';
++              cout << "The number of rows in the right matrix must match the number";
++              cout << endl << '\t' << "of columns in the left." << endl;
++              cout << '\t' << "Multiplication not defined." << endl;
++              exit(1);
++      }
++
++      double **prod;
++
++              prod=alloc(Left.Rows(),Right.Cols());
++              for (int i=1;i<=Left.Rows();i++) {
++                      for (int j=1;j<=Right.Cols();j++) {
++              prod[i][j] = 0;
++                              for (int k=1;k<=Left.Cols();k++) {
++              prod[i][j]+=Left(i,k)*Right(k,j);
++                              }
++                      }
++              }
++              dealloc(Left.data,Left.Rows(),Left.Cols());
++              Left.data=prod;
++              Left.cols=Right.cols;
++}
++
++
++FGMatrix operator/(FGMatrix& A, double scalar)
++{
++      FGMatrix Quot(A.Rows(),A.Cols());
++      A.keep = true;
++      for (int i=1;i<=A.Rows();i++) {
++              for (int j=1;j<=A.Cols();j++)   {
++              Quot(i,j)=A(i,j)/scalar;
++              }
++      }
++      return Quot;
++}
++
++
++void operator/=(FGMatrix &A,double scalar)
++{
++      for (int i=1;i<=A.Rows();i++)   {
++              for (int j=1;j<=A.Cols();j++) {
++                      A(i,j)/=scalar;
++              }
++      }
++}
++
++
++void FGMatrix::T(void)
++{
++      if (rows==cols)
++              TransposeSquare();
++      else
++              TransposeNonSquare();
++}
++
++
++void FGMatrix::TransposeSquare(void)
++{
++      for (int i=1;i<=rows;i++) {
++              for (int j=i+1;j<=cols;j++) {
++                      double tmp=data[i][j];
++                      data[i][j]=data[j][i];
++                      data[j][i]=tmp;
++              }
++      }
++}
++
++
++void FGMatrix::TransposeNonSquare(void)
++{
++      double **tran;
++
++      tran=alloc(rows,cols);
++      for (int i=1;i<=rows;i++) {
++              for (int j=1;j<=cols;j++) {
++                      tran[j][i]=data[i][j];
++              }
++      }
++      dealloc(data,rows,cols);
++
++      data=tran;
++      unsigned m=rows;
++      rows=cols;
++      cols=m;
++}
++
++
++FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
++FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
++FGColumnVector::FGColumnVector(FGColumnVector& b):FGMatrix(b) { }
++FGColumnVector::~FGColumnVector() { }
++double& FGColumnVector::operator()(int m)
++{
++      return FGMatrix::operator()(m,1);
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b3591b9462613108027d7e0d5d367994911dcc09
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,98 @@@
++/*******************************************************************************
++
++Header: FGMatrix.h
++Author: Tony Peden [formatted here by Jon Berndt]
++Date started: Unknown
++
++HISTORY
++--------------------------------------------------------------------------------
++??/??/??   TP   Created
++
++/*******************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGMATRIX_H
++#define FGMATRIX_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include <stdlib.h>
++#include <iostream.h>
++#include <fstream.h>
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++
++/*******************************************************************************
++CONSTANTS
++*******************************************************************************/
++
++
++/*******************************************************************************
++TYPEDEFS
++*******************************************************************************/
++
++
++/*******************************************************************************
++GLOBALS
++*******************************************************************************/
++
++class FGMatrix
++{
++private:
++  double **data;
++  unsigned rows,cols;
++  bool keep;
++  char delim;
++  int width,prec,origin;
++  void TransposeSquare(void);
++  void TransposeNonSquare(void);
++
++public:
++  FGMatrix(unsigned rows, unsigned cols);
++  FGMatrix(const FGMatrix& A);
++  ~FGMatrix(void);
++
++  FGMatrix& FGMatrix::operator=(const FGMatrix& A);
++  double& FGMatrix::operator()(unsigned row, unsigned col);
++
++  unsigned FGMatrix::Rows(void) const;
++  unsigned FGMatrix::Cols(void) const;
++
++  void FGMatrix::T(void);
++  void InitMatrix(void);
++  void InitMatrix(double value);
++
++  friend FGMatrix operator-(FGMatrix& A, FGMatrix& B);
++  friend FGMatrix operator+(FGMatrix& A, FGMatrix& B);
++  friend FGMatrix operator*(double scalar,FGMatrix& A);
++  friend FGMatrix operator*(FGMatrix& Left, FGMatrix& Right);
++  friend FGMatrix operator/(FGMatrix& A, double scalar);
++
++  friend void operator-=(FGMatrix &A,FGMatrix &B);
++  friend void operator+=(FGMatrix &A,FGMatrix &B);
++  friend void operator*=(FGMatrix &A,FGMatrix &B);
++  friend void operator*=(FGMatrix &A,double scalar);
++  friend void operator/=(FGMatrix &A,double scalar);
++
++  void SetOParams(char delim,int width,int prec, int origin=0);
++};
++
++class FGColumnVector : public FGMatrix
++{
++public:
++  FGColumnVector(void);
++  FGColumnVector(int m);
++  FGColumnVector(FGColumnVector& b);
++  ~FGColumnVector();
++
++  double& operator()(int m);
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..95807830d75dcfcde782749c0761a499f3257180
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,117 @@@
++/*******************************************************************************
++
++ Module:       FGModel.cpp
++ Author:       Jon Berndt
++ Date started: 11/11/98
++ Purpose:      Base class for all models
++ Called by:    FGSimExec, et. al.
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This base class for the FGAero, FGRotational, etc. classes defines methods
++common to all models.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/11/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGModel::FGModel(FGFDMExec* fdmex)
++{
++  FDMExec     = fdmex;
++  NextModel   = 0L;
++  
++  State       = 0;
++  Atmosphere  = 0;
++  FCS         = 0;
++  Aircraft    = 0;
++  Translation = 0;
++  Rotation    = 0;
++  Position    = 0;
++  Auxiliary   = 0;
++  Output      = 0;
++
++  exe_ctr     = 1;
++}
++
++
++FGModel::~FGModel()
++{
++}
++
++
++bool FGModel::InitModel(void)
++{
++  State       = FDMExec->GetState();
++  Atmosphere  = FDMExec->GetAtmosphere();
++  FCS         = FDMExec->GetFCS();
++  Aircraft    = FDMExec->GetAircraft();
++  Translation = FDMExec->GetTranslation();
++  Rotation    = FDMExec->GetRotation();
++  Position    = FDMExec->GetPosition();
++  Auxiliary   = FDMExec->GetAuxiliary();
++  Output      = FDMExec->GetOutput();
++
++  if (!State ||
++      !Atmosphere ||
++      !FCS ||
++      !Aircraft ||
++      !Translation ||
++      !Rotation ||
++      !Position ||
++      !Auxiliary ||
++      !Output) return(false);
++  else return(true);
++}
++
++
++bool FGModel::Run()
++{
++  if (exe_ctr == 1) {
++    if (exe_ctr++ >= rate) exe_ctr = 1;
++    return false;
++  } else {
++    if (exe_ctr++ >= rate) exe_ctr = 1;
++    return true;
++  }
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c5cec51c5fc974e653119832f244601a3f2b42fc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,107 @@@
++/*******************************************************************************
++
++ Header:       FGModel.h
++ Author:       Jon Berndt
++ Date started: 11/21/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/22/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGMODEL_H
++#define FGMODEL_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGDefs.h"
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  include STL_STRING
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <iostream>
++#  else
++#    include <iostream.h>
++#  endif
++   FG_USING_STD(string);
++#else
++#  include <string>
++#  include <iostream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGModel
++{
++public:
++  FGModel(FGFDMExec*);
++  ~FGModel(void);
++
++  FGModel* NextModel;
++  string Name;
++  virtual bool Run(void);
++  virtual bool InitModel(void);
++  void SetRate(int tt) {rate = tt;};
++
++protected:
++  int exe_ctr;
++  int rate;
++  
++  FGFDMExec*      FDMExec;
++  FGState*        State;
++  FGAtmosphere*   Atmosphere;
++  FGFCS*          FCS;
++  FGAircraft*     Aircraft;
++  FGTranslation*  Translation;
++  FGRotation*     Rotation;
++  FGPosition*     Position;
++  FGAuxiliary*    Auxiliary;
++  FGOutput*       Output;
++
++private:
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f327e6b4f81189c6408339985aa2d59613f41ab7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,222 @@@
++/*******************************************************************************
++
++ Module:       FGOutput.cpp
++ Author:       Jon Berndt
++ Date started: 12/02/98
++ Purpose:      Manage output of sim parameters to file or stdout
++ Called by:    FGSimExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This is the place where you create output routines to dump data for perusal
++later. Some machines may not support the ncurses console output. Borland is one
++of those environments which does not, so the ncurses stuff is commented out.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <iostream>
++#  else
++#    include <iostream.h>
++#  endif
++#else
++#  include <iostream>
++#endif
++
++#ifdef HAVE_CURSES
++  #include <ncurses.h>
++#endif
++
++#include "FGOutput.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGOutput";
++  FirstPass = true;
++#ifdef HAVE_CURSES
++  initscr();
++  cbreak();
++  noecho();
++#endif
++}
++
++
++FGOutput::~FGOutput(void)
++{
++}
++
++
++bool FGOutput::Run(void)
++{
++  if (!FGModel::Run()) {
++    DelimitedOutput();
++//    ConsoleOutput();
++  } else {
++  }
++  return false;
++}
++
++
++void FGOutput::ConsoleOutput(void)
++{
++#ifdef HAVE_CURSES
++  string buffer;
++
++  clear();
++  move(1,1);  insstr("Quaternions");
++  move(2,5);  insstr("Q0");
++  move(2,16); insstr("Q1");
++  move(2,27); insstr("Q2");
++  move(2,38); insstr("Q3");
++
++  move(3,1);  buffer = Rotation->GetQ0(); insstr(buffer.c_str());
++  move(3,12); buffer = Rotation->GetQ1(); insstr(buffer.c_str());
++  move(3,23); buffer = Rotation->GetQ2(); insstr(buffer.c_str());
++  move(3,34); buffer = Rotation->GetQ3(); insstr(buffer.c_str());
++
++  move(0,0); insstr("Time: ");
++  move(0,6); insstr(gcvt(State->Getsim_time(),6,buffer));
++
++  move(2,46); insstr("Phi");
++  move(2,55); insstr("Tht");
++  move(2,64); insstr("Psi");
++
++  move(3,45); buffer = Rotation->Getphi(); insstr(buffer.c_str());
++  move(3,54); buffer = Rotation->Gettht(); insstr(buffer.c_str());
++  move(3,63); buffer = Rotation->Getpsi(); insstr(buffer.c_str());
++
++  move(5,47); insstr("U");
++  move(5,56); insstr("V");
++  move(5,65); insstr("W");
++
++  move(6,45); buffer = Translation->GetU(); insstr(buffer.c_str());
++  move(6,54); buffer = Translation->GetV(); insstr(buffer.c_str());
++  move(6,63); buffer = Translation->GetW(); insstr(buffer.c_str());
++
++  move(8,47); insstr("Fx");
++  move(8,56); insstr("Fy");
++  move(8,65); insstr("Fz");
++
++  move(9,45); buffer = Aircraft->GetFx(); insstr(buffer.c_str());
++  move(9,54); buffer = Aircraft->GetFy(); insstr(buffer.c_str());
++  move(9,63); buffer = Aircraft->GetFz(); insstr(buffer.c_str());
++
++  move(11,47); insstr("Fn");
++  move(11,56); insstr("Fe");
++  move(11,65); insstr("Fd");
++
++  move(12,45); buffer = Position->GetFn(); insstr(buffer.c_str());
++  move(12,54); buffer = Position->GetFe(); insstr(buffer.c_str());
++  move(12,63); buffer = Position->GetFd(); insstr(buffer.c_str());
++
++  move(14,47); insstr("Latitude");
++  move(14,57); insstr("Longitude");
++  move(14,67); insstr("Altitude");
++
++  move(15,47); buffer = State->Getlatitude(); insstr(buffer.c_str());
++  move(15,57); buffer = State->Getlongitude(); insstr(buffer.c_str());
++  move(15,67); buffer = State->Geth(); insstr(buffer.c_str());
++
++  refresh();
++
++  move(LINES-1,1);
++  refresh();
++#endif
++}
++
++
++void FGOutput::DelimitedOutput(void)
++{
++  if (FirstPass) {
++    cout << "Time,";
++    cout << "Altitude,";
++    cout << "Phi,";
++    cout << "Tht,";
++    cout << "Psi,";
++    cout << "Rho,";
++    cout << "Vtotal,";
++    cout << "U,";
++    cout << "V,";
++    cout << "W,";
++    cout << "Vn,";
++    cout << "Ve,";
++    cout << "Vd,";
++    cout << "Udot,";
++    cout << "Vdot,";
++    cout << "Wdot,";
++    cout << "Fx,";
++    cout << "Fy,";
++    cout << "Fz,";
++    cout << "Latitude,";
++    cout << "Longitude,";
++    cout << "QBar,";
++    cout << "Alpha";
++    cout << endl;
++    FirstPass = false;
++  } else {
++    cout << State->Getsim_time() << ",";
++    cout << State->Geth() << ",";
++    cout << Rotation->Getphi() << ",";
++    cout << Rotation->Gettht() << ",";
++    cout << Rotation->Getpsi() << ",";
++    cout << Atmosphere->Getrho() << ",";
++    cout << State->GetVt() << ",";
++    cout << Translation->GetU() << ",";
++    cout << Translation->GetV() << ",";
++    cout << Translation->GetW() << ",";
++    cout << Position->GetVn() << ",";
++    cout << Position->GetVe() << ",";
++    cout << Position->GetVd() << ",";
++    cout << Translation->GetUdot() << ",";
++    cout << Translation->GetVdot() << ",";
++    cout << Translation->GetWdot() << ",";
++    cout << Aircraft->GetFx() << ",";
++    cout << Aircraft->GetFy() << ",";
++    cout << Aircraft->GetFz() << ",";
++    cout << State->Getlatitude() << ",";
++    cout << State->Getlongitude() << ",";
++    cout << State->Getqbar() << ",";
++    cout << Translation->Getalpha() << "";
++    cout << endl;
++  }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2ec4e7a95cd491fe7ce0811aee2c6ca20788aaca
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,66 @@@
++/*******************************************************************************
++
++ Header:       FGOutput.h
++ Author:       Jon Berndt
++ Date started: 12/2/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGOUTPUT_H
++#define FGOUTPUT_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGOutput : public FGModel
++{
++public:
++  FGOutput(FGFDMExec*);
++  ~FGOutput(void);
++
++  bool Run(void);
++
++  void ConsoleOutput(void);
++  void DelimitedOutput(void);
++
++protected:
++
++private:
++  bool FirstPass;
++};
++
++/******************************************************************************/
++#endif
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2f7eb655c03fa6b5679383a277ea2449b55b0c63
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,189 @@@
++/*******************************************************************************
++
++ Module:       FGPosition.cpp
++ Author:       Jon S. Berndt
++ Date started: 01/05/99
++ Purpose:      Integrate the EOM to determine instantaneous position
++ Called by:    FGFDMExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class encapsulates the integration of rates and accelerations to get the
++current position of the aircraft.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/05/99   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++    Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++    School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++    JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++    NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++    Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++    1982 ISBN 0-471-08936-2
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGPosition.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGPosition";
++  AccelN = AccelE = AccelD = 0.0;
++  LongitudeDot = LatitudeDot = RadiusDot = 0.0;
++}
++
++
++FGPosition::~FGPosition(void)
++{
++}
++
++
++bool FGPosition:: Run(void)
++{
++  float tanLat, cosLat;
++
++  if (!FGModel::Run()) {
++    GetState();
++    T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3;                    // Page A-11
++    T[1][2] = 2*(Q1*Q2 + Q0*Q3);                                // From
++    T[1][3] = 2*(Q1*Q3 - Q0*Q2);                                // Reference [2]
++    T[2][1] = 2*(Q1*Q2 - Q0*Q3);
++    T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
++    T[2][3] = 2*(Q2*Q3 + Q0*Q1);
++    T[3][1] = 2*(Q1*Q3 + Q0*Q2);
++    T[3][2] = 2*(Q2*Q3 - Q0*Q1);
++    T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
++
++    Fn = T[1][1]*Fx + T[2][1]*Fy + T[3][1]*Fz;                  // Eqn. 3.5
++    Fe = T[1][2]*Fx + T[2][2]*Fy + T[3][2]*Fz;                  // From
++    Fd = T[1][3]*Fx + T[2][3]*Fy + T[3][3]*Fz;                  // Reference [3]
++
++    tanLat = tan(Latitude);                                     // I made this up
++    cosLat = cos(Latitude);
++
++    lastAccelN = AccelN;
++    lastAccelE = AccelE;
++    lastAccelD = AccelD;
++
++    Vn = T[1][1]*U + T[2][1]*V + T[3][1]*W;
++    Ve = T[1][2]*U + T[2][2]*V + T[3][2]*W;
++    Vd = T[1][3]*U + T[2][3]*V + T[3][3]*W;
++
++    AccelN = invMass * Fn + invRadius * (Vn*Vd - Ve*Ve*tanLat); // Eqn. 3.6
++    AccelE = invMass * Fe + invRadius * (Ve*Vd + Vn*Ve*tanLat); // From
++    AccelD = invMass * Fd - invRadius * (Vn*Vn + Ve*Ve);        // Reference [3]
++
++    Vn += 0.5*dt*rate*(3.0*AccelN - lastAccelN);                // Eqn. 3.7
++    Ve += 0.5*dt*rate*(3.0*AccelE - lastAccelE);                // From
++    Vd += 0.5*dt*rate*(3.0*AccelD - lastAccelD);                // Reference [3]
++
++    Vee = Ve - OMEGAEARTH * (Radius) * cosLat;                  // From Eq. 3.8
++                                                                // Reference [3]
++    lastLatitudeDot = LatitudeDot;
++    lastLongitudeDot = LongitudeDot;
++    lastRadiusDot = RadiusDot;
++
++    if (cosLat != 0) LongitudeDot = Ve / (Radius * cosLat);
++    LatitudeDot = Vn * invRadius;
++    RadiusDot = -Vd;
++
++    Longitude += 0.5*dt*rate*(LongitudeDot + lastLongitudeDot);
++    Latitude  += 0.5*dt*rate*(LatitudeDot + lastLatitudeDot);
++    Radius    += 0.5*dt*rate*(RadiusDot + lastRadiusDot);
++
++    PutState();
++    return false;
++  } else {
++    return true;
++  }
++}
++
++
++void FGPosition::GetState(void)
++{
++  dt = State->Getdt();
++
++  Q0 = Rotation->GetQ0();
++  Q1 = Rotation->GetQ1();
++  Q2 = Rotation->GetQ2();
++  Q3 = Rotation->GetQ3();
++
++  Fx = Aircraft->GetFx();
++  Fy = Aircraft->GetFy();
++  Fz = Aircraft->GetFz();
++
++  U = Translation->GetU();
++  V = Translation->GetV();
++  W = Translation->GetW();
++
++  Latitude = State->Getlatitude();
++  Longitude = State->Getlongitude();
++
++  invMass = 1.0 / Aircraft->GetMass();
++  invRadius = 1.0 / (State->Geth() + EARTHRAD);
++  Radius = State->Geth() + EARTHRAD;
++}
++
++
++void FGPosition::PutState(void)
++{
++  State->Setlatitude(Latitude);
++  State->Setlongitude(Longitude);
++  State->Seth(Radius - EARTHRAD);
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ab04df424c80565faa080896114cfcfe26618e02
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,96 @@@
++/*******************************************************************************
++
++ Header:       FGPosition.h
++ Author:       Jon S. Berndt
++ Date started: 1/5/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/05/99   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGPOSITION_H
++#define FGPOSITION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGPosition : public FGModel
++{
++public:
++  FGPosition(FGFDMExec*);
++  ~FGPosition(void);
++
++  inline float GetFn(void) {return Fn;}
++  inline float GetFe(void) {return Fe;}
++  inline float GetFd(void) {return Fd;}
++
++  inline float GetVn(void) {return Vn;}
++  inline float GetVe(void) {return Ve;}
++  inline float GetVd(void) {return Vd;}
++
++  inline float GetT(int r, int c) {return T[r][c];}
++  inline void SetT(float t1, float t2, float t3, float t4, float t5, float t6,
++                                                   float t7, float t8, float t9)
++                                         {T[1][1]=t1; T[1][2]=t2 ;T[1][3]=t3;
++                                          T[2][1]=t4; T[2][2]=t5 ;T[2][3]=t6;
++                                          T[3][1]=t7; T[3][2]=t8 ;T[3][3]=t9;}
++
++  bool Run(void);
++
++protected:
++
++private:
++  float T[4][4];
++  float Q0, Q1, Q2, Q3;
++  float Fn, Fe, Fd;
++  float Fx, Fy, Fz;
++  float U, V, W;
++  float Vn, Ve, Vd, Vee;
++  float invMass, invRadius;
++  float Radius;
++  float AccelN, AccelE, AccelD;
++  float lastAccelN, lastAccelE, lastAccelD;
++  float LatitudeDot, LongitudeDot, RadiusDot;
++  float lastLatitudeDot, lastLongitudeDot, lastRadiusDot;
++  float Longitude, Latitude;
++  float dt;
++
++  void GetState(void);
++  void PutState(void);
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..494d9da663e6b8aac80d487fc2123cb111d82fd1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,176 @@@
++/*******************************************************************************
++
++ Module:       FGRotation.cpp
++ Author:       Jon Berndt
++ Date started: 12/02/98
++ Purpose:      Integrates the rotational EOM
++ Called by:    FGFDMExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class integrates the rotational EOM.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++    Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++    School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++    JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++    NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++    Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++    1982 ISBN 0-471-08936-2
++
++  The order of rotations used in this class corresponds to a 3-2-1 sequence,
++  or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGRotation";
++  Q0dot = Q1dot = Q2dot = Q3dot = 0.0;
++  Pdot = Qdot = Rdot = 0.0;
++}
++
++
++FGRotation::~FGRotation(void)
++{
++}
++
++
++bool FGRotation::Run(void)
++{
++  float L2, N1, iQtot, sum;
++
++  if (!FGModel::Run()) {
++    GetState();
++
++    lastPdot = Pdot;
++    lastQdot = Qdot;
++    lastRdot = Rdot;
++
++    L2 = L + Ixz*P*Q - (Izz-Iyy)*R*Q;
++    N1 = N - (Iyy-Ixx)*P*Q - Ixz*R*Q;
++
++    Pdot = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz);
++    Qdot = (M - (Ixx-Izz)*P*R - Ixz*(P*P - R*R))/Iyy;
++    Rdot = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
++
++    P += dt*rate*(lastPdot + Pdot)/2.0;
++    Q += dt*rate*(lastQdot + Qdot)/2.0;
++    R += dt*rate*(lastRdot + Rdot)/2.0;
++
++    lastQ0dot = Q0dot;
++    lastQ1dot = Q1dot;
++    lastQ2dot = Q2dot;
++    lastQ3dot = Q3dot;
++
++    Q0dot = -0.5*(Q1*P + Q2*Q + Q3*R);
++    Q1dot =  0.5*(Q0*P + Q2*R - Q3*Q);
++    Q2dot =  0.5*(Q0*Q + Q3*P - Q1*R);
++    Q3dot =  0.5*(Q0*R + Q1*Q - Q2*P);
++
++    Q0 += 0.5*dt*rate*(lastQ0dot + Q0dot);
++    Q1 += 0.5*dt*rate*(lastQ1dot + Q1dot);
++    Q2 += 0.5*dt*rate*(lastQ2dot + Q2dot);
++    Q3 += 0.5*dt*rate*(lastQ3dot + Q3dot);
++
++    sum = Q0*Q0 + Q1*Q1 + Q2*Q2 + Q3*Q3;
++
++    iQtot = 1.0 / sqrt(sum);
++
++    Q0 *= iQtot;
++    Q1 *= iQtot;
++    Q2 *= iQtot;
++    Q3 *= iQtot;
++
++    if (T[3][3] == 0)
++      phi = 0.0;
++    else
++      phi = atan2(T[2][3], T[3][3]);
++
++    tht = asin(-T[1][3]);
++
++    if (T[1][1] == 0.0)
++      psi = 0.0;
++    else
++      psi = atan2(T[1][2], T[1][1]);
++
++    if (psi < 0.0) psi += 2*M_PI;
++
++    PutState();
++  } else {
++  }
++  return false;
++}
++
++
++void FGRotation::GetState(void)
++{
++  dt = State->Getdt();
++
++  L = Aircraft->GetL();
++  M = Aircraft->GetM();
++  N = Aircraft->GetN();
++
++  Ixx = Aircraft->GetIxx();
++  Iyy = Aircraft->GetIyy();
++  Izz = Aircraft->GetIzz();
++  Ixz = Aircraft->GetIxz();
++
++  for (int r=1;r<=3;r++)
++    for (int c=1;c<=3;c++)
++      T[r][c] = Position->GetT(r,c);
++}
++
++
++void FGRotation::PutState(void)
++{
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e0b40894bed7cd8ff7792ea68eb11325ed6e8c26
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,142 @@@
++/*******************************************************************************
++
++ Header:       FGRotation.h
++ Author:       Jon Berndt
++ Date started: 12/02/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++    Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++    School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++    JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++    NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++    Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++    1982 ISBN 0-471-08936-2
++
++  The order of rotations used in this class corresponds to a 3-2-1 sequence,
++  or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGROTATION_H
++#define FGROTATION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGRotation : public FGModel
++{
++public:
++  FGRotation(FGFDMExec*);
++  ~FGRotation(void);
++
++  bool Run(void);
++
++  inline float GetP(void) {return P;}
++  inline float GetQ(void) {return Q;}
++  inline float GetR(void) {return R;}
++
++  inline float GetPdot(void) {return Pdot;}
++  inline float GetQdot(void) {return Qdot;}
++  inline float GetRdot(void) {return Rdot;}
++
++  inline float Getphi(void) {return phi;}
++  inline float Gettht(void) {return tht;}
++  inline float Getpsi(void) {return psi;}
++
++  inline float GetQ0(void) {return Q0;}
++  inline float GetQ1(void) {return Q1;}
++  inline float GetQ2(void) {return Q2;}
++  inline float GetQ3(void) {return Q3;}
++
++  inline void SetP(float tt) {P = tt;}
++  inline void SetQ(float tt) {Q = tt;}
++  inline void SetR(float tt) {R = tt;}
++
++  inline void SetPQR(float t1, float t2, float t3) {P=t1;
++                                                    Q=t2;
++                                                    R=t3;}
++
++  inline void Setphi(float tt) {phi = tt;}
++  inline void Settht(float tt) {tht = tt;}
++  inline void Setpsi(float tt) {psi = tt;}
++
++  inline void SetEuler(float t1, float t2, float t3) {phi=t1;
++                                                      tht=t2;
++                                                      psi=t3;}
++
++  inline void SetQ0123(float t1, float t2, float t3, float t4) {Q0=t1;
++                                                                Q1=t2;
++                                                                Q2=t3;
++                                                                Q3=t4;}
++
++protected:
++
++private:
++  float P, Q, R;
++  float L, M, N;
++  float Ixx, Iyy, Izz, Ixz;
++  float Q0, Q1, Q2, Q3;
++  float phi, tht, psi;
++  float Pdot, Qdot, Rdot;
++  float Q0dot, Q1dot, Q2dot, Q3dot;
++  float lastPdot, lastQdot, lastRdot;
++  float lastQ0dot, lastQ1dot, lastQ2dot, lastQ3dot;
++  float dt;
++  float T[4][4];
++
++  void GetState(void);
++  void PutState(void);
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..92ffa9de41a946335c1ed534ac10fcde7541937f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,259 @@@
++/*******************************************************************************
++                                                                       
++ Module:       FGState.cpp
++ Author:       Jon Berndt
++ Date started: 11/17/98
++ Called by:    FGFDMExec and accessed by all models.
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGState::FGState(FGFDMExec* fdex)
++{
++  FDMExec = fdex;
++
++  Vt = 0.0;
++  latitude = longitude = 0.0;
++  adot = bdot = 0.0;
++  h = 0.0;
++  a = 1000.0;
++  qbar = 0.0;
++  sim_time = dt = 0.1;
++}
++
++
++FGState::~FGState(void)
++{
++}
++
++
++bool FGState::Reset(string path, string fname)
++{
++  string resetDef;
++  float U, V, W;
++  float phi, tht, psi;
++  float alpha, beta, gamma;
++  float Q0, Q1, Q2, Q3;
++  float T[4][4];
++
++  resetDef = path + "/" + FDMExec->GetAircraft()->GetAircraftName() + "/" + fname;
++
++  ifstream resetfile(resetDef.c_str());
++
++  if (resetfile) {
++    resetfile >> U;
++    resetfile >> V;
++    resetfile >> W;
++    resetfile >> latitude;
++    resetfile >> longitude;
++    resetfile >> phi;
++    resetfile >> tht;
++    resetfile >> psi;
++    resetfile >> h;
++    resetfile.close();
++
++// Change all angular measurements from degrees (as in config file) to radians
++
++    gamma = 0.0;
++    if (W != 0.0)
++      alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
++    else
++      alpha = 0.0;
++    if (V != 0.0)
++      beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
++    else
++      beta = 0.0;
++
++    latitude  *= M_PI / 180.0;
++    longitude *= M_PI / 180.0;
++    phi       *= M_PI / 180.0;
++    tht       *= M_PI / 180.0;
++    psi       *= M_PI / 180.0;
++
++    FDMExec->GetTranslation()->SetUVW(U, V, W);
++    FDMExec->GetRotation()->SetEuler(phi, tht, psi);
++    FDMExec->GetTranslation()->SetABG(alpha, beta, gamma);
++
++    Vt = sqrt(U*U + V*V + W*W);
++    qbar = sqrt(U*U + V*V + W*W);
++
++    Q0 =  sin(psi*0.5)*sin(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*cos(phi*0.5);
++    Q1 = -sin(psi*0.5)*sin(tht*0.5)*cos(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*sin(phi*0.5);
++    Q2 =  sin(psi*0.5)*cos(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*sin(tht*0.5)*cos(phi*0.5);
++    Q3 =  sin(psi*0.5)*cos(tht*0.5)*cos(phi*0.5) - cos(psi*0.5)*sin(tht*0.5)*sin(phi*0.5);
++
++    FDMExec->GetRotation()->SetQ0123(Q0, Q1, Q2, Q3);
++
++    T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3;
++    T[1][2] = 2*(Q1*Q2 + Q0*Q3);
++    T[1][3] = 2*(Q1*Q3 - Q0*Q2);
++    T[2][1] = 2*(Q1*Q2 - Q0*Q3);
++    T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
++    T[2][3] = 2*(Q2*Q3 + Q0*Q1);
++    T[3][1] = 2*(Q1*Q3 + Q0*Q2);
++    T[3][2] = 2*(Q2*Q3 - Q0*Q1);
++    T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
++
++    FDMExec->GetPosition()->SetT(T[1][1], T[1][2], T[1][3],
++                                 T[2][1], T[2][2], T[2][3],
++                                 T[3][1], T[3][2], T[3][3]);
++
++    return true;
++  } else {
++    cerr << "Unable to load reset file " << fname << endl;
++    return false;
++  }
++}
++
++
++bool FGState::StoreData(string fname)
++{
++  ofstream datafile(fname.c_str());
++
++  if (datafile) {
++    datafile << FDMExec->GetTranslation()->GetU();
++    datafile << FDMExec->GetTranslation()->GetV();
++    datafile << FDMExec->GetTranslation()->GetW();
++    datafile << latitude;
++    datafile << longitude;
++    datafile << FDMExec->GetRotation()->Getphi();
++    datafile << FDMExec->GetRotation()->Gettht();
++    datafile << FDMExec->GetRotation()->Getpsi();
++    datafile << h;
++    datafile.close();
++    return true;
++  } else {
++    cerr << "Could not open dump file " << fname << endl;
++    return false;
++  }
++}
++
++
++bool FGState::DumpData(string fname)
++{
++  ofstream datafile(fname.c_str());
++
++  if (datafile) {
++    datafile << "U: " << FDMExec->GetTranslation()->GetU() << endl;
++    datafile << "V: " << FDMExec->GetTranslation()->GetV() << endl;
++    datafile << "W: " << FDMExec->GetTranslation()->GetW() << endl;
++    datafile << "P: " << FDMExec->GetRotation()->GetP() << endl;
++    datafile << "Q: " << FDMExec->GetRotation()->GetQ() << endl;
++    datafile << "R: " << FDMExec->GetRotation()->GetR() << endl;
++    datafile << "L: " << FDMExec->GetAircraft()->GetL() << endl;
++    datafile << "M: " << FDMExec->GetAircraft()->GetM() << endl;
++    datafile << "N: " << FDMExec->GetAircraft()->GetN() << endl;
++    datafile << "latitude: " << latitude << endl;
++    datafile << "longitude: " << longitude << endl;
++    datafile << "alpha: " << FDMExec->GetTranslation()->Getalpha() << endl;
++    datafile << "beta: " << FDMExec->GetTranslation()->Getbeta() << endl;
++    datafile << "gamma: " << FDMExec->GetTranslation()->Getgamma() << endl;
++    datafile << "phi: " << FDMExec->GetRotation()->Getphi() << endl;
++    datafile << "tht: " << FDMExec->GetRotation()->Gettht() << endl;
++    datafile << "psi: " << FDMExec->GetRotation()->Getpsi() << endl;
++    datafile << "Pdot: " << FDMExec->GetRotation()->GetPdot() << endl;
++    datafile << "Qdot: " << FDMExec->GetRotation()->GetQdot() << endl;
++    datafile << "Rdot: " << FDMExec->GetRotation()->GetRdot() << endl;
++    datafile << "h: " << h << endl;
++    datafile << "a: " << a << endl;
++    datafile << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
++    datafile << "qbar: " << qbar << endl;
++    datafile << "sim_time: " << sim_time << endl;
++    datafile << "dt: " << dt << endl;
++    datafile << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
++    datafile.close();
++    return true;
++  } else {
++    return false;
++  }
++}
++
++
++bool FGState::DisplayData(void)
++{
++  cout << "U: " << FDMExec->GetTranslation()->GetU() << endl;
++  cout << "V: " << FDMExec->GetTranslation()->GetV() << endl;
++  cout << "W: " << FDMExec->GetTranslation()->GetW() << endl;
++  cout << "P: " << FDMExec->GetRotation()->GetP() << endl;
++  cout << "Q: " << FDMExec->GetRotation()->GetQ() << endl;
++  cout << "R: " << FDMExec->GetRotation()->GetR() << endl;
++  cout << "L: " << FDMExec->GetAircraft()->GetL() << endl;
++  cout << "M: " << FDMExec->GetAircraft()->GetM() << endl;
++  cout << "N: " << FDMExec->GetAircraft()->GetN() << endl;
++  cout << "Vt: " << Vt << endl;
++  cout << "latitude: " << latitude << endl;
++  cout << "longitude: " << longitude << endl;
++  cout << "alpha: " << FDMExec->GetTranslation()->Getalpha() << endl;
++  cout << "beta: " << FDMExec->GetTranslation()->Getbeta() << endl;
++  cout << "gamma: " << FDMExec->GetTranslation()->Getgamma() << endl;
++  cout << "phi: " << FDMExec->GetRotation()->Getphi() << endl;
++  cout << "tht: " << FDMExec->GetRotation()->Gettht() << endl;
++  cout << "psi: " << FDMExec->GetRotation()->Getpsi() << endl;
++  cout << "Pdot: " << FDMExec->GetRotation()->GetPdot() << endl;
++  cout << "Qdot: " << FDMExec->GetRotation()->GetQdot() << endl;
++  cout << "Rdot: " << FDMExec->GetRotation()->GetRdot() << endl;
++  cout << "h: " << h << endl;
++  cout << "a: " << a << endl;
++  cout << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
++  cout << "qbar: " << qbar << endl;
++  cout << "sim_time: " << sim_time << endl;
++  cout << "dt: " << dt << endl;
++  cout << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
++
++  return true;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a5cf6a8f4e0623351c7d7e10463b83848046ee74
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,139 @@@
++/*******************************************************************************
++
++ Header:       FGState.h
++ Author:       Jon S. Berndt
++ Date started: 11/17/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class wraps all
++global state variables (such as velocity, position, orientation, etc.).
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGSTATE_H
++#define FGSTATE_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  include STL_STRING
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <fstream>
++#  else
++#    include <fstream.h>
++#  endif
++   FG_USING_STD(string);
++#else
++#  include <string>
++#  include <fstream>
++#endif
++
++#include "FGDefs.h"
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState
++{
++public:
++   FGState(FGFDMExec*);
++  ~FGState(void);
++
++  bool Reset(string, string);
++  bool StoreData(string);
++  bool DumpData(string);
++  bool DisplayData(void);
++
++  inline float GetVt(void) {return Vt;}
++
++  inline float Getlatitude(void) {return latitude;}
++  inline float Getlongitude(void) {return longitude;}
++  inline float GetGeodeticLat(void) {return GeodeticLat;}
++
++  inline float Getadot(void) {return adot;}
++  inline float Getbdot(void) {return bdot;}
++
++  inline float Geth(void) {return h;}
++  inline float Geta(void) {return a;}
++  inline float GetMach(void) {return Mach;}
++
++  inline float Getsim_time(void) {return sim_time;}
++  inline float Getdt(void) {return dt;}
++
++  inline float Getqbar(void) {return qbar;}
++
++  inline void SetVt(float tt) {Vt = tt;}
++
++  inline void Setlatitude(float tt) {latitude = tt;}
++  inline void Setlongitude(float tt) {longitude = tt;}
++  inline void SetGeodeticLat(float tt) {GeodeticLat = tt;}
++
++  inline void Setadot(float tt) {adot = tt;}
++  inline void Setbdot(float tt) {bdot = tt;}
++
++  inline void Setqbar(float tt) {qbar = tt;}
++
++  inline void Seth(float tt) {h = tt;}
++  inline void Seta(float tt) {a = tt;}
++  inline void SetMach(float tt) {Mach = tt;}
++
++  inline float Setsim_time(float tt) {sim_time = tt; return sim_time;}
++  inline void  Setdt(float tt) {dt = tt;}
++
++  inline float IncrTime(void) {sim_time+=dt;return sim_time;}
++
++private:
++
++  float Vt;                         // Total velocity
++  float latitude, longitude;        // position
++  float GeodeticLat;                // Geodetic Latitude
++  float adot, bdot;                 // alpha dot and beta dot
++  float h, a;                       // altitude above sea level, speed of sound
++  float qbar;                       // dynamic pressure
++  float sim_time, dt;
++  float Mach;                       // Mach number
++
++  FGFDMExec* FDMExec;
++
++protected:
++
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ea118069547dfd3046e5f94f5b4d7b8b6894d993
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,85 @@@
++/*******************************************************************************
++
++ Module:       FGTank.cpp
++ Author:       Jon Berndt
++ Date started: 01/21/99
++ Called by:    FGAircraft
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99   JSB   Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGTank.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGTank::FGTank(ifstream& acfile)
++{
++  string type;
++
++  acfile >> type;                              // Type = 0: fuel, 1: oxidizer
++  if (type == "FUEL") Type = ttFUEL;
++  else if (type == "OXIDIZER") Type = ttOXIDIZER;
++  else Type = ttUNKNOWN;
++  acfile >> X;                                 // inches
++  acfile >> Y;                                 // "
++  acfile >> Z;                                 // "
++  acfile >> Radius;                            // "
++  acfile >> Capacity;                          // pounds (amount it can hold)
++  acfile >> Contents;                          // pounds  (amount it is holding)
++  Selected = true;
++  PctFull = 100.0*Contents/Capacity;           // percent full; 0 to 100.0
++}
++
++
++FGTank::~FGTank(void)
++{
++}
++
++
++float FGTank::Reduce(float used)
++{
++  float shortage;
++
++  if (used < Contents) {
++    Contents -= used;
++    PctFull = 100.0*Contents/Capacity;
++    return Contents;
++  } else {
++    shortage = Contents - used;
++    Contents = 0.0;
++    PctFull = 0.0;
++    Selected = false;
++    return shortage;
++  }
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a41841c8555f87ebc2981479ff512d11c632279f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,95 @@@
++/*******************************************************************************
++
++ Header:       FGTank.h
++ Author:       Jon S. Berndt
++ Date started: 01/21/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class simulates
++a generic Tank.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGTank_H
++#define FGTank_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  include STL_STRING
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <fstream>
++#  else
++#    include <fstream.h>
++#  endif
++   FG_USING_STD(string);
++#else
++#  include <string>
++#  include <fstream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGTank
++{
++public:
++  FGTank(ifstream&);
++  ~FGTank(void);
++
++  float Reduce(float);
++  int GetType(void) {return Type;}
++  bool GetSelected(void) {return Selected;}
++  float GetPctFull(void) {return PctFull;}
++  float GetContents(void) {return Contents;}
++
++  enum TankType {ttUNKNOWN, ttFUEL, ttOXIDIZER};
++  
++private:
++  TankType Type;
++  float X, Y, Z;
++  float Capacity;
++  float Radius;
++  float PctFull;
++  float Contents;
++  bool  Selected;
++
++protected:
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..63db8801f32b84febddbb528007a06c0abd173e2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,146 @@@
++/*******************************************************************************
++
++ Module:       FGTranslation.cpp
++ Author:       Jon Berndt
++ Date started: 12/02/98
++ Purpose:      Integrates the translational EOM
++ Called by:    FDMExec
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class integrates the translational EOM.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++    Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++    School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++    JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++    NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++    Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++    1982 ISBN 0-471-08936-2
++
++  The order of rotations used in this class corresponds to a 3-2-1 sequence,
++  or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++  Name = "FGTranslation";
++  Udot = Vdot = Wdot = 0.0;
++}
++
++
++FGTranslation::~FGTranslation(void)
++{
++}
++
++
++bool FGTranslation::Run(void)
++{
++  if (!FGModel::Run()) {
++
++    GetState();
++
++    lastUdot = Udot;
++    lastVdot = Vdot;
++    lastWdot = Wdot;
++
++    Udot = V*R - W*Q + Fx/Mass;
++    Vdot = W*P - U*R + Fy/Mass;
++    Wdot = U*Q - V*P + Fz/Mass;
++
++    U += 0.5*dt*rate*(lastUdot + Udot);
++    V += 0.5*dt*rate*(lastVdot + Vdot);
++    W += 0.5*dt*rate*(lastWdot + Wdot);
++
++    Vt = U*U+V*V+W*W > 0.0 ? sqrt(U*U + V*V + W*W) : 0.0;
++
++    if (W != 0.0)
++      alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
++    if (V != 0.0)
++      beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
++
++    qbar = 0.5*rho*Vt*Vt;
++
++    PutState();
++  } else {
++  }
++  return false;
++}
++
++
++void FGTranslation::GetState(void)
++{
++  dt = State->Getdt();
++
++  P = Rotation->GetP();
++  Q = Rotation->GetQ();
++  R = Rotation->GetR();
++
++  Fx = Aircraft->GetFx();
++  Fy = Aircraft->GetFy();
++  Fz = Aircraft->GetFz();
++
++  Mass = Aircraft->GetMass();
++  rho = Atmosphere->Getrho();
++
++  phi = Rotation->Getphi();
++  tht = Rotation->Gettht();
++  psi = Rotation->Getpsi();
++}
++
++
++void FGTranslation::PutState(void)
++{
++  State->SetVt(Vt);
++  State->Setqbar(qbar);
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bbc3dc297c5c6b8c4d938615131bbd6b5b72edb3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,127 @@@
++/*******************************************************************************
++
++ Header:       FGTranslation.h
++ Author:       Jon Berndt
++ Date started: 12/02/98
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98   JSB   Created
++
++********************************************************************************
++COMMENTS, REFERENCES,  and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++    Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
++    School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++    JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++    NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++    Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++    1982 ISBN 0-471-08936-2
++
++  The order of rotations used in this class corresponds to a 3-2-1 sequence,
++  or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGTRANSLATION_H
++#define FGTRANSLATION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGTranslation : public FGModel
++{
++public:
++   FGTranslation(FGFDMExec*);
++   ~FGTranslation(void);
++
++   inline float GetU(void) {return U;}
++   inline float GetV(void) {return V;}
++   inline float GetW(void) {return W;}
++
++   inline float GetUdot(void) {return Udot;}
++   inline float GetVdot(void) {return Vdot;}
++   inline float GetWdot(void) {return Wdot;}
++
++   inline float Getalpha(void) {return alpha;}
++   inline float Getbeta (void) {return beta; }
++   inline float Getgamma(void) {return gamma;}
++
++   inline void SetU(float tt) {U = tt;}
++   inline void SetV(float tt) {V = tt;}
++   inline void SetW(float tt) {W = tt;}
++
++   inline void SetUVW(float t1, float t2, float t3) {U=t1; V=t2; W=t3;}
++
++   inline void Setalpha(float tt) {alpha = tt;}
++   inline void Setbeta (float tt) {beta  = tt;}
++   inline void Setgamma(float tt) {gamma = tt;}
++
++   inline void SetABG(float t1, float t2, float t3) {alpha=t1; beta=t2; gamma=t3;}
++
++   bool Run(void);
++
++protected:
++
++private:
++  float U, V, W;                 // Body frame velocities owned by FGTranslation
++  float P, Q, R;
++  float Vt, qbar;
++  float Udot, Vdot, Wdot;
++  float lastUdot, lastVdot, lastWdot;
++  float phi, tht, psi;
++  float Fx, Fy, Fz;
++  float Mass, dt;
++  float alpha, beta, gamma;
++  float rho;
++
++  void GetState(void);
++  void PutState(void);
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f7e7d1de342d42b723d796087f740e3830199dbb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,132 @@@
++/*******************************************************************************
++
++ Module:       FGUtility.cpp
++ Author:       Jon Berndt
++ Date started: 01/09/99
++ Purpose:      Contains utility classes for the FG FDM
++ Called by:    FGPosition, et. al.
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class is a container for all utility classes used by the flight dynamics
++model.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/09/99   JSB   Created
++
++********************************************************************************
++DEFINES
++*******************************************************************************/
++                                                        
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++#  include <Include/compiler.h>
++#  ifdef FG_HAVE_STD_INCLUDES
++#    include <cmath>
++#  else
++#    include <math.h>
++#  endif
++#else
++#  include <cmath>
++#endif
++
++#include "FGUtility.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGUtility::FGUtility()
++{
++  // Move constant stuff to here (if any) so it won't take CPU time
++  // in the methods below.
++  SeaLevelR   = EARTHRAD * ECCENT;
++}
++
++
++FGUtility::~FGUtility()
++{
++}
++                       
++
++float FGUtility::ToGeodetic()
++{
++  float GeodeticLat, Latitude, Radius, Altitude;
++  float tanLat, xAlpha, muAlpha, sinmuAlpha, denom, rhoAlpha, dMu;
++  float lPoint, lambdaSL, sinlambdaSL, dLambda, rAlpha;
++
++  Latitude = State->Getlatitude();
++  Radius = State->Geth() + EARTHRAD;
++
++  if (( M_PI_2 - Latitude < ONESECOND) ||
++      ( M_PI_2 + Latitude < ONESECOND)) { // Near a pole
++    GeodeticLat = Latitude;
++    Altitude    = Radius - SeaLevelR;
++  } else {
++    tanLat = tan(Latitude);
++    xAlpha = ECCENT*EARTHRAD /
++                                sqrt(tanLat*tanLat + ECCENTSQRD);
++    muAlpha = atan2(sqrt(EARTHRADSQRD - xAlpha*xAlpha), ECCENT*xAlpha);
++
++    if (Latitude < 0.0) muAlpha = -muAlpha;
++
++    sinmuAlpha  = sin(muAlpha);
++    dLambda     = muAlpha - Latitude;
++    rAlpha      = xAlpha / cos(Latitude);
++    lPoint      = Radius - rAlpha;
++    Altitude    = lPoint*cos(dLambda);
++    denom       = sqrt(1-EPS*EPS*sinmuAlpha*sinmuAlpha);
++    rhoAlpha    = EARTHRAD*(1.0 - EPS) / (denom*denom*denom);
++    dMu         = atan2(lPoint*sin(dLambda),rhoAlpha + Altitude);
++    State->SetGeodeticLat(muAlpha - dMu);
++    lambdaSL    = atan(ECCENTSQRD*tan(GeodeticLat));
++    sinlambdaSL = sin(lambdaSL);
++    SeaLevelR   = sqrt(EARTHRADSQRD / (1 + INVECCENTSQRDM1* sinlambdaSL*sinlambdaSL));
++  }
++  return 0.0;
++}
++
++
++float FGUtility:: FromGeodetic()
++{
++  float lambdaSL, sinlambdaSL, coslambdaSL, sinMu, cosMu, py, px;
++  float Altitude, SeaLevelR;
++
++  lambdaSL = atan(ECCENTSQRD*tan(State->GetGeodeticLat()));
++  sinlambdaSL = sin(lambdaSL);
++  coslambdaSL = cos(lambdaSL);
++  sinMu = sin(State->GetGeodeticLat());
++  cosMu = cos(State->GetGeodeticLat());
++  SeaLevelR = sqrt(EARTHRADSQRD /
++             (1 + INVECCENTSQRDM1*sinlambdaSL*sinlambdaSL));
++  px = SeaLevelR*coslambdaSL + Altitude*cosMu;
++  py = SeaLevelR*sinlambdaSL + Altitude*sinMu;
++  State->Setlatitude(atan2(py,px));
++  return 0.0;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d5dc6499a71cb0d45d92fe8ea2524ee76aa8ba93
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,70 @@@
++/*******************************************************************************
++
++ Header:       FGUtility.h
++ Author:       Jon Berndt
++ Date started: 01/09/99
++
++ ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ This program is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free Software
++ Foundation; either version 2 of the License, or (at your option) any later
++ version.
++
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
++ details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ Place - Suite 330, Boston, MA  02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/09/99   JSB   Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGUTILITY_H
++#define FGUTILITY_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++
++class FGUtility
++{
++public:
++  FGUtility(void);
++  ~FGUtility(void);
++
++  float ToGeodetic(void);
++  float FromGeodetic(void);
++
++protected:
++
++private:
++  float SeaLevelR;
++  FGState* State;
++  FGFDMExec* FDMExec;
++};
++
++/******************************************************************************/
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bc540a476bf7714828207ceb7b520136a5333381
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++noinst_LIBRARIES = libJSBsim.a
++
++libJSBsim_a_SOURCES = FGAircraft.cpp FGAircraft.h \
++      FGAtmosphere.cpp FGAtmosphere.h \
++      FGAuxiliary.cpp FGAuxiliary.h \
++      FGCoefficient.cpp FGCoefficient.h \
++      FGDefs.h \
++      FGFCS.cpp FGFCS.h \
++      FGFDMExec.cpp FGFDMExec.h \
++      FGModel.cpp FGModel.h \
++      FGOutput.cpp FGOutput.h \
++      FGPosition.cpp FGPosition.h \
++      FGRotation.cpp FGRotation.h \
++      FGState.cpp FGState.h \
++      FGTranslation.cpp FGTranslation.h \
++      FGUtility.cpp FGUtility.h \
++      FGEngine.cpp FGEngine.h \
++      FGTank.cpp FGTank.h 
++
++INCLUDES += -I$(top_builddir)
++
++DEFS += -DFGFS
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..416b40d674a2c7f003a02d350f1f04213685b3bb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,16 @@@
++if ENABLE_LINUX_JOYSTICK
++DEFS += -DENABLE_LINUX_JOYSTICK
++else
++DEFS += -DENABLE_GLUT_JOYSTICK
++endif
++
++EXTRA_DIST = js.cxx
++
++noinst_LIBRARIES = libJoystick.a
++
++libJoystick_a_SOURCES = joystick.cxx joystick.hxx js.hxx
++
++INCLUDES += -I$(top_builddir) \
++      -I$(top_builddir)/Lib \
++      -I$(top_builddir)/Lib/plib/include \
++      -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b5bef52802ef7dfedaedd183a57145e2b6d77642
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,253 @@@
++// joystick.cxx -- joystick support
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#endif
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++#  include <js.h>
++#elif defined( ENABLE_GLUT_JOYSTICK )
++#  include <GL/glut.h>
++#  include <XGL/xgl.h>
++#endif
++
++
++#include "joystick.hxx"
++
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++// joystick classes
++static jsJoystick *js0;
++static jsJoystick *js1;
++
++// these will hold the values of the axes
++static float *js_ax0, *js_ax1;
++
++#elif defined( ENABLE_GLUT_JOYSTICK )
++
++// Do we want these user settable ??
++static float joy_scale = 1./1000;
++
++// play with following to get your desired sensitivity
++static int x_dead_zone = 50;
++static int y_dead_zone = 2*x_dead_zone;
++
++// Joystick support using glut -- William Riley -- riley@technologist.com
++
++// Joystick fixed values for calibration and scaling
++static float joy_x_max = joy_scale;
++static float joy_y_max = joy_scale;
++
++static int joy_z_min = 1000, /* joy_z_ctr=0, */ joy_z_max = -1000;
++static int joy_z_dead_min = 100, joy_z_dead_max = -100;
++
++#else
++#  error port me: no joystick support
++#endif
++
++
++
++#if defined( ENABLE_GLUT_JOYSTICK )
++
++// Function called by glutJoystickFunc(), adjusts read values and
++// passes them to the necessary aircraft control functions
++void joystick(unsigned int buttonMask, int js_x, int js_y, int js_z)
++{
++    float joy_x, joy_y, joy_z;
++    // adjust the values to fgfs's scale and allow a 'dead zone' to
++    // reduce jitter code adapted from joystick.c by Michele
++    // F. America - nomimarketing@mail.telepac.pt
++
++    if( js_x > -x_dead_zone && js_x < x_dead_zone) {
++      joy_x = 0.0;
++    } else {
++      joy_x = js_x * joy_scale;
++    }
++
++    if( js_y > -y_dead_zone && js_y < y_dead_zone) {
++      joy_y = 0.0;
++    } else {
++      joy_y = js_y * joy_scale;
++    }
++
++    if( js_z >= joy_z_dead_min && js_z <= joy_z_dead_max ) {
++      joy_z = 0.0;
++    }
++    joy_z = (float)js_z / (float)(joy_z_max - joy_z_min);
++    joy_z = (((joy_z*2.0)+1.0)/2);
++
++    // Pass the values to the control routines
++    controls.set_elevator( -joy_y );
++    controls.set_aileron( joy_x );
++    controls.set_throttle( FGControls::ALL_ENGINES, joy_z );
++}
++
++#endif // ENABLE_GLUT_JOYSTICK
++
++
++// Initialize the joystick(s)
++int fgJoystickInit( void ) {
++
++    FG_LOG( FG_INPUT, FG_INFO, "Initializing joystick" );
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++    js0 = new jsJoystick ( 0 );
++    js1 = new jsJoystick ( 1 );
++
++    if ( js0->notWorking () ) {
++      // not working
++    } else {
++      // allocate storage for axes values
++      js_ax0 = new float [ js0->getNumAxes() ];
++
++      // configure
++      js0->setDeadBand( 0, 0.1 );
++      js0->setDeadBand( 1, 0.1 );
++
++      FG_LOG ( FG_INPUT, FG_INFO, 
++               "  Joystick 0 detected with " << js0->getNumAxes() 
++               << " axes" );
++    }
++
++    if ( js1->notWorking () ) {
++      // not working
++    } else {
++      // allocate storage for axes values
++      js_ax1 = new float [ js1->getNumAxes() ];
++
++      // configure
++      js1->setDeadBand( 0, 0.1 );
++      js1->setDeadBand( 1, 0.1 );
++
++      FG_LOG ( FG_INPUT, FG_INFO,
++               "  Joystick 1 detected with " << js1->getNumAxes() 
++               << " axes" );
++    }
++
++    if ( js0->notWorking() && js1->notWorking() ) {
++      FG_LOG ( FG_INPUT, FG_INFO, "  No joysticks detected" );
++      return 0;
++    }
++
++#elif defined( ENABLE_GLUT_JOYSTICK )
++
++    glutJoystickFunc(joystick, 100);
++
++#else
++#  error port me: no joystick support
++#endif
++
++    return 1;
++}
++
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++// update the control parameters based on joystick intput
++int fgJoystickRead( void ) {
++    int b;
++
++    if ( ! js0->notWorking() ) {
++      js0->read( &b, js_ax0 ) ;
++      controls.set_aileron( js_ax0[0] );
++      controls.set_elevator( -js_ax0[1] );
++    }
++
++    if ( ! js1->notWorking() ) {
++      js1->read( &b, js_ax1 ) ;
++      controls.set_rudder( js_ax1[0] );
++      controls.set_throttle( FGControls::ALL_ENGINES, -js_ax1[1] * 1.05 );
++    }
++
++    return 1;
++}
++
++#endif // ENABLE_LINUX_JOYSTICK
++
++
++// $Log$
++// Revision 1.8  1999/04/03 04:20:33  curt
++// Integration of Steve's plib conglomeration.
++//
++// Revision 1.7  1999/01/19 17:52:30  curt
++// Some joystick tweaks by Norman Vine.
++//
++// Revision 1.6  1998/12/05 16:13:16  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.5  1998/11/06 21:18:04  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.4  1998/10/27 02:14:32  curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.3  1998/10/25 14:08:44  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2  1998/10/25 10:56:25  curt
++// Completely rewritten to use Steve Baker's joystick interface class.
++//
++// Revision 1.1  1998/10/24 22:28:16  curt
++// Renamed joystick.[ch] to joystick.[ch]xx
++// Added js.hxx which is Steve's joystick interface class.
++//
++// Revision 1.7  1998/04/25 22:06:29  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.6  1998/04/18 04:14:05  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.5  1998/02/12 21:59:44  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.4  1998/02/03 23:20:20  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.3  1998/01/27 00:47:54  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.2  1997/12/30 20:47:40  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.1  1997/08/29 18:06:54  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..23bebedc634f58746564b3f427d6fb9f39c81894
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,66 @@@
++// joystick.cxx -- joystick support
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _JOYSTICK_HXX
++#define _JOYSTICK_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// Initialize the joystick(s)
++int fgJoystickInit( void );
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++    // update the control parameters based on joystick intput
++    int fgJoystickRead( void );
++#endif // ENABLE_LINUX_JOYSTICK
++
++
++#endif // _JOYSTICK_HXX
++
++
++// $Log$
++// Revision 1.3  1998/10/27 02:14:33  curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.2  1998/10/25 10:56:27  curt
++// Completely rewritten to use Steve Baker's joystick interface class.
++//
++// Revision 1.1  1998/10/24 22:28:18  curt
++// Renamed joystick.[ch] to joystick.[ch]xx
++// Added js.hxx which is Steve's joystick interface class.
++//
++// Revision 1.3  1998/04/22 13:26:21  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.2  1998/01/22 02:59:36  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.1  1997/08/29 18:06:55  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..318df20b06a5da645c7052a1e29bb3f2e6e44f7a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,26 @@@
++if ENABLE_CHEROKEE
++AIRCRAFT_MODEL = cherokee_aero.c cherokee_engine.c cherokee_gear.c cherokee_init.c navion_init.h
++else
++AIRCRAFT_MODEL = navion_aero.c navion_engine.c navion_gear.c navion_init.c navion_init.h
++endif
++
++noinst_LIBRARIES = libLaRCsim.a
++
++libLaRCsim_a_SOURCES = \
++      atmos_62.c atmos_62.h \
++      default_model_routines.c default_model_routines.h \
++      ls_accel.c ls_accel.h \
++      ls_aux.c ls_aux.h \
++      ls_cockpit.h ls_constants.h ls_generic.h \
++      ls_geodesy.c ls_geodesy.h \
++      ls_gravity.c ls_gravity.h \
++      ls_init.c ls_init.h \
++      ls_matrix.c ls_matrix.h \
++      ls_model.c ls_model.h \
++      ls_sim_control.h \
++        ls_step.c ls_step.h \
++      ls_sym.h ls_types.h \
++      $(AIRCRAFT_MODEL) \
++      ls_interface.c ls_interface.h
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3c351882c6212dd4a8bc0952a4d1170a380ba447
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,272 @@@
++/***************************************************************************
++
++    TITLE:            atmos_62
++
++----------------------------------------------------------------------------
++
++    FUNCTION:         1962 atmosphere table interpolation routine
++
++----------------------------------------------------------------------------
++
++    MODULE STATUS:    developmental
++
++----------------------------------------------------------------------------
++
++    GENEALOGY:        Created 920827 by Bruce Jackson as part of the C-castle
++              development effort.
++
++----------------------------------------------------------------------------
++
++    DESIGNED BY:      B. Jackson
++
++    CODED BY:         B. Jackson
++
++    MAINTAINED BY:    B. Jackson
++
++----------------------------------------------------------------------------
++
++    MODIFICATION HISTORY:
++
++      DATE    PURPOSE                                                 BY
++      931220  Added ambient pressure and temperature as outputs.      EBJ
++      940111  Changed includes from "ls_eom.h" to "ls_types.h" and
++              "ls_constants.h"; changed DATA to SCALAR types.         EBJ
++
++----------------------------------------------------------------------------
++
++    REFERENCES:
++
++    [ 1]      Hornbeck, Robert W.: "Numerical Methods", Prentice-Hall,
++              1975.  ISBN  0-13-626614-2
++
++----------------------------------------------------------------------------
++
++    CALLED BY:
++
++----------------------------------------------------------------------------
++
++    CALLS TO:
++
++----------------------------------------------------------------------------
++
++    INPUTS:
++
++----------------------------------------------------------------------------
++
++    OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++
++#include "atmos_62.h"
++
++#include <math.h>
++
++#define       alt_0   d_a_table[index  ][0]
++#define       alt_1   d_a_table[index+1][0]
++#define       den_0   d_a_table[index  ][1]
++#define den_1 d_a_table[index+1][1]
++#define       sps_0   d_a_table[index  ][2]
++#define       sps_1   d_a_table[index+1][2]
++#define gden_0        d_a_table[index  ][3]
++#define       gden_1  d_a_table[index+1][3]
++#define       gsps_0  d_a_table[index  ][4]
++#define gsps_1        d_a_table[index+1][4]
++
++#define MAX_ALT_INDEX 121
++#define DELT_ALT 2000.
++#define HLEV 36089.
++#define TAMB0 518.7
++#define PAMB0 2113.8
++#define MAX_ALTITUDE 240000.
++
++void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound, 
++              SCALAR * t_amb, SCALAR * p_amb )
++{
++
++    int               index;
++    SCALAR    daltp, daltn, daltp3, daltn3, density;
++    SCALAR    t_amb_r, p_amb_r;
++    SCALAR      tmp;
++
++    static SCALAR     d_a_table[MAX_ALT_INDEX][5] =
++    {
++      {      0.,       2.37701E-03,    1.11642E+03,    0.00000E+00,    0.00000E+00    },
++      {   2000.,       2.24098E-03,    1.10872E+03,    1.92857E-12,   -1.75815E-08    },
++      {   4000.,       2.11099E-03,    1.10097E+03,    1.34570E-12,   -1.21740E-08    },
++      {   6000.,       1.98684E-03,    1.09315E+03,    1.44862E-12,   -1.47225E-08    },
++      {   8000.,       1.86836E-03,    1.08529E+03,    1.36481E-12,   -1.44359E-08    },
++      {  10000.,       1.75537E-03,    1.07736E+03,    1.32716E-12,   -1.45340E-08    },
++      {  12000.,       1.64768E-03,    1.06938E+03,    1.27657E-12,   -1.44280E-08    },
++      {  14000.,       1.54511E-03,    1.06133E+03,    1.24656E-12,   -1.62540E-08    },
++      {  16000.,       1.44751E-03,    1.05323E+03,    1.19220E-12,   -1.50560E-08    },
++      {  18000.,       1.35469E-03,    1.04506E+03,    1.15463E-12,   -1.65220E-08    },
++      {  20000.,       1.26649E-03,    1.03683E+03,    1.11926E-12,   -1.63562E-08    },
++      {  22000.,       1.18276E-03,    1.02853E+03,    1.07333E-12,   -1.70533E-08    },
++      {  24000.,       1.10333E-03,    1.02016E+03,    1.03743E-12,   -1.59305E-08    },
++      {  26000.,       1.02805E-03,    1.01173E+03,    1.00195E-12,   -2.27248E-08    },
++      {  28000.,       9.56760E-04,    1.00322E+03,    9.39764E-13,    3.29851E-10    },
++      {  30000.,       8.89320E-04,    9.94641E+02,    1.01399E-12,   -8.80946E-08    },
++      {  32000.,       8.25570E-04,    9.85988E+02,    5.39268E-13,    2.41048E-07    },
++      {  34000.,       7.65380E-04,    9.77258E+02,    2.16894E-12,   -9.91599E-07    },
++      {  36000.,       7.08600E-04,    9.68448E+02,   -4.10001E-12,    3.60535E-06    },
++      {  38000.,       6.44190E-04,    9.68053E+02,    2.78612E-12,   -8.07290E-07    },
++      {  40000.,       5.85146E-04,    9.68053E+02,    1.00455E-12,    2.16313E-07    },
++      {  42000.,       5.31517E-04,    9.68053E+02,    1.31819E-12,   -5.79609E-08    },
++      {  44000.,       4.82801E-04,    9.68053E+02,    1.09217E-12,    1.55309E-08    },
++      {  46000.,       4.38554E-04,    9.68053E+02,    1.01661E-12,   -4.16262E-09    },
++      {  48000.,       3.98359E-04,    9.68053E+02,    9.19375E-13,    1.11961E-09    },
++      {  50000.,       3.61850E-04,    9.68053E+02,    8.34886E-13,   -3.15801E-10    },
++      {  52000.,       3.28686E-04,    9.68053E+02,    7.58579E-13,    1.43600E-10    },
++      {  54000.,       2.98561E-04,    9.68053E+02,    6.89297E-13,   -2.58597E-10    },
++      {  56000.,       2.71197E-04,    9.68053E+02,    6.25735E-13,    8.90788E-10    },
++      {  58000.,       2.46341E-04,    9.68053E+02,    5.69765E-13,   -3.30456E-09    },
++      {  60000.,       2.23765E-04,    9.68053E+02,    5.15206E-13,    1.23274E-08    },
++      {  62000.,       2.03256E-04,    9.68053E+02,    4.69912E-13,   -4.60052E-08    },
++      {  64000.,       1.84627E-04,    9.68053E+02,    4.25146E-13,    1.71693E-07    },
++      {  66000.,       1.67616E-04,    9.68314E+02,    2.56502E-13,   -2.49268E-07    },
++      {  68000.,       1.51855E-04,    9.68676E+02,    4.23844E-13,    9.76878E-07    },
++      {  70000.,       1.37615E-04,    9.71034E+02,    3.29621E-13,   -6.64245E-07    },
++      {  72000.,       1.24744E-04,    9.72390E+02,    3.11170E-13,    1.77102E-07    },
++      {  74000.,       1.13107E-04,    9.73745E+02,    2.76697E-13,   -4.56627E-08    },
++      {  76000.,       1.02584E-04,    9.75099E+02,    2.53043E-13,    4.04902E-09    },
++      {  78000.,       9.30660E-05,    9.76450E+02,    2.18633E-13,    2.49667E-08    },
++      {  80000.,       8.44530E-05,    9.77799E+02,    2.29927E-13,   -1.06916E-07    },
++      {  82000.,       7.67140E-05,    9.78950E+02,    1.72660E-13,    1.05696E-07    },
++      {  84000.,       6.97010E-05,    9.80290E+02,    1.68432E-13,   -3.23682E-08    },
++      {  86000.,       6.33490E-05,    9.81620E+02,    1.45113E-13,    8.77690E-09    },
++      {  88000.,       5.75880E-05,    9.82950E+02,    1.37617E-13,   -2.73938E-09    },
++      {  90000.,       5.23700E-05,    9.84280E+02,    1.18918E-13,    2.18061E-09    },
++      {  92000.,       4.76350E-05,    9.85610E+02,    1.11210E-13,   -5.98306E-09    },
++      {  94000.,       4.33410E-05,    9.86930E+02,    9.77408E-14,    6.75162E-09    },
++      {  96000.,       3.94430E-05,    9.88260E+02,    9.18264E-14,   -6.02343E-09    },
++      {  98000.,       3.59080E-05,    9.89580E+02,    7.94534E-14,    2.34210E-09    },
++      { 100000.,       3.26960E-05,    9.90900E+02,    7.48600E-14,   -3.34498E-09    },
++      { 102000.,       2.97810E-05,    9.92210E+02,    6.66067E-14,   -3.96219E-09    },
++      { 104000.,       2.71320E-05,    9.93530E+02,    5.77131E-14,    3.41937E-08    },
++      { 106000.,       2.46980E-05,    9.95410E+02,    2.50410E-14,    7.07187E-07    },
++      { 108000.,       2.24140E-05,    9.99070E+02,    6.71229E-14,   -1.92943E-07    },
++      { 110000.,       2.03570E-05,    1.00272E+03,    4.69675E-14,    4.95832E-08    },
++      { 112000.,       1.85010E-05,    1.00636E+03,    4.65069E-14,   -2.03903E-08    },
++      { 114000.,       1.68270E-05,    1.00998E+03,    4.00047E-14,    1.97789E-09    },
++      { 116000.,       1.53150E-05,    1.01359E+03,    3.64744E-14,   -2.52130E-09    },
++      { 118000.,       1.39480E-05,    1.01719E+03,    3.15976E-14,   -6.89271E-09    },
++      { 120000.,       1.27100E-05,    1.02077E+03,    3.06351E-14,    9.21465E-11    },
++      { 122000.,       1.15920E-05,    1.02434E+03,    2.58618E-14,   -8.47587E-09    },
++      { 124000.,       1.05790E-05,    1.02789E+03,    2.34176E-14,    3.81135E-09    },
++      { 126000.,       9.66010E-06,    1.03144E+03,    2.16178E-14,   -6.76951E-09    },
++      { 128000.,       8.82710E-06,    1.03497E+03,    1.89611E-14,   -6.73330E-09    },
++      { 130000.,       8.07070E-06,    1.03848E+03,    1.74377E-14,    3.70270E-09    },
++      { 132000.,       7.38380E-06,    1.04199E+03,    1.55382E-14,   -8.07752E-09    },
++      { 134000.,       6.75940E-06,    1.04548E+03,    1.41595E-14,   -1.39263E-09    },
++      { 136000.,       6.19160E-06,    1.04896E+03,    1.27239E-14,   -1.35196E-09    },
++      { 138000.,       5.67490E-06,    1.05243E+03,    1.15951E-14,   -8.19953E-09    },
++      { 140000.,       5.20450E-06,    1.05588E+03,    1.03459E-14,    4.15010E-09    },
++      { 142000.,       4.77570E-06,    1.05933E+03,    9.42149E-15,   -8.40086E-09    },
++      { 144000.,       4.38470E-06,    1.06276E+03,    8.66820E-15,   -5.46671E-10    },
++      { 146000.,       4.02820E-06,    1.06618E+03,    7.65573E-15,   -4.41246E-09    },
++      { 148000.,       3.70260E-06,    1.06959E+03,    7.05890E-15,    3.19650E-09    },
++      { 150000.,       3.40520E-06,    1.07299E+03,    6.40867E-15,   -2.33736E-08    },
++      { 152000.,       3.13330E-06,    1.07637E+03,    5.55641E-15,    6.02977E-08    },
++      { 154000.,       2.88480E-06,    1.07975E+03,    6.46568E-15,   -2.17817E-07    },
++      { 156000.,       2.66270E-06,    1.08202E+03,    8.18087E-15,   -8.54029E-07    },
++      { 158000.,       2.46830E-06,    1.08202E+03,    2.36086E-15,    2.28931E-07    },
++      { 160000.,       2.28810E-06,    1.08202E+03,    3.67571E-15,   -6.16972E-08    },
++      { 162000.,       2.12120E-06,    1.08202E+03,    2.88632E-15,    1.78573E-08    },
++      { 164000.,       1.96640E-06,    1.08202E+03,    2.92903E-15,   -9.73206E-09    },
++      { 166000.,       1.82300E-06,    1.08202E+03,    2.49757E-15,    2.10709E-08    },
++      { 168000.,       1.69000E-06,    1.08202E+03,    2.68069E-15,   -7.45517E-08    },
++      { 170000.,       1.56680E-06,    1.08202E+03,    1.47966E-15,    2.77136E-07    },
++      { 172000.,       1.45250E-06,    1.08202E+03,    4.75068E-15,   -1.03399E-06    },
++      { 174000.,       1.35240E-06,    1.07963E+03,    8.17622E-16,    2.73830E-07    },
++      { 176000.,       1.25880E-06,    1.07723E+03,    1.72883E-15,   -7.63301E-08    },
++      { 178000.,       1.17130E-06,    1.07482E+03,    1.41704E-15,    1.64901E-08    },
++      { 180000.,       1.08960E-06,    1.07240E+03,    1.30299E-15,   -4.63038E-09    },
++      { 182000.,       1.01320E-06,    1.06998E+03,    1.32100E-15,    2.03140E-09    },
++      { 184000.,       9.41950E-07,    1.06756E+03,    1.13799E-15,   -3.49522E-09    },
++      { 186000.,       8.75370E-07,    1.06513E+03,    1.13202E-15,   -3.05052E-09    },
++      { 188000.,       8.13260E-07,    1.06269E+03,    1.03892E-15,    6.97283E-10    },
++      { 190000.,       7.55320E-07,    1.06025E+03,    9.67290E-16,    2.61383E-10    },
++      { 192000.,       7.01260E-07,    1.05781E+03,    9.11920E-16,   -1.74281E-09    },
++      { 194000.,       6.50850E-07,    1.05536E+03,    8.60032E-16,   -8.29013E-09    },
++      { 196000.,       6.03870E-07,    1.05290E+03,    7.92951E-16,    1.99033E-08    },
++      { 198000.,       5.60110E-07,    1.05044E+03,    7.98164E-16,   -7.13232E-08    },
++      { 200000.,       5.19320E-07,    1.04798E+03,    4.69394E-16,    2.65389E-07    },
++      { 202000.,       4.81340E-07,    1.04550E+03,    1.53926E-15,   -1.02023E-06    },
++      { 204000.,       4.47960E-07,    1.04063E+03,    2.73571E-16,    2.30547E-07    },
++      { 206000.,       4.16690E-07,    1.03565E+03,    5.31456E-16,   -6.69551E-08    },
++      { 208000.,       3.87320E-07,    1.03065E+03,    4.50605E-16,    7.27308E-09    },
++      { 210000.,       3.59790E-07,    1.02562E+03,    4.26126E-16,   -7.13720E-09    },
++      { 212000.,       3.33970E-07,    1.02057E+03,    4.09893E-16,   -8.72426E-09    },
++      { 214000.,       3.09780E-07,    1.01549E+03,    3.79301E-16,   -2.96576E-09    },
++      { 216000.,       2.87120E-07,    1.01039E+03,    3.67902E-16,   -9.41272E-09    },
++      { 218000.,       2.65920E-07,    1.00526E+03,    3.39092E-16,   -4.38337E-09    },
++      { 220000.,       2.46090E-07,    1.00011E+03,    3.30732E-16,   -3.05378E-09    },
++      { 222000.,       2.27570E-07,    9.94940E+02,    3.02981E-16,   -1.34015E-08    },
++      { 224000.,       2.10270E-07,    9.89730E+02,    2.87343E-16,   -3.34027E-09    },
++      { 226000.,       1.94120E-07,    9.84500E+02,    2.72646E-16,   -3.23743E-09    },
++      { 228000.,       1.79060E-07,    9.79250E+02,    2.57074E-16,   -1.37100E-08    },
++      { 230000.,       1.65030E-07,    9.73960E+02,    2.44060E-16,   -1.92258E-09    },
++      { 232000.,       1.51970E-07,    9.68650E+02,    2.21687E-16,   -8.59969E-09    },
++      { 234000.,       1.39810E-07,    9.63310E+02,    2.19191E-16,   -8.67865E-09    },
++      { 236000.,       1.28510E-07,    9.57940E+02,    1.91549E-16,   -1.68569E-09    },
++      { 238000.,       1.18020E-07,    9.52550E+02,    2.29613E-16,   -1.45786E-08    },
++      { 240000.,       1.08270E-07,    9.47120E+02,    0.00000E+00,    0.00000E+00    }
++    };
++
++    /* for purposes of doing the table lookup, force the incoming
++       altitude to be >= 0 */
++
++    // printf("altitude = %.2f\n", altitude);
++
++    if ( altitude < 0.0 ) {
++      altitude = 0.0;
++    }
++
++    // printf("altitude = %.2f\n", altitude);
++
++    index = (int)( altitude / 2000 );
++    if (index > (MAX_ALT_INDEX-2))
++    {
++     index = MAX_ALT_INDEX-2; /* limit maximum altitude */
++     altitude = MAX_ALTITUDE;
++    }
++    if (index < 0) index = 0;
++    daltp = alt_1 - altitude;
++    daltp3 = daltp*daltp*daltp;
++    daltn = altitude - alt_0;
++    daltn3 = daltn*daltn*daltn;
++    
++    density = (gden_0/6)*((daltp3/2000) - 2000*daltp)
++                          + (gden_1/6)*((daltn3/2000) - 2000*daltn)
++                          + den_0*daltp/2000 + den_1*daltn/2000;
++                          
++    *v_sound = (gsps_0/6)*((daltp3/2000) - 2000*daltp)
++                          + (gsps_1/6)*((daltn3/2000) - 2000*daltn)
++                          + sps_0*daltp/2000 + sps_1*daltn/2000;
++
++    *sigma = density/SEA_LEVEL_DENSITY;
++
++    if (altitude < HLEV)    /* BUG - these curve fits are only good to about 75000 ft */
++      {
++      t_amb_r = 1. - 6.875e-6*altitude;
++      // printf("index = %d  t_amb_r = %.2f\n", index, t_amb_r);
++      // p_amb_r = pow( t_amb_r, 5.256 );
++      tmp = 5.256; // avoid a segfault (?)
++      p_amb_r = pow( t_amb_r, tmp );
++      // printf("p_amb_r = %.2f\n", p_amb_r);
++      }
++    else
++      {
++      t_amb_r = 0.751895;
++      p_amb_r = 0.2234*exp( -4.806e-5 * (altitude - HLEV));
++      }
++
++    *p_amb = p_amb_r * PAMB0;
++    *t_amb = t_amb_r * TAMB0;
++
++/* end of atmos_62 */
++}
++/**************************************************************************/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f192cac112cfddaaf5bf5ec395c4369f764fc85b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++/* a quick atmos_62.h */
++
++
++#ifndef _ATMOS_62_H
++#define _ATMOS_62_H
++
++
++void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound, 
++              SCALAR * t_amb, SCALAR * p_amb );
++
++
++#endif /* _ATMOS_62_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4fb611c95a1ddaf80677bb81afab45c8c3f5747e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,92 @@@
++/***************************************************************************
++
++      TITLE:          engine.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       dummy engine routine
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  incomplete
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 OCT 92 as dummy routine for checkout. EBJ
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    designer
++      
++      CODED BY:       programmer
++      
++      MAINTAINED BY:  maintainer
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      CURRENT RCS HEADER INFO:
++
++$Header$
++
++$Log$
++Revision 1.3  1998/08/06 12:46:37  curt
++Header change.
++
++Revision 1.2  1998/01/19 18:40:23  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:53  curt
++Initial Flight Gear revision.
++
++ * Revision 1.3  1994/01/11  19:10:45  bjax
++ * Removed include files.
++ *
++ * Revision 1.2  1993/03/14  12:16:10  bjax
++ * simple correction: added ';' to end of default routines. EBJ
++ *
++ * Revision 1.1  93/03/10  06:43:46  bjax
++ * Initial revision
++ * 
++ * Revision 1.1  92/12/30  13:21:46  bjax
++ * Initial revision
++ * 
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:      ls_model();
++
++----------------------------------------------------------------------------
++
++      CALLS TO:       none
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++
++#include "ls_types.h"
++#include "default_model_routines.h"
++
++void inertias( SCALAR dt, int Initialize )    {}
++void subsystems( SCALAR dt, int Initialize )  {}
++/* void engine()      {} */
++/* void gear()                {} */
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..930441ae7b04c1d63decc131bb60041e6d4ae715
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,18 @@@
++/* a quick default_model_routines.h */
++
++
++#ifndef _DEFAULT_MODEL_ROUTINES_H
++#define _DEFAULT_MODEL_ROUTINES_H
++
++
++#include "ls_types.h"
++
++
++void inertias( SCALAR dt, int Initialize );
++void subsystems( SCALAR dt, int Initialize );
++void aero( SCALAR dt, int Initialize );
++void engine( SCALAR dt, int Initialize );
++void gear( SCALAR dt, int Initialize );
++
++
++#endif /* _DEFAULT_MODEL_ROUTINES_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7e419fdef1d405b7c0549784566ef9d800722f4d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,216 @@@
++/***************************************************************************
++  
++  TITLE:      ls_Accel
++  
++  ----------------------------------------------------------------------------
++  
++  FUNCTION:   Sums forces and moments and calculates accelerations
++  
++  ----------------------------------------------------------------------------
++  
++  MODULE STATUS:      developmental
++  
++  ----------------------------------------------------------------------------
++  
++  GENEALOGY:  Written 920731 by Bruce Jackson.  Based upon equations
++  given in reference [1] and a Matrix-X/System Build block
++  diagram model of equations of motion coded by David Raney
++  at NASA-Langley in June of 1992.
++  
++  ----------------------------------------------------------------------------
++  
++  DESIGNED BY:        Bruce Jackson
++  
++  CODED BY:           Bruce Jackson
++  
++  MAINTAINED BY:      
++  
++  ----------------------------------------------------------------------------
++  
++  MODIFICATION HISTORY:
++  
++  DATE                PURPOSE         
++  
++  931007    Moved calculations of auxiliary accelerations here from ls_aux.c                                                                  BY
++          and corrected minus sign in front of A_Y_Pilot 
++          contribution from Q_body*P_body*D_X_pilot term.
++  940111    Changed DATA to SCALAR; updated header files
++          
++$Header$
++$Log$
++Revision 1.4  1998/08/24 20:09:26  curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3  1998/08/06 12:46:38  curt
++Header change.
++
++Revision 1.2  1998/01/19 18:40:24  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:53  curt
++Initial Flight Gear revision.
++
++ * Revision 1.5  1994/01/11  18:42:16  bjax
++ * Oops! Changed data types from DATA to SCALAR for precision control.
++ *
++ * Revision 1.4  1994/01/11  18:36:58  bjax
++ * Removed ls_eom.h include directive; replaced with ls_types, ls_constants,
++ * and ls_generic.h includes.
++ *
++ * Revision 1.3  1993/10/07  18:45:24  bjax
++ * Added local defn of d[xyz]_pilot_from_cg to support previous mod. EBJ
++ *
++ * Revision 1.2  1993/10/07  18:41:31  bjax
++ * Moved calculations of auxiliary accelerations here from ls_aux, and
++ * corrected sign on Q_body*P_body*d_x_pilot term of A_Y_pilot calc.  EBJ
++ *
++ * Revision 1.1  1992/12/30  13:17:02  bjax
++ * Initial revision
++ *
++  
++  ----------------------------------------------------------------------------
++  
++  REFERENCES:
++  
++  [  1]       McFarland, Richard E.: "A Standard Kinematic Model
++  for Flight Simulation at NASA-Ames", NASA CR-2497,
++  January 1975 
++  
++  ----------------------------------------------------------------------------
++  
++  CALLED BY:
++  
++  ----------------------------------------------------------------------------
++  
++  CALLS TO:
++  
++  ----------------------------------------------------------------------------
++  
++  INPUTS:  Aero, engine, gear forces & moments
++  
++  ----------------------------------------------------------------------------
++  
++  OUTPUTS:    State derivatives
++  
++  -------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_constants.h"
++#include "ls_accel.h"
++#include <math.h>
++
++void ls_accel( void ) {
++  
++  SCALAR      inv_Mass, inv_Radius;
++  SCALAR      ixz2, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10;
++  SCALAR      dx_pilot_from_cg, dy_pilot_from_cg, dz_pilot_from_cg;
++  SCALAR      tan_Lat_geocentric;
++  
++  
++  /* Sum forces and moments at reference point */
++  
++  
++  F_X = F_X_aero + F_X_engine + F_X_gear;
++  F_Y = F_Y_aero + F_Y_engine + F_Y_gear;
++  F_Z = F_Z_aero + F_Z_engine + F_Z_gear;
++  
++  M_l_rp = M_l_aero + M_l_engine + M_l_gear;
++  M_m_rp = M_m_aero + M_m_engine + M_m_gear;
++  M_n_rp = M_n_aero + M_n_engine + M_n_gear;
++  
++  /* Transfer moments to center of gravity */
++  
++  M_l_cg = M_l_rp + F_Y*Dz_cg - F_Z*Dy_cg;
++  M_m_cg = M_m_rp + F_Z*Dx_cg - F_X*Dz_cg;
++  M_n_cg = M_n_rp + F_X*Dy_cg - F_Y*Dx_cg;
++  
++  /* Transform from body to local frame */
++  
++  F_north = T_local_to_body_11*F_X + T_local_to_body_21*F_Y 
++    + T_local_to_body_31*F_Z;
++  F_east  = T_local_to_body_12*F_X + T_local_to_body_22*F_Y 
++    + T_local_to_body_32*F_Z;
++  F_down  = T_local_to_body_13*F_X + T_local_to_body_23*F_Y 
++    + T_local_to_body_33*F_Z;
++  
++  /* Calculate linear accelerations */
++  
++  tan_Lat_geocentric = tan(Lat_geocentric);
++  inv_Mass = 1/Mass;
++  inv_Radius = 1/Radius_to_vehicle;
++  V_dot_north = inv_Mass*F_north + 
++    inv_Radius*(V_north*V_down - V_east*V_east*tan_Lat_geocentric);
++  V_dot_east  = inv_Mass*F_east  + 
++    inv_Radius*(V_east*V_down + V_north*V_east*tan_Lat_geocentric);
++  V_dot_down  = inv_Mass*(F_down) + Gravity -
++    inv_Radius*(V_north*V_north + V_east*V_east);
++  
++  /* Invert the symmetric inertia matrix */
++  
++  ixz2 = I_xz*I_xz;
++  c0  = 1/(I_xx*I_zz - ixz2);
++  c1  = c0*((I_yy-I_zz)*I_zz - ixz2);
++  c4  = c0*I_xz;
++  /* c2  = c0*I_xz*(I_xx - I_yy + I_zz); */
++  c2  = c4*(I_xx - I_yy + I_zz);
++  c3  = c0*I_zz;
++  c7  = 1/I_yy;
++  c5  = c7*(I_zz - I_xx);
++  c6  = c7*I_xz;
++  c8  = c0*((I_xx - I_yy)*I_xx + ixz2);
++  /* c9  = c0*I_xz*(I_yy - I_zz - I_xx); */
++  c9  = c4*(I_yy - I_zz - I_xx);
++  c10 = c0*I_xx;
++  
++  /* Calculate the rotational body axis accelerations */
++  
++  P_dot_body = (c1*R_body + c2*P_body)*Q_body + c3*M_l_cg +  c4*M_n_cg;
++  Q_dot_body = c5*R_body*P_body + c6*(R_body*R_body - P_body*P_body) + c7*M_m_cg;
++  R_dot_body = (c8*P_body + c9*R_body)*Q_body + c4*M_l_cg + c10*M_n_cg;
++  
++  /* Calculate body axis accelerations (move to ls_accel?)    */
++
++    inv_Mass = 1/Mass;
++    
++    A_X_cg = F_X * inv_Mass;
++    A_Y_cg = F_Y * inv_Mass;
++    A_Z_cg = F_Z * inv_Mass;
++    
++    dx_pilot_from_cg = Dx_pilot - Dx_cg;
++    dy_pilot_from_cg = Dy_pilot - Dy_cg;
++    dz_pilot_from_cg = Dz_pilot - Dz_cg;
++    
++    A_X_pilot = A_X_cg        + (-R_body*R_body - Q_body*Q_body)*dx_pilot_from_cg
++                                          + ( P_body*Q_body - R_dot_body   )*dy_pilot_from_cg
++                                          + ( P_body*R_body + Q_dot_body   )*dz_pilot_from_cg;
++    A_Y_pilot = A_Y_cg        + ( P_body*Q_body + R_dot_body   )*dx_pilot_from_cg
++                                          + (-P_body*P_body - R_body*R_body)*dy_pilot_from_cg
++                                          + ( Q_body*R_body - P_dot_body   )*dz_pilot_from_cg;
++    A_Z_pilot = A_Z_cg        + ( P_body*R_body - Q_dot_body   )*dx_pilot_from_cg
++                                          + ( Q_body*R_body + P_dot_body   )*dy_pilot_from_cg
++                                          + (-Q_body*Q_body - P_body*P_body)*dz_pilot_from_cg;
++                                          
++    N_X_cg = INVG*A_X_cg;
++    N_Y_cg = INVG*A_Y_cg;
++    N_Z_cg = INVG*A_Z_cg;
++    
++    N_X_pilot = INVG*A_X_pilot;
++    N_Y_pilot = INVG*A_Y_pilot;
++    N_Z_pilot = INVG*A_Z_pilot;
++    
++    
++    U_dot_body = T_local_to_body_11*V_dot_north + T_local_to_body_12*V_dot_east
++                                  + T_local_to_body_13*V_dot_down - Q_total*W_body + R_total*V_body;
++    V_dot_body = T_local_to_body_21*V_dot_north + T_local_to_body_22*V_dot_east
++                                  + T_local_to_body_23*V_dot_down - R_total*U_body + P_total*W_body;
++    W_dot_body = T_local_to_body_31*V_dot_north + T_local_to_body_32*V_dot_east
++                                  + T_local_to_body_33*V_dot_down - P_total*V_body + Q_total*U_body;
++    /* End of ls_accel */
++  
++}
++/**************************************************************************/
++
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9bbcfeb7c1c7ee4c1bee136d9f814355253a5ba3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_accel.h */
++
++
++#ifndef _LS_ACCEL_H
++#define _LS_ACCEL_H
++
++
++void ls_accel( void );
++
++
++#endif /* _LS_ACCEL_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..448448cf6ab9b2110048971c31891b8c4b096252
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,347 @@@
++/***************************************************************************
++
++    TITLE:            ls_aux
++              
++----------------------------------------------------------------------------
++
++    FUNCTION: Atmospheric and auxilary relationships for LaRCSim EOM
++
++----------------------------------------------------------------------------
++
++    MODULE STATUS:    developmental
++
++----------------------------------------------------------------------------
++
++    GENEALOGY:        Created 9208026 as part of C-castle simulation project.
++
++----------------------------------------------------------------------------
++
++    DESIGNED BY:      B. Jackson
++    
++    CODED BY:         B. Jackson
++    
++    MAINTAINED BY:    B. Jackson
++
++----------------------------------------------------------------------------
++
++    MODIFICATION HISTORY:
++    
++    DATE    PURPOSE   
++    
++    931006  Moved calculations of auxiliary accelerations from here
++          to ls_accel.c and corrected minus sign in front of A_Y_Pilot
++          contribution from Q_body*P_body*D_X_pilot term.         EBJ
++    931014  Changed calculation of Alpha from atan to atan2 so sign is correct.
++                                                                  EBJ
++    931220  Added calculations for static and total temperatures & pressures,
++          as well as dynamic and impact pressures and calibrated airspeed.
++                                                                  EBJ
++    940111  Changed #included header files from old "ls_eom.h" to newer
++          "ls_types.h", "ls_constants.h" and "ls_generic.h".      EBJ
++
++    950207  Changed use of "abs" to "fabs" in calculation of signU. EBJ
++    
++    950228  Fixed bug in calculation of beta_dot.                 EBJ
++
++    CURRENT RCS HEADER INFO:
++
++$Header$
++$Log$
++Revision 1.4  1998/08/24 20:09:26  curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3  1998/08/06 12:46:38  curt
++Header change.
++
++Revision 1.2  1998/01/19 18:40:24  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:54  curt
++Initial Flight Gear revision.
++
++ * Revision 1.12  1995/02/28  17:57:16  bjax
++ * Corrected calculation of beta_dot. EBJ
++ *
++ * Revision 1.11  1995/02/07  21:09:47  bjax
++ * Corrected calculation of "signU"; was using divide by
++ * abs(), which returns an integer; now using fabs(), which
++ * returns a double.  EBJ
++ *
++ * Revision 1.10  1994/05/10  20:09:42  bjax
++ * Fixed a major problem with dx_pilot_from_cg, etc. not being calculated locally.
++ *
++ * Revision 1.9  1994/01/11  18:44:33  bjax
++ * Changed header files to use ls_types, ls_constants, and ls_generic.
++ *
++ * Revision 1.8  1993/12/21  14:36:33  bjax
++ * Added calcs of pressures, temps and calibrated airspeeds.
++ *
++ * Revision 1.7  1993/10/14  11:25:38  bjax
++ * Changed calculation of Alpha to use 'atan2' instead of 'atan' so alphas
++ * larger than +/- 90 degrees are calculated correctly.                       EBJ
++ *
++ * Revision 1.6  1993/10/07  18:45:56  bjax
++ * A little cleanup; no significant changes. EBJ
++ *
++ * Revision 1.5  1993/10/07  18:42:22  bjax
++ * Moved calculations of auxiliary accelerations here from ls_aux, and
++ * corrected sign on Q_body*P_body*d_x_pilot term of A_Y_pilot calc.  EBJ
++ *
++ * Revision 1.4  1993/07/16  18:28:58  bjax
++ * Changed call from atmos_62 to ls_atmos. EBJ
++ *
++ * Revision 1.3  1993/06/02  15:02:42  bjax
++ * Changed call to geodesy calcs from ls_geodesy to ls_geoc_to_geod.
++ *
++ * Revision 1.1  92/12/30  13:17:39  bjax
++ * Initial revision
++ * 
++
++
++----------------------------------------------------------------------------
++
++    REFERENCES:       [ 1] Shapiro, Ascher H.: "The Dynamics and Thermodynamics
++                      of Compressible Fluid Flow", Volume I, The Ronald 
++                      Press, 1953.
++
++----------------------------------------------------------------------------
++
++              CALLED BY:
++
++----------------------------------------------------------------------------
++
++              CALLS TO:
++
++----------------------------------------------------------------------------
++
++              INPUTS:
++
++----------------------------------------------------------------------------
++
++              OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++
++#include "ls_aux.h"
++
++#include "atmos_62.h"
++#include "ls_geodesy.h"
++#include "ls_gravity.h"
++
++#include <math.h>
++
++
++void ls_aux( void ) {
++
++      SCALAR  dx_pilot_from_cg, dy_pilot_from_cg, dz_pilot_from_cg;
++      /* SCALAR inv_Mass; */
++      SCALAR  v_XZ_plane_2, signU, v_tangential;
++      /* SCALAR inv_radius_ratio; */
++      SCALAR  cos_rwy_hdg, sin_rwy_hdg;
++      SCALAR  mach2, temp_ratio, pres_ratio;
++      SCALAR  tmp;
++      
++    /* update geodetic position */
++
++      ls_geoc_to_geod( Lat_geocentric, Radius_to_vehicle, 
++                              &Latitude, &Altitude, &Sea_level_radius );
++      Longitude = Lon_geocentric - Earth_position_angle;
++
++    /* Calculate body axis velocities */
++
++      /* Form relative velocity vector */
++
++      V_north_rel_ground = V_north;
++      V_east_rel_ground  = V_east 
++        - OMEGA_EARTH*Sea_level_radius*cos( Lat_geocentric );
++      V_down_rel_ground  = V_down;
++      
++      V_north_rel_airmass = V_north_rel_ground - V_north_airmass;
++      V_east_rel_airmass  = V_east_rel_ground  - V_east_airmass;
++      V_down_rel_airmass  = V_down_rel_ground  - V_down_airmass;
++      
++      U_body = T_local_to_body_11*V_north_rel_airmass 
++        + T_local_to_body_12*V_east_rel_airmass
++          + T_local_to_body_13*V_down_rel_airmass + U_gust;
++      V_body = T_local_to_body_21*V_north_rel_airmass 
++        + T_local_to_body_22*V_east_rel_airmass
++          + T_local_to_body_23*V_down_rel_airmass + V_gust;
++      W_body = T_local_to_body_31*V_north_rel_airmass 
++        + T_local_to_body_32*V_east_rel_airmass
++          + T_local_to_body_33*V_down_rel_airmass + W_gust;
++                              
++      V_rel_wind = sqrt(U_body*U_body + V_body*V_body + W_body*W_body);
++
++
++    /* Calculate alpha and beta rates */
++
++      v_XZ_plane_2 = (U_body*U_body + W_body*W_body);
++      
++      if (U_body == 0)
++              signU = 1;
++      else
++              signU = U_body/fabs(U_body);
++              
++      if( (v_XZ_plane_2 == 0) || (V_rel_wind == 0) )
++      {
++              Alpha_dot = 0;
++              Beta_dot = 0;
++      }
++      else
++      {
++              Alpha_dot = (U_body*W_dot_body - W_body*U_dot_body)/
++                v_XZ_plane_2;
++              Beta_dot = (signU*v_XZ_plane_2*V_dot_body 
++                - V_body*(U_body*U_dot_body + W_body*W_dot_body))
++                  /(V_rel_wind*V_rel_wind*sqrt(v_XZ_plane_2));
++      }
++
++    /* Calculate flight path and other flight condition values */
++
++      if (U_body == 0) 
++              Alpha = 0;
++      else
++              Alpha = atan2( W_body, U_body );
++              
++      Cos_alpha = cos(Alpha);
++      Sin_alpha = sin(Alpha);
++      
++      if (V_rel_wind == 0)
++              Beta = 0;
++      else
++              Beta = asin( V_body/ V_rel_wind );
++              
++      Cos_beta = cos(Beta);
++      Sin_beta = sin(Beta);
++      
++      V_true_kts = V_rel_wind * V_TO_KNOTS;
++      
++      V_ground_speed = sqrt(V_north_rel_ground*V_north_rel_ground
++                            + V_east_rel_ground*V_east_rel_ground );
++
++      V_rel_ground = sqrt(V_ground_speed*V_ground_speed
++                          + V_down_rel_ground*V_down_rel_ground );
++      
++      v_tangential = sqrt(V_north*V_north + V_east*V_east);
++      
++      V_inertial = sqrt(v_tangential*v_tangential + V_down*V_down);
++      
++      if( (V_ground_speed == 0) && (V_down == 0) )
++        Gamma_vert_rad = 0;
++      else
++        Gamma_vert_rad = atan2( -V_down, V_ground_speed );
++              
++      if( (V_north_rel_ground == 0) && (V_east_rel_ground == 0) )
++        Gamma_horiz_rad = 0;
++      else
++        Gamma_horiz_rad = atan2( V_east_rel_ground, V_north_rel_ground );
++      
++      if (Gamma_horiz_rad < 0) 
++        Gamma_horiz_rad = Gamma_horiz_rad + 2*PI;
++      
++    /* Calculate local gravity        */
++      
++      ls_gravity( Radius_to_vehicle, Lat_geocentric, &Gravity );
++      
++    /* call function for (smoothed) density ratio, sonic velocity, and
++         ambient pressure */
++
++      ls_atmos(Altitude, &Sigma, &V_sound, 
++               &Static_temperature, &Static_pressure);
++      
++      Density = Sigma*SEA_LEVEL_DENSITY;
++      
++      Mach_number = V_rel_wind / V_sound;
++      
++      V_equiv = V_rel_wind*sqrt(Sigma);
++      
++      V_equiv_kts = V_equiv*V_TO_KNOTS;
++
++    /* calculate temperature and pressure ratios (from [1]) */
++
++      mach2 = Mach_number*Mach_number;
++      temp_ratio = 1.0 + 0.2*mach2; 
++      tmp = 3.5;
++      pres_ratio = pow( temp_ratio, tmp );
++
++      Total_temperature = temp_ratio*Static_temperature;
++      Total_pressure    = pres_ratio*Static_pressure;
++
++    /* calculate impact and dynamic pressures */
++      
++      Impact_pressure = Total_pressure - Static_pressure; 
++
++      Dynamic_pressure = 0.5*Density*V_rel_wind*V_rel_wind;
++
++    /* calculate calibrated airspeed indication */
++
++      V_calibrated = sqrt( 2.0*Dynamic_pressure / SEA_LEVEL_DENSITY );
++      V_calibrated_kts = V_calibrated*V_TO_KNOTS;
++      
++      Centrifugal_relief = 1 - v_tangential/(Radius_to_vehicle*Gravity);
++      
++/* Determine location in runway coordinates */
++
++      Radius_to_rwy = Sea_level_radius + Runway_altitude;
++      cos_rwy_hdg = cos(Runway_heading*DEG_TO_RAD);
++      sin_rwy_hdg = sin(Runway_heading*DEG_TO_RAD);
++      
++      D_cg_north_of_rwy = Radius_to_rwy*(Latitude - Runway_latitude);
++      D_cg_east_of_rwy = Radius_to_rwy*cos(Runway_latitude)
++              *(Longitude - Runway_longitude);
++      D_cg_above_rwy  = Radius_to_vehicle - Radius_to_rwy;
++      
++      X_cg_rwy = D_cg_north_of_rwy*cos_rwy_hdg 
++        + D_cg_east_of_rwy*sin_rwy_hdg;
++      Y_cg_rwy =-D_cg_north_of_rwy*sin_rwy_hdg 
++        + D_cg_east_of_rwy*cos_rwy_hdg;
++      H_cg_rwy = D_cg_above_rwy;
++      
++      dx_pilot_from_cg = Dx_pilot - Dx_cg;
++      dy_pilot_from_cg = Dy_pilot - Dy_cg;
++      dz_pilot_from_cg = Dz_pilot - Dz_cg;
++
++      D_pilot_north_of_rwy = D_cg_north_of_rwy 
++        + T_local_to_body_11*dx_pilot_from_cg 
++          + T_local_to_body_21*dy_pilot_from_cg
++            + T_local_to_body_31*dz_pilot_from_cg;
++      D_pilot_east_of_rwy  = D_cg_east_of_rwy 
++        + T_local_to_body_12*dx_pilot_from_cg 
++          + T_local_to_body_22*dy_pilot_from_cg
++            + T_local_to_body_32*dz_pilot_from_cg;
++      D_pilot_above_rwy    = D_cg_above_rwy 
++        - T_local_to_body_13*dx_pilot_from_cg 
++          - T_local_to_body_23*dy_pilot_from_cg
++            - T_local_to_body_33*dz_pilot_from_cg;
++                                                      
++      X_pilot_rwy =  D_pilot_north_of_rwy*cos_rwy_hdg
++        + D_pilot_east_of_rwy*sin_rwy_hdg;
++      Y_pilot_rwy = -D_pilot_north_of_rwy*sin_rwy_hdg
++        + D_pilot_east_of_rwy*cos_rwy_hdg;
++      H_pilot_rwy =  D_pilot_above_rwy;
++                                                              
++/* Calculate Euler rates */
++      
++      Sin_phi = sin(Phi);
++      Cos_phi = cos(Phi);
++      Sin_theta = sin(Theta);
++      Cos_theta = cos(Theta);
++      Sin_psi = sin(Psi);
++      Cos_psi = cos(Psi);
++      
++      if( Cos_theta == 0 )
++        Psi_dot = 0;
++      else
++        Psi_dot = (Q_total*Sin_phi + R_total*Cos_phi)/Cos_theta;
++      
++      Theta_dot = Q_total*Cos_phi - R_total*Sin_phi;
++      Phi_dot = P_total + Psi_dot*Sin_theta;
++      
++/* end of ls_aux */
++
++}
++/*************************************************************************/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c59180337b17509d3138559004562cf3865dd6a8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_aux.h */
++
++
++#ifndef _LS_AUX_H 
++#define _LS_AUX_H
++
++
++void ls_aux( void );
++
++
++#endif /* _LS_AUX_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3dcddcdc992b616f711be6a282e54f5725508e9f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,104 @@@
++/***************************************************************************
++
++      TITLE:          ls_cockpit.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Header for cockpit IO
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  Developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 20 DEC 93 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    E. B. Jackson
++      
++      CODED BY:       E. B. Jackson
++      
++      MAINTAINED BY:  E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      950314  Added "throttle_pct" field to cockpit header for both
++              display and trim purposes.                      EBJ
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.5  1998/10/17 01:34:14  curt
++C++ ifying ...
++
++Revision 1.4  1998/08/06 12:46:39  curt
++Header change.
++
++Revision 1.3  1998/01/22 02:59:32  curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.2  1997/05/31 19:16:27  curt
++Elevator trim added.
++
++Revision 1.1  1997/05/29 00:09:54  curt
++Initial Flight Gear revision.
++
++ * Revision 1.3  1995/03/15  12:32:10  bjax
++ * Added throttle_pct field.
++ *
++ * Revision 1.2  1995/02/28  20:37:02  bjax
++ * Changed name of gear_sel_down switch to gear_sel_up to reflect
++ * correct sense of switch.  EBJ
++ *
++ * Revision 1.1  1993/12/21  14:39:04  bjax
++ * Initial revision
++ *
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_COCKPIT_H
++#define _LS_COCKPIT_H
++
++
++typedef struct {
++    float   long_stick, lat_stick, rudder_pedal;
++    float   long_trim;
++    float   throttle[4];
++    short   forward_trim, aft_trim, left_trim, right_trim;
++    short   left_pb_on_stick, right_pb_on_stick, trig_pos_1, trig_pos_2;
++    short   sb_extend, sb_retract, gear_sel_up;
++    float   throttle_pct;
++    float   brake_pct;
++} COCKPIT;
++
++extern COCKPIT cockpit_;
++
++#define Left_button   cockpit_.left_pb_on_stick
++#define Right_button  cockpit_.right_pb_on_stick
++#define Rudder_pedal  cockpit_.rudder_pedal
++#define Throttle      cockpit_.throttle
++#define Throttle_pct  cockpit_.throttle_pct
++#define First_trigger cockpit_.trig_pos_1
++#define Second_trigger        cockpit_.trig_pos_2
++#define Long_control  cockpit_.long_stick
++#define Long_trim       cockpit_.long_trim
++#define Lat_control   cockpit_.lat_stick
++#define Fwd_trim      cockpit_.forward_trim
++#define Aft_trim      cockpit_.aft_trim
++#define Left_trim     cockpit_.left_trim
++#define Right_trim    cockpit_.right_trim
++#define SB_extend     cockpit_.sb_extend
++#define SB_retract    cockpit_.sb_retract
++#define Gear_sel_up   cockpit_.gear_sel_up
++#define Brake_pct       cockpit_.brake_pct
++
++
++#endif /* _LS_COCKPIT_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2393f4c5dc6b7dd232665bc63f432ed5f4b9d0ba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,133 @@@
++/***************************************************************************
++
++      TITLE:  ls_constants.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       LaRCSim constants definition header file
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 DEC 1993 by Bruce Jackson; was part of
++                      old ls_eom.h header file
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    B. Jackson
++      
++      CODED BY:       B. Jackson
++      
++      MAINTAINED BY:  guess who
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++                      
++----------------------------------------------------------------------------
++
++      REFERENCES:
++      
++              [ 1]    McFarland, Richard E.: "A Standard Kinematic Model
++                      for Flight Simulation at NASA-Ames", NASA CR-2497,
++                      January 1975
++                      
++              [ 2]    ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++                      pheric and Space Flight Vehicle Coordinate Systems",
++                      February 1992
++                      
++              [ 3]    Beyer, William H., editor: "CRC Standard Mathematical
++                      Tables, 28th edition", CRC Press, Boca Raton, FL, 1987,
++                      ISBN 0-8493-0628-0
++                      
++              [ 4]    Dowdy, M. C.; Jackson, E. B.; and Nichols, J. H.:
++                      "Controls Analysis and Simulation Test Loop Environ-
++                      ment (CASTLE) Programmer's Guide, Version 1.3", 
++                      NATC TM 89-11, 30 March 1989.
++                      
++              [ 5]    Halliday, David; and Resnick, Robert: "Fundamentals
++                      of Physics, Revised Printing", Wiley and Sons, 1974.
++                      ISBN 0-471-34431-1
++
++              [ 6]    Anon: "U. S. Standard Atmosphere, 1962"
++              
++              [ 7]    Anon: "Aeronautical Vest Pocket Handbook, 17th edition",
++                      Pratt & Whitney Aircraft Group, Dec. 1977
++                      
++              [ 8]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
++                      Control and Simulation", Wiley and Sons, 1992.
++                      ISBN 0-471-61397-5                      
++
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_CONSTANTS
++#define _LS_CONSTANTS
++
++
++#ifndef CONSTANTS
++
++#define CONSTANTS -1
++
++/* Define application-wide macros */
++
++#define PATHNAME "LARCSIMPATH"
++#ifndef NIL_POINTER
++#define NIL_POINTER 0L
++#endif
++
++/* Define constants (note: many factors will need to change for other 
++      systems of measure)     */
++
++/* Value of Pi from ref [3] */
++#ifdef PI
++#  undef PI /* avoid a harmless compiler warning */
++#endif
++#define       PI 3.14159265358979323846264338327950288419716939967511
++
++/* Value of earth radius from [8], ft */
++#define       EQUATORIAL_RADIUS 20925650.
++#define RESQ 437882827922500.
++
++/* Value of earth flattening parameter from ref [8]                   
++      
++      Note: FP = f
++            E  = 1-f
++            EPS = sqrt(1-(1-f)^2)                     */
++            
++#define FP    .003352813178
++#define E   .996647186
++#define EPS .081819221
++#define INVG .031080997
++
++/* linear velocity of earth at equator from w*R; w=2pi/24 hrs, in ft/sec */
++#define OMEGA_EARTH .00007272205217
++
++/* miscellaneous units conversions (ref [7]) */
++#define       V_TO_KNOTS      0.5921
++#define DEG_TO_RAD    0.017453292
++#define RAD_TO_DEG    57.29577951
++#define FT_TO_METERS  0.3048
++#define METERS_TO_FT  3.2808
++#define K_TO_R                1.8
++#define R_TO_K                0.55555556
++#define NSM_TO_PSF    0.02088547
++#define PSF_TO_NSM    47.8801826
++#define KCM_TO_SCF    0.00194106
++#define SCF_TO_KCM    515.183616
++
++
++/* ENGLISH Atmospheric reference properties [6] */
++#define SEA_LEVEL_DENSITY     0.002376888
++
++#endif
++
++
++#endif /* _LS_CONSTANTS_H */
++
++
++/*------------------------- end of ls_constants.h -------------------------*/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6059cce1e52b07ce1031e5e3e5281396e46a0baf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,426 @@@
++/***************************************************************************
++
++      TITLE:  ls_generic.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       LaRCSim generic parameters header file
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 DEC 1993 by Bruce Jackson;
++                      was part of old ls_eom.h header
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    B. Jackson
++      
++      CODED BY:       B. Jackson
++      
++      MAINTAINED BY:  guess who
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++              
++----------------------------------------------------------------------------
++
++      REFERENCES:
++      
++              [ 1]    McFarland, Richard E.: "A Standard Kinematic Model
++                      for Flight Simulation at NASA-Ames", NASA CR-2497,
++                      January 1975
++                      
++              [ 2]    ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++                      pheric and Space Flight Vehicle Coordinate Systems",
++                      February 1992
++                      
++              [ 3]    Beyer, William H., editor: "CRC Standard Mathematical
++                      Tables, 28th edition", CRC Press, Boca Raton, FL, 1987,
++                      ISBN 0-8493-0628-0
++                      
++              [ 4]    Dowdy, M. C.; Jackson, E. B.; and Nichols, J. H.:
++                      "Controls Analysis and Simulation Test Loop Environ-
++                      ment (CASTLE) Programmer's Guide, Version 1.3", 
++                      NATC TM 89-11, 30 March 1989.
++                      
++              [ 5]    Halliday, David; and Resnick, Robert: "Fundamentals
++                      of Physics, Revised Printing", Wiley and Sons, 1974.
++                      ISBN 0-471-34431-1
++
++              [ 6]    Anon: "U. S. Standard Atmosphere, 1962"
++              
++              [ 7]    Anon: "Aeronautical Vest Pocket Handbook, 17th edition",
++                      Pratt & Whitney Aircraft Group, Dec. 1977
++                      
++              [ 8]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
++                      Control and Simulation", Wiley and Sons, 1992.
++                      ISBN 0-471-61397-5                      
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_GENERIC_H
++#define _LS_GENERIC_H
++
++
++#ifdef __cplusplus                                                          
++extern "C" {                            
++#endif                                   
++
++
++#include "ls_types.h"
++
++
++typedef struct {
++
++/*================== Mass properties and geometry values ==================*/
++      
++    DATA    mass, i_xx, i_yy, i_zz, i_xz;     /* Inertias */
++#define Mass                  generic_.mass
++#define I_xx                  generic_.i_xx
++#define I_yy                  generic_.i_yy
++#define I_zz                  generic_.i_zz
++#define I_xz                  generic_.i_xz
++      
++    VECTOR_3    d_pilot_rp_body_v;    /* Pilot location rel to ref pt */
++#define D_pilot_rp_body_v     generic_.d_pilot_rp_body_v
++#define Dx_pilot              generic_.d_pilot_rp_body_v[0]
++#define       Dy_pilot                generic_.d_pilot_rp_body_v[1]
++#define       Dz_pilot                generic_.d_pilot_rp_body_v[2]
++
++    VECTOR_3    d_cg_rp_body_v;       /* CG position w.r.t. ref. point */
++#define D_cg_rp_body_v                generic_.d_cg_rp_body_v
++#define Dx_cg                 generic_.d_cg_rp_body_v[0]
++#define Dy_cg                 generic_.d_cg_rp_body_v[1]
++#define Dz_cg                 generic_.d_cg_rp_body_v[2]
++      
++/*================================ Forces =================================*/
++
++    VECTOR_3    f_body_total_v;
++#define F_body_total_v                generic_.f_body_total_v
++#define       F_X                     generic_.f_body_total_v[0]
++#define F_Y                   generic_.f_body_total_v[1]
++#define F_Z                   generic_.f_body_total_v[2]
++
++    VECTOR_3    f_local_total_v;
++#define F_local_total_v               generic_.f_local_total_v
++#define       F_north                 generic_.f_local_total_v[0]
++#define F_east                        generic_.f_local_total_v[1]
++#define F_down                        generic_.f_local_total_v[2]
++
++    VECTOR_3    f_aero_v;
++#define F_aero_v              generic_.f_aero_v
++#define       F_X_aero                generic_.f_aero_v[0]
++#define       F_Y_aero                generic_.f_aero_v[1]
++#define       F_Z_aero                generic_.f_aero_v[2]
++
++    VECTOR_3    f_engine_v;
++#define F_engine_v            generic_.f_engine_v
++#define       F_X_engine              generic_.f_engine_v[0]
++#define       F_Y_engine              generic_.f_engine_v[1]
++#define       F_Z_engine              generic_.f_engine_v[2]
++
++    VECTOR_3    f_gear_v;
++#define F_gear_v              generic_.f_gear_v
++#define       F_X_gear                generic_.f_gear_v[0]
++#define       F_Y_gear                generic_.f_gear_v[1]
++#define       F_Z_gear                generic_.f_gear_v[2]
++
++/*================================ Moments ================================*/
++
++    VECTOR_3    m_total_rp_v;
++#define M_total_rp_v          generic_.m_total_rp_v
++#define       M_l_rp                  generic_.m_total_rp_v[0]
++#define M_m_rp                        generic_.m_total_rp_v[1]
++#define M_n_rp                        generic_.m_total_rp_v[2]
++
++    VECTOR_3    m_total_cg_v;
++#define M_total_cg_v          generic_.m_total_cg_v
++#define       M_l_cg                  generic_.m_total_cg_v[0]
++#define M_m_cg                        generic_.m_total_cg_v[1]
++#define M_n_cg                        generic_.m_total_cg_v[2]
++
++    VECTOR_3    m_aero_v;
++#define M_aero_v              generic_.m_aero_v
++#define       M_l_aero                generic_.m_aero_v[0]
++#define       M_m_aero                generic_.m_aero_v[1]
++#define       M_n_aero                generic_.m_aero_v[2]
++
++    VECTOR_3    m_engine_v;
++#define M_engine_v            generic_.m_engine_v
++#define       M_l_engine              generic_.m_engine_v[0]
++#define       M_m_engine              generic_.m_engine_v[1]
++#define       M_n_engine              generic_.m_engine_v[2]
++
++    VECTOR_3    m_gear_v;
++#define M_gear_v              generic_.m_gear_v
++#define       M_l_gear                generic_.m_gear_v[0]
++#define       M_m_gear                generic_.m_gear_v[1]
++#define       M_n_gear                generic_.m_gear_v[2]
++
++/*============================== Accelerations ============================*/
++
++    VECTOR_3    v_dot_local_v;
++#define V_dot_local_v         generic_.v_dot_local_v
++#define       V_dot_north             generic_.v_dot_local_v[0]
++#define       V_dot_east              generic_.v_dot_local_v[1]
++#define       V_dot_down              generic_.v_dot_local_v[2]
++
++    VECTOR_3    v_dot_body_v;
++#define V_dot_body_v          generic_.v_dot_body_v
++#define       U_dot_body              generic_.v_dot_body_v[0]
++#define       V_dot_body              generic_.v_dot_body_v[1]
++#define       W_dot_body              generic_.v_dot_body_v[2]
++
++    VECTOR_3    a_cg_body_v;
++#define A_cg_body_v           generic_.a_cg_body_v
++#define       A_X_cg                  generic_.a_cg_body_v[0]
++#define A_Y_cg                        generic_.a_cg_body_v[1]
++#define       A_Z_cg                  generic_.a_cg_body_v[2]
++
++    VECTOR_3    a_pilot_body_v;
++#define A_pilot_body_v                generic_.a_pilot_body_v
++#define       A_X_pilot               generic_.a_pilot_body_v[0]
++#define       A_Y_pilot               generic_.a_pilot_body_v[1]
++#define       A_Z_pilot               generic_.a_pilot_body_v[2]
++
++    VECTOR_3    n_cg_body_v;
++#define N_cg_body_v           generic_.n_cg_body_v
++#define       N_X_cg                  generic_.n_cg_body_v[0]
++#define N_Y_cg                        generic_.n_cg_body_v[1]
++#define       N_Z_cg                  generic_.n_cg_body_v[2]
++
++    VECTOR_3    n_pilot_body_v;
++#define N_pilot_body_v                generic_.n_pilot_body_v
++#define       N_X_pilot               generic_.n_pilot_body_v[0]
++#define       N_Y_pilot               generic_.n_pilot_body_v[1]
++#define       N_Z_pilot               generic_.n_pilot_body_v[2]
++
++    VECTOR_3    omega_dot_body_v;
++#define Omega_dot_body_v      generic_.omega_dot_body_v
++#define P_dot_body            generic_.omega_dot_body_v[0]
++#define Q_dot_body            generic_.omega_dot_body_v[1]
++#define       R_dot_body              generic_.omega_dot_body_v[2]
++
++
++/*============================== Velocities ===============================*/
++
++    VECTOR_3    v_local_v;
++#define V_local_v             generic_.v_local_v
++#define       V_north                 generic_.v_local_v[0]
++#define       V_east                  generic_.v_local_v[1]
++#define       V_down                  generic_.v_local_v[2]
++
++    VECTOR_3    v_local_rel_ground_v; /* V rel w.r.t. earth surface   */
++#define V_local_rel_ground_v  generic_.v_local_rel_ground_v
++#define       V_north_rel_ground      generic_.v_local_rel_ground_v[0]
++#define V_east_rel_ground     generic_.v_local_rel_ground_v[1]
++#define       V_down_rel_ground       generic_.v_local_rel_ground_v[2]
++
++    VECTOR_3    v_local_airmass_v;    /* velocity of airmass (steady winds)   */
++#define V_local_airmass_v     generic_.v_local_airmass_v
++#define V_north_airmass               generic_.v_local_airmass_v[0]
++#define       V_east_airmass          generic_.v_local_airmass_v[1]
++#define       V_down_airmass          generic_.v_local_airmass_v[2]
++
++    VECTOR_3    v_local_rel_airmass_v;        /* velocity of veh. relative to airmass */
++#define V_local_rel_airmass_v generic_.v_local_rel_airmass_v
++#define       V_north_rel_airmass     generic_.v_local_rel_airmass_v[0]
++#define       V_east_rel_airmass      generic_.v_local_rel_airmass_v[1]
++#define       V_down_rel_airmass      generic_.v_local_rel_airmass_v[2]
++
++    VECTOR_3    v_local_gust_v; /* linear turbulence components, L frame */
++#define V_local_gust_v                generic_.v_local_gust_v
++#define       U_gust                  generic_.v_local_gust_v[0]
++#define       V_gust                  generic_.v_local_gust_v[1]
++#define       W_gust                  generic_.v_local_gust_v[2]
++
++    VECTOR_3    v_wind_body_v;        /* Wind-relative velocities in body axis        */
++#define V_wind_body_v         generic_.v_wind_body_v
++#define       U_body                  generic_.v_wind_body_v[0]
++#define V_body                        generic_.v_wind_body_v[1]
++#define       W_body                  generic_.v_wind_body_v[2]
++
++    DATA    v_rel_wind, v_true_kts, v_rel_ground, v_inertial;
++    DATA    v_ground_speed, v_equiv, v_equiv_kts;
++    DATA    v_calibrated, v_calibrated_kts;
++#define V_rel_wind            generic_.v_rel_wind
++#define V_true_kts            generic_.v_true_kts
++#define V_rel_ground          generic_.v_rel_ground
++#define V_inertial            generic_.v_inertial
++#define V_ground_speed                generic_.v_ground_speed
++#define V_equiv                       generic_.v_equiv
++#define V_equiv_kts           generic_.v_equiv_kts
++#define V_calibrated          generic_.v_calibrated
++#define V_calibrated_kts      generic_.v_calibrated_kts
++
++    VECTOR_3    omega_body_v; /* Angular B rates      */
++#define Omega_body_v          generic_.omega_body_v
++#define       P_body                  generic_.omega_body_v[0]
++#define       Q_body                  generic_.omega_body_v[1]
++#define       R_body                  generic_.omega_body_v[2]
++                      
++    VECTOR_3    omega_local_v;        /* Angular L rates      */
++#define Omega_local_v         generic_.omega_local_v
++#define       P_local                 generic_.omega_local_v[0]
++#define       Q_local                 generic_.omega_local_v[1]
++#define       R_local                 generic_.omega_local_v[2]
++
++    VECTOR_3    omega_total_v;        /* Diff btw B & L       */      
++#define Omega_total_v         generic_.omega_total_v
++#define       P_total                 generic_.omega_total_v[0]
++#define       Q_total                 generic_.omega_total_v[1]
++#define       R_total                 generic_.omega_total_v[2]
++
++    VECTOR_3    euler_rates_v;
++#define Euler_rates_v         generic_.euler_rates_v
++#define       Phi_dot                 generic_.euler_rates_v[0]
++#define       Theta_dot               generic_.euler_rates_v[1]
++#define       Psi_dot                 generic_.euler_rates_v[2]
++
++    VECTOR_3    geocentric_rates_v;   /* Geocentric linear velocities */
++#define Geocentric_rates_v    generic_.geocentric_rates_v
++#define       Latitude_dot            generic_.geocentric_rates_v[0]
++#define       Longitude_dot           generic_.geocentric_rates_v[1]
++#define       Radius_dot              generic_.geocentric_rates_v[2]
++
++/*=============================== Positions ===============================*/
++
++    VECTOR_3    geocentric_position_v;
++#define Geocentric_position_v generic_.geocentric_position_v
++#define Lat_geocentric                generic_.geocentric_position_v[0]
++#define       Lon_geocentric          generic_.geocentric_position_v[1]
++#define       Radius_to_vehicle       generic_.geocentric_position_v[2]
++
++    VECTOR_3    geodetic_position_v;
++#define Geodetic_position_v   generic_.geodetic_position_v
++#define Latitude              generic_.geodetic_position_v[0]
++#define       Longitude               generic_.geodetic_position_v[1]
++#define Altitude                      generic_.geodetic_position_v[2]
++
++    VECTOR_3    euler_angles_v;
++#define Euler_angles_v                generic_.euler_angles_v
++#define       Phi                     generic_.euler_angles_v[0]
++#define       Theta                   generic_.euler_angles_v[1]
++#define       Psi                     generic_.euler_angles_v[2]
++
++/*======================= Miscellaneous quantities ========================*/
++      
++    DATA    t_local_to_body_m[3][3];  /* Transformation matrix L to B */
++#define T_local_to_body_m     generic_.t_local_to_body_m
++#define       T_local_to_body_11      generic_.t_local_to_body_m[0][0]
++#define       T_local_to_body_12      generic_.t_local_to_body_m[0][1]
++#define       T_local_to_body_13      generic_.t_local_to_body_m[0][2]
++#define       T_local_to_body_21      generic_.t_local_to_body_m[1][0]
++#define       T_local_to_body_22      generic_.t_local_to_body_m[1][1]
++#define       T_local_to_body_23      generic_.t_local_to_body_m[1][2]
++#define       T_local_to_body_31      generic_.t_local_to_body_m[2][0]
++#define       T_local_to_body_32      generic_.t_local_to_body_m[2][1]
++#define       T_local_to_body_33      generic_.t_local_to_body_m[2][2]
++
++    DATA    gravity;          /* Local acceleration due to G  */
++#define Gravity                       generic_.gravity
++
++    DATA    centrifugal_relief;       /* load factor reduction due to speed */
++#define Centrifugal_relief    generic_.centrifugal_relief
++
++    DATA    alpha, beta, alpha_dot, beta_dot; /* in radians   */
++#define Alpha                 generic_.alpha
++#define Beta                  generic_.beta
++#define Alpha_dot             generic_.alpha_dot
++#define Beta_dot              generic_.beta_dot
++
++    DATA    cos_alpha, sin_alpha, cos_beta, sin_beta;
++#define Cos_alpha             generic_.cos_alpha
++#define Sin_alpha             generic_.sin_alpha
++#define Cos_beta              generic_.cos_beta
++#define Sin_beta              generic_.sin_beta
++
++    DATA    cos_phi, sin_phi, cos_theta, sin_theta, cos_psi, sin_psi;
++#define Cos_phi                       generic_.cos_phi
++#define Sin_phi                       generic_.sin_phi
++#define Cos_theta             generic_.cos_theta
++#define Sin_theta             generic_.sin_theta
++#define Cos_psi                       generic_.cos_psi
++#define Sin_psi                       generic_.sin_psi
++      
++    DATA    gamma_vert_rad, gamma_horiz_rad;  /* Flight path angles   */
++#define Gamma_vert_rad                generic_.gamma_vert_rad
++#define Gamma_horiz_rad               generic_.gamma_horiz_rad
++      
++    DATA    sigma, density, v_sound, mach_number;
++#define Sigma                 generic_.sigma
++#define Density                       generic_.density
++#define V_sound                       generic_.v_sound
++#define Mach_number           generic_.mach_number
++      
++    DATA    static_pressure, total_pressure, impact_pressure, dynamic_pressure;
++#define Static_pressure               generic_.static_pressure
++#define Total_pressure                generic_.total_pressure
++#define Impact_pressure               generic_.impact_pressure
++#define Dynamic_pressure      generic_.dynamic_pressure
++
++    DATA    static_temperature, total_temperature;
++#define Static_temperature    generic_.static_temperature
++#define Total_temperature     generic_.total_temperature
++      
++    DATA    sea_level_radius, earth_position_angle;
++#define Sea_level_radius      generic_.sea_level_radius
++#define Earth_position_angle  generic_.earth_position_angle
++      
++    DATA    runway_altitude, runway_latitude, runway_longitude, runway_heading;
++#define Runway_altitude               generic_.runway_altitude
++#define Runway_latitude               generic_.runway_latitude
++#define Runway_longitude      generic_.runway_longitude
++#define Runway_heading                generic_.runway_heading
++
++    DATA    radius_to_rwy;
++#define Radius_to_rwy         generic_.radius_to_rwy
++      
++    VECTOR_3    d_cg_rwy_local_v;       /* CG rel. to rwy in local coords */
++#define D_cg_rwy_local_v      generic_.d_cg_rwy_local_v
++#define       D_cg_north_of_rwy       generic_.d_cg_rwy_local_v[0]
++#define       D_cg_east_of_rwy        generic_.d_cg_rwy_local_v[1]
++#define       D_cg_above_rwy          generic_.d_cg_rwy_local_v[2]
++
++    VECTOR_3    d_cg_rwy_rwy_v;       /* CG relative to runway, in rwy coordinates */
++#define D_cg_rwy_rwy_v                generic_.d_cg_rwy_rwy_v
++#define X_cg_rwy              generic_.d_cg_rwy_rwy_v[0]
++#define Y_cg_rwy              generic_.d_cg_rwy_rwy_v[1]
++#define H_cg_rwy              generic_.d_cg_rwy_rwy_v[2]
++
++    VECTOR_3    d_pilot_rwy_local_v;  /* pilot rel. to rwy in local coords */
++#define D_pilot_rwy_local_v   generic_.d_pilot_rwy_local_v
++#define       D_pilot_north_of_rwy    generic_.d_pilot_rwy_local_v[0]
++#define       D_pilot_east_of_rwy     generic_.d_pilot_rwy_local_v[1]
++#define       D_pilot_above_rwy       generic_.d_pilot_rwy_local_v[2]
++
++    VECTOR_3   d_pilot_rwy_rwy_v;     /* pilot rel. to rwy, in rwy coords. */
++#define D_pilot_rwy_rwy_v     generic_.d_pilot_rwy_rwy_v
++#define X_pilot_rwy           generic_.d_pilot_rwy_rwy_v[0]
++#define Y_pilot_rwy           generic_.d_pilot_rwy_rwy_v[1]
++#define H_pilot_rwy           generic_.d_pilot_rwy_rwy_v[2]
++
++
++} GENERIC;
++
++extern GENERIC generic_;      /* usually defined in ls_main.c */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++#endif /* _LS_GENERIC_H */
++
++
++/*---------------------------  end of ls_generic.h  ------------------------*/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ed808d135d5839dbad22afd72e02a19810944b17
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,160 @@@
++/***************************************************************************
++
++      TITLE:  ls_geodesy
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Converts geocentric coordinates to geodetic positions
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Written as part of LaRCSim project by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    E. B. Jackson
++      
++      CODED BY:       E. B. Jackson
++      
++      MAINTAINED BY:  E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++      930208  Modified to avoid singularity near polar region.        EBJ
++      930602  Moved backwards calcs here from ls_step.                EBJ
++      931214  Changed erroneous Latitude and Altitude variables to 
++              *lat_geod and *alt in routine ls_geoc_to_geod.          EBJ
++      940111  Changed header files from old ls_eom.h style to ls_types, 
++              and ls_constants.  Also replaced old DATA type with new
++              SCALAR type.                                            EBJ
++
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.3  1998/07/08 14:41:37  curt
++.
++
++Revision 1.2  1998/01/19 18:40:25  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:56  curt
++Initial Flight Gear revision.
++
++ * Revision 1.5  1994/01/11  18:47:05  bjax
++ * Changed include files to use types and constants, not ls_eom.h
++ * Also changed DATA type to SCALAR type.
++ *
++ * Revision 1.4  1993/12/14  21:06:47  bjax
++ * Removed global variable references Altitude and Latitude.   EBJ
++ *
++ * Revision 1.3  1993/06/02  15:03:40  bjax
++ * Made new subroutine for calculating geodetic to geocentric; changed name
++ * of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
++ *
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++              [ 1]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
++                      Control and Simulation", Wiley and Sons, 1992.
++                      ISBN 0-471-61397-5                    
++
++
++----------------------------------------------------------------------------
++
++      CALLED BY:      ls_aux
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS: 
++              lat_geoc        Geocentric latitude, radians, + = North
++              radius          C.G. radius to earth center, ft
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++              lat_geod        Geodetic latitude, radians, + = North
++              alt             C.G. altitude above mean sea level, ft
++              sea_level_r     radius from earth center to sea level at
++                              local vertical (surface normal) of C.G.
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_geodesy.h"
++#include <math.h>
++
++/* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */
++#define ONE_SECOND 4.848136811E-6
++#define HALF_PI 0.5*PI
++
++
++void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod, 
++                    SCALAR *alt, SCALAR *sea_level_r )
++{
++      SCALAR  t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
++      SCALAR  sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
++
++      if(   ( (HALF_PI - lat_geoc) < ONE_SECOND )     /* near North pole */
++         || ( (HALF_PI + lat_geoc) < ONE_SECOND ) )   /* near South pole */
++        {
++          *lat_geod = lat_geoc;
++          *sea_level_r = EQUATORIAL_RADIUS*E;
++          *alt = radius - *sea_level_r;
++        }
++      else
++        {
++          t_lat = tan(lat_geoc);
++          x_alpha = E*EQUATORIAL_RADIUS/sqrt(t_lat*t_lat + E*E);
++          mu_alpha = atan2(sqrt(RESQ - x_alpha*x_alpha),E*x_alpha);
++          if (lat_geoc < 0) mu_alpha = - mu_alpha;
++          sin_mu_a = sin(mu_alpha);
++          delt_lambda = mu_alpha - lat_geoc;
++          r_alpha = x_alpha/cos(lat_geoc);
++          l_point = radius - r_alpha;
++          *alt = l_point*cos(delt_lambda);
++          denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
++          rho_alpha = EQUATORIAL_RADIUS*(1-EPS)/
++            (denom*denom*denom);
++          delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
++          *lat_geod = mu_alpha - delt_mu;
++          lambda_sl = atan( E*E * tan(*lat_geod) ); /* SL geoc. latitude */
++          sin_lambda_sl = sin( lambda_sl );
++          *sea_level_r = sqrt(RESQ
++                         /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
++        }
++}
++
++
++void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, 
++                    SCALAR *sl_radius, SCALAR *lat_geoc )
++{
++    SCALAR lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
++    
++    lambda_sl = atan( E*E * tan(lat_geod) ); /* sea level geocentric latitude */
++    sin_lambda_sl = sin( lambda_sl );
++    cos_lambda_sl = cos( lambda_sl );
++    sin_mu = sin(lat_geod);   /* Geodetic (map makers') latitude */
++    cos_mu = cos(lat_geod);
++    *sl_radius = sqrt(RESQ
++      /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
++    py = *sl_radius*sin_lambda_sl + alt*sin_mu;
++    px = *sl_radius*cos_lambda_sl + alt*cos_mu;
++    *lat_geoc = atan2( py, px );
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5443c04845e10bd952afe5d85efb1b36179ac1fd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++/* a quick ls_geodesy.h */
++
++
++#ifndef _LS_GEODESY_H
++#define _LS_GEODESY_H
++
++
++void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, 
++                    SCALAR *lat_geod, SCALAR *alt, SCALAR *sea_level_r );
++
++void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, SCALAR *sl_radius, 
++                    SCALAR *lat_geoc );
++
++
++#endif /* _LS_GEODESY_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..44b56349fa6f7b72d271e3a0f626f0585ba57394
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,99 @@@
++/***************************************************************************
++
++      TITLE:  ls_gravity
++              
++----------------------------------------------------------------------------
++
++      FUNCTION:       Gravity model for LaRCsim
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created by Bruce Jackson on September 25, 1992.
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    Bruce Jackson
++              
++      CODED BY:       Bruce Jackson
++              
++      MAINTAINED BY:  Bruce Jackson
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++              
++      DATE    PURPOSE                                                 BY
++              
++      940111  Changed include files to "ls_types.h" and 
++              "ls_constants.h" from "ls_eom.h"; also changed DATA types
++              to SCALAR types.                                        EBJ
++              
++                                                                              
++$Header$
++$Log$
++Revision 1.3  1998/08/06 12:46:39  curt
++Header change.
++
++Revision 1.2  1998/01/19 18:40:26  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:56  curt
++Initial Flight Gear revision.
++
++ * Revision 1.2  1994/01/11  18:50:35  bjax
++ * Corrected include files (was ls_eom.h) and DATA types changed
++ * to SCALARs. EBJ
++ *
++ * Revision 1.1  1992/12/30  13:18:46  bjax
++ * Initial revision
++ *            
++
++----------------------------------------------------------------------------
++
++              REFERENCES:     Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
++                              Control and Simulation", Wiley and Sons, 1992.
++                              ISBN 0-471-
++
++----------------------------------------------------------------------------
++
++              CALLED BY:
++
++----------------------------------------------------------------------------
++
++              CALLS TO:
++
++----------------------------------------------------------------------------
++
++              INPUTS:
++
++----------------------------------------------------------------------------
++
++              OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_gravity.h"
++#include <math.h>
++
++#define GM    1.4076431E16
++#define J2    1.08263E-3
++
++void ls_gravity( SCALAR radius, SCALAR lat, SCALAR *gravity )
++{
++
++      SCALAR  radius_ratio, rrsq, sinsqlat;
++      
++      radius_ratio = radius/EQUATORIAL_RADIUS;
++      rrsq = radius_ratio*radius_ratio;
++      sinsqlat = sin(lat)*sin(lat);
++      *gravity = (GM/(radius*radius))
++              *sqrt(2.25*rrsq*rrsq*J2*J2*(5*sinsqlat*sinsqlat -2*sinsqlat + 1)
++                              + 3*rrsq*J2*(1 - 3*sinsqlat) + 1);
++
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dd118dcdae720e799234d4f3bd8919f6fcd6caad
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_gravity.h */
++
++
++#ifndef _LS_GRAVITY_H
++#define _LS_GRAVITY_H
++
++
++void ls_gravity( SCALAR radius, SCALAR lat, SCALAR *gravity );
++
++
++#endif _LS_GRAVITY_H
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7550764468691156c2e2044a636783f191da1d9e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,381 @@@
++/***************************************************************************
++
++      TITLE:  ls_init.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Initializes simulation
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  incomplete
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Written 921230 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    EBJ
++      
++      CODED BY:       EBJ
++      
++      MAINTAINED BY:  EBJ
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      950314  Added get_set, put_set, and init routines.      EBJ
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.5  1998/07/12 03:11:03  curt
++Removed some printf()'s.
++Fixed the autopilot integration so it should be able to update it's control
++  positions every time the internal flight model loop is run, and not just
++  once per rendered frame.
++Added a routine to do the necessary stuff to force an arbitrary altitude
++  change.
++Gave the Navion engine just a tad more power.
++
++Revision 1.4  1998/01/19 18:40:26  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.3  1998/01/05 22:19:25  curt
++#ifdef'd out some unused code that was problematic for MSVC++ to compile.
++
++Revision 1.2  1997/05/29 22:39:58  curt
++Working on incorporating the LaRCsim flight model.
++
++Revision 1.1  1997/05/29 00:09:57  curt
++Initial Flight Gear revision.
++
++ * Revision 1.4  1995/03/15  12:15:23  bjax
++ * Added ls_init_get_set() and ls_init_put_set() and ls_init_init()
++ * routines. EBJ
++ *
++ * Revision 1.3  1994/01/11  19:09:44  bjax
++ * Fixed header includes.
++ *
++ * Revision 1.2  1992/12/30  14:04:53  bjax
++ * Added call to ls_step(0, 1).
++ *
++ * Revision 1.1  92/12/30  14:02:19  bjax
++ * Initial revision
++ * 
++ * Revision 1.1  92/12/30  13:21:21  bjax
++ * Initial revision
++ * 
++ * Revision 1.3  93/12/31  10:34:11  bjax
++ * Added $Log marker as well.
++ * 
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++static char rcsid[] = "$Id$";
++
++#include <string.h>
++#include <stdio.h>
++#include "ls_types.h"
++#include "ls_sym.h"
++#include "ls_step.h"
++#include "ls_init.h"
++#include "navion_init.h"
++
++/* temp */
++#include "ls_generic.h"
++
++#define MAX_NUMBER_OF_CONTINUOUS_STATES 100
++#define MAX_NUMBER_OF_DISCRETE_STATES  20
++#define HARDWIRED 13
++#define NIL_POINTER 0L
++
++#define FACILITY_NAME_STRING "init"
++#define CURRENT_VERSION 10
++
++typedef struct
++{
++    symbol_rec        Symbol;
++    double    value;
++} cont_state_rec;
++
++typedef struct
++{
++    symbol_rec        Symbol;
++    long      value;
++} disc_state_rec;
++
++
++extern SCALAR Simtime;
++
++/* static int Symbols_loaded = 0; */
++static int Number_of_Continuous_States = 0;
++static int Number_of_Discrete_States = 0;
++static cont_state_rec Continuous_States[ MAX_NUMBER_OF_CONTINUOUS_STATES ];
++static disc_state_rec Discrete_States[  MAX_NUMBER_OF_DISCRETE_STATES ];
++
++
++void ls_init_init( void ) {
++    int i;
++    /* int error; */
++
++    if (Number_of_Continuous_States == 0)
++      {
++          Number_of_Continuous_States = HARDWIRED;
++
++          for (i=0;i<HARDWIRED;i++)
++              strcpy( Continuous_States[i].Symbol.Mod_Name, "*" );
++
++          strcpy( Continuous_States[ 0].Symbol.Par_Name, 
++                  "generic_.geodetic_position_v[0]");
++          strcpy( Continuous_States[ 1].Symbol.Par_Name, 
++                  "generic_.geodetic_position_v[1]");
++          strcpy( Continuous_States[ 2].Symbol.Par_Name, 
++                  "generic_.geodetic_position_v[2]");
++          strcpy( Continuous_States[ 3].Symbol.Par_Name, 
++                  "generic_.v_local_v[0]");
++          strcpy( Continuous_States[ 4].Symbol.Par_Name, 
++                  "generic_.v_local_v[1]");
++          strcpy( Continuous_States[ 5].Symbol.Par_Name, 
++                  "generic_.v_local_v[2]");
++          strcpy( Continuous_States[ 6].Symbol.Par_Name, 
++                  "generic_.euler_angles_v[0]");
++          strcpy( Continuous_States[ 7].Symbol.Par_Name, 
++                  "generic_.euler_angles_v[1]");
++          strcpy( Continuous_States[ 8].Symbol.Par_Name, 
++                  "generic_.euler_angles_v[2]");
++          strcpy( Continuous_States[ 9].Symbol.Par_Name, 
++                  "generic_.omega_body_v[0]");
++          strcpy( Continuous_States[10].Symbol.Par_Name, 
++                  "generic_.omega_body_v[1]");
++          strcpy( Continuous_States[11].Symbol.Par_Name, 
++                  "generic_.omega_body_v[2]");
++          strcpy( Continuous_States[12].Symbol.Par_Name, 
++                  "generic_.earth_position_angle");
++      }
++
++    /* commented out by CLO 
++    for (i=0;i<Number_of_Continuous_States;i++)
++      {
++          (void) ls_get_sym_val( &Continuous_States[i].Symbol, &error );
++          if (error) Continuous_States[i].Symbol.Addr = NIL_POINTER;
++      }
++
++    for (i=0;i<Number_of_Discrete_States;i++)
++      {
++          (void) ls_get_sym_val( &Discrete_States[i].Symbol, &error );
++          if (error) Discrete_States[i].Symbol.Addr = NIL_POINTER;
++      }
++    */
++}
++
++void ls_init( void ) {
++    /* int i; */
++
++    Simtime = 0;
++
++    /* printf("LS in init() pos = %.2f\n", Latitude); */
++
++    ls_init_init();
++
++    /* printf("LS after init_init() pos = %.2f\n", Latitude); */
++
++    /* move the states to proper values */
++
++    /* commented out by CLO
++    for(i=0;i<Number_of_Continuous_States;i++)
++      if (Continuous_States[i].Symbol.Addr)
++          ls_set_sym_val( &Continuous_States[i].Symbol, 
++                          Continuous_States[i].value );
++
++    for(i=0;i<Number_of_Discrete_States;i++)
++      if (Discrete_States[i].Symbol.Addr)
++          ls_set_sym_val( &Discrete_States[i].Symbol, 
++                          (double) Discrete_States[i].value );
++    */
++  
++    model_init();
++
++    /* printf("LS after model_init() pos = %.2f\n", Latitude); */
++
++    ls_step(0.0, -1);
++
++    /* printf("LS after ls_step() pos = %.2f\n", Latitude); */
++}
++
++
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++
++char *ls_init_get_set(char *buffer, char *eob)
++/* This routine parses the settings file for "init" entries. */
++{
++
++    static char *fac_name = FACILITY_NAME_STRING;
++    char *bufptr;
++    char line[256];
++    int n, ver, i, error, abrt;
++
++    enum {cont_states_header, cont_states, disc_states_header, disc_states, done } looking_for;
++
++    abrt = 0;
++    looking_for = cont_states_header;
++
++    n = sscanf(buffer, "%s", line);
++    if (n == 0) return 0L;
++    if (strncasecmp( fac_name, line, strlen(fac_name) )) return 0L;
++
++    bufptr = strtok( buffer+strlen(fac_name)+1, "\n");
++    if (bufptr == 0) return 0L;
++
++    sscanf( bufptr, "%d", &ver );
++    if (ver != CURRENT_VERSION) return 0L;
++
++    ls_init_init();
++
++    while( !abrt && (eob > bufptr))
++      {
++      bufptr = strtok( 0L, "\n");
++      if (bufptr == 0) return 0L;
++      if (strncasecmp( bufptr, "end", 3) == 0) break;
++
++      sscanf( bufptr, "%s", line );
++      if (line[0] != '#') /* ignore comments */
++          {
++              switch (looking_for)
++                  {
++                  case cont_states_header:
++                      {
++                          if (strncasecmp( line, "continuous_states", 17) == 0) 
++                              {
++                                  n = sscanf( bufptr, "%s%d", line, 
++                                              &Number_of_Continuous_States );
++                                  if (n != 2) abrt = 1;
++                                  looking_for = cont_states;
++                                  i = 0;
++                              }
++                          break;
++                      }
++                  case cont_states:
++                      {
++                          n = sscanf( bufptr, "%s%s%le", 
++                                      Continuous_States[i].Symbol.Mod_Name,
++                                      Continuous_States[i].Symbol.Par_Name,
++                                      &Continuous_States[i].value );
++                          if (n != 3) abrt = 1;
++                          Continuous_States[i].Symbol.Addr = NIL_POINTER;
++                          i++;
++                          if (i >= Number_of_Continuous_States) 
++                              looking_for = disc_states_header;
++                          break;
++                      }
++                  case disc_states_header:
++                      {
++                          if (strncasecmp( line, "discrete_states", 15) == 0) 
++                              {
++                                  n = sscanf( bufptr, "%s%d", line, 
++                                              &Number_of_Discrete_States );
++                                  if (n != 2) abrt = 1;
++                                  looking_for = disc_states;
++                                  i = 0;
++                              }
++                          break;
++                      }
++                  case disc_states:
++                      {
++                          n = sscanf( bufptr, "%s%s%ld", 
++                                      Discrete_States[i].Symbol.Mod_Name,
++                                      Discrete_States[i].Symbol.Par_Name,
++                                      &Discrete_States[i].value );
++                          if (n != 3) abrt = 1;
++                          Discrete_States[i].Symbol.Addr = NIL_POINTER;
++                          i++;
++                          if (i >= Number_of_Discrete_States) looking_for = done;
++                      }  
++                  case done:
++                      {
++                          break;
++                      }
++                  }
++
++          }
++      }
++
++    Symbols_loaded = !abrt;
++
++    return bufptr;
++}
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++
++
++void ls_init_put_set( FILE *fp )
++{
++    int i;
++
++    if (fp==0) return;
++    fprintf(fp, "\n");
++    fprintf(fp, "#==============================  %s\n", FACILITY_NAME_STRING);
++    fprintf(fp, "\n");
++    fprintf(fp, FACILITY_NAME_STRING);
++    fprintf(fp, "\n");
++    fprintf(fp, "%04d\n", CURRENT_VERSION);
++    fprintf(fp, "  continuous_states: %d\n", Number_of_Continuous_States);
++    fprintf(fp, "#    module    parameter   value\n");
++    for (i=0; i<Number_of_Continuous_States; i++)
++      fprintf(fp, "    %s\t%s\t%E\n", 
++              Continuous_States[i].Symbol.Mod_Name,
++              Continuous_States[i].Symbol.Par_Name,
++              Continuous_States[i].value );
++
++    fprintf(fp, "  discrete_states: %d\n", Number_of_Discrete_States);
++    fprintf(fp, "#    module    parameter   value\n");
++    for (i=0;i<Number_of_Discrete_States;i++)
++      fprintf(fp, "    %s\t%s\t%ld\n",
++              Discrete_States[i].Symbol.Mod_Name,
++              Discrete_States[i].Symbol.Par_Name,
++              Discrete_States[i].value );
++    fprintf(fp, "end\n");
++    return;
++}
++
++void ls_save_current_as_ic( void ) {
++    /* Save current states as initial conditions */
++
++    /* int i, error; */
++
++    /* commented out by CLO 
++    for(i=0;i<Number_of_Continuous_States;i++)
++      if (Continuous_States[i].Symbol.Addr)
++          Continuous_States[i].value = 
++              ls_get_sym_val( &Continuous_States[i].Symbol, &error );
++
++    for(i=0;i<Number_of_Discrete_States;i++)
++      if (Discrete_States[i].Symbol.Addr)
++          Discrete_States[i].value = (long)
++              ls_get_sym_val( &Discrete_States[i].Symbol, &error );
++    */
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..06188f432b1d8016949ff8b5d4033cb225f93f58
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_init.h */
++
++
++#ifndef _LS_INIT_H
++#define _LS_INIT_H
++
++
++void ls_init( void );
++
++
++#endif /* _LS_INIT_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..09eda1ed1f448f8238174fc13e98ec7809deb995
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,670 @@@
++/**************************************************************************
++ * ls_interface.c -- the FG interface to the LaRCsim routines
++ *                   This is a heavily modified version of LaRCsim.c
++ *                   As a result there is much old baggage left in this file.
++ *
++ * Originally Written 921230 by Bruce Jackson
++ * Modified by Curtis Olson, started May 1997.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++/* Original headers follow: */
++
++/***************************************************************************
++
++      TITLE:          LaRCsim.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Top level routine for LaRCSIM.  Includes
++                      global variable declarations.
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  Developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Written 921230 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    EBJ
++      
++      CODED BY:       EBJ
++      
++      MAINTAINED BY:  EBJ
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      930111  Added "progname" variable to keep name of invoking command.
++                                                                      EBJ
++      931012  Removed altitude < 0. test to support gear development. EBJ
++      931214  Added various pressures (Impact, Dynamic, Static, etc.) EBJ
++      931215  Adopted new generic variable structure.                 EBJ
++      931218  Added command line options decoding.                    EBJ
++      940110  Changed file type of matrix file to ".m"                EBJ
++      940513  Renamed this routine "LaRCsim.c" from "ls_main.c"       EBJ
++      940513  Added time_stamp routine,  t_stamp.                     EBJ
++      950225  Added options flag, 'i', to set I/O output rate.        EBJ
++      950306  Added calls to ls_get_settings() and ls_put_settings()  EBJ
++      950314  Options flag 'i' now reads IC file; 'o' is output rate  EBJ
++      950406  Many changes: added definition of default value macros;
++              removed local variables term_update_hz, model_dt, endtime,
++              substituted sim_control_ globals for these; removed
++              initialization of sim_control_.tape_channels; moved optarg
++              to generic extern; added mod_end_time & mod_buf_size flags
++              and temporary buffer_time and data_rate locals to
++              ls_checkopts(); added additional command line switches '-s'
++              and '-b'; made psuedo-mandatory file names for data output
++              switches; considerable rewrite of logic for setting data
++              buffer length and interleave parameters; updated '-h' help
++              output message; added protection logic to calculations of
++              these parameters; added check of return value on first call
++              to ls_cockpit() so <esc> abort works from initial pause
++              state; added call to ls_unsync() immediately following
++              first ls_sync() call, if paused (to avoid alarm clock
++              timeout); moved call to ls_record() into non-paused
++              multiloop path (was filling buffer with identical data
++              during pause); put check of paused flag before calling sync
++              routine ls_pause(); and added call to exit() on termination.
++
++
++$Header$
++$Original log: LaRCsim.c,v $
++ * Revision 1.4.1.7  1995/04/07  01:04:37  bjax
++ * Many changes made to support storage of sim options from run to run,
++ * as well as restructuring storage buffer sizing and some loop logic
++ * changes. See the modification log for details.
++ *
++ * Revision 1.4.1.6  1995/03/29  16:12:09  bjax
++ * Added argument to -o switch; changed run loop to pass dt=0
++ * if in paused mode. EBj
++ *
++ * Revision 1.4.1.5  1995/03/15  12:30:20  bjax
++ * Set paused flag to non-zero by default; moved 'i' I/O rate flag
++ * switch to 'o'; made 'i' an initial conditions file switch; added
++ * null string to ls_get_settings() call so that default settings
++ * file will be read. EBJ
++ *
++ * Revision 1.4.1.4  1995/03/08  12:31:34  bjax
++ * Added userid retrieval and proper termination of time & date strings.
++ *
++ * Revision 1.4.1.3  1995/03/08  12:00:21  bjax
++ * Moved setting of default options to ls_setdefopts from
++ * ls_checkopts; rearranged order of ls_get_settings() call
++ * to between ls_setdefopts and ls_checkopts, so command
++ * line options will override settings file options.
++ * EBJ
++ *
++ * Revision 1.4.1.2  1995/03/06  18:48:49  bjax
++ * Added calles to ls_get_settings() and ls_put_settings(); added
++ * passing of dt and init flags in ls_model(). EBJ
++ *
++ * Revision 1.4.1.1  1995/03/03  02:23:08  bjax
++ * Beta version for LaRCsim, version 1.4
++ *
++ * Revision 1.3.2.7  1995/02/27  20:00:21  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.2.6  1995/02/25  16:52:31  bjax
++ * Added 'i' option to set I/O iteration rate. EBJ
++ *
++ * Revision 1.3.2.5  1995/02/06  19:33:15  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.2.4  1995/02/06  19:30:30  bjax
++ * Oops, should really compile these before checking in. Fixed capitailzation of
++ * Initialize in ls_loop parameter.
++ *
++ * Revision 1.3.2.3  1995/02/06  19:25:44  bjax
++ * Moved main simulation loop into subroutine ls_loop. EBJ
++ *
++ * Revision 1.3.2.2  1994/05/20  21:46:45  bjax
++ * A little better logic on checking for option arguments.
++ *
++ * Revision 1.3.2.1  1994/05/20  19:29:51  bjax
++ * Added options arguments to command line.
++ *
++ * Revision 1.3.1.16  1994/05/17  15:08:45  bjax
++ * Corrected so that full name to directyr and file is saved
++ * in new global variable "fullname"; this allows symbol table
++ * to be extracted when in another default directory.
++ *
++ * Revision 1.3.1.15  1994/05/17  14:50:24  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.14  1994/05/17  14:50:23  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.13  1994/05/17  14:50:21  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.12  1994/05/17  14:50:20  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.11  1994/05/17  13:56:24  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.10  1994/05/17  13:23:03  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.9  1994/05/17  13:20:03  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.8  1994/05/17  13:19:23  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.7  1994/05/17  13:18:29  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.6  1994/05/17  13:16:30  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.5  1994/05/17  13:03:44  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.4  1994/05/17  13:03:38  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.3  1994/05/17  12:49:08  bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.2  1994/05/17  12:48:45  bjax
++ * *** empty log message ***
++ *
++ * Revision 1.3.1.1  1994/05/13  20:39:17  bjax
++ * Top of 1.3 branch.
++ *
++ * Revision 1.2  1994/05/13  19:51:50  bjax
++ * Skip rev
++ *
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++/* #include <sys/types.h> */
++/* #include <sys/stat.h> */
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++#include <time.h>
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_sim_control.h"
++#include "ls_cockpit.h"
++#include "ls_interface.h"
++#include "ls_step.h"
++#include "ls_accel.h"
++#include "ls_aux.h"
++#include "ls_model.h"
++#include "ls_init.h"
++
++// #include <Flight/flight.h>
++// #include <Aircraft/aircraft.h>
++// #include <Debug/fg_debug.h>
++
++
++/* global variable declarations */
++
++/* TAPE               *Tape; */
++GENERIC       generic_;
++SIM_CONTROL   sim_control_;
++COCKPIT         cockpit_;
++
++SCALAR                Simtime;
++
++#define DEFAULT_TERM_UPDATE_HZ 20
++#define DEFAULT_MODEL_HZ 120
++#define DEFAULT_END_TIME 3600.
++#define DEFAULT_SAVE_SPACING 8
++#define DEFAULT_WRITE_SPACING 1
++#define MAX_FILE_NAME_LENGTH 80
++
++/* global variables */
++
++char    *progname;
++char  *fullname;
++
++/* file variables - default simulation settings */
++
++static double model_dt;
++static double speedup;
++static char  asc1name[MAX_FILE_NAME_LENGTH] = "run.asc1";
++static char  tabname[MAX_FILE_NAME_LENGTH]  = "run.dat";
++static char  fltname[MAX_FILE_NAME_LENGTH]  = "run.flt";
++static char  matname[MAX_FILE_NAME_LENGTH]  = "run.m";
++
++
++
++void ls_stamp( void ) {
++    char rcsid[] = "$Id$";
++    char revid[] = "$Revision$";
++    char dateid[] = "$Date$";
++    struct tm *nowtime;
++    time_t nowtime_t;
++    long date;
++    
++    /* report version of LaRCsim*/
++    printf("\nLaRCsim %s, %s\n\n", revid, dateid); 
++    
++    nowtime_t = time( 0 );
++    nowtime = localtime( &nowtime_t ); /* set fields to correct time values */
++    date = (nowtime->tm_year)*10000 
++       + (nowtime->tm_mon + 1)*100
++       + (nowtime->tm_mday);
++    sprintf(sim_control_.date_string, "%06d\0", date);
++    sprintf(sim_control_.time_stamp, "%02d:%02d:%02d\0", 
++      nowtime->tm_hour, nowtime->tm_min, nowtime->tm_sec);
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++    cuserid( sim_control_.userid );   /* set up user id */
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++    return;
++}
++
++void ls_setdefopts( void ) {
++    /* set default values for most options */
++
++    sim_control_.debug = 0;           /* change to non-zero if in dbx! */
++    sim_control_.vision = 0;
++    sim_control_.write_av = 0;                /* write Agile-Vu '.flt' file */
++    sim_control_.write_mat = 0;               /* write matrix-x/matlab script */
++    sim_control_.write_tab = 0;               /* write tab delim. history file */
++    sim_control_.write_asc1 = 0;      /* write GetData file */
++    sim_control_.save_spacing = DEFAULT_SAVE_SPACING; 
++                                      /* interpolation on recording */
++    sim_control_.write_spacing = DEFAULT_WRITE_SPACING;       
++                                      /* interpolation on output */
++    sim_control_.end_time = DEFAULT_END_TIME;
++    sim_control_.model_hz = DEFAULT_MODEL_HZ;
++    sim_control_.term_update_hz = DEFAULT_TERM_UPDATE_HZ;
++    sim_control_.time_slices = (long int)(DEFAULT_END_TIME * DEFAULT_MODEL_HZ / 
++      DEFAULT_SAVE_SPACING);
++    sim_control_.paused = 0;
++
++    speedup = 1.0;
++}
++
++
++/* return result codes from ls_checkopts */
++
++#define OPT_OK 0
++#define OPT_ERR 1
++
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++
++extern char *optarg;
++extern int optind;
++
++int ls_checkopts(argc, argv)  /* check and set options flags */
++  int argc;
++  char *argv[];
++  {
++    int c;
++    int opt_err = 0;
++    int mod_end_time = 0;
++    int mod_buf_size = 0;
++    float buffer_time, data_rate;
++
++    /* set default values */
++
++    buffer_time = sim_control_.time_slices * sim_control_.save_spacing / 
++      sim_control_.model_hz;
++    data_rate   = sim_control_.model_hz / sim_control_.save_spacing;
++
++    while ((c = getopt(argc, argv, "Aa:b:de:f:hi:kmo:r:s:t:x:")) != EOF)
++      switch (c) {
++          case 'A':
++              if (sim_control_.sim_type == GLmouse)
++                {
++                  fprintf(stderr, "Cannot specify both keyboard (k) and ACES (A) cockpits option\n");
++                  fprintf(stderr, "Keyboard operation assumed.\n");
++                  break;
++                }
++              sim_control_.sim_type = cockpit;
++              break;
++          case 'a':
++              sim_control_.write_av = 1;
++              if (optarg != NULL)
++              if (*optarg != '-') 
++                  strncpy(fltname, optarg, MAX_FILE_NAME_LENGTH);
++              else
++                  optind--;
++              break;
++          case 'b':   
++              buffer_time = atof(optarg);
++              if (buffer_time <= 0.) opt_err = -1;
++              mod_buf_size++;
++              break;
++          case 'd':
++              sim_control_.debug = 1;
++              break;
++          case 'e':
++              sim_control_.end_time = atof(optarg);
++              mod_end_time++;
++              break;
++          case 'f':
++              sim_control_.model_hz = atof(optarg);
++              break;
++          case 'h': 
++              opt_err = 1;
++              break;
++          case 'i':
++              /* ls_get_settings( optarg ); */
++              break;
++          case 'k':
++              sim_control_.sim_type = GLmouse;
++              break;
++          case 'm':
++              sim_control_.vision = 1;
++              break;
++          case 'o': 
++              sim_control_.term_update_hz = atof(optarg);
++              if (sim_control_.term_update_hz <= 0.) opt_err = 1;
++              break;
++          case 'r':
++              sim_control_.write_mat = 1;
++              if (optarg != NULL)
++              if (*optarg != '-') 
++                  strncpy(matname, optarg, MAX_FILE_NAME_LENGTH);
++              else
++                  optind--;
++              break;
++          case 's':
++              data_rate = atof(optarg);
++              if (data_rate <= 0.) opt_err = -1;
++              break;
++          case 't':
++              sim_control_.write_tab = 1;
++              if (optarg != NULL)
++              if (*optarg != '-') 
++                  strncpy(tabname, optarg, MAX_FILE_NAME_LENGTH);
++              else
++                  optind--;
++              break;
++          case 'x':
++              sim_control_.write_asc1 = 1;
++              if (optarg != NULL)
++              if (*optarg != '-') 
++                  strncpy(asc1name, optarg, MAX_FILE_NAME_LENGTH);
++              else
++                  optind--;
++              break;
++          default:
++              opt_err = 1;
++          
++      }
++
++    if (opt_err)
++      {
++      fprintf(stderr, "Usage: %s [-options]\n", progname);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  where [-options] is zero or more of the following:\n");
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [A|k]           Run mode: [A]CES cockpit   [default]\n");
++      fprintf(stderr, "                         or [k]eyboard\n");
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [i <filename>]  [i]nitial conditions filename\n");
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [f <value>]     Iteration rate [f]requency, Hz (default is %5.2f Hz)\n", 
++                                              sim_control_.model_hz);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [o <value>]     Display [o]utput frequency, Hz (default is %5.2f Hz)\n", 
++                                              sim_control_.term_update_hz);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [s <value>]     Data storage frequency, Hz (default is %5.2f Hz)\n",
++                                              data_rate);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [e <value>]     [e]nd time in seconds (default %5.1f seconds)\n", 
++                                              sim_control_.end_time);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [b <value>]     circular time history storage [b]uffer size, in seconds \n");
++      fprintf(stderr, "                  (default %5.1f seconds) (normally same as end time)\n", 
++                                              sim_control_.time_slices*sim_control_.save_spacing/
++                                                      sim_control_.model_hz);
++      fprintf(stderr, "\n");
++      fprintf(stderr, "  [atxr [<filename>]] Output: [a]gile-vu  (default name: %s )\n", fltname);
++      fprintf(stderr, "                       and/or [t]ab delimited ( '' name: %s )\n", tabname);
++      fprintf(stderr, "                       and/or [x]plot     (default name: %s)\n", asc1name);
++      fprintf(stderr, "                       and/or mat[r]ix script ( '' name: %s   )\n", matname);
++      fprintf(stderr, "\n");
++      return OPT_ERR;
++      }
++
++/* calculate additional controls */
++
++    sim_control_.save_spacing = (int) (0.5 + sim_control_.model_hz / data_rate);
++    if (sim_control_.save_spacing < 1) sim_control_.save_spacing = 1;
++
++    sim_control_.time_slices = buffer_time * sim_control_.model_hz / 
++      sim_control_.save_spacing;
++    if (sim_control_.time_slices < 2) sim_control_.time_slices = 2;
++       
++    return OPT_OK;
++  }
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++
++
++void ls_loop( SCALAR dt, int initialize ) {
++    /* printf ("  In ls_loop()\n"); */
++    ls_step( dt, initialize );
++    /* if (sim_control_.sim_type == cockpit ) ls_ACES();  */
++    ls_aux();
++    ls_model( dt, initialize );
++    ls_accel();
++}
++
++
++
++int ls_cockpit( void ) {
++    // fgCONTROLS *c;
++
++    sim_control_.paused = 0;
++
++    // c = current_aircraft.controls;
++
++    // Lat_control = FG_Aileron;
++    // Long_control = FG_Elevator;
++    // Long_trim = FG_Elev_Trim;
++    // Rudder_pedal = FG_Rudder;
++    // Throttle_pct = FG_Throttle[0];
++
++    /* printf("Mach = %.2f  ", Mach_number);
++    printf("%.4f,%.4f,%.2f  ", Latitude, Longitude, Altitude);
++    printf("%.2f,%.2f,%.2f\n", Phi, Theta, Psi); */
++
++    return( 0 );
++}
++
++
++/* Initialize the LaRCsim flight model, dt is the time increment for
++   each subsequent iteration through the EOM */
++int ls_toplevel_init(double dt) {
++    model_dt = dt;
++
++    ls_setdefopts();          /* set default options */
++      
++    ls_stamp();   /* ID stamp; record time and date of run */
++
++    if (speedup == 0.0) {
++      fprintf(stderr, "%s: Cannot run with speedup of 0.\n", progname);
++      return 1;
++    }
++
++    /* printf("LS pre Init pos = %.2f\n", Latitude); */
++
++    ls_init();
++
++    /* printf("LS post Init pos = %.2f\n", Latitude); */
++
++    if (speedup > 0) {
++      /* Initialize (get) cockpit (controls) settings */
++      ls_cockpit();
++    }
++
++    return(1);
++}
++
++
++/* Run an iteration of the EOM (equations of motion) */
++int ls_update(int multiloop) {
++    int       i;
++
++    if (speedup > 0) {
++      ls_cockpit();
++    }
++
++    for ( i = 0; i < multiloop; i++ ) {
++      ls_loop( model_dt, 0);
++    }
++
++    return 1;
++}
++
++
++/* Set the altitude (force) */
++int ls_ForceAltitude(double alt_feet) {
++    Altitude = alt_feet;
++    ls_geod_to_geoc( Latitude, Altitude, &Sea_level_radius, &Lat_geocentric);
++    Radius_to_vehicle = Altitude + Sea_level_radius;
++}
++
++
++/* Flight Gear Modification Log
++ *
++ * $Log$
++ * Revision 1.25  1999/01/19 20:57:02  curt
++ * MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++ *
++ * Revision 1.24  1998/12/14 13:27:47  curt
++ * Removed some old, outdated, no longer needed code.
++ *
++ * Revision 1.23  1998/10/16 23:27:44  curt
++ * C++-ifying.
++ *
++ * Revision 1.22  1998/09/29 02:02:59  curt
++ * Added a brake + autopilot mods.
++ *
++ * Revision 1.21  1998/08/22  14:49:56  curt
++ * Attempting to iron out seg faults and crashes.
++ * Did some shuffling to fix a initialization order problem between view
++ * position, scenery elevation.
++ *
++ * Revision 1.20  1998/07/12 03:11:03  curt
++ * Removed some printf()'s.
++ * Fixed the autopilot integration so it should be able to update it's control
++ *   positions every time the internal flight model loop is run, and not just
++ *   once per rendered frame.
++ * Added a routine to do the necessary stuff to force an arbitrary altitude
++ *   change.
++ * Gave the Navion engine just a tad more power.
++ *
++ * Revision 1.19  1998/05/11 18:17:28  curt
++ * Output message tweaking.
++ *
++ * Revision 1.18  1998/04/21 16:59:38  curt
++ * Integrated autopilot.
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.17  1998/02/23 19:07:58  curt
++ * Incorporated Durk's Astro/ tweaks.  Includes unifying the sun position
++ * calculation code between sun display, and other FG sections that use this
++ * for things like lighting.
++ *
++ * Revision 1.16  1998/02/07 15:29:38  curt
++ * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++ * <chotchkiss@namg.us.anritsu.com>
++ *
++ * Revision 1.15  1998/01/22 22:03:47  curt
++ * Removed #include <sys/stat.h>
++ *
++ * Revision 1.14  1998/01/19 19:27:04  curt
++ * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++ * This should simplify things tremendously.
++ *
++ * Revision 1.13  1998/01/19 18:40:26  curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.12  1998/01/06 01:20:16  curt
++ * Tweaks to help building with MSVC++
++ *
++ * Revision 1.11  1998/01/05 22:19:26  curt
++ * #ifdef'd out some unused code that was problematic for MSVC++ to compile.
++ *
++ * Revision 1.10  1997/12/10 22:37:43  curt
++ * Prepended "fg" on the name of all global structures that didn't have it yet.
++ * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++ *
++ * Revision 1.9  1997/08/27 03:30:08  curt
++ * Changed naming scheme of basic shared structures.
++ *
++ * Revision 1.8  1997/06/21 17:12:50  curt
++ * Capitalized subdirectory names.
++ *
++ * Revision 1.7  1997/05/31 19:16:28  curt
++ * Elevator trim added.
++ *
++ * Revision 1.6  1997/05/31 04:13:53  curt
++ * WE CAN NOW FLY!!!
++ *
++ * Continuing work on the LaRCsim flight model integration.
++ * Added some MSFS-like keyboard input handling.
++ *
++ * Revision 1.5  1997/05/30 23:26:25  curt
++ * Added elevator/aileron controls.
++ *
++ * Revision 1.4  1997/05/30 19:30:15  curt
++ * The LaRCsim flight model is starting to look like it is working.
++ *
++ * Revision 1.3  1997/05/30 03:54:12  curt
++ * Made a bit more progress towards integrating the LaRCsim flight model.
++ *
++ * Revision 1.2  1997/05/29 22:39:59  curt
++ * Working on incorporating the LaRCsim flight model.
++ *
++ * Revision 1.1  1997/05/29 00:09:57  curt
++ * Initial Flight Gear revision.
++ *
++ */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..67745dd284f2c9db7c9affa5608a394382f571da
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,113 @@@
++/**************************************************************************
++ * ls_interface.h -- interface to the "LaRCsim" flight model
++ *
++ * Written by Curtis Olson, started May 1997.
++ *
++ * Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _LS_INTERFACE_H
++#define _LS_INTERFACE_H
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++#include "ls_types.h"
++
++
++/* reset flight params to a specific position */ 
++int ls_toplevel_init(double dt);
++
++/* update position based on inputs, positions, velocities, etc. */
++int ls_update(int multiloop);
++
++#if 0
++/* Convert from the fgFLIGHT struct to the LaRCsim generic_ struct */
++int fgFlight_2_LaRCsim (fgFLIGHT *f);
++
++/* Convert from the LaRCsim generic_ struct to the fgFLIGHT struct */
++int fgLaRCsim_2_Flight (fgFLIGHT *f);
++
++void ls_loop( SCALAR dt, int initialize );
++#endif
++
++/* Set the altitude (force) */
++int ls_ForceAltitude(double alt_feet);
++
++
++#endif /* _LS_INTERFACE_H */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++// $Log$
++// Revision 1.11  1998/10/17 01:34:15  curt
++// C++ ifying ...
++//
++// Revision 1.10  1998/10/16 23:27:45  curt
++// C++-ifying.
++//
++// Revision 1.9  1998/07/12 03:11:04  curt
++// Removed some printf()'s.
++// Fixed the autopilot integration so it should be able to update it's control
++//   positions every time the internal flight model loop is run, and not just
++//   once per rendered frame.
++// Added a routine to do the necessary stuff to force an arbitrary altitude
++//   change.
++// Gave the Navion engine just a tad more power.
++//
++// Revision 1.8  1998/04/21 16:59:39  curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.7  1998/02/07 15:29:39  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6  1998/02/03 23:20:17  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.5  1998/01/19 19:27:05  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4  1998/01/19 18:40:27  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3  1997/07/23 21:52:20  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.2  1997/05/29 22:39:59  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.1  1997/05/29 00:09:58  curt
++// Initial Flight Gear revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..808eade4be6667a7daba96f663afea5ff6450223
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,349 @@@
++/***************************************************************************
++
++      TITLE:          ls_matrix.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       general real matrix routines; includes
++                              gaussj() for matrix inversion using
++                              Gauss-Jordan method with full pivoting.
++                              
++      The routines in this module have come more or less from ref [1].
++      Note that, probably due to the heritage of ref [1] (which has a 
++      FORTRAN version that was probably written first), the use of 1 as
++      the first element of an array (or vector) is used. This is accomplished
++      in memory by allocating, but not using, the 0 elements in each dimension.
++      While this wastes some memory, it allows the routines to be ported more
++      easily from FORTRAN (I suspect) as well as adhering to conventional 
++      matrix notation.  As a result, however, traditional ANSI C convention
++      (0-base indexing) is not followed; as the authors of ref [1] point out,
++      there is some question of the portability of the resulting routines
++      which sometimes access negative indexes. See ref [1] for more details.
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 950222 E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    from Numerical Recipes in C, by Press, et. al.
++      
++      CODED BY:       Bruce Jackson
++      
++      MAINTAINED BY:  
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.1  1998/06/27 22:34:57  curt
++Initial revision.
++
++ * Revision 1.1  1995/02/27  19:55:44  bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++      REFERENCES:     [1] Press, William H., et. al, Numerical Recipes in 
++                          C, 2nd edition, Cambridge University Press, 1992
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++
++#ifdef HAVE_UNISTD_H
++#  include <unistd.h>
++#endif
++
++#include "ls_matrix.h"
++
++
++#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
++
++static char rcsid[] = "$Id$";
++
++
++int *nr_ivector(long nl, long nh)
++{
++    int *v;
++
++    v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
++    return v-nl+NR_END;
++}
++
++
++
++double **nr_matrix(long nrl, long nrh, long ncl, long nch)
++/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
++{
++    long i, nrow=nrh-nrl+1, ncol=nch-ncl+1;
++    double **m;
++
++    /* allocate pointers to rows */
++    m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
++
++    if (!m)
++      {
++          fprintf(stderr, "Memory failure in routine 'nr_matrix'.\n");
++          exit(1);
++      }
++
++    m += NR_END;
++    m -= nrl;
++
++    /* allocate rows and set pointers to them */
++    m[nrl] = (double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
++    if (!m[nrl]) 
++      {
++          fprintf(stderr, "Memory failure in routine 'matrix'\n");
++          exit(1);
++      }
++
++    m[nrl] += NR_END;
++    m[nrl] -= ncl;
++
++    for (i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
++
++    /* return pointer to array of pointers to rows */
++    return m;
++}
++
++
++void nr_free_ivector(int *v, long nl /* , long nh */)
++{
++    free( (char *) (v+nl-NR_END));
++}
++
++
++void nr_free_matrix(double **m, long nrl, long nrh, long ncl, long nch)
++/* free a double matrix allocated by nr_matrix() */
++{
++    free((char *) (m[nrl]+ncl-NR_END));
++    free((char *) (m+nrl-NR_END));
++}
++
++
++int nr_gaussj(double **a, int n, double **b, int m)
++
++/* Linear equation solution by Gauss-Jordan elimination. a[1..n][1..n] is */
++/* the input matrix. b[1..n][1..m] is input containing the m right-hand   */
++/* side vectors. On output, a is replaced by its matrix invers, and b is  */
++/* replaced by the corresponding set of solution vectors.                 */
++
++/* Note: this routine modified by EBJ to make b optional, if m == 0 */
++
++{
++    int               *indxc, *indxr, *ipiv;
++    int       i, icol, irow, j, k, l, ll;
++    double       big, dum, pivinv, temp;
++
++    int               bexists = ((m != 0) || (b == 0));
++
++    indxc = nr_ivector(1,n);  /* The integer arrays ipiv, indxr, and  */
++    indxr = nr_ivector(1,n);  /* indxc are used for pivot bookkeeping */
++    ipiv  = nr_ivector(1,n);
++    
++    for (j=1;j<=n;j++) ipiv[j] = 0;
++
++    for (i=1;i<=n;i++)                /* This is the main loop over columns   */
++      {
++          big = 0.0;
++          for (j=1;j<=n;j++)  /* This is outer loop of pivot search   */
++              if (ipiv[j] != 1)
++                  for (k=1;k<=n;k++)
++                      {
++                          if (ipiv[k] == 0)
++                              {
++                                  if (fabs(a[j][k]) >= big)
++                                      {
++                                          big = fabs(a[j][k]);
++                                          irow = j;
++                                          icol = k;
++                                      }
++                              }
++                          else
++                              if (ipiv[k] > 1) return -1;
++                      }
++          ++(ipiv[icol]);
++
++/*    We now have the pivot element, so we interchange rows, if needed,  */
++/* to put the pivot element on the diagonal.  The columns are not        */
++/* physically interchanged, only relabeled: indxc[i], the column of the  */
++/* ith pivot element, is the ith column that is reduced, while indxr[i]  */
++/* is the row in which that pivot element was orignally located. If      */
++/* indxr[i] != indxc[i] there is an implied column interchange.  With    */
++/* this form of bookkeeping, the solution b's will end up in the correct */
++/* order, and the inverse matrix will be scrambed by columns.            */
++
++          if (irow != icol)
++              {
++/*                for (l=1;1<=n;l++) SWAP(a[irow][l],a[icol][l]) */
++                      for (l=1;l<=n;l++) 
++                        { 
++                              temp=a[irow][l]; 
++                              a[irow][l]=a[icol][l]; 
++                              a[icol][l]=temp; 
++                        }
++                  if (bexists) for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
++              }
++          indxr[i] = irow;    /* We are now ready to divide the pivot row */
++          indxc[i] = icol;    /* by the pivot element, a[irow][icol]      */
++          if (a[icol][icol] == 0.0) return -1;
++          pivinv = 1.0/a[icol][icol];
++          a[icol][icol] = 1.0;
++          for (l=1;l<=n;l++) a[icol][l] *= pivinv;
++          if (bexists) for (l=1;l<=m;l++) b[icol][l] *= pivinv;
++          for (ll=1;ll<=n;ll++)       /* Next, we reduce the rows...  */
++              if (ll != icol )        /* .. except for the pivot one  */
++                  {
++                      dum = a[ll][icol];
++                      a[ll][icol] = 0.0;
++                      for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
++         if (bexists) for (l=1;l<=m;l++) b[ll][i] -= b[icol][l]*dum;
++                  }
++      }
++
++/* This is the end of the mail loop over columns of the reduction. It
++       only remains to unscrambled the solution in view of the column
++       interchanges. We do this by interchanging pairs of columns in
++       the reverse order that the permutation was built up. */
++                      
++    for (l=n;l>=1;l--)
++      {
++          if (indxr[l] != indxc[l])
++              for (k=1;k<=n;k++)
++                  SWAP(a[k][indxr[l]],a[k][indxc[l]])
++      }
++
++/* and we are done */
++    
++    nr_free_ivector(ipiv,1 /*,n*/ );
++    nr_free_ivector(indxr,1 /*,n*/ );
++    nr_free_ivector(indxc,1 /*,n*/ );
++
++    return 0; /* indicate success */
++}
++
++void nr_copymat(double **orig, int n, double **copy)
++/* overwrites matrix 'copy' with copy of matrix 'orig' */
++{
++      long i, j;
++      
++      if ((orig==0)||(copy==0)||(n==0)) return;
++      
++      for (i=1;i<=n;i++)
++              for (j=1;j<=n;j++)
++                      copy[i][j] = orig[i][j];
++}
++
++void nr_multmat(double **m1, int n, double **m2, double **prod)
++{
++      long i, j, k;
++      
++      if ((m1==0)||(m2==0)||(prod==0)||(n==0)) return;
++      
++      for (i=1;i<=n;i++)
++              for (j=1;j<=n;j++)
++                      {
++                              prod[i][j] = 0.0;
++                              for(k=1;k<=n;k++) prod[i][j] += m1[i][k]*m2[k][j];
++                      }
++}
++                      
++
++
++void nr_printmat(double **a, int n)
++{
++    int i,j;
++    
++    printf("\n");
++    for(i=1;i<=n;i++) 
++      {
++        for(j=1;j<=n;j++)
++            printf("% 9.4f ", a[i][j]);
++        printf("\n");
++      }
++    printf("\n");
++    
++}
++
++
++void testmat( void ) /* main() for test purposes */
++{
++    double **mat1, **mat2, **mat3;
++    double invmaxlong;
++    int loop, i, j, n = 20;
++    long maxlong = RAND_MAX;
++    int maxloop = 2;
++
++    invmaxlong = 1.0/(double)maxlong;
++    mat1 = nr_matrix(1, n, 1, n );
++    mat2 = nr_matrix(1, n, 1, n );
++    mat3 = nr_matrix(1, n, 1, n );
++
++/*    for(i=1;i<=n;i++) mat1[i][i]= 5.0; */
++
++      for(loop=0;loop<maxloop;loop++)
++      {
++          if (loop != 0)
++              for(i=1;i<=n;i++)
++                  for(j=1;j<=n;j++) 
++                      mat1[i][j] = 2.0 - 4.0*invmaxlong*(double) rand();
++
++              printf("Original matrix:\n");
++          nr_printmat( mat1, n );
++          
++          nr_copymat( mat1, n, mat2 );
++      
++          i = nr_gaussj( mat2, n, 0, 0 );
++      
++          if (i) printf("Singular matrix.\n");
++      
++              printf("Inverted matrix:\n");
++          nr_printmat( mat2, n );
++          
++          nr_multmat( mat1, n, mat2, mat3 );
++          
++          printf("Original multiplied by inverse:\n");
++          nr_printmat( mat3, n );
++          
++          if (loop < maxloop-1) /* sleep(1) */;
++      }
++
++    nr_free_matrix( mat1, 1, n, 1, n );
++    nr_free_matrix( mat2, 1, n, 1, n );
++    nr_free_matrix( mat3, 1, n, 1, n );
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..85ec27e94657caaa7da7fa4f2868f5f91f9364ed
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,108 @@@
++/***************************************************************************
++
++      TITLE:          ls_matrix.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Header file for general real matrix routines.
++                              
++      The routines in this module have come more or less from ref [1].
++      Note that, probably due to the heritage of ref [1] (which has a 
++      FORTRAN version that was probably written first), the use of 1 as
++      the first element of an array (or vector) is used. This is accomplished
++      in memory by allocating, but not using, the 0 elements in each dimension.
++      While this wastes some memory, it allows the routines to be ported more
++      easily from FORTRAN (I suspect) as well as adhering to conventional 
++      matrix notation.  As a result, however, traditional ANSI C convention
++      (0-base indexing) is not followed; as the authors of ref [1] point out,
++      there is some question of the portability of the resulting routines
++      which sometimes access negative indexes. See ref [1] for more details.
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 950222 E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    from Numerical Recipes in C, by Press, et. al.
++      
++      CODED BY:       Bruce Jackson
++      
++      MAINTAINED BY:  
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.1  1998/06/27 22:34:58  curt
++Initial revision.
++
++ * Revision 1.1  1995/02/27  20:02:18  bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++      REFERENCES:     [1] Press, William H., et. al, Numerical Recipes in 
++                          C, 2nd edition, Cambridge University Press, 1992
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++
++#define NR_END 1
++
++/* matrix creation & destruction routines */
++
++int *nr_ivector(long nl, long nh);
++double **nr_matrix(long nrl, long nrh, long ncl, long nch);
++
++void nr_free_ivector(int *v, long nl /* , long nh */);
++void nr_free_matrix(double **m, long nrl, long nrh, long ncl, long nch);
++
++
++/* Gauss-Jordan inversion routine */
++
++int nr_gaussj(double **a, int n, double **b, int m);
++
++/* Linear equation solution by Gauss-Jordan elimination. a[1..n][1..n] is */
++/* the input matrix. b[1..n][1..m] is input containing the m right-hand   */
++/* side vectors. On output, a is replaced by its matrix invers, and b is  */
++/* replaced by the corresponding set of solution vectors.                 */
++
++/* Note: this routine modified by EBJ to make b optional, if m == 0 */
++
++/* Matrix copy, multiply, and printout routines (by EBJ) */
++
++void nr_copymat(double **orig, int n, double **copy);
++void nr_multmat(double **m1, int n, double **m2, double **prod);
++void nr_printmat(double **a, int n);
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b9646a14fff1715c1dfdad623e79aec3c58de9cf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,94 @@@
++/***************************************************************************
++
++      TITLE:          ls_model()      
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Model loop executive
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 October 1992 as part of LaRCSIM project
++                      by Bruce Jackson.
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    Bruce Jackson
++      
++      CODED BY:       Bruce Jackson
++      
++      MAINTAINED BY:  maintainer
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      950306  Added parameters to call: dt, which is the step size
++              to be taken this loop (caution: may vary from call to call)
++              and Initialize, which if non-zero, implies an initialization
++              is requested.                                   EBJ
++
++      CURRENT RCS HEADER INFO:
++$Header$
++$Log$
++Revision 1.3  1998/08/06 12:46:39  curt
++Header change.
++
++Revision 1.2  1998/01/19 18:40:27  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:58  curt
++Initial Flight Gear revision.
++
++ * Revision 1.3  1995/03/06  18:49:46  bjax
++ * Added dt and initialize flag parameters to subroutine calls. This will
++ * support trim routine (to allow single throttle setting to drive
++ * all four throttle positions, for example, if initialize is TRUE).
++ *
++ * Revision 1.2  1993/03/10  06:38:09  bjax
++ * Added additional calls: inertias() and subsystems()... EBJ
++ *
++ * Revision 1.1  92/12/30  13:19:08  bjax
++ * Initial revision
++ * 
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:      ls_step (in initialization), ls_loop (planned)
++
++----------------------------------------------------------------------------
++
++      CALLS TO:       aero(), engine(), gear()
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_model.h"
++#include "default_model_routines.h"
++
++
++void ls_model( SCALAR dt, int Initialize ) {
++    inertias( dt, Initialize );
++    subsystems( dt, Initialize );
++    aero( dt, Initialize );
++    engine( dt, Initialize );
++    gear( dt, Initialize );
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cb0d0321fcad90f2c1ebcefe227425cc22e6ca16
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_model.h */
++
++
++#ifndef _LS_MODEL_H
++#define _LS_MODEL_H
++
++
++void ls_model( SCALAR dt, int Initialize );
++
++
++#endif /* _LS_MODEL_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..753c75be5df19562ad9380a8a5ccfabbc156811c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,132 @@@
++/***************************************************************************
++
++      TITLE:          ls_sim_control.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       LaRCSim simulation control parameters header file
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 18 DEC 1993 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    B. Jackson
++      
++      CODED BY:       B. Jackson
++      
++      MAINTAINED BY:  guess who
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++      940204  Added "overrun" flag to indicate non-real-time frame.
++      940210  Added "vision" flag to indicate use of shared memory.
++      940513  Added "max_tape_channels" and "max_time_slices" EBJ
++      950308  Increased size of time_stamp and date_string to include
++              terminating null char.                          EBJ
++      950314  Addedf "paused" flag to make this global (was local to
++              ls_cockpit routine).                            EBJ
++      950406  Removed tape_channels parameter, and added end_time, model_hz,
++              and term_update_hz parameters.                  EBJ     
++
++$Header$
++$Log$
++Revision 1.4  1998/08/06 12:46:39  curt
++Header change.
++
++Revision 1.3  1998/01/22 02:59:33  curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.2  1998/01/06 01:20:17  curt
++Tweaks to help building with MSVC++
++
++Revision 1.1  1997/05/29 00:09:59  curt
++Initial Flight Gear revision.
++
++ * Revision 1.11  1995/04/07  01:39:09  bjax
++ * Removed tape_channels and added end_time, model_hz, and term_update_hz.
++ *
++ * Revision 1.10  1995/03/15  12:33:29  bjax
++ * Added 'paused' flag.
++ *
++ * Revision 1.9  1995/03/08  12:34:21  bjax
++ * Increased size of date_string and time_stamp by 1 to include terminating null;
++ * added userid field and include of stdio.h. EBJ
++ *
++ * Revision 1.8  1994/05/13  20:41:43  bjax
++ * Increased size of time_stamp to 8 chars to allow for colons.
++ * Added fields "tape_channels" and "time_slices" to allow user to change.
++ *
++ * Revision 1.7  1994/05/10  15:18:49  bjax
++ * Modified write_cmp2 flag to write_asc1 flag, since XPLOT 4.00 doesn't
++ * support cmp2.  Also added RCS header and log entries in header.
++ *
++              
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_SIM_CONTROL_H
++#define _LS_SIM_CONTROL_H
++
++
++#include <stdio.h>
++
++#ifndef SIM_CONTROL
++
++typedef struct {
++
++  enum { batch, terminal, GLmouse, cockpit } sim_type;
++  char simname[64];   /* name of simulation */
++  int run_number;     /* run number of this session                     */
++  char date_string[7];        /* like "931220" */
++  char time_stamp[9];         /* like "13:00:00" */
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++  char userid[L_cuserid]; /* who is running this sim */
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++  long time_slices;   /* number of points that can be recorded (circ buff) */
++  int write_av;               /* will be writing out an Agile_VU file after run */
++  int write_mat;      /* will be writing out a matrix script of session */
++  int write_tab;      /* will be writing out a tab-delimited time history */
++  int write_asc1;     /* will be writing out a GetData ASCII 1 file */
++  int save_spacing;   /* spacing between data points when recording
++                         data to memory; 0 = every point, 1 = every 
++                         other point; 2 = every fourth point, etc. */
++  int write_spacing;  /* spacing between data points when writing
++                         output files; 0 = every point, 1 = every 
++                         other point; 2 = every fourth point, etc. */
++  int overrun;                /* indicates, if non-zero, a frame overrun
++                         occurred in the previous frame. Suitable for
++                         setting a display flag or writing an error
++                         message.                                     */
++  int vision;         /* indicates, if non-zero, marriage to LaRC VISION
++                         software (developed A. Dare and J. Burley of the 
++                         former Cockpit Technologies Branch) */
++  int debug;          /* indicates, if non-zero, to operate in debug mode
++                         which implies disable double-buffering and synch.
++                         attempts to avoid errors */
++  int paused;         /* indicates simulation is paused */
++  float end_time;     /* end of simulation run value */
++  float model_hz;     /* current inner loop frame rate */
++  float term_update_hz; /* current terminal refresh frequency */
++
++} SIM_CONTROL;
++
++extern SIM_CONTROL sim_control_;
++
++#endif
++
++
++#endif /* _LS_SIM_CONTROL_H */
++
++
++/*------------------------  end of ls_sim_control.h ----------------------*/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..58838e8d3692538ca88379b20287c3354d3f366d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,361 @@@
++/***************************************************************************
++
++      TITLE:  ls_step
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Integration routine for equations of motion 
++                      (vehicle states)
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Written 920802 by Bruce Jackson.  Based upon equations
++                      given in reference [1] and a Matrix-X/System Build block
++                      diagram model of equations of motion coded by David Raney
++                      at NASA-Langley in June of 1992.
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    Bruce Jackson
++      
++      CODED BY:       Bruce Jackson
++      
++      MAINTAINED BY:  
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      921223  Modified calculation of Phi and Psi to use the "atan2" routine
++              rather than the "atan" to allow full circular angles.
++              "atan" limits to +/- pi/2.                      EBJ
++              
++      940111  Changed from oldstyle include file ls_eom.h; also changed
++              from DATA to SCALAR type.                       EBJ
++
++      950207  Initialized Alpha_dot and Beta_dot to zero on first pass; calculated
++              thereafter.                                     EBJ
++
++      950224  Added logic to avoid adding additional increment to V_east
++              in case V_east already accounts for rotating earth. 
++                                                              EBJ
++
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.4  1998/08/24 20:09:27  curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3  1998/07/12 03:11:04  curt
++Removed some printf()'s.
++Fixed the autopilot integration so it should be able to update it's control
++  positions every time the internal flight model loop is run, and not just
++  once per rendered frame.
++Added a routine to do the necessary stuff to force an arbitrary altitude
++  change.
++Gave the Navion engine just a tad more power.
++
++Revision 1.2  1998/01/19 18:40:28  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:09:59  curt
++Initial Flight Gear revision.
++
++ * Revision 1.5  1995/03/02  20:24:13  bjax
++ * Added logic to avoid adding additional increment to V_east
++ * in case V_east already accounts for rotating earth. EBJ
++ *
++ * Revision 1.4  1995/02/07  20:52:21  bjax
++ * Added initialization of Alpha_dot and Beta_dot to zero on first
++ * pass; they get calculated by ls_aux on next pass...  EBJ
++ *
++ * Revision 1.3  1994/01/11  19:01:12  bjax
++ * Changed from DATA to SCALAR type; also fixed header files (was ls_eom.h)
++ *
++ * Revision 1.2  1993/06/02  15:03:09  bjax
++ * Moved initialization of geocentric position to subroutine ls_geod_to_geoc.
++ *
++ * Revision 1.1  92/12/30  13:16:11  bjax
++ * Initial revision
++ * 
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++      
++              [ 1]    McFarland, Richard E.: "A Standard Kinematic Model
++                      for Flight Simulation at NASA-Ames", NASA CR-2497,
++                      January 1975
++                       
++              [ 2]    ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++                      pheric and Space Flight Vehicle Coordinate Systems",
++                      February 1992
++                      
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:       None.
++
++----------------------------------------------------------------------------
++
++      INPUTS: State derivatives
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:        States
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_accel.h"
++#include "ls_aux.h"
++#include "ls_model.h"
++#include "ls_step.h"
++#include "ls_geodesy.h"
++#include "ls_gravity.h"
++/* #include "ls_sim_control.h" */
++#include <math.h>
++
++extern SCALAR Simtime;                /* defined in ls_main.c */
++
++void ls_step( SCALAR dt, int Initialize ) {
++      static  int     inited = 0;
++              SCALAR  dth;
++      static  SCALAR  v_dot_north_past, v_dot_east_past, v_dot_down_past;
++      static  SCALAR  latitude_dot_past, longitude_dot_past, radius_dot_past;
++      static  SCALAR  p_dot_body_past, q_dot_body_past, r_dot_body_past;
++              SCALAR  p_local_in_body, q_local_in_body, r_local_in_body;
++              SCALAR  epsilon, inv_eps, local_gnd_veast;
++              SCALAR  e_dot_0, e_dot_1, e_dot_2, e_dot_3;
++      static  SCALAR  e_0, e_1, e_2, e_3;
++      static  SCALAR  e_dot_0_past, e_dot_1_past, e_dot_2_past, e_dot_3_past;
++              SCALAR  cos_Lat_geocentric, inv_Radius_to_vehicle;
++
++/*  I N I T I A L I Z A T I O N   */
++
++
++      if ( (inited == 0) || (Initialize != 0) )
++      {
++/* Set past values to zero */
++      v_dot_north_past = v_dot_east_past = v_dot_down_past      = 0;
++      latitude_dot_past = longitude_dot_past = radius_dot_past  = 0;
++      p_dot_body_past = q_dot_body_past = r_dot_body_past       = 0;
++      e_dot_0_past = e_dot_1_past = e_dot_2_past = e_dot_3_past = 0;
++      
++/* Initialize geocentric position from geodetic latitude and altitude */
++
++      ls_geod_to_geoc( Latitude, Altitude, &Sea_level_radius, &Lat_geocentric);
++      Earth_position_angle = 0;
++      Lon_geocentric = Longitude;
++      Radius_to_vehicle = Altitude + Sea_level_radius;
++
++/* Correct eastward velocity to account for earths' rotation, if necessary */
++
++      local_gnd_veast = OMEGA_EARTH*Sea_level_radius*cos(Lat_geocentric);
++      if( fabs(V_east - V_east_rel_ground) < 0.8*local_gnd_veast )
++      V_east = V_east + local_gnd_veast;
++
++/* Initialize quaternions and transformation matrix from Euler angles */
++
++          e_0 = cos(Psi*0.5)*cos(Theta*0.5)*cos(Phi*0.5) 
++              + sin(Psi*0.5)*sin(Theta*0.5)*sin(Phi*0.5);
++          e_1 = cos(Psi*0.5)*cos(Theta*0.5)*sin(Phi*0.5) 
++              - sin(Psi*0.5)*sin(Theta*0.5)*cos(Phi*0.5);
++          e_2 = cos(Psi*0.5)*sin(Theta*0.5)*cos(Phi*0.5) 
++              + sin(Psi*0.5)*cos(Theta*0.5)*sin(Phi*0.5);
++          e_3 =-cos(Psi*0.5)*sin(Theta*0.5)*sin(Phi*0.5) 
++              + sin(Psi*0.5)*cos(Theta*0.5)*cos(Phi*0.5);
++          T_local_to_body_11 = e_0*e_0 + e_1*e_1 - e_2*e_2 - e_3*e_3;
++          T_local_to_body_12 = 2*(e_1*e_2 + e_0*e_3);
++          T_local_to_body_13 = 2*(e_1*e_3 - e_0*e_2);
++          T_local_to_body_21 = 2*(e_1*e_2 - e_0*e_3);
++          T_local_to_body_22 = e_0*e_0 - e_1*e_1 + e_2*e_2 - e_3*e_3;
++          T_local_to_body_23 = 2*(e_2*e_3 + e_0*e_1);
++          T_local_to_body_31 = 2*(e_1*e_3 + e_0*e_2);
++          T_local_to_body_32 = 2*(e_2*e_3 - e_0*e_1);
++          T_local_to_body_33 = e_0*e_0 - e_1*e_1 - e_2*e_2 + e_3*e_3;
++
++/*    Calculate local gravitation acceleration        */
++
++              ls_gravity( Radius_to_vehicle, Lat_geocentric, &Gravity );
++
++/*    Initialize vehicle model                        */
++
++              ls_aux();
++              ls_model(0.0, 0);
++
++/*    Calculate initial accelerations */
++
++              ls_accel();
++              
++/* Initialize auxiliary variables */
++
++              ls_aux();
++              Alpha_dot = 0.;
++              Beta_dot = 0.;
++
++/* set flag; disable integrators */
++
++              inited = -1;
++              dt = 0;
++              
++      }
++
++/* Update time */
++
++      dth = 0.5*dt;
++      Simtime = Simtime + dt;
++
++/*  L I N E A R   V E L O C I T I E S   */
++
++/* Integrate linear accelerations to get velocities */
++/*    Using predictive Adams-Bashford algorithm     */
++
++    V_north = V_north + dth*(3*V_dot_north - v_dot_north_past);
++    V_east  = V_east  + dth*(3*V_dot_east  - v_dot_east_past );
++    V_down  = V_down  + dth*(3*V_dot_down  - v_dot_down_past );
++    
++/* record past states */
++
++    v_dot_north_past = V_dot_north;
++    v_dot_east_past  = V_dot_east;
++    v_dot_down_past  = V_dot_down;
++    
++/* Calculate trajectory rate (geocentric coordinates) */
++
++    inv_Radius_to_vehicle = 1.0/Radius_to_vehicle;
++    cos_Lat_geocentric = cos(Lat_geocentric);
++
++    if ( cos_Lat_geocentric != 0) {
++      Longitude_dot = V_east/(Radius_to_vehicle*cos_Lat_geocentric);
++    }
++      
++    Latitude_dot = V_north*inv_Radius_to_vehicle;
++    Radius_dot = -V_down;
++      
++/*  A N G U L A R   V E L O C I T I E S   A N D   P O S I T I O N S  */
++    
++/* Integrate rotational accelerations to get velocities */
++
++    P_body = P_body + dth*(3*P_dot_body - p_dot_body_past);
++    Q_body = Q_body + dth*(3*Q_dot_body - q_dot_body_past);
++    R_body = R_body + dth*(3*R_dot_body - r_dot_body_past);
++
++/* Save past states */
++
++    p_dot_body_past = P_dot_body;
++    q_dot_body_past = Q_dot_body;
++    r_dot_body_past = R_dot_body;
++    
++/* Calculate local axis frame rates due to travel over curved earth */
++
++    P_local =  V_east*inv_Radius_to_vehicle;
++    Q_local = -V_north*inv_Radius_to_vehicle;
++    R_local = -V_east*tan(Lat_geocentric)*inv_Radius_to_vehicle;
++    
++/* Transform local axis frame rates to body axis rates */
++
++    p_local_in_body = T_local_to_body_11*P_local + T_local_to_body_12*Q_local + T_local_to_body_13*R_local;
++    q_local_in_body = T_local_to_body_21*P_local + T_local_to_body_22*Q_local + T_local_to_body_23*R_local;
++    r_local_in_body = T_local_to_body_31*P_local + T_local_to_body_32*Q_local + T_local_to_body_33*R_local;
++    
++/* Calculate total angular rates in body axis */
++
++    P_total = P_body - p_local_in_body;
++    Q_total = Q_body - q_local_in_body;
++    R_total = R_body - r_local_in_body;
++    
++/* Transform to quaternion rates (see Appendix E in [2]) */
++
++    e_dot_0 = 0.5*( -P_total*e_1 - Q_total*e_2 - R_total*e_3 );
++    e_dot_1 = 0.5*(  P_total*e_0 - Q_total*e_3 + R_total*e_2 );
++    e_dot_2 = 0.5*(  P_total*e_3 + Q_total*e_0 - R_total*e_1 );
++    e_dot_3 = 0.5*( -P_total*e_2 + Q_total*e_1 + R_total*e_0 );
++
++/* Integrate using trapezoidal as before */
++
++      e_0 = e_0 + dth*(e_dot_0 + e_dot_0_past);
++      e_1 = e_1 + dth*(e_dot_1 + e_dot_1_past);
++      e_2 = e_2 + dth*(e_dot_2 + e_dot_2_past);
++      e_3 = e_3 + dth*(e_dot_3 + e_dot_3_past);
++      
++/* calculate orthagonality correction  - scale quaternion to unity length */
++      
++      epsilon = sqrt(e_0*e_0 + e_1*e_1 + e_2*e_2 + e_3*e_3);
++      inv_eps = 1/epsilon;
++      
++      e_0 = inv_eps*e_0;
++      e_1 = inv_eps*e_1;
++      e_2 = inv_eps*e_2;
++      e_3 = inv_eps*e_3;
++
++/* Save past values */
++
++      e_dot_0_past = e_dot_0;
++      e_dot_1_past = e_dot_1;
++      e_dot_2_past = e_dot_2;
++      e_dot_3_past = e_dot_3;
++      
++/* Update local to body transformation matrix */
++
++      T_local_to_body_11 = e_0*e_0 + e_1*e_1 - e_2*e_2 - e_3*e_3;
++      T_local_to_body_12 = 2*(e_1*e_2 + e_0*e_3);
++      T_local_to_body_13 = 2*(e_1*e_3 - e_0*e_2);
++      T_local_to_body_21 = 2*(e_1*e_2 - e_0*e_3);
++      T_local_to_body_22 = e_0*e_0 - e_1*e_1 + e_2*e_2 - e_3*e_3;
++      T_local_to_body_23 = 2*(e_2*e_3 + e_0*e_1);
++      T_local_to_body_31 = 2*(e_1*e_3 + e_0*e_2);
++      T_local_to_body_32 = 2*(e_2*e_3 - e_0*e_1);
++      T_local_to_body_33 = e_0*e_0 - e_1*e_1 - e_2*e_2 + e_3*e_3;
++      
++/* Calculate Euler angles */
++
++      Theta = asin( -T_local_to_body_13 );
++
++      if( T_local_to_body_11 == 0 )
++      Psi = 0;
++      else
++      Psi = atan2( T_local_to_body_12, T_local_to_body_11 );
++
++      if( T_local_to_body_33 == 0 )
++      Phi = 0;
++      else
++      Phi = atan2( T_local_to_body_23, T_local_to_body_33 );
++
++/* Resolve Psi to 0 - 359.9999 */
++
++      if (Psi < 0 ) Psi = Psi + 2*PI;
++
++/*  L I N E A R   P O S I T I O N S   */
++
++/* Trapezoidal acceleration for position */
++
++      Lat_geocentric    = Lat_geocentric    + dth*(Latitude_dot  + latitude_dot_past );
++      Lon_geocentric    = Lon_geocentric    + dth*(Longitude_dot + longitude_dot_past);
++      Radius_to_vehicle = Radius_to_vehicle + dth*(Radius_dot    + radius_dot_past );
++      Earth_position_angle = Earth_position_angle + dt*OMEGA_EARTH;
++      
++/* Save past values */
++
++      latitude_dot_past  = Latitude_dot;
++      longitude_dot_past = Longitude_dot;
++      radius_dot_past    = Radius_dot;
++      
++/* end of ls_step */
++}
++/*************************************************************************/
++      
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e18f93e30528ae4357faf2a3197398a38856e55f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick ls_step.h */
++
++
++#ifndef _LS_STEP_H
++#define _LS_STEP_H
++
++
++void ls_step( SCALAR dt, int Initialize );    
++
++
++#endif /* _LS_STEP_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eca19894bee6096ca537cce978380dd698da9b00
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,166 @@@
++/***************************************************************************
++
++      TITLE:          ls_sym.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Header file for symbol table routines
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  production
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 930629 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    Bruce Jackson
++      
++      CODED BY:       same
++      
++      MAINTAINED BY:  
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      950227  Added header and declarations for ls_print_findsym_error(),
++              ls_get_double(), and ls_get_double() routines.  EBJ
++
++      950302  Added structure for symbol description.         EBJ
++      
++      950306  Added ls_get_sym_val() and ls_set_sym_val() routines.
++              This is now the production version.             EBJ
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.3  1998/08/06 12:46:40  curt
++Header change.
++
++Revision 1.2  1998/01/22 02:59:34  curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.1  1997/05/29 00:10:00  curt
++Initial Flight Gear revision.
++
++ * Revision 1.9  1995/03/07  12:52:33  bjax
++ * This production version now specified ls_get_sym_val() and ls_put_sym_val().
++ *
++ * Revision 1.6.1.2  1995/03/06  18:45:41  bjax
++ * Added def'n of ls_get_sym_val() and ls_set_sym_val(); changed symbol_rec
++ * Addr field from void * to char *.
++ *  EBJ
++ *
++ * Revision 1.6.1.1  1995/03/03  01:17:44  bjax
++ * Experimental version with just ls_get_double and ls_set_double() routines.
++ *
++ * Revision 1.6  1995/02/27  19:50:49  bjax
++ * Added header and declarations for ls_print_findsym_error(),
++ * ls_get_double(), and ls_set_double().  EBJ
++ *
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_SYM_H
++#define _LS_SYM_H
++
++
++/* Return codes */
++
++#define SYM_NOT_LOADED -2
++#define SYM_UNEXPECTED_ERR -1
++#define SYM_OK 0
++#define SYM_OPEN_ERR 1
++#define SYM_NO_SYMS 2
++#define SYM_MOD_NOT_FOUND 3
++#define SYM_VAR_NOT_FOUND 4
++#define SYM_NOT_SCALAR 5
++#define SYM_NOT_STATIC 6
++#define SYM_MEMORY_ERR 7 
++#define SYM_UNMATCHED_PAREN 8
++#define SYM_BAD_SYNTAX 9
++#define SYM_INDEX_BOUNDS_ERR 10
++
++typedef enum {Unknown, Char, UChar, SHint, USHint, Sint, Uint, Slng, Ulng, flt, dbl} vartype;
++
++typedef char          SYMBOL_NAME[64];
++typedef       vartype         SYMBOL_TYPE;
++
++
++
++typedef struct
++{
++    SYMBOL_NAME       Mod_Name;
++    SYMBOL_NAME       Par_Name;
++    SYMBOL_TYPE Par_Type;
++    SYMBOL_NAME Alias;
++    char      *Addr;
++}     symbol_rec;
++
++
++extern int    ls_findsym( const char *modname, const char *varname, 
++                          char **addr, vartype *vtype );
++  
++extern void   ls_print_findsym_error(int result, 
++                                     char *mod_name, 
++                                     char *var_name);
++  
++extern double ls_get_double(vartype sym_type, void *addr );
++  
++extern void   ls_set_double(vartype sym_type, void *addr, double value );
++
++extern double ls_get_sym_val( symbol_rec *symrec, int *error );
++
++      /* This routine attempts to return the present value of the symbol
++         described in symbol_rec. If Addr is non-zero, the value of that
++         location, interpreted as type double, will be returned. If Addr
++         is zero, and Mod_Name and Par_Name are both not null strings, 
++         the ls_findsym() routine is used to try to obtain the address
++         by looking at debugger symbol tables in the executable image, and
++         the value of the double contained at that address is returned, 
++         and the symbol record is updated to contain the address of that
++         symbol. If an error is discovered, 'error' will be non-zero and
++         and error message is printed on stderr.                      */
++
++extern void   ls_set_sym_val( symbol_rec *symrec, double value );
++
++      /* This routine sets the value of a double at the location pointed
++         to by the symbol_rec's Addr field, if Addr is non-zero. If Addr
++         is zero, and Mod_Name and Par_Name are both not null strings, 
++         the ls_findsym() routine is used to try to obtain the address
++         by looking at debugger symbol tables in the executable image, and
++         the value of the double contained at that address is returned, 
++         and the symbol record is updated to contain the address of that
++         symbol. If an error is discovered, 'error' will be non-zero and
++         and error message is printed on stderr.                      */
++
++
++#endif /* _LS_SYM_H */
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c778e1df7940482a8171ef4a443770f1ad5daa16
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,52 @@@
++/***************************************************************************
++
++      TITLE:  ls_types.h
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       LaRCSim type definitions header file
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 DEC 1993 by Bruce Jackson from old
++                      ls_eom.h header
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    B. Jackson
++      
++      CODED BY:       B. Jackson
++      
++      MAINTAINED BY:  guess who
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++      
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_TYPES_H
++#define _LS_TYPES_H
++
++
++/* SCALAR type is used throughout equations of motion code - sets precision */
++
++typedef double SCALAR;
++
++typedef SCALAR VECTOR_3[3];
++
++/* DATA type is old style; this statement for continuity */
++
++#define DATA SCALAR
++
++
++#endif /* _LS_TYPES_H */
++
++
++/* --------------------------- end of ls_types.h -------------------------*/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b4ecbddeb05e59a29ed85dc1061452e4c4d028c2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++/* test main for playing with the LaRCsim code */
++
++#include "ls_types.h"
++#include "ls_cockpit.h"
++#include "ls_generic.h"
++
++
++COCKPIT cockpit_;
++GENERIC generic_;
++
++int main(int argc, char **argv) {
++    model_init();
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6839e457c37de4371875bd3bd9c878522ce34a91
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,213 @@@
++/***************************************************************************
++
++  TITLE:      Navion_aero
++              
++----------------------------------------------------------------------------
++
++  FUNCTION:   Linear aerodynamics model
++
++----------------------------------------------------------------------------
++
++  MODULE STATUS:      developmental
++
++----------------------------------------------------------------------------
++
++  GENEALOGY:  Based upon class notes from AA271, Stanford University,
++                Spring 1988.  Dr. Robert Cannon, instructor.  
++
++----------------------------------------------------------------------------
++
++  DESIGNED BY:        Bruce Jackson
++              
++  CODED BY:           Bruce Jackson
++              
++  MAINTAINED BY:      Bruce Jackson
++
++----------------------------------------------------------------------------
++
++  MODIFICATION HISTORY:
++              
++  DATE                PURPOSE                                                                                         BY
++  921229     Changed Alpha, Beta into radians; added Alpha bias.
++                                               EBJ
++  930105     Modified to support linear airframe simulation by
++                         adding shared memory initialization routine. EBJ
++  931013     Added scaling by airspeed,  to allow for low-airspeed
++                          ground operations.                          EBJ
++  940216    Scaled long, lat stick and rudder to more appropriate values 
++          of elevator and aileron. EBJ
++
++----------------------------------------------------------------------------
++
++  REFERENCES:
++
++The Navion "aero" routine is a simple representation of the North
++American Navion airplane, a 1950-s vintage single-engine, low-wing
++mono-lane built by NAA (who built the famous P-51 Mustang) supposedly
++as a plane for returning WW-II fighter jocks to carry the family
++around the country in. Unfortunately underpowered, it can still be
++found in small airports across the United States. From behind, it sort
++of looks like a Volkswagen driving a Piper by virtue of its nicely
++rounded cabin roof and small rear window.
++
++The aero routine is only valid around 100 knots; it is referred to as
++a "linear model" of the navion; the data having been extracted by
++someone unknown from a more complete model, or more likely, from
++in-flight measurements and manuever time histories.  It probably came
++from someone at Princeton U; they owned a couple modified Navions that
++had a variable-stability system installed, and were highly
++instrumented (and well calibrated, I assume).
++
++In any event, a linearized model, such as this one, contains various
++"stability derivatives", or estimates of how aerodynamic forces and
++moments vary with changes in angle of attack, angular body rates, and
++control surface deflections. For example, L_beta is an estimate of how
++much roll moment varies per degree of sideslip increase.  A decoding
++ring is given below:
++
++      X       Aerodynamic force, lbs, in X-axis (+ forward)
++      Y       Aerodynamic force, lbs, in Y-axis (+ right)
++      Z       Aerodynamic force, lbs, in Z-axis (+ down)
++      L       Aero. moment about X-axis (+ roll right), ft-lbs
++      M       Aero. moment about Y-axis (+ pitch up), ft-lbs
++      N       Aero. moment about Z-axis (+ nose right), ft-lbs
++
++      0       Subscript implying initial, or nominal, value
++      u       X-axis component of airspeed (ft/sec) (+ forward)
++      v       Y-axis component of airspeed (ft/sec) (+ right) 
++      w       Z-axis component of airspeed (ft/sec) (+ down)
++      p       X-axis ang. rate (rad/sec) (+ roll right), rad/sec
++      q       Y-axis ang. rate (rad/sec) (+ pitch up), rad/sec
++      r       Z-axis ang. rate (rad/sec) (+ yaw right), rad/sec
++      beta    Angle of sideslip, degrees (+ wind in RIGHT ear)
++      da      Aileron deflection, degrees (+ left ail. TE down)
++      de      Elevator deflection, degrees (+ trailing edge down)
++      dr      Rudder deflection, degrees (+ trailing edge LEFT)
++
++----------------------------------------------------------------------------
++
++  CALLED BY:
++
++----------------------------------------------------------------------------
++
++  CALLS TO:
++
++----------------------------------------------------------------------------
++
++  INPUTS:
++
++----------------------------------------------------------------------------
++
++  OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++/* define trimmed w_body to correspond with alpha_trim = 5 */
++#define TRIMMED_W  15.34
++
++extern COCKPIT cockpit_;
++
++
++void aero( SCALAR dt, int Initialize ) {
++  static int init = 0;
++
++  SCALAR u, w;
++  static SCALAR elevator, aileron, rudder;
++  static SCALAR long_scale = 0.3;
++  static SCALAR lat_scale  = 0.1;
++  static SCALAR yaw_scale  = -0.1;
++  static SCALAR scale = 1.0;
++  
++  /* static SCALAR trim_inc = 0.0002; */
++  /* static SCALAR long_trim; */
++
++  static DATA U_0;
++  static DATA X_0;
++  static DATA M_0;
++  static DATA Z_0;
++  static DATA X_u;
++  static DATA X_w;
++  static DATA X_de;
++  static DATA Y_v;
++  static DATA Z_u;
++  static DATA Z_w;
++  static DATA Z_de;
++  static DATA L_beta;
++  static DATA L_p;
++  static DATA L_r;
++  static DATA L_da;
++  static DATA L_dr;
++  static DATA M_w;
++  static DATA M_q;
++  static DATA M_de;
++  static DATA N_beta;
++  static DATA N_p;    
++  static DATA N_r;
++  static DATA N_da;
++  static DATA N_dr;
++
++  if (!init)
++    {
++      init = -1;
++
++      /* Initialize aero coefficients */
++
++      U_0 = 176;
++      X_0 = -573.75;
++      M_0 = 0;
++      Z_0 = -2750;
++      X_u = -0.0451;        /* original value */
++      /* X_u = 0.0000; */   /* for MUCH better performance - EBJ */
++      X_w =  0.03607;
++      X_de = 0;
++      Y_v = -0.2543;
++      Z_u = -0.3697;        /* original value */
++      /* Z_u = -0.03697; */ /* for better performance - EBJ */
++      Z_w = -2.0244;
++      Z_de = -28.17;
++      L_beta = -15.982;
++      L_p = -8.402;
++      L_r = 2.193;
++      L_da = 28.984;
++      L_dr = 2.548;
++      M_w = -0.05;
++      M_q = -2.0767;
++      M_de = -11.1892;
++      N_beta = 4.495;
++      N_p = -0.3498;    
++      N_r = -0.7605;
++      N_da = -0.2218;
++      N_dr = -4.597;
++    }
++    
++  u = V_rel_wind - U_0;
++  w = W_body - TRIMMED_W;
++  
++  elevator = long_scale * Long_control;
++  aileron  = lat_scale  * Lat_control;
++  rudder   = yaw_scale  * Rudder_pedal;
++  
++  /* if(Aft_trim) long_trim = long_trim - trim_inc; */
++  /* if(Fwd_trim) long_trim = long_trim + trim_inc; */
++  
++  scale = V_rel_wind*V_rel_wind/(U_0*U_0); 
++  if (scale > 1.0) scale = 1.0; /* ebj */
++    
++  
++  F_X_aero = scale*(X_0 + Mass*(X_u*u + X_w*w + X_de*elevator));
++  F_Y_aero = scale*(Mass*Y_v*V_body);
++  F_Z_aero = scale*(Z_0 + Mass*(Z_u*u + Z_w*w + Z_de*elevator));
++  
++  M_l_aero = scale*(I_xx*(L_beta*Beta + L_p*P_body + L_r*R_body
++                 + L_da*aileron + L_dr*rudder));
++  M_m_aero = scale*(M_0 + I_yy*(M_w*w + M_q*Q_body + M_de*(elevator + Long_trim)));
++  M_n_aero = scale*(I_zz*(N_beta*Beta + N_p*P_body + N_r*R_body
++                 + N_da*aileron + N_dr*rudder));
++  
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d1ae9018ee8d8337c16ed4ca1f013a92739bdd84
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,82 @@@
++/***************************************************************************
++
++      TITLE:          engine.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       dummy engine routine
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  incomplete
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 15 OCT 92 as dummy routine for checkout. EBJ
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    designer
++      
++      CODED BY:       programmer
++      
++      MAINTAINED BY:  maintainer
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      CURRENT RCS HEADER INFO:
++
++$Header$
++
++ * Revision 1.1  92/12/30  13:21:46  bjax
++ * Initial revision
++ * 
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:      ls_model();
++
++----------------------------------------------------------------------------
++
++      CALLS TO:       none
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <math.h>
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_sim_control.h"
++#include "ls_cockpit.h"
++
++extern SIM_CONTROL    sim_control_;
++
++void engine( SCALAR dt, int init ) {
++    /* if (init) { */
++    Throttle[3] = Throttle_pct;
++    /* } */
++
++    /* F_X_engine = Throttle[3]*813.4/0.2; */  /* original code */
++    /* F_Z_engine = Throttle[3]*11.36/0.2; */  /* original code */
++    F_X_engine = Throttle[3]*813.4/0.83;
++    F_Z_engine = Throttle[3]*11.36/0.83;
++
++    Throttle_pct = Throttle[3];
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d64fdea1a5c6af5f810535909a1ddaa018e69310
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,333 @@@
++/***************************************************************************
++
++      TITLE:  gear
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Landing gear model for example simulation
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Created 931012 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    E. B. Jackson
++      
++      CODED BY:       E. B. Jackson
++      
++      MAINTAINED BY:  E. B. Jackson
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      931218  Added navion.h header to allow connection with
++              aileron displacement for nosewheel steering.    EBJ
++      940511  Connected nosewheel to rudder pedal; adjusted gain.
++      
++      CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.6  1998/10/17 01:34:16  curt
++C++ ifying ...
++
++Revision 1.5  1998/09/29 02:03:00  curt
++Added a brake + autopilot mods.
++
++Revision 1.4  1998/08/06 12:46:40  curt
++Header change.
++
++Revision 1.3  1998/02/03 23:20:18  curt
++Lots of little tweaks to fix various consistency problems discovered by
++Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++passed arguments along to the real printf().  Also incorporated HUD changes
++by Michele America.
++
++Revision 1.2  1998/01/19 18:40:29  curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1  1997/05/29 00:10:02  curt
++Initial Flight Gear revision.
++
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <math.h>
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++
++void sub3( DATA v1[],  DATA v2[], DATA result[] )
++{
++    result[0] = v1[0] - v2[0];
++    result[1] = v1[1] - v2[1];
++    result[2] = v1[2] - v2[2];
++}
++
++void add3( DATA v1[],  DATA v2[], DATA result[] )
++{
++    result[0] = v1[0] + v2[0];
++    result[1] = v1[1] + v2[1];
++    result[2] = v1[2] + v2[2];
++}
++
++void cross3( DATA v1[],  DATA v2[], DATA result[] )
++{
++    result[0] = v1[1]*v2[2] - v1[2]*v2[1];
++    result[1] = v1[2]*v2[0] - v1[0]*v2[2];
++    result[2] = v1[0]*v2[1] - v1[1]*v2[0];
++}
++
++void multtrans3x3by3( DATA m[][3], DATA v[], DATA result[] )
++{
++    result[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2];
++    result[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2];
++    result[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2];
++}
++
++void mult3x3by3( DATA m[][3], DATA v[], DATA result[] )
++{
++    result[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
++    result[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
++    result[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
++}
++
++void clear3( DATA v[] )
++{
++    v[0] = 0.; v[1] = 0.; v[2] = 0.;
++}
++
++void gear( SCALAR dt, int Initialize ) {
++char rcsid[] = "$Id$";
++
++  /*
++   * Aircraft specific initializations and data goes here
++   */
++   
++#define NUM_WHEELS 3
++
++    static int num_wheels = NUM_WHEELS;                   /* number of wheels  */
++    static DATA d_wheel_rp_body_v[NUM_WHEELS][3] =  /* X, Y, Z locations */
++    {
++      { 10.,  0., 4. },                               /* in feet */
++      { -1.,  3., 4. }, 
++      { -1., -3., 4. }
++    };
++    static DATA spring_constant[NUM_WHEELS] =     /* springiness, lbs/ft */
++      { 1500., 5000., 5000. };
++    static DATA spring_damping[NUM_WHEELS] =      /* damping, lbs/ft/sec */
++      { 100.,  150.,  150. };         
++    static DATA percent_brake[NUM_WHEELS] =       /* percent applied braking */
++      { 0.,  0.,  0. };                           /* 0 = none, 1 = full */
++    static DATA caster_angle_rad[NUM_WHEELS] =            /* steerable tires - in */
++      { 0., 0., 0.};                              /* radians, +CW */  
++  /*
++   * End of aircraft specific code
++   */
++    
++  /*
++   * Constants & coefficients for tyres on tarmac - ref [1]
++   */
++   
++    /* skid function looks like:
++     * 
++     *           mu  ^
++     *               |
++     *       max_mu  |       +                
++     *               |      /|                
++     *   sliding_mu  |     / +------  
++     *               |    /           
++     *               |   /            
++     *               +--+------------------------> 
++     *               |  |    |      sideward V
++     *               0 bkout skid
++     *                       V     V
++     */
++  
++  
++    static DATA sliding_mu   = 0.5;   
++    static DATA rolling_mu   = 0.01;  
++    static DATA max_brake_mu = 0.6;   
++    static DATA max_mu             = 0.8;     
++    static DATA bkout_v            = 0.1;
++    static DATA skid_v       = 1.0;
++  /*
++   * Local data variables
++   */
++   
++    DATA d_wheel_cg_body_v[3];                /* wheel offset from cg,  X-Y-Z */
++    DATA d_wheel_cg_local_v[3];               /* wheel offset from cg,  N-E-D */
++    DATA d_wheel_rwy_local_v[3];      /* wheel offset from rwy, N-E-U */
++    DATA v_wheel_body_v[3];           /* wheel velocity,        X-Y-Z */
++    DATA v_wheel_local_v[3];          /* wheel velocity,        N-E-D */
++    DATA f_wheel_local_v[3];          /* wheel reaction force,  N-E-D */
++    DATA temp3a[3], temp3b[3], tempF[3], tempM[3];    
++    DATA reaction_normal_force;               /* wheel normal (to rwy) force  */
++    DATA cos_wheel_hdg_angle, sin_wheel_hdg_angle;    /* temp storage */
++    DATA v_wheel_forward, v_wheel_sideward,  abs_v_wheel_sideward;
++    DATA forward_mu, sideward_mu;     /* friction coefficients        */
++    DATA beta_mu;                     /* breakout friction slope      */
++    DATA forward_wheel_force, sideward_wheel_force;
++
++    int i;                            /* per wheel loop counter */
++  
++  /*
++   * Execution starts here
++   */
++   
++    beta_mu = max_mu/(skid_v-bkout_v);
++    clear3( F_gear_v );               /* Initialize sum of forces...  */
++    clear3( M_gear_v );               /* ...and moments               */
++    
++  /*
++   * Put aircraft specific executable code here
++   */
++   
++    /* replace with cockpit brake handle connection code */
++    percent_brake[1] = Brake_pct;
++    percent_brake[2] = percent_brake[1];
++    
++    caster_angle_rad[0] = 0.03*Rudder_pedal;
++    
++    for (i=0;i<num_wheels;i++)            /* Loop for each wheel */
++    {
++      /*========================================*/
++      /* Calculate wheel position w.r.t. runway */
++      /*========================================*/
++      
++          /* First calculate wheel location w.r.t. cg in body (X-Y-Z) axes... */
++      
++      sub3( d_wheel_rp_body_v[i], D_cg_rp_body_v, d_wheel_cg_body_v );
++      
++          /* then converting to local (North-East-Down) axes... */
++      
++      multtrans3x3by3( T_local_to_body_m,  d_wheel_cg_body_v, d_wheel_cg_local_v );
++      
++          /* Runway axes correction - third element is Altitude, not (-)Z... */
++      
++      d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* since altitude = -Z */
++      
++          /* Add wheel offset to cg location in local axes */
++      
++      add3( d_wheel_cg_local_v, D_cg_rwy_local_v, d_wheel_rwy_local_v );
++      
++          /* remove Runway axes correction so right hand rule applies */
++      
++      d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* now Z positive down */
++      
++      /*============================*/
++      /* Calculate wheel velocities */
++      /*============================*/
++      
++          /* contribution due to angular rates */
++          
++      cross3( Omega_body_v, d_wheel_cg_body_v, temp3a );
++      
++          /* transform into local axes */
++        
++      multtrans3x3by3( T_local_to_body_m, temp3a, temp3b );
++
++          /* plus contribution due to cg velocities */
++
++      add3( temp3b, V_local_rel_ground_v, v_wheel_local_v );
++      
++      
++      /*===========================================*/
++      /* Calculate forces & moments for this wheel */
++      /*===========================================*/
++      
++          /* Add any anticipation, or frame lead/prediction, here... */
++          
++                  /* no lead used at present */
++              
++          /* Calculate sideward and forward velocities of the wheel 
++                  in the runway plane                                 */
++          
++      cos_wheel_hdg_angle = cos(caster_angle_rad[i] + Psi);
++      sin_wheel_hdg_angle = sin(caster_angle_rad[i] + Psi);
++      
++      v_wheel_forward  = v_wheel_local_v[0]*cos_wheel_hdg_angle
++                       + v_wheel_local_v[1]*sin_wheel_hdg_angle;
++      v_wheel_sideward = v_wheel_local_v[1]*cos_wheel_hdg_angle
++                       - v_wheel_local_v[0]*sin_wheel_hdg_angle;
++
++          /* Calculate normal load force (simple spring constant) */
++      
++      reaction_normal_force = 0.;
++      if( d_wheel_rwy_local_v[2] < 0. ) 
++      {
++          reaction_normal_force = spring_constant[i]*d_wheel_rwy_local_v[2]
++                                - v_wheel_local_v[2]*spring_damping[i];
++          if (reaction_normal_force > 0.) reaction_normal_force = 0.;
++              /* to prevent damping component from swamping spring component */
++      }
++      
++          /* Calculate friction coefficients */
++          
++      forward_mu = (max_brake_mu - rolling_mu)*percent_brake[i] + rolling_mu;
++      abs_v_wheel_sideward = sqrt(v_wheel_sideward*v_wheel_sideward);
++      sideward_mu = sliding_mu;
++      if (abs_v_wheel_sideward < skid_v) 
++          sideward_mu = (abs_v_wheel_sideward - bkout_v)*beta_mu;
++      if (abs_v_wheel_sideward < bkout_v) sideward_mu = 0.;
++
++          /* Calculate foreward and sideward reaction forces */
++          
++      forward_wheel_force  =   forward_mu*reaction_normal_force;
++      sideward_wheel_force =  sideward_mu*reaction_normal_force;
++      if(v_wheel_forward < 0.) forward_wheel_force = -forward_wheel_force;
++      if(v_wheel_sideward < 0.) sideward_wheel_force = -sideward_wheel_force;
++      
++          /* Rotate into local (N-E-D) axes */
++      
++      f_wheel_local_v[0] = forward_wheel_force*cos_wheel_hdg_angle
++                        - sideward_wheel_force*sin_wheel_hdg_angle;
++      f_wheel_local_v[1] = forward_wheel_force*sin_wheel_hdg_angle
++                        + sideward_wheel_force*cos_wheel_hdg_angle;
++      f_wheel_local_v[2] = reaction_normal_force;       
++         
++          /* Convert reaction force from local (N-E-D) axes to body (X-Y-Z) */
++      
++      mult3x3by3( T_local_to_body_m, f_wheel_local_v, tempF );
++      
++          /* Calculate moments from force and offsets in body axes */
++
++      cross3( d_wheel_cg_body_v, tempF, tempM );
++      
++      /* Sum forces and moments across all wheels */
++      
++      add3( tempF, F_gear_v, F_gear_v );
++      add3( tempM, M_gear_v, M_gear_v );
++      
++    }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..286c11d1a5ac9ee6af3f92dd3ec16db4cd8e58e3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,69 @@@
++/***************************************************************************
++
++      TITLE:  navion_init.c
++      
++----------------------------------------------------------------------------
++
++      FUNCTION:       Initializes navion math model
++
++----------------------------------------------------------------------------
++
++      MODULE STATUS:  developmental
++
++----------------------------------------------------------------------------
++
++      GENEALOGY:      Added to navion package 930111 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++      DESIGNED BY:    EBJ
++      
++      CODED BY:       EBJ
++      
++      MAINTAINED BY:  EBJ
++
++----------------------------------------------------------------------------
++
++      MODIFICATION HISTORY:
++      
++      DATE    PURPOSE                                         BY
++
++      950314  Removed initialization of state variables, since this is
++              now done (version 1.4b1) in ls_init.            EBJ
++      950406  Removed #include of "shmdefs.h"; shmdefs.h is a duplicate
++              of "navion.h". EBJ
++      
++      CURRENT RCS HEADER:
++
++----------------------------------------------------------------------------
++
++      REFERENCES:
++
++----------------------------------------------------------------------------
++
++      CALLED BY:
++
++----------------------------------------------------------------------------
++
++      CALLS TO:
++
++----------------------------------------------------------------------------
++
++      INPUTS:
++
++----------------------------------------------------------------------------
++
++      OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++void model_init( void ) {
++
++  Throttle[3] = 0.2; Rudder_pedal = 0; Lat_control = 0; Long_control = 0;
++  
++  Dx_pilot = 0; Dy_pilot = 0; Dz_pilot = 0;
++  
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f7d097e14f1ccfea8b68ab00cc663507755ad451
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++/* a quick navion_init.h */
++
++
++#ifndef _NAVION_INIT_H
++#define _NAVION_INIT_H
++
++
++void model_init( void );
++
++
++#endif _NAVION_INIT_H
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4382653b847696e0e9f4c1258b43cc81a5effea5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,741 @@@
++// GLUTkey.cxx -- handle GLUT keyboard events
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++#include <GL/xmesa.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Astro/sky.hxx>
++#include <Autopilot/autopilot.hxx>
++#include <Cockpit/hud.hxx>
++#include <GUI/gui.h>
++#include <Include/fg_constants.h>
++#include <Objects/material.hxx>
++#include <pu.h>
++#include <Time/light.hxx>
++#include <Weather/weather.hxx>
++
++#include "GLUTkey.hxx"
++#include "options.hxx"
++#include "views.hxx"
++
++
++// Force an update of the sky and lighting parameters
++static void local_update_sky_and_lighting_params( void ) {
++    // fgSunInit();
++    SolarSystem::theSolarSystem->rebuild();
++    cur_light_params.Update();
++    fgSkyColorsInit();
++}
++
++
++// Handle keyboard events
++void GLUTkey(unsigned char k, int x, int y) {
++    FGInterface *f;
++    fgTIME *t;
++    FGView *v;
++    FGWeather *w;
++    float fov, tmp;
++    static bool winding_ccw = true;
++
++    f = current_aircraft.fdm_state;
++    t = &cur_time_params;
++    v = &current_view;
++    w = &current_weather;
++
++    FG_LOG( FG_INPUT, FG_DEBUG, "Key hit = " << k );
++    puKeyboard(k, PU_DOWN );
++
++    if ( GLUT_ACTIVE_ALT && glutGetModifiers() ) {
++      FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
++      switch (k) {
++      case 1: // Ctrl-A key
++          fgAPToggleAltitude();
++          return;
++      case 8: // Ctrl-H key
++          fgAPToggleHeading();
++          return;
++      case 18: // Ctrl-R key
++          // temporary
++          winding_ccw = !winding_ccw;
++          if ( winding_ccw ) {
++              glFrontFace ( GL_CCW );
++          } else {
++              glFrontFace ( GL_CW );
++          }
++          return;
++      case 19: // Ctrl-S key
++          fgAPToggleAutoThrottle();
++          return;
++      case 20: // Ctrl-T key
++          fgAPToggleTerrainFollow();
++          return;
++      case 49: // numeric keypad 1
++          v->set_goal_view_offset( FG_PI * 0.75 );
++          return;
++      case 50: // numeric keypad 2
++          v->set_goal_view_offset( FG_PI );
++          return;
++      case 51: // numeric keypad 3
++          v->set_goal_view_offset( FG_PI * 1.25 );
++          return;
++      case 52: // numeric keypad 4
++          v->set_goal_view_offset( FG_PI * 0.50 );
++          return;
++      case 54: // numeric keypad 6
++          v->set_goal_view_offset( FG_PI * 1.50 );
++          return;
++      case 55: // numeric keypad 7
++          v->set_goal_view_offset( FG_PI * 0.25 );
++          return;
++      case 56: // numeric keypad 8
++          v->set_goal_view_offset( 0.00 );
++          return;
++      case 57: // numeric keypad 9
++          v->set_goal_view_offset( FG_PI * 1.75 );
++          return;
++      case 72: // H key
++          // status = current_options.get_hud_status();
++          // current_options.set_hud_status(!status);
++          HUD_brightkey( true );
++          return;
++      case 73: // i key
++          // Minimal Hud
++          fgHUDInit2(&current_aircraft);
++          return;
++      case 77: // M key
++          t->warp -= 60;
++          local_update_sky_and_lighting_params();
++          return;
++      case 84: // T key
++          t->warp_delta -= 30;
++          local_update_sky_and_lighting_params();
++          return;
++      case 87: // W key
++#if defined(FX) && !defined(WIN32)
++          global_fullscreen = ( !global_fullscreen );
++#  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
++          XMesaSetFXmode( global_fullscreen ? 
++                          XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW );
++#  endif
++#endif
++          return;
++      case 88: // X key
++          fov = current_options.get_fov();
++          fov *= 1.05;
++          if ( fov > FG_FOV_MAX ) {
++              fov = FG_FOV_MAX;
++          }
++          current_options.set_fov(fov);
++          v->force_update_fov_math();
++          return;
++      case 90: // Z key
++          tmp = w->get_visibility();   // in meters
++          tmp /= 1.10;
++          w->set_visibility( tmp );
++          return;
++      }
++    } else {
++      FG_LOG( FG_INPUT, FG_DEBUG, "" );
++      switch (k) {
++      case 50: // numeric keypad 2
++          if( fgAPAltitudeEnabled() ) {
++              fgAPAltitudeAdjust( 100 );
++          } else {
++              controls.move_elevator(-0.05);
++          }
++          return;
++      case 56: // numeric keypad 8
++          if( fgAPAltitudeEnabled() ) {
++              fgAPAltitudeAdjust( -100 );
++          } else {
++              controls.move_elevator(0.05);
++          }
++          return;
++      case 49: // numeric keypad 1
++          controls.move_elevator_trim(-0.001);
++          return;
++      case 55: // numeric keypad 7
++          controls.move_elevator_trim(0.001);
++          return;
++      case 52: // numeric keypad 4
++          controls.move_aileron(-0.05);
++          return;
++      case 54: // numeric keypad 6
++          controls.move_aileron(0.05);
++          return;
++      case 48: // numeric keypad Ins
++          if( fgAPHeadingEnabled() ) {
++              fgAPHeadingAdjust( -1 );
++          } else {
++              controls.move_rudder(-0.05);
++          }
++          return;
++      case 13: // numeric keypad Enter
++          if( fgAPHeadingEnabled() ) {
++              fgAPHeadingAdjust( 1 );
++          } else {
++              controls.move_rudder(0.05);
++          }
++          return;
++      case 53: // numeric keypad 5
++          controls.set_aileron(0.0);
++          controls.set_elevator(0.0);
++          controls.set_rudder(0.0);
++          return;
++      case 57: // numeric keypad 9 (Pg Up)
++          if( fgAPAutoThrottleEnabled() ) {
++              fgAPAutoThrottleAdjust( 5 );
++          } else {
++              controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
++          }
++          return;
++      case 51: // numeric keypad 3 (Pg Dn)
++          if( fgAPAutoThrottleEnabled() ) {
++              fgAPAutoThrottleAdjust( -5 );
++          } else {
++              controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
++          }
++          return;
++      case 98: // b key
++          int b_ret;
++          double b_set;
++          b_ret = int( controls.get_brake( 0 ) );
++          b_set = double(!b_ret);
++          controls.set_brake( FGControls::ALL_WHEELS, b_set);
++          return;
++      case 104: // h key
++          HUD_brightkey( false );
++          return;
++      case 105: // i key
++          fgHUDInit(&current_aircraft);  // normal HUD
++          return;
++      case 109: // m key
++          t->warp += 60;
++          local_update_sky_and_lighting_params();
++          return;
++      case 112: // p key
++          t->pause = !t->pause;
++          // printf position and attitude information
++          FG_LOG( FG_INPUT, FG_INFO,
++                  "Lon = " << f->get_Longitude() * RAD_TO_DEG
++                  << "  Lat = " << f->get_Latitude() * RAD_TO_DEG
++                  << "  Altitude = " << f->get_Altitude() * FEET_TO_METER );
++          FG_LOG( FG_INPUT, FG_INFO,
++                  "Heading = " << f->get_Psi() * RAD_TO_DEG 
++                  << "  Roll = " << f->get_Phi() * RAD_TO_DEG
++                  << "  Pitch = " << f->get_Theta() * RAD_TO_DEG );
++          return;
++      case 116: // t key
++          t->warp_delta += 30;
++          local_update_sky_and_lighting_params();
++          return;
++      case 120: // X key
++          fov = current_options.get_fov();
++          fov /= 1.05;
++          if ( fov < FG_FOV_MIN ) {
++              fov = FG_FOV_MIN;
++          }
++          current_options.set_fov(fov);
++          v->force_update_fov_math();
++          return;
++      case 122: // z key
++          tmp = w->get_visibility();   // in meters
++          tmp *= 1.10;
++          w->set_visibility( tmp );
++          return;
++      case 27: // ESC
++          // if( fg_DebugOutput ) {
++          //   fclose( fg_DebugOutput );
++          // }
++          FG_LOG( FG_INPUT, FG_ALERT, 
++                  "Program exiting normally at user request." );
++          exit(-1);
++      }
++    }
++}
++
++
++// Handle "special" keyboard events
++void GLUTspecialkey(int k, int x, int y) {
++    FGView *v;
++
++    v = &current_view;
++
++    FG_LOG( FG_INPUT, FG_DEBUG, "Special key hit = " << k );
++    puKeyboard(k + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN);
++
++    if ( GLUT_ACTIVE_SHIFT && glutGetModifiers() ) {
++      FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
++      switch (k) {
++      case GLUT_KEY_END: // numeric keypad 1
++          v->set_goal_view_offset( FG_PI * 0.75 );
++          return;
++      case GLUT_KEY_DOWN: // numeric keypad 2
++          v->set_goal_view_offset( FG_PI );
++          return;
++      case GLUT_KEY_PAGE_DOWN: // numeric keypad 3
++          v->set_goal_view_offset( FG_PI * 1.25 );
++          return;
++      case GLUT_KEY_LEFT: // numeric keypad 4
++          v->set_goal_view_offset( FG_PI * 0.50 );
++          return;
++      case GLUT_KEY_RIGHT: // numeric keypad 6
++          v->set_goal_view_offset( FG_PI * 1.50 );
++          return;
++      case GLUT_KEY_HOME: // numeric keypad 7
++          v->set_goal_view_offset( FG_PI * 0.25 );
++          return;
++      case GLUT_KEY_UP: // numeric keypad 8
++          v->set_goal_view_offset( 0.00 );
++          return;
++      case GLUT_KEY_PAGE_UP: // numeric keypad 9
++          v->set_goal_view_offset( FG_PI * 1.75 );
++          return;
++      }
++    } else {
++        FG_LOG( FG_INPUT, FG_DEBUG, "" );
++      switch (k) {
++      case GLUT_KEY_F8: // F8 toggles fog ... off fastest nicest...
++          current_options.cycle_fog();
++      
++          if ( current_options.get_fog() == fgOPTIONS::FG_FOG_DISABLED ) {
++              FG_LOG( FG_INPUT, FG_INFO, "Fog disabled" );
++          } else if ( current_options.get_fog() == 
++                      fgOPTIONS::FG_FOG_FASTEST )
++          {
++              FG_LOG( FG_INPUT, FG_INFO, 
++                      "Fog enabled, hint set to fastest" );
++          } else if ( current_options.get_fog() ==
++                      fgOPTIONS::FG_FOG_NICEST )
++          {
++              FG_LOG( FG_INPUT, FG_INFO,
++                      "Fog enabled, hint set to nicest" );
++          }
++
++          return;
++      case GLUT_KEY_F9: // F9 toggles textures on and off...
++          if ( material_mgr.get_textures_loaded() ) {
++              current_options.get_textures() ?
++                  current_options.set_textures(false) :
++                  current_options.set_textures(true);
++              FG_LOG( FG_INPUT, FG_INFO, "Toggling texture" );
++          } else {
++              FG_LOG( FG_INPUT, FG_INFO, 
++                      "No textures loaded, cannot toggle" );
++          }
++          return;
++      case GLUT_KEY_F10: // F10 toggles menu on and off...
++          FG_LOG(FG_INPUT, FG_INFO, "Invoking call back function");
++          hideMenuButton -> 
++              setValue ((int) !(hideMenuButton -> getValue() ) );
++          hideMenuButton -> invokeCallback();
++          //exit(1);
++          return;
++      case GLUT_KEY_UP:
++          if( fgAPAltitudeEnabled() ) {
++              fgAPAltitudeAdjust( -100 );
++          } else {
++              controls.move_elevator(0.05);
++          }
++          return;
++      case GLUT_KEY_DOWN:
++          if( fgAPAltitudeEnabled() ) {
++              fgAPAltitudeAdjust( 100 );
++          } else {
++              controls.move_elevator(-0.05);
++          }
++          return;
++      case GLUT_KEY_LEFT:
++          controls.move_aileron(-0.05);
++          return;
++      case GLUT_KEY_RIGHT:
++          controls.move_aileron(0.05);
++          return;
++      case GLUT_KEY_HOME: // numeric keypad 1
++          controls.move_elevator_trim(0.001);
++          return;
++      case GLUT_KEY_END: // numeric keypad 7
++          controls.move_elevator_trim(-0.001);
++          return;
++      case GLUT_KEY_INSERT: // numeric keypad Ins
++          if( fgAPHeadingEnabled() ) {
++              fgAPHeadingAdjust( -1 );
++          } else {
++              controls.move_rudder(-0.05);
++          }
++          return;
++      case 13: // numeric keypad Enter
++          if( fgAPHeadingEnabled() ) {
++              fgAPHeadingAdjust( 1 );
++          } else {
++              controls.move_rudder(0.05);
++          }
++          return;
++      case 53: // numeric keypad 5
++          controls.set_aileron(0.0);
++          controls.set_elevator(0.0);
++          controls.set_rudder(0.0);
++          return;
++      case GLUT_KEY_PAGE_UP: // numeric keypad 9 (Pg Up)
++          if( fgAPAutoThrottleEnabled() ) {
++              fgAPAutoThrottleAdjust( 5 );
++          } else {
++              controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
++          }
++          return;
++      case GLUT_KEY_PAGE_DOWN: // numeric keypad 3 (Pg Dn)
++          if( fgAPAutoThrottleEnabled() ) {
++              fgAPAutoThrottleAdjust( -5 );
++          } else {
++              controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
++          }
++          return;
++      }
++    }
++}
++
++
++// $Log$
++// Revision 1.44  1999/04/03 04:21:01  curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.43  1999/03/11 23:09:46  curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url.  Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.42  1999/02/26 22:09:46  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.41  1999/02/12 23:22:43  curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.40  1999/02/12 22:17:59  curt
++// Changes to allow adjustment of the autopilot settings while it is activated.
++//
++// Revision 1.39  1999/02/05 21:29:07  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.38  1998/12/11 20:26:25  curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.37  1998/12/09 18:50:22  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.36  1998/12/06 13:51:20  curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.35  1998/12/05 16:13:17  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.34  1998/12/05 15:54:17  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.33  1998/12/03 01:17:12  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.32  1998/11/06 21:18:06  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.31  1998/11/02 18:25:37  curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.30  1998/10/25 14:08:46  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.29  1998/10/20 14:58:57  curt
++// Ctrl-R now reverses default polygon winding so I can see if a hole in the
++// terrain is a result of improper winding, or if it is just an empty hole.
++//
++// Revision 1.28  1998/10/17 01:34:20  curt
++// C++ ifying ...
++//
++// Revision 1.27  1998/10/02 12:46:46  curt
++// Added an "auto throttle"
++//
++// Revision 1.26  1998/10/01 00:38:04  curt
++// More altitude hold tweaks.
++//
++// Revision 1.25  1998/09/29 02:03:36  curt
++// Autopilot mods.
++//
++// Revision 1.24  1998/09/26 13:16:44  curt
++// C++-ified the comments.
++//
++// Revision 1.23  1998/09/17 18:35:30  curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.22  1998/09/15 04:27:27  curt
++// Changes for new Astro code.
++//
++// Revision 1.21  1998/08/29 13:09:25  curt
++// Changes to event manager from Bernie Bright.
++//
++// Revision 1.20  1998/08/24 20:11:12  curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.19  1998/08/05 00:19:33  curt
++// Added a local routine to update lighting params every frame when time is
++// accelerated.
++//
++// Revision 1.18  1998/07/30 23:48:24  curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.17  1998/07/27 18:41:23  curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.16  1998/07/16 17:33:34  curt
++// "H" / "h" now control hud brightness as well with off being one of the
++//   states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++//   whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.15  1998/07/13 21:01:34  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.14  1998/07/06 02:42:02  curt
++// Added support for switching between fullscreen and window mode for
++// Mesa/3dfx/glide.
++//
++// Added a basic splash screen.  Restructured the main loop and top level
++// initialization routines to do this.
++//
++// Hacked in some support for playing a startup mp3 sound file while rest
++// of sim initializes.  Currently only works in Unix using the mpg123 player.
++// Waits for the mpg123 player to finish before initializing internal
++// sound drivers.
++//
++// Revision 1.13  1998/06/27 16:54:32  curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.12  1998/06/12 14:27:26  curt
++// Pui -> PUI, Gui -> GUI.
++//
++// Revision 1.11  1998/06/12 00:57:38  curt
++// Added support for Pui/Gui.
++// Converted fog to GL_FOG_EXP2.
++// Link to static simulator parts.
++// Update runfg.bat to try to be a little smarter.
++//
++// Revision 1.10  1998/05/27 02:24:05  curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.9  1998/05/16 13:05:21  curt
++// Added limits to fov.
++//
++// Revision 1.8  1998/05/13 18:29:56  curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.7  1998/05/07 23:14:14  curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.6  1998/04/28 01:20:20  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.5  1998/04/25 22:06:29  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.4  1998/04/25 20:24:00  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.3  1998/04/24 14:19:29  curt
++// Fog tweaks.
++//
++// Revision 1.2  1998/04/24 00:49:17  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1  1998/04/22 13:25:40  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.33  1998/04/18 04:11:25  curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.32  1998/04/14 02:21:01  curt
++// Incorporated autopilot heading hold contributed by:  Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.31  1998/04/08 23:34:05  curt
++// Patch from Durk to fix trim reversal with numlock key active.
++//
++// Revision 1.30  1998/04/03 22:09:02  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.29  1998/02/07 15:29:40  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.28  1998/02/03 23:20:23  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.27  1998/01/27 00:47:55  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.26  1998/01/19 19:27:07  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.25  1998/01/05 18:44:34  curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.24  1997/12/30 16:36:46  curt
++// Merged in Durk's changes ...
++//
++// Revision 1.23  1997/12/15 23:54:44  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.22  1997/12/10 22:37:45  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.21  1997/08/27 21:32:23  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.20  1997/08/27 03:30:13  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.19  1997/08/25 20:27:21  curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.18  1997/08/22 21:34:38  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.17  1997/07/19 22:34:02  curt
++// Moved PI definitions to ../constants.h
++// Moved random() stuff to ../Utils/ and renamed fg_random()
++//
++// Revision 1.16  1997/07/18 23:41:24  curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.15  1997/07/16 20:04:47  curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.14  1997/07/12 03:50:20  curt
++// Added an #include <Windows32/Base.h> to help compiling for Win32
++//
++// Revision 1.13  1997/06/25 15:39:46  curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.12  1997/06/21 17:12:52  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.11  1997/06/18 04:10:31  curt
++// A couple more runway tweaks ...
++//
++// Revision 1.10  1997/06/18 02:21:23  curt
++// Hacked in a runway
++//
++// Revision 1.9  1997/06/02 03:40:06  curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.8  1997/06/02 03:01:38  curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.7  1997/05/31 19:16:25  curt
++// Elevator trim added.
++//
++// Revision 1.6  1997/05/31 04:13:52  curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.5  1997/05/30 23:26:19  curt
++// Added elevator/aileron controls.
++//
++// Revision 1.4  1997/05/27 17:44:31  curt
++// Renamed & rearranged variables and routines.   Added some initial simple
++// timer/alarm routines so the flight model can be updated on a regular 
++// interval.
++//
++// Revision 1.3  1997/05/23 15:40:25  curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.2  1997/05/23 00:35:12  curt
++// Trying to get fog to work ...
++//
++// Revision 1.1  1997/05/21 15:57:50  curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.2  1997/05/19 18:22:41  curt
++// Parameter tweaking ... starting to stub in fog support.
++//
++// Revision 1.1  1997/05/16 16:05:51  curt
++// Initial revision.
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b0322e1051d29ece763b439badd065dfc4ba401e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,110 @@@
++// GLUTkey.hxx -- handle GLUT keyboard events
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _GLUTKEY_HXX
++#define _GLUTKEY_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++
++// Handle keyboard events
++void GLUTkey(unsigned char k, int x, int y);
++void GLUTspecialkey(int k, int x, int y);
++
++
++#endif // _GLUTKEY_HXX
++
++
++// $Log$
++// Revision 1.4  1999/03/12 22:51:53  curt
++// Converted to C++ style comments.
++//
++// Revision 1.3  1999/03/11 23:09:47  curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url.  Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.2  1998/04/24 00:49:18  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1  1998/04/22 13:25:41  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.9  1998/04/21 17:02:36  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.8  1998/04/03 22:09:02  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.7  1998/02/12 21:59:44  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6  1998/01/22 02:59:36  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.5  1997/07/23 21:52:23  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.4  1997/06/02 03:40:06  curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.3  1997/05/31 04:13:52  curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.2  1997/05/23 15:40:25  curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.1  1997/05/21 15:57:51  curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.2  1997/05/17 00:17:34  curt
++// Trying to stub in support for standard OpenGL.
++//
++// Revision 1.1  1997/05/16 16:05:53  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3060fa11b933294a9189638d5e580eaa58e41222
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1800 @@@
++// GLUTmain.cxx -- top level sim routines
++//
++// Written by Curtis Olson for OpenGL, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++#define MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#  include <float.h>                    
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++#include <stdio.h>
++#include <string.h>
++#include <string>
++
++#ifdef HAVE_STDLIB_H
++#   include <stdlib.h>
++#endif
++
++#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.hxx>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Astro/sky.hxx>
++#include <Astro/stars.hxx>
++#include <Astro/solarsystem.hxx>
++
++#ifdef ENABLE_AUDIO_SUPPORT
++#  include <sl.h>
++#  include <sm.h>
++#endif
++
++#include <Autopilot/autopilot.hxx>
++#include <Cockpit/cockpit.hxx>
++#include <GUI/gui.h>
++#include <Joystick/joystick.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Math/fg_random.h>
++#include <pu.h>
++#include <Scenery/scenery.hxx>
++#include <Scenery/tilemgr.hxx>
++#include <Time/event.hxx>
++#include <Time/fg_time.hxx>
++#include <Time/fg_timer.hxx>
++#include <Time/sunpos.hxx>
++#include <Weather/weather.hxx>
++
++#include "GLUTkey.hxx"
++#include "fg_init.hxx"
++#include "options.hxx"
++#include "splash.hxx"
++#include "views.hxx"
++#include "fg_serial.hxx"
++
++
++// This is a record containing a bit of global housekeeping information
++FGGeneral general;
++
++// Specify our current idle function state.  This is used to run all
++// our initializations out of the glutIdleLoop() so that we can get a
++// splash screen up and running right away.
++static int idle_state = 0;
++
++// Another hack
++int use_signals = 0;
++
++// Global structures for the Audio library
++#ifdef ENABLE_AUDIO_SUPPORT
++slEnvelope pitch_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
++slEnvelope volume_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
++slScheduler *audio_sched;
++smMixer *audio_mixer;
++slSample *s1;
++slSample *s2;
++#endif
++
++
++// The following defines flight gear options. Because glutlib will also
++// want to parse its own options, those options must not be included here
++// or they will get parsed by the main program option parser. Hence case
++// is significant for any option added that might be in conflict with
++// glutlib's parser.
++//
++// glutlib parses for:
++//    -display
++//    -direct   (invalid in Win32)
++//    -geometry
++//    -gldebug
++//    -iconized
++//    -indirect (invalid in Win32)
++//    -synce
++//
++// Note that glutlib depends upon strings while this program's
++// option parser wants only initial characters followed by numbers
++// or pathnames.
++//
++
++
++// fgInitVisuals() -- Initialize various GL/view parameters
++static void fgInitVisuals( void ) {
++    fgLIGHT *l;
++
++    l = &cur_light_params;
++
++    // Go full screen if requested ...
++    if ( current_options.get_fullscreen() ) {
++      glutFullScreen();
++    }
++
++    // If enabled, normal vectors specified with glNormal are scaled
++    // to unit length after transformation.  See glNormal.
++    // xglEnable( GL_NORMALIZE );
++
++    xglEnable( GL_LIGHTING );
++    xglEnable( GL_LIGHT0 );
++    xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
++
++    // xglFogi (GL_FOG_MODE, GL_LINEAR);
++    xglFogi (GL_FOG_MODE, GL_EXP2);
++    // Fog density is now set when the weather system is initialized
++    // xglFogf (GL_FOG_DENSITY, w->fog_density);
++    if ( (current_options.get_fog() == 1) || 
++       (current_options.get_shading() == 0) ) {
++      // if fastest fog requested, or if flat shading force fastest
++      xglHint ( GL_FOG_HINT, GL_FASTEST );
++    } else if ( current_options.get_fog() == 2 ) {
++      xglHint ( GL_FOG_HINT, GL_NICEST );
++    }
++    if ( current_options.get_wireframe() ) {
++      // draw wire frame
++      xglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
++    }
++
++    // This is the default anyways, but it can't hurt
++    xglFrontFace ( GL_CCW );
++
++    // Just testing ...
++    // xglEnable(GL_POINT_SMOOTH);
++    // xglEnable(GL_LINE_SMOOTH);
++    // xglEnable(GL_POLYGON_SMOOTH);      
++}
++
++
++#if 0
++// Draw a basic instrument panel
++static void fgUpdateInstrViewParams( void ) {
++
++    exit(0);
++
++    fgVIEW *v = &current_view;
++
++    xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
++  
++    xglMatrixMode(GL_PROJECTION);
++    xglPushMatrix();
++  
++    xglLoadIdentity();
++    gluOrtho2D(0, 640, 0, 480);
++    xglMatrixMode(GL_MODELVIEW);
++    xglPushMatrix();
++    xglLoadIdentity();
++
++    xglColor3f(1.0, 1.0, 1.0);
++    xglIndexi(7);
++  
++    xglDisable(GL_DEPTH_TEST);
++    xglDisable(GL_LIGHTING);
++  
++    xglLineWidth(1);
++    xglColor3f (0.5, 0.5, 0.5);
++
++    xglBegin(GL_QUADS);
++    xglVertex2f(0.0, 0.00);
++    xglVertex2f(0.0, 480.0);
++    xglVertex2f(640.0,480.0);
++    xglVertex2f(640.0, 0.0);
++    xglEnd();
++
++    xglRectf(0.0,0.0, 640, 480);
++    xglEnable(GL_DEPTH_TEST);
++    xglEnable(GL_LIGHTING);
++    xglMatrixMode(GL_PROJECTION);
++    xglPopMatrix();
++    xglMatrixMode(GL_MODELVIEW);
++    xglPopMatrix();
++}
++#endif
++
++
++// Update all Visuals (redraws anything graphics related)
++static void fgRenderFrame( void ) {
++    fgLIGHT *l = &cur_light_params;
++    fgTIME *t = &cur_time_params;
++    FGView *v = &current_view;
++
++    double angle;
++    // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
++    GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
++    GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
++    GLbitfield clear_mask;
++
++    if ( idle_state != 1000 ) {
++      // still initializing, draw the splash screen
++      if ( current_options.get_splash_screen() == 1 ) {
++          fgSplashUpdate(0.0);
++      }
++    } else {
++      // idle_state is now 1000 meaning we've finished all our
++      // initializations and are running the main loop, so this will
++      // now work without seg faulting the system.
++
++      // printf("Ground = %.2f  Altitude = %.2f\n", scenery.cur_elev, 
++      //        FG_Altitude * FEET_TO_METER);
++    
++      // this is just a temporary hack, to make me understand Pui
++      // timerText -> setLabel (ctime (&t->cur_time));
++      // end of hack
++
++      // 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;
++      }
++      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_textures() ) {
++              // glClearColor(black[0], black[1], black[2], black[3]);
++              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], 
++                       l->sky_color[2], l->sky_color[3]);
++          clear_mask |= GL_COLOR_BUFFER_BIT;
++      }
++      xglClear( clear_mask );
++
++      // Tell GL we are switching to model view parameters
++      xglMatrixMode(GL_MODELVIEW);
++      // xglLoadIdentity();
++
++      // draw sky
++      xglDisable( GL_DEPTH_TEST );
++      xglDisable( GL_LIGHTING );
++      xglDisable( GL_CULL_FACE );
++      xglDisable( GL_FOG );
++      xglShadeModel( GL_SMOOTH );
++      if ( current_options.get_skyblend() ) {
++          fgSkyRender();
++      }
++
++      // setup transformation for drawing astronomical objects
++      xglPushMatrix();
++      // Translate to view position
++      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;
++      // printf("Rotating astro objects by %.2f degrees\n",angle);
++      xglRotatef( angle, 0.0, 0.0, -1.0 );
++
++      // draw stars and planets
++      fgStarsRender();
++      SolarSystem::theSolarSystem->draw();
++
++      xglPopMatrix();
++
++      // draw scenery
++      if ( current_options.get_shading() ) {
++          xglShadeModel( GL_SMOOTH ); 
++      } else {
++          xglShadeModel( GL_FLAT ); 
++      }
++      xglEnable( GL_DEPTH_TEST );
++      if ( current_options.get_fog() > 0 ) {
++          xglEnable( GL_FOG );
++          xglFogfv (GL_FOG_COLOR, l->adj_fog_color);
++      }
++      // set lighting parameters
++      xglLightfv(GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
++      xglLightfv(GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
++      
++      if ( current_options.get_textures() ) {
++          // texture parameters
++          xglEnable( GL_TEXTURE_2D );
++          xglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
++          xglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
++          // set base color (I don't think this is doing anything here)
++          xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
++          xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
++      } else {
++          xglDisable( GL_TEXTURE_2D );
++          xglMaterialfv (GL_FRONT, GL_AMBIENT, terrain_color);
++          xglMaterialfv (GL_FRONT, GL_DIFFUSE, terrain_color);
++          // xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
++          // xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
++      }
++
++      fgTileMgrRender();
++
++      xglDisable( GL_TEXTURE_2D );
++      xglDisable( GL_FOG );
++
++      // display HUD && Panel
++      fgCockpitUpdate();
++
++      // We can do translucent menus, so why not. :-)
++      xglEnable    ( GL_BLEND ) ;
++      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, int remainder) {
++    FGInterface *f = current_aircraft.fdm_state;
++    fgLIGHT *l = &cur_light_params;
++    fgTIME *t = &cur_time_params;
++    FGView *v = &current_view;
++    int i;
++
++    // update the flight model
++    if ( multi_loop < 0 ) {
++      multi_loop = DEFAULT_MULTILOOP;
++    }
++
++    if ( !t->pause ) {
++      // run Autopilot system
++      fgAPRun();
++
++      // printf("updating flight model x %d\n", multi_loop);
++      fgFDMUpdate( current_options.get_flight_model(), 
++                           cur_fdm_state, multi_loop, remainder );
++    } else {
++      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->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->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->inc_view_offset( -0.01 );
++              }
++          } else {
++              if ( v->get_view_offset() - v->get_goal_view_offset() < FG_PI ){
++                  v->inc_view_offset( -0.01 );
++              } else {
++                  v->inc_view_offset( 0.01 );
++              }
++          }
++          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) 
++      - (f->get_Psi() - v->get_view_offset() );
++    while ( tmp < 0.0 ) {
++      tmp += FG_2PI;
++    }
++    while ( tmp > FG_2PI ) {
++      tmp -= FG_2PI;
++    }
++    /* printf("Psi = %.2f, viewoffset = %.2f sunrot = %.2f rottosun = %.2f\n",
++         FG_Psi * RAD_TO_DEG, v->view_offset * RAD_TO_DEG, 
++         -(l->sun_rotation+FG_PI) * RAD_TO_DEG, tmp * RAD_TO_DEG); */
++    l->UpdateAdjFog();
++}
++
++
++void fgInitTimeDepCalcs( void ) {
++    // initialize timer
++
++    // #ifdef HAVE_SETITIMER
++    //   fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
++    // #endif HAVE_SETITIMER
++}
++
++static const double alt_adjust_ft = 3.758099;
++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 ) {
++    FGInterface *f;
++    fgTIME *t;
++    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, "======= ==== ====");
++
++#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,
++         f->get_Runway_altitude() * FEET_TO_METER,
++         f->get_Altitude() * FEET_TO_METER); */
++
++    if ( scenery.cur_elev > -9990 ) {
++      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", 
++                 f->get_Altitude() * FEET_TO_METER,
++                 scenery.cur_elev + alt_adjust_m - 3.0,
++                 scenery.cur_elev + alt_adjust_m );
++          fgFDMForceAltitude( current_options.get_flight_model(), 
++                              scenery.cur_elev + alt_adjust_m );
++
++          FG_LOG( FG_ALL, FG_DEBUG, 
++                  "<*> resetting altitude to " 
++                  << f->get_Altitude() * FEET_TO_METER << " meters" );
++      }
++      fgFDMSetGroundElevation( current_options.get_flight_model(),
++                               scenery.cur_elev );  // meters
++    }
++
++    /* printf("Adjustment - ground = %.2f  runway = %.2f  alt = %.2f\n",
++         scenery.cur_elev,
++         f->get_Runway_altitude() * FEET_TO_METER,
++         f->get_Altitude() * FEET_TO_METER); */
++
++    // update "time"
++    fgTimeUpdate(f, t);
++
++    // Get elapsed time (in usec) for this past frame
++    elapsed = fgGetTimeInterval();
++    FG_LOG( FG_ALL, FG_DEBUG, 
++          "Elapsed time interval is = " << elapsed 
++          << ", previous remainder is = " << remainder );
++
++    // Calculate frame rate average
++    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];
++          // printf("frame[%d] = %.2f\n", i, g->frames[i]);
++          g->frames[i+1] = g->frames[i];
++      }
++      g->frames[0] = 1000.0 / (float)elapsed;
++      // printf("frame[0] = %.2f\n", g->frames[0]);
++      accum += g->frames[0];
++      g->frame_rate = accum / (float)FG_FRAME_RATE_HISTORY;
++      // printf("ave = %.2f\n", g->frame_rate);
++    }
++    */
++
++    // 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
++      if ( multi_loop > 0 ) {
++          fgUpdateTimeDepCalcs(multi_loop, remainder);
++      } else {
++          FG_LOG( FG_ALL, FG_INFO, "Elapsed time is zero ... we're zinging" );
++      }
++    }
++
++    // Do any serial port work that might need to be done
++    fgSerialProcess();
++
++    // see if we need to load any new scenery tiles
++    fgTileMgrUpdate();
++
++    // Process/manage pending events
++    global_events.Process();
++
++    // Run audio scheduler
++#ifdef ENABLE_AUDIO_SUPPORT
++    if ( current_options.get_sound() && !audio_sched->not_working() ) {
++
++#   ifdef MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
++
++      // note: all these factors are relative to the sample.  our
++      // sample format should really contain a conversion factor so
++      // that we can get prop speed right for arbitrary samples.
++      // Note that for normal-size props, there is a point at which
++      // the prop tips approach the speed of sound; that is a pretty
++      // strong limit to how fast the prop can go.
++
++      // multiplication factor is prime pitch control; add some log
++      // component for verisimilitude
++
++      double pitch = log((controls.get_throttle(0) * 14.0) + 1.0);
++      //fprintf(stderr, "pitch1: %f ", pitch);
++      if (controls.get_throttle(0) > 0.0 || f->v_rel_wind > 40.0) {
++          //fprintf(stderr, "rel_wind: %f ", f->v_rel_wind);
++          // only add relative wind and AoA if prop is moving
++          // or we're really flying at idle throttle
++          if (pitch < 5.4) {  // this needs tuning
++              // prop tips not breaking sound barrier
++              pitch += log(f->v_rel_wind + 0.8)/2;
++          } else {
++              // prop tips breaking sound barrier
++              pitch += log(f->v_rel_wind + 0.8)/10;
++          }
++          //fprintf(stderr, "pitch2: %f ", pitch);
++          //fprintf(stderr, "AoA: %f ", FG_Gamma_vert_rad);
++
++          // Angle of Attack next... -x^3(e^x) is my best guess Just
++          // need to calculate some reasonable scaling factor and
++          // then clamp it on the positive aoa (neg adj) side
++          double aoa = f->get_Gamma_vert_rad() * 2.2;
++          double tmp = 3.0;
++          double aoa_adj = pow(-aoa, tmp) * pow(M_E, aoa);
++          if (aoa_adj < -0.8) aoa_adj = -0.8;
++          pitch += aoa_adj;
++          //fprintf(stderr, "pitch3: %f ", pitch);
++
++          // don't run at absurdly slow rates -- not realistic
++          // and sounds bad to boot.  :-)
++          if (pitch < 0.8) pitch = 0.8;
++      }
++      //fprintf(stderr, "pitch4: %f\n", pitch);
++
++      double volume = controls.get_throttle(0) * 1.15 + 0.3 +
++          log(f->v_rel_wind + 1.0)/14.0;
++      // fprintf(stderr, "volume: %f\n", volume);
++
++      pitch_envelope.setStep  ( 0, 0.01, pitch );
++      volume_envelope.setStep ( 0, 0.01, volume );
++
++#   else
++
++       double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
++       pitch_envelope.setStep  ( 0, 0.01, param );
++       volume_envelope.setStep ( 0, 0.01, param );
++
++#   endif // experimental throttle patch
++
++      audio_sched -> update();
++    }
++#endif
++
++    // redraw display
++    fgRenderFrame();
++
++    FG_LOG( FG_ALL, FG_DEBUG, "" );
++}
++
++
++// This is the top level master main function that is registered as
++// our idle funciton
++//
++
++// The first few passes take care of initialization things (a couple
++// per pass) and once everything has been initialized fgMainLoop from
++// then on.
++
++static void fgIdleFunction ( void ) {
++    // printf("idle state == %d\n", idle_state);
++
++    if ( idle_state == 0 ) {
++      // Initialize the splash screen right away
++      if ( current_options.get_splash_screen() ) {
++          fgSplashInit();
++      }
++      
++      idle_state++;
++    } else if ( idle_state == 1 ) {
++      // Start the intro music
++#if !defined(WIN32)
++      if ( current_options.get_intro_music() ) {
++          string lockfile = "/tmp/mpg123.running";
++          string mp3file = current_options.get_fg_root() +
++              "/Sounds/intro.mp3";
++          string command = "(touch " + lockfile + "; mpg123 " + mp3file +
++               "> /dev/null 2>&1; /bin/rm " + lockfile + ") &";
++          FG_LOG( FG_GENERAL, FG_INFO, 
++                  "Starting intro music: " << mp3file );
++          system ( command.c_str() );
++      }
++#endif
++
++      idle_state++;
++    } else if ( idle_state == 2 ) {
++      // These are a few miscellaneous things that aren't really
++      // "subsystems" but still need to be initialized.
++
++#ifdef USE_GLIDE
++      if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
++          grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
++      }
++#endif
++
++      idle_state++;
++    } else if ( idle_state == 3 ) {
++      // This is the top level init routine which calls all the
++      // other subsystem initialization routines.  If you are adding
++      // a subsystem to flight gear, its initialization call should
++      // located in this routine.
++      if( !fgInitSubsystems()) {
++          FG_LOG( FG_GENERAL, FG_ALERT,
++                  "Subsystem initializations failed ..." );
++          exit(-1);
++      }
++
++      idle_state++;
++    } else if ( idle_state == 4 ) {
++      // setup OpenGL view parameters
++      fgInitVisuals();
++
++      if ( use_signals ) {
++          // init timer routines, signals, etc.  Arrange for an alarm
++          // signal to be generated, etc.
++          fgInitTimeDepCalcs();
++      }
++
++      idle_state++;
++    } else if ( idle_state == 5 ) {
++
++      idle_state++;
++    } else if ( idle_state == 6 ) {
++      // Initialize audio support
++#ifdef ENABLE_AUDIO_SUPPORT
++
++#if !defined(WIN32)
++      if ( current_options.get_intro_music() ) {
++          // Let's wait for mpg123 to finish
++          string lockfile = "/tmp/mpg123.running";
++          struct stat stat_buf;
++
++          FG_LOG( FG_GENERAL, FG_INFO, 
++                  "Waiting for mpg123 player to finish ..." );
++          while ( stat(lockfile.c_str(), &stat_buf) == 0 ) {
++              // file exist, wait ...
++              sleep(1);
++              FG_LOG( FG_GENERAL, FG_INFO, ".");
++          }
++          FG_LOG( FG_GENERAL, FG_INFO, "");
++      }
++#endif // WIN32
++
++      audio_sched = new slScheduler ( 8000 );
++      audio_mixer = new smMixer;
++      audio_mixer -> setMasterVolume ( 80 ) ;  /* 80% of max volume. */
++      audio_sched -> setSafetyMargin ( 1.0 ) ;
++      string slfile = current_options.get_fg_root() + "/Sounds/wasp.wav";
++
++      s1 = new slSample ( (char *)slfile.c_str() );
++      FG_LOG( FG_GENERAL, FG_INFO,
++              "Rate = " << s1 -> getRate()
++              << "  Bps = " << s1 -> getBps()
++              << "  Stereo = " << s1 -> getStereo() );
++      audio_sched -> loopSample ( s1 );
++
++      if ( audio_sched->not_working() ) {
++          // skip
++      } else {
++          pitch_envelope.setStep  ( 0, 0.01, 0.6 );
++          volume_envelope.setStep ( 0, 0.01, 0.6 );
++
++          audio_sched -> addSampleEnvelope( s1, 0, 0, &
++                                            pitch_envelope,
++                                            SL_PITCH_ENVELOPE );
++          audio_sched -> addSampleEnvelope( s1, 0, 1, 
++                                            &volume_envelope,
++                                            SL_VOLUME_ENVELOPE );
++      }
++
++      // strcpy(slfile, path);
++      // strcat(slfile, "thunder.wav");
++      // s2 -> loadFile ( slfile );
++      // s2 -> adjustVolume(0.5);
++      // audio_sched -> playSample ( s2 );
++#endif
++
++      // sleep(1);
++      idle_state = 1000;
++    } 
++
++    if ( idle_state == 1000 ) {
++      // We've finished all our initialization steps, from now on we
++      // run the main loop.
++
++      fgMainLoop();
++    } else {
++      if ( current_options.get_splash_screen() == 1 ) {
++          fgSplashUpdate(0.0);
++      }
++    }
++}
++
++
++// Handle new window size or exposure
++static void fgReshape( int width, int height ) {
++    // 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() ) {
++          current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
++      } else {
++          current_view.set_win_ratio( (GLfloat) width / 
++                                      ((GLfloat) (height)*0.4232) );
++      }
++    }
++
++    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);
++    if ( idle_state == 1000 ) {
++      // yes we've finished all our initializations and are running
++      // the main loop, so this will now work without seg faulting
++      // the system.
++      current_view.UpdateViewParams();
++      if ( current_options.get_panel_status() ) {
++          FGPanel::OurPanel->ReInit(0, 0, 1024, 768);
++      }
++    }
++}
++
++
++// Initialize GLUT and define a main window
++int fgGlutInit( int *argc, char **argv ) {
++    // GLUT will extract all glut specific options so later on we only
++    // need wory about our own.
++    xglutInit(argc, argv);
++
++    // Define Display Parameters
++    xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
++
++    FG_LOG( FG_GENERAL, FG_INFO, "Opening a window: " <<
++          current_options.get_xsize() << "x" << current_options.get_ysize() );
++
++    // Define initial window size
++    xglutInitWindowSize( current_options.get_xsize(),
++                       current_options.get_ysize() );
++
++    // Initialize windows
++    if ( current_options.get_game_mode() == 0 ) {
++      // Open the regular window
++      xglutCreateWindow("Flight Gear");
++    } else {
++      // Open the cool new 'game mode' window
++      char game_mode_str[256];
++      sprintf( game_mode_str, "width=%d height=%d bpp=16",
++               current_options.get_xsize(),
++               current_options.get_ysize() );
++
++      FG_LOG( FG_GENERAL, FG_INFO, 
++              "game mode params = " << game_mode_str );
++      glutGameModeString( game_mode_str );
++      glutEnterGameMode();
++    }
++
++    // This seems to be the absolute earliest in the init sequence
++    // that these calls will return valid info.  Too bad it's after
++    // we've already created and sized out window. :-(
++    general.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
++    general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
++    general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
++
++    FG_LOG ( FG_GENERAL, FG_INFO, general.get_glRenderer() );
++
++#if 0
++    // try to determine if we should adjust the initial default
++    // display resolution.  The options class defaults (is
++    // initialized) to 640x480.
++    string renderer = general.glRenderer;
++
++    // currently we only know how to deal with Mesa/Glide/Voodoo cards
++    if ( renderer.find( "Glide" ) != string::npos ) {
++      FG_LOG( FG_GENERAL, FG_INFO, "Detected a Glide driver" );
++      if ( renderer.find( "FB/8" ) != string::npos ) {
++          // probably a voodoo-2
++          if ( renderer.find( "TMU/SLI" ) != string::npos ) {
++              // probably two SLI'd Voodoo-2's
++              current_options.set_xsize( 1024 );
++              current_options.set_ysize( 768 );
++              FG_LOG( FG_GENERAL, FG_INFO,
++                      "It looks like you have two sli'd voodoo-2's." << endl
++                      << "upgrading your win resolution to 1024 x 768" );
++              glutReshapeWindow(1024, 768);
++          } else {
++              // probably a single non-SLI'd Voodoo-2
++              current_options.set_xsize( 800 );
++              current_options.set_ysize( 600 );
++              FG_LOG( FG_GENERAL, FG_INFO,
++                      "It looks like you have a voodoo-2." << endl
++                      << "upgrading your win resolution to 800 x 600" );
++              glutReshapeWindow(800, 600);
++          }
++      } else if ( renderer.find( "FB/2" ) != string::npos ) {
++          // probably a voodoo-1, stick with the default
++      }
++    } else {
++      // we have no special knowledge of this card, stick with the default
++    }
++#endif
++
++    return(1);
++}
++
++
++// Initialize GLUT event handlers
++int fgGlutInitEvents( void ) {
++    // call fgReshape() on window resizes
++    xglutReshapeFunc( fgReshape );
++
++    // call GLUTkey() on keyboard event
++    xglutKeyboardFunc( GLUTkey );
++    glutSpecialFunc( GLUTspecialkey );
++
++    // call guiMouseFunc() whenever our little rodent is used
++    glutMouseFunc ( guiMouseFunc );
++    glutMotionFunc (guiMotionFunc );
++    glutPassiveMotionFunc (guiMotionFunc );
++
++    // call fgMainLoop() whenever there is
++    // nothing else to do
++    xglutIdleFunc( fgIdleFunction );
++
++    // draw the scene
++    xglutDisplayFunc( fgRenderFrame );
++
++    return(1);
++}
++
++
++// Main ...
++int main( int argc, char **argv ) {
++    FGInterface *f;
++
++    f = current_aircraft.fdm_state;
++
++#ifdef HAVE_BC5PLUS
++    _control87(MCW_EM, MCW_EM);  /* defined in float.h */
++#endif
++
++    // set default log levels
++    fglog().setLogLevels( FG_ALL, FG_INFO );
++
++    FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear:  Version " << VERSION << endl );
++
++    string root;
++
++    FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
++    FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
++
++    // seed the random number generater
++    fg_srandom();
++
++    // Attempt to locate and parse a config file
++    // First check fg_root
++    string config = current_options.get_fg_root() + "/system.fgfsrc";
++    current_options.parse_config_file( config );
++
++    // Next check home directory
++    char* envp = ::getenv( "HOME" );
++    if ( envp != NULL ) {
++      config = envp;
++      config += "/.fgfsrc";
++      current_options.parse_config_file( config );
++    }
++
++    // Parse remaining command line options
++    // These will override anything specified in a config file
++    if ( current_options.parse_command_line(argc, argv) !=
++                                    fgOPTIONS::FG_OPTIONS_OK )
++    {
++      // Something must have gone horribly wrong with the command
++      // line parsing or maybe the user just requested help ... :-)
++      current_options.usage();
++      FG_LOG( FG_GENERAL, FG_ALERT, "\nExiting ...");
++      exit(-1);
++    }
++    
++    // Initialize the Window/Graphics environment.
++    if( !fgGlutInit(&argc, argv) ) {
++      FG_LOG( FG_GENERAL, FG_ALERT, "GLUT initialization failed ..." );
++      exit(-1);
++    }
++
++    // Initialize the various GLUT Event Handlers.
++    if( !fgGlutInitEvents() ) {
++      FG_LOG( FG_GENERAL, FG_ALERT, 
++              "GLUT event handler initialization failed ..." );
++      exit(-1);
++    }
++
++    // First do some quick general initializations
++    if( !fgInitGeneral()) {
++      FG_LOG( FG_GENERAL, FG_ALERT, 
++              "General initializations failed ..." );
++      exit(-1);
++    }
++
++    // Init the user interface (we need to do this before passing off
++    // control to glut
++    guiInit();
++
++    // pass control off to the master GLUT event handler
++    glutMainLoop();
++
++    // we never actually get here ... but just in case ... :-)
++    return(0);
++}
++
++
++// $Log$
++// Revision 1.88  1999/04/03 04:21:02  curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.87  1999/03/08 21:56:37  curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.86  1999/02/26 22:09:47  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.85  1999/02/05 21:29:08  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.84  1999/02/02 20:13:34  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.83  1999/01/27 04:49:17  curt
++// Game mode fixes from Norman Vine.
++// Initial altitude setting tweaks and fixes (especially for when starting
++// below sea level.)
++//
++// 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.
++//
++// Revision 1.67  1998/11/16 13:59:58  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.66  1998/11/11 00:24:00  curt
++// Added Michael Johnson's audio patches for testing.
++// Also did a few tweaks to avoid numerical problems when starting at a place
++// with no (or bogus) scenery.
++//
++// Revision 1.65  1998/11/09 23:39:22  curt
++// Tweaks for the instrument panel.
++//
++// Revision 1.64  1998/11/07 19:07:09  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.63  1998/11/06 21:18:08  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.62  1998/10/27 02:14:35  curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.61  1998/10/25 14:08:47  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.60  1998/10/25 10:57:18  curt
++// Changes to use the new joystick library if it is available.
++//
++// Revision 1.59  1998/10/17 01:34:21  curt
++// C++ ifying ...
++//
++// Revision 1.58  1998/10/16 23:27:52  curt
++// C++-ifying.
++//
++// Revision 1.57  1998/10/16 00:54:00  curt
++// Converted to Point3D class.
++//
++// Revision 1.56  1998/10/02 12:46:47  curt
++// Added an "auto throttle"
++//
++// Revision 1.55  1998/09/29 14:58:18  curt
++// Use working() instead of !not_working() for audio.
++//
++// Revision 1.54  1998/09/29 02:03:38  curt
++// Autopilot mods.
++//
++// Revision 1.53  1998/09/26 13:18:35  curt
++// Check if audio "working()" before doing audio manipulations.
++//
++// Revision 1.52  1998/09/25 16:02:07  curt
++// Added support for pitch and volume envelopes and tied them to the
++// throttle setting.
++//
++// Revision 1.51  1998/09/15 04:27:28  curt
++// Changes for new Astro code.
++//
++// Revision 1.50  1998/09/15 02:09:24  curt
++// Include/fg_callback.hxx
++//   Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++//   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
++//   complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++//   Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++//   Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++//   Uses fg_gzifstream when loading config file.
++//
++// Revision 1.49  1998/09/09 16:25:39  curt
++// Only use GLUT_STENCIL if the instument panel has been requested.
++//
++// Revision 1.48  1998/08/28 18:15:03  curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.47  1998/08/27 17:02:04  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.46  1998/08/22  14:49:56  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.45  1998/08/20 20:32:31  curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.44  1998/08/20 15:10:33  curt
++// Added GameGLUT support.
++//
++// Revision 1.43  1998/08/12 21:01:47  curt
++// Master volume from 30% -> 80%
++//
++// Revision 1.42  1998/07/30 23:48:25  curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.41  1998/07/27 18:41:24  curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.40  1998/07/24 21:56:59  curt
++// Set near clip plane to 0.5 meters when close to the ground.  Also, let the view get a bit closer to the ground before hitting the hard limit.
++//
++// Revision 1.39  1998/07/24 21:39:08  curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.38  1998/07/22 21:40:43  curt
++// Clear to adjusted fog color (for sunrise/sunset effects)
++// Make call to fog sunrise/sunset adjustment method.
++// Add a stdc++ library bug work around to fg_init.cxx
++//
++// Revision 1.37  1998/07/20 12:49:44  curt
++// Tweaked color buffer clearing defaults.  We clear the color buffer if we
++// are doing textures.  Assumptions:  If we are doing textures we have hardware
++// support that can clear the color buffer for "free."  If we are doing software
++// rendering with textures, then the extra clear time gets lost in the noise.
++//
++// Revision 1.36  1998/07/16 17:33:35  curt
++// "H" / "h" now control hud brightness as well with off being one of the
++//   states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++//   whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.35  1998/07/13 21:01:36  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.34  1998/07/13 15:32:37  curt
++// Clear color buffer if drawing wireframe.
++// When specifying and airport, start elevation at -1000 and let the system
++// position you at ground level.
++//
++// Revision 1.33  1998/07/12 03:14:42  curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++//   and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++//   ground.
++// Did some serious horsing around getting the initial airplane position to be
++//   correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++//   dropping below the terrain, even when the flight model doesn't quite
++//   put you as high as you'd like.
++//
++// Revision 1.32  1998/07/08 14:45:07  curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++//   /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.31  1998/07/06 21:34:17  curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.30  1998/07/06 02:42:03  curt
++// Added support for switching between fullscreen and window mode for
++// Mesa/3dfx/glide.
++//
++// Added a basic splash screen.  Restructured the main loop and top level
++// initialization routines to do this.
++//
++// Hacked in some support for playing a startup mp3 sound file while rest
++// of sim initializes.  Currently only works in Unix using the mpg123 player.
++// Waits for the mpg123 player to finish before initializing internal
++// sound drivers.
++//
++// Revision 1.29  1998/07/04 00:52:22  curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.)  But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card.  This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.28  1998/06/27 16:54:32  curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.27  1998/06/17 21:35:10  curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.26  1998/06/13 00:40:32  curt
++// Tweaked fog command line options.
++//
++// Revision 1.25  1998/06/12 14:27:26  curt
++// Pui -> PUI, Gui -> GUI.
++//
++// Revision 1.24  1998/06/12 00:57:39  curt
++// Added support for Pui/Gui.
++// Converted fog to GL_FOG_EXP2.
++// Link to static simulator parts.
++// Update runfg.bat to try to be a little smarter.
++//
++// Revision 1.23  1998/06/08 17:57:04  curt
++// Minor sound/startup position tweaks.
++//
++// Revision 1.22  1998/06/05 18:18:40  curt
++// A bit of fiddling with audio ...
++//
++// Revision 1.21  1998/06/03 22:01:06  curt
++// Tweaking sound library usage.
++//
++// Revision 1.20  1998/06/03 00:47:11  curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.19  1998/06/01 17:54:40  curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.18  1998/05/29 20:37:19  curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.17  1998/05/22 21:28:52  curt
++// Modifications to use the new fgEVENT_MGR class.
++//
++// Revision 1.16  1998/05/20 20:51:33  curt
++// Tweaked smooth shaded texture lighting properties.
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.15  1998/05/16 13:08:34  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.14  1998/05/13 18:29:57  curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.13  1998/05/11 18:18:15  curt
++// For flat shading use "glHint (GL_FOG_HINT, GL_FASTEST )"
++//
++// Revision 1.12  1998/05/07 23:14:15  curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.11  1998/05/06 03:16:23  curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.10  1998/05/03 00:47:31  curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.9  1998/04/30 12:34:17  curt
++// Added command line rendering options:
++//   enable/disable fog/haze
++//   specify smooth/flat shading
++//   disable sky blending and just use a solid color
++//   enable wireframe drawing mode
++//
++// Revision 1.8  1998/04/28 01:20:21  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.7  1998/04/26 05:10:02  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.6  1998/04/25 22:06:30  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.5  1998/04/25 20:24:01  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.4  1998/04/24 14:19:30  curt
++// Fog tweaks.
++//
++// Revision 1.3  1998/04/24 00:49:18  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.2  1998/04/22 13:25:41  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.1  1998/04/21 17:02:39  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.71  1998/04/18 04:11:26  curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.70  1998/04/14 02:21:02  curt
++// Incorporated autopilot heading hold contributed by:  Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.69  1998/04/08 23:35:34  curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.68  1998/04/03 22:09:03  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.67  1998/03/23 21:24:37  curt
++// Source code formating tweaks.
++//
++// Revision 1.66  1998/03/14 00:31:20  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.65  1998/03/09 22:45:57  curt
++// Minor tweaks for building on sparc platform.
++//
++// Revision 1.64  1998/02/20 00:16:23  curt
++// Thursday's tweaks.
++//
++// Revision 1.63  1998/02/16 16:17:39  curt
++// Minor tweaks.
++//
++// Revision 1.62  1998/02/16 13:39:42  curt
++// Miscellaneous weekend tweaks.  Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.61  1998/02/12 21:59:46  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.60  1998/02/11 02:50:40  curt
++// Minor changes.
++//
++// Revision 1.59  1998/02/09 22:56:54  curt
++// Removed "depend" files from cvs control.  Other minor make tweaks.
++//
++// Revision 1.58  1998/02/09 15:07:49  curt
++// Minor tweaks.
++//
++// Revision 1.57  1998/02/07 15:29:40  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.56  1998/02/03 23:20:23  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.55  1998/02/02 20:53:58  curt
++// Incorporated Durk's changes.
++//
++// Revision 1.54  1998/01/31 00:43:10  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.53  1998/01/27 18:35:54  curt
++// Minor tweaks.
++//
++// Revision 1.52  1998/01/27 00:47:56  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.51  1998/01/26 15:57:05  curt
++// Tweaks for dynamic scenery development.
++//
++// Revision 1.50  1998/01/19 19:27:07  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.49  1998/01/19 18:40:31  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.48  1998/01/19 18:35:46  curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.47  1998/01/13 00:23:08  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.46  1998/01/08 02:22:06  curt
++// Beginning to integrate Tile management subsystem.
++//
++// Revision 1.45  1998/01/07 03:18:55  curt
++// Moved astronomical stuff from .../Src/Scenery to .../Src/Astro/
++//
++// Revision 1.44  1997/12/30 22:22:31  curt
++// Further integration of event manager.
++//
++// Revision 1.43  1997/12/30 20:47:43  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.42  1997/12/30 16:36:47  curt
++// Merged in Durk's changes ...
++//
++// Revision 1.41  1997/12/30 13:06:56  curt
++// A couple lighting tweaks ...
++//
++// Revision 1.40  1997/12/30 01:38:37  curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.39  1997/12/22 23:45:45  curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.38  1997/12/22 04:14:28  curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.37  1997/12/19 23:34:03  curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.36  1997/12/19 16:44:57  curt
++// Working on scene rendering order and options.
++//
++// Revision 1.35  1997/12/18 23:32:32  curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.34  1997/12/17 23:13:34  curt
++// Began working on rendering a sky.
++//
++// Revision 1.33  1997/12/15 23:54:45  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.32  1997/12/15 20:59:08  curt
++// Misc. tweaks.
++//
++// Revision 1.31  1997/12/12 21:41:25  curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.30  1997/12/12 19:52:47  curt
++// Working on lightling and material properties.
++//
++// Revision 1.29  1997/12/11 04:43:54  curt
++// Fixed sun vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.28  1997/12/10 22:37:45  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.27  1997/12/09 05:11:54  curt
++// Working on tweaking lighting.
++//
++// Revision 1.26  1997/12/09 04:25:29  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.25  1997/12/08 22:54:09  curt
++// Enabled GL_CULL_FACE.
++//
++// Revision 1.24  1997/11/25 19:25:32  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.23  1997/11/15 18:16:34  curt
++// minor tweaks.
++//
++// Revision 1.22  1997/10/30 12:38:41  curt
++// Working on new scenery subsystem.
++//
++// Revision 1.21  1997/09/23 00:29:38  curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.20  1997/09/22 14:44:19  curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.19  1997/09/18 16:20:08  curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.18  1997/09/16 22:14:51  curt
++// Tweaked time of day lighting equations.  Don't draw stars during the day.
++//
++// Revision 1.17  1997/09/16 15:50:29  curt
++// Working on star alignment and time issues.
++//
++// Revision 1.16  1997/09/13 02:00:06  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.15  1997/09/05 14:17:27  curt
++// More tweaking with stars.
++//
++// Revision 1.14  1997/09/05 01:35:53  curt
++// Working on getting stars right.
++//
++// Revision 1.13  1997/09/04 02:17:34  curt
++// Shufflin' stuff.
++//
++// Revision 1.12  1997/08/27 21:32:24  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.11  1997/08/27 03:30:16  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.10  1997/08/25 20:27:22  curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.9  1997/08/22 21:34:39  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.8  1997/08/19 23:55:03  curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.7  1997/08/16 12:22:38  curt
++// Working on improving the lighting/shading.
++//
++// Revision 1.6  1997/08/13 20:24:56  curt
++// Changes due to changing sunpos interface.
++//
++// Revision 1.5  1997/08/06 21:08:32  curt
++// Sun position now really* works (I think) ... I still have sun time warping
++// code in place, probably should remove it soon.
++//
++// Revision 1.4  1997/08/06 15:41:26  curt
++// Working on correct sun position.
++//
++// Revision 1.3  1997/08/06 00:24:22  curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.2  1997/08/04 20:25:15  curt
++// Organizational tweaking.
++//
++// Revision 1.1  1997/08/02 18:45:00  curt
++// Renamed GLmain.c GLUTmain.c
++//
++// Revision 1.43  1997/08/02 16:23:47  curt
++// Misc. tweaks.
++//
++// Revision 1.42  1997/08/01 19:43:33  curt
++// Making progress with coordinate system overhaul.
++//
++// Revision 1.41  1997/07/31 22:52:37  curt
++// Working on redoing internal coordinate systems & scenery transformations.
++//
++// Revision 1.40  1997/07/30 16:12:42  curt
++// Moved fg_random routines from Util/ to Math/
++//
++// Revision 1.39  1997/07/21 14:45:01  curt
++// Minor tweaks.
++//
++// Revision 1.38  1997/07/19 23:04:47  curt
++// Added an initial weather section.
++//
++// Revision 1.37  1997/07/19 22:34:02  curt
++// Moved PI definitions to ../constants.h
++// Moved random() stuff to ../Utils/ and renamed fg_random()
++//
++// Revision 1.36  1997/07/18 23:41:25  curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.35  1997/07/18 14:28:34  curt
++// Hacked in some support for wind/turbulence.
++//
++// Revision 1.34  1997/07/16 20:04:48  curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.33  1997/07/12 03:50:20  curt
++// Added an #include <Windows32/Base.h> to help compiling for Win32
++//
++// Revision 1.32  1997/07/11 03:23:18  curt
++// Solved some scenery display/orientation problems.  Still have a positioning
++// (or transformation?) problem.
++//
++// Revision 1.31  1997/07/11 01:29:58  curt
++// More tweaking of terrian floor.
++//
++// Revision 1.30  1997/07/10 04:26:37  curt
++// We now can interpolated ground elevation for any position in the grid.  We
++// can use this to enforce a "hard" ground.  We still need to enforce some
++// bounds checking so that we don't try to lookup data points outside the
++// grid data set.
++//
++// Revision 1.29  1997/07/09 21:31:12  curt
++// Working on making the ground "hard."
++//
++// Revision 1.28  1997/07/08 18:20:12  curt
++// Working on establishing a hard ground.
++//
++// Revision 1.27  1997/07/07 20:59:49  curt
++// Working on scenery transformations to enable us to fly fluidly over the
++// poles with no discontinuity/distortion in scenery.
++//
++// Revision 1.26  1997/07/05 20:43:34  curt
++// renamed mat3 directory to Math so we could add other math related routines.
++//
++// Revision 1.25  1997/06/29 21:19:17  curt
++// Working on scenery management system.
++//
++// Revision 1.24  1997/06/26 22:14:53  curt
++// Beginning work on a scenery management system.
++//
++// Revision 1.23  1997/06/26 19:08:33  curt
++// Restructuring make, adding automatic "make dep" support.
++//
++// Revision 1.22  1997/06/25 15:39:47  curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.21  1997/06/22 21:44:41  curt
++// Working on intergrating the VRML (subset) parser.
++//
++// Revision 1.20  1997/06/21 17:12:53  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.19  1997/06/18 04:10:31  curt
++// A couple more runway tweaks ...
++//
++// Revision 1.18  1997/06/18 02:21:24  curt
++// Hacked in a runway
++//
++// Revision 1.17  1997/06/17 16:51:58  curt
++// Timer interval stuff now uses gettimeofday() instead of ftime()
++//
++// Revision 1.16  1997/06/17 04:19:16  curt
++// More timer related tweaks with respect to view direction changes.
++//
++// Revision 1.15  1997/06/17 03:41:10  curt
++// Nonsignal based interval timing is now working.
++// This would be a good time to look at cleaning up the code structure a bit.
++//
++// Revision 1.14  1997/06/16 19:32:51  curt
++// Starting to add general timer support.
++//
++// Revision 1.13  1997/06/02 03:40:06  curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.12  1997/06/02 03:01:38  curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.11  1997/05/31 19:16:25  curt
++// Elevator trim added.
++//
++// Revision 1.10  1997/05/31 04:13:52  curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.9  1997/05/30 19:27:01  curt
++// The LaRCsim flight model is starting to look like it is working.
++//
++// Revision 1.8  1997/05/30 03:54:10  curt
++// Made a bit more progress towards integrating the LaRCsim flight model.
++//
++// Revision 1.7  1997/05/29 22:39:49  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.6  1997/05/29 12:31:39  curt
++// Minor tweaks, moving towards general flight model integration.
++//
++// Revision 1.5  1997/05/29 02:33:23  curt
++// Updated to reflect changing interfaces in other "modules."
++//
++// Revision 1.4  1997/05/27 17:44:31  curt
++// Renamed & rearranged variables and routines.   Added some initial simple
++// timer/alarm routines so the flight model can be updated on a regular 
++// interval.
++//
++// Revision 1.3  1997/05/23 15:40:25  curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.2  1997/05/23 00:35:12  curt
++// Trying to get fog to work ...
++//
++// Revision 1.1  1997/05/21 15:57:51  curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.3  1997/05/19 18:22:42  curt
++// Parameter tweaking ... starting to stub in fog support.
++//
++// Revision 1.2  1997/05/17 00:17:34  curt
++// Trying to stub in support for standard OpenGL.
++//
++// Revision 1.1  1997/05/16 16:05:52  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0ce458f7343d9eb185bb29b48ddbb55227d1dffa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,77 @@@
++if ENABLE_AUDIO_SUPPORT
++DEFS += -DENABLE_AUDIO_SUPPORT
++AUDIO_LIBS = -L$(top_builddir)/Lib/plib/src/sl -lsl -lsm
++endif
++
++if ENABLE_IRIX_AUDIO
++LIBS += -laudio
++endif
++
++if ENABLE_WIN32_AUDIO
++LIBS += -lwinmm
++endif
++
++if ENABLE_LINUX_JOYSTICK
++DEFS += -DENABLE_LINUX_JOYSTICK
++else
++DEFS += -DENABLE_GLUT_JOYSTICK
++endif
++
++if ENABLE_XMESA_FX
++DEFS += -DXMESA -DFX
++endif
++
++if ENABLE_UNIX_SERIAL
++SERIAL_LIBS = $(top_builddir)/Lib/Serial/libSerial.a
++else
++SERIAL_LIBS =
++endif
++
++EXTRA_DIST = runfgfs.in runfgfs.bat.in
++
++bin_PROGRAMS = fgfs
++
++bin_SCRIPTS = runfgfs runfgfs.bat
++
++fgfs_SOURCES = \
++      GLUTkey.cxx GLUTkey.hxx GLUTmain.cxx \
++      fg_config.h \
++      fg_init.cxx fg_init.hxx \
++      fg_serial.cxx fg_serial.hxx \
++      options.cxx options.hxx \
++      splash.cxx splash.hxx \
++      views.cxx views.hxx
++
++fgfs_LDADD = \
++      $(top_builddir)/Simulator/Aircraft/libAircraft.a \
++      $(top_builddir)/Simulator/Astro/libAstro.a \
++      $(top_builddir)/Simulator/Autopilot/libAutopilot.a \
++      $(top_builddir)/Simulator/Cockpit/libCockpit.a \
++      $(top_builddir)/Simulator/Controls/libControls.a \
++      $(top_builddir)/Simulator/FDM/libFlight.a \
++      $(top_builddir)/Simulator/FDM/External/libExternal.a \
++      $(top_builddir)/Simulator/FDM/JSBsim/libJSBsim.a \
++      $(top_builddir)/Simulator/FDM/LaRCsim/libLaRCsim.a \
++      $(top_builddir)/Simulator/FDM/Slew/libSlew.a \
++      $(top_builddir)/Simulator/GUI/libGUI.a \
++      $(top_builddir)/Simulator/Scenery/libScenery.a \
++      $(top_builddir)/Simulator/Airports/libAirports.a \
++      $(top_builddir)/Simulator/Objects/libObjects.a \
++      $(top_builddir)/Simulator/Time/libTime.a \
++      $(top_builddir)/Simulator/Weather/libWeather.a \
++      $(top_builddir)/Simulator/Joystick/libJoystick.a \
++      $(AUDIO_LIBS) \
++      $(SERIAL_LIBS) \
++      $(top_builddir)/Lib/Math/libMath.a \
++      $(top_builddir)/Lib/Bucket/libBucket.a \
++      $(top_builddir)/Lib/Debug/libDebug.a \
++      -L$(top_builddir)/Lib/plib/src/pui -lpu \
++      $(top_builddir)/Lib/zlib/libz.a \
++      $(top_builddir)/Lib/Misc/libMisc.a \
++      $(opengl_LIBS)
++
++INCLUDES += \
++      -I$(top_builddir) \
++      -I$(top_builddir)/Lib \
++      -I$(top_builddir)/Lib/plib/include \
++      -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c2267cf89ddaed425c3223206225cd6ac21bfd52
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,954 @@@
++//
++// fg_init.cxx -- Flight Gear top level initialization routines
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++
++// work around a stdc++ lib bug in some versions of linux, but doesn't
++// seem to hurt to have this here for all versions of Linux.
++#ifdef linux
++#  define _G_NO_EXTERN_TEMPLATES
++#endif
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Airports/simple.hxx>
++#include <Astro/sky.hxx>
++#include <Astro/stars.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Autopilot/autopilot.hxx>
++#include <Cockpit/cockpit.hxx>
++#include <Include/fg_constants.h>
++#include <Include/general.hxx>
++#include <Joystick/joystick.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Scenery/tilemgr.hxx>
++#include <Time/event.hxx>
++#include <Time/fg_time.hxx>
++#include <Time/light.hxx>
++#include <Time/sunpos.hxx>
++#include <Time/moonpos.hxx>
++#include <Weather/weather.hxx>
++
++#include "fg_init.hxx"
++#include "options.hxx"
++#include "views.hxx"
++#include "fg_serial.hxx"
++
++#if defined(FX) && defined(XMESA)
++#include <GL/xmesa.h>
++#endif
++
++FG_USING_STD(string);
++
++extern const char *default_root;
++
++
++// Set initial position and orientation
++int fgInitPosition( void ) {
++    string id;
++    FGInterface *f;
++
++    f = current_aircraft.fdm_state;
++
++    id = current_options.get_airport_id();
++    if ( id.length() ) {
++      // set initial position from airport id
++
++      fgAIRPORTS airports;
++      fgAIRPORT a;
++
++      FG_LOG( FG_GENERAL, FG_INFO,
++              "Attempting to set starting position from airport code "
++              << id );
++
++      airports.load("apt_simple");
++      if ( ! airports.search( id, &a ) ) {
++          FG_LOG( FG_GENERAL, FG_ALERT,
++                  "Failed to find " << id << " in database." );
++          exit(-1);
++      } else {
++          f->set_Longitude( a.longitude * DEG_TO_RAD );
++          f->set_Latitude( a.latitude * DEG_TO_RAD );
++      }
++    } else {
++      // set initial position from default or command line coordinates
++
++      f->set_Longitude( current_options.get_lon() * DEG_TO_RAD );
++      f->set_Latitude( current_options.get_lat() * DEG_TO_RAD );
++    }
++
++    f->set_sin_cos_longitude(current_options.get_lon() * DEG_TO_RAD);
++    f->set_sin_cos_latitude(current_options.get_lat() * DEG_TO_RAD);
++
++    FG_LOG( FG_GENERAL, FG_INFO,
++          "starting altitude is = " << current_options.get_altitude() );
++
++    f->set_Altitude( current_options.get_altitude() * METER_TO_FEET );
++    fgFDMSetGroundElevation( current_options.get_flight_model(),
++                           (f->get_Altitude() - 3.758099) * FEET_TO_METER );
++
++    FG_LOG( FG_GENERAL, FG_INFO,
++          "Initial position is: ("
++          << (f->get_Longitude() * RAD_TO_DEG) << ", "
++          << (f->get_Latitude() * RAD_TO_DEG) << ", "
++          << (f->get_Altitude() * FEET_TO_METER) << ")" );
++
++    return(1);
++}
++
++
++// General house keeping initializations
++int fgInitGeneral( void ) {
++    string root;
++    char *mesa_win_state;
++
++    FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
++    FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
++
++    root = current_options.get_fg_root();
++    if ( ! root.length() ) {
++      // No root path set? Then bail ...
++      FG_LOG( FG_GENERAL, FG_ALERT,
++              "Cannot continue without environment variable FG_ROOT"
++              << "being defined." );
++      exit(-1);
++    }
++    FG_LOG( FG_GENERAL, FG_INFO, "FG_ROOT = " << root << endl );
++
++#if defined(FX) && defined(XMESA)
++    // initialize full screen flag
++    global_fullscreen = false;
++    if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
++      // Test for the MESA_GLX_FX env variable
++      if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
++          // test if we are fullscreen mesa/glide
++          if ( (mesa_win_state[0] == 'f') ||
++               (mesa_win_state[0] == 'F') ) {
++              global_fullscreen = true;
++          }
++      }
++    }
++#endif
++
++    return ( 1 );
++}
++
++
++// This is the top level init routine which calls all the other
++// initialization routines.  If you are adding a subsystem to flight
++// gear, its initialization call should located in this routine.
++// Returns non-zero if a problem encountered.
++int fgInitSubsystems( void )
++{
++    FGInterface *f; // assigned later
++    fgLIGHT *l = &cur_light_params;
++    fgTIME *t = &cur_time_params;
++    FGView *v = &current_view;
++
++    FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
++    FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
++
++    // allocates structures so must happen before any of the flight
++    // model or control parameters are set
++    fgAircraftInit();   // In the future this might not be the case.
++    f = current_aircraft.fdm_state;
++
++    // set the initial position
++    fgInitPosition();
++
++    // Initialize the Scenery Management subsystem
++    if ( fgSceneryInit() ) {
++      // Scenery initialized ok.
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
++      exit(-1);
++    }
++
++    if( fgTileMgrInit() ) {
++      // Load the local scenery data
++      fgTileMgrUpdate();
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
++      exit(-1);
++    }
++
++    FG_LOG( FG_GENERAL, FG_DEBUG,
++          "Current terrain elevation after tile mgr init " <<
++          scenery.cur_elev );
++
++    // Calculate ground elevation at starting point (we didn't have
++    // tmp_abs_view_pos calculated when fgTileMgrUpdate() was called above
++    //
++    // calculalate a cartesian point somewhere along the line between
++    // the center of the earth and our view position.  Doesn't have to
++    // be the exact elevation (this is good because we don't know it
++    // yet :-)
++
++    // now handled inside of the fgTileMgrUpdate()
++
++    /*
++    geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
++    tmp_abs_view_pos = fgGeodToCart(geod_pos);
++
++    FG_LOG( FG_GENERAL, FG_DEBUG,
++          "Initial abs_view_pos = " << tmp_abs_view_pos );
++    scenery.cur_elev =
++      fgTileMgrCurElev( f->get_Longitude(), f->get_Latitude(),
++                        tmp_abs_view_pos );
++    FG_LOG( FG_GENERAL, FG_DEBUG,
++          "Altitude after update " << scenery.cur_elev );
++    */
++
++    fgFDMSetGroundElevation( current_options.get_flight_model(),
++                           scenery.cur_elev );
++
++    // Reset our altitude if we are below ground
++    FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << f->get_Altitude() );
++    FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
++          f->get_Runway_altitude() );
++
++    if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
++      f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
++    }
++
++    FG_LOG( FG_GENERAL, FG_INFO,
++          "Updated position (after elevation adj): ("
++          << (f->get_Latitude() * RAD_TO_DEG) << ", "
++          << (f->get_Longitude() * RAD_TO_DEG) << ", "
++          << (f->get_Altitude() * FEET_TO_METER) << ")" );
++
++    // We need to calculate a few more values here that would normally
++    // be calculated by the FDM so that the v->UpdateViewMath()
++    // routine doesn't get hosed.
++
++    double sea_level_radius_meters;
++    double lat_geoc;
++    // Set the FG variables first
++    fgGeodToGeoc( f->get_Latitude(), f->get_Altitude(),
++                &sea_level_radius_meters, &lat_geoc);
++    f->set_Geocentric_Position( lat_geoc, f->get_Longitude(),
++                              f->get_Altitude() +
++                              (sea_level_radius_meters * METER_TO_FEET) );
++    f->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
++
++    // The following section sets up the flight model EOM parameters
++    // and should really be read in from one or more files.
++
++    // Initial Velocity
++    f->set_Velocities_Local( 0.0, 0.0, 0.0 );
++
++    // Initial Orientation
++    f->set_Euler_Angles( current_options.get_roll() * DEG_TO_RAD,
++                       current_options.get_pitch() * DEG_TO_RAD,
++                       current_options.get_heading() * DEG_TO_RAD );
++
++    // Initial Angular Body rates
++    f->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
++
++    f->set_Earth_position_angle( 0.0 );
++
++    // Mass properties and geometry values
++    f->set_Inertias( 8.547270E+01,
++                   1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
++
++    // CG position w.r.t. ref. point
++    f->set_CG_Position( 0.0, 0.0, 0.0 );
++
++    // Initialize the event manager
++    global_events.Init();
++
++    // Output event stats every 60 seconds
++    global_events.Register( "fgEVENT_MGR::PrintStats()",
++                          fgMethodCallback<fgEVENT_MGR>( &global_events,
++                                                 &fgEVENT_MGR::PrintStats),
++                          fgEVENT::FG_EVENT_READY, 60000 );
++
++    // Initialize the time dependent variables
++    fgTimeInit(t);
++    fgTimeUpdate(f, t);
++
++    // Initialize view parameters
++    FG_LOG( FG_GENERAL, FG_DEBUG, "Before v->init()");
++    v->Init();
++    FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
++    v->UpdateViewMath(f);
++    FG_LOG( FG_GENERAL, FG_DEBUG, "  abs_view_pos = " << v->get_abs_view_pos());
++    v->UpdateWorldToEye(f);
++
++    // Build the solar system
++    //fgSolarSystemInit(*t);
++    FG_LOG(FG_GENERAL, FG_INFO, "Building SolarSystem");
++    SolarSystem::theSolarSystem = new SolarSystem(t);
++
++    // Initialize the Stars subsystem
++    if( fgStarsInit() ) {
++      // Stars initialized ok.
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error in Stars initialization!" );
++      exit(-1);
++    }
++
++    // Initialize the planetary subsystem
++    // global_events.Register( "fgPlanetsInit()", fgPlanetsInit,
++    //                            fgEVENT::FG_EVENT_READY, 600000);
++
++    // Initialize the sun's position
++    // global_events.Register( "fgSunInit()", fgSunInit,
++    //                            fgEVENT::FG_EVENT_READY, 30000 );
++
++    // Intialize the moon's position
++    // global_events.Register( "fgMoonInit()", fgMoonInit,
++    //                            fgEVENT::FG_EVENT_READY, 600000 );
++
++    // register the periodic update of Sun, moon, and planets
++    global_events.Register( "ssolsysUpdate", solarSystemRebuild,
++                          fgEVENT::FG_EVENT_READY, 600000);
++
++    // fgUpdateSunPos() needs a few position and view parameters set
++    // so it can calculate local relative sun angle and a few other
++    // things for correctly orienting the sky.
++    fgUpdateSunPos();
++    fgUpdateMoonPos();
++    global_events.Register( "fgUpdateSunPos()", fgUpdateSunPos,
++                          fgEVENT::FG_EVENT_READY, 60000);
++    global_events.Register( "fgUpdateMoonPos()", fgUpdateMoonPos,
++                          fgEVENT::FG_EVENT_READY, 60000);
++
++    // Initialize Lighting interpolation tables
++    l->Init();
++
++    // update the lighting parameters (based on sun angle)
++    global_events.Register( "fgLight::Update()",
++                          fgMethodCallback<fgLIGHT>( &cur_light_params,
++                                                     &fgLIGHT::Update),
++                          fgEVENT::FG_EVENT_READY, 30000 );
++
++    // Initialize the weather modeling subsystem
++    current_weather.Init();
++
++    // Initialize the Cockpit subsystem
++    if( fgCockpitInit( &current_aircraft )) {
++      // Cockpit initialized ok.
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error in Cockpit initialization!" );
++      exit(-1);
++    }
++
++    // Initialize the "sky"
++    fgSkyInit();
++
++    // Initialize the flight model subsystem data structures base on
++    // above values
++
++    fgFDMInit( current_options.get_flight_model(), cur_fdm_state,
++                     1.0 / DEFAULT_MODEL_HZ );
++
++    // I'm just sticking this here for now, it should probably move
++    // eventually
++    scenery.cur_elev = f->get_Runway_altitude() * FEET_TO_METER;
++
++    if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
++      f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
++    }
++
++    FG_LOG( FG_GENERAL, FG_INFO,
++          "Updated position (after elevation adj): ("
++          << (f->get_Latitude() * RAD_TO_DEG) << ", "
++          << (f->get_Longitude() * RAD_TO_DEG) << ", "
++          << (f->get_Altitude() * FEET_TO_METER) << ")" );
++    // end of thing that I just stuck in that I should probably move
++
++    // Joystick support
++    if ( fgJoystickInit() ) {
++      // Joystick initialized ok.
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" );
++    }
++
++    // Autopilot init added here, by Jeff Goeke-Smith
++    fgAPInit(&current_aircraft);
++
++    // Initialize serial ports
++    fgSerialInit();
++
++    FG_LOG( FG_GENERAL, FG_INFO, endl);
++
++    return(1);
++}
++
++
++// $Log$
++// Revision 1.72  1999/04/05 02:13:58  curt
++// Minor patch from Norman Vine.
++//
++// Revision 1.71  1999/03/22 02:08:13  curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++//   some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++//   me earlier.
++//
++// Revision 1.70  1999/03/11 23:09:49  curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url.  Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.69  1999/03/08 21:56:39  curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.68  1999/03/02 01:03:15  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.67  1999/02/26 22:09:48  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.66  1999/02/05 21:29:10  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.65  1999/02/02 20:13:36  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.64  1999/02/01 21:15:43  curt
++// Removed unused variables.
++//
++// Revision 1.63  1999/01/27 04:49:19  curt
++// Game mode fixes from Norman Vine.
++// Initial altitude setting tweaks and fixes (especially for when starting
++// below sea level.)
++//
++// Revision 1.62  1999/01/20 13:42:25  curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.61  1999/01/08 03:23:57  curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.60  1999/01/07 20:25:09  curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.59  1998/12/18 23:40:57  curt
++// New frame rate counting mechanism.
++//
++// Revision 1.58  1998/12/09 18:50:25  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.57  1998/12/06 14:52:56  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.56  1998/12/06 13:51:23  curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.55  1998/12/05 15:54:20  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.54  1998/12/05 14:19:53  curt
++// Looking into a problem with cur_view_params.abs_view_pos initialization.
++//
++// Revision 1.53  1998/12/03 04:25:05  curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.52  1998/12/03 01:17:17  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.51  1998/11/20 01:02:37  curt
++// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
++//
++// Revision 1.50  1998/11/16 14:00:01  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.49  1998/11/11 00:24:02  curt
++// Added Michael Johnson's audio patches for testing.
++// Also did a few tweaks to avoid numerical problems when starting at a place
++// with no (or bogus) scenery.
++//
++// Revision 1.48  1998/11/07 19:07:10  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.47  1998/11/06 21:18:10  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.46  1998/10/27 02:14:38  curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.45  1998/10/25 10:57:21  curt
++// Changes to use the new joystick library if it is available.
++//
++// Revision 1.44  1998/10/18 01:17:17  curt
++// Point3D tweaks.
++//
++// Revision 1.43  1998/10/17 01:34:22  curt
++// C++ ifying ...
++//
++// Revision 1.42  1998/10/16 23:27:54  curt
++// C++-ifying.
++//
++// Revision 1.41  1998/10/16 00:54:01  curt
++// Converted to Point3D class.
++//
++// Revision 1.40  1998/10/02 12:46:49  curt
++// Added an "auto throttle"
++//
++// Revision 1.39  1998/09/29 02:03:39  curt
++// Autopilot mods.
++//
++// Revision 1.38  1998/09/15 04:27:30  curt
++// Changes for new Astro code.
++//
++// Revision 1.37  1998/09/15 02:09:26  curt
++// Include/fg_callback.hxx
++//   Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++//   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
++//   complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++//   Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++//   Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++//   Uses fg_gzifstream when loading config file.
++//
++// Revision 1.36  1998/09/08 21:40:08  curt
++// Fixes by Charlie Hotchkiss.
++//
++// Revision 1.35  1998/08/29 13:09:26  curt
++// Changes to event manager from Bernie Bright.
++//
++// Revision 1.34  1998/08/27 17:02:06  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.33  1998/08/25 20:53:32  curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.32  1998/08/25 16:59:09  curt
++// Directory reshuffling.
++//
++// Revision 1.31  1998/08/22  14:49:57  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.30  1998/08/20 20:32:33  curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.29  1998/07/30 23:48:27  curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.28  1998/07/27 18:41:25  curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.27  1998/07/24 21:39:10  curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.26  1998/07/22 21:40:44  curt
++// Clear to adjusted fog color (for sunrise/sunset effects)
++// Make call to fog sunrise/sunset adjustment method.
++// Add a stdc++ library bug work around to fg_init.cxx
++//
++// Revision 1.25  1998/07/13 21:01:38  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.24  1998/07/13 15:32:39  curt
++// Clear color buffer if drawing wireframe.
++// When specifying and airport, start elevation at -1000 and let the system
++// position you at ground level.
++//
++// Revision 1.23  1998/07/12 03:14:43  curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++//   and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++//   ground.
++// Did some serious horsing around getting the initial airplane position to be
++//   correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++//   dropping below the terrain, even when the flight model doesn't quite
++//   put you as high as you'd like.
++//
++// Revision 1.22  1998/07/04 00:52:25  curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.)  But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card.  This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.21  1998/06/27 16:54:33  curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.20  1998/06/17 21:35:12  curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.19  1998/06/08 17:57:05  curt
++// Minor sound/startup position tweaks.
++//
++// Revision 1.18  1998/06/03 00:47:14  curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.17  1998/06/01 17:54:42  curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.16  1998/05/29 20:37:24  curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.15  1998/05/22 21:28:53  curt
++// Modifications to use the new fgEVENT_MGR class.
++//
++// Revision 1.14  1998/05/20 20:51:35  curt
++// Tweaked smooth shaded texture lighting properties.
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.13  1998/05/16 13:08:35  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.12  1998/05/13 18:29:58  curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.11  1998/05/07 23:14:15  curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.10  1998/05/06 03:16:24  curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.9  1998/05/03 00:47:31  curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.8  1998/04/30 12:34:18  curt
++// Added command line rendering options:
++//   enable/disable fog/haze
++//   specify smooth/flat shading
++//   disable sky blending and just use a solid color
++//   enable wireframe drawing mode
++//
++// Revision 1.7  1998/04/28 01:20:22  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.6  1998/04/26 05:10:03  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.5  1998/04/25 22:06:30  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.4  1998/04/25 20:24:01  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.3  1998/04/25 15:11:11  curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.2  1998/04/24 00:49:20  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1  1998/04/22 13:25:44  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.56  1998/04/18 04:11:28  curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.55  1998/04/14 02:21:03  curt
++// Incorporated autopilot heading hold contributed by:  Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.54  1998/04/08 23:35:36  curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.53  1998/04/03 22:09:06  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.52  1998/03/23 21:24:38  curt
++// Source code formating tweaks.
++//
++// Revision 1.51  1998/03/14 00:31:22  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.50  1998/03/09 22:46:19  curt
++// Minor tweaks.
++//
++// Revision 1.49  1998/02/23 19:07:59  curt
++// Incorporated Durk's Astro/ tweaks.  Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.48  1998/02/21 14:53:15  curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.47  1998/02/19 13:05:53  curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.46  1998/02/18 15:07:06  curt
++// Tweaks to build with SGI OpenGL (and therefor hopefully other accelerated
++// drivers will work.)
++//
++// Revision 1.45  1998/02/16 13:39:43  curt
++// Miscellaneous weekend tweaks.  Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.44  1998/02/12 21:59:50  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.43  1998/02/11 02:50:40  curt
++// Minor changes.
++//
++// Revision 1.42  1998/02/09 22:56:58  curt
++// Removed "depend" files from cvs control.  Other minor make tweaks.
++//
++// Revision 1.41  1998/02/09 15:07:50  curt
++// Minor tweaks.
++//
++// Revision 1.40  1998/02/07 15:29:44  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.39  1998/02/03 23:20:25  curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf().  Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.38  1998/02/02 20:53:58  curt
++// Incorporated Durk's changes.
++//
++// Revision 1.37  1998/02/01 03:39:54  curt
++// Minor tweaks.
++//
++// Revision 1.36  1998/01/31 00:43:13  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.35  1998/01/27 00:47:57  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.34  1998/01/22 02:59:37  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.33  1998/01/21 21:11:34  curt
++// Misc. tweaks.
++//
++// Revision 1.32  1998/01/19 19:27:08  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.31  1998/01/19 18:40:32  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.30  1998/01/13 00:23:09  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.29  1998/01/08 02:22:08  curt
++// Beginning to integrate Tile management subsystem.
++//
++// Revision 1.28  1998/01/07 03:18:58  curt
++// Moved astronomical stuff from .../Src/Scenery to .../Src/Astro/
++//
++// Revision 1.27  1998/01/05 18:44:35  curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.26  1997/12/30 23:09:04  curt
++// Tweaking initialization sequences.
++//
++// Revision 1.25  1997/12/30 22:22:33  curt
++// Further integration of event manager.
++//
++// Revision 1.24  1997/12/30 20:47:44  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.23  1997/12/30 16:36:50  curt
++// Merged in Durk's changes ...
++//
++// Revision 1.22  1997/12/19 23:34:05  curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.21  1997/12/19 16:45:00  curt
++// Working on scene rendering order and options.
++//
++// Revision 1.20  1997/12/18 23:32:33  curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.19  1997/12/17 23:13:36  curt
++// Began working on rendering a sky.
++//
++// Revision 1.18  1997/12/15 23:54:49  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.17  1997/12/15 20:59:09  curt
++// Misc. tweaks.
++//
++// Revision 1.16  1997/12/12 19:52:48  curt
++// Working on lightling and material properties.
++//
++// Revision 1.15  1997/12/11 04:43:55  curt
++// Fixed sun vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.14  1997/12/10 22:37:47  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.13  1997/11/25 19:25:32  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.12  1997/11/15 18:16:35  curt
++// minor tweaks.
++//
++// Revision 1.11  1997/10/30 12:38:42  curt
++// Working on new scenery subsystem.
++//
++// Revision 1.10  1997/10/25 03:24:23  curt
++// Incorporated sun, moon, and star positioning code contributed by Durk Talsma.
++//
++// Revision 1.9  1997/09/23 00:29:39  curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.8  1997/09/22 14:44:20  curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.7  1997/09/16 15:50:30  curt
++// Working on star alignment and time issues.
++//
++// Revision 1.6  1997/09/05 14:17:30  curt
++// More tweaking with stars.
++//
++// Revision 1.5  1997/09/04 02:17:36  curt
++// Shufflin' stuff.
++//
++// Revision 1.4  1997/08/27 21:32:26  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.3  1997/08/27 03:30:19  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2  1997/08/25 20:27:23  curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.1  1997/08/23 01:46:20  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..503050ed8f8737ef1c6931faeb20f67bc1541381
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,68 @@@
++//
++// fg_init.hxx -- Flight Gear top level initialization routines
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_INIT_HXX
++#define _FG_INIT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// General house keeping initializations
++int fgInitGeneral ( void );
++
++
++// This is the top level init routine which calls all the other
++// initialization routines.  If you are adding a subsystem to flight
++// gear, its initialization call should located in this routine.
++int fgInitSubsystems( void );
++
++
++#endif // _FG_INIT_H
++
++
++// $Log$
++// Revision 1.2  1998/04/25 15:11:12  curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1  1998/04/22 13:25:44  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.4  1998/04/21 17:02:41  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.3  1998/02/12 21:59:50  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.2  1998/01/22 02:59:38  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.1  1997/08/23 01:46:20  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d0853074cae75054108c405861f653e688837d7f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,510 @@@
++// fg_serial.cxx -- higher level serial port management routines
++//
++// Written by Curtis Olson, started November 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cstdlib>    // atoi()
++#else
++#  include <stdlib.h>   // atoi()
++#endif
++
++#include STL_STRING
++#include STL_IOSTREAM                                           
++#include <vector>                                                               
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Serial/serial.hxx>
++#include <Time/fg_time.hxx>
++
++#include "options.hxx"
++
++#include "fg_serial.hxx"
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++// support an arbitrary number of serial channels.  Each channel can
++// be assigned to an arbitrary port.  Bi-directional communication is
++// supported by the underlying layer, but probably will never be
++// needed by FGFS?
++
++typedef vector < fgIOCHANNEL > io_container;
++typedef io_container::iterator io_iterator;
++typedef io_container::const_iterator const_io_iterator;
++
++// define the four channels
++io_container port_list;
++
++
++fgIOCHANNEL::fgIOCHANNEL() :
++    kind( FG_SERIAL_DISABLED ),
++    valid_config( false )
++{
++}
++
++
++fgIOCHANNEL::~fgIOCHANNEL() {
++}
++
++
++// configure a port based on the config string
++static fgIOCHANNEL parse_port_config( const string& config )
++{
++    fgIOCHANNEL p;
++
++    string::size_type begin, end;
++
++    begin = 0;
++
++    FG_LOG( FG_SERIAL, FG_INFO, "Parse serial port config: " << config );
++
++    // device name
++    end = config.find(",", begin);
++    if ( end == string::npos ) {
++      return p;
++    }
++    
++    p.device = config.substr(begin, end - begin);
++    begin = end + 1;
++    FG_LOG( FG_SERIAL, FG_INFO, "  device = " << p.device );
++
++    // format
++    end = config.find(",", begin);
++    if ( end == string::npos ) {
++      return p;
++    }
++    
++    p.format = config.substr(begin, end - begin);
++    begin = end + 1;
++    FG_LOG( FG_SERIAL, FG_INFO, "  format = " << p.format );
++
++    // baud
++    end = config.find(",", begin);
++    if ( end == string::npos ) {
++      return p;
++    }
++    
++    p.baud = config.substr(begin, end - begin);
++    begin = end + 1;
++    FG_LOG( FG_SERIAL, FG_INFO, "  baud = " << p.baud );
++
++    // direction
++    p.direction = config.substr(begin);
++    FG_LOG( FG_SERIAL, FG_INFO, "  direction = " << p.direction );
++
++    p.valid_config = true;
++
++    return p;
++}
++
++
++// configure a port based on the config info
++static bool config_port( fgIOCHANNEL &p )
++{
++    if ( p.port.is_enabled() ) {
++      FG_LOG( FG_SERIAL, FG_ALERT, "This shouldn't happen, but the port " 
++              << "is already in use, ignoring" );
++      return false;
++    }
++
++    if ( ! p.port.open_port( p.device ) ) {
++      FG_LOG( FG_SERIAL, FG_ALERT, "Error opening device: " << p.device );
++      return false;
++    }
++
++    // cout << "fd = " << p.port.fd << endl;
++
++    if ( ! p.port.set_baud( atoi( p.baud.c_str() ) ) ) {
++      FG_LOG( FG_SERIAL, FG_ALERT, "Error setting baud: " << p.baud );
++      return false;
++    }
++
++    if ( p.format == "nmea" ) {
++      if ( p.direction == "out" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_OUT;
++      } else if ( p.direction == "in" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_IN;
++      } else {
++          FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++          return false;
++      }
++    } else if ( p.format == "garmin" ) {
++      if ( p.direction == "out" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_GARMIN_OUT;
++      } else if ( p.direction == "in" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_GARMIN_IN;
++      } else {
++          FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++          return false;
++      }
++    } else if ( p.format == "fgfs" ) {
++      if ( p.direction == "out" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_OUT;
++      } else if ( p.direction == "in" ) {
++          p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_IN;
++      } else {
++          FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++          return false;
++      }
++    } else {
++      FG_LOG( FG_SERIAL, FG_ALERT, "Unknown format" );
++      return false;
++    }
++
++    return true;
++}
++
++
++// step through the port config streams (from fgOPTIONS) and setup
++// serial port channels for each
++void fgSerialInit() {
++    fgIOCHANNEL port;
++    bool result;
++    str_container port_options_list = current_options.get_port_options_list();
++
++    // we could almost do this in a single step except pushing a valid
++    // port onto the port list copies the structure and destroys the
++    // original, which closes the port and frees up the fd ... doh!!!
++
++    // parse the configuration strings and store the results in stub
++    // fgIOCHANNEL structures
++    const_str_iterator current_str = port_options_list.begin();
++    const_str_iterator last_str = port_options_list.end();
++    for ( ; current_str != last_str; ++current_str ) {
++      port = parse_port_config( *current_str );
++      if ( port.valid_config ) {
++          result = config_port( port );
++          if ( result ) {
++              port_list.push_back( port );
++          }
++      }
++    }
++}
++
++
++char calc_nmea_cksum(char *sentence) {
++    unsigned char sum = 0;
++    int i, len;
++
++    // printf("%s\n", sentence);
++
++    len = strlen(sentence);
++    sum = sentence[0];
++    for ( i = 1; i < len; i++ ) {
++        // printf("%c", sentence[i]);
++        sum ^= sentence[i];
++    }
++    // printf("\n");
++
++    // printf("sum = %02x\n", sum);
++    return sum;
++}
++
++
++static void send_nmea_out( fgIOCHANNEL *p ) {
++    char rmc[256], gga[256];
++    char rmc_sum[10], gga_sum[10];
++    char dir;
++    int deg;
++    double min;
++    FGInterface *f;
++    fgTIME *t;
++
++    // run once every two seconds
++    if ( p->last_time == cur_time_params.cur_time ) {
++      return;
++    }
++    p->last_time = cur_time_params.cur_time;
++    if ( cur_time_params.cur_time % 2 != 0 ) {
++      return;
++    }
++
++    f = current_aircraft.fdm_state;
++    t = &cur_time_params;
++
++    char utc[10];
++    sprintf( utc, "%02d%02d%02d", 
++           t->gmt->tm_hour, t->gmt->tm_min, t->gmt->tm_sec );
++
++    char lat[20];
++    double latd = f->get_Latitude() * RAD_TO_DEG;
++    if ( latd < 0.0 ) {
++      latd *= -1.0;
++      dir = 'S';
++    } else {
++      dir = 'N';
++    }
++    deg = (int)(latd);
++    min = (latd - (double)deg) * 60.0;
++    sprintf( lat, "%02d%06.3f,%c", abs(deg), min, dir);
++
++    char lon[20];
++    double lond = f->get_Longitude() * RAD_TO_DEG;
++    if ( lond < 0.0 ) {
++      lond *= -1.0;
++      dir = 'W';
++    } else {
++      dir = 'E';
++    }
++    deg = (int)(lond);
++    min = (lond - (double)deg) * 60.0;
++    sprintf( lon, "%03d%06.3f,%c", abs(deg), min, dir);
++
++    char speed[10];
++    sprintf( speed, "%05.1f", f->get_V_equiv_kts() );
++
++    char heading[10];
++    sprintf( heading, "%05.1f", f->get_Psi() * RAD_TO_DEG );
++
++    char altitude_m[10];
++    sprintf( altitude_m, "%02d", (int)(f->get_Altitude() * FEET_TO_METER) );
++
++    char altitude_ft[10];
++    sprintf( altitude_ft, "%02d", (int)f->get_Altitude() );
++
++    char date[10];
++    sprintf( date, "%02d%02d%02d", 
++           t->gmt->tm_mday, t->gmt->tm_mon+1, t->gmt->tm_year );
++
++    // $GPRMC,HHMMSS,A,DDMM.MMM,N,DDDMM.MMM,W,XXX.X,XXX.X,DDMMYY,XXX.X,E*XX
++    sprintf( rmc, "GPRMC,%s,A,%s,%s,%s,%s,%s,0.000,E",
++           utc, lat, lon, speed, heading, date );
++    sprintf( rmc_sum, "%02X", calc_nmea_cksum(rmc) );
++
++    sprintf( gga, "GPGGA,%s,%s,%s,1,,,%s,F,,,,",
++           utc, lat, lon, altitude_ft );
++    sprintf( gga_sum, "%02X", calc_nmea_cksum(gga) );
++
++
++    FG_LOG( FG_SERIAL, FG_DEBUG, rmc );
++    FG_LOG( FG_SERIAL, FG_DEBUG, gga );
++
++    // RMC sentence
++    string rmc_sentence = "$";
++    rmc_sentence += rmc;
++    rmc_sentence += "*";
++    rmc_sentence += rmc_sum;
++    rmc_sentence += "\n";
++    p->port.write_port(rmc_sentence);
++    // cout << rmc_sentence;
++
++    // GGA sentence
++    string gga_sentence = "$";
++    gga_sentence += gga;
++    gga_sentence += "*";
++    gga_sentence += gga_sum;
++    gga_sentence += "\n";
++    p->port.write_port(gga_sentence);
++    // cout << gga_sentence;
++}
++
++static void read_nmea_in( fgIOCHANNEL *p ) {
++}
++
++static void send_garmin_out( fgIOCHANNEL *p ) {
++    char rmc[256], rmc_sum[256], rmz[256], rmz_sum[256];
++    char dir;
++    int deg;
++    double min;
++    FGInterface *f;
++    fgTIME *t;
++
++    // run once per second
++    if ( p->last_time == cur_time_params.cur_time ) {
++      return;
++    }
++    p->last_time = cur_time_params.cur_time;
++    if ( cur_time_params.cur_time % 2 != 0 ) {
++      return;
++    }
++    
++    f = current_aircraft.fdm_state;
++    t = &cur_time_params;
++
++    char utc[10];
++    sprintf( utc, "%02d%02d%02d", 
++           t->gmt->tm_hour, t->gmt->tm_min, t->gmt->tm_sec );
++
++    char lat[20];
++    double latd = f->get_Latitude() * RAD_TO_DEG;
++    if ( latd < 0.0 ) {
++      latd *= -1.0;
++      dir = 'S';
++    } else {
++      dir = 'N';
++    }
++    deg = (int)(latd);
++    min = (latd - (double)deg) * 60.0;
++    sprintf( lat, "%02d%06.3f,%c", abs(deg), min, dir);
++
++    char lon[20];
++    double lond = f->get_Longitude() * RAD_TO_DEG;
++    if ( lond < 0.0 ) {
++      lond *= -1.0;
++      dir = 'W';
++    } else {
++      dir = 'E';
++    }
++    deg = (int)(lond);
++    min = (lond - (double)deg) * 60.0;
++    sprintf( lon, "%03d%06.3f,%c", abs(deg), min, dir);
++
++    char speed[10];
++    sprintf( speed, "%05.1f", f->get_V_equiv_kts() );
++
++    char heading[10];
++    sprintf( heading, "%05.1f", f->get_Psi() * RAD_TO_DEG );
++
++    char altitude_m[10];
++    sprintf( altitude_m, "%02d", (int)(f->get_Altitude() * FEET_TO_METER) );
++
++    char altitude_ft[10];
++    sprintf( altitude_ft, "%02d", (int)f->get_Altitude() );
++
++    char date[10];
++    sprintf( date, "%02d%02d%02d", 
++           t->gmt->tm_mday, t->gmt->tm_mon+1, t->gmt->tm_year );
++
++    // $GPRMC,HHMMSS,A,DDMM.MMM,N,DDDMM.MMM,W,XXX.X,XXX.X,DDMMYY,XXX.X,E*XX
++    sprintf( rmc, "GPRMC,%s,A,%s,%s,%s,%s,%s,000.0,E",
++           utc, lat, lon, speed, heading, date );
++    sprintf( rmc_sum, "%02X", calc_nmea_cksum(rmc) );
++
++    // sprintf( gga, "$GPGGA,%s,%s,%s,1,04,0.0,%s,M,00.0,M,,*00\r\n",
++    //          utc, lat, lon, altitude_m );
++
++    sprintf( rmz, "PGRMZ,%s,f,3", altitude_ft );
++    sprintf( rmz_sum, "%02X", calc_nmea_cksum(rmz) );
++
++    FG_LOG( FG_SERIAL, FG_DEBUG, rmc );
++    FG_LOG( FG_SERIAL, FG_DEBUG, rmz );
++
++    // RMC sentence
++    string rmc_sentence = "$";
++    rmc_sentence += rmc;
++    rmc_sentence += "*";
++    rmc_sentence += rmc_sum;
++    rmc_sentence += "\n";
++    p->port.write_port(rmc_sentence);
++    // cout << rmc_sentence;
++
++    // RMZ sentence (garmin proprietary)
++    string rmz_sentence = "$";
++    rmz_sentence += rmz;
++    rmz_sentence += "*";
++    rmz_sentence += rmz_sum;
++    rmz_sentence += "\n";
++    p->port.write_port(rmz_sentence);
++    // cout << rmz_sentence;
++}
++
++static void read_garmin_in( fgIOCHANNEL *p ) {
++}
++
++static void send_fgfs_out( fgIOCHANNEL *p ) {
++}
++
++static void read_fgfs_in( fgIOCHANNEL *p ) {
++}
++
++
++// one more level of indirection ...
++static void process_port( fgIOCHANNEL *p ) {
++    if ( p->kind == fgIOCHANNEL::FG_SERIAL_NMEA_OUT ) {
++      send_nmea_out(p);
++    } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_NMEA_IN ) {
++      read_nmea_in(p);
++    } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_GARMIN_OUT ) {
++      send_garmin_out(p);
++    } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_GARMIN_IN ) {
++      read_garmin_in(p);
++    } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_FGFS_OUT ) {
++      send_fgfs_out(p);
++    } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_FGFS_IN ) {
++      read_fgfs_in(p);
++    }
++}
++
++
++// process any serial port work
++void fgSerialProcess() {
++    fgIOCHANNEL *port;
++    
++    io_iterator current = port_list.begin();
++    io_iterator last = port_list.end();
++
++    for ( ; current != last; ++current ) {
++      port = current;
++      if ( port->kind != fgIOCHANNEL::FG_SERIAL_DISABLED ) {
++          process_port ( port );
++      }
++    }
++}
++
++
++// $Log$
++// Revision 1.13  1999/03/02 01:03:16  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.12  1999/02/26 22:09:50  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.11  1999/02/05 21:29:11  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.10  1999/01/21 00:55:01  curt
++// Fixed some problems with timing of output strings.
++// Added checksum support for nmea and garmin output.
++//
++// Revision 1.9  1999/01/20 13:42:26  curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.8  1999/01/19 20:57:04  curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.7  1998/12/05 15:54:21  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.6  1998/12/03 01:17:18  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.5  1998/11/30 17:43:32  curt
++// Lots of tweaking to get serial output to actually work.
++//
++// Revision 1.4  1998/11/25 01:33:58  curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.3  1998/11/23 20:51:51  curt
++// Tweaking serial stuff.
++//
++// Revision 1.2  1998/11/19 13:53:25  curt
++// Added a "Garmin" mode.
++//
++// Revision 1.1  1998/11/16 13:57:42  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c1bee22db1e939fea1759a6d13b2fd6e9b2b404f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,114 @@@
++// fg_serial.hxx -- Higher level serial port managment routines
++//
++// Written by Curtis Olson, started November 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_SERIAL_HXX
++#define _FG_SERIAL_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#include "Include/compiler.h"
++
++#include <string>
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <ctime>
++#else
++#  include <time.h>
++#endif
++
++#include <Serial/serial.hxx>
++
++
++class fgIOCHANNEL {
++
++public:
++
++    // Types of serial port protocols
++    enum fgPortKind {
++      FG_SERIAL_DISABLED = 0,
++      FG_SERIAL_NMEA_OUT = 1,
++      FG_SERIAL_NMEA_IN = 2,
++      FG_SERIAL_GARMIN_OUT = 3,
++      FG_SERIAL_GARMIN_IN = 4,
++      FG_SERIAL_FGFS_OUT = 5,
++      FG_SERIAL_FGFS_IN = 6
++    };
++
++    string device;
++    string format;
++    string baud;
++    string direction;
++
++    fgPortKind kind;
++    fgSERIAL port;
++    time_t last_time;
++    bool valid_config;
++
++    fgIOCHANNEL();
++    ~fgIOCHANNEL();
++};
++
++
++// support up to four serial channels.  Each channel can be assigned
++// to an arbitrary port.  Bi-directional communication is supported by
++// the underlying layer.
++
++// define the four channels
++// extern fgIOCHANNEL port_a;
++// extern fgIOCHANNEL port_b;
++// extern fgIOCHANNEL port_c;
++// extern fgIOCHANNEL port_d;
++
++
++// initialize serial ports based on command line options (if any)
++void fgSerialInit();
++
++
++// process any serial port work
++void fgSerialProcess();
++
++
++#endif // _FG_SERIAL_HXX
++
++
++// $Log$
++// Revision 1.5  1999/01/21 00:55:02  curt
++// Fixed some problems with timing of output strings.
++// Added checksum support for nmea and garmin output.
++//
++// Revision 1.4  1998/11/30 17:43:34  curt
++// Lots of tweaking to get serial output to actually work.
++//
++// Revision 1.3  1998/11/25 01:33:59  curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.2  1998/11/19 13:53:27  curt
++// Added a "Garmin" mode.
++//
++// Revision 1.1  1998/11/16 13:57:43  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0d4db31de4a146deb522d342b2de87734a75c593
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,863 @@@
++// options.cxx -- class to handle command line options
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#if defined(FX) && defined(XMESA)
++bool global_fullscreen = true;
++#endif
++
++#include <Include/compiler.h>
++
++#include <math.h>            // rint()
++#include <stdio.h>
++#include <stdlib.h>          // atof(), atoi()
++#include <string.h>
++
++#include STL_STRING
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++
++#include "fg_serial.hxx"
++
++FG_USING_STD(string);
++FG_USING_NAMESPACE(std);
++
++
++inline double
++atof( const string& str )
++{
++    return ::atof( str.c_str() );
++}
++
++inline int
++atoi( const string& str )
++{
++    return ::atoi( str.c_str() );
++}
++
++// Defined the shared options class here
++fgOPTIONS current_options;
++
++
++// Constructor
++fgOPTIONS::fgOPTIONS() :
++    // starting longitude in degrees (west = -)
++    // starting latitude in degrees (south = -)
++
++    // Default initial position is Globe, AZ (P13)
++    lon(-110.6642444),
++    lat(  33.3528917),
++
++    // North of the city of Globe
++    // lon(-110.7),
++    // lat(  33.4),
++
++    // North of the city of Globe
++    // lon(-110.742578),
++    // lat(  33.507122),
++
++    // Near where I used to live in Globe, AZ
++    // lon(-110.766000),
++    // lat(  33.377778),
++
++    // 10125 Jewell St. NE
++    // lon(-93.15),
++    // lat( 45.15),
++
++    // Near KHSP (Hot Springs, VA)
++    // lon(-79.8338964 + 0.01),
++    // lat( 37.9514564 + 0.008),
++
++    // (SEZ) SEDONA airport
++    // lon(-111.7884614 + 0.01),
++    // lat(  34.8486289 - 0.015),
++
++    // Jim Brennon's Kingmont Observatory
++    // lon(-121.1131667),
++    // lat(  38.8293917),
++
++    // Huaras, Peru (S09d 31.871'  W077d 31.498')
++    // lon(-77.5249667),
++    // lat( -9.5311833),
++ 
++    // Eclipse Watching w73.5 n10 (approx) 18:00 UT
++    // lon(-73.5),
++    // lat( 10.0),
++
++    // Timms Hill (WI)
++    // lon(-90.1953055556),
++    // lat( 45.4511388889),
++
++    // starting altitude in meters (this will be reset to ground level
++    // if it is lower than the terrain
++    altitude(-9999.0),
++
++    // Initial Orientation
++    heading(270.0),      // heading (yaw) angle in degress (Psi)
++    roll(0.0),           // roll angle in degrees (Phi)
++    pitch(0.424),        // pitch angle in degrees (Theta)
++
++    // Miscellaneous
++    game_mode(0),
++    splash_screen(1),
++    intro_music(1),
++    mouse_pointer(0),
++    pause(0),
++
++    // Features
++    hud_status(1),
++    panel_status(0),
++    sound(1),
++
++    // Flight Model options
++    flight_model(FGInterface::FG_LARCSIM),
++
++    // Rendering options
++    fog(FG_FOG_NICEST),  // nicest
++    fov(55.0),
++    fullscreen(0),
++    shading(1),
++    skyblend(1),
++    textures(1),
++    wireframe(0),
++    xsize(640),
++    ysize(480),
++
++    // Scenery options
++    tile_diameter(5),
++
++    // HUD options
++    units(FG_UNITS_FEET),
++    tris_or_culled(0),
++      
++    // Time options
++    time_offset(0)
++
++{
++    // set initial values/defaults
++    char* envp = ::getenv( "FG_ROOT" );
++
++    if ( envp != NULL ) {
++      // fg_root could be anywhere, so default to environmental
++      // variable $FG_ROOT if it is set.
++      fg_root = envp;
++    } else {
++      // Otherwise, default to a random compiled in location if
++      // $FG_ROOT is not set.  This can still be overridden from the
++      // command line or a config file.
++
++#if defined(WIN32)
++      fg_root = "\\FlightGear";
++#else
++      fg_root = "/usr/local/lib/FlightGear";
++#endif
++    }
++
++    airport_id = "";  // default airport id
++
++    // initialize port config string list
++    port_options_list.erase ( port_options_list.begin(), 
++                            port_options_list.end() );
++}
++
++
++double
++fgOPTIONS::parse_time(const string& time_in) {
++    char *time_str, num[256];
++    double hours, minutes, seconds;
++    double result = 0.0;
++    int sign = 1;
++    int i;
++
++    time_str = (char *)time_in.c_str();
++
++    // printf("parse_time(): %s\n", time_str);
++
++    // check for sign
++    if ( strlen(time_str) ) {
++      if ( time_str[0] == '+' ) {
++          sign = 1;
++          time_str++;
++      } else if ( time_str[0] == '-' ) {
++          sign = -1;
++          time_str++;
++      }
++    }
++    // printf("sign = %d\n", sign);
++
++    // get hours
++    if ( strlen(time_str) ) {
++      i = 0;
++      while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++          num[i] = time_str[0];
++          time_str++;
++          i++;
++      }
++      if ( time_str[0] == ':' ) {
++          time_str++;
++      }
++      num[i] = '\0';
++      hours = atof(num);
++      // printf("hours = %.2lf\n", hours);
++
++      result += hours;
++    }
++
++    // get minutes
++    if ( strlen(time_str) ) {
++      i = 0;
++      while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++          num[i] = time_str[0];
++          time_str++;
++          i++;
++      }
++      if ( time_str[0] == ':' ) {
++          time_str++;
++      }
++      num[i] = '\0';
++      minutes = atof(num);
++      // printf("minutes = %.2lf\n", minutes);
++
++      result += minutes / 60.0;
++    }
++
++    // get seconds
++    if ( strlen(time_str) ) {
++      i = 0;
++      while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++          num[i] = time_str[0];
++          time_str++;
++          i++;
++      }
++      num[i] = '\0';
++      seconds = atof(num);
++      // printf("seconds = %.2lf\n", seconds);
++
++      result += seconds / 3600.0;
++    }
++
++    return(sign * result);
++}
++
++
++// parse degree in the form of [+/-]hhh:mm:ss
++double
++fgOPTIONS::parse_degree( const string& degree_str) {
++    double result = parse_time( degree_str );
++
++    // printf("Degree = %.4f\n", result);
++
++    return(result);
++}
++
++
++// parse time offset command line option
++int
++fgOPTIONS::parse_time_offset( const string& time_str) {
++    int result;
++
++    // printf("time offset = %s\n", time_str);
++
++#ifdef HAVE_RINT
++    result = (int)rint(parse_time(time_str) * 3600.0);
++#else
++    result = (int)(parse_time(time_str) * 3600.0);
++#endif
++
++    // printf("parse_time_offset(): %d\n", result);
++
++    return( result );
++}
++
++
++// Parse --tile-diameter=n type option 
++
++int
++fgOPTIONS::parse_tile_radius( const string& arg ) {
++    int radius = atoi( arg );
++
++    if ( radius < FG_RADIUS_MIN ) { radius = FG_RADIUS_MIN; }
++    if ( radius > FG_RADIUS_MAX ) { radius = FG_RADIUS_MAX; }
++
++    // printf("parse_tile_radius(): radius = %d\n", radius);
++
++    return(radius);
++}
++
++
++// Parse --fdm=abcdefg type option 
++int
++fgOPTIONS::parse_fdm( const string& fm ) {
++    // printf("fdm = %s\n", fm);
++
++    if ( fm == "slew" ) {
++      return FGInterface::FG_SLEW;
++    } else if ( fm == "jsb" ) {
++      return FGInterface::FG_JSBSIM;
++    } else if ( (fm == "larcsim") || (fm == "LaRCsim") ) {
++      return FGInterface::FG_LARCSIM;
++    } else if ( fm == "external" ) {
++      return FGInterface::FG_EXTERNAL;
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Unknown fdm = " << fm );
++      exit(-1);
++    }
++
++    // we'll never get here, but it makes the compiler happy.
++    return -1;
++}
++
++
++// Parse --fov=x.xx type option 
++double
++fgOPTIONS::parse_fov( const string& arg ) {
++    double fov = atof(arg);
++
++    if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
++    if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
++
++    // printf("parse_fov(): result = %.4f\n", fov);
++
++    return(fov);
++}
++
++
++// Parse serial port option --serial=/dev/ttyS1,nmea,4800,out
++//
++// Format is "--serial=device,format,baud,direction" where
++// 
++//  device = OS device name to be open()'ed
++//  format = {nmea, fgfs}
++//  baud = {300, 1200, 2400, ..., 230400}
++//  direction = {in, out, bi}
++
++bool 
++fgOPTIONS::parse_serial( const string& serial_str ) {
++    string::size_type pos;
++
++    // cout << "Serial string = " << serial_str << endl;
++
++    // a flailing attempt to see if the port config string has a
++    // chance at being valid
++    pos = serial_str.find(",");
++    if ( pos == string::npos ) {
++      FG_LOG( FG_GENERAL, FG_ALERT, 
++              "Malformed serial port configure string" );
++      return false;
++    }
++    
++    port_options_list.push_back( serial_str );
++
++    return true;
++}
++
++
++// Parse a single option
++int fgOPTIONS::parse_option( const string& arg ) {
++    // General Options
++    if ( (arg == "--help") || (arg == "-h") ) {
++      // help/usage request
++      return(FG_OPTIONS_HELP);
++    } else if ( arg == "--disable-game-mode") {
++      game_mode = false;
++    } else if ( arg == "--enable-game-mode" ) {
++      game_mode = true;
++    } else if ( arg == "--disable-splash-screen" ) {
++      splash_screen = false;
++    } else if ( arg == "--enable-splash-screen" ) {
++      splash_screen = true;
++    } else if ( arg == "--disable-intro-music" ) {
++      intro_music = false;
++    } else if ( arg == "--enable-intro-music" ) {
++      intro_music = true;
++    } else if ( arg == "--disable-mouse-pointer" ) {
++      mouse_pointer = 1;
++    } else if ( arg == "--enable-mouse-pointer" ) {
++      mouse_pointer = 2;
++    } else if ( arg == "--disable-pause" ) {
++      pause = false;  
++    } else if ( arg == "--enable-pause" ) {
++      pause = true;   
++    } else if ( arg == "--disable-hud" ) {
++      hud_status = false;     
++    } else if ( arg == "--enable-hud" ) {
++      hud_status = true;      
++    } else if ( arg == "--disable-panel" ) {
++      panel_status = false;
++    } else if ( arg == "--enable-panel" ) {
++      panel_status = true;
++      fov *= 0.4232;
++    } else if ( arg == "--disable-sound" ) {
++      sound = false;
++    } else if ( arg == "--enable-sound" ) {
++      sound = true;
++    } else if ( arg.find( "--airport-id=") != string::npos ) {
++      airport_id = arg.substr( 13 );
++    } else if ( arg.find( "--lon=" ) != string::npos ) {
++      lon = parse_degree( arg.substr(6) );
++    } else if ( arg.find( "--lat=" ) != string::npos ) {
++      lat = parse_degree( arg.substr(6) );
++    } else if ( arg.find( "--altitude=" ) != string::npos ) {
++      if ( units == FG_UNITS_FEET ) {
++          altitude = atof( arg.substr(11) ) * FEET_TO_METER;
++      } else {
++          altitude = atof( arg.substr(11) );
++      }
++    } else if ( arg.find( "--heading=" ) != string::npos ) {
++      heading = atof( arg.substr(10) );
++    } else if ( arg.find( "--roll=" ) != string::npos ) {
++      roll = atof( arg.substr(7) );
++    } else if ( arg.find( "--pitch=" ) != string::npos ) {
++      pitch = atof( arg.substr(8) );
++    } else if ( arg.find( "--fg-root=" ) != string::npos ) {
++      fg_root = arg.substr( 10 );
++    } else if ( arg.find( "--fdm=" ) != string::npos ) {
++      flight_model = parse_fdm( arg.substr(6) );
++    } else if ( arg == "--fog-disable" ) {
++      fog = FG_FOG_DISABLED;  
++    } else if ( arg == "--fog-fastest" ) {
++      fog = FG_FOG_FASTEST;   
++    } else if ( arg == "--fog-nicest" ) {
++      fog = FG_FOG_NICEST;    
++    } else if ( arg.find( "--fov=" ) != string::npos ) {
++      fov = parse_fov( arg.substr(6) );
++    } else if ( arg == "--disable-fullscreen" ) {
++      fullscreen = false;     
++    } else if ( arg== "--enable-fullscreen") {
++      fullscreen = true;      
++    } else if ( arg == "--shading-flat") {
++      shading = 0;    
++    } else if ( arg == "--shading-smooth") {
++      shading = 1;    
++    } else if ( arg == "--disable-skyblend") {
++      skyblend = false;       
++    } else if ( arg== "--enable-skyblend" ) {
++      skyblend = true;        
++    } else if ( arg == "--disable-textures" ) {
++      textures = false;       
++    } else if ( arg == "--enable-textures" ) {
++      textures = true;
++    } else if ( arg == "--disable-wireframe" ) {
++      wireframe = false;      
++    } else if ( arg == "--enable-wireframe" ) {
++      wireframe = true;
++    } else if ( arg.find( "--geometry=" ) != string::npos ) {
++      string geometry = arg.substr( 11 );
++      if ( geometry == "640x480" ) {
++          xsize = 640;
++          ysize = 480;
++      } else if ( geometry == "800x600" ) {
++          xsize = 800;
++          ysize = 600;
++      } else if ( geometry == "1024x768" ) {
++          xsize = 1024;
++          ysize = 768;
++      } else {
++          FG_LOG( FG_GENERAL, FG_ALERT, "Unknown geometry: " << geometry );
++          exit(-1);
++      }
++    } else if ( arg == "--units-feet" ) {
++      units = FG_UNITS_FEET;  
++    } else if ( arg == "--units-meters" ) {
++      units = FG_UNITS_METERS;        
++    } else if ( arg.find( "--tile-radius=" ) != string::npos ) {
++      tile_radius = parse_tile_radius( arg.substr(14) );
++      tile_diameter = tile_radius * 2 + 1;
++    } else if ( arg.find( "--time-offset=" ) != string::npos ) {
++      time_offset = parse_time_offset( (arg.substr(14)) );
++    } else if ( arg == "--hud-tris" ) {
++      tris_or_culled = 0;     
++    } else if ( arg == "--hud-culled" ) {
++      tris_or_culled = 1;
++    } else if ( arg.find( "--serial=" ) != string::npos ) {
++      parse_serial( arg.substr(9) );
++    } else {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Unknown option '" << arg << "'" );
++      return FG_OPTIONS_ERROR;
++    }
++    
++    return FG_OPTIONS_OK;
++}
++
++
++// Parse the command line options
++int fgOPTIONS::parse_command_line( int argc, char **argv ) {
++    int i = 1;
++    int result;
++
++    FG_LOG(FG_GENERAL, FG_INFO, "Processing command line arguments");
++
++    while ( i < argc ) {
++      FG_LOG( FG_GENERAL, FG_DEBUG, "argv[" << i << "] = " << argv[i] );
++
++      result = parse_option(argv[i]);
++      if ( (result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR) ) {
++          return(result);
++      }
++
++      i++;
++    }
++    
++    return(FG_OPTIONS_OK);
++}
++
++
++// Parse config file options
++int fgOPTIONS::parse_config_file( const string& path ) {
++    fg_gzifstream in( path );
++    if ( !in )
++      return(FG_OPTIONS_ERROR);
++
++    FG_LOG( FG_GENERAL, FG_INFO, "Processing config file: " << path );
++
++    in >> skipcomment;
++    while ( !in.eof() )
++    {
++      string line;
++      getline( in, line );
++
++      if ( parse_option( line ) == FG_OPTIONS_ERROR ) {
++          FG_LOG( FG_GENERAL, FG_ALERT, 
++                  "Config file parse error: " << path << " '" 
++                  << line << "'" );
++          exit(-1);
++      }
++      in >> skipcomment;
++    }
++
++    return FG_OPTIONS_OK;
++}
++
++
++// Print usage message
++void fgOPTIONS::usage ( void ) {
++    printf("Usage: fg [ options ... ]\n");
++    printf("\n");
++
++    printf("General Options:\n");
++    printf("\t--help -h:  print usage\n");
++    printf("\t--fg-root=path:  specify the root path for all the data files\n");
++    printf("\t--disable-game-mode:  disable full-screen game mode\n");
++    printf("\t--enable-game-mode:  enable full-screen game mode\n");
++    printf("\t--disable-splash-screen:  disable splash screen\n");
++    printf("\t--enable-splash-screen:  enable splash screen\n");
++    printf("\t--disable-intro-music:  disable introduction music\n");
++    printf("\t--enable-intro-music:  enable introduction music\n");
++    printf("\t--disable-mouse-pointer:  disable extra mouse pointer\n");
++    printf("\t--enable-mouse-pointer:  enable extra mouse pointer (i.e. for\n");
++    printf("\t\tfull screen voodoo/voodoo-II based cards.)\n");
++    printf("\t--disable-pause:  start out in an active state\n");
++    printf("\t--enable-pause:  start out in a paused state\n");
++    printf("\n");
++
++    printf("Features:\n");
++    printf("\t--disable-hud:  disable heads up display\n");
++    printf("\t--enable-hud:  enable heads up display\n");
++    printf("\t--disable-panel:  disable instrument panel\n");
++    printf("\t--enable-panel:  enable instrumetn panel\n");
++    printf("\t--disable-sound:  disable sound effects\n");
++    printf("\t--enable-sound:  enable sound effects\n");
++    printf("\n");
++ 
++    printf("Flight Model:\n");
++    printf("\t--fdm=abcd:  one of slew, jsb, larcsim, or external\n");
++    printf("\n");
++
++    printf("Initial Position and Orientation:\n");
++    printf("\t--airport-id=ABCD:  specify starting postion by airport id\n");
++    printf("\t--lon=degrees:  starting longitude in degrees (west = -)\n");
++    printf("\t--lat=degrees:  starting latitude in degrees (south = -)\n");
++    printf("\t--altitude=feet:  starting altitude in feet\n");
++    printf("\t\t(unless --units-meters specified\n");
++    printf("\t--heading=degrees:  heading (yaw) angle in degress (Psi)\n");
++    printf("\t--roll=degrees:  roll angle in degrees (Phi)\n");
++    printf("\t--pitch=degrees:  pitch angle in degrees (Theta)\n");
++    printf("\n");
++
++    printf("Rendering Options:\n");
++    printf("\t--fog-disable:  disable fog/haze\n");
++    printf("\t--fog-fastest:  enable fastest fog/haze\n");
++    printf("\t--fog-nicest:  enable nicest fog/haze\n");
++    printf("\t--fov=xx.x:  specify initial field of view angle in degrees\n");
++    printf("\t--disable-fullscreen:  disable fullscreen mode\n");
++    printf("\t--enable-fullscreen:  enable fullscreen mode\n");
++    printf("\t--shading-flat:  enable flat shading\n");
++    printf("\t--shading-smooth:  enable smooth shading\n");
++    printf("\t--disable-skyblend:  disable sky blending\n");
++    printf("\t--enable-skyblend:  enable sky blending\n");
++    printf("\t--disable-textures:  disable textures\n");
++    printf("\t--enable-textures:  enable textures\n");
++    printf("\t--disable-wireframe:  disable wireframe drawing mode\n");
++    printf("\t--enable-wireframe:  enable wireframe drawing mode\n");
++    printf("\t--geometry=WWWxHHH:  window geometry: 640x480, 800x600, etc.\n");
++    printf("\n");
++
++    printf("Scenery Options:\n");
++    printf("\t--tile-radius=n:  specify tile radius, must be 1 - 4\n");
++    printf("\n");
++
++    printf("Hud Options:\n");
++    printf("\t--units-feet:  Hud displays units in feet\n");
++    printf("\t--units-meters:  Hud displays units in meters\n");
++    printf("\t--hud-tris:  Hud displays number of triangles rendered\n");
++    printf("\t--hud-culled:  Hud displays percentage of triangles culled\n");
++    printf("\n");
++      
++    printf("Time Options:\n");
++    printf("\t--time-offset=[+-]hh:mm:ss:  offset local time by this amount\n");
++}
++
++
++// Destructor
++fgOPTIONS::~fgOPTIONS( void ) {
++}
++
++
++// $Log$
++// Revision 1.43  1999/03/22 23:47:55  curt
++// FOV set properly when panel activated.
++//
++// Revision 1.42  1999/03/11 23:09:50  curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url.  Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.41  1999/03/02 01:03:17  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.40  1999/02/26 22:09:51  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.39  1999/02/05 21:29:12  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.38  1999/02/01 21:33:35  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.37  1999/01/19 20:57:05  curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.36  1999/01/07 20:25:10  curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.35  1998/12/06 14:52:57  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.34  1998/12/05 15:54:22  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.33  1998/12/04 01:30:44  curt
++// Added support for the External flight model.
++//
++// Revision 1.32  1998/11/25 01:34:00  curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.31  1998/11/23 21:49:04  curt
++// Borland portability tweaks.
++//
++// Revision 1.30  1998/11/16 14:00:02  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.29  1998/11/06 21:18:12  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.28  1998/11/06 14:47:03  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.27  1998/11/02 23:04:04  curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.26  1998/10/17 01:34:24  curt
++// C++ ifying ...
++//
++// Revision 1.25  1998/09/15 02:09:27  curt
++// Include/fg_callback.hxx
++//   Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++//   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
++//   complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++//   Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++//   Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++//   Uses fg_gzifstream when loading config file.
++//
++// Revision 1.24  1998/09/08 15:04:33  curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.23  1998/08/27 17:02:07  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.22  1998/08/24 20:11:13  curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.21  1998/08/20 15:10:34  curt
++// Added GameGLUT support.
++//
++// Revision 1.20  1998/07/30 23:48:28  curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.19  1998/07/27 18:41:25  curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.18  1998/07/22 01:27:03  curt
++// Strip out \r when parsing config file in case we are on a windoze system.
++//
++// Revision 1.17  1998/07/16 17:33:38  curt
++// "H" / "h" now control hud brightness as well with off being one of the
++//   states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++//   whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.16  1998/07/13 21:01:39  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15  1998/07/06 21:34:19  curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.14  1998/07/04 00:52:26  curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.)  But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card.  This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.13  1998/06/27 16:54:34  curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.12  1998/06/17 21:35:13  curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.11  1998/06/13 00:40:33  curt
++// Tweaked fog command line options.
++//
++// Revision 1.10  1998/05/16 13:08:36  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.9  1998/05/13 18:29:59  curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.8  1998/05/07 23:14:16  curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.7  1998/05/06 03:16:25  curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.6  1998/05/03 00:47:32  curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.5  1998/04/30 12:34:19  curt
++// Added command line rendering options:
++//   enable/disable fog/haze
++//   specify smooth/flat shading
++//   disable sky blending and just use a solid color
++//   enable wireframe drawing mode
++//
++// Revision 1.4  1998/04/28 01:20:22  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.3  1998/04/26 05:01:19  curt
++// Added an rint() / HAVE_RINT check.
++//
++// Revision 1.2  1998/04/25 15:11:12  curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1  1998/04/24 00:49:21  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ece66675750e68d773c1257c45d85c8202157c74
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,393 @@@
++// options.hxx -- class to handle command line options
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _OPTIONS_HXX
++#define _OPTIONS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif                                   
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++extern bool global_fullscreen;
++#endif
++
++#include STL_STRING
++#include <vector>
++
++FG_USING_STD(vector);
++FG_USING_STD(string);
++
++typedef vector < string > str_container;
++typedef str_container::iterator str_iterator;
++typedef str_container::const_iterator const_str_iterator;
++
++
++class fgOPTIONS {
++
++public:
++
++    enum
++    {
++      FG_OPTIONS_OK = 0,
++      FG_OPTIONS_HELP = 1,
++      FG_OPTIONS_ERROR = 2
++    };
++
++    enum
++    {
++      FG_UNITS_FEET = 0,
++      FG_UNITS_METERS = 1
++    };
++
++    enum fgFogKind
++    {
++      FG_FOG_DISABLED = 0,
++      FG_FOG_FASTEST  = 1,
++      FG_FOG_NICEST   = 2
++    };
++
++    enum
++    {
++      FG_RADIUS_MIN = 1,
++      FG_RADIUS_MAX = 4
++    };
++
++private:
++
++    // The flight gear "root" directory
++    string fg_root;
++
++    // Starting position and orientation
++    string airport_id;  // ID of initial starting airport
++    double lon;         // starting longitude in degrees (west = -)
++    double lat;         // starting latitude in degrees (south = -)
++    double altitude;    // starting altitude in meters
++    double heading;     // heading (yaw) angle in degress (Psi)
++    double roll;        // roll angle in degrees (Phi)
++    double pitch;       // pitch angle in degrees (Theta)
++
++    // Miscellaneous
++    bool game_mode;     // Game mode enabled/disabled
++    bool splash_screen; // show splash screen
++    bool intro_music;   // play introductory music
++    int mouse_pointer;  // show mouse pointer
++    bool pause;         // pause intially enabled/disabled
++
++    // Features
++    bool hud_status;    // HUD on/off
++    bool panel_status;  // Panel on/off
++    bool sound;         // play sound effects
++
++    // Flight Model options
++    int flight_model;   // Flight Model:  FG_SLEW, FG_LARCSIM, etc.
++
++    // Rendering options
++    fgFogKind fog;      // Fog nicest/fastest/disabled
++    double fov;         // Field of View
++    bool fullscreen;    // Full screen mode enabled/disabled
++    int shading;        // shading method, 0 = Flat, 1 = Smooth
++    bool skyblend;      // Blend sky to haze (using polygons) or just clear
++    bool textures;      // Textures enabled/disabled
++    bool wireframe;     // Wireframe mode enabled/disabled
++    int xsize, ysize;   // window size derived from geometry string
++
++    // Scenery options
++    int tile_radius;   // Square radius of rendered tiles (around center 
++                       // square.)
++    int tile_diameter; // Diameter of rendered tiles.  for instance
++                       // if tile_diameter = 3 then a 3 x 3 grid of tiles will 
++                       // be drawn.  Increase this to see terrain that is 
++                       // further away.
++
++    // HUD options
++    int units;         // feet or meters
++    int tris_or_culled;
++
++    // Time options
++    int time_offset;   // Offset true time by this many seconds
++
++    // Serial Ports, we currently support up to four channels
++    // fgSerialPortKind port_a_kind;  // Port a kind
++    // fgSerialPortKind port_b_kind;  // Port b kind
++    // fgSerialPortKind port_c_kind;  // Port c kind
++    // fgSerialPortKind port_d_kind;  // Port d kind
++
++    // Serial port configuration strings
++    str_container port_options_list;
++    
++public:
++
++    fgOPTIONS();
++    ~fgOPTIONS();
++
++    // Parse a single option
++    int parse_option( const string& arg );
++
++    // Parse the command line options
++    int parse_command_line( int argc, char **argv );
++
++    // Parse the command line options
++    int parse_config_file( const string& path );
++
++    // Print usage message
++    void usage ( void );
++
++    // Query functions
++    inline string get_fg_root() const { return fg_root; }
++    inline string get_airport_id() const { return airport_id; }
++    inline double get_lon() const { return lon; }
++    inline double get_lat() const { return lat; }
++    inline double get_altitude() const { return altitude; }
++    inline double get_heading() const { return heading; }
++    inline double get_roll() const { return roll; }
++    inline double get_pitch() const { return pitch; }
++    inline bool get_game_mode() const { return game_mode; }
++    inline bool get_splash_screen() const { return splash_screen; }
++    inline bool get_intro_music() const { return intro_music; }
++    inline int get_mouse_pointer() const { return mouse_pointer; }
++    inline bool get_pause() const { return pause; }
++    inline bool get_hud_status() const { return hud_status; }
++    inline bool get_panel_status() const { return panel_status; }
++    inline bool get_sound() const { return sound; }
++    inline int get_flight_model() const { return flight_model; }
++    inline bool fog_enabled() const { return fog != FG_FOG_DISABLED; }
++    inline fgFogKind get_fog() const { return fog; }
++    inline double get_fov() const { return fov; }
++    inline bool get_fullscreen() const { return fullscreen; }
++    inline int get_shading() const { return shading; }
++    inline bool get_skyblend() const { return skyblend; }
++    inline bool get_textures() const { return textures; }
++    inline bool get_wireframe() const { return wireframe; }
++    inline int get_xsize() const { return xsize; }
++    inline int get_ysize() const { return ysize; }
++    inline int get_tile_radius() const { return tile_radius; }
++    inline int get_tile_diameter() const { return tile_diameter; }
++
++    inline int get_units() const { return units; }
++    inline int get_tris_or_culled() const { return tris_or_culled; }
++
++    inline int get_time_offset() const { return time_offset; }
++
++    inline str_container get_port_options_list() const { 
++      return port_options_list;
++    }
++
++    // Update functions
++    inline void set_hud_status( bool status ) { hud_status = status; }
++    inline void set_fov( double amount ) { fov = amount; }
++    inline void set_textures( bool status ) { textures = status; }
++    inline void cycle_fog( void ) { 
++      if ( fog == FG_FOG_DISABLED ) {
++          fog = FG_FOG_FASTEST;
++      } else if ( fog == FG_FOG_FASTEST ) {
++          fog = FG_FOG_NICEST;
++          xglHint ( GL_FOG_HINT, GL_NICEST );
++      } else if ( fog == FG_FOG_NICEST ) {
++          fog = FG_FOG_DISABLED;
++          xglHint ( GL_FOG_HINT, GL_FASTEST );
++      }
++    }
++    inline void set_xsize( int x ) { xsize= x; }
++    inline void set_ysize( int y ) { xsize= y; }
++
++private:
++
++    double parse_time( const string& time_str );
++    double parse_degree( const string& degree_str );
++    int parse_time_offset( const string& time_str );
++    int parse_tile_radius( const string& arg );
++    int parse_fdm( const string& fm );
++    double parse_fov( const string& arg );
++    bool parse_serial( const string& serial_str );
++};
++
++
++extern fgOPTIONS current_options;
++
++
++#endif /* _OPTIONS_HXX */
++
++
++// $Log$
++// Revision 1.30  1999/03/11 23:09:51  curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url.  Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.29  1999/03/02 01:03:19  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.28  1999/02/26 22:09:52  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.27  1999/02/05 21:29:13  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.26  1999/02/02 20:13:37  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.25  1999/01/19 20:57:06  curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.24  1998/11/25 01:34:01  curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.23  1998/11/23 21:49:05  curt
++// Borland portability tweaks.
++//
++// Revision 1.22  1998/11/20 01:02:38  curt
++// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
++//
++// Revision 1.21  1998/11/16 14:00:04  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.20  1998/11/02 23:04:05  curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.19  1998/10/25 14:08:49  curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.18  1998/09/17 18:35:31  curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.17  1998/09/08 21:40:10  curt
++// Fixes by Charlie Hotchkiss.
++//
++// Revision 1.16  1998/08/27 17:02:08  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.15  1998/08/24 20:11:15  curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.14  1998/08/20 15:10:35  curt
++// Added GameGLUT support.
++//
++// Revision 1.13  1998/07/30 23:48:29  curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.12  1998/07/27 18:41:26  curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.11  1998/07/13 21:01:39  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10  1998/07/06 21:34:20  curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.9  1998/06/27 16:54:34  curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.8  1998/05/16 13:08:36  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.7  1998/05/13 18:29:59  curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.6  1998/05/06 03:16:26  curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.5  1998/05/03 00:47:32  curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.4  1998/04/30 12:34:19  curt
++// Added command line rendering options:
++//   enable/disable fog/haze
++//   specify smooth/flat shading
++//   disable sky blending and just use a solid color
++//   enable wireframe drawing mode
++//
++// Revision 1.3  1998/04/28 01:20:23  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.2  1998/04/25 15:11:13  curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1  1998/04/24 00:49:21  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e64c4b637ad488402b67f854929c582692bcb378
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,28 @@@
++REM @ECHO OFF\r
++\r
++REM Skip ahead to RUN1 if %FG_ROOT%\BIN\FGFS.EXE exists\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try "."\r
++SET FG_ROOT=.\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try ".."\r
++SET FG_ROOT=..\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try "@prefix@"\r
++SET FG_ROOT=@prefix@\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++ECHO Cannot find %FG_ROOT%\BIN\FGFS.EXE\r
++GOTO END\r
++\r
++:RUN1\r
++REM Now that FG_ROOT has been set, run the program\r
++ECHO FG_ROOT = %FG_ROOT%\r
++%FG_ROOT%\BIN\FGFS.EXE %1 %2 %3 %4 %5 %6 %7 %8 %9\r
++\r
++GOTO END\r
++\r
++:END\r
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6787f01793d16eb7d9a31c39f1e7d59147a76580
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,119 @@@
++#!/usr/bin/perl
++#
++# runfg -- front end for setting up the FG_ROOT env variable and launching 
++#          the fg executable.
++#
++# Written by Curtis Olson, started September 1997.
++#
++# Copyright (C) 1997 - 1998  Curtis L. Olson  - curt@me.umn.edu
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++#
++# $Id$
++# (Log is kept at end of this file)
++#---------------------------------------------------------------------------
++
++
++$prefix = "@prefix@";
++# print "-> $prefix\n";
++
++# potential names of Flight Gear executable to try
++@files = ( "fg", "fg.exe" );
++
++# search for the executable
++# potential paths where the executable may be found
++@paths = ( ".", "Simulator/Main", $prefix );
++
++$savepath = "";
++$savefile = "";
++
++foreach $path (@paths) {
++    foreach $file (@files) {
++      # print "'$savepath'\n";
++      if ( $savepath eq "" ) {
++          # don't search again if we've already found one
++          # print "checking $path" . "bin/$file and $path" . "$file\n";
++          if ( -x "$path/bin/$file" ) {
++              $saveprefix = $path;
++              $savepath = "$path/bin";
++              $savefile = "$file";
++          } elsif ( -x "$path/$file" ) {
++              $saveprefix = $path;
++              $savepath = "$path";
++              $savefile = "$file";
++          }
++      } else {
++          # print "skipping $path/bin/$file and $path/$file\n";
++      }
++    }
++}
++
++die "Cannot locate program.\n" if ( $savepath eq "" );
++
++
++# search for the "FlightGear" root directory
++@paths = ( $prefix, $saveprefix, $ENV{HOME} );
++
++$fg_root = "";
++
++foreach $path (@paths) {
++    # print "trying $path\n";
++
++    if ( $fg_root eq "" ) {
++      if ( -d "$path/FlightGear" ) {
++          $fg_root = "$path/FlightGear";
++      } elsif ( -d "$path/lib/FlightGear" ) {
++          $fg_root = "$path/lib/FlightGear";
++      }
++    }
++}
++
++die "Cannot locate FG root directory (data)\n" if ( $fg_root eq "" );
++
++# run Flight Gear
++print "Running $savepath/$savefile --fg-root=$fg_root @ARGV\n";
++exec("$savepath/$savefile --fg-root=$fg_root @ARGV");
++
++
++#---------------------------------------------------------------------------
++# $Log$
++# Revision 1.2  1998/08/25 16:59:10  curt
++# Directory reshuffling.
++#
++# Revision 1.1  1998/08/24 20:32:41  curt
++# runfg.in renamed to runfgfs.in
++#
++# Revision 1.3  1998/08/03 22:16:42  curt
++# Updated to be smarter about finding $FG_ROOT.
++#
++# Revision 1.2  1998/04/25 22:06:31  curt
++# Edited cvs log messages in source files ... bad bad bad!
++#
++# Revision 1.1  1998/04/09 01:45:31  curt
++# Moved to Main/ and incorperated with automake
++#
++# Revision 1.4  1998/03/09 22:52:38  curt
++# Mod's to better support win32 if perl exists.
++#
++# Revision 1.3  1998/02/16 16:17:34  curt
++# Minor tweaks.
++#
++# Revision 1.2  1998/01/27 00:47:43  curt
++# Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++# system and commandline/config file processing code.
++#
++# Revision 1.1  1997/10/28 18:47:27  curt
++# Initial revision.
++#
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9322aaf975dd9a33a182255bb6d20f0cdcd005ff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,201 @@@
++// splash.cxx -- draws the initial splash screen
++//
++// Written by Curtis Olson, started July 1998.  (With a little looking
++// at Freidemann's panel code.) :-)
++//
++// Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H          
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <string.h>
++
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++#include <Math/fg_random.h>
++#include <Objects/texload.h>
++
++#include "splash.hxx"
++#include "views.hxx"
++
++
++static GLuint splash_texid;
++static GLubyte *splash_texbuf;
++
++
++// Initialize the splash screen
++void fgSplashInit ( void ) {
++    string tpath, fg_tpath;
++    int width, height;
++
++    FG_LOG( FG_GENERAL, FG_INFO, "Initializing splash screen" );
++#ifdef GL_VERSION_1_1
++    xglGenTextures(1, &splash_texid);
++    xglBindTexture(GL_TEXTURE_2D, splash_texid);
++#elif GL_EXT_texture_object
++    xglGenTexturesEXT(1, &splash_texid);
++    xglBindTextureEXT(GL_TEXTURE_2D, splash_texid);
++#else
++#  error port me
++#endif
++
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++    xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++    // load in the texture data
++    int num = (int)(fg_random() * 4.0 + 1.0);
++    char num_str[256];
++    sprintf(num_str, "%d", num);
++    tpath = current_options.get_fg_root() + "/Textures/Splash";
++    tpath += num_str;
++    tpath += ".rgb";
++
++    if ( (splash_texbuf = 
++        read_rgb_texture(tpath.c_str(), &width, &height)) == NULL )
++    {
++      // Try compressed
++      fg_tpath = tpath + ".gz";
++      if ( (splash_texbuf = 
++            read_rgb_texture(fg_tpath.c_str(), &width, &height)) == NULL )
++      {
++          FG_LOG( FG_GENERAL, FG_ALERT, 
++                  "Error in loading splash screen texture " << tpath );
++          exit(-1);
++      } 
++    } 
++
++    xglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, 
++                 GL_UNSIGNED_BYTE, (GLvoid *)(splash_texbuf) );
++}
++
++
++// Update the splash screen with progress specified from 0.0 to 1.0
++void fgSplashUpdate ( double progress ) {
++    int xmin, ymin, xmax, ymax;
++    int xsize = 480;
++    int ysize = 380;
++
++    xmin = (current_view.get_winWidth() - xsize) / 2;
++    xmax = xmin + xsize;
++
++    ymin = (current_view.get_winHeight() - ysize) / 2;
++    ymax = ymin + ysize;
++
++    // first clear the screen;
++    xglClearColor(0.0, 0.0, 0.0, 1.0);
++    xglClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
++
++    // now draw the logo
++    xglMatrixMode(GL_PROJECTION);
++    xglPushMatrix();
++    xglLoadIdentity();
++    gluOrtho2D(0, current_view.get_winWidth(), 0, current_view.get_winHeight());
++    xglMatrixMode(GL_MODELVIEW);
++    xglPushMatrix();
++    xglLoadIdentity();
++
++    xglDisable(GL_DEPTH_TEST);
++    xglDisable(GL_LIGHTING);
++    xglEnable(GL_TEXTURE_2D);
++#ifdef GL_VERSION_1_1
++    xglBindTexture(GL_TEXTURE_2D, splash_texid);
++#elif GL_EXT_texture_object
++    xglBindTextureEXT(GL_TEXTURE_2D, splash_texid);
++#else
++#  error port me
++#endif
++    xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++
++    xglBegin(GL_POLYGON);
++    xglTexCoord2f(0.0, 0.0); glVertex2f(xmin, ymin);
++    xglTexCoord2f(1.0, 0.0); glVertex2f(xmax, ymin);
++    xglTexCoord2f(1.0, 1.0); glVertex2f(xmax, ymax);
++    xglTexCoord2f(0.0, 1.0); glVertex2f(xmin, ymax); 
++    xglEnd();
++
++    xglutSwapBuffers();
++
++    xglEnable(GL_DEPTH_TEST);
++    xglEnable(GL_LIGHTING);
++    xglDisable(GL_TEXTURE_2D);
++
++    xglMatrixMode(GL_PROJECTION);
++    xglPopMatrix();
++    xglMatrixMode(GL_MODELVIEW);
++    xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.10  1999/03/08 21:56:40  curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.9  1998/12/09 18:50:26  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.8  1998/11/16 14:00:05  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.7  1998/11/06 21:18:14  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.6  1998/10/17 01:34:25  curt
++// C++ ifying ...
++//
++// Revision 1.5  1998/09/26 13:17:29  curt
++// Clear screen to "black" before drawing splash screen.
++//
++// Revision 1.4  1998/08/27 17:02:08  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.3  1998/08/25 16:59:10  curt
++// Directory reshuffling.
++//
++// Revision 1.2  1998/07/13 21:01:40  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.1  1998/07/06 02:42:36  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1610dc37ab34abd2dea7d9fa35589b0f4f4338e3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,49 @@@
++// splash.hxx -- draws the initial splash screen
++//
++// Written by Curtis Olson, started July 1998.  (With a little looking
++// at Freidemann's panel code.) :-)
++//
++// Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _SPLASH_HXX
++#define _SPLASH_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// Initialize the splash screen
++void fgSplashInit ( void );
++
++// Update the splash screen with progress specified from 0.0 to 1.0
++void fgSplashUpdate ( double progress );
++
++
++#endif // _SPLASH_HXX
++
++
++// $Log$
++// Revision 1.1  1998/07/06 02:42:37  curt
++// Initial revision.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..57c059a3d8f12b327e3beddace69ece9cfb04018
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1223 @@@
++// views.cxx -- data structures and routines for managing and view
++//               parameters.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <Aircraft/aircraft.hxx>
++#include <Cockpit/panel.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_time.hxx>
++
++#include "options.hxx"
++#include "views.hxx"
++
++
++// Define following to extract various vectors directly
++// from matrices we have allready computed
++// rather then performing 'textbook algebra' to rederive them
++// Norman Vine -- nhv@yahoo.com
++// #define FG_VIEW_INLINE_OPTIMIZATIONS
++
++// temporary (hopefully) hack
++static int panel_hist = 0;
++
++
++// specify code paths ... these are done as variable rather than
++// #define's because down the road we may want to choose between them
++// on the fly for different flight models ... this way magic carpet
++// and external modes wouldn't need to recreate the LaRCsim matrices
++// themselves.
++
++static const bool use_larcsim_local_to_body = false;
++
++
++// This is a record containing current view parameters
++FGView current_view;
++
++
++// Constructor
++FGView::FGView( void ) {
++    MAT3identity(WORLD);
++}
++
++
++// Initialize a view structure
++void FGView::Init( void ) {
++    FG_LOG( FG_VIEW, FG_INFO, "Initializing View parameters" );
++
++    view_offset = 0.0;
++    goal_view_offset = 0.0;
++
++    winWidth = current_options.get_xsize();
++    winHeight = current_options.get_ysize();
++
++    if ( ! current_options.get_panel_status() ) {
++      current_view.set_win_ratio( (GLfloat) winWidth / (GLfloat) winHeight );
++    } else {
++      current_view.set_win_ratio( (GLfloat) winWidth / 
++                                  ((GLfloat) (winHeight)*0.4232) );
++    }
++
++    force_update_fov_math();
++}
++
++
++// Update the field of view coefficients
++void FGView::UpdateFOV( const fgOPTIONS& o ) {
++    double fov, theta_x, theta_y;
++
++    fov = o.get_fov();
++      
++    // printf("win_ratio = %.2f\n", win_ratio);
++    // calculate sin() and cos() of fov / 2 in X direction;
++    theta_x = (fov * win_ratio * DEG_TO_RAD) / 2.0;
++    // printf("theta_x = %.2f\n", theta_x);
++    sin_fov_x = sin(theta_x);
++    cos_fov_x = cos(theta_x);
++    slope_x =  -cos_fov_x / sin_fov_x;
++    // printf("slope_x = %.2f\n", slope_x);
++
++    // fov_x_clip and fov_y_clip convoluted algebraic simplification
++    // see code executed in tilemgr.cxx when USE_FAST_FOV_CLIP not
++    // defined Norman Vine -- nhv@yahoo.com
++#if defined( USE_FAST_FOV_CLIP )
++    fov_x_clip = slope_x*cos_fov_x - sin_fov_x;
++#endif // defined( USE_FAST_FOV_CLIP )
++
++    // calculate sin() and cos() of fov / 2 in Y direction;
++    theta_y = (fov * DEG_TO_RAD) / 2.0;
++    // printf("theta_y = %.2f\n", theta_y);
++    sin_fov_y = sin(theta_y);
++    cos_fov_y = cos(theta_y);
++    slope_y = cos_fov_y / sin_fov_y;
++    // printf("slope_y = %.2f\n", slope_y);
++
++#if defined( USE_FAST_FOV_CLIP )
++    fov_y_clip = -(slope_y*cos_fov_y + sin_fov_y);    
++#endif // defined( USE_FAST_FOV_CLIP )
++}
++
++
++// Basically, this is a modified version of the Mesa gluLookAt()
++// function that's been modified slightly so we can capture the
++// result before sending it off to OpenGL land.
++void FGView::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++                   GLdouble centerx, GLdouble centery, GLdouble centerz,
++                   GLdouble upx, GLdouble upy, GLdouble upz ) {
++    GLdouble *m;
++    GLdouble x[3], y[3], z[3];
++    GLdouble mag;
++
++    m = current_view.MODEL_VIEW;
++
++    /* Make rotation matrix */
++
++    /* Z vector */
++    z[0] = eyex - centerx;
++    z[1] = eyey - centery;
++    z[2] = eyez - centerz;
++    mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
++    if (mag) {  /* mpichler, 19950515 */
++      z[0] /= mag;
++      z[1] /= mag;
++      z[2] /= mag;
++    }
++
++    /* Y vector */
++    y[0] = upx;
++    y[1] = upy;
++    y[2] = upz;
++
++    /* X vector = Y cross Z */
++    x[0] =  y[1]*z[2] - y[2]*z[1];
++    x[1] = -y[0]*z[2] + y[2]*z[0];
++    x[2] =  y[0]*z[1] - y[1]*z[0];
++    
++    /* Recompute Y = Z cross X */
++    y[0] =  z[1]*x[2] - z[2]*x[1];
++    y[1] = -z[0]*x[2] + z[2]*x[0];
++    y[2] =  z[0]*x[1] - z[1]*x[0];
++
++    /* mpichler, 19950515 */
++    /* cross product gives area of parallelogram, which is < 1.0 for
++     * non-perpendicular unit-length vectors; so normalize x, y here
++     */
++
++    mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
++    if (mag) {
++      x[0] /= mag;
++      x[1] /= mag;
++      x[2] /= mag;
++    }
++
++    mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
++    if (mag) {
++      y[0] /= mag;
++      y[1] /= mag;
++      y[2] /= mag;
++    }
++
++#define M(row,col)  m[col*4+row]
++    M(0,0) = x[0];  M(0,1) = x[1];  M(0,2) = x[2];  M(0,3) = 0.0;
++    M(1,0) = y[0];  M(1,1) = y[1];  M(1,2) = y[2];  M(1,3) = 0.0;
++    M(2,0) = z[0];  M(2,1) = z[1];  M(2,2) = z[2];  M(2,3) = 0.0;
++    // the following is part of the original gluLookAt(), but we are
++    // commenting it out because we know we are going to be doing a
++    // translation below which will set these values anyways
++    // M(3,0) = 0.0;   M(3,1) = 0.0;   M(3,2) = 0.0;   M(3,3) = 1.0;
++#undef M
++
++    // Translate Eye to Origin
++    // replaces: glTranslated( -eyex, -eyey, -eyez );
++
++    // this has been slightly modified from the original glTranslate()
++    // code because we know that coming into this m[12] = m[13] =
++    // m[14] = 0.0, and m[15] = 1.0;
++    m[12] = m[0] * -eyex + m[4] * -eyey + m[8]  * -eyez /* + m[12] */;
++    m[13] = m[1] * -eyex + m[5] * -eyey + m[9]  * -eyez /* + m[13] */;
++    m[14] = m[2] * -eyex + m[6] * -eyey + m[10] * -eyez /* + m[14] */;
++    m[15] = 1.0 /* m[3] * -eyex + m[7] * -eyey + m[11] * -eyez + m[15] */;
++
++    // xglMultMatrixd( m );
++    xglLoadMatrixd( m );
++}
++
++
++// Update the view volume, position, and orientation
++void FGView::UpdateViewParams( void ) {
++    FGInterface *f = current_aircraft.fdm_state;
++
++    UpdateViewMath(f);
++    UpdateWorldToEye(f);
++    
++    if ((current_options.get_panel_status() != panel_hist) &&                          (current_options.get_panel_status()))
++    {
++      FGPanel::OurPanel->ReInit( 0, 0, 1024, 768);
++    }
++
++    if ( ! current_options.get_panel_status() ) {
++      xglViewport(0, 0 , (GLint)(winWidth), (GLint)(winHeight) );
++    } else {
++      xglViewport(0, (GLint)((winHeight)*0.5768), (GLint)(winWidth), 
++                    (GLint)((winHeight)*0.4232) );
++    }
++
++    // Tell GL we are about to modify the projection parameters
++    xglMatrixMode(GL_PROJECTION);
++    xglLoadIdentity();
++    if ( f->get_Altitude() * FEET_TO_METER - scenery.cur_elev > 10.0 ) {
++      gluPerspective(current_options.get_fov(), win_ratio, 10.0, 100000.0);
++    } else {
++      gluPerspective(current_options.get_fov(), win_ratio, 0.5, 100000.0);
++      // printf("Near ground, minimizing near clip plane\n");
++    }
++    // }
++
++    xglMatrixMode(GL_MODELVIEW);
++    xglLoadIdentity();
++    
++    // set up our view volume (default)
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++    LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++         view_pos.x() + view_forward[0], 
++         view_pos.y() + view_forward[1], 
++         view_pos.z() + view_forward[2],
++         view_up[0], view_up[1], view_up[2]);
++
++    // look almost straight up (testing and eclipse watching)
++    /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++       view_pos.x() + view_up[0] + .001, 
++       view_pos.y() + view_up[1] + .001, 
++       view_pos.z() + view_up[2] + .001,
++       view_up[0], view_up[1], view_up[2]); */
++
++    // lock view horizontally towards sun (testing)
++    /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++       view_pos.x() + surface_to_sun[0], 
++       view_pos.y() + surface_to_sun[1], 
++       view_pos.z() + surface_to_sun[2],
++       view_up[0], view_up[1], view_up[2]); */
++
++    // lock view horizontally towards south (testing)
++    /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++       view_pos.x() + surface_south[0], 
++       view_pos.y() + surface_south[1], 
++       view_pos.z() + surface_south[2],
++       view_up[0], view_up[1], view_up[2]); */
++
++#else // defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++    //void FGView::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++    //                     GLdouble centerx, GLdouble centery, GLdouble centerz,
++    //                     GLdouble upx, GLdouble upy, GLdouble upz )
++    {
++      GLdouble *m;
++      GLdouble x[3], y[3], z[3];
++      //    GLdouble mag;
++
++      m = current_view.MODEL_VIEW;
++
++      /* Make rotation matrix */
++
++      /* Z vector */
++      z[0] = -view_forward[0]; //eyex - centerx;
++      z[1] = -view_forward[1]; //eyey - centery;
++      z[2] = -view_forward[2]; //eyez - centerz;
++      
++      // In our case this is a unit vector  NHV
++      
++      //    mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
++      //    if (mag) {  /* mpichler, 19950515 */
++      //              mag = 1.0/mag;
++      //              printf("mag(%f)  ", mag);
++      //      z[0] *= mag;
++      //      z[1] *= mag;
++      //      z[2] *= mag;
++      //    }
++
++      /* Y vector */
++      y[0] = view_up[0]; //upx;
++      y[1] = view_up[1]; //upy;
++      y[2] = view_up[2]; //upz;
++
++      /* X vector = Y cross Z */
++      x[0] =  y[1]*z[2] - y[2]*z[1];
++      x[1] = -y[0]*z[2] + y[2]*z[0];
++      x[2] =  y[0]*z[1] - y[1]*z[0];
++
++      //      printf(" %f %f %f  ", y[0], y[1], y[2]);
++    
++      /* Recompute Y = Z cross X */
++      //    y[0] =  z[1]*x[2] - z[2]*x[1];
++      //    y[1] = -z[0]*x[2] + z[2]*x[0];
++      //    y[2] =  z[0]*x[1] - z[1]*x[0];
++
++      //      printf(" %f %f %f\n", y[0], y[1], y[2]);
++      
++      // In our case these are unit vectors  NHV
++
++      /* mpichler, 19950515 */
++      /* cross product gives area of parallelogram, which is < 1.0 for
++       * non-perpendicular unit-length vectors; so normalize x, y here
++       */
++
++      //    mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
++      //    if (mag) {
++      //              mag = 1.0/mag;
++      //              printf("mag2(%f) ", mag);
++      //      x[0] *= mag;
++      //      x[1] *= mag;
++      //      x[2] *= mag;
++      //    }
++
++      //    mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
++      //    if (mag) {
++      //              mag = 1.0/mag;
++      //              printf("mag3(%f)\n", mag);
++      //      y[0] *= mag;
++      //      y[1] *= mag;
++      //      y[2] *= mag;
++      //    }
++
++#define M(row,col)  m[col*4+row]
++      M(0,0) = x[0];  M(0,1) = x[1];  M(0,2) = x[2];  M(0,3) = 0.0;
++      M(1,0) = y[0];  M(1,1) = y[1];  M(1,2) = y[2];  M(1,3) = 0.0;
++      M(2,0) = z[0];  M(2,1) = z[1];  M(2,2) = z[2];  M(2,3) = 0.0;
++      // the following is part of the original gluLookAt(), but we are
++      // commenting it out because we know we are going to be doing a
++      // translation below which will set these values anyways
++      // M(3,0) = 0.0;   M(3,1) = 0.0;   M(3,2) = 0.0;   M(3,3) = 1.0;
++#undef M
++
++      // Translate Eye to Origin
++      // replaces: glTranslated( -eyex, -eyey, -eyez );
++
++      // this has been slightly modified from the original glTranslate()
++      // code because we know that coming into this m[12] = m[13] =
++      // m[14] = 0.0, and m[15] = 1.0;
++      m[12] = m[0] * -view_pos.x() + m[4] * -view_pos.y() + m[8]  * -view_pos.z() /* + m[12] */;
++      m[13] = m[1] * -view_pos.x() + m[5] * -view_pos.y() + m[9]  * -view_pos.z() /* + m[13] */;
++      m[14] = m[2] * -view_pos.x() + m[6] * -view_pos.y() + m[10] * -view_pos.z() /* + m[14] */;
++      m[15] = 1.0 /* m[3] * -view_pos.x() + m[7] * -view_pos.y() + m[11] * -view_pos.z() + m[15] */;
++
++      // xglMultMatrixd( m );
++      xglLoadMatrixd( m );
++    }
++#endif // FG_VIEW_INLINE_OPTIMIZATIONS
++      
++
++    panel_hist = current_options.get_panel_status();
++}
++
++
++void getRotMatrix(double* out, MAT3vec vec, double radians)
++{
++    /* This function contributed by Erich Boleyn (erich@uruk.org) */
++    /* This function used from the Mesa OpenGL code (matrix.c)  */
++    double s, c; // mag,
++    double vx, vy, vz, xy, yz, zx, xs, ys, zs, one_c; //, xx, yy, zz
++  
++    MAT3identity(out);
++    s = sin(radians);
++    c = cos(radians);
++  
++    //  mag = getMagnitude();
++  
++    vx = vec[0];
++    vy = vec[1];
++    vz = vec[2];
++  
++#define M(row,col)  out[row*4 + col]
++  
++    /*
++     *     Arbitrary axis rotation matrix.
++     *
++     *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
++     *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
++     *  (which is about the X-axis), and the two composite transforms
++     *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
++     *  from the arbitrary axis to the X-axis then back.  They are
++     *  all elementary rotations.
++     *
++     *  Rz' is a rotation about the Z-axis, to bring the axis vector
++     *  into the x-z plane.  Then Ry' is applied, rotating about the
++     *  Y-axis to bring the axis vector parallel with the X-axis.  The
++     *  rotation about the X-axis is then performed.  Ry and Rz are
++     *  simply the respective inverse transforms to bring the arbitrary
++     *  axis back to it's original orientation.  The first transforms
++     *  Rz' and Ry' are considered inverses, since the data from the
++     *  arbitrary axis gives you info on how to get to it, not how
++     *  to get away from it, and an inverse must be applied.
++     *
++     *  The basic calculation used is to recognize that the arbitrary
++     *  axis vector (x, y, z), since it is of unit length, actually
++     *  represents the sines and cosines of the angles to rotate the
++     *  X-axis to the same orientation, with theta being the angle about
++     *  Z and phi the angle about Y (in the order described above)
++     *  as follows:
++     *
++     *  cos ( theta ) = x / sqrt ( 1 - z^2 )
++     *  sin ( theta ) = y / sqrt ( 1 - z^2 )
++     *
++     *  cos ( phi ) = sqrt ( 1 - z^2 )
++     *  sin ( phi ) = z
++     *
++     *  Note that cos ( phi ) can further be inserted to the above
++     *  formulas:
++     *
++     *  cos ( theta ) = x / cos ( phi )
++     *  sin ( theta ) = y / cos ( phi )
++     *
++     *  ...etc.  Because of those relations and the standard trigonometric
++     *  relations, it is pssible to reduce the transforms down to what
++     *  is used below.  It may be that any primary axis chosen will give the
++     *  same results (modulo a sign convention) using thie method.
++     *
++     *  Particularly nice is to notice that all divisions that might
++     *  have caused trouble when parallel to certain planes or
++     *  axis go away with care paid to reducing the expressions.
++     *  After checking, it does perform correctly under all cases, since
++     *  in all the cases of division where the denominator would have
++     *  been zero, the numerator would have been zero as well, giving
++     *  the expected result.
++     */
++    
++    one_c = 1.0F - c;
++    
++    //  xx = vx * vx;
++    //  yy = vy * vy;
++    //  zz = vz * vz;
++  
++    //  xy = vx * vy;
++    //  yz = vy * vz;
++    //  zx = vz * vx;
++  
++  
++    M(0,0) = (one_c * vx * vx) + c;  
++    xs = vx * s;
++    yz = vy * vz * one_c;
++    M(1,2) = yz + xs;
++    M(2,1) = yz - xs;
++
++    M(1,1) = (one_c * vy * vy) + c;
++    ys = vy * s;
++    zx = vz * vx * one_c;
++    M(0,2) = zx - ys;
++    M(2,0) = zx + ys;
++  
++    M(2,2) = (one_c * vz *vz) + c;
++    zs = vz * s;
++    xy = vx * vy * one_c;
++    M(0,1) = xy + zs;
++    M(1,0) = xy - zs;
++  
++    //  M(0,0) = (one_c * xx) + c;
++    //  M(1,0) = (one_c * xy) - zs;
++    //  M(2,0) = (one_c * zx) + ys;
++  
++    //  M(0,1) = (one_c * xy) + zs;
++    //  M(1,1) = (one_c * yy) + c;
++    //  M(2,1) = (one_c * yz) - xs;
++  
++    //  M(0,2) = (one_c * zx) - ys;
++    //  M(1,2) = (one_c * yz) + xs;
++    //  M(2,2) = (one_c * zz) + c;
++  
++#undef M
++}
++
++
++// Update the view parameters
++void FGView::UpdateViewMath( FGInterface *f ) {
++    Point3D p;
++    MAT3vec vec, forward, v0, minus_z;
++    MAT3mat R, TMP, UP, LOCAL, VIEW;
++    double ntmp;
++
++    if ( update_fov ) {
++      // printf("Updating fov\n");
++      UpdateFOV( current_options );
++      update_fov = false;
++    }
++              
++    scenery.center = scenery.next_center;
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++    // printf("scenery center = %.2f %.2f %.2f\n", scenery.center.x,
++    //        scenery.center.y, scenery.center.z);
++
++    // calculate the cartesion coords of the current lat/lon/0 elev
++    p = Point3D( f->get_Longitude(), 
++               f->get_Lat_geocentric(), 
++               f->get_Sea_level_radius() * FEET_TO_METER );
++
++    cur_zero_elev = fgPolarToCart3d(p) - scenery.center;
++
++    // calculate view position in current FG view coordinate system
++    // p.lon & p.lat are already defined earlier, p.radius was set to
++    // the sea level radius, so now we add in our altitude.
++    if ( f->get_Altitude() * FEET_TO_METER > 
++       (scenery.cur_elev + 0.5 * METER_TO_FEET) ) {
++      p.setz( p.radius() + f->get_Altitude() * FEET_TO_METER );
++    } else {
++      p.setz( p.radius() + scenery.cur_elev + 0.5 * METER_TO_FEET );
++    }
++
++    abs_view_pos = fgPolarToCart3d(p);
++      
++#else // FG_VIEW_INLINE_OPTIMIZATIONS
++      
++    double tmp_radius = f->get_Sea_level_radius() * FEET_TO_METER;
++    double tmp = f->get_cos_lat_geocentric() * tmp_radius;
++      
++    cur_zero_elev.setx(f->get_cos_longitude()*tmp - scenery.center.x());
++    cur_zero_elev.sety(f->get_sin_longitude()*tmp - scenery.center.y());
++    cur_zero_elev.setz(f->get_sin_lat_geocentric()*tmp_radius - scenery.center.z());
++
++    // calculate view position in current FG view coordinate system
++    // p.lon & p.lat are already defined earlier, p.radius was set to
++    // the sea level radius, so now we add in our altitude.
++    if ( f->get_Altitude() * FEET_TO_METER > 
++       (scenery.cur_elev + 0.5 * METER_TO_FEET) ) {
++      tmp_radius += f->get_Altitude() * FEET_TO_METER;
++    } else {
++      tmp_radius += scenery.cur_elev + 0.5 * METER_TO_FEET ;
++    }
++    tmp = f->get_cos_lat_geocentric() * tmp_radius;
++    abs_view_pos.setx(f->get_cos_longitude()*tmp);
++    abs_view_pos.sety(f->get_sin_longitude()*tmp);
++    abs_view_pos.setz(f->get_sin_lat_geocentric()*tmp_radius);
++      
++#endif // FG_VIEW_INLINE_OPTIMIZATIONS
++      
++    view_pos = abs_view_pos - scenery.center;
++
++    FG_LOG( FG_VIEW, FG_DEBUG, "Polar view pos = " << p );
++    FG_LOG( FG_VIEW, FG_DEBUG, "Absolute view pos = " << abs_view_pos );
++    FG_LOG( FG_VIEW, FG_DEBUG, "Relative view pos = " << view_pos );
++
++    // Derive the LOCAL aircraft rotation matrix (roll, pitch, yaw)
++    // from FG_T_local_to_body[3][3]
++
++    if ( use_larcsim_local_to_body ) {
++
++      // Question: Why is the LaRCsim matrix arranged so differently
++      // than the one we need???
++
++      // Answer (I think): The LaRCsim matrix is generated in a
++      // different reference frame than we've set up for our world
++
++      LOCAL[0][0] = f->get_T_local_to_body_33();
++      LOCAL[0][1] = -f->get_T_local_to_body_32();
++      LOCAL[0][2] = -f->get_T_local_to_body_31();
++      LOCAL[0][3] = 0.0;
++      LOCAL[1][0] = -f->get_T_local_to_body_23();
++      LOCAL[1][1] = f->get_T_local_to_body_22();
++      LOCAL[1][2] = f->get_T_local_to_body_21();
++      LOCAL[1][3] = 0.0;
++      LOCAL[2][0] = -f->get_T_local_to_body_13();
++      LOCAL[2][1] = f->get_T_local_to_body_12();
++      LOCAL[2][2] = f->get_T_local_to_body_11();
++      LOCAL[2][3] = 0.0;
++      LOCAL[3][0] = LOCAL[3][1] = LOCAL[3][2] = LOCAL[3][3] = 0.0;
++      LOCAL[3][3] = 1.0;
++
++      // printf("LaRCsim LOCAL matrix\n");
++      // MAT3print(LOCAL, stdout);
++
++    } else {
++
++      // code to calculate LOCAL matrix calculated from Phi, Theta, and
++      // Psi (roll, pitch, yaw) in case we aren't running LaRCsim as our
++      // flight model
++
++      MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++      MAT3rotate(R, vec, f->get_Phi());
++      /* printf("Roll matrix\n"); */
++      /* MAT3print(R, stdout); */
++
++      MAT3_SET_VEC(vec, 0.0, 1.0, 0.0);
++      /* MAT3mult_vec(vec, vec, R); */
++      MAT3rotate(TMP, vec, f->get_Theta());
++      /* printf("Pitch matrix\n"); */
++      /* MAT3print(TMP, stdout); */
++      MAT3mult(R, R, TMP);
++
++      MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
++      /* MAT3mult_vec(vec, vec, R); */
++      /* MAT3rotate(TMP, vec, FG_Psi - FG_PI_2); */
++      MAT3rotate(TMP, vec, -f->get_Psi());
++      /* printf("Yaw matrix\n");
++         MAT3print(TMP, stdout); */
++      MAT3mult(LOCAL, R, TMP);
++      // printf("FG derived LOCAL matrix\n");
++      // MAT3print(LOCAL, stdout);
++
++    } // if ( use_larcsim_local_to_body ) 
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++      
++    // Derive the local UP transformation matrix based on *geodetic*
++    // coordinates
++    MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++    MAT3rotate(R, vec, f->get_Longitude());     // R = rotate about Z axis
++    // printf("Longitude matrix\n");
++    // MAT3print(R, stdout);
++
++    MAT3_SET_VEC(vec, 0.0, 1.0, 0.0);
++    MAT3mult_vec(vec, vec, R);
++    MAT3rotate(TMP, vec, -f->get_Latitude());  // TMP = rotate about X axis
++    // printf("Latitude matrix\n");
++    // MAT3print(TMP, stdout);
++
++    MAT3mult(UP, R, TMP);
++    // printf("Local up matrix\n");
++    // MAT3print(UP, stdout);
++
++    MAT3_SET_VEC(local_up, 1.0, 0.0, 0.0);
++    MAT3mult_vec(local_up, local_up, UP);
++
++    // printf( "Local Up = (%.4f, %.4f, %.4f)\n",
++    //         local_up[0], local_up[1], local_up[2]);
++    
++    // Alternative method to Derive local up vector based on
++    // *geodetic* coordinates
++    // alt_up = fgPolarToCart(FG_Longitude, FG_Latitude, 1.0);
++    // printf( "    Alt Up = (%.4f, %.4f, %.4f)\n", 
++    //         alt_up.x, alt_up.y, alt_up.z);
++
++    // Calculate the VIEW matrix
++    MAT3mult(VIEW, LOCAL, UP);
++    // printf("VIEW matrix\n");
++    // MAT3print(VIEW, stdout);
++
++    // generate the current up, forward, and fwrd-view vectors
++    MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
++    MAT3mult_vec(view_up, vec, VIEW);
++
++    MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++    MAT3mult_vec(forward, vec, VIEW);
++    // printf( "Forward vector is (%.2f,%.2f,%.2f)\n", forward[0], forward[1], 
++    //         forward[2]);
++
++    MAT3rotate(TMP, view_up, view_offset);
++    MAT3mult_vec(view_forward, forward, TMP);
++
++    // make a vector to the current view position
++    MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++    // Given a vector pointing straight down (-Z), map into onto the
++    // local plane representing "horizontal".  This should give us the
++    // local direction for moving "south".
++    MAT3_SET_VEC(minus_z, 0.0, 0.0, -1.0);
++    map_vec_onto_cur_surface_plane(local_up, v0, minus_z, surface_south);
++    MAT3_NORMALIZE_VEC(surface_south, ntmp);
++    // printf( "Surface direction directly south %.2f %.2f %.2f\n",
++    //         surface_south[0], surface_south[1], surface_south[2]);
++
++    // now calculate the surface east vector
++    MAT3rotate(TMP, view_up, FG_PI_2);
++    MAT3mult_vec(surface_east, surface_south, TMP);
++    // printf( "Surface direction directly east %.2f %.2f %.2f\n",
++    //         surface_east[0], surface_east[1], surface_east[2]);
++    // printf( "Should be close to zero = %.2f\n", 
++    //         MAT3_DOT_PRODUCT(surface_south, surface_east));
++      
++#else // FG_VIEW_INLINE_OPTIMIZATIONS
++       
++    //        // Build spherical to cartesian transform matrix directly
++    double cos_lat = f->get_cos_latitude(); // cos(-f->get_Latitude());
++    double sin_lat = -f->get_sin_latitude(); // sin(-f->get_Latitude());
++    double cos_lon = f->get_cos_longitude(); //cos(f->get_Longitude());
++    double sin_lon = f->get_sin_longitude(); //sin(f->get_Longitude());
++
++    double *mat = (double *)UP;
++      
++    mat[0] =  cos_lat*cos_lon;
++    mat[1] =  cos_lat*sin_lon;
++    mat[2] = -sin_lat;
++    mat[3] =  0.0;
++    mat[4] =  -sin_lon;
++    mat[5] =  cos_lon;
++    mat[6] =  0.0;
++    mat[7] =  0.0;
++    mat[8]  =  sin_lat*cos_lon;
++    mat[9]  =  sin_lat*sin_lon;
++    mat[10] =  cos_lat;
++    mat[11] =  mat[12] = mat[13] = mat[14] = 0.0;
++    mat[15] =  1.0;
++
++    MAT3mult(VIEW, LOCAL, UP);
++      
++    // THESE COULD JUST BE POINTERS !!!
++    MAT3_SET_VEC(local_up, mat[0],     mat[1],     mat[2]);
++    MAT3_SET_VEC(view_up,  VIEW[0][0], VIEW[0][1], VIEW[0][2]);
++    MAT3_SET_VEC(forward,  VIEW[2][0], VIEW[2][1], VIEW[2][2]);
++
++    getRotMatrix((double *)TMP, view_up, view_offset);
++    MAT3mult_vec(view_forward, forward, TMP);
++
++    // make a vector to the current view position
++    MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++    // Given a vector pointing straight down (-Z), map into onto the
++    // local plane representing "horizontal".  This should give us the
++    // local direction for moving "south".
++    MAT3_SET_VEC(minus_z, 0.0, 0.0, -1.0);
++    map_vec_onto_cur_surface_plane(local_up, v0, minus_z, surface_south);
++
++    MAT3_NORMALIZE_VEC(surface_south, ntmp);
++    // printf( "Surface direction directly south %.6f %.6f %.6f\n",
++    //         surface_south[0], surface_south[1], surface_south[2]);
++
++    // now calculate the surface east vector
++    getRotMatrix((double *)TMP, view_up, FG_PI_2);
++    MAT3mult_vec(surface_east, surface_south, TMP);
++    // printf( "Surface direction directly east %.6f %.6f %.6f\n",
++    //         surface_east[0], surface_east[1], surface_east[2]);
++    // printf( "Should be close to zero = %.6f\n", 
++    //         MAT3_DOT_PRODUCT(surface_south, surface_east));
++#endif // !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++}
++
++
++// Update the "World to Eye" transformation matrix
++// This is most useful for view frustum culling
++void FGView::UpdateWorldToEye( FGInterface *f ) {
++    MAT3mat R_Phi, R_Theta, R_Psi, R_Lat, R_Lon, T_view;
++    MAT3mat TMP;
++    MAT3hvec vec;
++
++    if ( use_larcsim_local_to_body ) {
++
++      // Question: hey this is even different then LOCAL[][] above??
++      // Answer: yet another coordinate system, this time the
++      // coordinate system in which we do our view frustum culling.
++
++      AIRCRAFT[0][0] = -f->get_T_local_to_body_22();
++      AIRCRAFT[0][1] = -f->get_T_local_to_body_23();
++      AIRCRAFT[0][2] = f->get_T_local_to_body_21();
++      AIRCRAFT[0][3] = 0.0;
++      AIRCRAFT[1][0] = f->get_T_local_to_body_32();
++      AIRCRAFT[1][1] = f->get_T_local_to_body_33();
++      AIRCRAFT[1][2] = -f->get_T_local_to_body_31();
++      AIRCRAFT[1][3] = 0.0;
++      AIRCRAFT[2][0] = f->get_T_local_to_body_12();
++      AIRCRAFT[2][1] = f->get_T_local_to_body_13();
++      AIRCRAFT[2][2] = -f->get_T_local_to_body_11();
++      AIRCRAFT[2][3] = 0.0;
++      AIRCRAFT[3][0] = AIRCRAFT[3][1] = AIRCRAFT[3][2] = AIRCRAFT[3][3] = 0.0;
++      AIRCRAFT[3][3] = 1.0;
++
++    } else {
++
++      // Roll Matrix
++      MAT3_SET_HVEC(vec, 0.0, 0.0, -1.0, 1.0);
++      MAT3rotate(R_Phi, vec, f->get_Phi());
++      // printf("Roll matrix (Phi)\n");
++      // MAT3print(R_Phi, stdout);
++
++      // Pitch Matrix
++      MAT3_SET_HVEC(vec, 1.0, 0.0, 0.0, 1.0);
++      MAT3rotate(R_Theta, vec, f->get_Theta());
++      // printf("\nPitch matrix (Theta)\n");
++      // MAT3print(R_Theta, stdout);
++
++      // Yaw Matrix
++      MAT3_SET_HVEC(vec, 0.0, -1.0, 0.0, 1.0);
++      MAT3rotate(R_Psi, vec, f->get_Psi() + FG_PI /* - view_offset */ );
++      // MAT3rotate(R_Psi, vec, f->get_Psi() + FG_PI - view_offset );
++      // printf("\nYaw matrix (Psi)\n");
++      // MAT3print(R_Psi, stdout);
++
++      // aircraft roll/pitch/yaw
++      MAT3mult(TMP, R_Phi, R_Theta);
++      MAT3mult(AIRCRAFT, TMP, R_Psi);
++
++    } // if ( use_larcsim_local_to_body )
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++      
++    // printf("AIRCRAFT matrix\n");
++    // MAT3print(AIRCRAFT, stdout);
++
++    // View rotation matrix relative to current aircraft orientation
++    MAT3_SET_HVEC(vec, 0.0, -1.0, 0.0, 1.0);
++    MAT3mult_vec(vec, vec, AIRCRAFT);
++    // printf("aircraft up vector = %.2f %.2f %.2f\n", 
++    //        vec[0], vec[1], vec[2]);
++    MAT3rotate(TMP, vec, -view_offset );
++    MAT3mult(VIEW_OFFSET, AIRCRAFT, TMP);
++    // printf("VIEW_OFFSET matrix\n");
++    // MAT3print(VIEW_OFFSET, stdout);
++
++    // View position in scenery centered coordinates
++    MAT3_SET_HVEC(vec, view_pos.x(), view_pos.y(), view_pos.z(), 1.0);
++    MAT3translate(T_view, vec);
++    // printf("\nTranslation matrix\n");
++    // MAT3print(T_view, stdout);
++
++    // Latitude
++    MAT3_SET_HVEC(vec, 1.0, 0.0, 0.0, 1.0);
++    // R_Lat = rotate about X axis
++    MAT3rotate(R_Lat, vec, f->get_Latitude());
++    // printf("\nLatitude matrix\n");
++    // MAT3print(R_Lat, stdout);
++
++    // Longitude
++    MAT3_SET_HVEC(vec, 0.0, 0.0, 1.0, 1.0);
++    // R_Lon = rotate about Z axis
++    MAT3rotate(R_Lon, vec, f->get_Longitude() - FG_PI_2 );
++    // printf("\nLongitude matrix\n");
++    // MAT3print(R_Lon, stdout);
++
++    // lon/lat
++    MAT3mult(WORLD, R_Lat, R_Lon);
++    // printf("\nworld\n");
++    // MAT3print(WORLD, stdout);
++
++    MAT3mult(EYE_TO_WORLD, VIEW_OFFSET, WORLD);
++    MAT3mult(EYE_TO_WORLD, EYE_TO_WORLD, T_view);
++    // printf("\nEye to world\n");
++    // MAT3print(EYE_TO_WORLD, stdout);
++
++    MAT3invert(WORLD_TO_EYE, EYE_TO_WORLD);
++    // printf("\nWorld to eye\n");
++    // MAT3print(WORLD_TO_EYE, stdout);
++
++    // printf( "\nview_pos = %.2f %.2f %.2f\n", 
++    //         view_pos.x, view_pos.y, view_pos.z );
++
++    // MAT3_SET_HVEC(eye, 0.0, 0.0, 0.0, 1.0);
++    // MAT3mult_vec(vec, eye, EYE_TO_WORLD);
++    // printf("\neye -> world = %.2f %.2f %.2f\n", vec[0], vec[1], vec[2]);
++
++    // MAT3_SET_HVEC(vec1, view_pos.x, view_pos.y, view_pos.z, 1.0);
++    // MAT3mult_vec(vec, vec1, WORLD_TO_EYE);
++    // printf( "\nabs_view_pos -> eye = %.2f %.2f %.2f\n", 
++    //         vec[0], vec[1], vec[2]);
++#else  // FG_VIEW_INLINE_OPTIMIZATIONS
++      
++    MAT3_SET_HVEC(vec, -AIRCRAFT[1][0], -AIRCRAFT[1][1], -AIRCRAFT[1][2], -AIRCRAFT[1][3]);
++    getRotMatrix((double *)TMP, vec, -view_offset );
++    MAT3mult(VIEW_OFFSET, AIRCRAFT, TMP);
++    // MAT3print_formatted(VIEW_OFFSET, stdout, "VIEW_OFFSET matrix:\n",
++    //                                         NULL, "%#8.6f  ", "\n");
++
++    // Build spherical to cartesian transform matrix directly
++    double *mat = (double *)WORLD; //T_view; //WORLD;
++    double cos_lat = f->get_cos_latitude(); //cos(f->get_Latitude());
++    double sin_lat = f->get_sin_latitude(); //sin(f->get_Latitude());
++    // using trig identities  this:
++    //        mat[0]  =  cos(f->get_Longitude() - FG_PI_2);//cos_lon;
++    //        mat[1]  =  sin(f->get_Longitude() - FG_PI_2);//sin_lon;
++    // becomes this: :-)
++    mat[0]  =  f->get_sin_longitude(); //cos_lon;
++    mat[1]  = -f->get_cos_longitude(); //sin_lon;
++    mat[4]  = -cos_lat*mat[1]; //mat[1]=sin_lon;
++    mat[5]  =  cos_lat*mat[0]; //mat[0]=cos_lon;
++    mat[6]  =  sin_lat;
++    mat[8]  =  sin_lat*mat[1]; //mat[1]=sin_lon;
++    mat[9]  = -sin_lat*mat[0]; //mat[0]=cos_lon;
++    mat[10] =  cos_lat;
++
++    // BUILD EYE_TO_WORLD = AIRCRAFT * WORLD
++    // and WORLD_TO_EYE = Inverse( EYE_TO_WORLD) concurrently
++    // by Transposing the 3x3 rotation sub-matrix
++    WORLD_TO_EYE[0][0] = EYE_TO_WORLD[0][0] =
++      VIEW_OFFSET[0][0]*mat[0] + VIEW_OFFSET[0][1]*mat[4] + VIEW_OFFSET[0][2]*mat[8];
++      
++    WORLD_TO_EYE[1][0] = EYE_TO_WORLD[0][1] =
++      VIEW_OFFSET[0][0]*mat[1] + VIEW_OFFSET[0][1]*mat[5] + VIEW_OFFSET[0][2]*mat[9];
++      
++    WORLD_TO_EYE[2][0] = EYE_TO_WORLD[0][2] =
++      VIEW_OFFSET[0][1]*mat[6] + VIEW_OFFSET[0][2]*mat[10];
++      
++    WORLD_TO_EYE[0][1] = EYE_TO_WORLD[1][0] =
++      VIEW_OFFSET[1][0]*mat[0] + VIEW_OFFSET[1][1]*mat[4] + VIEW_OFFSET[1][2]*mat[8];
++      
++    WORLD_TO_EYE[1][1] = EYE_TO_WORLD[1][1] =
++      VIEW_OFFSET[1][0]*mat[1] + VIEW_OFFSET[1][1]*mat[5] + VIEW_OFFSET[1][2]*mat[9];
++      
++    WORLD_TO_EYE[2][1] = EYE_TO_WORLD[1][2] =
++      VIEW_OFFSET[1][1]*mat[6] + VIEW_OFFSET[1][2]*mat[10];
++      
++    WORLD_TO_EYE[0][2] = EYE_TO_WORLD[2][0] =
++      VIEW_OFFSET[2][0]*mat[0] + VIEW_OFFSET[2][1]*mat[4] + VIEW_OFFSET[2][2]*mat[8];
++      
++    WORLD_TO_EYE[1][2] = EYE_TO_WORLD[2][1] =
++      VIEW_OFFSET[2][0]*mat[1] + VIEW_OFFSET[2][1]*mat[5] + VIEW_OFFSET[2][2]*mat[9];
++      
++    WORLD_TO_EYE[2][2] = EYE_TO_WORLD[2][2] =
++      VIEW_OFFSET[2][1]*mat[6] + VIEW_OFFSET[2][2]*mat[10];
++      
++    // TRANSLATE TO VIEW POSITION
++    EYE_TO_WORLD[3][0] = view_pos.x();
++    EYE_TO_WORLD[3][1] = view_pos.y();
++    EYE_TO_WORLD[3][2] = view_pos.z();
++      
++    // FILL 0 ENTRIES
++    WORLD_TO_EYE[0][3] = WORLD_TO_EYE[1][3] = WORLD_TO_EYE[2][3] = 
++      EYE_TO_WORLD[0][3] = EYE_TO_WORLD[1][3] = EYE_TO_WORLD[2][3] = 0.0;
++
++    // FILL UNITY ENTRIES
++    WORLD_TO_EYE[3][3] = EYE_TO_WORLD[3][3] = 1.0;
++      
++    /* MAKE THE INVERTED TRANSLATIONS */
++    mat = (double *)EYE_TO_WORLD;
++    WORLD_TO_EYE[3][0] = -mat[12]*mat[0]
++      -mat[13]*mat[1]
++      -mat[14]*mat[2];
++      
++    WORLD_TO_EYE[3][1] = -mat[12]*mat[4]
++      -mat[13]*mat[5]
++      -mat[14]*mat[6];
++      
++    WORLD_TO_EYE[3][2] = -mat[12]*mat[8]
++      -mat[13]*mat[9]
++      -mat[14]*mat[10];
++      
++    // MAT3print_formatted(EYE_TO_WORLD, stdout, "EYE_TO_WORLD matrix:\n",
++    //                                         NULL, "%#8.6f  ", "\n");
++
++    // MAT3print_formatted(WORLD_TO_EYE, stdout, "WORLD_TO_EYE matrix:\n",
++    //                                         NULL, "%#8.6f  ", "\n");
++
++#endif // defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++}
++
++
++#if 0
++// Reject non viewable spheres from current View Frustrum by Curt
++// Olson curt@me.umn.edu and Norman Vine nhv@yahoo.com with 'gentle
++// guidance' from Steve Baker sbaker@link.com
++int
++FGView::SphereClip( const Point3D& cp, const double radius )
++{
++    double x1, y1;
++
++    MAT3vec eye;      
++    double *mat;
++    double x, y, z;
++
++    x = cp->x;
++    y = cp->y;
++    z = cp->z;
++      
++    mat = (double *)(WORLD_TO_EYE);
++      
++    eye[2] =  x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
++      
++    // Check near and far clip plane
++    if( ( eye[2] > radius ) ||
++      ( eye[2] + radius + current_weather.visibility < 0) )
++      // ( eye[2] + radius + far_plane < 0) )
++    {
++      return 1;
++    }
++      
++    // check right and left clip plane (from eye perspective)
++    x1 = radius * fov_x_clip;
++    eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12]) * slope_x;
++    if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) ) {
++      return(1);
++    }
++      
++    // check bottom and top clip plane (from eye perspective)
++    y1 = radius * fov_y_clip;
++    eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13]) * slope_y; 
++    if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) ) {
++      return 1;
++    }
++
++    return 0;
++}
++#endif
++
++
++// Destructor
++FGView::~FGView( void ) {
++}
++
++
++// $Log$
++// Revision 1.35  1999/04/03 04:21:04  curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.34  1999/03/08 21:56:41  curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.33  1999/02/05 21:29:14  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.32  1999/01/07 20:25:12  curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.31  1998/12/11 20:26:28  curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.30  1998/12/09 18:50:28  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.29  1998/12/05 15:54:24  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.28  1998/12/03 01:17:20  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.27  1998/11/16 14:00:06  curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.26  1998/11/09 23:39:25  curt
++// Tweaks for the instrument panel.
++//
++// Revision 1.25  1998/11/06 21:18:15  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.24  1998/10/18 01:17:19  curt
++// Point3D tweaks.
++//
++// Revision 1.23  1998/10/17 01:34:26  curt
++// C++ ifying ...
++//
++// Revision 1.22  1998/10/16 00:54:03  curt
++// Converted to Point3D class.
++//
++// Revision 1.21  1998/09/17 18:35:33  curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.20  1998/09/08 15:04:35  curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.19  1998/08/20 20:32:34  curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.18  1998/07/24 21:57:02  curt
++// Set near clip plane to 0.5 meters when close to the ground.  Also, let the view get a bit closer to the ground before hitting the hard limit.
++//
++// Revision 1.17  1998/07/24 21:39:12  curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.16  1998/07/13 21:01:41  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15  1998/07/12 03:14:43  curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++//   and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++//   ground.
++// Did some serious horsing around getting the initial airplane position to be
++//   correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++//   dropping below the terrain, even when the flight model doesn't quite
++//   put you as high as you'd like.
++//
++// Revision 1.14  1998/07/08 14:45:08  curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++//   /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.13  1998/07/04 00:52:27  curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.)  But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card.  This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.12  1998/06/03 00:47:15  curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.11  1998/05/27 02:24:05  curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.10  1998/05/17 16:59:03  curt
++// First pass at view frustum culling now operational.
++//
++// Revision 1.9  1998/05/16 13:08:37  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.8  1998/05/02 01:51:01  curt
++// Updated polartocart conversion routine.
++//
++// Revision 1.7  1998/04/30 12:34:20  curt
++// Added command line rendering options:
++//   enable/disable fog/haze
++//   specify smooth/flat shading
++//   disable sky blending and just use a solid color
++//   enable wireframe drawing mode
++//
++// Revision 1.6  1998/04/28 01:20:23  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.5  1998/04/26 05:10:04  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4  1998/04/25 22:04:53  curt
++// Use already calculated LaRCsim values to create the roll/pitch/yaw
++// transformation matrix (we call it LOCAL)
++//
++// Revision 1.3  1998/04/25 20:24:02  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2  1998/04/24 00:49:22  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1  1998/04/22 13:25:45  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.16  1998/04/18 04:11:29  curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.15  1998/02/20 00:16:24  curt
++// Thursday's tweaks.
++//
++// Revision 1.14  1998/02/09 15:07:50  curt
++// Minor tweaks.
++//
++// Revision 1.13  1998/02/07 15:29:45  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12  1998/01/29 00:50:28  curt
++// Added a view record field for absolute x, y, z position.
++//
++// Revision 1.11  1998/01/27 00:47:58  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.10  1998/01/19 19:27:09  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.9  1998/01/13 00:23:09  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.8  1997/12/30 22:22:33  curt
++// Further integration of event manager.
++//
++// Revision 1.7  1997/12/30 20:47:45  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.6  1997/12/22 04:14:32  curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.5  1997/12/18 04:07:02  curt
++// Worked on properly translating and positioning the sky dome.
++//
++// Revision 1.4  1997/12/17 23:13:36  curt
++// Began working on rendering a sky.
++//
++// Revision 1.3  1997/12/15 23:54:50  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2  1997/12/10 22:37:48  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1  1997/08/27 21:31:17  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1de311f694c0e31d6d095ee774321a9038a17d85
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,412 @@@
++// views.hxx -- data structures and routines for managing and view parameters.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _VIEWS_HXX
++#define _VIEWS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <FDM/flight.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Time/fg_time.hxx>
++#include <Time/light.hxx>
++
++#include "options.hxx"
++
++
++// used in views.cxx and tilemgr.cxx
++#define USE_FAST_FOV_CLIP 
++
++
++// Define a structure containing view information
++class FGView {
++
++public:
++
++    // the current offset from forward for viewing
++    double view_offset;
++
++    // the goal view offset for viewing (used for smooth view changes)
++    double goal_view_offset;
++
++    // flag forcing update of fov related stuff
++    bool update_fov;
++      
++    // fov of view is specified in the y direction, win_ratio is used to
++    // calculate the fov in the X direction = width/height
++    double win_ratio;
++
++    // width & height of window
++    int winWidth, winHeight;
++
++    // sin and cos of (fov / 2) in Y axis
++    double sin_fov_y, cos_fov_y;
++    double sinlon, coslon;
++
++    // slope of view frustum edge in eye space Y axis
++    double slope_y;
++
++    // sin and cos of (fov / 2) in X axis
++    double sin_fov_x, cos_fov_x;
++
++    // slope of view frustum edge in eye space X axis
++    double slope_x;
++
++#if defined( USE_FAST_FOV_CLIP )
++    double fov_x_clip, fov_y_clip;
++#endif // USE_FAST_FOV_CLIP
++
++    // View frustum cull ratio (% of tiles culled ... used for
++    // reporting purposes)
++    double vfc_ratio;
++
++    // Number of triangles rendered;
++    int tris_rendered;
++    int tris_culled;
++
++    // absolute view position
++    Point3D abs_view_pos;
++
++    // view position translated to scenery.center
++    Point3D view_pos;
++
++    // cartesion coordinates of current lon/lat if at sea level
++    // translated to scenery.center*/
++    Point3D cur_zero_elev;
++
++    // vector in cartesian coordinates from current position to the
++    // postion on the earth's surface the sun is directly over
++    MAT3vec to_sun;
++    
++    // surface direction to go to head towards sun
++    MAT3vec surface_to_sun;
++
++    // vector in cartesian coordinates from current position to the
++    // postion on the earth's surface the moon is directly over
++    MAT3vec to_moon;
++  
++    // surface direction to go to head towards moon
++    MAT3vec surface_to_moon;
++
++    // surface vector heading south
++    MAT3vec surface_south;
++
++    // surface vector heading east (used to unambiguously align sky
++    // with sun)
++    MAT3vec surface_east;
++
++    // local up vector (normal to the plane tangent to the earth's
++    // surface at the spot we are directly above
++    MAT3vec local_up;
++
++    // up vector for the view (usually point straight up through the
++    // top of the aircraft
++    MAT3vec view_up;
++
++    // the vector pointing straight out the nose of the aircraft
++    MAT3vec view_forward;
++
++    // Transformation matrix for eye coordinates to aircraft coordinates
++    MAT3mat AIRCRAFT;
++
++    // Transformation matrix for the view direction offset relative to
++    // the AIRCRAFT matrix
++    MAT3mat VIEW_OFFSET;
++
++    // Transformation matrix for aircraft coordinates to world
++    // coordinates
++    MAT3mat WORLD;
++
++    // Combined transformation from eye coordinates to world coordinates
++    MAT3mat EYE_TO_WORLD;
++
++    // Inverse of EYE_TO_WORLD which is a transformation from world
++    // coordinates to eye coordinates
++    MAT3mat WORLD_TO_EYE;
++
++    // Current model view matrix;
++    GLdouble MODEL_VIEW[16];
++
++public:
++
++    // Constructor
++    FGView( void );
++
++    // Destructor
++    ~FGView( void );
++
++    // Initialize a view class
++    void Init( void );
++
++    // Basically, this is a modified version of the Mesa gluLookAt()
++    // function that's been modified slightly so we can capture the
++    // result (and use it later) otherwise this all gets calculated in
++    // OpenGL land and we don't have access to the results.
++    void LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++               GLdouble centerx, GLdouble centery, GLdouble centerz,
++               GLdouble upx, GLdouble upy, GLdouble upz );
++
++    // Update the view volume, position, and orientation
++    void UpdateViewParams( void );
++
++    // Flag to request that UpdateFOV() be called next time
++    // UpdateViewMath() is run.
++    inline void force_update_fov_math() { update_fov = true; }
++
++    // Update the view parameters
++    void UpdateViewMath( FGInterface *f );
++
++    // Update the "World to Eye" transformation matrix
++    void UpdateWorldToEye( FGInterface *f );
++
++    // Update the field of view coefficients
++    void UpdateFOV( const fgOPTIONS& o );
++
++    // accessor functions
++    inline double get_view_offset() const { return view_offset; }
++    inline void set_view_offset( double a ) { view_offset = a; }
++    inline void inc_view_offset( double amt ) { view_offset += amt; }
++    inline double get_goal_view_offset() const { return goal_view_offset; }
++    inline void set_goal_view_offset( double a) { goal_view_offset = a; }
++    inline double get_win_ratio() const { return win_ratio; }
++    inline void set_win_ratio( double r ) { win_ratio = r; }
++    inline int get_winWidth() const { return winWidth; }
++    inline void set_winWidth( int w ) { winWidth = w; }
++    inline int get_winHeight() const { return winHeight; }
++    inline void set_winHeight( int h ) { winHeight = h; }
++    inline double get_slope_y() const { return slope_y; }
++    inline double get_slope_x() const { return slope_x; }
++#if defined( USE_FAST_FOV_CLIP )
++    inline double get_fov_x_clip() const { return fov_x_clip; }
++    inline double get_fov_y_clip() const { return fov_y_clip; }
++#endif // USE_FAST_FOV_CLIP
++    inline double get_vfc_ratio() const { return vfc_ratio; }
++    inline void set_vfc_ratio(double r) { vfc_ratio = r; }
++    inline int get_tris_rendered() const { return tris_rendered; }
++    inline void set_tris_rendered( int tris) { tris_rendered = tris; }
++    inline int get_tris_culled() const { return tris_culled; }
++    inline void set_tris_culled( int tris) { tris_culled = tris; }
++    inline Point3D get_abs_view_pos() const { return abs_view_pos; }
++    inline Point3D get_view_pos() const { return view_pos; }
++    inline Point3D get_cur_zero_elev() const { return cur_zero_elev; }
++    inline double *get_to_sun() { return to_sun; }
++    inline void set_to_sun( double x, double y, double z) {
++      to_sun[0] = x;
++      to_sun[1] = y;
++      to_sun[2] = z;
++    }
++    inline double *get_surface_to_sun() { return surface_to_sun; }
++    inline void set_surface_to_sun( double x, double y, double z) {
++      surface_to_sun[0] = x;
++      surface_to_sun[1] = y;
++      surface_to_sun[2] = z;
++    }
++    inline double *get_to_moon() { return to_moon; }
++    inline void set_to_moon( double x, double y, double z) {
++      to_moon[0] = x;
++      to_moon[1] = y;
++      to_moon[2] = z;
++    }
++    inline double *get_surface_to_moon() { return surface_to_moon; }
++    inline void set_surface_to_moon( double x, double y, double z) {
++      surface_to_moon[0] = x;
++      surface_to_moon[1] = y;
++      surface_to_moon[2] = z;
++    }
++    inline double *get_surface_south() { return surface_south; }
++    inline double *get_surface_east() { return surface_east; }
++    inline double *get_local_up() { return local_up; }
++    inline const MAT3mat *get_WORLD_TO_EYE() const { return &WORLD_TO_EYE; }
++    inline GLdouble *get_MODEL_VIEW() { return MODEL_VIEW; }
++};
++
++
++extern FGView current_view;
++
++
++#endif // _VIEWS_HXX
++
++
++// $Log$
++// Revision 1.23  1999/04/03 04:21:06  curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.22  1999/03/22 02:08:15  curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++//   some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++//   me earlier.
++//
++// Revision 1.21  1999/02/05 21:29:15  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.20  1999/02/02 20:13:38  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.19  1999/02/01 21:33:36  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.18  1998/12/11 20:26:30  curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.17  1998/12/09 18:50:29  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.16  1998/12/05 15:54:25  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.15  1998/10/16 23:27:56  curt
++// C++-ifying.
++//
++// Revision 1.14  1998/10/16 00:54:04  curt
++// Converted to Point3D class.
++//
++// Revision 1.13  1998/09/08 15:04:36  curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.12  1998/08/24 20:11:15  curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.11  1998/08/20 20:32:35  curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.10  1998/07/08 14:45:09  curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++//   /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.9  1998/07/04 00:52:27  curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.)  But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card.  This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.8  1998/05/27 02:24:06  curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.7  1998/05/17 16:59:04  curt
++// First pass at view frustum culling now operational.
++//
++// Revision 1.6  1998/05/16 13:08:37  curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++//   name.
++// Added a WORLD_TO_EYE transformation to views.cxx.  This allows us
++//  to transform world space to eye space for view frustum culling.
++//
++// Revision 1.5  1998/05/02 01:51:02  curt
++// Updated polartocart conversion routine.
++//
++// Revision 1.4  1998/04/28 01:20:24  curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.3  1998/04/25 22:06:31  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:49:22  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1  1998/04/22 13:25:46  curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.11  1998/04/21 17:02:42  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.10  1998/02/07 15:29:45  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9  1998/01/29 00:50:29  curt
++// Added a view record field for absolute x, y, z position.
++//
++// Revision 1.8  1998/01/27 00:47:58  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7  1998/01/22 02:59:38  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.6  1998/01/19 19:27:10  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5  1997/12/22 04:14:32  curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.4  1997/12/17 23:13:36  curt
++// Began working on rendering a sky.
++//
++// Revision 1.3  1997/12/15 23:54:51  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2  1997/12/10 22:37:48  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1  1997/08/27 21:31:18  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b04d45d48ee208291ac839596f136dbf7228434f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++noinst_LIBRARIES = libObjects.a
++
++libObjects_a_SOURCES = \
++      fragment.cxx fragment.hxx \
++      material.cxx material.hxx \
++      obj.cxx obj.hxx \
++      texload.c texload.h
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9af71d78f85dc21c8c46c923301c262b185ae6b4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,406 @@@
++// fragment.cxx -- routines to handle "atomic" display objects
++//
++// Written by Curtis Olson, started August 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Scenery/tile.hxx>
++
++#include "fragment.hxx"
++
++
++template <class T>
++inline const int FG_SIGN(const T& x) {
++    return x < T(0) ? -1 : 1;
++}
++
++template <class T>
++inline const T& FG_MIN(const T& a, const T& b) {
++    return b < a ? b : a;
++}
++
++template <class T>
++inline const T& FG_MAX(const T& a, const T& b) {
++    return  a < b ? b : a;
++}
++
++// return the minimum of the three values
++template <class T>
++inline const T& fg_min3( const T& a, const T& b, const T& c)
++{
++    return (a > b ? FG_MIN (b, c) : FG_MIN (a, c));
++}
++
++
++// return the maximum of the three values
++template <class T>
++inline const T& fg_max3 (const T& a, const T& b, const T& c)
++{
++    return (a < b ? FG_MAX (b, c) : FG_MAX (a, c));
++}
++
++// Add a face to the face list
++// Copy constructor
++fgFRAGMENT::fgFRAGMENT ( const fgFRAGMENT & rhs ) :
++    center         ( rhs.center          ),
++    bounding_radius( rhs.bounding_radius ),
++    material_ptr   ( rhs.material_ptr    ),
++    tile_ptr       ( rhs.tile_ptr        ),
++    display_list   ( rhs.display_list    ),
++    faces          ( rhs.faces           )
++{
++}
++
++fgFRAGMENT & fgFRAGMENT::operator = ( const fgFRAGMENT & rhs )
++{
++    if(!(this == &rhs )) {
++      center          = rhs.center;
++      bounding_radius = rhs.bounding_radius;
++      material_ptr    = rhs.material_ptr;
++      tile_ptr        = rhs.tile_ptr;
++      // display_list    = rhs.display_list;
++      faces           = rhs.faces;
++    }
++    return *this;
++}
++
++
++// test if line intesects with this fragment.  p0 and p1 are the two
++// line end points of the line.  If side_flag is true, check to see
++// that end points are on opposite sides of face.  Returns 1 if it
++// intersection found, 0 otherwise.  If it intesects, result is the
++// point of intersection
++
++int fgFRAGMENT::intersect( const Point3D& end0,
++                         const Point3D& end1,
++                         int side_flag,
++                         Point3D& result) const
++{
++    fgTILE *t;
++    MAT3vec v1, v2, n, center;
++    double p1[3], p2[3], p3[3];
++    double x, y, z;  // temporary holding spot for result
++    double a, b, c, d;
++    double x0, y0, z0, x1, y1, z1, a1, b1, c1;
++    double t1, t2, t3;
++    double xmin, xmax, ymin, ymax, zmin, zmax;
++    double dx, dy, dz, min_dim, x2, y2, x3, y3, rx, ry;
++    int side1, side2;
++
++    // find the associated tile
++    t = tile_ptr;
++
++    // printf("Intersecting\n");
++
++    // traverse the face list for this fragment
++    const_iterator last = faces.end();
++    for ( const_iterator current = faces.begin(); current != last; ++current )
++    {
++      // printf(".");
++
++      // get face vertex coordinates
++      center[0] = t->center.x();
++      center[1] = t->center.y();
++      center[2] = t->center.z();
++
++      MAT3_ADD_VEC(p1, t->nodes[(*current).n1], center);
++      MAT3_ADD_VEC(p2, t->nodes[(*current).n2], center);
++      MAT3_ADD_VEC(p3, t->nodes[(*current).n3], center);
++
++      // printf("point 1 = %.2f %.2f %.2f\n", p1[0], p1[1], p1[2]);
++      // printf("point 2 = %.2f %.2f %.2f\n", p2[0], p2[1], p2[2]);
++      // printf("point 3 = %.2f %.2f %.2f\n", p3[0], p3[1], p3[2]);
++
++      // calculate two edge vectors, and the face normal
++      MAT3_SUB_VEC(v1, p2, p1);
++      MAT3_SUB_VEC(v2, p3, p1);
++      MAT3cross_product(n, v1, v2);
++
++      // calculate the plane coefficients for the plane defined by
++      // this face.  If n is the normal vector, n = (a, b, c) and p1
++      // is a point on the plane, p1 = (x0, y0, z0), then the
++      // equation of the line is a(x-x0) + b(y-y0) + c(z-z0) = 0
++      a = n[0];
++      b = n[1];
++      c = n[2];
++      d = a * p1[0] + b * p1[1] + c * p1[2];
++      // printf("a, b, c, d = %.2f %.2f %.2f %.2f\n", a, b, c, d);
++
++      // printf("p1(d) = %.2f\n", a * p1[0] + b * p1[1] + c * p1[2]);
++      // printf("p2(d) = %.2f\n", a * p2[0] + b * p2[1] + c * p2[2]);
++      // printf("p3(d) = %.2f\n", a * p3[0] + b * p3[1] + c * p3[2]);
++
++      // calculate the line coefficients for the specified line
++      x0 = end0.x();  x1 = end1.x();
++      y0 = end0.y();  y1 = end1.y();
++      z0 = end0.z();  z1 = end1.z();
++
++      if ( fabs(x1 - x0) > FG_EPSILON ) {
++          a1 = 1.0 / (x1 - x0);
++      } else {
++          // we got a big divide by zero problem here
++          a1 = 0.0;
++      }
++      b1 = y1 - y0;
++      c1 = z1 - z0;
++
++      // intersect the specified line with this plane
++      t1 = b * b1 * a1;
++      t2 = c * c1 * a1;
++
++      // printf("a = %.2f  t1 = %.2f  t2 = %.2f\n", a, t1, t2);
++
++      if ( fabs(a + t1 + t2) > FG_EPSILON ) {
++          x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2);
++          t3 = a1 * (x - x0);
++          y = b1 * t3 + y0;
++          z = c1 * t3 + z0;       
++          // printf("result(d) = %.2f\n", a * x + b * y + c * z);
++      } else {
++          // no intersection point
++          continue;
++      }
++
++      if ( side_flag ) {
++          // check to see if end0 and end1 are on opposite sides of
++          // plane
++          if ( (x - x0) > FG_EPSILON ) {
++              t1 = x;
++              t2 = x0;
++              t3 = x1;
++          } else if ( (y - y0) > FG_EPSILON ) {
++              t1 = y;
++              t2 = y0;
++              t3 = y1;
++          } else if ( (z - z0) > FG_EPSILON ) {
++              t1 = z;
++              t2 = z0;
++              t3 = z1;
++          } else {
++              // everything is too close together to tell the difference
++              // so the current intersection point should work as good
++              // as any
++              result = Point3D(x, y, z);
++              return(1);
++          }
++          side1 = FG_SIGN (t1 - t2);
++          side2 = FG_SIGN (t1 - t3);
++          if ( side1 == side2 ) {
++              // same side, punt
++              continue;
++          }
++      }
++
++      // check to see if intersection point is in the bounding
++      // cube of the face
++#ifdef XTRA_DEBUG_STUFF
++      xmin = fg_min3 (p1[0], p2[0], p3[0]);
++      xmax = fg_max3 (p1[0], p2[0], p3[0]);
++      ymin = fg_min3 (p1[1], p2[1], p3[1]);
++      ymax = fg_max3 (p1[1], p2[1], p3[1]);
++      zmin = fg_min3 (p1[2], p2[2], p3[2]);
++      zmax = fg_max3 (p1[2], p2[2], p3[2]);
++      printf("bounding cube = %.2f,%.2f,%.2f  %.2f,%.2f,%.2f\n",
++             xmin, ymin, zmin, xmax, ymax, zmax);
++#endif
++      // punt if outside bouding cube
++      if ( x < (xmin = fg_min3 (p1[0], p2[0], p3[0])) ) {
++          continue;
++      } else if ( x > (xmax = fg_max3 (p1[0], p2[0], p3[0])) ) {
++          continue;
++      } else if ( y < (ymin = fg_min3 (p1[1], p2[1], p3[1])) ) {
++          continue;
++      } else if ( y > (ymax = fg_max3 (p1[1], p2[1], p3[1])) ) {
++          continue;
++      } else if ( z < (zmin = fg_min3 (p1[2], p2[2], p3[2])) ) {
++          continue;
++      } else if ( z > (zmax = fg_max3 (p1[2], p2[2], p3[2])) ) {
++          continue;
++      }
++
++      // (finally) check to see if the intersection point is
++      // actually inside this face
++
++      //first, drop the smallest dimension so we only have to work
++      //in 2d.
++      dx = xmax - xmin;
++      dy = ymax - ymin;
++      dz = zmax - zmin;
++      min_dim = fg_min3 (dx, dy, dz);
++      if ( fabs(min_dim - dx) <= FG_EPSILON ) {
++          // x is the smallest dimension
++          x1 = p1[1];
++          y1 = p1[2];
++          x2 = p2[1];
++          y2 = p2[2];
++          x3 = p3[1];
++          y3 = p3[2];
++          rx = y;
++          ry = z;
++      } else if ( fabs(min_dim - dy) <= FG_EPSILON ) {
++          // y is the smallest dimension
++          x1 = p1[0];
++          y1 = p1[2];
++          x2 = p2[0];
++          y2 = p2[2];
++          x3 = p3[0];
++          y3 = p3[2];
++          rx = x;
++          ry = z;
++      } else if ( fabs(min_dim - dz) <= FG_EPSILON ) {
++          // z is the smallest dimension
++          x1 = p1[0];
++          y1 = p1[1];
++          x2 = p2[0];
++          y2 = p2[1];
++          x3 = p3[0];
++          y3 = p3[1];
++          rx = x;
++          ry = y;
++      } else {
++          // all dimensions are really small so lets call it close
++          // enough and return a successful match
++          result = Point3D(x, y, z);
++          return(1);
++      }
++
++      // check if intersection point is on the same side of p1 <-> p2 as p3
++      t1 = (y1 - y2) / (x1 - x2);
++      side1 = FG_SIGN (t1 * ((x3) - x2) + y2 - (y3));
++      side2 = FG_SIGN (t1 * ((rx) - x2) + y2 - (ry));
++      if ( side1 != side2 ) {
++          // printf("failed side 1 check\n");
++          continue;
++      }
++
++      // check if intersection point is on correct side of p2 <-> p3 as p1
++      t1 = (y2 - y3) / (x2 - x3);
++      side1 = FG_SIGN (t1 * ((x1) - x3) + y3 - (y1));
++      side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
++      if ( side1 != side2 ) {
++          // printf("failed side 2 check\n");
++          continue;
++      }
++
++      // check if intersection point is on correct side of p1 <-> p3 as p2
++      t1 = (y1 - y3) / (x1 - x3);
++      side1 = FG_SIGN (t1 * ((x2) - x3) + y3 - (y2));
++      side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
++      if ( side1 != side2 ) {
++          // printf("failed side 3  check\n");
++          continue;
++      }
++
++      // printf( "intersection point = %.2f %.2f %.2f\n", x, y, z);
++      result = Point3D(x, y, z);
++      return(1);
++    }
++
++    // printf("\n");
++
++    return(0);
++}
++
++// $Log$
++// Revision 1.7  1999/02/26 22:09:56  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.6  1998/10/18 01:17:20  curt
++// Point3D tweaks.
++//
++// Revision 1.5  1998/10/16 00:54:37  curt
++// Converted to Point3D class.
++//
++// Revision 1.4  1998/09/15 01:35:03  curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.3  1998/09/08 21:40:42  curt
++// Updates from Bernie Bright.
++//
++// Revision 1.2  1998/09/01 19:03:07  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1  1998/08/25 16:51:23  curt
++// Moved from ../Scenery
++//
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..86b718e83d6ad18d52c3d4db15f8c36030d58be7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,295 @@@
++// fragment.hxx -- routines to handle "atomic" display objects
++//
++// Written by Curtis Olson, started August 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _FRAGMENT_HXX
++#define _FRAGMENT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <vector>
++
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++
++FG_USING_STD(vector);
++
++
++struct fgFACE {
++    int n1, n2, n3;
++
++    fgFACE( int a = 0, int b =0, int c =0 )
++      : n1(a), n2(b), n3(c) {}
++
++    fgFACE( const fgFACE & image )
++      : n1(image.n1), n2(image.n2), n3(image.n3) {}
++
++    fgFACE& operator= ( const fgFACE & image ) {
++      n1 = image.n1; n2 = image.n2; n3 = image.n3; return *this;
++    }
++
++    ~fgFACE() {}
++};
++
++inline bool
++operator== ( const fgFACE& lhs, const fgFACE& rhs )
++{
++    return (lhs.n1 == rhs.n1) && (lhs.n2 == rhs.n2) && (lhs.n3 == rhs.n3);
++}
++
++// Forward declarations
++class fgTILE;
++class fgMATERIAL;
++
++// Object fragment data class
++class fgFRAGMENT {
++
++private:
++
++public:
++    // culling data for this object fragment (fine grain culling)
++    Point3D center;
++    double bounding_radius;
++
++    // variable offset data for this object fragment for this frame
++    // fgCartesianPoint3d tile_offset;
++
++    // saved transformation matrix for this fragment (used by renderer)
++    // GLfloat matrix[16];
++    
++    // tile_ptr & material_ptr are set so that when we traverse the
++    // list of fragments we can quickly reference back the tile or
++    // material property this fragment is assigned to.
++
++    // material property pointer
++    fgMATERIAL *material_ptr;
++
++    // tile pointer
++    fgTILE *tile_ptr;
++
++    // OpenGL display list for fragment data
++    GLint display_list;
++
++    // face list (this indexes into the master tile vertex list)
++    typedef vector < fgFACE > container;
++    typedef container::iterator iterator;
++    typedef container::const_iterator const_iterator;
++
++    container faces;
++
++public:
++
++    // number of faces in this fragment
++    int num_faces() {
++      return faces.size();
++    }
++
++    // Add a face to the face list
++    void add_face(int n1, int n2, int n3) {
++      faces.push_back( fgFACE(n1,n2,n3) );
++    }
++
++    // test if line intesects with this fragment.  p0 and p1 are the
++    // two line end points of the line.  If side_flag is true, check
++    // to see that end points are on opposite sides of face.  Returns
++    // 1 if it intersection found, 0 otherwise.  If it intesects,
++    // result is the point of intersection
++    int intersect( const Point3D& end0,
++                 const Point3D& end1,
++                 int side_flag,
++                 Point3D& result) const;
++
++    // Constructors
++    fgFRAGMENT () { /*faces.reserve(512);*/}
++    fgFRAGMENT ( const fgFRAGMENT &image );
++
++    // Destructor
++    ~fgFRAGMENT() { faces.erase( faces.begin(), faces.end() ); }
++
++    // operators
++    fgFRAGMENT & operator = ( const fgFRAGMENT & rhs );
++
++    bool operator <  ( const fgFRAGMENT & rhs ) const {
++      // This is completely arbitrary. It satisfies RW's STL implementation
++      return bounding_radius < rhs.bounding_radius;
++    }
++
++    void init() {
++      faces.erase( faces.begin(), faces.end() );
++    }
++
++    int deleteDisplayList() {
++      xglDeleteLists( display_list, 1 ); return 0;
++    }
++
++    friend bool operator== ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs );
++};
++
++inline bool
++operator == ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs ) {
++    return lhs.center == rhs.center;
++}
++
++
++#endif // _FRAGMENT_HXX 
++
++
++// $Log$
++// Revision 1.12  1999/04/05 02:14:21  curt
++// Moved max node per tile definition to fg_constants.h
++//
++// Revision 1.11  1999/03/25 19:02:53  curt
++// Removed an unneeded include.
++//
++// Revision 1.10  1999/03/15 17:59:12  curt
++// MSVC++ portability tweaks contributed by Bernie Bright.
++//   Un-nested struct fgFace.
++//   Made fgFragment::deleteDisplayList() a non-const member.
++//
++// Revision 1.9  1999/03/02 01:03:23  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.8  1999/02/26 22:09:57  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.7  1998/11/02 18:29:00  curt
++// Portability changes for the Borland compiler.
++//
++// Revision 1.6  1998/10/16 00:54:38  curt
++// Converted to Point3D class.
++//
++// Revision 1.5  1998/09/15 01:35:04  curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.4  1998/09/10 19:07:09  curt
++// /Simulator/Objects/fragment.hxx
++//   Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++//   Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++//   data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++//   In viewable() delay evaluation of eye[0] and eye[1] in until they're
++//   actually needed.
++//   Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++//   method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++//   Added support for g++ 2.7.
++//   Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++//   operator->() not supported by iterators: use (*i).x instead of i->x
++//   default template arguments not supported,
++//   <functional> doesn't have mem_fun_ref() needed by callbacks.
++//   some std include files have different names.
++//   template member functions not supported.
++//
++// Revision 1.3  1998/09/08 21:40:44  curt
++// Updates from Bernie Bright.
++//
++// Revision 1.2  1998/09/01 19:03:08  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1  1998/08/25 16:51:23  curt
++// Moved from ../Scenery
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6500edc8547cbacf649cda57eb100dee4cc1f3a9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,559 @@@
++// material.cxx -- class to handle material properties
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <string.h>
++#include STL_STRING
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Scenery/tile.hxx>
++
++#include "material.hxx"
++#include "fragment.hxx"
++#include "texload.h"
++
++FG_USING_STD(string);
++
++
++// global material management class
++fgMATERIAL_MGR material_mgr;
++
++
++// Constructor
++fgMATERIAL::fgMATERIAL ( void )
++    : texture_name(""),
++      alpha(0)
++      // , list_size(0)
++{
++    ambient[0]  = ambient[1]  = ambient[2]  = ambient[3]  = 0.0;
++    diffuse[0]  = diffuse[1]  = diffuse[2]  = diffuse[3]  = 0.0;
++    specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
++    emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
++}
++
++/*
++int
++fgMATERIAL::append_sort_list( fgFRAGMENT *object )
++{
++    if ( list_size < FG_MAX_MATERIAL_FRAGS ) {
++      list[ list_size++ ] = object;
++      return 1;
++    } else {
++      return 0;
++    }
++}
++*/
++
++istream&
++operator >> ( istream& in, fgMATERIAL& m )
++{
++    string token;
++
++    for (;;) {
++      in >> token;
++      if ( token == "texture" )
++      {
++          in >> token >> m.texture_name;
++      }
++      else if ( token == "ambient" )
++      {
++          in >> token >> m.ambient[0] >> m.ambient[1]
++                      >> m.ambient[2] >> m.ambient[3];
++      }
++      else if ( token == "diffuse" )
++      {
++          in >> token >> m.diffuse[0] >> m.diffuse[1]
++                      >> m.diffuse[2] >> m.diffuse[3];
++      }
++      else if ( token == "specular" )
++      {
++          in >> token >> m.specular[0] >> m.specular[1]
++                      >> m.specular[2] >> m.specular[3];
++      }
++      else if ( token == "emissive" )
++      {
++          in >> token >> m.emissive[0] >> m.emissive[1]
++                      >> m.emissive[2] >> m.emissive[3];
++      }
++      else if ( token == "alpha" )
++      {
++          in >> token >> token;
++          if ( token == "yes" )
++              m.alpha = 1;
++          else if ( token == "no" )
++              m.alpha = 0;
++          else
++          {
++              FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
++          }
++      }
++      else if ( token[0] == '}' )
++      {
++          break;
++      }
++    }
++
++    return in;
++}
++
++void
++fgMATERIAL::load_texture()
++{
++      GLubyte *texbuf;
++      int width, height;
++
++      // create the texture object and bind it
++#ifdef GL_VERSION_1_1
++      xglGenTextures(1, &texture_id );
++      xglBindTexture(GL_TEXTURE_2D, texture_id );
++#elif GL_EXT_texture_object
++      xglGenTexturesEXT(1, &texture_id );
++      xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
++#else
++#  error port me
++#endif
++
++      // set the texture parameters for this texture
++      xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
++      xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
++      xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
++                        GL_LINEAR );
++      // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
++      //                   GL_NEAREST_MIPMAP_NEAREST );
++      xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
++                        /* GL_LINEAR */ 
++                        /* GL_NEAREST_MIPMAP_LINEAR */
++                        GL_LINEAR_MIPMAP_LINEAR ) ;
++
++      /* load in the texture data */
++      string tpath = current_options.get_fg_root() + "/Textures/" + 
++          texture_name + ".rgb";
++      string fg_tpath = tpath + ".gz";
++
++      if ( alpha == 0 ) {
++          // load rgb texture
++
++          // Try uncompressed
++          if ( (texbuf = 
++                read_rgb_texture(tpath.c_str(), &width, &height)) == 
++               NULL )
++          {
++              // Try compressed
++              if ( (texbuf = 
++                    read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
++                   == NULL )
++              {
++                  FG_LOG( FG_GENERAL, FG_ALERT, 
++                          "Error in loading texture " << tpath );
++                  exit(-1);
++              } 
++          } 
++
++          /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
++             GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
++
++          gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, 
++                             GL_RGB, GL_UNSIGNED_BYTE, texbuf );
++      } else if ( alpha == 1 ) {
++          // load rgba (alpha) texture
++
++          // Try uncompressed
++          if ( (texbuf = 
++                read_alpha_texture(tpath.c_str(), &width, &height))
++               == NULL )
++          {
++              // Try compressed
++              if ((texbuf = 
++                   read_alpha_texture(fg_tpath.c_str(), &width, &height))
++                  == NULL )
++              {
++                  FG_LOG( FG_GENERAL, FG_ALERT, 
++                          "Error in loading texture " << tpath );
++                  exit(-1);
++              } 
++          } 
++
++          xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
++                        GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
++      }
++}
++
++
++// Destructor
++fgMATERIAL::~fgMATERIAL ( void ) {
++}
++
++
++// Constructor
++fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
++    textures_loaded = false;
++}
++
++
++void
++fgMATERIAL::render_fragments()
++{
++    int tris_rendered = current_view.get_tris_rendered();
++
++    // cout << "rendering " + texture_name + " = " << list_size << "\n";
++
++    if ( empty() )
++      return;
++
++    if ( current_options.get_textures() )
++    {
++#ifdef GL_VERSION_1_1
++      xglBindTexture(GL_TEXTURE_2D, texture_id);
++#elif GL_EXT_texture_object
++      xglBindTextureEXT(GL_TEXTURE_2D, texture_id);
++#else
++#  error port me
++#endif
++    } else {
++      xglMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
++      xglMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
++    }
++
++    fgTILE* last_tile_ptr = NULL;
++    frag_list_iterator current = list.begin();
++    frag_list_iterator last = list.end();
++
++    for ( ; current != last; ++current ) {
++      fgFRAGMENT* frag_ptr = *current;
++      tris_rendered += frag_ptr->num_faces();
++      if ( frag_ptr->tile_ptr != last_tile_ptr )
++      {
++          // new tile, new translate
++          last_tile_ptr = frag_ptr->tile_ptr;
++          xglLoadMatrixd( frag_ptr->tile_ptr->model_view );
++      }
++
++      // Woohoo!!!  We finally get to draw something!
++      // printf("  display_list = %d\n", frag_ptr->display_list);
++      xglCallList( frag_ptr->display_list );
++    }
++
++    current_view.set_tris_rendered( tris_rendered );
++}
++
++
++// Load a library of material properties
++int
++fgMATERIAL_MGR::load_lib ( void )
++{
++    string material_name;
++
++    // build the path name to the material db
++    string mpath = current_options.get_fg_root() + "/materials";
++    fg_gzifstream in( mpath );
++    if ( ! in ) {
++      FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
++      exit(-1);
++    }
++
++    while ( ! in.eof() ) {
++        // printf("%s", line);
++
++      // strip leading white space and comments
++      in >> skipcomment;
++
++      // set to zero to prevent its value accidently being '{'
++      // after a failed >> operation.
++      char token = 0;
++
++      in >> material_name >> token;
++
++      if ( token == '{' ) {
++          FG_LOG( FG_TERRAIN, FG_INFO,
++                  "  Loading material " << material_name );
++          fgMATERIAL m;
++          in >> m;
++
++          if ( current_options.get_textures() ) {
++              m.load_texture();
++          }
++
++          material_mgr.material_map[material_name] = m;
++      }
++    }
++
++    if ( current_options.get_textures() ) {
++      textures_loaded = true;
++    }
++
++    return(1);
++}
++
++
++// Initialize the transient list of fragments for each material property
++void
++fgMATERIAL_MGR::init_transient_material_lists( void )
++{
++    iterator last = end();
++    for ( iterator it = begin(); it != last; ++it )
++    {
++      (*it).second.init_sort_list();
++    }
++}
++
++
++bool
++fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
++{
++    iterator it = material_map.find( material );
++    if ( it != end() )
++    {
++      mtl_ptr = &((*it).second);
++      return true;
++    }
++
++    return false;
++}
++
++
++// Destructor
++fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
++}
++
++
++void
++fgMATERIAL_MGR::render_fragments()
++{
++    current_view.set_tris_rendered( 0 );
++
++    iterator last = end();
++    for ( iterator current = begin(); current != last; ++current )
++      (*current).second.render_fragments();
++}
++
++
++// $Log$
++// Revision 1.14  1999/03/02 01:03:24  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.13  1999/02/26 22:09:58  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.12  1998/12/09 18:50:30  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.11  1998/11/07 19:07:12  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.10  1998/11/06 21:18:17  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9  1998/11/06 14:47:05  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.8  1998/10/12 23:49:17  curt
++// Changes from NHV to make the code more dynamic with fewer hard coded limits.
++//
++// Revision 1.7  1998/09/17 18:35:52  curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.6  1998/09/15 01:35:05  curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.5  1998/09/10 19:07:11  curt
++// /Simulator/Objects/fragment.hxx
++//   Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++//   Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++//   data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++//   In viewable() delay evaluation of eye[0] and eye[1] in until they're
++//   actually needed.
++//   Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++//   method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++//   Added support for g++ 2.7.
++//   Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++//   operator->() not supported by iterators: use (*i).x instead of i->x
++//   default template arguments not supported,
++//   <functional> doesn't have mem_fun_ref() needed by callbacks.
++//   some std include files have different names.
++//   template member functions not supported.
++//
++// Revision 1.4  1998/09/01 19:03:08  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.3  1998/08/27 17:02:09  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.2  1998/08/25 20:53:33  curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.1  1998/08/25 16:51:24  curt
++// Moved from ../Scenery
++//
++// Revision 1.13  1998/08/24 20:11:39  curt
++// Tweaks ...
++//
++// Revision 1.12  1998/08/12 21:41:27  curt
++// Need to negate the test for textures so that textures aren't loaded when
++// they are disabled rather than visa versa ... :-)
++//
++// Revision 1.11  1998/08/12 21:13:03  curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.10  1998/07/24 21:42:06  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.9  1998/07/13 21:01:57  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.8  1998/07/08 14:47:20  curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.7  1998/07/04 00:54:28  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.6  1998/06/27 16:54:59  curt
++// Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
++//   "EXT" versions of texture management routines.
++//
++// Revision 1.5  1998/06/17 21:36:39  curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.4  1998/06/12 00:58:04  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.3  1998/06/05 22:39:53  curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.2  1998/06/01 17:56:20  curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.1  1998/05/30 01:56:45  curt
++// Added material.cxx material.hxx
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9e8b1b1d38793ce5e9a8738892b31ef481888b5f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,320 @@@
++// material.hxx -- class to handle material properties
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _MATERIAL_HXX
++#define _MATERIAL_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <string>        // Standard C++ string library
++#include <map>           // STL associative "array"
++#include <vector>        // STL "array"
++
++#include "Include/compiler.h"
++FG_USING_STD(string);
++FG_USING_STD(map);
++FG_USING_STD(vector);
++FG_USING_STD(less);
++
++// forward decl.
++class fgFRAGMENT;
++
++
++// convenience types
++typedef vector < fgFRAGMENT * > frag_list_type;
++typedef frag_list_type::iterator frag_list_iterator;
++typedef frag_list_type::const_iterator frag_list_const_iterator;
++
++
++// #define FG_MAX_MATERIAL_FRAGS 800
++
++// MSVC++ 6.0 kuldge - Need forward declaration of friends.
++class fgMATERIAL;
++istream& operator >> ( istream& in, fgMATERIAL& m );
++
++// Material property class
++class fgMATERIAL {
++
++private:
++    // OpenGL texture name
++    GLuint texture_id;
++
++    // file name of texture
++    string texture_name;
++
++    // alpha texture?
++    int alpha;
++
++    // material properties
++    GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
++    GLint texture_ptr;
++
++    // transient list of objects with this material type (used for sorting
++    // by material to reduce GL state changes when rendering the scene
++    frag_list_type list;
++    // size_t list_size;
++
++public:
++
++    // Constructor
++    fgMATERIAL ( void );
++
++    int size() const { return list.size(); }
++    bool empty() const { return list.size() == 0; }
++
++    // Sorting routines
++    void init_sort_list( void ) {
++      list.erase( list.begin(), list.end() );
++    }
++
++    bool append_sort_list( fgFRAGMENT *object ) {
++      list.push_back( object );
++      return true;
++    }
++
++    void render_fragments();
++
++    void load_texture();
++
++    // Destructor
++    ~fgMATERIAL ( void );
++
++    friend istream& operator >> ( istream& in, fgMATERIAL& m );
++};
++
++
++// Material management class
++class fgMATERIAL_MGR {
++
++public:
++
++    // associative array of materials
++    typedef map < string, fgMATERIAL, less<string> > container;
++    typedef container::iterator iterator;
++    typedef container::const_iterator const_iterator;
++
++    iterator begin() { return material_map.begin(); }
++    const_iterator begin() const { return material_map.begin(); }
++
++    iterator end() { return material_map.end(); }
++    const_iterator end() const { return material_map.end(); }
++
++    // Constructor
++    fgMATERIAL_MGR ( void );
++
++    // Load a library of material properties
++    int load_lib ( void );
++
++    bool get_textures_loaded() { return textures_loaded; }
++
++    // Initialize the transient list of fragments for each material property
++    void init_transient_material_lists( void );
++
++    bool find( const string& material, fgMATERIAL*& mtl_ptr );
++
++    void render_fragments();
++
++    // Destructor
++    ~fgMATERIAL_MGR ( void );
++
++private:
++
++    // Have textures been loaded
++    bool textures_loaded;
++
++    container material_map;
++};
++
++
++// global material management class
++extern fgMATERIAL_MGR material_mgr;
++
++
++#endif // _MATERIAL_HXX 
++
++
++// $Log$
++// Revision 1.6  1999/02/02 20:13:39  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.5  1998/10/12 23:49:18  curt
++// Changes from NHV to make the code more dynamic with fewer hard coded limits.
++//
++// Revision 1.4  1998/09/17 18:35:53  curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.3  1998/09/10 19:07:12  curt
++// /Simulator/Objects/fragment.hxx
++//   Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++//   Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++//   data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++//   In viewable() delay evaluation of eye[0] and eye[1] in until they're
++//   actually needed.
++//   Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++//   method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++//   Added support for g++ 2.7.
++//   Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++//   operator->() not supported by iterators: use (*i).x instead of i->x
++//   default template arguments not supported,
++//   <functional> doesn't have mem_fun_ref() needed by callbacks.
++//   some std include files have different names.
++//   template member functions not supported.
++//
++// Revision 1.2  1998/09/01 19:03:09  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1  1998/08/25 16:51:24  curt
++// Moved from ../Scenery
++//
++// Revision 1.10  1998/07/24 21:42:06  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.9  1998/07/06 21:34:33  curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.8  1998/06/17 21:36:39  curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.7  1998/06/12 00:58:04  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.6  1998/06/06 01:09:31  curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.5  1998/06/06 01:07:17  curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.4  1998/06/05 22:39:53  curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.3  1998/06/03 00:47:50  curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.2  1998/06/01 17:56:20  curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.1  1998/05/30 01:56:45  curt
++// Added material.cxx material.hxx
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..56cb1d8fe4d49d7b2a87d15e278168f8e2f11190
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,933 @@@
++// obj.cxx -- routines to handle "sorta" WaveFront .obj format files.
++//
++// Written by Curtis Olson, started October 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <stdio.h>
++#include <string.h>
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++// #if defined ( __sun__ )
++// extern "C" void *memmove(void *, const void *, size_t);
++// extern "C" void *memset(void *, int, size_t);
++// #endif
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <map>          // STL
++#include <ctype.h>      // isdigit()
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/mat3.h>
++#include <Math/fg_random.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Misc/stopwatch.hxx>
++#include <Scenery/tile.hxx>
++
++#include "material.hxx"
++#include "obj.hxx"
++
++FG_USING_STD(string);
++
++
++static double normals[MAX_NODES][3];
++
++
++// given three points defining a triangle, calculate the normal
++static void calc_normal(double p1[3], double p2[3], 
++                      double p3[3], double normal[3])
++{
++    double v1[3], v2[3];
++    double temp;
++
++    v1[0] = p2[0] - p1[0]; v1[1] = p2[1] - p1[1]; v1[2] = p2[2] - p1[2];
++    v2[0] = p3[0] - p1[0]; v2[1] = p3[1] - p1[1]; v2[2] = p3[2] - p1[2];
++
++    MAT3cross_product(normal, v1, v2);
++    MAT3_NORMALIZE_VEC(normal,temp);
++
++    // fgPrintf( FG_TERRAIN, FG_DEBUG, "  Normal = %.2f %.2f %.2f\n", 
++    //           normal[0], normal[1], normal[2]);
++}
++
++
++#define FG_TEX_CONSTANT 69.0
++
++
++// Calculate texture coordinates for a given point.
++static Point3D calc_tex_coords(double *node, const Point3D& ref) {
++    Point3D cp;
++    Point3D pp;
++    // double tmplon, tmplat;
++
++    // cout << "-> " << node[0] << " " << node[1] << " " << node[2] << endl;
++    // cout << "-> " << ref.x() << " " << ref.y() << " " << ref.z() << endl;
++
++    cp = Point3D( node[0] + ref.x(),
++                node[1] + ref.y(),
++                node[2] + ref.z() );
++
++    pp = fgCartToPolar3d(cp);
++
++    // tmplon = pp.lon() * RAD_TO_DEG;
++    // tmplat = pp.lat() * RAD_TO_DEG;
++    // cout << tmplon << " " << tmplat << endl;
++
++    pp.setx( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.x(), 11.0) );
++    pp.sety( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.y(), 11.0) );
++
++    if ( pp.x() < 0.0 ) {
++      pp.setx( pp.x() + 11.0 );
++    }
++
++    if ( pp.y() < 0.0 ) {
++      pp.sety( pp.y() + 11.0 );
++    }
++
++    // cout << pp << endl;
++
++    return(pp);
++}
++
++
++// Load a .obj file and build the GL fragment list
++int fgObjLoad( const string& path, fgTILE *t) {
++    fgFRAGMENT fragment;
++    Point3D pp;
++    double approx_normal[3], normal[3] /*, scale = 0.0 */;
++    // double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
++    // GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
++    GLint display_list = 0;
++    int shading;
++    int in_fragment = 0, in_faces = 0, vncount;
++    int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
++    int last1 = 0, last2 = 0, odd = 0;
++    double (*nodes)[3];
++    Point3D center;
++
++    // printf("loading %s\n", path.c_str() );
++
++    // Attempt to open "path.gz" or "path"
++    fg_gzifstream in( path );
++    if ( ! in ) {
++      FG_LOG( FG_TERRAIN, FG_ALERT, "Cannot open file: " << path );
++      return 0;
++    }
++
++    shading = current_options.get_shading();
++
++    in_fragment = 0;
++    t->ncount = 0;
++    vncount = 0;
++    t->bounding_radius = 0.0;
++    nodes = t->nodes;
++    center = t->center;
++
++    StopWatch stopwatch;
++    stopwatch.start();
++
++    // ignore initial comments and blank lines. (priming the pump)
++    // in >> skipcomment;
++    string line;
++
++    while ( ! in.eof() ) {
++      string token;
++      char c;
++
++      in >> skipws;
++
++      if ( in.get( c ) && c == '#' ) {
++          // process a comment line
++
++          // getline( in, line );
++          // cout << "comment = " << line << endl;
++
++          in >> token;
++
++          if ( token == "gbs" ) {
++              // reference point (center offset)
++              in >> t->center >> t->bounding_radius;
++              center = t->center;
++              // cout << "center = " << center 
++              //      << " radius = " << t->bounding_radius << endl;
++          } else if ( token == "bs" ) {
++              // reference point (center offset)
++              in >> fragment.center;
++              in >> fragment.bounding_radius;
++
++              // cout << "center = " << fragment.center 
++              //      << " radius = " << fragment.bounding_radius << endl;
++          } else if ( token == "usemtl" ) {
++              // material property specification
++
++              // series of individual triangles
++              if ( in_faces ) {
++                  xglEnd();
++              }
++
++              // this also signals the start of a new fragment
++              if ( in_fragment ) {
++                  // close out the previous structure and start the next
++                  xglEndList();
++                  // printf("xglEnd(); xglEndList();\n");
++
++                  // update fragment
++                  fragment.display_list = display_list;
++
++                  // push this fragment onto the tile's object list
++                  t->fragment_list.push_back(fragment);
++              } else {
++                  in_fragment = 1;
++              }
++
++              // printf("start of fragment (usemtl)\n");
++
++              display_list = xglGenLists(1);
++              xglNewList(display_list, GL_COMPILE);
++              // printf("xglGenLists(); xglNewList();\n");
++              in_faces = 0;
++
++              // reset the existing face list
++              // printf("cleaning a fragment with %d faces\n", 
++              //        fragment.faces.size());
++              fragment.init();
++              
++              // scan the material line
++              string material;
++              in >> material;
++              fragment.tile_ptr = t;
++              
++              // find this material in the properties list
++              if ( ! material_mgr.find( material, fragment.material_ptr )) {
++                  FG_LOG( FG_TERRAIN, FG_ALERT, 
++                          "Ack! unknown usemtl name = " << material 
++                          << " in " << path );
++              }
++              
++              // initialize the fragment transformation matrix
++              /*
++               for ( i = 0; i < 16; i++ ) {
++                 fragment.matrix[i] = 0.0;
++               }
++               fragment.matrix[0] = fragment.matrix[5] =
++               fragment.matrix[10] = fragment.matrix[15] = 1.0;
++              */
++          } else {
++              // unknown comment, just gobble the input untill the
++              // end of line
++
++              in >> skipeol;
++          }
++      } else {
++          in.putback( c );
++      
++          in >> token;
++
++          // cout << "token = " << token << endl;
++
++          if ( token == "vn" ) {
++              // vertex normal
++              if ( vncount < MAX_NODES ) {
++                  in >> normals[vncount][0]
++                     >> normals[vncount][1]
++                     >> normals[vncount][2];
++                  vncount++;
++              } else {
++                  FG_LOG( FG_TERRAIN, FG_ALERT, 
++                          "Read too many vertex normals ... dying :-(" );
++                  exit(-1);
++              }
++          } else if ( token == "v" ) {
++              // node (vertex)
++              if ( t->ncount < MAX_NODES ) {
++                  in >> t->nodes[t->ncount][0]
++                     >> t->nodes[t->ncount][1]
++                     >> t->nodes[t->ncount][2];
++                  t->ncount++;
++              } else {
++                  FG_LOG( FG_TERRAIN, FG_ALERT, 
++                          "Read too many nodes ... dying :-(");
++                  exit(-1);
++              }
++          } else if ( token == "t" ) {
++              // start a new triangle strip
++
++              n1 = n2 = n3 = n4 = 0;
++
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, 
++              //           "    new tri strip = %s", line);
++              in >> n1 >> n2 >> n3;
++              fragment.add_face(n1, n2, n3);
++
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, "(t) = ");
++
++              xglBegin(GL_TRIANGLE_STRIP);
++              // printf("xglBegin(tristrip) %d %d %d\n", n1, n2, n3);
++
++              odd = 1; 
++              // scale = 1.0;
++
++              if ( shading ) {
++                  // Shading model is "GL_SMOOTH" so use precalculated
++                  // (averaged) normals
++                  // MAT3_SCALE_VEC(normal, normals[n1], scale);
++                  xglNormal3dv(normal);
++                  pp = calc_tex_coords(nodes[n1], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n1]);            
++
++                  // MAT3_SCALE_VEC(normal, normals[n2], scale);
++                  xglNormal3dv(normal);
++                  pp = calc_tex_coords(nodes[n2], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n2]);                            
++
++                  // MAT3_SCALE_VEC(normal, normals[n3], scale);
++                  xglNormal3dv(normal);
++                  pp = calc_tex_coords(nodes[n3], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n3]);
++              } else {
++                  // Shading model is "GL_FLAT" so calculate per face
++                  // normals on the fly.
++                  if ( odd ) {
++                      calc_normal(nodes[n1], nodes[n2], 
++                                  nodes[n3], approx_normal);
++                  } else {
++                      calc_normal(nodes[n2], nodes[n1], 
++                                  nodes[n3], approx_normal);
++                  }
++                  // MAT3_SCALE_VEC(normal, approx_normal, scale);
++                  xglNormal3dv(normal);
++
++                  pp = calc_tex_coords(nodes[n1], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n1]);            
++
++                  pp = calc_tex_coords(nodes[n2], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n2]);            
++                  
++                  pp = calc_tex_coords(nodes[n3], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n3]);            
++              }
++              // printf("some normals, texcoords, and vertices\n");
++
++              odd = 1 - odd;
++              last1 = n2;
++              last2 = n3;
++
++              // There can be three or four values 
++              char c;
++              while ( in.get(c) ) {
++                  if ( c == '\n' ) {
++                      break; // only the one
++                  }
++                  if ( isdigit(c) ){
++                      in.putback(c);
++                      in >> n4;
++                      break;
++                  }
++              }
++
++              if ( n4 > 0 ) {
++                  fragment.add_face(n3, n2, n4);
++
++                  if ( shading ) {
++                      // Shading model is "GL_SMOOTH"
++                      // MAT3_SCALE_VEC(normal, normals[n4], scale);
++                  } else {
++                      // Shading model is "GL_FLAT"
++                      calc_normal(nodes[n3], nodes[n2], nodes[n4], 
++                                  approx_normal);
++                      // MAT3_SCALE_VEC(normal, approx_normal, scale);
++                  }
++                  xglNormal3dv(normal);
++                  pp = calc_tex_coords(nodes[n4], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n4]);            
++                  
++                  odd = 1 - odd;
++                  last1 = n3;
++                  last2 = n4;
++                  // printf("a normal, texcoord, and vertex (4th)\n");
++              }
++          } else if ( token == "tf" ) {
++              // triangle fan
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, "new fan");
++
++              xglBegin(GL_TRIANGLE_FAN);
++
++              in >> n1;
++              xglNormal3dv(normals[n1]);
++              pp = calc_tex_coords(nodes[n1], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n1]);
++
++              in >> n2;
++              xglNormal3dv(normals[n2]);
++              pp = calc_tex_coords(nodes[n2], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n2]);
++              
++              // read all subsequent numbers until next thing isn't a number
++              while ( true ) {
++                  in >> skipws;
++
++                  char c;
++                  in.get(c);
++                  in.putback(c);
++                  if ( ! isdigit(c) || in.eof() ) {
++                      break;
++                  }
++
++                  in >> n3;
++                  // cout << "  triangle = " 
++                  //      << n1 << "," << n2 << "," << n3 
++                  //      << endl;
++                  xglNormal3dv(normals[n3]);
++                  pp = calc_tex_coords(nodes[n3], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n3]);
++
++                  fragment.add_face(n1, n2, n3);
++                  n2 = n3;
++              }
++
++              xglEnd();
++          } else if ( token == "f" ) {
++              // unoptimized face
++
++              if ( !in_faces ) {
++                  xglBegin(GL_TRIANGLES);
++                  // printf("xglBegin(triangles)\n");
++                  in_faces = 1;
++              }
++
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
++              in >> n1 >> n2 >> n3;
++              fragment.add_face(n1, n2, n3);
++
++              // xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
++              xglNormal3dv(normals[n1]);
++              pp = calc_tex_coords(nodes[n1], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n1]);
++
++              xglNormal3dv(normals[n2]);
++              pp = calc_tex_coords(nodes[n2], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n2]);
++              
++              xglNormal3dv(normals[n3]);
++              pp = calc_tex_coords(nodes[n3], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n3]);
++              // printf("some normals, texcoords, and vertices (tris)\n");
++          } else if ( token == "q" ) {
++              // continue a triangle strip
++              n1 = n2 = 0;
++
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, "continued tri strip = %s ", 
++              //           line);
++              in >> n1;
++
++              // There can be one or two values 
++              char c;
++              while ( in.get(c) ) {
++                  if ( c == '\n' ) {
++                      break; // only the one
++                  }
++
++                  if ( isdigit(c) ) {
++                      in.putback(c);
++                      in >> n2;
++                      break;
++                  }
++              }
++              // fgPrintf( FG_TERRAIN, FG_DEBUG, "read %d %d\n", n1, n2);
++
++              if ( odd ) {
++                  fragment.add_face(last1, last2, n1);
++              } else {
++                  fragment.add_face(last2, last1, n1);
++              }
++
++              if ( shading ) {
++                  // Shading model is "GL_SMOOTH"
++                  // MAT3_SCALE_VEC(normal, normals[n1], scale);
++              } else {
++                  // Shading model is "GL_FLAT"
++                  if ( odd ) {
++                      calc_normal(nodes[last1], nodes[last2], nodes[n1], 
++                                  approx_normal);
++                  } else {
++                      calc_normal(nodes[last2], nodes[last1], nodes[n1], 
++                                  approx_normal);
++                  }
++                  // MAT3_SCALE_VEC(normal, approx_normal, scale);
++              }
++              xglNormal3dv(normal);
++
++              pp = calc_tex_coords(nodes[n1], center);
++              xglTexCoord2f(pp.lon(), pp.lat());
++              xglVertex3dv(nodes[n1]);
++              // printf("a normal, texcoord, and vertex (4th)\n");
++   
++              odd = 1 - odd;
++              last1 = last2;
++              last2 = n1;
++
++              if ( n2 > 0 ) {
++                  // fgPrintf( FG_TERRAIN, FG_DEBUG, " (cont)\n");
++
++                  if ( odd ) {
++                      fragment.add_face(last1, last2, n2);
++                  } else {
++                      fragment.add_face(last2, last1, n2);
++                  }
++
++                  if ( shading ) {
++                      // Shading model is "GL_SMOOTH"
++                      // MAT3_SCALE_VEC(normal, normals[n2], scale);
++                  } else {
++                      // Shading model is "GL_FLAT"
++                      if ( odd ) {
++                          calc_normal(nodes[last1], nodes[last2], 
++                                      nodes[n2], approx_normal);
++                      } else {
++                          calc_normal(nodes[last2], nodes[last1], 
++                                      nodes[n2], approx_normal);
++                      }
++                      // MAT3_SCALE_VEC(normal, approx_normal, scale);
++                  }
++                  xglNormal3dv(normal);
++              
++                  pp = calc_tex_coords(nodes[n2], center);
++                  xglTexCoord2f(pp.lon(), pp.lat());
++                  xglVertex3dv(nodes[n2]);            
++                  // printf("a normal, texcoord, and vertex (4th)\n");
++
++                  odd = 1 -odd;
++                  last1 = last2;
++                  last2 = n2;
++              }
++          } else {
++              FG_LOG( FG_TERRAIN, FG_WARN, "Unknown token in " 
++                      << path << " = " << token );
++          }
++
++          // eat white space before start of while loop so if we are
++          // done with useful input it is noticed before hand.
++          in >> skipws;
++      }
++    }
++
++    if ( in_fragment ) {
++      // close out the previous structure and start the next
++      xglEnd();
++      xglEndList();
++      // printf("xglEnd(); xglEndList();\n");
++      
++      // update fragment
++      fragment.display_list = display_list;
++      
++      // push this fragment onto the tile's object list
++      t->fragment_list.push_back(fragment);
++    }
++
++#if 0
++    // Draw normal vectors (for visually verifying normals)
++    xglBegin(GL_LINES);
++    xglColor3f(0.0, 0.0, 0.0);
++    for ( i = 0; i < t->ncount; i++ ) {
++      xglVertex3d(t->nodes[i][0],
++                  t->nodes[i][1] ,
++                  t->nodes[i][2]);
++      xglVertex3d(t->nodes[i][0] + 500*normals[i][0],
++                  t->nodes[i][1] + 500*normals[i][1],
++                  t->nodes[i][2] + 500*normals[i][2]);
++    } 
++    xglEnd();
++#endif
++
++    stopwatch.stop();
++    FG_LOG( FG_TERRAIN, FG_INFO, 
++          "Loaded " << path << " in " 
++          << stopwatch.elapsedSeconds() << " seconds" );
++    
++    return 1;
++}
++
++
++// $Log$
++// Revision 1.15  1999/03/31 13:25:58  curt
++// Removed some debugging output.
++//
++// Revision 1.14  1999/03/30 23:48:24  curt
++// modifications to obj loader to handle tri fans.
++//
++// Revision 1.13  1999/03/27 05:36:03  curt
++// Alas, I have made non-backwardsly compatible changes to the scenery file
++//   format.  Thus I have had to make the corresponding changes here in the
++//   file loader.
++// Things that do not correspond the the .obj format are placed in comments.
++//
++// Revision 1.12  1999/03/02 01:03:25  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.11  1999/02/26 22:09:59  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.10  1998/11/06 21:18:18  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9  1998/11/06 14:47:06  curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.8  1998/10/20 18:33:55  curt
++// Tweaked texture coordinates, but we still have some problems. :-(
++//
++// Revision 1.7  1998/10/20 15:48:44  curt
++// Removed an extraneous output message.
++//
++// Revision 1.6  1998/10/18 01:17:21  curt
++// Point3D tweaks.
++//
++// Revision 1.5  1998/10/16 00:54:39  curt
++// Converted to Point3D class.
++//
++// Revision 1.4  1998/09/15 01:35:07  curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.3  1998/09/03 21:27:03  curt
++// Fixed a serious bug caused by not-quite-correct comment/white space eating
++// which resulted in mismatched glBegin() glEnd() pairs, incorrect display lists,
++// and ugly display artifacts.
++//
++// Revision 1.2  1998/09/01 19:03:09  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1  1998/08/25 16:51:25  curt
++// Moved from ../Scenery
++//
++// Revision 1.23  1998/08/20 15:16:43  curt
++// obj.cxx: use more explicit parenthases.
++// texload.[ch]: use const in function definitions where appropriate.
++//
++// Revision 1.22  1998/08/20 15:12:03  curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.21  1998/08/12 21:13:04  curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.20  1998/07/24 21:42:07  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.19  1998/07/13 21:01:58  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.18  1998/07/12 03:18:27  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.17  1998/07/08 14:47:21  curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.16  1998/07/06 21:34:33  curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.15  1998/07/04 00:54:28  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.14  1998/06/17 21:36:40  curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.13  1998/06/12 00:58:05  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.12  1998/06/08 17:57:54  curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.11  1998/06/06 01:09:31  curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.10  1998/06/06 01:07:17  curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.9  1998/06/05 22:39:54  curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.8  1998/06/05 18:19:18  curt
++// Recognize file, file.gz, and file.obj as scenery object files.
++//
++// Revision 1.7  1998/05/24 02:49:09  curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.6  1998/05/23 14:09:20  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that 
++// fragment.
++//
++// Revision 1.5  1998/05/20 20:53:53  curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.4  1998/05/16 13:09:57  curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++//   scenery generation tools and scenery can be updated.
++//
++// Revision 1.3  1998/05/03 00:48:01  curt
++// Updated texture coordinate fmod() parameter.
++//
++// Revision 1.2  1998/05/02 01:52:14  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1  1998/04/30 12:35:28  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.35  1998/04/28 21:43:26  curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.34  1998/04/28 01:21:42  curt
++// Tweaked texture parameter calculations to keep the number smaller.  This
++// avoids the "swimming" problem.
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.33  1998/04/27 15:58:15  curt
++// Screwing around with texture coordinate generation ... still needs work.
++//
++// Revision 1.32  1998/04/27 03:30:13  curt
++// Minor transformation adjustments to try to keep scenery tiles closer to
++// (0, 0, 0)  GLfloats run out of precision at the distances we need to model
++// the earth, but we can do a bunch of pre-transformations using double math
++// and then cast to GLfloat once everything is close in where we have less
++// precision problems.
++//
++// Revision 1.31  1998/04/25 15:09:57  curt
++// Changed "r" to "rb" in gzopen() options.  This fixes bad behavior in win32.
++//
++// Revision 1.30  1998/04/24 14:21:08  curt
++// Added "file.obj.gz" support.
++//
++// Revision 1.29  1998/04/24 00:51:07  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.28  1998/04/22 13:22:44  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.27  1998/04/18 04:13:17  curt
++// Added zlib on the fly decompression support for loading scenery objects.
++//
++// Revision 1.26  1998/04/03 22:11:36  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.25  1998/03/14 00:30:50  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.24  1998/02/09 21:30:18  curt
++// Fixed a nagging problem with terrain tiles not "quite" matching up perfectly.
++//
++// Revision 1.23  1998/02/09 15:07:52  curt
++// Minor tweaks.
++//
++// Revision 1.22  1998/02/01 03:39:54  curt
++// Minor tweaks.
++//
++// Revision 1.21  1998/01/31 00:43:25  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.20  1998/01/29 00:51:39  curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.19  1998/01/27 03:26:42  curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.18  1998/01/19 19:27:16  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.17  1998/01/13 00:23:10  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.16  1997/12/30 23:09:40  curt
++// Worked on winding problem without luck, so back to calling glFrontFace()
++// 3 times for each scenery area.
++//
++// Revision 1.15  1997/12/30 20:47:51  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.14  1997/12/30 01:38:46  curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.13  1997/12/18 23:32:36  curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.12  1997/12/17 23:13:47  curt
++// Began working on rendering the sky.
++//
++// Revision 1.11  1997/12/15 23:55:01  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.10  1997/12/12 21:41:28  curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.9  1997/12/12 19:52:57  curt
++// Working on lightling and material properties.
++//
++// Revision 1.8  1997/12/10 01:19:51  curt
++// Tweaks for verion 0.15 release.
++//
++// Revision 1.7  1997/12/08 22:51:17  curt
++// Enhanced to handle ccw and cw tri-stripe winding.  This is a temporary
++// admission of defeat.  I will eventually go back and get all the stripes
++// wound the same way (ccw).
++//
++// Revision 1.6  1997/11/25 19:25:35  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.5  1997/11/15 18:16:39  curt
++// minor tweaks.
++//
++// Revision 1.4  1997/11/14 00:26:49  curt
++// Transform scenery coordinates earlier in pipeline when scenery is being
++// created, not when it is being loaded.  Precalculate normals for each node
++// as average of the normals of each containing polygon so Garoude shading is
++// now supportable.
++//
++// Revision 1.3  1997/10/31 04:49:12  curt
++// Tweaking vertex orders.
++//
++// Revision 1.2  1997/10/30 12:38:45  curt
++// Working on new scenery subsystem.
++//
++// Revision 1.1  1997/10/28 21:14:54  curt
++// Initial revision.
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c07dd1c262c1c46b1225413bae74b5a6e815b90d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,173 @@@
++// obj.hxx -- routines to handle WaveFront .obj-ish format files.
++//
++// Written by Curtis Olson, started October 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _OBJ_HXX
++#define _OBJ_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++
++#include <string>
++
++#include <Scenery/tile.hxx>
++
++
++// Load a .obj file and build the GL fragment list
++int fgObjLoad(const string& path, fgTILE *tile);
++
++
++#endif // _OBJ_HXX
++
++
++// $Log$
++// Revision 1.3  1998/10/16 00:54:41  curt
++// Converted to Point3D class.
++//
++// Revision 1.2  1998/09/01 19:03:10  curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++//  - The new classes in libmisc.tgz define a stream interface into zlib.
++//    I've put these in a new directory, Lib/Misc.  Feel free to rename it
++//    to something more appropriate.  However you'll have to change the
++//    include directives in all the other files.  Additionally you'll have
++//    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++//    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++//    test so I've included the required changes in config.tgz.
++//
++//    There are a fair few changes to Simulator/Objects as I've moved
++//    things around.  Loading tiles is quicker but thats not where the delay
++//    is.  Tile loading takes a few tenths of a second per file on a P200
++//    but it seems to be the post-processing that leads to a noticeable
++//    blip in framerate.  I suppose its time to start profiling to see where
++//    the delays are.
++//
++//    I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++//   zfstream.cxx
++//   zfstream.hxx
++//     C++ stream interface into zlib.
++//     Taken from zlib-1.1.3/contrib/iostream/.
++//     Minor mods for STL compatibility.
++//     There's no copyright associated with these so I assume they're
++//     covered by zlib's.
++//
++//   fgstream.cxx
++//   fgstream.hxx
++//     FlightGear input stream using gz_ifstream.  Tries to open the
++//     given filename.  If that fails then filename is examined and a
++//     ".gz" suffix is removed or appended and that file is opened.
++//
++//   stopwatch.hxx
++//     A simple timer for benchmarking.  Not used in production code.
++//     Taken from the Blitz++ project.  Covered by GPL.
++//
++//   strutils.cxx
++//   strutils.hxx
++//     Some simple string manipulation routines.
++//
++// Simulator/Airports/
++//   Load airports database using fgstream.
++//   Changed fgAIRPORTS to use set<> instead of map<>.
++//   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++//   Returns true if found.
++//
++// Simulator/Astro/
++//   Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++//   Modified fgObjLoad() to use fgstream.
++//   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++//   Many changes to fgMATERIAL.
++//   Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1  1998/08/25 16:51:26  curt
++// Moved from ../Scenery
++//
++// Revision 1.4  1998/05/24 02:49:10  curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.3  1998/05/23 14:09:21  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that
++// fragment. 
++//
++// Revision 1.2  1998/05/02 01:52:15  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1  1998/04/30 12:35:29  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.11  1998/04/25 22:06:31  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.10  1998/04/24 00:51:07  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.9  1998/04/22 13:22:45  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.8  1998/04/21 17:02:43  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.7  1998/04/03 22:11:37  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.6  1998/01/31 00:43:25  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.5  1998/01/27 00:48:03  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.4  1998/01/22 02:59:41  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3  1998/01/19 19:27:17  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2  1998/01/13 00:23:10  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.1  1997/10/28 21:14:55  curt
++// Initial revision.
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e6ebbb137c935ff3251ffbdfea4cb636584544a2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,273 @@@
++
++/* texture.c - by David Blythe, SGI */
++
++/* texload is a simplistic routine for reading an SGI .rgb image file. */
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h> 
++#include <string.h>
++
++#include <Include/fg_zlib.h>
++
++#include "texload.h"
++
++typedef struct _ImageRec {
++    unsigned short imagic;
++    unsigned short type;
++    unsigned short dim;
++    unsigned short xsize, ysize, zsize;
++    unsigned int min, max;
++    unsigned int wasteBytes;
++    char name[80];
++    unsigned long colorMap;
++    fgFile file;
++    unsigned char *tmp;
++    unsigned long rleEnd;
++    unsigned int *rowStart;
++    int *rowSize;
++} ImageRec;
++
++void
++rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
++    while(n--) {
++        l[0] = r[0];
++        l[1] = g[0];
++        l[2] = b[0];
++        l += 3; r++; g++; b++;
++    }
++}
++
++static void
++ConvertShort(unsigned short *array, unsigned int length) {
++    unsigned short b1, b2;
++    unsigned char *ptr;
++
++    ptr = (unsigned char *)array;
++    while (length--) {
++        b1 = *ptr++;
++        b2 = *ptr++;
++        *array++ = (b1 << 8) | (b2);
++    }
++}
++
++static void
++ConvertUint(unsigned *array, unsigned int length) {
++    unsigned int b1, b2, b3, b4;
++    unsigned char *ptr;
++
++    ptr = (unsigned char *)array;
++    while (length--) {
++        b1 = *ptr++;
++        b2 = *ptr++;
++        b3 = *ptr++;
++        b4 = *ptr++;
++        *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
++    }
++}
++
++static ImageRec *ImageOpen(const char *fileName)
++{
++     union {
++       int testWord;
++       char testByte[4];
++     } endianTest;
++
++    ImageRec *image;
++    int swapFlag;
++    int x;
++
++    endianTest.testWord = 1;
++    if (endianTest.testByte[0] == 1) {
++        swapFlag = 1;
++    } else {
++        swapFlag = 0;
++    }
++
++    image = (ImageRec *)malloc(sizeof(ImageRec));
++    if (image == NULL) {
++        fprintf(stderr, "Out of memory!\n");
++        exit(1);
++    }
++    if ((image->file = fgopen(fileName, "rb")) == NULL) {
++      return NULL;
++    }
++
++    // fread(image, 1, 12, image->file);
++    fgread(image->file, image, 12);
++
++    if (swapFlag) {
++        ConvertShort(&image->imagic, 6);
++    }
++
++    image->tmp = (unsigned char *)malloc(image->xsize*256);
++    if (image->tmp == NULL) {
++        fprintf(stderr, "\nOut of memory!\n");
++        exit(1);
++    }
++
++    if ((image->type & 0xFF00) == 0x0100) {
++        x = image->ysize * image->zsize * (int) sizeof(unsigned);
++        image->rowStart = (unsigned *)malloc(x);
++        image->rowSize = (int *)malloc(x);
++        if (image->rowStart == NULL || image->rowSize == NULL) {
++            fprintf(stderr, "\nOut of memory!\n");
++            exit(1);
++        }
++        image->rleEnd = 512 + (2 * x);
++        fgseek(image->file, 512, SEEK_SET);
++        // fread(image->rowStart, 1, x, image->file);
++      fgread(image->file, image->rowStart, x);
++        // fread(image->rowSize, 1, x, image->file);
++      fgread(image->file, image->rowSize, x);
++        if (swapFlag) {
++            ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
++            ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
++        }
++    }
++    return image;
++}
++
++static void
++ImageClose(ImageRec *image) {
++    fgclose(image->file);
++    free(image->tmp);
++    free(image);
++}
++
++static void
++ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
++    unsigned char *iPtr, *oPtr, pixel;
++    int count;
++
++    if ((image->type & 0xFF00) == 0x0100) {
++        fgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
++        // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
++        //      image->file);
++      fgread(image->file, image->tmp, 
++             (unsigned int)image->rowSize[y+z*image->ysize]);
++
++        iPtr = image->tmp;
++        oPtr = buf;
++        for (;;) {
++            pixel = *iPtr++;
++            count = (int)(pixel & 0x7F);
++            if (!count) {
++                return;
++            }
++            if (pixel & 0x80) {
++                while (count--) {
++                    *oPtr++ = *iPtr++;
++                }
++            } else {
++                pixel = *iPtr++;
++                while (count--) {
++                    *oPtr++ = pixel;
++                }
++            }
++        }
++    } else {
++        fgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
++              SEEK_SET);
++        // fread(buf, 1, image->xsize, image->file);
++      fgread(image->file, buf, image->xsize);
++    }
++}
++
++GLubyte *
++read_alpha_texture(const char *name, int *width, int *height)
++{
++    unsigned char *base, *lptr;
++    ImageRec *image;
++    int y;
++
++    image = ImageOpen(name);
++    if(!image) {
++        return NULL;
++    }
++
++    (*width)=image->xsize;
++    (*height)=image->ysize;
++
++    printf("image->zsize = %d\n", image->zsize);
++
++    if (image->zsize != 1) {
++      ImageClose(image);
++      return NULL;
++    }
++
++    base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
++    lptr = base;
++    for(y=0; y<image->ysize; y++) {
++        ImageGetRow(image,lptr,y,0);
++        lptr += image->xsize;
++    }
++    ImageClose(image);
++
++    return (unsigned char *) base;
++}
++
++GLubyte *
++read_rgb_texture(const char *name, int *width, int *height)
++{
++    unsigned char *base, *ptr;
++    unsigned char *rbuf, *gbuf, *bbuf, *abuf;
++    ImageRec *image;
++    int y;
++
++    image = ImageOpen(name);
++    
++    if(!image)
++        return NULL;
++    (*width)=image->xsize;
++    (*height)=image->ysize;
++    if (image->zsize != 3 && image->zsize != 4) {
++      ImageClose(image);
++      return NULL;
++    }
++
++    base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
++    rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++    gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++    bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++    abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++    if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
++      if (base) free(base);
++      if (rbuf) free(rbuf);
++      if (gbuf) free(gbuf);
++      if (bbuf) free(bbuf);
++      if (abuf) free(abuf);
++      return NULL;
++    }
++    ptr = base;
++    for(y=0; y<image->ysize; y++) {
++        if(image->zsize == 4) {
++            ImageGetRow(image,rbuf,y,0);
++            ImageGetRow(image,gbuf,y,1);
++            ImageGetRow(image,bbuf,y,2);
++            ImageGetRow(image,abuf,y,3);  /* Discard. */
++            rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
++            ptr += (image->xsize * 3);
++        } else {
++            ImageGetRow(image,rbuf,y,0);
++            ImageGetRow(image,gbuf,y,1);
++            ImageGetRow(image,bbuf,y,2);
++            rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
++            ptr += (image->xsize * 3);
++        }
++    }
++    ImageClose(image);
++    free(rbuf);
++    free(gbuf);
++    free(bbuf);
++    free(abuf);
++
++    return (GLubyte *) base;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e15e025cfbad91a453ce9e8660482349516f8c1f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,30 @@@
++
++/* Copyright (c) Mark J. Kilgard, 1997.  */
++
++/* This program is freely distributable without licensing fees 
++   and is provided without guarantee or warrantee expressed or 
++   implied. This program is -not- in the public domain. */
++
++
++#ifndef _TEXLOAD_H
++#define _TEXLOAD_H
++
++
++#include <GL/glut.h>
++
++
++#ifdef __cplusplus                                                          
++extern "C" {                            
++#endif                                   
++
++
++extern GLubyte *read_alpha_texture(const char *name, int *width, int *height);
++extern GLubyte * read_rgb_texture(const char *name, int *width, int *height);
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++#endif /* _TEXLOAD_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6e8da5051beb7535b27254409baa440d7c06d7ac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++noinst_LIBRARIES = libScenery.a
++
++libScenery_a_SOURCES = \
++      scenery.cxx scenery.hxx \
++      tile.cxx tile.hxx \
++      tilecache.cxx tilecache.hxx \
++      tilemgr.cxx tilemgr.hxx
++
++INCLUDES += \
++      -I$(top_builddir) \
++      -I$(top_builddir)/Lib \
++      -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..730a9c92429534de5dd137b564940f94263d6cac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,262 @@@
++// scenery.cxx -- data structures and routines for managing scenery.
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdio.h>
++#include <string.h>
++
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++
++// #include "obj.hxx"
++#include "scenery.hxx"
++// #include "texload.h"
++
++
++// Temporary hack until we get a better texture management system running
++GLint area_texture;
++
++
++// Shared structure to hold current scenery parameters
++struct fgSCENERY scenery;
++
++
++// Initialize the Scenery Management system
++int fgSceneryInit( void ) {
++    fgOPTIONS *o;
++    // char path[1024], fgpath[1024];
++    // GLubyte *texbuf;
++    // int width, height;
++
++    o = &current_options;
++
++    FG_LOG( FG_TERRAIN, FG_INFO, "Initializing scenery subsystem" );
++
++    scenery.cur_elev = -9999;
++
++    return(1);
++}
++
++
++// Tell the scenery manager where we are so it can load the proper data, and
++// build the proper structures.
++void fgSceneryUpdate(double lon, double lat, double elev) {
++    // does nothing;
++}
++
++
++// Render out the current scene
++void fgSceneryRender( void ) {
++}
++
++
++// $Log$
++// Revision 1.10  1998/11/06 21:18:20  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9  1998/10/16 23:27:57  curt
++// C++-ifying.
++//
++// Revision 1.8  1998/08/25 16:52:40  curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++//   ../Objects
++//
++// Revision 1.7  1998/07/13 21:01:59  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.6  1998/07/12 03:18:27  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.5  1998/06/17 21:36:41  curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.4  1998/05/13 18:26:40  curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.3  1998/05/07 23:15:20  curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.2  1998/05/02 01:52:16  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1  1998/04/30 12:35:30  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.42  1998/04/28 21:43:27  curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.41  1998/04/24 00:51:08  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.40  1998/04/18 04:14:06  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.39  1998/04/08 23:30:07  curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.38  1998/04/03 22:11:37  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.37  1998/03/23 21:23:05  curt
++// Debugging output tweaks.
++//
++// Revision 1.36  1998/03/14 00:30:50  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.35  1998/01/31 00:43:26  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.34  1998/01/27 03:26:43  curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.33  1998/01/19 19:27:17  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.32  1998/01/19 18:40:37  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.31  1998/01/13 00:23:11  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.30  1998/01/07 03:22:29  curt
++// Moved astro stuff to .../Src/Astro/
++//
++// Revision 1.29  1997/12/30 20:47:52  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.28  1997/12/15 23:55:02  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.27  1997/12/12 21:41:30  curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.26  1997/12/12 19:52:58  curt
++// Working on lightling and material properties.
++//
++// Revision 1.25  1997/12/10 22:37:51  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.24  1997/12/08 22:51:18  curt
++// Enhanced to handle ccw and cw tri-stripe winding.  This is a temporary
++// admission of defeat.  I will eventually go back and get all the stripes
++// wound the same way (ccw).
++//
++// Revision 1.23  1997/11/25 19:25:37  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.22  1997/10/28 21:00:22  curt
++// Changing to new terrain format.
++//
++// Revision 1.21  1997/10/25 03:24:24  curt
++// Incorporated sun, moon, and star positioning code contributed by Durk Talsma.
++//
++// Revision 1.20  1997/10/25 03:18:27  curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.19  1997/09/05 14:17:30  curt
++// More tweaking with stars.
++//
++// Revision 1.18  1997/09/05 01:35:59  curt
++// Working on getting stars right.
++//
++// Revision 1.17  1997/08/29 17:55:27  curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.16  1997/08/27 21:32:29  curt
++// Restructured view calculation code.  Added stars.
++//
++// Revision 1.15  1997/08/27 03:30:32  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.14  1997/08/25 20:27:24  curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.13  1997/08/22 21:34:41  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.12  1997/08/19 23:55:08  curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.11  1997/08/13 20:24:22  curt
++// Changed default detail level.
++//
++// Revision 1.10  1997/08/06 00:24:30  curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.9  1997/08/04 17:08:11  curt
++// Testing cvs on IRIX 6.x
++//
++// Revision 1.8  1997/07/18 23:41:27  curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.7  1997/07/16 20:04:52  curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.6  1997/07/14 16:26:05  curt
++// Testing/playing -- placed objects randomly across the entire terrain.
++//
++// Revision 1.5  1997/07/11 03:23:19  curt
++// Solved some scenery display/orientation problems.  Still have a positioning
++// (or transformation?) problem.
++//
++// Revision 1.4  1997/07/11 01:30:03  curt
++// More tweaking of terrian floor.
++//
++// Revision 1.3  1997/06/29 21:16:50  curt
++// More twiddling with the Scenery Management system.
++//
++// Revision 1.2  1997/06/27 20:03:37  curt
++// Working on Makefile structure.
++//
++// Revision 1.1  1997/06/27 02:26:30  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..385c8a8f224f83567ff2c718fd2a3c40aaec9a5a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,164 @@@
++// scenery.hxx -- data structures and routines for managing scenery.
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _SCENERY_HXX
++#define _SCENERY_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Math/point3d.hxx>
++
++
++// Define a structure containing global scenery parameters
++struct fgSCENERY {
++    // center of current scenery chunk
++    Point3D center;
++
++    // next center of current scenery chunk
++    Point3D next_center;
++
++    // angle of sun relative to current local horizontal
++    double sun_angle;
++
++    // elevation of terrain at our current lat/lon (based on the
++    // actual drawn polygons)
++    double cur_elev;
++};
++
++extern struct fgSCENERY scenery;
++
++
++// Initialize the Scenery Management system
++int fgSceneryInit( void );
++
++
++// Tell the scenery manager where we are so it can load the proper
++// data, and build the proper structures.
++void fgSceneryUpdate(double lon, double lat, double elev);
++
++
++// Render out the current scene
++void fgSceneryRender( void );
++
++
++#endif // _SCENERY_HXX
++
++
++// $Log$
++// Revision 1.6  1998/10/16 23:27:59  curt
++// C++-ifying.
++//
++// Revision 1.5  1998/10/16 00:55:44  curt
++// Converted to Point3D class.
++//
++// Revision 1.4  1998/07/12 03:18:28  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.3  1998/07/08 14:47:22  curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.2  1998/05/02 01:52:16  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1  1998/04/30 12:35:31  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.21  1998/04/25 22:06:31  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.20  1998/04/22 13:22:45  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.19  1998/04/21 17:02:43  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.18  1998/03/14 00:30:51  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.17  1998/02/20 00:16:24  curt
++// Thursday's tweaks.
++//
++// Revision 1.16  1998/01/27 00:48:03  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.15  1998/01/22 02:59:41  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.14  1998/01/19 19:27:17  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.13  1998/01/19 18:40:38  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.12  1997/12/15 23:55:03  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.11  1997/12/10 22:37:52  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.10  1997/09/04 02:17:37  curt
++// Shufflin' stuff.
++//
++// Revision 1.9  1997/08/27 03:30:33  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.8  1997/08/06 00:24:30  curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.7  1997/07/23 21:52:27  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.6  1997/07/11 01:30:03  curt
++// More tweaking of terrian floor.
++//
++// Revision 1.5  1997/06/26 22:14:57  curt
++// Beginning work on a scenery management system.
++//
++// Revision 1.4  1997/06/21 17:57:21  curt
++// directory shuffling ...
++//
++// Revision 1.2  1997/05/23 15:40:43  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 16:07:07  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bd95eb6d581102ac512afc7f65d6d2af02a8ed3b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,175 @@@
++// tile.cxx -- routines to handle a scenery tile
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_FUNCTIONAL
++#include STL_ALGORITHM
++
++#include <Debug/logstream.hxx>
++#include <Scenery/tile.hxx>
++#include "Bucket/newbucket.hxx"
++
++#include "tile.hxx"
++
++FG_USING_STD(for_each);
++FG_USING_STD(mem_fun_ref);
++
++
++// Constructor
++fgTILE::fgTILE ( void )
++    : nodes(new double[MAX_NODES][3]),
++      ncount(0),
++      used(false)
++{
++}
++
++
++// Destructor
++fgTILE::~fgTILE ( void ) {
++//     free(nodes);
++    delete[] nodes;
++}
++
++// Step through the fragment list, deleting the display list, then
++// the fragment, until the list is empty.
++void
++fgTILE::release_fragments()
++{
++    FG_LOG( FG_TERRAIN, FG_DEBUG,
++          "FREEING TILE = (" << tile_bucket << ")" );
++    for_each( begin(), end(),
++            mem_fun_ref( &fgFRAGMENT::deleteDisplayList ));
++    fragment_list.erase( begin(), end() );
++    used = false;
++}
++
++
++// $Log$
++// Revision 1.16  1999/03/25 19:03:24  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.15  1999/03/02 01:03:29  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.14  1999/02/02 20:13:40  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.13  1998/11/09 23:40:46  curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling.  Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>.  Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that.  All access seems to be sequential.  Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators.  This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++//   Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++//   Changed fragment list to a vector.
++//   Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++//   use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++//   uses all the new convenience functions.
++//
++// Revision 1.12  1998/10/16 00:55:45  curt
++// Converted to Point3D class.
++//
++// Revision 1.11  1998/09/02 14:37:08  curt
++// Use erase() instead of while ( size() ) pop_front();
++//
++// Revision 1.10  1998/08/25 16:52:42  curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++//   ../Objects
++//
++// Revision 1.9  1998/08/24 20:11:39  curt
++// Tweaks ...
++//
++// Revision 1.8  1998/08/22  14:49:58  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.7  1998/08/20 15:12:05  curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.6  1998/08/12 21:13:05  curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.5  1998/07/24 21:42:08  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.4  1998/07/22 21:41:42  curt
++// Add basic fgFACE methods contributed by Charlie Hotchkiss.
++// intersect optimization from Norman Vine.
++//
++// Revision 1.3  1998/07/16 17:34:24  curt
++// Ground collision detection optimizations contributed by Norman Vine.
++//
++// Revision 1.2  1998/07/12 03:18:28  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.1  1998/05/23 14:09:21  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4fd636e17907a4cbd6470b8521280133528826db
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,311 @@@
++// tile.hxx -- routines to handle a scenery tile
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILE_HXX
++#define _TILE_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <vector>
++#include STL_STRING
++
++#include <Bucket/newbucket.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Objects/fragment.hxx>
++
++#ifdef FG_HAVE_NATIVE_SGI_COMPILERS
++#include <strings.h>
++#endif
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++
++// Scenery tile class
++class fgTILE {
++
++public:
++
++    typedef vector < fgFRAGMENT > container;
++    typedef container::iterator FragmentIterator;
++    typedef container::const_iterator FragmentConstIterator;
++
++public:
++    // node list (the per fragment face lists reference this node list)
++    double (*nodes)[3];
++    int ncount;
++
++    // culling data for whole tile (course grain culling)
++    Point3D center;
++    double bounding_radius;
++    Point3D offset;
++    GLdouble model_view[16];
++
++    // this tile's official location in the world
++    FGBucket tile_bucket;
++
++    // the tile cache will mark here if the tile is being used
++    bool used;
++
++    container fragment_list;
++
++public:
++
++    FragmentIterator begin() { return fragment_list.begin(); }
++    FragmentConstIterator begin() const { return fragment_list.begin(); }
++
++    FragmentIterator end() { return fragment_list.end(); }
++    FragmentConstIterator end() const { return fragment_list.end(); }
++
++    void add_fragment( fgFRAGMENT& frag ) {
++      frag.tile_ptr = this;
++      fragment_list.push_back( frag );
++    }
++
++    //
++    size_t num_fragments() const {
++      return fragment_list.size();
++    }
++
++    // Step through the fragment list, deleting the display list, then
++    // the fragment, until the list is empty.
++    void release_fragments();
++
++//     int ObjLoad( const string& path, const fgBUCKET& p );
++
++    // Constructor
++    fgTILE ( void );
++
++    // Destructor
++    ~fgTILE ( void );
++
++    // Calculate this tile's offset
++    void SetOffset( const Point3D& off)
++    {
++      offset = center - off;
++    }
++
++
++    // Calculate the model_view transformation matrix for this tile
++    inline void
++    UpdateViewMatrix(GLdouble *MODEL_VIEW)
++    {
++
++#if defined( USE_MEM ) || defined( WIN32 )
++      memcpy( model_view, MODEL_VIEW, 16*sizeof(GLdouble) );
++#else 
++      bcopy( MODEL_VIEW, model_view, 16*sizeof(GLdouble) );
++#endif
++      
++      // This is equivalent to doing a glTranslatef(x, y, z);
++      model_view[12] += (model_view[0]*offset.x() +
++                         model_view[4]*offset.y() +
++                         model_view[8]*offset.z());
++      model_view[13] += (model_view[1]*offset.x() +
++                         model_view[5]*offset.y() +
++                         model_view[9]*offset.z());
++      model_view[14] += (model_view[2]*offset.x() +
++                         model_view[6]*offset.y() +
++                         model_view[10]*offset.z() );
++      // m[15] += (m[3]*x + m[7]*y + m[11]*z);
++      // m[3] m7[] m[11] are 0.0 see LookAt() in views.cxx
++      // so m[15] is unchanged
++    }
++
++private:
++
++    // not defined
++    fgTILE( const fgTILE& );
++    fgTILE& operator = ( const fgTILE& );
++};
++
++
++#endif // _TILE_HXX 
++
++
++// $Log$
++// Revision 1.26  1999/03/25 19:03:25  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.25  1999/03/02 01:03:30  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.24  1999/02/26 22:10:02  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.23  1999/02/02 20:13:41  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.22  1998/12/03 01:18:16  curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.21  1998/11/09 23:40:47  curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling.  Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>.  Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that.  All access seems to be sequential.  Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators.  This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++//   Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++//   Changed fragment list to a vector.
++//   Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++//   use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++//   uses all the new convenience functions.
++//
++// Revision 1.20  1998/10/16 00:55:46  curt
++// Converted to Point3D class.
++//
++// Revision 1.19  1998/09/17 18:36:17  curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.18  1998/08/25 16:52:42  curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++//   ../Objects
++//
++// Revision 1.17  1998/08/22  14:49:58  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.16  1998/08/22 02:01:34  curt
++// increased fragment list size.
++//
++// Revision 1.15  1998/08/20 15:12:06  curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.14  1998/08/12 21:13:06  curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.13  1998/07/24 21:42:08  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.12  1998/07/22 21:41:42  curt
++// Add basic fgFACE methods contributed by Charlie Hotchkiss.
++// intersect optimization from Norman Vine.
++//
++// Revision 1.11  1998/07/12 03:18:28  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.10  1998/07/08 14:47:22  curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.9  1998/07/06 21:34:34  curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.8  1998/07/04 00:54:30  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.7  1998/06/12 00:58:05  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.6  1998/06/08 17:57:54  curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.5  1998/06/06 01:09:32  curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.4  1998/06/06 01:07:18  curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.3  1998/06/05 22:39:54  curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.2  1998/06/03 00:47:50  curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.1  1998/05/23 14:09:21  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8b8c441d747fe3831ecec9dff90fa088dc05fc19
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,343 @@@
++// tilecache.cxx -- routines to handle scenery tile caching
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Debug/logstream.hxx>
++#include <Airports/genapt.hxx>
++// #include <Bucket/bucketutils.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Objects/obj.hxx>
++
++#include "tile.hxx"
++#include "tilecache.hxx"
++
++
++// the tile cache
++fgTILECACHE global_tile_cache;
++
++
++// Constructor
++fgTILECACHE::fgTILECACHE( void ) {
++}
++
++
++// Initialize the tile cache subsystem
++void
++fgTILECACHE::init( void )
++{
++    int i;
++
++    FG_LOG( FG_TERRAIN, FG_INFO, "Initializing the tile cache." );
++
++    for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++      tile_cache[i].used = 0;
++    }
++}
++
++
++// Search for the specified "bucket" in the cache
++int
++fgTILECACHE::exists( const FGBucket& p )
++{
++    int i;
++
++    for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++      if ( tile_cache[i].tile_bucket == p ) {
++          FG_LOG( FG_TERRAIN, FG_DEBUG, 
++                  "TILE EXISTS in cache ... index = " << i );
++          return( i );
++      }
++    }
++    
++    return( -1 );
++}
++
++
++// Fill in a tile cache entry with real data for the specified bucket
++void
++fgTILECACHE::fill_in( int index, FGBucket& p )
++{
++    // Load the appropriate data file and build tile fragment list
++    string tile_path = current_options.get_fg_root() +
++      "/Scenery/" + p.gen_base_path() + "/" + p.gen_index_str();
++
++    tile_cache[index].used = true;
++    tile_cache[index].tile_bucket = p;
++    fgObjLoad( tile_path, &tile_cache[index] );
++//     tile_cache[ index ].ObjLoad( tile_path, p );
++
++    // cout << " ncount before = " << tile_cache[index].ncount << "\n";
++    // cout << " fragments before = " << tile_cache[index].fragment_list.size()
++    //      << "\n";
++
++    string apt_path = tile_path + ".apt";
++    fgAptGenerate( apt_path, &tile_cache[index] );
++
++    // cout << " ncount after = " << tile_cache[index].ncount << "\n";
++    // cout << " fragments after = " << tile_cache[index].fragment_list.size()
++    //      << "\n";
++}
++
++
++// Free a tile cache entry
++void
++fgTILECACHE::entry_free( int index )
++{
++    tile_cache[index].release_fragments();
++}
++
++
++// Return index of next available slot in tile cache
++int
++fgTILECACHE::next_avail( void )
++{
++    Point3D delta, abs_view_pos;
++    int i;
++    float max, med, min, tmp;
++    float dist, max_dist;
++    int max_index;
++    
++    max_dist = 0.0;
++    max_index = 0;
++
++    for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++      if ( ! tile_cache[i].used ) {
++          return(i);
++      } else {
++          // calculate approximate distance from view point
++          abs_view_pos = current_view.get_abs_view_pos();
++
++          FG_LOG( FG_TERRAIN, FG_DEBUG,
++                  "DIST Abs view pos = " << abs_view_pos );
++          FG_LOG( FG_TERRAIN, FG_DEBUG,
++                  "    ref point = " << tile_cache[i].center );
++
++          delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) );
++          delta.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) );
++          delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) );
++
++          max = delta.x(); med = delta.y(); min = delta.z();
++          if ( max < med ) {
++              tmp = max; max = med; med = tmp;
++          }
++          if ( max < min ) {
++              tmp = max; max = min; min = tmp;
++          }
++          dist = max + (med + min) / 4;
++
++          FG_LOG( FG_TERRAIN, FG_DEBUG, "    distance = " << dist );
++
++          if ( dist > max_dist ) {
++              max_dist = dist;
++              max_index = i;
++          }
++      }
++    }
++
++    // If we made it this far, then there were no open cache entries.
++    // We will instead free the furthest cache entry and return it's
++    // index.
++    
++    entry_free( max_index );
++    return( max_index );
++}
++
++
++// Destructor
++fgTILECACHE::~fgTILECACHE( void ) {
++}
++
++
++// $Log$
++// Revision 1.23  1999/03/25 19:03:26  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.22  1999/02/26 22:10:04  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.21  1998/12/09 18:50:32  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.20  1998/11/09 23:40:49  curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling.  Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>.  Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that.  All access seems to be sequential.  Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators.  This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++//   Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++//   Changed fragment list to a vector.
++//   Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++//   use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++//   uses all the new convenience functions.
++//
++// Revision 1.19  1998/11/06 21:18:21  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.18  1998/10/16 18:12:28  curt
++// Fixed a bug in the conversion to Point3D.
++//
++// Revision 1.17  1998/10/16 00:55:48  curt
++// Converted to Point3D class.
++//
++// Revision 1.16  1998/09/14 12:45:23  curt
++// minor tweaks.
++//
++// Revision 1.15  1998/08/27 17:02:10  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.14  1998/08/25 16:52:43  curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++//   ../Objects
++//
++// Revision 1.13  1998/07/13 21:02:00  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.12  1998/07/12 03:18:29  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.11  1998/07/04 00:54:30  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.10  1998/05/23 14:09:22  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.9  1998/05/20 20:53:54  curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.8  1998/05/16 13:09:57  curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++//   scenery generation tools and scenery can be updated.
++//
++// Revision 1.7  1998/05/13 18:26:41  curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.6  1998/05/02 01:52:17  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.5  1998/04/30 12:35:31  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.4  1998/04/28 01:21:43  curt
++// Tweaked texture parameter calculations to keep the number smaller.  This
++// avoids the "swimming" problem.
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3  1998/04/25 22:06:32  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:51:08  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1  1998/04/22 13:22:46  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11  1998/04/18 04:14:07  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10  1998/04/14 02:23:17  curt
++// Code reorganizations.  Added a Lib/ directory for more general libraries.
++//
++// Revision 1.9  1998/04/08 23:30:07  curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.8  1998/04/03 22:11:38  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.7  1998/02/01 03:39:55  curt
++// Minor tweaks.
++//
++// Revision 1.6  1998/01/31 00:43:26  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.5  1998/01/29 00:51:39  curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.4  1998/01/27 03:26:43  curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.3  1998/01/27 00:48:03  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.2  1998/01/26 15:55:24  curt
++// Progressing on building dynamic scenery system.
++//
++// Revision 1.1  1998/01/24 00:03:29  curt
++// Initial revision.
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..49e7c0c7906d205a1c99ac400ec39abf4728a63e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,221 @@@
++// tilecache.hxx -- routines to handle scenery tile caching
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILECACHE_HXX
++#define _TILECACHE_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Bucket/newbucket.hxx>
++#include <Math/point3d.hxx>
++
++#include "tile.hxx"
++
++
++// For best results ... i.e. to avoid tile load problems and blank areas
++//
++// FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2 
++#define FG_TILE_CACHE_SIZE 121
++
++// A class to store and manage a pile of tiles
++class fgTILECACHE {
++
++//     enum
++//     {
++//    // For best results... i.e. to avoid tile load problems and blank areas
++//    // FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2 
++//    FG_TILE_CACHE_SIZE = 121
++//     };
++
++    // cache storage space
++    fgTILE tile_cache[ FG_TILE_CACHE_SIZE ];
++
++public:
++
++    // Constructor
++    fgTILECACHE( void );
++
++    // Initialize the tile cache subsystem 
++    void init( void );
++
++    // Search for the specified "bucket" in the cache 
++    int exists( const FGBucket& p );
++
++    // Return index of next available slot in tile cache 
++    int next_avail( void );
++
++    // Free a tile cache entry
++    void entry_free( int index );
++
++    // Fill in a tile cache entry with real data for the specified bucket 
++    void fill_in( int index, FGBucket& p );
++
++    // Return a pointer to the specified tile cache entry 
++    fgTILE *get_tile( int index ) {
++      return &tile_cache[index];
++    }
++
++    // Destructor
++    ~fgTILECACHE( void );
++};
++
++
++// the tile cache
++extern fgTILECACHE global_tile_cache;
++
++
++#endif // _TILECACHE_HXX 
++
++
++// $Log$
++// Revision 1.14  1999/03/25 19:03:27  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.13  1998/11/09 23:40:51  curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling.  Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>.  Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that.  All access seems to be sequential.  Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators.  This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++//   Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++//   Changed fragment list to a vector.
++//   Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++//   use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++//   uses all the new convenience functions.
++//
++// Revision 1.12  1998/10/16 00:55:49  curt
++// Converted to Point3D class.
++//
++// Revision 1.11  1998/09/14 12:45:25  curt
++// minor tweaks.
++//
++// Revision 1.10  1998/07/04 00:54:31  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.9  1998/05/23 14:09:22  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.8  1998/05/20 20:53:54  curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.7  1998/05/16 13:09:57  curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++//   scenery generation tools and scenery can be updated.
++//
++// Revision 1.6  1998/05/07 23:15:20  curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.5  1998/05/02 01:52:17  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.4  1998/04/30 12:35:31  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.3  1998/04/25 22:06:32  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:51:08  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1  1998/04/22 13:22:47  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.10  1998/04/21 17:02:45  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.9  1998/04/14 02:23:17  curt
++// Code reorganizations.  Added a Lib/ directory for more general libraries.
++//
++// Revision 1.8  1998/04/08 23:30:08  curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.7  1998/04/03 22:11:38  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.6  1998/02/18 15:07:10  curt
++// Tweaks to build with SGI OpenGL (and therefor hopefully other accelerated
++// drivers will work.)
++//
++// Revision 1.5  1998/02/16 13:39:45  curt
++// Miscellaneous weekend tweaks.  Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.4  1998/01/31 00:43:27  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.3  1998/01/29 00:51:40  curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.2  1998/01/27 00:48:04  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.1  1998/01/24 00:03:29  curt
++// Initial revision.
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5c8e9b2c6a3d897780e3f162ad9b6e46e46f614f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1123 @@@
++// tilemgr.cxx -- routines to handle dynamic management of scenery tiles
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++
++#include <Debug/logstream.hxx>
++// #include <Bucket/bucketutils.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Objects/material.hxx>
++#include <Objects/obj.hxx>
++#include <Weather/weather.hxx>
++
++#include "scenery.hxx"
++#include "tile.hxx"
++#include "tilecache.hxx"
++#include "tilemgr.hxx"
++
++
++// to test clipping speedup in fgTileMgrRender()
++#if defined ( USE_FAST_FOV_CLIP )
++  // #define TEST_FOV_CLIP
++  // #define TEST_ELEV
++#endif
++
++
++#define FG_LOCAL_X_Y         81  // max(o->tile_diameter) ** 2
++
++#define FG_SQUARE( X ) ( (X) * (X) )
++
++#if defined(USE_MEM) || defined(WIN32)
++#  define FG_MEM_COPY(to,from,n)        memcpy(to, from, n)
++#else
++#  define FG_MEM_COPY(to,from,n)        bcopy(from, to, n)
++#endif
++
++// closest (potentially viewable) tiles, centered on current tile.
++// This is an array of pointers to cache indexes.
++int tiles[FG_LOCAL_X_Y];
++
++
++// Initialize the Tile Manager subsystem
++int fgTileMgrInit( void ) {
++    FG_LOG( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem." );
++
++    // load default material library
++    material_mgr.load_lib();
++
++    return 1;
++}
++
++
++// load a tile
++void fgTileMgrLoadTile( const FGBucket& p, int *index) {
++    fgTILECACHE *c;
++
++    c = &global_tile_cache;
++
++    FG_LOG( FG_TERRAIN, FG_DEBUG, "Updating for bucket " << p );
++    
++    // if not in cache, load tile into the next available slot
++    *index = c->exists(p);
++    if ( *index < 0 ) {
++      *index = c->next_avail();
++      c->fill_in(*index, p);
++    }
++
++    FG_LOG( FG_TERRAIN, FG_DEBUG, "Selected cache index: " << *index );
++}
++
++
++// Calculate shortest distance from point to line
++static double point_line_dist_squared( const Point3D& tc, const Point3D& vp, 
++                                     MAT3vec d )
++{
++    MAT3vec p, p0;
++    double dist;
++
++    p[0] = tc.x(); p[1] = tc.y(); p[2] = tc.z();
++    p0[0] = vp.x(); p0[1] = vp.y(); p0[2] = vp.z();
++
++    return fgPointLineSquared(p, p0, d);
++}
++
++
++// Determine scenery altitude.  Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely.  lat & lon are in radians.  abs_view_pos in meters.
++// Returns result in meters.
++double
++fgTileMgrCurElevNEW( const FGBucket& p ) {
++    fgTILE *t;
++    fgFRAGMENT *frag_ptr;
++    Point3D abs_view_pos = current_view.get_abs_view_pos();
++    Point3D earth_center(0.0);
++    Point3D result;
++    MAT3vec local_up;
++    double dist, lat_geod, alt, sea_level_r;
++    int index;
++
++    local_up[0] = abs_view_pos.x();
++    local_up[1] = abs_view_pos.y();
++    local_up[2] = abs_view_pos.z();
++
++    // Find current translation offset
++    // fgBucketFind(lon * RAD_TO_DEG, lat * RAD_TO_DEG, &p);
++    index = global_tile_cache.exists(p);
++    if ( index < 0 ) {
++      FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found" );
++      return 0.0;
++    }
++
++    t = global_tile_cache.get_tile(index);
++
++    scenery.next_center = t->center;
++    
++    FG_LOG( FG_TERRAIN, FG_DEBUG, 
++          "Current bucket = " << p << "  Index = " << p.gen_index_str() );
++    FG_LOG( FG_TERRAIN, FG_DEBUG,
++          "abs_view_pos = " << abs_view_pos );
++
++    // calculate tile offset
++    // x = (t->offset.x = t->center.x - scenery.center.x);
++    // y = (t->offset.y = t->center.y - scenery.center.y);
++    // z = (t->offset.z = t->center.z - scenery.center.z);
++    
++    // calc current terrain elevation calculate distance from
++    // vertical tangent line at current position to center of
++    // tile.
++      
++    /* printf("distance squared = %.2f, bounding radius = %.2f\n", 
++       point_line_dist_squared(&(t->offset), &(v->view_pos), 
++       v->local_up), t->bounding_radius); */
++
++    dist = point_line_dist_squared( t->center, abs_view_pos, local_up );
++    if ( dist < FG_SQUARE(t->bounding_radius) ) {
++
++      // traverse fragment list for tile
++        fgTILE::FragmentIterator current = t->begin();
++        fgTILE::FragmentIterator last = t->end();
++
++      for ( ; current != last; ++current ) {
++          frag_ptr = &(*current);
++          /* printf("distance squared = %.2f, bounding radius = %.2f\n", 
++             point_line_dist_squared( &(frag_ptr->center), 
++             &abs_view_pos), local_up),
++             frag_ptr->bounding_radius); */
++
++          dist = point_line_dist_squared( frag_ptr->center,
++                                          abs_view_pos,
++                                          local_up);
++          if ( dist <= FG_SQUARE(frag_ptr->bounding_radius) ) {
++              if ( frag_ptr->intersect( abs_view_pos, 
++                                        earth_center, 0, result ) ) {
++                  FG_LOG( FG_TERRAIN, FG_DEBUG, "intersection point " <<
++                          result );
++                  // compute geocentric coordinates of tile center
++                  Point3D pp = fgCartToPolar3d(result);
++                  FG_LOG( FG_TERRAIN, FG_DEBUG, "  polar form = " << pp );
++                  // convert to geodetic coordinates
++                  fgGeocToGeod(pp.lat(), pp.radius(), &lat_geod, 
++                               &alt, &sea_level_r);
++
++                  // printf("alt = %.2f\n", alt);
++                  // exit since we found an intersection
++                  if ( alt > -9999.0 ) {
++                      // printf("returning alt\n");
++                      return alt;
++                  } else {
++                      // printf("returning 0\n");
++                      return 0.0;
++                  }
++              }
++          }
++      }
++    }
++
++    FG_LOG( FG_TERRAIN, FG_INFO, "(new) no terrain intersection found" );
++
++    return 0.0;
++}
++
++
++// Determine scenery altitude.  Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely.  lat & lon are in radians.  abs_view_pos in meters.
++// Returns result in meters.
++double
++fgTileMgrCurElev( double lon, double lat, const Point3D& abs_view_pos ) {
++    fgTILECACHE *c;
++    fgTILE *t;
++    fgFRAGMENT *frag_ptr;
++    Point3D earth_center(0.0);
++    Point3D result;
++    MAT3vec local_up;
++    double dist, lat_geod, alt, sea_level_r;
++    int index;
++
++    c = &global_tile_cache;
++
++    local_up[0] = abs_view_pos.x();
++    local_up[1] = abs_view_pos.y();
++    local_up[2] = abs_view_pos.z();
++
++    FG_LOG( FG_TERRAIN, FG_DEBUG, "Absolute view pos = " << abs_view_pos );
++
++    // Find current translation offset
++    FGBucket p( lon * RAD_TO_DEG, lat * RAD_TO_DEG );
++    index = c->exists(p);
++    if ( index < 0 ) {
++      FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found" );
++      return 0.0;
++    }
++
++    t = c->get_tile(index);
++
++    scenery.next_center = t->center;
++    
++    FG_LOG( FG_TERRAIN, FG_DEBUG, 
++          "Pos = (" << lon * RAD_TO_DEG << ", " << lat * RAD_TO_DEG
++          << ")  Current bucket = " << p 
++          << "  Index = " << p.gen_index_str() );
++
++    FG_LOG( FG_TERRAIN, FG_DEBUG, "Tile center " << t->center 
++          << "  bounding radius = " << t->bounding_radius );
++
++    // calculate tile offset
++    // x = (t->offset.x = t->center.x - scenery.center.x);
++    // y = (t->offset.y = t->center.y - scenery.center.y);
++    // z = (t->offset.z = t->center.z - scenery.center.z);
++    
++    // calc current terrain elevation calculate distance from
++    // vertical tangent line at current position to center of
++    // tile.
++      
++    /* printf("distance squared = %.2f, bounding radius = %.2f\n", 
++       point_line_dist_squared(&(t->offset), &(v->view_pos), 
++       v->local_up), t->bounding_radius); */
++
++    dist = point_line_dist_squared( t->center, abs_view_pos, local_up );
++    FG_LOG( FG_TERRAIN, FG_DEBUG, "(gross check) dist squared = " << dist );
++
++    if ( dist < FG_SQUARE(t->bounding_radius) ) {
++
++      // traverse fragment list for tile
++        fgTILE::FragmentIterator current = t->begin();
++        fgTILE::FragmentIterator last = t->end();
++
++      for ( ; current != last; ++current ) {
++          frag_ptr = &(*current);
++          /* printf("distance squared = %.2f, bounding radius = %.2f\n", 
++             point_line_dist_squared( &(frag_ptr->center), 
++             &abs_view_pos), local_up),
++             frag_ptr->bounding_radius); */
++
++          dist = point_line_dist_squared( frag_ptr->center,
++                                          abs_view_pos,
++                                          local_up);
++          if ( dist <= FG_SQUARE(frag_ptr->bounding_radius) ) {
++              if ( frag_ptr->intersect( abs_view_pos, 
++                                        earth_center, 0, result ) ) {
++                  FG_LOG( FG_TERRAIN, FG_DEBUG, "intersection point " <<
++                          result );
++                  // compute geocentric coordinates of tile center
++                  Point3D pp = fgCartToPolar3d(result);
++                  FG_LOG( FG_TERRAIN, FG_DEBUG, "  polar form = " << pp );
++                  // convert to geodetic coordinates
++                  fgGeocToGeod(pp.lat(), pp.radius(), &lat_geod, 
++                               &alt, &sea_level_r);
++
++                  // printf("alt = %.2f\n", alt);
++                  // exit since we found an intersection
++                  if ( alt > -9999.0 ) {
++                      // printf("returning alt\n");
++                      return alt;
++                  } else {
++                      // printf("returning 0\n");
++                      return 0.0;
++                  }
++              }
++          }
++      }
++    }
++
++    FG_LOG( FG_TERRAIN, FG_INFO, "(old) no terrain intersection found" );
++
++    return 0.0;
++}
++
++
++// given the current lon/lat, fill in the array of local chunks.  If
++// the chunk isn't already in the cache, then read it from disk.
++int fgTileMgrUpdate( void ) {
++    fgTILECACHE *c;
++    FGInterface *f;
++    FGBucket p2;
++    static FGBucket p_last(false);
++    static double last_lon = -1000.0;  // in degrees
++    static double last_lat = -1000.0;  // in degrees
++    int tile_diameter;
++    int i, j, dw, dh;
++
++    c = &global_tile_cache;
++    f = current_aircraft.fdm_state;
++
++    tile_diameter = current_options.get_tile_diameter();
++
++    FGBucket p1( f->get_Longitude() * RAD_TO_DEG,
++               f->get_Latitude() * RAD_TO_DEG );
++    dw = tile_diameter / 2;
++    dh = tile_diameter / 2;
++
++    if ( p1 == p_last ) {
++      // same bucket as last time
++      FG_LOG( FG_TERRAIN, FG_DEBUG, "Same bucket as last time" );
++    } else if ( p_last.get_lon() == -1000 ) {
++      // First time through, initialize the system and load all
++      // relavant tiles
++
++      FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 );
++      FG_LOG( FG_TERRAIN, FG_INFO, "  First time through ... " );
++      FG_LOG( FG_TERRAIN, FG_INFO, "  Updating Tile list for " << p1 );
++      FG_LOG( FG_TERRAIN, FG_INFO, "  Loading " 
++              << tile_diameter * tile_diameter << " tiles" );
++
++      // wipe/initialize tile cache
++      c->init();
++
++      // build the local area list and update cache
++      for ( j = 0; j < tile_diameter; j++ ) {
++          for ( i = 0; i < tile_diameter; i++ ) {
++              // fgBucketOffset(&p1, &p2, i - dw, j - dh);
++              p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
++                                   f->get_Latitude() * RAD_TO_DEG,
++                                   i - dw, j -dh );
++              fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) + i]);
++          }
++      }
++    } else {
++      // We've moved to a new bucket, we need to scroll our
++        // structures, and load in the new tiles
++
++      // CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES.
++      // AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF
++      // THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION.
++
++      FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 );
++
++      if ( (p1.get_lon() > p_last.get_lon()) ||
++           ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) {
++          FG_LOG( FG_TERRAIN, FG_INFO, 
++                  "  Loading " << tile_diameter << "tiles" );
++          for ( j = 0; j < tile_diameter; j++ ) {
++              // scrolling East
++              for ( i = 0; i < tile_diameter - 1; i++ ) {
++                  tiles[(j*tile_diameter) + i] = 
++                      tiles[(j*tile_diameter) + i + 1];
++              }
++              // load in new column
++              // fgBucketOffset(&p_last, &p2, dw + 1, j - dh);
++              p2 = fgBucketOffset( last_lon, last_lat, dw + 1, j - dh );
++              fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) + 
++                                           tile_diameter - 1]);
++          }
++      } else if ( (p1.get_lon() < p_last.get_lon()) ||
++                  ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() < p_last.get_x()) ) ) {
++          FG_LOG( FG_TERRAIN, FG_INFO, 
++                  "  Loading " << tile_diameter << "tiles" );
++          for ( j = 0; j < tile_diameter; j++ ) {
++              // scrolling West
++              for ( i = tile_diameter - 1; i > 0; i-- ) {
++                  tiles[(j*tile_diameter) + i] = 
++                      tiles[(j*tile_diameter) + i - 1];
++              }
++              // load in new column
++              // fgBucketOffset(&p_last, &p2, -dw - 1, j - dh);
++              p2 = fgBucketOffset( last_lon, last_lat, -dw - 1, j - dh );
++              fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) + 0]);
++          }
++      }
++
++      if ( (p1.get_lat() > p_last.get_lat()) ||
++           ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) {
++          FG_LOG( FG_TERRAIN, FG_INFO, 
++                  "  Loading " << tile_diameter << "tiles" );
++          for ( i = 0; i < tile_diameter; i++ ) {
++              // scrolling North
++              for ( j = 0; j < tile_diameter - 1; j++ ) {
++                  tiles[(j * tile_diameter) + i] =
++                      tiles[((j+1) * tile_diameter) + i];
++              }
++              // load in new column
++              // fgBucketOffset(&p_last, &p2, i - dw, dh + 1);
++              p2 = fgBucketOffset( last_lon, last_lat, i - dw, dh + 1);
++              fgTileMgrLoadTile( p2, &tiles[((tile_diameter-1) * 
++                                             tile_diameter) + i]);
++          }
++      } else if ( (p1.get_lat() < p_last.get_lat()) ||
++                  ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) {
++          FG_LOG( FG_TERRAIN, FG_INFO, 
++                  "  Loading " << tile_diameter << "tiles" );
++          for ( i = 0; i < tile_diameter; i++ ) {
++              // scrolling South
++              for ( j = tile_diameter - 1; j > 0; j-- ) {
++                  tiles[(j * tile_diameter) + i] = 
++                      tiles[((j-1) * tile_diameter) + i];
++              }
++              // load in new column
++              // fgBucketOffset(&p_last, &p2, i - dw, -dh - 1);
++              p2 = fgBucketOffset( last_lon, last_lat, i - dw, -dh - 1);
++              fgTileMgrLoadTile( p2, &tiles[0 + i]);
++          }
++      }
++    }
++
++    // find our current elevation (feed in the current bucket to save work)
++    Point3D geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
++    Point3D tmp_abs_view_pos = fgGeodToCart(geod_pos);
++
++    scenery.cur_elev = 
++      fgTileMgrCurElev( f->get_Longitude(), f->get_Latitude(), 
++                        tmp_abs_view_pos );
++
++    p_last = p1;
++    last_lon = f->get_Longitude() * RAD_TO_DEG;
++    last_lat = f->get_Latitude() * RAD_TO_DEG;
++
++    return 1;
++}
++
++
++// Calculate if point/radius is inside view frustum
++static int viewable( const Point3D& cp, double radius ) {
++    int viewable = 1; // start by assuming it's viewable
++    double x1, y1;
++
++/********************************/
++#if defined( USE_FAST_FOV_CLIP ) // views.hxx
++/********************************/
++      
++    MAT3vec eye;      
++    double *mat;
++    double x, y, z;
++
++    x = cp.x();
++    y = cp.y();
++    z = cp.z();
++      
++    mat = (double *)(current_view.get_WORLD_TO_EYE());
++      
++    eye[2] =  x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
++      
++    // Check near and far clip plane
++    if( ( eye[2] > radius ) ||
++      ( eye[2] + radius + current_weather.get_visibility() < 0) )
++    {
++      return(0);
++    }
++      
++    eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12])
++      * current_view.get_slope_x();
++
++    // check right and left clip plane (from eye perspective)
++    x1 = radius * current_view.get_fov_x_clip();
++    if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) )
++    {
++      return(0);
++    }
++      
++    eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13]) 
++      * current_view.get_slope_y();
++
++    // check bottom and top clip plane (from eye perspective)
++    y1 = radius * current_view.get_fov_y_clip();
++    if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) )
++    {
++      return(0);
++    }
++
++/********************************/    
++#else // DO NOT USE_FAST_FOV_CLIP
++/********************************/    
++
++    fgVIEW *v;
++    MAT3hvec world, eye;
++    double x0, slope;
++
++    v = &current_view;
++
++    MAT3_SET_HVEC(world, cp->x, cp->y, cp->z, 1.0);
++    // MAT3mult_vec(eye, world, v->WORLD_TO_EYE);
++    // printf( "\nworld -> eye = %.2f %.2f %.2f  radius = %.2f\n", 
++    //         eye[0], eye[1], eye[2], radius);
++
++    // Use lazy evaluation for calculating eye hvec.
++#define vec world
++#define mat v->WORLD_TO_EYE
++    eye[2] = vec[0]*mat[0][2]+vec[1]*mat[1][2]+vec[2]*mat[2][2]+mat[3][2];
++
++    // Check near clip plane
++    if ( eye[2] > radius ) {
++      return(0);
++    }
++
++    // Check far clip plane
++    if ( eye[2] + radius < -current_weather.get_visibility() ) {
++      return(0);
++    }
++
++    // check right clip plane (from eye perspective)
++    // y = m * (x - x0) = equation of a line intercepting X axis at x0
++    x1 = v->cos_fov_x * radius;
++    y1 = v->sin_fov_x * radius;
++    slope = v->slope_x;
++    eye[0] = vec[0]*mat[0][0]+vec[1]*mat[1][0]+vec[2]*mat[2][0]+mat[3][0];
++
++    if ( eye[2] > ((slope * (eye[0] - x1)) + y1) ) {
++      return( false );
++    }
++
++    // check left clip plane (from eye perspective)
++    if ( eye[2] > -((slope * (eye[0] + x1)) - y1) ) {
++      return( false );
++    }
++
++    // check bottom clip plane (from eye perspective)
++    x1 = -(v->cos_fov_y) * radius;
++    y1 = v->sin_fov_y * radius;
++    slope = v->slope_y;
++    eye[1] = vec[0]*mat[0][1]+vec[1]*mat[1][1]+vec[2]*mat[2][1]+mat[3][1];
++#undef vec
++#undef mat
++
++    if ( eye[2] > ((slope * (eye[1] - x1)) + y1) ) {
++      return( false );
++    }
++
++    // check top clip plane (from eye perspective)
++    if ( eye[2] > -((slope * (eye[1] + x1)) - y1) ) {
++      return( false );
++    }
++
++#endif // defined( USE_FAST_FOV_CLIP )
++      
++    return(viewable);
++}
++
++
++// NEW 
++
++// inrange() IS THIS POINT WITHIN POSSIBLE VIEWING RANGE ?
++//    calculate distance from vertical tangent line at
++//    current position to center of object.
++//    this is equivalent to
++//    dist = point_line_dist_squared( &(t->center), &(v->abs_view_pos), 
++//                                    v->local_up );
++//    if ( dist < FG_SQUARE(t->bounding_radius) ) {
++//
++// the compiler should inline this for us
++
++static int
++inrange( const double radius, const Point3D& center, const Point3D& vp,
++       const MAT3vec up)
++{
++    MAT3vec u, u1, v;
++    //        double tmp;
++      
++    // u = p - p0
++    u[0] = center.x() - vp.x();
++    u[1] = center.y() - vp.y();
++    u[2] = center.z() - vp.z();
++      
++    // calculate the projection, u1, of u along d.
++    // u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
++      
++    MAT3_SCALE_VEC(u1, up,
++                 (MAT3_DOT_PRODUCT(u, up) / MAT3_DOT_PRODUCT(up, up)) );
++    
++    // v = u - u1 = vector from closest point on line, p1, to the
++    // original point, p.
++    MAT3_SUB_VEC(v, u, u1);
++      
++    return( FG_SQUARE(radius) >= MAT3_DOT_PRODUCT(v, v));
++}
++
++
++// NEW for legibility
++
++// update this tile's geometry for current view
++// The Compiler should inline this
++static void
++update_tile_geometry( fgTILE *t, GLdouble *MODEL_VIEW)
++{
++    GLdouble *m;
++    double x, y, z;
++      
++    // calculate tile offset
++    t->offset = t->center - scenery.center;
++
++    x = t->offset.x();
++    y = t->offset.y();
++    z = t->offset.z();
++      
++    m = t->model_view;
++      
++    // Calculate the model_view transformation matrix for this tile
++    FG_MEM_COPY( m, MODEL_VIEW, 16*sizeof(GLdouble) );
++    
++    // This is equivalent to doing a glTranslatef(x, y, z);
++    m[12] += (m[0]*x + m[4]*y + m[8] *z);
++    m[13] += (m[1]*x + m[5]*y + m[9] *z);
++    m[14] += (m[2]*x + m[6]*y + m[10]*z);
++    // m[15] += (m[3]*x + m[7]*y + m[11]*z);
++    // m[3] m7[] m[11] are 0.0 see LookAt() in views.cxx
++    // so m[15] is unchanged
++}
++
++
++// Render the local tiles
++void fgTileMgrRender( void ) {
++    FGInterface *f;
++    fgTILECACHE *c;
++    fgTILE *t;
++    FGView *v;
++    Point3D frag_offset;
++    fgFRAGMENT *frag_ptr;
++    fgMATERIAL *mtl_ptr;
++    int i;
++    int tile_diameter;
++    int index;
++    int culled = 0;
++    int drawn = 0;
++
++    c = &global_tile_cache;
++    f = current_aircraft.fdm_state;
++    v = &current_view;
++
++    tile_diameter = current_options.get_tile_diameter();
++
++    // moved to fgTileMgrUpdate, right after we check if we need to
++    // load additional tiles:
++    // scenery.cur_elev = fgTileMgrCurElev( FG_Longitude, FG_Latitude, 
++    //                                      v->abs_view_pos );
++ 
++    // initialize the transient per-material fragment lists
++    material_mgr.init_transient_material_lists();
++   
++    // Pass 1
++    // traverse the potentially viewable tile list
++    for ( i = 0; i < (tile_diameter * tile_diameter); i++ ) {
++      index = tiles[i];
++      // fgPrintf( FG_TERRAIN, FG_DEBUG, "Index = %d\n", index);
++      t = c->get_tile(index);
++
++      // calculate tile offset
++      t->SetOffset( scenery.center );
++
++      // Course (tile based) culling
++      if ( viewable(t->offset, t->bounding_radius) ) {
++          // at least a portion of this tile could be viewable
++          
++          // Calculate the model_view transformation matrix for this tile
++          // This is equivalent to doing a glTranslatef(x, y, z);
++          t->UpdateViewMatrix( v->get_MODEL_VIEW() );
++
++          // xglPushMatrix();
++          // xglTranslatef(t->offset.x, t->offset.y, t->offset.z);
++
++          // traverse fragment list for tile
++            fgTILE::FragmentIterator current = t->begin();
++            fgTILE::FragmentIterator last = t->end();
++
++          for ( ; current != last; ++current ) {
++              frag_ptr = &(*current);
++              
++              if ( frag_ptr->display_list >= 0 ) {
++                  // Fine (fragment based) culling
++                  frag_offset = frag_ptr->center - scenery.center;
++
++                  if ( viewable(frag_offset, frag_ptr->bounding_radius*2) ) {
++                      // add to transient per-material property fragment list
++                      // frag_ptr->tile_offset.x = t->offset.x;
++                      // frag_ptr->tile_offset.y = t->offset.y;
++                      // frag_ptr->tile_offset.z = t->offset.z;
++
++                      mtl_ptr = frag_ptr->material_ptr;
++                      // printf(" lookup = %s\n", mtl_ptr->texture_name);
++                      if ( ! mtl_ptr->append_sort_list( frag_ptr ) ) {
++                          FG_LOG( FG_TERRAIN, FG_ALERT,
++                                  "Overran material sorting array" );
++                      }
++
++                      // xglCallList(frag_ptr->display_list);
++                      drawn++;
++                  } else {
++                      // printf("Culled a fragment %.2f %.2f %.2f %.2f\n",
++                      //        frag_ptr->center.x, frag_ptr->center.y,
++                      //        frag_ptr->center.z, frag_ptr->bounding_radius);
++                      culled++;
++                  }
++              }
++          }
++
++          // xglPopMatrix();
++      } else {
++          culled += t->fragment_list.size();
++      }
++    }
++
++    if ( (drawn + culled) > 0 ) {
++      v->set_vfc_ratio( (double)culled / (double)(drawn + culled) );
++    } else {
++      v->set_vfc_ratio( 0.0 );
++    }
++    // printf("drawn = %d  culled = %d  saved = %.2f\n", drawn, culled, 
++    //        v->vfc_ratio);
++
++    // Pass 2
++    // traverse the transient per-material fragment lists and render
++    // out all fragments for each material property.
++    xglPushMatrix();
++    material_mgr.render_fragments();
++    xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.55  1999/03/25 19:03:28  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.54  1999/02/26 22:10:05  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.53  1999/02/05 21:29:16  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.52  1999/01/27 04:49:48  curt
++// Fixes so that the sim can start out at an airport below sea level.
++//
++// Revision 1.51  1998/12/09 18:50:33  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.50  1998/12/06 13:51:25  curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.49  1998/12/05 15:54:26  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.48  1998/12/05 14:20:21  curt
++// Looking into a terrain intersection problem.
++//
++// Revision 1.47  1998/12/05 14:11:19  curt
++// Sun portability tweak.
++//
++// Revision 1.46  1998/12/03 14:15:24  curt
++// Actually set the current scenery elevation based on scenery intersection point
++// rather than calculating the intesection point and throwing it away.
++//
++// Revision 1.45  1998/12/03 01:18:18  curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.44  1998/11/23 21:49:48  curt
++// minor tweaks.
++//
++// Revision 1.43  1998/11/09 23:40:52  curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling.  Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>.  Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that.  All access seems to be sequential.  Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators.  This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++//   Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++//   Changed fragment list to a vector.
++//   Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++//   use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++//   uses all the new convenience functions.
++//
++// Revision 1.42  1998/11/06 21:18:23  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.41  1998/10/18 01:17:23  curt
++// Point3D tweaks.
++//
++// Revision 1.40  1998/10/17 01:34:28  curt
++// C++ ifying ...
++//
++// Revision 1.39  1998/10/16 00:55:50  curt
++// Converted to Point3D class.
++//
++// Revision 1.38  1998/09/17 18:36:18  curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.37  1998/09/15 01:36:45  curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.36  1998/09/14 12:45:26  curt
++// minor tweaks.
++//
++// Revision 1.35  1998/09/10 19:07:16  curt
++// /Simulator/Objects/fragment.hxx
++//   Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++//   Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++//   data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++//   In viewable() delay evaluation of eye[0] and eye[1] in until they're
++//   actually needed.
++//   Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++//   method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++//   Added support for g++ 2.7.
++//   Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++//   operator->() not supported by iterators: use (*i).x instead of i->x
++//   default template arguments not supported,
++//   <functional> doesn't have mem_fun_ref() needed by callbacks.
++//   some std include files have different names.
++//   template member functions not supported.
++//
++// Revision 1.34  1998/09/09 20:58:09  curt
++// Tweaks to loop constructs with STL usage.
++//
++// Revision 1.33  1998/09/08 15:05:10  curt
++// Optimization by Norman Vine.
++//
++// Revision 1.32  1998/08/25 16:52:44  curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++//   ../Objects
++//
++// Revision 1.31  1998/08/24 20:11:40  curt
++// Tweaks ...
++//
++// Revision 1.30  1998/08/22  14:49:59  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.29  1998/08/20 15:12:06  curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.28  1998/08/12 21:13:06  curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.27  1998/07/24 21:42:09  curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.26  1998/07/20 12:51:26  curt
++// Added far clip plane to fragment clipping calculations and tie this to
++// weather->visibility.  This way you can increase framerates by increasing
++// for and lowering visibility.
++//
++// Revision 1.25  1998/07/13 21:02:01  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.24  1998/07/12 03:18:29  curt
++// Added ground collision detection.  This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++//   an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.23  1998/07/08 14:47:23  curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.22  1998/07/04 00:54:31  curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.21  1998/06/27 16:54:59  curt
++// Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
++//   "EXT" versions of texture management routines.
++//
++// Revision 1.20  1998/06/17 21:36:42  curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.19  1998/06/08 17:57:54  curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.18  1998/06/06 01:09:32  curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.17  1998/06/06 01:07:18  curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.16  1998/06/05 22:39:55  curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.15  1998/06/03 00:47:51  curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.14  1998/06/01 17:56:20  curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.13  1998/05/24 02:49:10  curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.12  1998/05/23 14:09:23  curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.11  1998/05/20 20:53:55  curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.10  1998/05/17 16:59:34  curt
++// Frist pass at view frustum culling now operational.
++//
++// Revision 1.9  1998/05/16 13:09:58  curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++//   scenery generation tools and scenery can be updated.
++//
++// Revision 1.8  1998/05/07 23:15:21  curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.7  1998/05/06 03:16:42  curt
++// Added an option to control square tile radius.
++//
++// Revision 1.6  1998/05/02 01:52:18  curt
++// Playing around with texture coordinates.
++//
++// Revision 1.5  1998/04/30 12:35:32  curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.4  1998/04/27 03:30:14  curt
++// Minor transformation adjustments to try to keep scenery tiles closer to
++// (0, 0, 0)  GLfloats run out of precision at the distances we need to model
++// the earth, but we can do a bunch of pre-transformations using double math
++// and then cast to GLfloat once everything is close in where we have less
++// precision problems.
++//
++// Revision 1.3  1998/04/25 22:06:32  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/24 00:51:09  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1  1998/04/22 13:22:48  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.25  1998/04/18 04:14:07  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.24  1998/04/14 02:23:18  curt
++// Code reorganizations.  Added a Lib/ directory for more general libraries.
++//
++// Revision 1.23  1998/04/08 23:30:08  curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.22  1998/04/03 22:11:38  curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.21  1998/03/23 21:23:05  curt
++// Debugging output tweaks.
++//
++// Revision 1.20  1998/03/14 00:30:51  curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.19  1998/02/20 00:16:25  curt
++// Thursday's tweaks.
++//
++// Revision 1.18  1998/02/19 13:05:54  curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.17  1998/02/16 13:39:46  curt
++// Miscellaneous weekend tweaks.  Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.16  1998/02/12 21:59:53  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.14  1998/02/09 21:30:19  curt
++// Fixed a nagging problem with terrain tiles not "quite" matching up perfectly.
++//
++// Revision 1.13  1998/02/07 15:29:46  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12  1998/02/01 03:39:55  curt
++// Minor tweaks.
++//
++// Revision 1.11  1998/01/31 00:43:27  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.10  1998/01/29 00:51:40  curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.9  1998/01/27 03:26:44  curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.8  1998/01/27 00:48:04  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7  1998/01/26 15:55:25  curt
++// Progressing on building dynamic scenery system.
++//
++// Revision 1.6  1998/01/24 00:03:30  curt
++// Initial revision.
++//
++// Revision 1.5  1998/01/19 19:27:18  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4  1998/01/19 18:40:38  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3  1998/01/13 00:23:11  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.2  1998/01/08 02:22:27  curt
++// Continue working on basic features.
++//
++// Revision 1.1  1998/01/07 23:50:51  curt
++// "area" renamed to "tile"
++//
++// Revision 1.2  1998/01/07 03:29:29  curt
++// Given an arbitrary lat/lon, we can now:
++//   generate a unique index for the chunk containing the lat/lon
++//   generate a path name to the chunk file
++//   build a list of the indexes of all the nearby areas.
++//
++// Revision 1.1  1998/01/07 02:05:48  curt
++// Initial revision.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d35958c8852f35e3c0df0efc51aad1355e7f959b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,113 @@@
++// tilemgr.hxx -- routines to handle dynamic management of scenery tiles
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILEMGR_HXX
++#define _TILEMGR_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Bucket/newbucket.hxx>
++
++
++// Initialize the Tile Manager subsystem
++int fgTileMgrInit( void );
++
++
++// given the current lon/lat, fill in the array of local chunks.  If
++// the chunk isn't already in the cache, then read it from disk.
++int fgTileMgrUpdate( void );
++
++
++// Determine scenery altitude.  Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely.  lat & lon are in radians.  abs_view_pos in meters.
++// Returns result in meters.
++double fgTileMgrCurElevNEW( const FGBucket& p );
++double fgTileMgrCurElev( double lon, double lat, const Point3D& abs_view_pos );
++
++
++// Render the local tiles --- hack, hack, hack
++void fgTileMgrRender( void );
++
++
++#endif // _TILEMGR_HXX
++
++
++// $Log$
++// Revision 1.8  1999/03/25 19:03:29  curt
++// Converted to use new bucket routines.
++//
++// Revision 1.7  1999/01/27 04:49:49  curt
++// Fixes so that the sim can start out at an airport below sea level.
++//
++// Revision 1.6  1998/12/03 01:18:19  curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.5  1998/10/16 00:55:52  curt
++// Converted to Point3D class.
++//
++// Revision 1.4  1998/09/09 20:58:11  curt
++// Tweaks to loop constructs with STL usage.
++//
++// Revision 1.3  1998/08/22  14:49:59  curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.2  1998/05/20 20:53:56  curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.1  1998/04/22 13:22:49  curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.6  1998/04/21 17:02:45  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.5  1998/02/12 21:59:53  curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.4  1998/01/22 02:59:42  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3  1998/01/19 18:40:38  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.2  1998/01/13 00:23:11  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.1  1998/01/07 23:50:51  curt
++// "area" renamed to "tile"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4a35d93101b44733bc1cda47d205a61fc69d4f5f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,166 @@@
++--------------------------------------------------------------------------
++| Done
++--------------------------------------------------------------------------
++
++7/21/98 -  add a --enable/disable-sound option.
++
++7/11/98 -  Ground collision detection
++
++7/3/98 -   Generate and store the transform matrix when rendering by
++           material property so we don't have to push, transform, pop
++           continually.  See mesa code for gluLookAt()
++
++6/11/98 -  convert to static libraries and reduce libtool usage ...
++
++6/11/98 -  Converted to GL_FOG_EXP2
++
++5/29/98 -  Widened edges of tiles to overlap a bit.  This should help 
++           reduce floating point induced gaps between tiles.
++
++5/27/98 -  Rewrote airport list manager using an STL "map" (associative
++           array) for quick lookup.
++
++5/26/98 -  Impose a maximum triangle area during scenery generation so
++           even very flat areas will get split into a few smaller sub
++           triangles.
++
++5/26/98 -  Overhaul view parameter generation ... see if we can piggy
++           back off of larcsim calcs, and consolate potentially
++           redundant code -- Norman Vine
++
++5/24/98 -  Fine grain view frustum culling
++
++5/20/98 -  fix winding problem with tri-strips in obj.c (wait for next
++           version of stripe)
++
++5/17/98 -  Course grain (tile based) view frustum culling
++
++5/6/98 -   HUD updates from Jeff Goeke-Smith.
++
++5/5/98 -   Added a visual frame rate counter on the HUD.
++
++5/2/98  -  Option to go full screen.  call glutFullScreen()
++
++4/29/98 -  Option to toggle between smooth / flat shading.
++
++4/28/98 -  Physically check if airport list overruns array size when loading.
++
++4/28/98 -  Wrap up zlib so we can conditionally compile back in normal
++           behavior on systems that have trouble building zlib.
++
++4/27/98 -  Do a better job of translating scenery tiles towards (0,0,0)
++
++4/27/98 -  fgTIME fgVIEW struct -> typedef
++
++4/27/98 -  Add a option to disable texturing.
++
++4/25/98 -  Clean up initialization sequence and eliminate
++           interdependencies between lighting and position.
++
++4/23/98 -  encapsulate all #include <config.h>'s with #ifdef HAVE_CONFIG_H
++
++4/23/98 -  Give all textured polygons ambient and diffuse glMaterial()
++           properties of "white" so GL_MODULATE works as expected and
++           textures are not oddly tinted.
++
++4/21/98 -  Convert lighting equations to table lookups
++
++4/21/98 -  Make sure all #ifdef _cplusplus are after any other includes
++           Make sure all .hxx files have #ifndef cplusplus #error
++
++4/21/98 -  various autoconf cleanups/preparation for C++
++
++4/9/98 -   Fixed a bug in event management where the next event run time
++           was miscalculated so it was never run.
++
++4/6/98 -   Cleanups
++
++--------------------------------------------------------------------------
++
++4/3/98 -   Released version 0.40
++
++4/3/98 -   Incorporated the Gnu automake/autoconf/libtool system.
++
++3/17/98  - Fix time jumping problem on win32
++
++3/1/98 -   Unify sun position render code with existing sunpos
++           calculations so the sun doesn't do it's little jump every
++           hour.
++
++2/19/98 -  Fixed a problem with smooth view (scenery center) switch
++           when entering a new tile.
++
++2/18/98 -  Fixed a problem with terrain generation that was causing
++           some strips to be put in the wrong winding list.
++
++2/9/98 -   Fixed a problem with terrain tiles not quite matching up perfectly.
++
++2/2/98 -   Fix warning when compiling with c++ ... also successfully built 
++           with cygnus-g++.  There should be nothing holding us back from 
++           using C++.
++
++1/30/98 -  remove Scenery/geometry.c and Scenery/mesh.c
++   
++1/28/98 -  Dynamic unloading of scenery.
++
++1/26/98 -  Debug message system.
++
++1/26/98 -  Dynamic loading of scenery
++
++1/24/98 -  Remove some of the unused files such as ls_sync.c
++
++1/23/98 -  in all .h's change #ifdef FILE_H -> #ifdef _FILE_H
++
++--------------------------------------------------------------------------
++
++1/22/98 -  Released version 0.25
++
++1/19/98 -  Compile with c++
++
++1/17/98 -  Change all "type function();" to "type function( void );"
++
++--------------------------------------------------------------------------
++
++1/16/98 -  Release verison 0.23
++
++1/6/98 -   Added FGwin32.mak (a MSVC++ Makefile for building win32 versions)
++
++--------------------------------------------------------------------------
++
++1/5/98 -   Released version 0.21
++
++12/31/97 - remove Unix dependencies from .../Time/fg_time.c
++
++--------------------------------------------------------------------------
++
++12/30/97 - Released version 0.20
++
++12/30/97 - Released version 0.19
++
++12/30/97 - Event manager
++
++12/23/97 - First stab at a reasonable sky ... I'm going to probably
++           leave this for now so I don't spend the rest of my life
++           trying to tweak it.
++
++12/17/97 - Released version 0.18
++
++12/17/97 - Fix sun/moon initialization code so display lists aren't 
++           re-created at every Init().
++
++12/12/97 - Released verison 0.17
++
++12/10/97 - Released version 0.16
++
++12/9/97 -  Released demtools version 0.01
++
++12/9/97 -  Released version 0.15
++
++11/25/97 - Released version 0.14
++
++10/24/97 - Released version 0.13
++
++9/22/97 -  Released version 0.12
++
++9/16/97 -  Released version 0.11
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e806ae16c58c3492230c25cbfb8858fb4881f953
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++SUBDIRS = \
++      Aircraft \
++      Airports \
++      Astro \
++      Autopilot \
++      Cockpit \
++      Controls \
++      FDM \
++      GUI \
++      Joystick \
++      Objects \
++      Scenery \
++      Time \
++      Weather \
++      Main
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3c9601b9839196fa4ee9a6c30af22f487efbf033
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,75 @@@
++--------------------------------------------------------------------------
++| Todo 
++--------------------------------------------------------------------------
++
++        -  M82, HSV , 3M5
++           Charlie Scanlon (757) 864-2034 LaRC
++           Geotif - geolocation tools for mapping.
++           Dr. Nevan Bryant (818) 354-7236
++           Position Integrity -- Terravoid Bob Servano (714) 854-2643
++              http://www.jpl.nasa.gov/releases/98/damds3.html
++           Press release # 
++           John G. Watson (818) 354-5011 release 98-52
++
++7/22/98 -  add some trig debugging wrappers that can be #ifdef'd in
++           kind of like the xgl stuff.  The debugging version can do
++           bounds checking and such.
++
++6/10/98 -  problem with view culling when not looking forward.  Need to 
++           generate the correct matrix and work it into the calculations.
++
++6/10/98 -  terrain generation - add an option to try to iteratively change
++           the error tolerance to try to generate "close" to a certain
++           number of vertices so that we can have consistent size, rendering
++           speed etc. among various terrain tiles.
++
++5/26/98 -  Add version checking to scenery files
++
++4/25/98 -  Roll all of Time/sunpos.cxx into Astro/sun.cxx
++
++4/21/98 -  Tweak lighting parameter interpolation tables to better fit
++           "perceived" reality
++
++4/21/98 -  Make sure all .hxx files have #ifndef cplusplus #error
++           Make sure all #ifdef _FILE_H or _FILE_HXX
++
++4/14/98 -  Convert gl__() calls in Cockpit/ to xgl__() calls
++
++12/29/97 - Add a mechanism to parse additional command line options?
++    * No astronomy.
++    * Less detailed terrain.
++    * Texture - but no MIP-mapping.
++    * Texture - but no bilinear blending.
++
++12/29/97 - sky tweaking
++  Steve Baker writes:
++    So, by building the sky in the flattened shape, we can have it be
++    very foggy at the horizon and clear blue overhead.
++
++    The other important feature of this model is the colours. We
++    colour each vertex of the dish individually to allow for cute
++    sunsets, a darker blue overhead than at the horizon in daylight, a
++    gradual darkening of the sky as a function of altitude for very
++    high altitude flight - into space. Also we tint the horizon more
++    in the direction of the sun so that sunset starts where the sun
++    goes down - and the sky remains blue on the opposite side of the
++    sky - then as the sun gets lower, the colour spreads outwards all
++    around the sky and the black of night creeps in slowly from the
++    opposite side of the sky from the sunset.
++
++    We also like to tint the bottom edge of the sky with white - even
++    in broad daylight - so it looks fuzzy - even when there is very
++    little fog to achieve that effect.
++
++    We use a text file that contains a lookup table relating the sun
++    angle relative to the horizon to:
++
++    *  The colour at the top of the sky dome,
++    *  The colour of the horizon nearest to the sun
++    *  The colour of the horizon farthest from the sun
++    *  The colour of the texture environment blend for the clouds.
++    *  The fog colour.
++
++    We can then tweak that file to set up all the conditions. The
++    realtime system interpolates the horizon colours all around the edge
++    of the sky.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ff257f02928811006f0e9ccf54239519ed192054
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++noinst_LIBRARIES = libSlew.a
++
++libSlew_a_SOURCES = slew.cxx slew.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2706b990641affd9845d55561742d8243604db24
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,155 @@@
++// slew.cxx -- the "slew" flight model
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#include <math.h>
++
++#include "slew.hxx"
++
++#include <FDM/flight.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Include/fg_constants.h>
++
++
++// reset flight params to a specific position
++void fgSlewInit(double pos_x, double pos_y, double pos_z, double heading) {
++    FGInterface *f;
++    
++    f = current_aircraft.fdm_state;
++
++    /*
++    f->pos_x = pos_x;
++    f->pos_y = pos_y;
++    f->pos_z = pos_z;
++
++    f->vel_x = 0.0;
++    f->vel_y = 0.0;
++    f->vel_z = 0.0;
++
++    f->Phi = 0.0;
++    f->Theta = 0.0;
++    f->Psi = 0.0;
++
++    f->vel_Phi = 0.0;
++    f->vel_Theta = 0.0;
++    f->vel_Psi = 0.0;
++
++    f->Psi = heading;
++    */
++}
++
++
++// update position based on inputs, positions, velocities, etc.
++void fgSlewUpdate( void ) {
++    FGInterface *f;
++    FGControls *c;
++
++    f = current_aircraft.fdm_state;
++    c = current_aircraft.controls;
++
++    /* f->Psi += ( c->aileron / 8 );
++    if ( f->Psi > FG_2PI ) {
++      f->Psi -= FG_2PI;
++    } else if ( f->Psi < 0 ) {
++      f->Psi += FG_2PI;
++    }
++
++    f->vel_x = -c->elev;
++
++    f->pos_x = f->pos_x + (cos(f->Psi) * f->vel_x);
++    f->pos_y = f->pos_y + (sin(f->Psi) * f->vel_x); */
++}
++
++
++// $Log$
++// Revision 1.6  1999/02/05 21:29:05  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5  1999/02/01 21:33:33  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.4  1998/12/05 16:13:14  curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.3  1998/12/05 15:54:16  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2  1998/10/17 01:34:17  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/16 23:27:50  curt
++// C++-ifying.
++//
++// Revision 1.13  1998/04/25 22:06:29  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.12  1998/04/08 23:35:30  curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.11  1998/02/07 15:29:39  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10  1998/01/27 00:47:53  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9  1998/01/19 19:27:06  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.8  1998/01/19 18:40:30  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7  1997/12/15 23:54:42  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6  1997/08/27 03:30:11  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5  1997/07/19 22:35:06  curt
++// Moved fiddled with PI to avoid compiler warnings.
++//
++// Revision 1.4  1997/06/21 17:12:51  curt
++// Capitalized subdirectory names.
++//
++// Revision 1.3  1997/05/29 22:40:00  curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.2  1997/05/29 12:30:19  curt
++// Some initial mods to work better in a timer environment.
++//
++// Revision 1.1  1997/05/29 02:29:42  curt
++// Moved to their own directory.
++//
++// Revision 1.2  1997/05/23 15:40:37  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 16:04:45  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f6b4e309c1864eeb2b5852373e7c72d798cd0737
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,70 @@@
++// slew.hxx -- the "slew" flight model
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _SLEW_HXX
++#define _SLEW_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++// reset flight params to a specific position 
++void fgSlewInit(double pos_x, double pos_y, double pos_z, double heading);
++
++// update position based on inputs, positions, velocities, etc.
++void fgSlewUpdate( void );
++
++
++#endif // _SLEW_HXX
++
++
++// $Log$
++// Revision 1.2  1998/10/17 01:34:18  curt
++// C++ ifying ...
++//
++// Revision 1.1  1998/10/16 23:27:52  curt
++// C++-ifying.
++//
++// Revision 1.4  1998/01/22 02:59:34  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3  1998/01/19 18:40:30  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.2  1997/07/23 21:52:20  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.1  1997/05/29 02:29:43  curt
++// Moved to their own directory.
++//
++// Revision 1.2  1997/05/23 15:40:38  curt
++// Added GNU copyright headers.
++//
++// Revision 1.1  1997/05/16 16:04:46  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..657a74240d8cbd21fd7d34a7a895babbbcfd1e26
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++if HAVE_DAYLIGHT
++DEFS += -DHAVE_DAYLIGHT
++endif
++
++if HAVE_TIMEZONE
++DEFS += -DHAVE_TIMEZONE
++endif
++
++noinst_LIBRARIES = libTime.a
++
++libTime_a_SOURCES = \
++      event.cxx event.hxx \
++      fg_time.cxx fg_time.hxx \
++      fg_timer.cxx fg_timer.hxx \
++      light.cxx light.hxx \
++      moonpos.cxx moonpos.hxx \
++      sunpos.cxx sunpos.hxx \
++      timestamp.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d1c622ead09556d0aed56834a68e2787e66a669b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,462 @@@
++// event.cxx -- Flight Gear periodic event scheduler
++//
++// Written by Curtis Olson, started December 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <string>
++
++#include "Include/compiler.h"
++
++#include STL_ALGORITHM
++#include STL_FUNCTIONAL
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cstdio>
++#  ifdef HAVE_STDLIB_H
++#    include <cstdlib>
++#  endif
++#else
++#  include <stdio.h>
++#  ifdef HAVE_STDLIB_H
++#    include <stdlib.h>
++#  endif
++#endif
++
++#if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
++#  include <windows.h>         // For Metrowerks environment
++#  include <winbase.h>         // There is no ANSI/MSL time function that
++                         // contains milliseconds
++#endif
++
++#include <Debug/logstream.hxx>
++
++#include "event.hxx"
++
++FG_USING_STD(for_each);
++FG_USING_STD(mem_fun);
++
++fgEVENT_MGR global_events;
++
++
++fgEVENT::fgEVENT( const string& desc,
++                const fgCallback& cb,
++                EventState evt_status,
++                int evt_interval )
++    : description(desc),
++      event_cb(cb.clone()),
++      status(evt_status),
++      interval(evt_interval),
++      cum_time(0),
++      min_time(100000),
++      max_time(0),
++      count(0)
++{
++}
++
++#if 0
++fgEVENT::fgEVENT( const fgEVENT& evt )
++    : description(evt.description),
++      event_cb(evt.event_cb),
++      status(evt.status),
++      interval(evt.interval),
++      last_run(evt.last_run),
++      current(evt.current),
++      next_run(evt.next_run),
++      cum_time(evt.cum_time),
++      min_time(evt.min_time),
++      max_time(evt.max_time),
++      count(evt.count)
++{
++}
++
++fgEVENT&
++fgEVENT::operator= ( const fgEVENT& evt )
++{
++    if ( this != &evt )
++    {
++      description = evt.description;
++      event_cb = evt.event_cb;
++      status = evt.status;
++      interval = evt.interval;
++      last_run = evt.last_run;
++      current = evt.current;
++      next_run = evt.next_run;
++      cum_time = evt.cum_time;
++      min_time = evt.min_time;
++      max_time = evt.max_time;
++      count = evt.count;
++    }
++    return *this;
++}
++#endif
++
++fgEVENT::~fgEVENT()
++{
++    delete event_cb;
++}
++
++void
++fgEVENT::run()
++{
++    FG_LOG(FG_EVENT, FG_INFO, "Running " << description );
++
++    // record starting time
++    last_run.stamp();
++
++    // run the event
++    event_cb->call( (void**)NULL );
++
++    // increment the counter for this event
++    count++;
++
++    // update the event status
++    status = FG_EVENT_READY;
++
++    // calculate duration and stats
++    current.stamp();
++    long duration = current - last_run;
++
++    cum_time += duration;
++
++    if ( duration < min_time ) {
++      min_time = duration;
++    }
++
++    if ( duration > max_time ) {
++      max_time = duration;
++    }
++
++    // determine the next absolute run time
++    next_run =  last_run + interval;
++}
++
++
++// Dump scheduling stats
++int
++fgEVENT::PrintStats() const
++{
++    FG_LOG( FG_EVENT, FG_INFO, 
++          "  " << description 
++          << " int=" << interval / 1000.0
++          << " cum=" << cum_time
++          << " min=" << min_time
++          << " max=" <<  max_time
++          << " count=" << count
++          << " ave=" << cum_time / (double)count );
++    return 0;
++}
++
++// Constructor
++fgEVENT_MGR::fgEVENT_MGR( void ) {
++}
++
++
++// Initialize the scheduling subsystem
++void fgEVENT_MGR::Init( void ) {
++    FG_LOG(FG_EVENT, FG_INFO, "Initializing event manager" );
++
++    run_queue.erase( run_queue.begin(), run_queue.end() );
++    event_table.erase( event_table.begin(), event_table.end() );
++}
++
++
++// Register an event with the scheduler.
++void
++fgEVENT_MGR::Register( const string& desc,
++                     const fgCallback& cb,
++                     fgEVENT::EventState status, 
++                     int interval )
++{
++    // convert interval specified in milleseconds to usec
++    fgEVENT* e = new fgEVENT( desc, cb, status, interval * 1000 );
++
++    FG_LOG( FG_EVENT, FG_INFO, "Registering event: " << desc );
++
++    // Actually run the event
++    e->run();
++
++    // Now add to event_table
++    event_table.push_back(e);
++}
++
++
++// Update the scheduling parameters for an event
++void fgEVENT_MGR::Update( void ) {
++}
++
++
++// Delete a scheduled event
++void fgEVENT_MGR::Delete( void ) {
++}
++
++
++// Temporarily suspend scheduling of an event
++void fgEVENT_MGR::Suspend( void ) {
++}
++
++
++// Resume scheduling and event
++void fgEVENT_MGR::Resume( void ) {
++}
++
++// Dump scheduling stats
++void
++fgEVENT_MGR::PrintStats()
++{
++    FG_LOG( FG_EVENT, FG_INFO, "" );
++    FG_LOG( FG_EVENT, FG_INFO, "Event Stats" );
++    FG_LOG( FG_EVENT, FG_INFO, "-----------" );
++
++    ConstEventIterator first = event_table.begin();
++    ConstEventIterator last = event_table.end();
++    while ( first != last )
++    {
++        (*first)->PrintStats();
++        ++first;
++    }
++#if 0 // msvc++ 6.0 barfs at mem_fun()
++    for_each( event_table.begin(),
++            event_table.end(),
++            mem_fun( &fgEVENT::PrintStats ) );
++#endif
++    FG_LOG( FG_EVENT, FG_INFO, "");
++}
++
++
++// Add pending jobs to the run queue and run the job at the front of
++// the queue
++void fgEVENT_MGR::Process( void ) {
++    fgEVENT *e_ptr;
++    FGTimeStamp cur_time;
++    unsigned int i, size;
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "Processing events" );
++    
++    // get the current time
++    cur_time.stamp();
++
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "  Current timestamp = " << cur_time.get_seconds() );
++
++    // printf("Checking if anything is ready to move to the run queue\n");
++
++    // see if anything else is ready to be placed on the run queue
++    size = event_table.size();
++    // while ( current != last ) {
++    for ( i = 0; i < size; i++ ) {
++      // e = *current++;
++      e_ptr = event_table[i];
++      if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
++          FG_LOG( FG_EVENT, FG_DEBUG, 
++                  "  Item " << i << " current " << cur_time.get_seconds()
++                  << " next run @ " << e_ptr->next_run.get_seconds() );
++          if ( ( e_ptr->next_run - cur_time ) <= 0 ) {
++              run_queue.push_back(e_ptr);
++              e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
++          }
++      }
++    }
++
++    // Checking to see if there is anything on the run queue
++    // printf("Checking to see if there is anything on the run queue\n");
++    if ( run_queue.size() ) {
++      // printf("Yep, running it\n");
++      e_ptr = run_queue.front();
++      run_queue.pop_front();
++      e_ptr->run();
++    }
++}
++
++
++// Destructor
++fgEVENT_MGR::~fgEVENT_MGR( void ) {
++    EventIterator first = event_table.begin();
++    EventIterator last = event_table.end();
++    for ( ; first != last; ++first )
++    {
++        delete (*first);
++    }
++
++    run_queue.erase( run_queue.begin(), run_queue.end() );
++    event_table.erase( event_table.begin(), event_table.end() );
++}
++
++
++// $Log$
++// Revision 1.17  1999/01/27 04:50:18  curt
++// Move sun/solaris specific stuff to compiler.h
++//
++// Revision 1.16  1999/01/21 20:14:18  curt
++// Sun portability hack.
++//
++// Revision 1.15  1999/01/09 13:37:42  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.14  1999/01/07 20:25:32  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.13  1998/12/04 01:32:46  curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.12  1998/11/23 21:49:07  curt
++// Borland portability tweaks.
++//
++// Revision 1.11  1998/11/09 23:41:51  curt
++// Log message clean ups.
++//
++// Revision 1.10  1998/11/07 19:07:13  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.9  1998/11/06 21:18:24  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8  1998/09/15 02:09:29  curt
++// Include/fg_callback.hxx
++//   Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++//   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
++//   complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++//   Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++//   Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++//   Uses fg_gzifstream when loading config file.
++//
++// Revision 1.7  1998/08/29 13:11:31  curt
++// Bernie Bright writes:
++//   I've created some new classes to enable pointers-to-functions and
++//   pointers-to-class-methods to be treated like objects.  These objects
++//   can be registered with fgEVENT_MGR.
++//
++//   File "Include/fg_callback.hxx" contains the callback class defns.
++//
++//   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
++//   some minor tweaks to STL usage.
++//
++//   Added file "Include/fg_stl_config.h" to deal with STL portability
++//   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
++//   I don't have access to Visual C++ so I've left that for someone else.
++//   This file is influenced by the stl_config.h file delivered with egcs.
++//
++//   Added "Include/auto_ptr.hxx" which contains an implementation of the
++//   STL auto_ptr class which is not provided in all STL implementations
++//   and is needed to use the callback classes.
++//
++//   Deleted fgLightUpdate() which was just a wrapper to call
++//   fgLIGHT::Update().
++//
++//   Modified fg_init.cxx to register two method callbacks in place of the
++//   old wrapper functions.
++//
++// Revision 1.6  1998/08/20 15:12:26  curt
++// Tweak ...
++//
++// Revision 1.5  1998/06/12 00:59:52  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++//   Solaris, and be easier to port, and understand the GMT vs. local
++//   timezone issues.
++//
++// Revision 1.4  1998/06/05 18:18:12  curt
++// Incorporated some automake conditionals to try to support mktime() correctly
++// on a wider variety of platforms.
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.3  1998/05/22 21:14:53  curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic.  Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.2  1998/04/25 22:06:33  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.1  1998/04/24 00:52:26  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.13  1998/04/18 04:14:08  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.12  1998/04/09 18:40:13  curt
++// We had unified some of the platform disparate time handling code, and
++// there was a bug in timesum() which calculated a new time stamp based on
++// the current time stamp + offset.  This hosed the periodic event processing
++// logic because you'd never arrive at the time the event was scheduled for.
++// Sky updates and lighting changes are handled via this event mechanism so
++// they never changed ... it is fixed now.
++//
++// Revision 1.11  1998/04/03 22:12:55  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.10  1998/03/14 00:28:34  curt
++// replaced a printf() with an fgPrintf().
++//
++// Revision 1.9  1998/01/31 00:43:44  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.8  1998/01/27 00:48:05  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7  1998/01/19 19:27:19  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.6  1998/01/19 18:40:39  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.5  1998/01/06 01:20:27  curt
++// Tweaks to help building with MSVC++
++//
++// Revision 1.4  1997/12/31 17:46:50  curt
++// Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
++//
++// Revision 1.3  1997/12/30 22:22:42  curt
++// Further integration of event manager.
++//
++// Revision 1.2  1997/12/30 20:47:58  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.1  1997/12/30 04:19:22  curt
++// Initial revision.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..69ad7217e1415f74973add3e060664c44bdc35f7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,290 @@@
++// event.hxx -- Flight Gear periodic event scheduler
++//
++// Written by Curtis Olson, started December 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _EVENT_HXX
++#define _EVENT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#include <Include/compiler.h>
++#include <Include/fg_callback.hxx>
++
++#include <deque>        // STL double ended queue
++#include <list>         // STL list
++#include STL_STRING
++
++#include "fg_time.hxx"
++#include "timestamp.hxx"
++
++FG_USING_STD(deque);
++FG_USING_STD(list);
++FG_USING_STD(string);
++
++
++class fgEVENT
++{
++public:
++    enum EventState
++    {
++      FG_EVENT_SUSP   = 0,
++      FG_EVENT_READY  = 1,
++      FG_EVENT_QUEUED = 2
++    };
++
++    friend class fgEVENT_MGR;
++
++    fgEVENT() {} // Required by deque<>.
++
++    fgEVENT( const string& desc,
++           const fgCallback& cb,
++           EventState evt_status,
++           int evt_interval );
++
++    ~fgEVENT();
++
++    void run();
++
++//     void PrintStats() const;
++    int PrintStats() const;
++
++private:
++    // not defined
++    fgEVENT( const fgEVENT& evt );
++    fgEVENT& operator= ( const fgEVENT& evt );
++
++private:
++
++    string description;
++
++    // The callback object.
++    fgCallback* event_cb;
++
++    EventState status;       // status flag
++
++    long interval;    // interval in ms between each iteration of this event
++
++    FGTimeStamp last_run;
++    FGTimeStamp current;
++    FGTimeStamp next_run;
++
++    long cum_time;    // cumulative processor time of this event
++    long min_time;    // time of quickest execution
++    long max_time;    // time of slowest execution
++    long count;       // number of times executed
++};
++
++
++class fgEVENT_MGR {
++
++    // Event table
++    typedef deque < fgEVENT* >             EventContainer;
++    typedef EventContainer::iterator       EventIterator;
++    typedef EventContainer::const_iterator ConstEventIterator;
++
++    EventContainer event_table;
++
++    // Run Queue
++    typedef list < fgEVENT * > RunContainer;
++
++    RunContainer run_queue;
++
++public:
++
++    // Constructor
++    fgEVENT_MGR ( void );
++
++    // Initialize the scheduling subsystem
++    void Init( void );
++
++    // Register an event with the scheduler
++    void Register( const string& desc, void (*event)( void ),
++                 fgEVENT::EventState status, int interval) {
++      Register( desc, fgFunctionCallback(event), status, interval );
++    }
++
++    void Register( const string& desc,
++                 const fgCallback& cb,
++                 fgEVENT::EventState status, 
++                 int interval );
++
++    // Update the scheduling parameters for an event
++    void Update( void );
++
++    // Delete a scheduled event
++    void Delete( void );
++
++    // Temporarily suspend scheduling of an event
++    void Suspend( void );
++
++    // Resume scheduling and event
++    void Resume( void );
++
++    // Dump scheduling stats
++    void PrintStats( void );
++
++    // Add pending jobs to the run queue and run the job at the front
++    // of the queue
++    void Process( void );
++
++    // Destructor
++    ~fgEVENT_MGR ( void );
++};
++
++
++// Wrapper to dump scheduling stats
++void fgEventPrintStats( void );
++
++extern fgEVENT_MGR global_events;
++
++
++#endif // _EVENT_HXX
++
++
++// $Log$
++// Revision 1.18  1999/03/02 01:03:33  curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.17  1999/02/26 22:10:08  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.16  1999/01/09 13:37:43  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.15  1999/01/07 20:25:33  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.14  1998/12/05 14:21:28  curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.13  1998/12/04 01:32:47  curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.12  1998/10/16 00:56:08  curt
++// Converted to Point3D class.
++//
++// Revision 1.11  1998/09/15 02:09:30  curt
++// Include/fg_callback.hxx
++//   Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++//   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
++//   complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++//   Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++//   Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++//   Uses fg_gzifstream when loading config file.
++//
++// Revision 1.10  1998/09/08 21:41:06  curt
++// Added constructor for fgEVENT.
++//
++// Revision 1.9  1998/09/02 14:37:45  curt
++// Renamed struct -> class.
++//
++// Revision 1.8  1998/08/29 13:11:32  curt
++// Bernie Bright writes:
++//   I've created some new classes to enable pointers-to-functions and
++//   pointers-to-class-methods to be treated like objects.  These objects
++//   can be registered with fgEVENT_MGR.
++//
++//   File "Include/fg_callback.hxx" contains the callback class defns.
++//
++//   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
++//   some minor tweaks to STL usage.
++//
++//   Added file "Include/fg_stl_config.h" to deal with STL portability
++//   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
++//   I don't have access to Visual C++ so I've left that for someone else.
++//   This file is influenced by the stl_config.h file delivered with egcs.
++//
++//   Added "Include/auto_ptr.hxx" which contains an implementation of the
++//   STL auto_ptr class which is not provided in all STL implementations
++//   and is needed to use the callback classes.
++//
++//   Deleted fgLightUpdate() which was just a wrapper to call
++//   fgLIGHT::Update().
++//
++//   Modified fg_init.cxx to register two method callbacks in place of the
++//   old wrapper functions.
++//
++// Revision 1.7  1998/07/30 23:48:54  curt
++// Sgi build tweaks.
++// Pause support.
++//
++// Revision 1.6  1998/07/24 21:42:25  curt
++// Output message tweaks.
++//
++// Revision 1.5  1998/07/13 21:02:07  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.4  1998/06/12 00:59:52  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++//   Solaris, and be easier to port, and understand the GMT vs. local
++//   timezone issues.
++//
++// Revision 1.3  1998/06/03 00:48:12  curt
++// No .h for STL includes.
++//
++// Revision 1.2  1998/05/22 21:14:54  curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic.  Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.1  1998/04/24 00:52:26  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.4  1998/04/21 17:01:43  curt
++// Fixed a problems where a pointer to a function was being passed around.  In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ).  The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.3  1998/01/22 02:59:43  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2  1998/01/19 18:40:39  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1  1997/12/30 04:19:22  curt
++// Initial revision.
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ac6eb9f3264511334cf3186b64461f102a2b06b9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,691 @@@
++//
++// fg_time.cxx -- data structures and routines for managing time related stuff.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cmath>
++#  include <cstdio>
++#  include <cstdlib>
++#  include <ctime>
++#else
++#  include <math.h>
++#  include <stdio.h>
++#  include <stdlib.h>
++#  include <time.h>
++#endif
++
++#ifdef HAVE_SYS_TIMEB_H
++#  include <sys/timeb.h> // for ftime() and struct timeb
++#endif
++#ifdef HAVE_UNISTD_H
++#  include <unistd.h>    // for gettimeofday()
++#endif
++#ifdef HAVE_SYS_TIME_H
++#  include <sys/time.h>  // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#include <Debug/logstream.hxx>
++#include <Astro/sky.hxx>
++#include <Astro/solarsystem.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Time/light.hxx>
++
++#include "fg_time.hxx"
++
++
++#define DEGHR(x)        ((x)/15.)
++#define RADHR(x)        DEGHR(x*RAD_TO_DEG)
++
++// #define MK_TIME_IS_GMT 0         // default value
++// #define TIME_ZONE_OFFSET_WORK 0  // default value
++
++
++fgTIME cur_time_params;
++
++
++// Force an update of the sky and lighting parameters
++static void local_update_sky_and_lighting_params( void ) {
++    // fgSunInit();
++    SolarSystem::theSolarSystem->rebuild();
++    cur_light_params.Update();
++    fgSkyColorsInit();
++}
++
++
++// Initialize the time dependent variables
++void fgTimeInit(fgTIME *t) {
++    FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
++
++    t->gst_diff = -9999.0;
++
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "time offset = " << current_options.get_time_offset() );
++
++    t->warp = current_options.get_time_offset();
++    t->warp_delta = 0;
++
++    t->pause = current_options.get_pause();
++}
++
++
++// given a date in months, mn, days, dy, years, yr, return the
++// modified Julian date (number of days elapsed since 1900 jan 0.5),
++// mjd.  Adapted from Xephem.
++
++double cal_mjd (int mn, double dy, int yr) {
++    static double last_mjd, last_dy;
++    double mjd;
++    static int last_mn, last_yr;
++    int b, d, m, y;
++    long c;
++
++    if (mn == last_mn && yr == last_yr && dy == last_dy) {
++      mjd = last_mjd;
++      return(mjd);
++    }
++
++    m = mn;
++    y = (yr < 0) ? yr + 1 : yr;
++    if (mn < 3) {
++      m += 12;
++      y -= 1;
++    }
++
++    if (yr < 1582 || (yr == 1582 && (mn < 10 || (mn == 10 && dy < 15)))) {
++      b = 0;
++    } else {
++      int a;
++      a = y/100;
++      b = 2 - a + a/4;
++    }
++
++    if (y < 0) {
++      c = (long)((365.25*y) - 0.75) - 694025L;
++    } else {
++      c = (long)(365.25*y) - 694025L;
++    }
++    
++    d = (int)(30.6001*(m+1));
++
++    mjd = b + c + d + dy - 0.5;
++
++    last_mn = mn;
++    last_dy = dy;
++    last_yr = yr;
++    last_mjd = mjd;
++
++    return(mjd);
++}
++
++
++// given an mjd, return greenwich mean sidereal time, gst
++
++double utc_gst (double mjd) {
++    double gst;
++    double day = floor(mjd-0.5)+0.5;
++    double hr = (mjd-day)*24.0;
++    double T, x;
++
++    T = ((int)(mjd - 0.5) + 0.5 - J2000)/36525.0;
++    x = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T;
++    x /= 3600.0;
++    gst = (1.0/SIDRATE)*hr + x;
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "  gst => " << gst );
++
++    return(gst);
++}
++
++
++// given Julian Date and Longitude (decimal degrees West) compute and
++// return Local Sidereal Time, in decimal hours.
++//
++// Provided courtesy of ecdowney@noao.edu (Elwood Downey) 
++//
++
++double sidereal_precise (double mjd, double lng) {
++    double gst;
++    double lst;
++
++    /* printf ("Current Lst on JD %13.5f at %8.4f degrees West: ", 
++       mjd + MJD0, lng); */
++
++    // convert to required internal units
++    lng *= DEG_TO_RAD;
++
++    // compute LST and print
++    gst = utc_gst (mjd);
++    lst = gst - RADHR (lng);
++    lst -= 24.0*floor(lst/24.0);
++    // printf ("%7.4f\n", lst);
++
++    // that's all
++    return (lst);
++}
++
++
++// Fix up timezone if using ftime()
++long int fix_up_timezone( long int timezone_orig ) {
++#if !defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_FTIME )
++    // ftime() needs a little extra help finding the current timezone
++    struct timeb current;
++    ftime(&current);
++    return( current.timezone * 60 );
++#else
++    return( timezone_orig );
++#endif
++}
++
++
++// Return time_t for Sat Mar 21 12:00:00 GMT
++//
++// I believe the mktime() has a SYSV vs. BSD behavior difference.
++//
++// The BSD style mktime() is nice because it returns its result
++// assuming you have specified the input time in GMT
++//
++// The SYSV style mktime() is a pain because it returns its result
++// assuming you have specified the input time in your local timezone.
++// Therefore you have to go to extra trouble to convert back to GMT.
++//
++// If you are having problems with incorrectly positioned astronomical
++// bodies, this is a really good place to start looking.
++
++time_t get_start_gmt(int year) {
++    struct tm mt;
++
++    // For now we assume that if daylight is not defined in
++    // /usr/include/time.h that we have a machine with a BSD behaving
++    // mktime()
++#   if !defined(HAVE_DAYLIGHT)
++#       define MK_TIME_IS_GMT 1
++#   endif
++
++    // timezone seems to work as a proper offset for Linux & Solaris
++#   if defined( __linux__ ) || defined( __sun__ ) 
++#       define TIMEZONE_OFFSET_WORKS 1
++#   endif
++
++    mt.tm_mon = 2;
++    mt.tm_mday = 21;
++    mt.tm_year = year;
++    mt.tm_hour = 12;
++    mt.tm_min = 0;
++    mt.tm_sec = 0;
++    mt.tm_isdst = -1; // let the system determine the proper time zone
++
++#   if defined( MK_TIME_IS_GMT )
++    return ( mktime(&mt) );
++#   else // ! defined ( MK_TIME_IS_GMT )
++
++    long int start = mktime(&mt);
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "start1 = " << start );
++    // the ctime() call can screw up time progression on some versions
++    // of Linux
++    // fgPrintf( FG_EVENT, FG_DEBUG, "start2 = %s", ctime(&start));
++    FG_LOG( FG_EVENT, FG_DEBUG, "(tm_isdst = " << mt.tm_isdst << ")" );
++
++    timezone = fix_up_timezone( timezone );
++
++#   if defined( TIMEZONE_OFFSET_WORKS )
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "start = " << start << ", timezone = " << timezone );
++    return( start - timezone );
++#   else // ! defined( TIMEZONE_OFFSET_WORKS )
++
++    daylight = mt.tm_isdst;
++    if ( daylight > 0 ) {
++      daylight = 1;
++    } else if ( daylight < 0 ) {
++      FG_LOG( FG_EVENT, FG_WARN, 
++              "OOOPS, problem in fg_time.cxx, no daylight savings info." );
++    }
++
++    long int offset = -(timezone / 3600 - daylight);
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "  Raw time zone offset = " << timezone );
++    FG_LOG( FG_EVENT, FG_DEBUG, "  Daylight Savings = " << daylight );
++    FG_LOG( FG_EVENT, FG_DEBUG, "  Local hours from GMT = " << offset );
++    
++    long int start_gmt = start - timezone + (daylight * 3600);
++    
++    FG_LOG( FG_EVENT, FG_DEBUG, "  March 21 noon (CST) = " << start );
++
++    return ( start_gmt );
++#   endif // ! defined( TIMEZONE_OFFSET_WORKS )
++#   endif // ! defined ( MK_TIME_IS_GMT )
++}
++
++static char*
++format_time( const struct tm* p, char* buf )
++{
++    sprintf( buf, "%d/%d/%2d %d:%02d:%02d", 
++           p->tm_mon, p->tm_mday, p->tm_year,
++           p->tm_hour, p->tm_min, p->tm_sec);
++    return buf;
++}
++
++// return a courser but cheaper estimate of sidereal time
++double sidereal_course(fgTIME *t, double lng) {
++    struct tm *gmt;
++    time_t start_gmt, now;
++    double diff, part, days, hours, lst;
++    char tbuf[64];
++
++    gmt = t->gmt;
++    now = t->cur_time;
++    start_gmt = get_start_gmt(gmt->tm_year);
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "  COURSE: GMT = " << format_time(gmt, tbuf) );
++    FG_LOG( FG_EVENT, FG_DEBUG, "  March 21 noon (GMT) = " << start_gmt );
++
++    diff = (now - start_gmt) / (3600.0 * 24.0);
++    
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "  Time since 3/21/" << gmt->tm_year << " GMT = " << diff );
++
++    part = fmod(diff, 1.0);
++    days = diff - part;
++    hours = gmt->tm_hour + gmt->tm_min/60.0 + gmt->tm_sec/3600.0;
++
++    lst = (days - lng)/15.0 + hours - 12;
++
++    while ( lst < 0.0 ) {
++      lst += 24.0;
++    }
++
++    FG_LOG( FG_EVENT, FG_DEBUG,
++          "  days = " << days << "  hours = " << hours << "  lon = " 
++          << lng << "  lst = " << lst );
++
++    return(lst);
++}
++
++
++// Update time variables such as gmt, julian date, and sidereal time
++void fgTimeUpdate(FGInterface *f, fgTIME *t) {
++    double gst_precise, gst_course;
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "Updating time" );
++
++    // get current Unix calendar time (in seconds)
++    t->warp += t->warp_delta;
++    t->cur_time = time(NULL) + t->warp;
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "  Current Unix calendar time = " << t->cur_time 
++          << "  warp = " << t->warp << "  delta = " << t->warp_delta );
++
++    if ( t->warp_delta ) {
++      // time is changing so force an update
++      local_update_sky_and_lighting_params();
++    }
++
++    // get GMT break down for current time
++    t->gmt = gmtime(&t->cur_time);
++    FG_LOG( FG_EVENT, FG_DEBUG, 
++          "  Current GMT = " << t->gmt->tm_mon+1 << "/" 
++          << t->gmt->tm_mday << "/" << t->gmt->tm_year << " "
++          << t->gmt->tm_hour << ":" << t->gmt->tm_min << ":" 
++          << t->gmt->tm_sec );
++
++    // calculate modified Julian date
++    t->mjd = cal_mjd ((int)(t->gmt->tm_mon+1), (double)t->gmt->tm_mday, 
++           (int)(t->gmt->tm_year + 1900));
++
++    // add in partial day
++    t->mjd += (t->gmt->tm_hour / 24.0) + (t->gmt->tm_min / (24.0 * 60.0)) +
++         (t->gmt->tm_sec / (24.0 * 60.0 * 60.0));
++
++    // convert "back" to Julian date + partial day (as a fraction of one)
++    t->jd = t->mjd + MJD0;
++    FG_LOG( FG_EVENT, FG_DEBUG, "  Current Julian Date = " << t->jd );
++
++    // printf("  Current Longitude = %.3f\n", FG_Longitude * RAD_TO_DEG);
++
++    // Calculate local side real time
++    if ( t->gst_diff < -100.0 ) {
++      // first time through do the expensive calculation & cheap
++        // calculation to get the difference.
++      FG_LOG( FG_EVENT, FG_INFO, "  First time, doing precise gst" );
++      t->gst = gst_precise = sidereal_precise(t->mjd, 0.00);
++      gst_course = sidereal_course(t, 0.00);
++      t->gst_diff = gst_precise - gst_course;
++
++      t->lst =
++        sidereal_course(t, -(f->get_Longitude() * RAD_TO_DEG)) + t->gst_diff;
++    } else {
++      // course + difference should drift off very slowly
++      t->gst = sidereal_course(t, 0.00) + t->gst_diff;
++      t->lst = sidereal_course(t, -(f->get_Longitude() * RAD_TO_DEG)) + 
++          t->gst_diff;
++    }
++    FG_LOG( FG_EVENT, FG_DEBUG,
++          "  Current lon=0.00 Sidereal Time = " << t->gst );
++    FG_LOG( FG_EVENT, FG_DEBUG,
++          "  Current LOCAL Sidereal Time = " << t->lst << " (" 
++          << sidereal_precise(t->mjd, -(f->get_Longitude() * RAD_TO_DEG)) 
++          << ") (diff = " << t->gst_diff << ")" );
++}
++
++
++// $Log$
++// Revision 1.32  1999/02/26 22:10:10  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.31  1999/02/05 21:29:18  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.30  1999/02/01 21:33:37  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.29  1999/01/19 20:57:08  curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.28  1999/01/07 20:25:34  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.27  1998/12/11 20:26:55  curt
++// #include tweaks.
++//
++// Revision 1.26  1998/12/05 15:54:28  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.25  1998/12/05 14:21:30  curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.24  1998/12/04 01:32:49  curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.23  1998/12/03 01:18:40  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.22  1998/11/16 14:00:28  curt
++// FG_LOG() message tweaks.
++//
++// Revision 1.21  1998/11/06 21:18:26  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.20  1998/11/02 18:25:38  curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.19  1998/10/17 01:34:29  curt
++// C++ ifying ...
++//
++// Revision 1.18  1998/10/02 21:36:09  curt
++// Fixes to try to break through the win95/98 18.3 fps barrier.
++//
++// Revision 1.17  1998/09/15 04:27:49  curt
++// Changes for new astro code.
++//
++// Revision 1.16  1998/08/29 13:11:32  curt
++// Bernie Bright writes:
++//   I've created some new classes to enable pointers-to-functions and
++//   pointers-to-class-methods to be treated like objects.  These objects
++//   can be registered with fgEVENT_MGR.
++//
++//   File "Include/fg_callback.hxx" contains the callback class defns.
++//
++//   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
++//   some minor tweaks to STL usage.
++//
++//   Added file "Include/fg_stl_config.h" to deal with STL portability
++//   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
++//   I don't have access to Visual C++ so I've left that for someone else.
++//   This file is influenced by the stl_config.h file delivered with egcs.
++//
++//   Added "Include/auto_ptr.hxx" which contains an implementation of the
++//   STL auto_ptr class which is not provided in all STL implementations
++//   and is needed to use the callback classes.
++//
++//   Deleted fgLightUpdate() which was just a wrapper to call
++//   fgLIGHT::Update().
++//
++//   Modified fg_init.cxx to register two method callbacks in place of the
++//   old wrapper functions.
++//
++// Revision 1.15  1998/08/24 20:12:16  curt
++// Rewrote sidereal_course with simpler parameters.
++//
++// Revision 1.14  1998/08/05 00:20:07  curt
++// Added a local routine to update lighting params every frame when time is
++// accelerated.
++//
++// Revision 1.13  1998/07/30 23:48:55  curt
++// Sgi build tweaks.
++// Pause support.
++//
++// Revision 1.12  1998/07/27 18:42:22  curt
++// Added a pause option.
++//
++// Revision 1.11  1998/07/22 21:45:37  curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++//   but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++//   and view orientation.  This is an attempt to match the fog color to the
++//   sky color in the center of the screen.  You see discrepancies at the
++//   edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here.  (what compass direction
++//   do we need to face to point directly at sun)
++//
++// Revision 1.10  1998/07/13 21:02:07  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.9  1998/06/12 00:59:53  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++//   Solaris, and be easier to port, and understand the GMT vs. local
++//   timezone issues.
++//
++// Revision 1.8  1998/06/05 18:18:13  curt
++// Incorporated some automake conditionals to try to support mktime() correctly
++// on a wider variety of platforms.
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.7  1998/05/30 01:57:25  curt
++// misc updates.
++//
++// Revision 1.6  1998/05/02 01:53:17  curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.5  1998/04/28 21:45:34  curt
++// Fixed a horible bug that cause the time to be *WAY* off when compiling
++// with the CygWin32 compiler.  This may not yet completely address other
++// Win32 compilers, but we'll have to take them on a case by case basis.
++//
++// Revision 1.4  1998/04/28 01:22:16  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3  1998/04/25 22:06:33  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/25 20:24:02  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1  1998/04/24 00:52:27  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.41  1998/04/22 13:24:05  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.40  1998/04/18 04:14:09  curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.39  1998/04/09 18:40:14  curt
++// We had unified some of the platform disparate time handling code, and
++// there was a bug in timesum() which calculated a new time stamp based on
++// the current time stamp + offset.  This hosed the periodic event processing
++// logic because you'd never arrive at the time the event was scheduled for.
++// Sky updates and lighting changes are handled via this event mechanism so
++// they never changed ... it is fixed now.
++//
++// Revision 1.38  1998/04/08 23:35:40  curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.37  1998/04/03 22:12:55  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.36  1998/03/09 22:48:09  curt
++// Debug message tweaks.
++//
++// Revision 1.35  1998/02/09 15:07:52  curt
++// Minor tweaks.
++//
++// Revision 1.34  1998/02/07 15:29:47  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.33  1998/02/02 20:54:04  curt
++// Incorporated Durk's changes.
++//
++// Revision 1.32  1998/02/01 03:39:56  curt
++// Minor tweaks.
++//
++// Revision 1.31  1998/01/27 00:48:06  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.30  1998/01/21 21:11:35  curt
++// Misc. tweaks.
++//
++// Revision 1.29  1998/01/19 19:27:20  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.28  1998/01/19 18:35:49  curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.27  1998/01/13 00:23:13  curt
++// Initial changes to support loading and management of scenery tiles.  Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.26  1998/01/05 18:44:36  curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.25  1997/12/31 17:46:50  curt
++// Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
++//
++// Revision 1.24  1997/12/30 22:22:42  curt
++// Further integration of event manager.
++//
++// Revision 1.23  1997/12/30 20:47:58  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.22  1997/12/30 01:38:47  curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.21  1997/12/23 04:58:39  curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.20  1997/12/15 23:55:06  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.19  1997/12/15 20:59:10  curt
++// Misc. tweaks.
++//
++// Revision 1.18  1997/12/12 21:41:31  curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.17  1997/12/12 19:53:04  curt
++// Working on lightling and material properties.
++//
++// Revision 1.16  1997/12/11 04:43:57  curt
++// Fixed sun vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15  1997/12/10 22:37:54  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14  1997/12/10 01:19:52  curt
++// Tweaks for verion 0.15 release.
++//
++// Revision 1.13  1997/12/09 05:11:56  curt
++// Working on tweaking lighting.
++//
++// Revision 1.12  1997/12/09 04:25:37  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.11  1997/11/25 19:25:40  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.10  1997/11/15 18:16:42  curt
++// minor tweaks.
++//
++// Revision 1.9  1997/11/14 00:26:50  curt
++// Transform scenery coordinates earlier in pipeline when scenery is being
++// created, not when it is being loaded.  Precalculate normals for each node
++// as average of the normals of each containing polygon so Garoude shading is
++// now supportable.
++//
++// Revision 1.8  1997/10/25 03:30:08  curt
++// Misc. tweaks.
++//
++// Revision 1.7  1997/09/23 00:29:50  curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.6  1997/09/20 03:34:34  curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.5  1997/09/16 22:14:52  curt
++// Tweaked time of day lighting equations.  Don't draw stars during the day.
++//
++// Revision 1.4  1997/09/16 15:50:31  curt
++// Working on star alignment and time issues.
++//
++// Revision 1.3  1997/09/13 02:00:08  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.2  1997/08/27 03:30:35  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.1  1997/08/13 21:55:59  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a784531fef8e10686b7af292be5f640b31c49443
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,231 @@@
++//
++// fg_time.hxx -- data structures and routines for managing time related stuff.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_TIME_HXX
++#define _FG_TIME_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <ctime>
++#else
++#  include <time.h>
++#endif
++
++#include <FDM/flight.hxx>
++
++
++// Define a structure containing global time parameters
++typedef struct {
++    // the date/time in various forms
++    // Unix "calendar" time in seconds
++    time_t cur_time;
++
++    // Break down of GMT time
++    struct tm *gmt;
++
++    // Julian date
++    double jd;
++
++    // modified Julian date
++    double mjd;
++
++    // side real time at prime meridian
++    double gst;
++
++    // local side real time
++    double lst;
++
++    // the difference between the precise sidereal time algorithm
++    // result and the course result.  
++    // course + diff has good accuracy for the short term
++    double gst_diff;
++
++    // An offset in seconds from the true time.  Allows us to adjust
++    // the effective time of day.
++    long int warp;
++
++    // How much to change the value of warp each iteration.  Allows us
++    // to make time progress faster than normal.
++    long int warp_delta; 
++
++    // Paused (0 = no, 1 = yes)
++    int pause;
++} fgTIME;
++
++extern fgTIME cur_time_params;
++
++
++// Update time variables such as gmt, julian date, and sidereal time
++void fgTimeInit(fgTIME *t);
++
++
++// Update the time dependent variables
++void fgTimeUpdate(FGInterface *f, fgTIME *t);
++
++
++#endif // _FG_TIME_HXX
++
++
++// $Log$
++// Revision 1.14  1999/02/05 21:29:19  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.13  1999/02/01 21:33:39  curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.12  1999/01/07 20:25:35  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.11  1998/12/05 15:54:29  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.10  1998/12/05 14:21:31  curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.9  1998/12/04 01:32:50  curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.8  1998/10/16 23:28:00  curt
++// C++-ifying.
++//
++// Revision 1.7  1998/10/16 00:56:09  curt
++// Converted to Point3D class.
++//
++// Revision 1.6  1998/07/27 18:42:22  curt
++// Added a pause option.
++//
++// Revision 1.5  1998/05/22 21:14:54  curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic.  Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.4  1998/04/28 01:22:17  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3  1998/04/25 22:06:34  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2  1998/04/25 20:24:03  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1  1998/04/24 00:52:28  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.20  1998/04/22 13:24:05  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.19  1998/04/21 17:01:44  curt
++// Fixed a problems where a pointer to a function was being passed around.  In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ).  The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.18  1998/04/08 23:35:40  curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.17  1998/04/03 22:12:56  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.16  1998/02/07 15:29:47  curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.15  1998/01/27 00:48:06  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.14  1998/01/22 02:59:43  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.13  1998/01/19 19:27:20  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.12  1998/01/05 18:44:37  curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.11  1997/12/19 23:35:07  curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.10  1997/12/15 23:55:07  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.9  1997/12/10 22:37:55  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.8  1997/12/09 04:25:38  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.7  1997/11/25 19:25:41  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.6  1997/09/20 03:34:35  curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.5  1997/09/16 15:50:31  curt
++// Working on star alignment and time issues.
++//
++// Revision 1.4  1997/09/13 02:00:08  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.3  1997/09/04 02:17:39  curt
++// Shufflin' stuff.
++//
++// Revision 1.2  1997/08/27 03:30:36  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.1  1997/08/13 21:56:00  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..074d90f5bf45dc5c066ed4ce90e90390441303df
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,190 @@@
++// fg_timer.cxx -- time handling routines
++//
++// Written by Curtis Olson, started June 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <signal.h>    // for timer routines
++#include <stdio.h>     // for printf()
++
++#ifdef HAVE_STDLIB_H
++#  include <stdlib.h>
++#endif
++
++#ifdef HAVE_SYS_TIME_H
++#  include <sys/time.h>  // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#include "fg_time.hxx"
++#include "fg_timer.hxx"
++#include "timestamp.hxx"
++
++
++unsigned long int fgSimTime;
++
++#ifdef HAVE_SETITIMER
++  static struct itimerval t, ot;
++  static void (*callbackfunc)(int multi_loop);
++
++
++// This routine catches the SIGALRM
++void fgTimerCatch( int dummy ) {
++    int warning_avoider;
++
++    // get past a compiler warning
++    warning_avoider = dummy;
++
++    // ignore any SIGALRM's until we come back from our EOM iteration
++    signal(SIGALRM, SIG_IGN);
++
++    // printf("In fgTimerCatch()\n");
++
++    // -1 tells the routine to use default interval rather than
++    // something dynamically calculated based on frame rate
++    callbackfunc(-1); 
++
++    signal(SIGALRM, fgTimerCatch);
++}
++
++
++// this routine initializes the interval timer to generate a SIGALRM
++// after the specified interval (dt)
++void fgTimerInit(float dt, void (*f)( int )) {
++    int terr;
++    int isec;
++    int usec;
++
++    callbackfunc = f;
++
++    isec = (int) dt;
++    usec = 1000000 * ((int)dt - isec);
++
++    t.it_interval.tv_sec = isec;
++    t.it_interval.tv_usec = usec;
++    t.it_value.tv_sec = isec;
++    t.it_value.tv_usec = usec;
++    // printf("fgTimerInit() called\n");
++    fgTimerCatch(0);   // set up for SIGALRM signal catch
++    terr = setitimer( ITIMER_REAL, &t, &ot );
++    if (terr) {
++      printf("Error returned from setitimer");
++      exit(0);
++    }
++}
++#endif // HAVE_SETITIMER
++
++
++// This function returns the number of microseconds since the last
++// time it was called.
++int fgGetTimeInterval( void ) {
++    int interval;
++    static int inited = 0;
++    static FGTimeStamp last;
++    FGTimeStamp current;
++
++    if ( ! inited ) {
++      inited = 1;
++      last.stamp();
++      interval = 0;
++    } else {
++        current.stamp();
++      interval = current - last;
++      last = current;
++    }
++
++    return(interval);
++}
++
++
++// $Log$
++// Revision 1.6  1999/01/09 13:37:45  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.5  1998/12/05 14:21:32  curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.4  1998/12/04 01:32:51  curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.3  1998/04/28 01:22:18  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.2  1998/04/25 20:24:03  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1  1998/04/24 00:52:29  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.12  1998/04/21 17:01:44  curt
++// Fixed a problems where a pointer to a function was being passed around.  In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ).  The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.11  1998/04/03 22:12:56  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.10  1998/01/31 00:43:45  curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.9  1998/01/19 19:27:21  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.8  1998/01/19 18:40:39  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7  1997/12/30 13:06:58  curt
++// A couple lighting tweaks ...
++//
++// Revision 1.6  1997/07/12 02:13:04  curt
++// Add ftime() support for those that don't have gettimeofday()
++//
++// Revision 1.5  1997/06/26 19:08:38  curt
++// Restructuring make, adding automatic "make dep" support.
++//
++// Revision 1.4  1997/06/25 15:39:49  curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.3  1997/06/17 16:52:04  curt
++// Timer interval stuff now uses gettimeofday() instead of ftime()
++//
++// Revision 1.2  1997/06/17 03:41:10  curt
++// Nonsignal based interval timing is now working.
++// This would be a good time to look at cleaning up the code structure a bit.
++//
++// Revision 1.1  1997/06/16 19:24:20  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7cfd106320f8c53ec70350e1f24891cdfad2a505
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,77 @@@
++/**************************************************************************
++ * fg_timer.hxx -- time handling routines
++ *
++ * Written by Curtis Olson, started June 1997.
++ *
++ * Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * $Id$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _FG_TIMER_HXX
++#define _FG_TIMER_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++extern unsigned long int fgSimTime;
++
++/* this routine initializes the interval timer to generate a SIGALRM
++ * after the specified interval (dt) the function f() will be called
++ * at each signal */
++void fgTimerInit( float dt, void (*f)( int ) );
++
++/* This function returns the number of milleseconds since the last
++   time it was called. */
++int fgGetTimeInterval( void );
++
++
++#endif /* _FG_TIMER_HXX */
++
++
++/* $Log$
++/* Revision 1.1  1998/04/24 00:52:30  curt
++/* Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++/* Fog color fixes.
++/* Separated out lighting calcs into their own file.
++/*
++ * Revision 1.5  1998/04/21 17:01:45  curt
++ * Fixed a problems where a pointer to a function was being passed around.  In
++ * one place this functions arguments were defined as ( void ) while in another
++ * place they were defined as ( int ).  The correct answer was ( int ).
++ *
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.4  1998/01/22 02:59:43  curt
++ * Changed #ifdef FILE_H to #ifdef _FILE_H
++ *
++ * Revision 1.3  1998/01/19 18:40:40  curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.2  1997/07/23 21:52:27  curt
++ * Put comments around the text after an #endif for increased portability.
++ *
++ * Revision 1.1  1997/06/16 19:24:20  curt
++ * Initial revision.
++ *
++ */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f7e06ea48a044aaca25c879b3f47e2aa15dbe640
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,346 @@@
++//
++// light.hxx -- lighting routines
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include "Include/compiler.h"
++
++#ifdef FG_MATH_EXCEPTION_CLASH
++#  define exception c_exception
++#endif
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cmath>
++#else
++#  include <math.h>
++#endif
++
++#include <string>
++FG_USING_STD(string);
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/interpolater.hxx>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++
++#include "fg_time.hxx"
++#include "light.hxx"
++#include "sunpos.hxx"
++
++
++fgLIGHT cur_light_params;
++
++
++// Constructor
++fgLIGHT::fgLIGHT( void ) {
++}
++
++
++// initialize lighting tables
++void fgLIGHT::Init( void ) {
++    FG_LOG( FG_EVENT, FG_INFO, 
++          "Initializing Lighting interpolation tables." );
++
++    // build the path name to the ambient lookup table
++    string path = current_options.get_fg_root();
++    string ambient = path + "/Lighting/ambient";
++    string diffuse = path + "/Lighting/diffuse";
++    string sky     = path + "/Lighting/sky";
++
++    // initialize ambient table
++    ambient_tbl = new fgINTERPTABLE( ambient );
++
++    // initialize diffuse table
++    diffuse_tbl = new fgINTERPTABLE( diffuse );
++    
++    // initialize sky table
++    sky_tbl = new fgINTERPTABLE( sky );
++}
++
++
++// update lighting parameters based on current sun position
++void fgLIGHT::Update( void ) {
++    FGInterface *f;
++    fgTIME *t;
++    // if the 4th field is 0.0, this specifies a direction ...
++    GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
++    // base sky color
++    GLfloat base_sky_color[4] =        {0.60, 0.60, 0.90, 1.0};
++    // base fog color
++    GLfloat base_fog_color[4] = {0.90, 0.90, 1.00, 1.0};
++    double deg, ambient, diffuse, sky_brightness;
++
++    f = current_aircraft.fdm_state;
++    t = &cur_time_params;
++
++    FG_LOG( FG_EVENT, FG_INFO, "Updating light parameters." );
++
++    // calculate lighting parameters based on sun's relative angle to
++    // local up
++
++    deg = sun_angle * 180.0 / FG_PI;
++    FG_LOG( FG_EVENT, FG_INFO, "  Sun angle = " << deg );
++
++    ambient = ambient_tbl->interpolate( deg );
++    diffuse = diffuse_tbl->interpolate( deg );
++    sky_brightness = sky_tbl->interpolate( deg );
++
++    FG_LOG( FG_EVENT, FG_INFO, 
++          "  ambient = " << ambient << "  diffuse = " << diffuse 
++          << "  sky = " << sky_brightness );
++
++    // sky_brightness = 0.15;  // used to force a dark sky (when testing)
++
++    // if ( ambient < 0.02 ) { ambient = 0.02; }
++    // if ( diffuse < 0.0 ) { diffuse = 0.0; }
++    // if ( sky_brightness < 0.1 ) { sky_brightness = 0.1; }
++
++    scene_ambient[0] = white[0] * ambient;
++    scene_ambient[1] = white[1] * ambient;
++    scene_ambient[2] = white[2] * ambient;
++
++    scene_diffuse[0] = white[0] * diffuse;
++    scene_diffuse[1] = white[1] * diffuse;
++    scene_diffuse[2] = white[2] * diffuse;
++
++    // set sky color
++    sky_color[0] = base_sky_color[0] * sky_brightness;
++    sky_color[1] = base_sky_color[1] * sky_brightness;
++    sky_color[2] = base_sky_color[2] * sky_brightness;
++    sky_color[3] = base_sky_color[3];
++
++    // set fog color
++    fog_color[0] = base_fog_color[0] * sky_brightness;
++    fog_color[1] = base_fog_color[1] * sky_brightness;
++    fog_color[2] = base_fog_color[2] * sky_brightness;
++    fog_color[3] = base_fog_color[3];
++}
++
++
++// calculate fog color adjusted for sunrise/sunset effects
++void fgLIGHT::UpdateAdjFog( void ) {
++    FGInterface *f;
++    double sun_angle_deg, rotation, param1[3], param2[3];
++
++    f = current_aircraft.fdm_state;
++
++    FG_LOG( FG_EVENT, FG_DEBUG, "Updating adjusted fog parameters." );
++
++    // set fog color (we'll try to match the sunset color in the
++    // direction we are looking
++
++    // first determine the difference between our view angle and local
++    // direction to the sun
++    rotation = -(sun_rotation + FG_PI) 
++      - (f->get_Psi() - current_view.get_view_offset());
++    while ( rotation < 0 ) {
++      rotation += FG_2PI;
++    }
++    while ( rotation > FG_2PI ) {
++      rotation -= FG_2PI;
++    }
++    rotation *= RAD_TO_DEG;
++    // fgPrintf( FG_EVENT, FG_INFO, 
++    //           "  View to sun difference in degrees = %.2f\n", rotation);
++
++    // next check if we are in a sunset/sunrise situation
++    sun_angle_deg = sun_angle * RAD_TO_DEG;
++    if ( (sun_angle_deg > 80.0) && (sun_angle_deg < 100.0) ) {
++      /* 0.0 - 0.6 */
++      param1[0] = (10.0 - fabs(90.0 - sun_angle_deg)) / 20.0;
++      param1[1] = (10.0 - fabs(90.0 - sun_angle_deg)) / 40.0;
++      param1[2] = (10.0 - fabs(90.0 - sun_angle_deg)) / 30.0;
++      // param2[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
++    } else {
++      param1[0] = param1[1] = param1[2] = 0.0;
++    }
++
++    if ( rotation - 180.0 <= 0.0 ) {
++      param2[0] = param1[0] * (180.0 - rotation) / 180.0;
++      param2[1] = param1[1] * (180.0 - rotation) / 180.0;
++      param2[2] = param1[2] * (180.0 - rotation) / 180.0;
++      // printf("param1[0] = %.2f param2[0] = %.2f\n", param1[0], param2[0]);
++    } else {
++      param2[0] = param1[0] * (rotation - 180.0) / 180.0;
++      param2[1] = param1[1] * (rotation - 180.0) / 180.0;
++      param2[2] = param1[2] * (rotation - 180.0) / 180.0;
++      // printf("param1[0] = %.2f param2[0] = %.2f\n", param1[0], param2[0]);
++    }
++
++    adj_fog_color[0] = fog_color[0] + param2[0];
++    if ( adj_fog_color[0] > 1.0 ) { adj_fog_color[0] = 1.0; }
++
++    adj_fog_color[1] = fog_color[1] + param2[1];
++    if ( adj_fog_color[1] > 1.0 ) { adj_fog_color[1] = 1.0; }
++
++    adj_fog_color[2] = fog_color[2] + param2[2];
++    if ( adj_fog_color[2] > 1.0 ) { adj_fog_color[2] = 1.0; }
++
++    adj_fog_color[3] = fog_color[3];
++}
++
++
++// Destructor
++fgLIGHT::~fgLIGHT( void ) {
++}
++
++
++// $Log$
++// Revision 1.27  1999/04/05 02:14:40  curt
++// Fixed a fog coloring bug.
++//
++// Revision 1.26  1999/02/05 21:29:20  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.25  1999/01/07 20:25:36  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.24  1998/12/09 18:50:35  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.23  1998/12/05 15:54:30  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.22  1998/12/03 01:18:42  curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.21  1998/11/23 21:49:09  curt
++// Borland portability tweaks.
++//
++// Revision 1.20  1998/11/06 21:18:27  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.19  1998/10/20 18:41:53  curt
++// Tweaked sunrise/sunset colors.
++//
++// Revision 1.18  1998/10/17 01:34:30  curt
++// C++ ifying ...
++//
++// Revision 1.17  1998/08/29 13:11:33  curt
++// Bernie Bright writes:
++//   I've created some new classes to enable pointers-to-functions and
++//   pointers-to-class-methods to be treated like objects.  These objects
++//   can be registered with fgEVENT_MGR.
++//
++//   File "Include/fg_callback.hxx" contains the callback class defns.
++//
++//   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
++//   some minor tweaks to STL usage.
++//
++//   Added file "Include/fg_stl_config.h" to deal with STL portability
++//   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
++//   I don't have access to Visual C++ so I've left that for someone else.
++//   This file is influenced by the stl_config.h file delivered with egcs.
++//
++//   Added "Include/auto_ptr.hxx" which contains an implementation of the
++//   STL auto_ptr class which is not provided in all STL implementations
++//   and is needed to use the callback classes.
++//
++//   Deleted fgLightUpdate() which was just a wrapper to call
++//   fgLIGHT::Update().
++//
++//   Modified fg_init.cxx to register two method callbacks in place of the
++//   old wrapper functions.
++//
++// Revision 1.16  1998/08/27 17:02:11  curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++//   them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.15  1998/08/25 20:53:33  curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.14  1998/08/06 12:47:22  curt
++// Adjusted dusk/dawn lighting ...
++//
++// Revision 1.13  1998/07/24 21:42:26  curt
++// Output message tweaks.
++//
++// Revision 1.12  1998/07/22 21:45:38  curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++//   but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++//   and view orientation.  This is an attempt to match the fog color to the
++//   sky color in the center of the screen.  You see discrepancies at the
++//   edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here.  (what compass direction
++//   do we need to face to point directly at sun)
++//
++// Revision 1.11  1998/07/13 21:02:08  curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10  1998/07/08 14:48:38  curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.9  1998/05/29 20:37:51  curt
++// Renamed <Table>.table to be <Table> so we can add a .gz under DOS.
++//
++// Revision 1.8  1998/05/20 20:54:16  curt
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.7  1998/05/13 18:26:50  curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.6  1998/05/11 18:18:51  curt
++// Made fog color slightly bluish.
++//
++// Revision 1.5  1998/05/03 00:48:38  curt
++// polar.h -> polar3d.h
++//
++// Revision 1.4  1998/04/28 01:22:18  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3  1998/04/26 05:10:04  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.2  1998/04/24 00:52:30  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1  1998/04/22 13:24:06  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1ae4eb55e03691d87936fcf0b4290fb4829252a1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,223 @@@
++// light.hxx -- lighting routines
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++
++
++#ifndef _LIGHT_HXX
++#define _LIGHT_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++// #include <Include/fg_types.h>
++#include <Math/interpolater.hxx>
++#include <Math/point3d.hxx>
++
++
++// Define a structure containing the global lighting parameters
++class fgLIGHT {
++
++    // Lighting look up tables (based on sun angle with local horizon)
++    fgINTERPTABLE *ambient_tbl;
++    fgINTERPTABLE *diffuse_tbl;
++    fgINTERPTABLE *sky_tbl;
++
++public:
++
++    ///////////////////////////////////////////////////////////
++    // position of the sun in various forms
++
++    // in geocentric coordinates
++    double sun_lon, sun_gc_lat;
++
++    // in cartesian coordiantes
++    Point3D fg_sunpos;
++
++    // (in view coordinates)
++    GLfloat sun_vec[4];
++
++    // inverse (in view coordinates)
++    GLfloat sun_vec_inv[4];
++
++    // the angle between the sun and the local horizontal (in radians)
++    double sun_angle;
++
++    // the rotation around our vertical axis of the sun (relative to
++    // due south with positive numbers going in the counter clockwise
++    // direction.)  This is the direction we'd need to face if we
++    // wanted to travel towards the sun.
++    double sun_rotation;
++
++    ///////////////////////////////////////////////////////////
++    // Have the same for the moon. Useful for having some light at night
++    // and stuff. I (Durk) also want to use this for adding similar 
++    // coloring effects to the moon as I did to the sun. 
++    ///////////////////////////////////////////////////////////
++    // position of the moon in various forms
++
++    // in geocentric coordinates
++    double moon_lon, moon_gc_lat;
++
++    // in cartesian coordiantes
++    Point3D fg_moonpos;
++
++    // (in view coordinates)
++    GLfloat moon_vec[4];
++
++    // inverse (in view coordinates)
++    GLfloat moon_vec_inv[4];
++
++    // the angle between the moon and the local horizontal (in radians)
++    double moon_angle;
++
++    // the rotation around our vertical axis of the moon (relative to
++    // due south with positive numbers going in the counter clockwise
++    // direction.)  This is the direction we'd need to face if we
++    // wanted to travel towards the sun.
++    double moon_rotation;
++
++    ///////////////////////////////////////////////////////////
++    // Derived lighting values
++
++    // ambient component
++    GLfloat scene_ambient[3];
++
++    // diffuse component
++    GLfloat scene_diffuse[3];
++
++    // fog color
++    GLfloat fog_color[4];
++
++    // fog color adjusted for sunset effects
++    GLfloat adj_fog_color[4];
++
++    // clear screen color
++    GLfloat sky_color[4];
++
++    // Constructor
++    fgLIGHT( void );
++
++    // initialize lighting tables
++    void Init( void );
++
++    // update lighting parameters based on current sun position
++    void Update( void);
++
++    // calculate fog color adjusted for sunrise/sunset effects
++    void UpdateAdjFog( void );
++
++    // Destructor
++    ~fgLIGHT( void );
++};
++
++
++// Global shared light parameter structure
++extern fgLIGHT cur_light_params;
++
++
++#endif // _LIGHT_HXX
++
++
++// $Log$
++// Revision 1.9  1999/03/22 02:08:17  curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++//   some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++//   me earlier.
++//
++// Revision 1.8  1998/10/16 00:56:10  curt
++// Converted to Point3D class.
++//
++// Revision 1.7  1998/08/29 13:11:33  curt
++// Bernie Bright writes:
++//   I've created some new classes to enable pointers-to-functions and
++//   pointers-to-class-methods to be treated like objects.  These objects
++//   can be registered with fgEVENT_MGR.
++//
++//   File "Include/fg_callback.hxx" contains the callback class defns.
++//
++//   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
++//   some minor tweaks to STL usage.
++//
++//   Added file "Include/fg_stl_config.h" to deal with STL portability
++//   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
++//   I don't have access to Visual C++ so I've left that for someone else.
++//   This file is influenced by the stl_config.h file delivered with egcs.
++//
++//   Added "Include/auto_ptr.hxx" which contains an implementation of the
++//   STL auto_ptr class which is not provided in all STL implementations
++//   and is needed to use the callback classes.
++//
++//   Deleted fgLightUpdate() which was just a wrapper to call
++//   fgLIGHT::Update().
++//
++//   Modified fg_init.cxx to register two method callbacks in place of the
++//   old wrapper functions.
++//
++// Revision 1.6  1998/07/22 21:45:39  curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++//   but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++//   and view orientation.  This is an attempt to match the fog color to the
++//   sky color in the center of the screen.  You see discrepancies at the
++//   edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here.  (what compass direction
++//   do we need to face to point directly at sun)
++//
++// Revision 1.5  1998/07/08 14:48:39  curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.4  1998/05/20 20:54:17  curt
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.3  1998/05/02 01:53:18  curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.2  1998/04/24 00:52:31  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1  1998/04/22 13:24:06  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7247cbebfbc273d5c0a5693b1b2312f5d391cfd8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,608 @@@
++// moonpos.cxx (basically, this is a slightly modified version of the 'sunpos.cxx' file, adapted from XEarth)
++
++// kirk johnson
++// july 1993
++//
++// code for calculating the position on the earth's surface for which
++// the moon is directly overhead (adapted from _practical astronomy
++// with your calculator, third edition_, peter duffett-smith,
++// cambridge university press, 1988.)
++//
++// Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++//
++// Parts of the source code (as marked) are:
++//   Copyright (C) 1989, 1990, 1991 by Jim Frost
++//   Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++//
++// Permission to use, copy, modify and freely distribute xearth for
++// non-commercial and not-for-profit purposes is hereby granted
++// without fee, provided that both the above copyright notice and this
++// permission notice appear in all copies and in supporting
++// documentation.
++//
++// The author makes no representations about the suitability of this
++// software for any purpose. It is provided "as is" without express or
++// implied warranty.
++//
++// THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cmath>
++#  include <cstdio>
++#  include <ctime>
++#else
++#  include <math.h>
++#  include <stdio.h>
++#  include <time.h>
++#endif
++
++
++//#include <Astro/orbits.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++
++#include "fg_time.hxx"
++#include "moonpos.hxx"
++
++extern SolarSystem *solarSystem;
++
++#undef E
++
++
++/*
++ * the epoch upon which these astronomical calculations are based is
++ * 1990 january 0.0, 631065600 seconds since the beginning of the
++ * "unix epoch" (00:00:00 GMT, Jan. 1, 1970)
++ *
++ * given a number of seconds since the start of the unix epoch,
++ * DaysSinceEpoch() computes the number of days since the start of the
++ * astronomical epoch (1990 january 0.0)
++ */
++
++#define EpochStart           (631065600)
++#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
++
++/*
++ * assuming the apparent orbit of the moon about the earth is circular,
++ * the rate at which the orbit progresses is given by RadsPerDay --
++ * FG_2PI radians per orbit divided by 365.242191 days per year:
++ */
++
++#define RadsPerDay (FG_2PI/365.242191)
++
++/*
++ * details of moon's apparent orbit at epoch 1990.0 (after
++ * duffett-smith, table 6, section 46)
++ *
++ * Epsilon_g    (ecliptic longitude at epoch 1990.0) 279.403303 degrees
++ * OmegaBar_g   (ecliptic longitude of perigee)      282.768422 degrees
++ * Eccentricity (eccentricity of orbit)                0.016713
++ */
++
++#define Epsilon_g    (279.403303*(FG_2PI/360))
++#define OmegaBar_g   (282.768422*(FG_2PI/360))
++#define Eccentricity (0.016713)
++
++/*
++ * MeanObliquity gives the mean obliquity of the earth's axis at epoch
++ * 1990.0 (computed as 23.440592 degrees according to the method given
++ * in duffett-smith, section 27)
++ */
++#define MeanObliquity (23.440592*(FG_2PI/360))
++
++/* static double solve_keplers_equation(double); */
++/* static double moon_ecliptic_longitude(time_t); */
++static void   ecliptic_to_equatorial(double, double, double *, double *);
++static double julian_date(int, int, int);
++static double GST(time_t);
++
++/*
++ * solve Kepler's equation via Newton's method
++ * (after duffett-smith, section 47)
++ */
++/*
++static double solve_keplers_equation(double M) {
++    double E;
++    double delta;
++
++    E = M;
++    while (1) {
++      delta = E - Eccentricity*sin(E) - M;
++      if (fabs(delta) <= 1e-10) break;
++      E -= delta / (1 - Eccentricity*cos(E));
++    }
++
++    return E;
++}
++*/
++
++
++/* compute ecliptic longitude of moon (in radians) (after
++ * duffett-smith, section 47) */
++/*
++static double moon_ecliptic_longitude(time_t ssue) {
++    // time_t ssue;              //  seconds since unix epoch
++    double D, N;
++    double M_moon, E;
++    double v;
++
++    D = DaysSinceEpoch(ssue);
++
++    N = RadsPerDay * D;
++    N = fmod(N, FG_2PI);
++    if (N < 0) N += FG_2PI;
++
++    M_moon = N + Epsilon_g - OmegaBar_g;
++    if (M_moon < 0) M_moon += FG_2PI;
++
++    E = solve_keplers_equation(M_moon);
++    v = 2 * atan(sqrt((1+Eccentricity)/(1-Eccentricity)) * tan(E/2));
++
++    return (v + OmegaBar_g);
++}
++*/
++
++
++/* convert from ecliptic to equatorial coordinates (after
++ * duffett-smith, section 27) */
++
++static void ecliptic_to_equatorial(double lambda, double beta, 
++                                 double *alpha, double *delta) {
++    /* double  lambda;            ecliptic longitude       */
++    /* double  beta;              ecliptic latitude        */
++    /* double *alpha;             (return) right ascension */
++    /* double *delta;             (return) declination     */
++
++    double sin_e, cos_e;
++    double sin_l, cos_l;
++
++    sin_e = sin(MeanObliquity);
++    cos_e = cos(MeanObliquity);
++    sin_l = sin(lambda);
++    cos_l = cos(lambda);
++
++    *alpha = atan2(sin_l*cos_e - tan(beta)*sin_e, cos_l);
++    *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin_l);
++}
++
++
++/* computing julian dates (assuming gregorian calendar, thus this is
++ * only valid for dates of 1582 oct 15 or later) (after duffett-smith,
++ * section 4) */
++
++static double julian_date(int y, int m, int d) {
++    /* int y;                    year (e.g. 19xx)          */
++    /* int m;                    month (jan=1, feb=2, ...) */
++    /* int d;                    day of month              */
++
++    int    A, B, C, D;
++    double JD;
++
++    /* lazy test to ensure gregorian calendar */
++    if (y < 1583) {
++      FG_LOG( FG_EVENT, FG_ALERT, 
++              "WHOOPS! Julian dates only valid for 1582 oct 15 or later" );
++    }
++
++    if ((m == 1) || (m == 2)) {
++      y -= 1;
++      m += 12;
++    }
++
++    A = y / 100;
++    B = 2 - A + (A / 4);
++    C = (int)(365.25 * y);
++    D = (int)(30.6001 * (m + 1));
++
++    JD = B + C + D + d + 1720994.5;
++
++    return JD;
++}
++
++
++/* compute greenwich mean sidereal time (GST) corresponding to a given
++ * number of seconds since the unix epoch (after duffett-smith,
++ * section 12) */
++static double GST(time_t ssue) {
++    /* time_t ssue;           seconds since unix epoch */
++
++    double     JD;
++    double     T, T0;
++    double     UT;
++    struct tm *tm;
++
++    tm = gmtime(&ssue);
++
++    JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
++    T  = (JD - 2451545) / 36525;
++
++    T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
++
++    T0 = fmod(T0, 24.0);
++    if (T0 < 0) T0 += 24;
++
++    UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
++
++    T0 += UT * 1.002737909;
++    T0 = fmod(T0, 24.0);
++    if (T0 < 0) T0 += 24;
++
++    return T0;
++}
++
++
++/* given a particular time (expressed in seconds since the unix
++ * epoch), compute position on the earth (lat, lon) such that moon is
++ * directly overhead.  (lat, lon are reported in radians */
++
++void fgMoonPosition(time_t ssue, double *lon, double *lat) {
++    /* time_t  ssue;           seconds since unix epoch */
++    /* double *lat;            (return) latitude        */
++    /* double *lon;            (return) longitude       */
++
++    /* double lambda; */
++    double alpha, delta;
++    double tmp;
++
++    /* lambda = moon_ecliptic_longitude(ssue); */
++    /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++    //ecliptic_to_equatorial (solarPosition.lonMoon, 0.0, &alpha, &delta);
++    
++    /* ********************************************************************** 
++     * NOTE: in the next function, each time the moon's position is updated, the
++     * the moon's longitude is returned from solarSystem->moon. Note that the 
++     * moon's position is updated at a much higher frequency than the rate at 
++     * which the solar system's rebuilds occur. This is not a problem, however,
++     * because the fgMoonPosition we're talking about here concerns the changing
++     * position of the moon due to the daily rotation of the earth.
++     * The ecliptic longitude, however, represents the position of the moon with
++     * respect to the stars, and completes just one cycle over the course of a 
++     * year. Its therefore pretty safe to update the moon's longitude only once
++     * every ten minutes. (Comment added by Durk Talsma).
++     ************************************************************************/
++
++    ecliptic_to_equatorial( SolarSystem::theSolarSystem->getMoon()->getLon(),
++                          0.0, &alpha, &delta );
++    tmp = alpha - (FG_2PI/24)*GST(ssue);
++    if (tmp < -FG_PI) {
++      do tmp += FG_2PI;
++      while (tmp < -FG_PI);
++    } else if (tmp > FG_PI) {
++      do tmp -= FG_2PI;
++      while (tmp < -FG_PI);
++    }
++
++    *lon = tmp;
++    *lat = delta;
++}
++
++
++/* given a particular time expressed in side real time at prime
++ * meridian (GST), compute position on the earth (lat, lon) such that
++ * moon is directly overhead.  (lat, lon are reported in radians */
++
++static void fgMoonPositionGST(double gst, double *lon, double *lat) {
++    /* time_t  ssue;           seconds since unix epoch */
++    /* double *lat;            (return) latitude        */
++    /* double *lon;            (return) longitude       */
++
++    /* double lambda; */
++    double alpha, delta;
++    double tmp;
++
++    /* lambda = moon_ecliptic_longitude(ssue); */
++    /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++    //ecliptic_to_equatorial (solarPosition.lonMoon, 0.0, &alpha, &delta);
++    ecliptic_to_equatorial( SolarSystem::theSolarSystem->getMoon()->getLon(),
++                          SolarSystem::theSolarSystem->getMoon()->getLat(), 
++                          &alpha,  &delta );
++
++//    tmp = alpha - (FG_2PI/24)*GST(ssue);
++    tmp = alpha - (FG_2PI/24)*gst;    
++    if (tmp < -FG_PI) {
++      do tmp += FG_2PI;
++      while (tmp < -FG_PI);
++    } else if (tmp > FG_PI) {
++      do tmp -= FG_2PI;
++      while (tmp < -FG_PI);
++    }
++
++    *lon = tmp;
++    *lat = delta;
++}
++
++
++// update the cur_time_params structure with the current moon position
++void fgUpdateMoonPos( void ) {
++    fgLIGHT *l;
++    fgTIME *t;
++    FGView *v;
++    MAT3vec nup, nmoon, v0, surface_to_moon;
++    Point3D p, rel_moonpos;
++    double dot, east_dot;
++    double moon_gd_lat, sl_radius;
++    double ntmp;
++
++    l = &cur_light_params;
++    t = &cur_time_params;
++    v = &current_view;
++
++    FG_LOG( FG_EVENT, FG_INFO, "  Updating Moon position" );
++
++    // (not sure why there was two)
++    // fgMoonPosition(t->cur_time, &l->moon_lon, &moon_gd_lat);
++    fgMoonPositionGST(t->gst, &l->moon_lon, &moon_gd_lat);
++
++    fgGeodToGeoc(moon_gd_lat, 0.0, &sl_radius, &l->moon_gc_lat);
++
++    p = Point3D( l->moon_lon, l->moon_gc_lat, sl_radius );
++    l->fg_moonpos = fgPolarToCart3d(p);
++
++    FG_LOG( FG_EVENT, FG_INFO, "    t->cur_time = " << t->cur_time );
++    FG_LOG( FG_EVENT, FG_INFO, 
++          "    Moon Geodetic lat = " << moon_gd_lat
++          << " Geocentric lat = " << l->moon_gc_lat );
++
++    // I think this will work better for generating the moon light vector
++    l->moon_vec[0] = l->fg_moonpos.x();
++    l->moon_vec[1] = l->fg_moonpos.y();
++    l->moon_vec[2] = l->fg_moonpos.z();
++    MAT3_NORMALIZE_VEC(l->moon_vec, ntmp);
++    MAT3_SCALE_VEC(l->moon_vec_inv, l->moon_vec, -1.0);
++
++    // make sure these are directional light sources only
++    l->moon_vec[3] = 0.0;
++    l->moon_vec_inv[3] = 0.0;
++
++    // printf("  l->moon_vec = %.2f %.2f %.2f\n", l->moon_vec[0], l->moon_vec[1],
++    //        l->moon_vec[2]);
++
++    // calculate the moon's relative angle to local up
++    MAT3_COPY_VEC(nup, v->get_local_up());
++    nmoon[0] = l->fg_moonpos.x(); 
++    nmoon[1] = l->fg_moonpos.y();
++    nmoon[2] = l->fg_moonpos.z();
++    MAT3_NORMALIZE_VEC(nup, ntmp);
++    MAT3_NORMALIZE_VEC(nmoon, ntmp);
++
++    l->moon_angle = acos(MAT3_DOT_PRODUCT(nup, nmoon));
++    // printf("  MOON ANGLE relative to current location = %.3f rads.\n", 
++    //        l->moon_angle);
++    
++    // calculate vector to moon's position on the earth's surface
++    rel_moonpos = l->fg_moonpos - (v->get_view_pos() + scenery.center);
++    v->set_to_moon( rel_moonpos.x(), rel_moonpos.y(), rel_moonpos.z() );
++    // printf( "Vector to moon = %.2f %.2f %.2f\n",
++    //         v->to_moon[0], v->to_moon[1], v->to_moon[2]);
++
++    // make a vector to the current view position
++    Point3D view_pos = v->get_view_pos();
++    MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++    // Given a vector from the view position to the point on the
++    // earth's surface the moon is directly over, map into onto the
++    // local plane representing "horizontal".
++    map_vec_onto_cur_surface_plane( v->get_local_up(), v0, v->get_to_moon(), 
++                                  surface_to_moon );
++    MAT3_NORMALIZE_VEC(surface_to_moon, ntmp);
++    v->set_surface_to_moon( surface_to_moon[0], surface_to_moon[1], 
++                         surface_to_moon[2] );
++    // printf("Surface direction to moon is %.2f %.2f %.2f\n",
++    //        v->surface_to_moon[0], v->surface_to_moon[1], v->surface_to_moon[2]);
++    // printf("Should be close to zero = %.2f\n", 
++    //        MAT3_DOT_PRODUCT(v->local_up, v->surface_to_moon));
++
++    // calculate the angle between v->surface_to_moon and
++    // v->surface_east.  We do this so we can sort out the acos()
++    // ambiguity.  I wish I could think of a more efficient way ... :-(
++    east_dot = MAT3_DOT_PRODUCT( surface_to_moon, v->get_surface_east() );
++    // printf("  East dot product = %.2f\n", east_dot);
++
++    // calculate the angle between v->surface_to_moon and
++    // v->surface_south.  this is how much we have to rotate the sky
++    // for it to align with the moon
++    dot = MAT3_DOT_PRODUCT( surface_to_moon, v->get_surface_south() );
++    // printf("  Dot product = %.2f\n", dot);
++    if ( east_dot >= 0 ) {
++      l->moon_rotation = acos(dot);
++    } else {
++      l->moon_rotation = -acos(dot);
++    }
++    // printf("  Sky needs to rotate = %.3f rads = %.1f degrees.\n", 
++    //        angle, angle * RAD_TO_DEG); */
++}
++
++
++// $Log$
++// Revision 1.1  1999/03/22 12:08:57  curt
++// Initial revision.
++//
++// Revision 1.19  1999/01/07 20:25:37  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.18  1998/12/09 18:50:36  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.17  1998/11/09 23:41:53  curt
++// Log message clean ups.
++//
++// Revision 1.16  1998/11/07 19:07:14  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.15  1998/10/18 01:17:24  curt
++// Point3D tweaks.
++//
++// Revision 1.14  1998/10/17 01:34:32  curt
++// C++ ifying ...
++//
++// Revision 1.13  1998/10/16 00:56:12  curt
++// Converted to Point3D class.
++//
++// Revision 1.12  1998/09/15 04:27:50  curt
++// Changes for new astro code.
++//
++// Revision 1.11  1998/08/12 21:13:22  curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.10  1998/07/22 21:45:39  curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++//   but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on moonrise/moonset effects
++//   and view orientation.  This is an attempt to match the fog color to the
++//   sky color in the center of the screen.  You see discrepancies at the
++//   edges, but what else can be done?
++// moonpos.cxx: Caculate local direction to moon here.  (what compass direction
++//   do we need to face to point directly at moon)
++//
++// Revision 1.9  1998/07/08 14:48:39  curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.8  1998/05/02 01:53:18  curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.7  1998/04/30 12:36:05  curt
++// C++-ifying a couple source files.
++//
++// Revision 1.6  1998/04/28 01:22:18  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.5  1998/04/26 05:10:05  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4  1998/04/25 22:06:34  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.3  1998/04/25 20:24:03  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between moon position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2  1998/04/24 00:52:31  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1  1998/04/22 13:24:07  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.27  1998/04/03 22:12:57  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.26  1998/02/23 19:08:00  curt
++// Incorporated Durk's Astro/ tweaks.  Includes unifying the moon position
++// calculation code between moon display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.25  1998/02/09 15:07:53  curt
++// Minor tweaks.
++//
++// Revision 1.24  1998/01/27 00:48:07  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.23  1998/01/19 19:27:21  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.22  1998/01/19 18:40:40  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.21  1997/12/30 23:10:19  curt
++// Calculate lighting parameters here.
++//
++// Revision 1.20  1997/12/30 22:22:43  curt
++// Further integration of event manager.
++//
++// Revision 1.19  1997/12/30 20:47:59  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.18  1997/12/23 04:58:40  curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.17  1997/12/15 23:55:08  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.16  1997/12/11 04:43:57  curt
++// Fixed moon vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15  1997/12/10 22:37:55  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14  1997/12/09 04:25:39  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.13  1997/11/25 19:25:42  curt
++// Changes to integrate Durk's moon/moon code updates + clean up.
++//
++// Revision 1.12  1997/11/15 18:15:39  curt
++// Reverse direction of moon vector, so object normals can be more normal.
++//
++// Revision 1.11  1997/10/28 21:07:21  curt
++// Changed GLUT/ -> Main/
++//
++// Revision 1.10  1997/09/13 02:00:09  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.9  1997/09/05 14:17:31  curt
++// More tweaking with stars.
++//
++// Revision 1.8  1997/09/05 01:36:04  curt
++// Working on getting stars right.
++//
++// Revision 1.7  1997/09/04 02:17:40  curt
++// Shufflin' stuff.
++//
++// Revision 1.6  1997/08/27 03:30:37  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5  1997/08/22 21:34:41  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4  1997/08/19 23:55:09  curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.3  1997/08/13 20:23:49  curt
++// The interface to moonpos now updates a global structure rather than returning
++// current moon position.
++//
++// Revision 1.2  1997/08/06 00:24:32  curt
++// Working on correct real time moon lighting.
++//
++// Revision 1.1  1997/08/01 15:27:56  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dad36e880b312a9d1cdeca90cac2ba1165f24e9f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,60 @@@
++/*
++ * moonpos.hxx (taken from XEarth)
++ * kirk johnson
++ * july 1993
++ *
++ * code for calculating the position on the earth's surface for which
++ * the sun is directly overhead (adapted from _practical astronomy
++ * with your calculator, third edition_, peter duffett-smith,
++ * cambridge university press, 1988.)
++ *
++ * RCS $Id$
++ *
++ * Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++ *
++ * Parts of the source code (as marked) are:
++ *   Copyright (C) 1989, 1990, 1991 by Jim Frost
++ *   Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++ *
++ * Permission to use, copy, modify and freely distribute xearth for
++ * non-commercial and not-for-profit purposes is hereby granted
++ * without fee, provided that both the above copyright notice and this
++ * permission notice appear in all copies and in supporting
++ * documentation.
++ *
++ * The author makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without express or
++ * implied warranty.
++ *
++ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++ * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _MOONPOS_HXX
++#define _MOONPOS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <ctime>
++#else
++#  include <time.h>
++#endif
++
++/* update the cur_time_params structure with the current moon position */
++void fgUpdateMoonPos( void );
++
++void fgMoonPosition(time_t ssue, double *lon, double *lat);
++
++
++#endif /* _MOONPOS_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..024258828fc0a7da6f831ae70570fd2441726afe
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,524 @@@
++// sunpos.cxx (adapted from XEarth)
++// kirk johnson
++// july 1993
++//
++// code for calculating the position on the earth's surface for which
++// the sun is directly overhead (adapted from _practical astronomy
++// with your calculator, third edition_, peter duffett-smith,
++// cambridge university press, 1988.)
++//
++// Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++//
++// Parts of the source code (as marked) are:
++//   Copyright (C) 1989, 1990, 1991 by Jim Frost
++//   Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++//
++// Permission to use, copy, modify and freely distribute xearth for
++// non-commercial and not-for-profit purposes is hereby granted
++// without fee, provided that both the above copyright notice and this
++// permission notice appear in all copies and in supporting
++// documentation.
++//
++// The author makes no representations about the suitability of this
++// software for any purpose. It is provided "as is" without express or
++// implied warranty.
++//
++// THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <cmath>
++#  include <cstdio>
++#  include <ctime>
++#else
++#  include <math.h>
++#  include <stdio.h>
++#  include <time.h>
++#endif
++
++#include <Debug/logstream.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++
++#include "fg_time.hxx"
++#include "sunpos.hxx"
++
++extern SolarSystem *solarSystem;
++
++#undef E
++#define MeanObliquity (23.440592*(FG_2PI/360))
++
++static void   ecliptic_to_equatorial(double, double, double *, double *);
++static double julian_date(int, int, int);
++static double GST(time_t);
++
++static void ecliptic_to_equatorial(double lambda, double beta, 
++                                 double *alpha, double *delta) {
++    /* double  lambda;            ecliptic longitude       */
++    /* double  beta;              ecliptic latitude        */
++    /* double *alpha;             (return) right ascension */
++    /* double *delta;             (return) declination     */
++
++    double sin_e, cos_e;
++    double sin_l, cos_l;
++
++    sin_e = sin(MeanObliquity);
++    cos_e = cos(MeanObliquity);
++    sin_l = sin(lambda);
++    cos_l = cos(lambda);
++
++    *alpha = atan2(sin_l*cos_e - tan(beta)*sin_e, cos_l);
++    *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin_l);
++}
++
++
++/* computing julian dates (assuming gregorian calendar, thus this is
++ * only valid for dates of 1582 oct 15 or later) (after duffett-smith,
++ * section 4) */
++
++static double julian_date(int y, int m, int d) {
++    /* int y;                    year (e.g. 19xx)          */
++    /* int m;                    month (jan=1, feb=2, ...) */
++    /* int d;                    day of month              */
++
++    int    A, B, C, D;
++    double JD;
++
++    /* lazy test to ensure gregorian calendar */
++    if (y < 1583) {
++      FG_LOG( FG_EVENT, FG_ALERT, 
++              "WHOOPS! Julian dates only valid for 1582 oct 15 or later" );
++    }
++
++    if ((m == 1) || (m == 2)) {
++      y -= 1;
++      m += 12;
++    }
++
++    A = y / 100;
++    B = 2 - A + (A / 4);
++    C = (int)(365.25 * y);
++    D = (int)(30.6001 * (m + 1));
++
++    JD = B + C + D + d + 1720994.5;
++
++    return JD;
++}
++
++
++/* compute greenwich mean sidereal time (GST) corresponding to a given
++ * number of seconds since the unix epoch (after duffett-smith,
++ * section 12) */
++static double GST(time_t ssue) {
++    /* time_t ssue;           seconds since unix epoch */
++
++    double     JD;
++    double     T, T0;
++    double     UT;
++    struct tm *tm;
++
++    tm = gmtime(&ssue);
++
++    JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
++    T  = (JD - 2451545) / 36525;
++
++    T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
++
++    T0 = fmod(T0, 24.0);
++    if (T0 < 0) T0 += 24;
++
++    UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
++
++    T0 += UT * 1.002737909;
++    T0 = fmod(T0, 24.0);
++    if (T0 < 0) T0 += 24;
++
++    return T0;
++}
++
++
++/* given a particular time (expressed in seconds since the unix
++ * epoch), compute position on the earth (lat, lon) such that sun is
++ * directly overhead.  (lat, lon are reported in radians */
++
++void fgSunPosition(time_t ssue, double *lon, double *lat) {
++    /* time_t  ssue;           seconds since unix epoch */
++    /* double *lat;            (return) latitude        */
++    /* double *lon;            (return) longitude       */
++
++    /* double lambda; */
++    double alpha, delta;
++    double tmp;
++
++    /* lambda = sun_ecliptic_longitude(ssue); */
++    /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++    //ecliptic_to_equatorial (solarPosition.lonSun, 0.0, &alpha, &delta);
++    
++    /* ********************************************************************** 
++     * NOTE: in the next function, each time the sun's position is updated, the
++     * the sun's longitude is returned from solarSystem->sun. Note that the 
++     * sun's position is updated at a much higher frequency than the rate at 
++     * which the solar system's rebuilds occur. This is not a problem, however,
++     * because the fgSunPosition we're talking about here concerns the changing
++     * position of the sun due to the daily rotation of the earth.
++     * The ecliptic longitude, however, represents the position of the sun with
++     * respect to the stars, and completes just one cycle over the course of a 
++     * year. Its therefore pretty safe to update the sun's longitude only once
++     * every ten minutes. (Comment added by Durk Talsma).
++     ************************************************************************/
++
++    ecliptic_to_equatorial( SolarSystem::theSolarSystem->getSun()->getLon(),
++                          0.0, &alpha, &delta );
++    tmp = alpha - (FG_2PI/24)*GST(ssue);
++    if (tmp < -FG_PI) {
++      do tmp += FG_2PI;
++      while (tmp < -FG_PI);
++    } else if (tmp > FG_PI) {
++      do tmp -= FG_2PI;
++      while (tmp < -FG_PI);
++    }
++
++    *lon = tmp;
++    *lat = delta;
++}
++
++
++/* given a particular time expressed in side real time at prime
++ * meridian (GST), compute position on the earth (lat, lon) such that
++ * sun is directly overhead.  (lat, lon are reported in radians */
++
++static void fgSunPositionGST(double gst, double *lon, double *lat) {
++    /* time_t  ssue;           seconds since unix epoch */
++    /* double *lat;            (return) latitude        */
++    /* double *lon;            (return) longitude       */
++
++    /* double lambda; */
++    double alpha, delta;
++    double tmp;
++
++    /* lambda = sun_ecliptic_longitude(ssue); */
++    /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++    //ecliptic_to_equatorial (solarPosition.lonSun, 0.0, &alpha, &delta);
++    ecliptic_to_equatorial( SolarSystem::theSolarSystem->getSun()->getLon(),
++                          SolarSystem::theSolarSystem->getSun()->getLat(),
++                          &alpha,  &delta );
++
++//    tmp = alpha - (FG_2PI/24)*GST(ssue);
++    tmp = alpha - (FG_2PI/24)*gst;    
++    if (tmp < -FG_PI) {
++      do tmp += FG_2PI;
++      while (tmp < -FG_PI);
++    } else if (tmp > FG_PI) {
++      do tmp -= FG_2PI;
++      while (tmp < -FG_PI);
++    }
++
++    *lon = tmp;
++    *lat = delta;
++}
++
++
++// update the cur_time_params structure with the current sun position
++void fgUpdateSunPos( void ) {
++    fgLIGHT *l;
++    fgTIME *t;
++    FGView *v;
++    MAT3vec nup, nsun, v0, surface_to_sun;
++    Point3D p, rel_sunpos;
++    double dot, east_dot;
++    double sun_gd_lat, sl_radius;
++    double ntmp;
++
++    l = &cur_light_params;
++    t = &cur_time_params;
++    v = &current_view;
++
++    FG_LOG( FG_EVENT, FG_INFO, "  Updating Sun position" );
++
++    // (not sure why there was two)
++    // fgSunPosition(t->cur_time, &l->sun_lon, &sun_gd_lat);
++    fgSunPositionGST(t->gst, &l->sun_lon, &sun_gd_lat);
++
++    fgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &l->sun_gc_lat);
++
++    p = Point3D( l->sun_lon, l->sun_gc_lat, sl_radius );
++    l->fg_sunpos = fgPolarToCart3d(p);
++
++    FG_LOG( FG_EVENT, FG_INFO, "    t->cur_time = " << t->cur_time );
++    FG_LOG( FG_EVENT, FG_INFO, 
++          "    Sun Geodetic lat = " << sun_gd_lat
++          << " Geocentric lat = " << l->sun_gc_lat );
++
++    // I think this will work better for generating the sun light vector
++    l->sun_vec[0] = l->fg_sunpos.x();
++    l->sun_vec[1] = l->fg_sunpos.y();
++    l->sun_vec[2] = l->fg_sunpos.z();
++    MAT3_NORMALIZE_VEC(l->sun_vec, ntmp);
++    MAT3_SCALE_VEC(l->sun_vec_inv, l->sun_vec, -1.0);
++
++    // make sure these are directional light sources only
++    l->sun_vec[3] = 0.0;
++    l->sun_vec_inv[3] = 0.0;
++
++    // printf("  l->sun_vec = %.2f %.2f %.2f\n", l->sun_vec[0], l->sun_vec[1],
++    //        l->sun_vec[2]);
++
++    // calculate the sun's relative angle to local up
++    MAT3_COPY_VEC(nup, v->get_local_up());
++    nsun[0] = l->fg_sunpos.x(); 
++    nsun[1] = l->fg_sunpos.y();
++    nsun[2] = l->fg_sunpos.z();
++    MAT3_NORMALIZE_VEC(nup, ntmp);
++    MAT3_NORMALIZE_VEC(nsun, ntmp);
++
++    l->sun_angle = acos(MAT3_DOT_PRODUCT(nup, nsun));
++    // printf("  SUN ANGLE relative to current location = %.3f rads.\n", 
++    //        l->sun_angle);
++    
++    // calculate vector to sun's position on the earth's surface
++    rel_sunpos = l->fg_sunpos - (v->get_view_pos() + scenery.center);
++    v->set_to_sun( rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() );
++    // printf( "Vector to sun = %.2f %.2f %.2f\n",
++    //         v->to_sun[0], v->to_sun[1], v->to_sun[2]);
++
++    // make a vector to the current view position
++    Point3D view_pos = v->get_view_pos();
++    MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++    // Given a vector from the view position to the point on the
++    // earth's surface the sun is directly over, map into onto the
++    // local plane representing "horizontal".
++    map_vec_onto_cur_surface_plane( v->get_local_up(), v0, v->get_to_sun(), 
++                                  surface_to_sun );
++    MAT3_NORMALIZE_VEC(surface_to_sun, ntmp);
++    v->set_surface_to_sun( surface_to_sun[0], surface_to_sun[1], 
++                         surface_to_sun[2] );
++    // printf("Surface direction to sun is %.2f %.2f %.2f\n",
++    //        v->surface_to_sun[0], v->surface_to_sun[1], v->surface_to_sun[2]);
++    // printf("Should be close to zero = %.2f\n", 
++    //        MAT3_DOT_PRODUCT(v->local_up, v->surface_to_sun));
++
++    // calculate the angle between v->surface_to_sun and
++    // v->surface_east.  We do this so we can sort out the acos()
++    // ambiguity.  I wish I could think of a more efficient way ... :-(
++    east_dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_east() );
++    // printf("  East dot product = %.2f\n", east_dot);
++
++    // calculate the angle between v->surface_to_sun and
++    // v->surface_south.  this is how much we have to rotate the sky
++    // for it to align with the sun
++    dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_south() );
++    // printf("  Dot product = %.2f\n", dot);
++    if ( east_dot >= 0 ) {
++      l->sun_rotation = acos(dot);
++    } else {
++      l->sun_rotation = -acos(dot);
++    }
++    // printf("  Sky needs to rotate = %.3f rads = %.1f degrees.\n", 
++    //        angle, angle * RAD_TO_DEG); */
++}
++
++
++// $Log$
++// Revision 1.21  1999/03/22 02:08:18  curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++//   some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++//   me earlier.
++//
++// Revision 1.20  1999/02/26 22:10:11  curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.19  1999/01/07 20:25:37  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.18  1998/12/09 18:50:36  curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.17  1998/11/09 23:41:53  curt
++// Log message clean ups.
++//
++// Revision 1.16  1998/11/07 19:07:14  curt
++// Enable release builds using the --without-logging option to the configure
++// script.  Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.15  1998/10/18 01:17:24  curt
++// Point3D tweaks.
++//
++// Revision 1.14  1998/10/17 01:34:32  curt
++// C++ ifying ...
++//
++// Revision 1.13  1998/10/16 00:56:12  curt
++// Converted to Point3D class.
++//
++// Revision 1.12  1998/09/15 04:27:50  curt
++// Changes for new astro code.
++//
++// Revision 1.11  1998/08/12 21:13:22  curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.10  1998/07/22 21:45:39  curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++//   but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++//   and view orientation.  This is an attempt to match the fog color to the
++//   sky color in the center of the screen.  You see discrepancies at the
++//   edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here.  (what compass direction
++//   do we need to face to point directly at sun)
++//
++// Revision 1.9  1998/07/08 14:48:39  curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.8  1998/05/02 01:53:18  curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.7  1998/04/30 12:36:05  curt
++// C++-ifying a couple source files.
++//
++// Revision 1.6  1998/04/28 01:22:18  curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.5  1998/04/26 05:10:05  curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4  1998/04/25 22:06:34  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.3  1998/04/25 20:24:03  curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position.  This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2  1998/04/24 00:52:31  curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1  1998/04/22 13:24:07  curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.27  1998/04/03 22:12:57  curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.26  1998/02/23 19:08:00  curt
++// Incorporated Durk's Astro/ tweaks.  Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.25  1998/02/09 15:07:53  curt
++// Minor tweaks.
++//
++// Revision 1.24  1998/01/27 00:48:07  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.23  1998/01/19 19:27:21  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.22  1998/01/19 18:40:40  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.21  1997/12/30 23:10:19  curt
++// Calculate lighting parameters here.
++//
++// Revision 1.20  1997/12/30 22:22:43  curt
++// Further integration of event manager.
++//
++// Revision 1.19  1997/12/30 20:47:59  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.18  1997/12/23 04:58:40  curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.17  1997/12/15 23:55:08  curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.16  1997/12/11 04:43:57  curt
++// Fixed sun vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15  1997/12/10 22:37:55  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14  1997/12/09 04:25:39  curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.13  1997/11/25 19:25:42  curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.12  1997/11/15 18:15:39  curt
++// Reverse direction of sun vector, so object normals can be more normal.
++//
++// Revision 1.11  1997/10/28 21:07:21  curt
++// Changed GLUT/ -> Main/
++//
++// Revision 1.10  1997/09/13 02:00:09  curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.9  1997/09/05 14:17:31  curt
++// More tweaking with stars.
++//
++// Revision 1.8  1997/09/05 01:36:04  curt
++// Working on getting stars right.
++//
++// Revision 1.7  1997/09/04 02:17:40  curt
++// Shufflin' stuff.
++//
++// Revision 1.6  1997/08/27 03:30:37  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5  1997/08/22 21:34:41  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4  1997/08/19 23:55:09  curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.3  1997/08/13 20:23:49  curt
++// The interface to sunpos now updates a global structure rather than returning
++// current sun position.
++//
++// Revision 1.2  1997/08/06 00:24:32  curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.1  1997/08/01 15:27:56  curt
++// Initial revision.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c1a57b83bebfe3ebb4259e19ecbd1f9f07f1386e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,63 @@@
++/*
++ * sunpos.hxx (taken from XEarth)
++ * kirk johnson
++ * july 1993
++ *
++ * code for calculating the position on the earth's surface for which
++ * the sun is directly overhead (adapted from _practical astronomy
++ * with your calculator, third edition_, peter duffett-smith,
++ * cambridge university press, 1988.)
++ *
++ * RCS $Id$
++ *
++ * Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++ *
++ * Parts of the source code (as marked) are:
++ *   Copyright (C) 1989, 1990, 1991 by Jim Frost
++ *   Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++ *
++ * Permission to use, copy, modify and freely distribute xearth for
++ * non-commercial and not-for-profit purposes is hereby granted
++ * without fee, provided that both the above copyright notice and this
++ * permission notice appear in all copies and in supporting
++ * documentation.
++ *
++ * The author makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without express or
++ * implied warranty.
++ *
++ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++ * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _SUNPOS_HXX
++#define _SUNPOS_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <ctime>
++#else
++#  include <time.h>
++#endif
++
++/* update the cur_time_params structure with the current sun position */
++void fgUpdateSunPos( void );
++
++/* update the cur_time_params structure with the current moon position */
++void fgUpdateMoonPos( void );
++
++void fgSunPosition(time_t ssue, double *lon, double *lat);
++
++
++#endif /* _SUNPOS_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dbd9acddced10ca45fdaf5ffe14aeb2d11ec3c7d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,198 @@@
++//
++// timestamp.hxx -- class for managing a timestamp (seconds & milliseconds.)
++//
++// Written by Curtis Olson, started December 1998.
++//
++// Copyright (C) 1998  Curtis L. Olson  - curt@flightgear.org
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _TIMESTAMP_HXX
++#define _TIMESTAMP_HXX
++
++
++#ifndef __cplusplus                                                          
++# error This library requires C++
++#endif                                   
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++#  include <ctime>
++#else
++#  include <time.h>
++#endif
++
++#ifdef HAVE_SYS_TIMEB_H
++#  include <sys/timeb.h> // for ftime() and struct timeb
++#endif
++#ifdef HAVE_UNISTD_H
++#  include <unistd.h>    // for gettimeofday()
++#endif
++#ifdef HAVE_SYS_TIME_H
++#  include <sys/time.h>  // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#ifdef  WIN32
++#  include <windows.h>
++#  if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
++#    define NEAR /* */
++#    define FAR  /* */
++#  endif
++#  include <mmsystem.h>
++#endif
++
++// MSVC++ 6.0 kuldge - Need forward declaration of friends.
++class FGTimeStamp;
++FGTimeStamp operator + (const FGTimeStamp& t, const long& m);
++long operator - (const FGTimeStamp& a, const FGTimeStamp& b);
++
++class FGTimeStamp {
++
++private:
++
++    long seconds;
++    long usec;
++
++public:
++
++    FGTimeStamp();
++    FGTimeStamp( const long s, const long m );
++    ~FGTimeStamp();
++
++    // Set time to current time
++    void stamp();
++
++    FGTimeStamp& operator = ( const FGTimeStamp& t );
++
++    friend FGTimeStamp operator + (const FGTimeStamp& t, const long& m);
++    friend long operator - (const FGTimeStamp& a, const FGTimeStamp& b);
++
++    inline long get_seconds() const { return seconds; }
++    // inline long get_usec() const { return usec; }
++};
++
++inline FGTimeStamp::FGTimeStamp() {
++}
++
++inline FGTimeStamp::FGTimeStamp( const long s, const long u ) {
++    seconds = s;
++    usec = u;
++}
++
++inline FGTimeStamp::~FGTimeStamp() {
++}
++
++inline FGTimeStamp& FGTimeStamp::operator = (const FGTimeStamp& t)
++{
++    seconds = t.seconds;
++    usec = t.usec;
++    return *this;
++}
++
++inline void FGTimeStamp::stamp() {
++#if defined( WIN32 )
++    unsigned int t;
++    t = timeGetTime();
++    seconds = 0;
++    usec =  t * 1000;
++#elif defined( HAVE_GETTIMEOFDAY )
++    struct timeval current;
++    struct timezone tz;
++    // fg_timestamp currtime;
++    gettimeofday(&current, &tz);
++    seconds = current.tv_sec;
++    usec = current.tv_usec;
++#elif defined( HAVE_GETLOCALTIME )
++    SYSTEMTIME current;
++    GetLocalTime(&current);
++    seconds = current.wSecond;
++    usec = current.wMilliseconds * 1000;
++#elif defined( HAVE_FTIME )
++    struct timeb current;
++    ftime(&current);
++    seconds = current.time;
++    usec = current.millitm * 1000;
++#else
++# error Port me
++#endif
++}
++
++// difference between time stamps in microseconds (usec)
++inline FGTimeStamp operator + (const FGTimeStamp& t, const long& m) {
++#ifdef WIN32
++    return FGTimeStamp( 0, t.usec + m );
++#else
++    return FGTimeStamp( t.seconds + ( t.usec + m ) / 1000000,
++                      ( t.usec + m ) % 1000000 );
++#endif
++}
++
++// difference between time stamps in microseconds (usec)
++inline long operator - (const FGTimeStamp& a, const FGTimeStamp& b)
++{
++#if defined( WIN32 )
++    return a.usec - b.usec;
++#else
++    return 1000000 * (a.seconds - b.seconds) + (a.usec - b.usec);
++#endif
++}
++
++
++#endif // _TIMESTAMP_HXX
++
++
++// $Log$
++// Revision 1.5  1999/02/02 20:13:43  curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG.  Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.4  1999/01/09 13:37:46  curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.3  1999/01/07 20:25:39  curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.2  1998/12/11 20:26:56  curt
++// #include tweaks.
++//
++// Revision 1.1  1998/12/05 14:21:33  curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4a5521e1bcf46e9f1c677ddf26b6b136bcb8c0b7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++# libdir      = ${exec_prefix}/lib
++# lib_LTLIBRARIES = libWeather.la
++# libWeather_la_SOURCES = weather.c weather.h
++
++noinst_LIBRARIES = libWeather.a
++
++libWeather_a_SOURCES = weather.cxx weather.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7a1b50c119fb886cc52c90fa7efb5703a3db42a4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,164 @@@
++// weather.cxx -- routines to model weather
++//
++// Written by Curtis Olson, started July 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>                     
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <math.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Math/fg_random.h>
++#include <Weather/weather.hxx>
++
++
++// This is a record containing current weather info
++FGWeather current_weather;
++
++
++FGWeather::FGWeather() {
++}
++
++
++FGWeather::~FGWeather() {
++}
++
++
++// Initialize the weather modeling subsystem
++void FGWeather::Init( ) {
++    FG_LOG( FG_GENERAL, FG_INFO, "Initializing weather subsystem");
++
++    // Configure some wind
++    // FG_V_north_airmass = 15; // ft/s =~ 10mph
++
++    // set_visibility( 45000.0 );    // in meters
++    set_visibility( 32000.0 );       // about 20 miles (in meters)
++}
++
++
++// Update the weather parameters for the current position
++void FGWeather::Update( void ) {
++    FGInterface *f;
++
++    f = current_aircraft.fdm_state;
++
++    // Add some random turbulence
++    // f->set_U_gust( fg_random() * 5.0 - 2.5 );
++    // f->set_V_gust( fg_random() * 5.0 - 2.5 );
++    // f->set_W_gust( fg_random() * 5.0 - 2.5 );
++}
++
++
++// $Log$
++// Revision 1.6  1999/02/05 21:29:21  curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5  1998/12/06 13:51:26  curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.4  1998/12/05 15:54:31  curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.3  1998/11/23 21:49:11  curt
++// Borland portability tweaks.
++//
++// Revision 1.2  1998/11/06 21:18:29  curt
++// Converted to new logstream debugging facility.  This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.1  1998/10/17 01:34:36  curt
++// C++ ifying ...
++//
++// Revision 1.18  1998/10/02 12:46:50  curt
++// Added an "auto throttle"
++//
++// Revision 1.17  1998/07/20 12:51:57  curt
++// Default visibility to about 20 miles.
++//
++// Revision 1.16  1998/06/12 01:00:59  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Added support for exponetial fog, which solves for the proper density to
++// achieve the desired visibility range.
++//
++// Revision 1.15  1998/04/25 22:06:34  curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14  1998/02/09 15:07:54  curt
++// Minor tweaks.
++//
++// Revision 1.13  1998/01/27 00:48:08  curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.12  1998/01/19 19:27:22  curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.11  1998/01/19 18:40:41  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.10  1997/12/30 22:22:46  curt
++// Further integration of event manager.
++//
++// Revision 1.9  1997/12/30 20:48:03  curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.8  1997/12/11 04:43:58  curt
++// Fixed sun vector and lighting problems.  I thing the moon is now lit
++// correctly.
++//
++// Revision 1.7  1997/12/10 22:37:56  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.6  1997/08/27 03:30:38  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5  1997/08/22 21:34:42  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4  1997/08/02 16:23:55  curt
++// Misc. tweaks.
++//
++// Revision 1.3  1997/07/31 22:52:41  curt
++// Working on redoing internal coordinate systems & scenery transformations.
++//
++// Revision 1.2  1997/07/30 16:12:44  curt
++// Moved fg_random routines from Util/ to Math/
++//
++// Revision 1.1  1997/07/19 23:03:57  curt
++// Initial revision.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e17e1f2f55edbfce0ea5de6424527941be390a97
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,113 @@@
++// weather.hxx -- routines to model weather
++//
++// Written by Curtis Olson, started July 1997.
++//
++// Copyright (C) 1997  Curtis L. Olson  - curt@me.umn.edu
++//
++// This program is free software; you can redistribute it and/or
++// modify it under the terms of the GNU General Public License as
++// published by the Free Software Foundation; either version 2 of the
++// License, or (at your option) any later version.
++//
++// This program is distributed in the hope that it will be useful, but
++// WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++// General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with this program; if not, write to the Free Software
++// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifndef _WEATHER_HXX
++#define _WEATHER_HXX
++
++
++// holds the current weather values
++class FGWeather {
++
++private:
++
++    double visibility;
++    GLfloat fog_exp_density;
++    GLfloat fog_exp2_density;
++
++public:
++
++    FGWeather();
++    ~FGWeather();
++
++    void Init();
++    void Update();
++    
++    inline double get_visibility() const { return visibility; }
++
++    inline void set_visibility( double v ) {
++      // in meters
++      visibility = v;
++
++        // for GL_FOG_EXP
++      fog_exp_density = -log(0.01 / visibility);
++
++      // for GL_FOG_EXP2
++      fog_exp2_density = sqrt( -log(0.01) ) / visibility;
++
++      // Set correct opengl fog density
++      xglFogf (GL_FOG_DENSITY, fog_exp2_density);
++
++      // FG_LOG( FG_INPUT, FG_DEBUG, "Fog density = " << w->fog_density );
++    }
++};
++
++extern FGWeather current_weather;
++
++
++#endif // _WEATHER_HXX
++
++
++// $Log$
++// Revision 1.2  1998/12/06 13:51:27  curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.1  1998/10/17 01:34:37  curt
++// C++ ifying ...
++//
++// Revision 1.10  1998/06/12 01:01:00  curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Added support for exponetial fog, which solves for the proper density to
++// achieve the desired visibility range.
++//
++// Revision 1.9  1998/04/21 17:02:46  curt
++// Prepairing for C++ integration.
++//
++// Revision 1.8  1998/01/22 02:59:44  curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.7  1998/01/19 18:40:41  curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6  1997/12/30 22:22:47  curt
++// Further integration of event manager.
++//
++// Revision 1.5  1997/12/10 22:37:56  curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.4  1997/08/27 03:30:39  curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.3  1997/08/22 21:34:43  curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.2  1997/07/23 21:52:30  curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.1  1997/07/19 23:03:58  curt
++// Initial revision.
++//
++