1998-09-29 14:56:30 +00:00
|
|
|
// 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
|
2006-02-21 01:16:04 +00:00
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-09-29 14:56:30 +00:00
|
|
|
//
|
|
|
|
// $Id$
|
1998-05-11 18:13:10 +00:00
|
|
|
|
2001-01-11 05:04:17 +00:00
|
|
|
#include <simgear/compiler.h>
|
2003-09-24 17:20:55 +00:00
|
|
|
#include <simgear/structure/exception.hxx>
|
1997-08-29 18:03:19 +00:00
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
#include STL_STRING
|
|
|
|
#include STL_FSTREAM
|
|
|
|
|
1998-04-24 00:45:53 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
1998-04-03 21:55:27 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_WINDOWS_H
|
1998-02-03 23:20:08 +00:00
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
1998-11-23 21:48:09 +00:00
|
|
|
#ifdef __BORLANDC__
|
|
|
|
# define exception c_exception
|
|
|
|
#endif
|
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
#include <math.h>
|
2002-12-10 20:50:48 +00:00
|
|
|
|
1997-08-29 18:03:19 +00:00
|
|
|
#include <stdlib.h>
|
2006-06-14 10:30:10 +00:00
|
|
|
#include <stdio.h> // char related functions
|
|
|
|
#include <string.h> // strcmp()
|
1998-02-03 23:20:08 +00:00
|
|
|
|
2004-11-18 19:53:00 +00:00
|
|
|
#include SG_GLU_H
|
2004-04-06 03:51:11 +00:00
|
|
|
|
2000-02-15 03:30:01 +00:00
|
|
|
#include <simgear/constants.h>
|
2000-02-16 23:01:03 +00:00
|
|
|
#include <simgear/debug/logstream.hxx>
|
2003-05-06 23:46:24 +00:00
|
|
|
#include <simgear/props/props.hxx>
|
2002-03-16 00:18:38 +00:00
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2000-02-15 03:30:01 +00:00
|
|
|
|
1998-10-16 23:26:44 +00:00
|
|
|
#include <Aircraft/aircraft.hxx>
|
2004-01-31 19:47:45 +00:00
|
|
|
#include <Autopilot/xmlauto.hxx>
|
2005-11-09 10:47:40 +00:00
|
|
|
#include <GUI/new_gui.hxx>
|
2000-10-19 23:09:33 +00:00
|
|
|
#include <Main/globals.hxx>
|
2001-01-13 22:06:39 +00:00
|
|
|
#include <Main/fg_props.hxx>
|
1998-04-30 12:35:59 +00:00
|
|
|
#include <Scenery/scenery.hxx>
|
1997-08-29 18:03:19 +00:00
|
|
|
|
1998-07-30 23:44:05 +00:00
|
|
|
#include "hud.hxx"
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
|
2006-06-09 10:53:48 +00:00
|
|
|
static HUD_Properties *HUD = 0;
|
2006-06-07 18:01:19 +00:00
|
|
|
|
1998-11-03 12:33:11 +00:00
|
|
|
static char units[5];
|
1998-06-05 18:17:10 +00:00
|
|
|
|
1999-05-12 02:04:38 +00:00
|
|
|
// The following routines obtain information concerning the aircraft's
|
1998-02-07 15:29:31 +00:00
|
|
|
// current state and return it to calling instrument display routines.
|
|
|
|
// They should eventually be member functions of the aircraft.
|
|
|
|
//
|
|
|
|
|
1999-05-12 02:04:38 +00:00
|
|
|
deque< instr_item * > HUD_deque;
|
|
|
|
|
1999-06-01 21:17:10 +00:00
|
|
|
fgTextList HUD_TextList;
|
|
|
|
fgLineList HUD_LineList;
|
|
|
|
fgLineList HUD_StippleLineList;
|
1998-02-16 13:38:39 +00:00
|
|
|
|
2000-05-13 00:02:43 +00:00
|
|
|
fntRenderer *HUDtext = 0;
|
2006-06-06 15:34:18 +00:00
|
|
|
fntTexFont *HUD_Font = 0;
|
|
|
|
float HUD_TextSize = 0;
|
2000-05-13 00:02:43 +00:00
|
|
|
int HUD_style = 0;
|
|
|
|
|
|
|
|
float HUD_matrix[16];
|
|
|
|
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
//$$$ begin - added, Neetha, 28 Nov 2k
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
static string name;
|
|
|
|
static int x;
|
|
|
|
static int y;
|
2001-01-08 20:55:16 +00:00
|
|
|
static UINT width;
|
|
|
|
static UINT height;
|
2006-06-09 21:29:40 +00:00
|
|
|
static float factor;
|
2001-01-08 20:55:16 +00:00
|
|
|
static float span_units;
|
|
|
|
static float division_units;
|
|
|
|
static float minor_division = 0;
|
|
|
|
static UINT screen_hole;
|
|
|
|
static UINT lbl_pos;
|
|
|
|
static bool working;
|
|
|
|
static string loadfn;
|
2006-06-09 21:29:40 +00:00
|
|
|
static UINT options;
|
2001-01-08 20:55:16 +00:00
|
|
|
static float maxValue;
|
|
|
|
static float minValue;
|
|
|
|
static float scaling;
|
|
|
|
static UINT major_divs;
|
|
|
|
static UINT minor_divs;
|
|
|
|
static UINT modulator;
|
|
|
|
static int dp_showing = 0;
|
|
|
|
static string label_format;
|
|
|
|
static string prelabel;
|
|
|
|
static string postlabel;
|
|
|
|
static int justi;
|
2006-06-09 21:29:40 +00:00
|
|
|
static int blinking;
|
2001-01-08 20:55:16 +00:00
|
|
|
static float maxBankAngle;
|
|
|
|
static float maxSlipAngle;
|
|
|
|
static UINT gap_width;
|
2006-06-09 21:29:40 +00:00
|
|
|
static bool latitude;
|
|
|
|
static bool longitude;
|
|
|
|
static bool tick_bottom;
|
|
|
|
static bool tick_top;
|
|
|
|
static bool tick_right;
|
|
|
|
static bool tick_left;
|
|
|
|
static bool cap_bottom;
|
|
|
|
static bool cap_top;
|
|
|
|
static bool cap_right;
|
|
|
|
static bool cap_left;
|
2001-01-08 20:55:16 +00:00
|
|
|
static float marker_off;
|
|
|
|
static string type;
|
|
|
|
static bool enable_pointer;
|
|
|
|
static string type_pointer;
|
|
|
|
static bool frl_spot;
|
2006-06-09 21:29:40 +00:00
|
|
|
static bool target;
|
2001-01-08 20:55:16 +00:00
|
|
|
static bool vel_vector;
|
|
|
|
static bool drift;
|
|
|
|
static bool alpha;
|
2006-06-09 21:29:40 +00:00
|
|
|
static bool energy;
|
|
|
|
static bool climb_dive;
|
|
|
|
static bool glide;
|
|
|
|
static float glide_slope_val;
|
|
|
|
static bool worm_energy;
|
|
|
|
static bool waypoint;
|
2006-06-14 10:30:10 +00:00
|
|
|
static string type_tick;
|
|
|
|
static string length_tick;
|
|
|
|
static bool label_box;
|
|
|
|
static int digits;
|
|
|
|
static float radius;
|
|
|
|
static int divisions;
|
|
|
|
static int zoom;
|
|
|
|
static int zenith;
|
|
|
|
static int nadir ;
|
|
|
|
static int hat;
|
|
|
|
static bool tsi;
|
|
|
|
static float rad;
|
2006-06-09 21:29:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
static FLTFNPTR load_fn;
|
2001-01-08 20:55:16 +00:00
|
|
|
static fgLabelJust justification;
|
|
|
|
static const char *pre_label_string = 0;
|
|
|
|
static const char *post_label_string = 0;
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
int readHud( istream &input );
|
|
|
|
int readInstrument ( const SGPropertyNode * node);
|
|
|
|
static instr_item * readLadder ( const SGPropertyNode * node);
|
|
|
|
static instr_item * readCard ( const SGPropertyNode * node);
|
|
|
|
static instr_item * readLabel( const SGPropertyNode * node);
|
|
|
|
static instr_item * readTBI( const SGPropertyNode * node);
|
|
|
|
//$$$ end - added, Neetha, 28 Nov 2k
|
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
static void drawHUD();
|
|
|
|
static void fgUpdateHUDVirtual();
|
|
|
|
|
1998-05-11 18:13:10 +00:00
|
|
|
class locRECT {
|
2001-09-20 22:10:45 +00:00
|
|
|
public:
|
1998-05-11 18:13:10 +00:00
|
|
|
RECT rect;
|
1998-02-16 13:38:39 +00:00
|
|
|
|
1998-05-11 18:13:10 +00:00
|
|
|
locRECT( UINT left, UINT top, UINT right, UINT bottom);
|
|
|
|
RECT get_rect(void) { return rect;}
|
|
|
|
};
|
1998-02-16 13:38:39 +00:00
|
|
|
|
1998-05-11 18:13:10 +00:00
|
|
|
locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
|
1998-02-16 13:38:39 +00:00
|
|
|
{
|
2001-09-20 22:10:45 +00:00
|
|
|
rect.left = left;
|
|
|
|
rect.top = top;
|
|
|
|
rect.right = right;
|
|
|
|
rect.bottom = bottom;
|
1998-02-16 13:38:39 +00:00
|
|
|
|
|
|
|
}
|
1998-05-11 18:13:10 +00:00
|
|
|
// #define DEBUG
|
1998-02-16 13:38:39 +00:00
|
|
|
|
1998-05-11 18:13:10 +00:00
|
|
|
//========================= End of Class Implementations===================
|
1998-02-07 15:29:31 +00:00
|
|
|
// 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!
|
|
|
|
//
|
1998-05-11 18:13:10 +00:00
|
|
|
|
1998-07-03 13:16:27 +00:00
|
|
|
#define INSTRDEFS 21
|
1998-05-11 18:13:10 +00:00
|
|
|
|
2001-01-05 16:44:48 +00:00
|
|
|
//$$$ begin - added, Neetha, 28 Nov 2k
|
2006-06-09 21:29:40 +00:00
|
|
|
static instr_item *
|
2001-01-05 16:44:48 +00:00
|
|
|
readLadder(const SGPropertyNode * node)
|
1997-08-29 18:03:19 +00:00
|
|
|
{
|
1999-05-12 02:04:38 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
instr_item *p;
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
name = node->getStringValue("name");
|
|
|
|
x = node->getIntValue("x");
|
|
|
|
y = node->getIntValue("y");
|
|
|
|
width = node->getIntValue("width");
|
|
|
|
height = node->getIntValue("height");
|
|
|
|
factor = node->getFloatValue("compression_factor");
|
|
|
|
span_units = node->getFloatValue("span_units");
|
|
|
|
division_units = node->getFloatValue("division_units");
|
|
|
|
screen_hole = node->getIntValue("screen_hole");
|
|
|
|
lbl_pos = node->getIntValue("lbl_pos");
|
|
|
|
frl_spot = node->getBoolValue("enable_frl",false);
|
|
|
|
target = node->getBoolValue("enable_target_spot",false);
|
|
|
|
vel_vector = node->getBoolValue("enable_velocity_vector",false);
|
|
|
|
drift = node->getBoolValue("enable_drift_marker",false);
|
|
|
|
alpha = node->getBoolValue("enable_alpha_bracket",false);
|
|
|
|
energy = node->getBoolValue("enable_energy_marker",false);
|
|
|
|
climb_dive = node->getBoolValue("enable_climb_dive_marker",false);
|
|
|
|
glide = node->getBoolValue("enable_glide_slope_marker",false);
|
|
|
|
glide_slope_val = node->getFloatValue("glide_slope",-4.0);
|
|
|
|
worm_energy = node->getBoolValue("enable_energy_marker",false);
|
|
|
|
waypoint = node->getBoolValue("enable_waypoint_marker",false);
|
|
|
|
working = node->getBoolValue("working");
|
2006-06-14 10:30:10 +00:00
|
|
|
zenith = node->getIntValue("zenith");
|
|
|
|
nadir = node->getIntValue("nadir");
|
2006-06-09 21:29:40 +00:00
|
|
|
hat = node->getIntValue("hat");
|
2003-03-21 15:02:23 +00:00
|
|
|
// The factor assumes a base of 55 degrees per 640 pixels.
|
|
|
|
// Invert to convert the "compression" factor to a
|
|
|
|
// pixels-per-degree number.
|
2006-06-14 10:30:10 +00:00
|
|
|
if (fgGetBool("/sim/hud/enable3d", true)) {
|
|
|
|
if (HUD_style == 1) {
|
2003-03-21 15:02:23 +00:00
|
|
|
factor = 1;
|
2003-07-14 13:57:11 +00:00
|
|
|
factor = (640./55.) / factor;
|
|
|
|
}
|
2003-03-21 15:02:23 +00:00
|
|
|
}
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
p = (instr_item *) new HudLadder( name, x, y,
|
|
|
|
width, height, factor,
|
|
|
|
get_roll, get_pitch,
|
|
|
|
span_units, division_units, minor_division,
|
2006-06-09 21:29:40 +00:00
|
|
|
screen_hole, lbl_pos, frl_spot, target, vel_vector,
|
|
|
|
drift, alpha, energy, climb_dive,
|
|
|
|
glide, glide_slope_val, worm_energy,
|
2001-09-20 22:10:45 +00:00
|
|
|
waypoint, working, zenith, nadir, hat);
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
return p;
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-01-05 16:44:48 +00:00
|
|
|
} //end readLadder
|
The following changes were made to flightgear-0.7.5 code to implement the follow
ing features:
a) ADA Flight model - ADA.cxx, ADA.hxx, flight.hxx
b) Fighter a/c HUD - flight.hxx, hud.hxx, hud.cxx, cockpit.cxx, hud_ladr.c
xx, hud_card.cxx
c) 3-window display - options.hxx, options.cxx, viewer.cxx
d) Moving objects (ship) - main.cxx
e) Patches - main.cxx
ADA.cxx, ADA.hxx
--------------------------
Interface to the external ADA flight dynamics package.
flight.hxx
----------
Included prototypes for accepting additional data fron the External flight
model for fighter aircraft HUD
Hud.hxx
-------
Included prototypes for accepting additional data for fighter HUD from Exernal F
light model.
Defined FIGHTER_HUD pre-processor directive to enable compilation of fighter hud
code.
hud.cxx, cockpit.cxx, hud_ladr.cxx, hud_card.cxx
---------------------------------------
Included code to initialise additional reticles/text for fighter HUD which is co
nditionally
compiled if FIGHTER_HUD is defined.
options.hxx
-----------
Added window_offset, and function to retrieve its value for 3 windows
options.cxx
-----------
Changed few options to suit ADA/CEF projection system/screens and checks for win
dow offset.
views.cxx
---------
Added code to retrieve view offset for window.
Main.cxx
--------
Added code to load and move an aircraft carrier.
Patch to enable clouds from command line until Curtis fixes it. By default cloud
s are disabled.
2000-10-19 19:46:13 +00:00
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
static instr_item *
|
2001-01-05 16:44:48 +00:00
|
|
|
readCard(const SGPropertyNode * node)
|
|
|
|
{
|
1999-05-12 02:04:38 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
instr_item *p;
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
name = node->getStringValue("name");
|
|
|
|
x = node->getIntValue("x");
|
|
|
|
y = node->getIntValue("y");
|
|
|
|
width = node->getIntValue("width");
|
|
|
|
height = node->getIntValue("height");
|
|
|
|
loadfn = node->getStringValue("loadfn");
|
|
|
|
options = node->getIntValue("options");
|
|
|
|
maxValue = node->getFloatValue("maxValue");
|
|
|
|
minValue = node->getFloatValue("minValue");
|
|
|
|
scaling = node->getFloatValue("disp_scaling");
|
|
|
|
major_divs = node->getIntValue("major_divs");
|
|
|
|
minor_divs = node->getIntValue("minor_divs");
|
|
|
|
modulator = node->getIntValue("modulator");
|
|
|
|
span_units = node->getFloatValue("value_span");
|
|
|
|
type = node->getStringValue("type");
|
|
|
|
tick_bottom = node->getBoolValue("tick_bottom",false);
|
|
|
|
tick_top = node->getBoolValue("tick_top",false);
|
|
|
|
tick_right = node->getBoolValue("tick_right",false);
|
|
|
|
tick_left = node->getBoolValue("tick_left",false);
|
|
|
|
cap_bottom = node->getBoolValue("cap_bottom",false);
|
|
|
|
cap_top = node->getBoolValue("cap_top",false);
|
|
|
|
cap_right = node->getBoolValue("cap_right",false);
|
|
|
|
cap_left = node->getBoolValue("cap_left",false);
|
|
|
|
marker_off = node->getFloatValue("marker_offset",0.0);
|
|
|
|
enable_pointer = node->getBoolValue("enable_pointer",true);
|
|
|
|
type_pointer = node->getStringValue("pointer_type");
|
2006-06-14 10:30:10 +00:00
|
|
|
type_tick = node->getStringValue("tick_type"); // 'circle' or 'line'
|
|
|
|
length_tick = node->getStringValue("tick_length"); // for variable length
|
2006-06-09 21:29:40 +00:00
|
|
|
working = node->getBoolValue("working");
|
2006-06-14 10:30:10 +00:00
|
|
|
radius = node->getFloatValue("radius");
|
|
|
|
divisions = node->getIntValue("divisions");
|
|
|
|
zoom = node->getIntValue("zoom");
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
|
|
|
|
|
|
|
|
|
2006-06-14 10:30:10 +00:00
|
|
|
if (type=="gauge") {
|
2001-09-20 22:10:45 +00:00
|
|
|
span_units = maxValue - minValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loadfn=="anzg") {
|
|
|
|
load_fn = get_anzg;
|
|
|
|
} else if (loadfn=="heading") {
|
|
|
|
load_fn = get_heading;
|
|
|
|
} else if (loadfn=="aoa") {
|
|
|
|
load_fn = get_aoa;
|
|
|
|
} else if (loadfn=="climb") {
|
|
|
|
load_fn = get_climb_rate;
|
|
|
|
} else if (loadfn=="altitude") {
|
|
|
|
load_fn = get_altitude;
|
|
|
|
} else if (loadfn=="agl") {
|
|
|
|
load_fn = get_agl;
|
|
|
|
} else if (loadfn=="speed") {
|
|
|
|
load_fn = get_speed;
|
|
|
|
} else if (loadfn=="view_direction") {
|
|
|
|
load_fn = get_view_direction;
|
|
|
|
} else if (loadfn=="aileronval") {
|
|
|
|
load_fn = get_aileronval;
|
|
|
|
} else if (loadfn=="elevatorval") {
|
|
|
|
load_fn = get_elevatorval;
|
2002-03-27 20:27:52 +00:00
|
|
|
} else if (loadfn=="elevatortrimval") {
|
|
|
|
load_fn = get_elev_trimval;
|
2001-09-20 22:10:45 +00:00
|
|
|
} else if (loadfn=="rudderval") {
|
|
|
|
load_fn = get_rudderval;
|
|
|
|
} else if (loadfn=="throttleval") {
|
|
|
|
load_fn = get_throttleval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( (type == "dial") | (type == "tape") ) {
|
|
|
|
p = (instr_item *) new hud_card( x,
|
2006-06-09 21:29:40 +00:00
|
|
|
y,
|
2001-09-20 22:10:45 +00:00
|
|
|
width,
|
|
|
|
height,
|
|
|
|
load_fn,
|
|
|
|
options,
|
|
|
|
maxValue, minValue,
|
|
|
|
scaling,
|
|
|
|
major_divs, minor_divs,
|
|
|
|
modulator,
|
|
|
|
dp_showing,
|
|
|
|
span_units,
|
|
|
|
type,
|
|
|
|
tick_bottom,
|
|
|
|
tick_top,
|
|
|
|
tick_right,
|
|
|
|
tick_left,
|
|
|
|
cap_bottom,
|
|
|
|
cap_top,
|
|
|
|
cap_right,
|
|
|
|
cap_left,
|
|
|
|
marker_off,
|
|
|
|
enable_pointer,
|
|
|
|
type_pointer,
|
2006-06-14 10:30:10 +00:00
|
|
|
type_tick,
|
|
|
|
length_tick,
|
2001-09-20 22:10:45 +00:00
|
|
|
working,
|
2006-06-14 10:30:10 +00:00
|
|
|
radius,
|
|
|
|
divisions,
|
|
|
|
zoom
|
2001-09-20 22:10:45 +00:00
|
|
|
);
|
|
|
|
} else {
|
2006-06-09 21:29:40 +00:00
|
|
|
p = (instr_item *) new gauge_instr( x, // x
|
|
|
|
y, // y
|
|
|
|
width, // width
|
|
|
|
height, // height
|
2001-09-20 22:10:45 +00:00
|
|
|
load_fn, // data source
|
|
|
|
options,
|
|
|
|
scaling,
|
|
|
|
maxValue,minValue,
|
|
|
|
major_divs, minor_divs,
|
|
|
|
dp_showing,
|
|
|
|
modulator,
|
|
|
|
working);
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
2001-01-05 16:44:48 +00:00
|
|
|
}// end readCard
|
|
|
|
|
|
|
|
static instr_item *
|
|
|
|
readLabel(const SGPropertyNode * node)
|
|
|
|
{
|
2001-09-20 22:10:45 +00:00
|
|
|
instr_item *p;
|
|
|
|
|
2002-07-06 17:50:38 +00:00
|
|
|
int font_size = (fgGetInt("/sim/startup/xsize") > 1000) ? HUD_FONT_LARGE : HUD_FONT_SMALL;
|
2001-09-20 22:10:45 +00:00
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
name = node->getStringValue("name");
|
|
|
|
x = node->getIntValue("x");
|
|
|
|
y = node->getIntValue("y");
|
|
|
|
width = node->getIntValue("width");
|
|
|
|
height = node->getIntValue("height");
|
|
|
|
loadfn = node->getStringValue("data_source");
|
|
|
|
label_format = node->getStringValue("label_format");
|
|
|
|
prelabel = node->getStringValue("pre_label_string");
|
|
|
|
postlabel = node->getStringValue("post_label_string");
|
|
|
|
scaling = node->getFloatValue("scale_data");
|
|
|
|
options = node->getIntValue("options");
|
|
|
|
justi = node->getIntValue("justification");
|
|
|
|
blinking = node->getIntValue("blinking");
|
|
|
|
latitude = node->getBoolValue("latitude",false);
|
|
|
|
longitude = node->getBoolValue("longitude",false);
|
2006-06-14 10:30:10 +00:00
|
|
|
label_box = node->getBoolValue("label_box",false);
|
2006-06-09 21:29:40 +00:00
|
|
|
working = node->getBoolValue("working");
|
2006-06-14 10:30:10 +00:00
|
|
|
digits = node->getIntValue("digits");
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
|
|
|
|
|
|
|
|
|
|
|
|
if ( justi == 0 ) {
|
|
|
|
justification = LEFT_JUST;
|
|
|
|
} else {
|
|
|
|
if ( justi == 1 ) {
|
|
|
|
justification = CENTER_JUST;
|
2001-06-06 17:43:16 +00:00
|
|
|
} else {
|
2001-09-20 22:10:45 +00:00
|
|
|
if ( justi == 2 ) {
|
|
|
|
justification = RIGHT_JUST;
|
2001-06-06 17:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
if ( prelabel == "NULL" ) {
|
|
|
|
pre_label_string = NULL;
|
|
|
|
} else {
|
|
|
|
if ( prelabel == "blank" ) {
|
|
|
|
pre_label_string = " ";
|
2001-06-06 17:43:16 +00:00
|
|
|
} else {
|
2001-09-20 22:10:45 +00:00
|
|
|
pre_label_string = prelabel.c_str();
|
2001-06-06 17:43:16 +00:00
|
|
|
}
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
if ( postlabel == "blank" ) {
|
|
|
|
post_label_string = " ";
|
|
|
|
} else {
|
|
|
|
if ( postlabel == "NULL" ) {
|
|
|
|
post_label_string = NULL;
|
2001-06-06 17:43:16 +00:00
|
|
|
} else {
|
2001-09-20 22:10:45 +00:00
|
|
|
if ( postlabel == "units" ) {
|
|
|
|
post_label_string = units;
|
2001-06-06 17:43:16 +00:00
|
|
|
} else {
|
2001-09-20 22:10:45 +00:00
|
|
|
post_label_string = postlabel.c_str();
|
2001-06-06 17:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2004-10-20 08:15:55 +00:00
|
|
|
#ifdef ENABLE_SP_FMDS
|
2001-09-20 22:10:45 +00:00
|
|
|
if ( loadfn== "aux1" ) {
|
|
|
|
load_fn = get_aux1;
|
|
|
|
} else if ( loadfn == "aux2" ) {
|
|
|
|
load_fn = get_aux2;
|
|
|
|
} else if ( loadfn == "aux3" ) {
|
|
|
|
load_fn = get_aux3;
|
|
|
|
} else if ( loadfn == "aux4" ) {
|
|
|
|
load_fn = get_aux4;
|
|
|
|
} else if ( loadfn == "aux5" ) {
|
|
|
|
load_fn = get_aux5;
|
|
|
|
} else if ( loadfn == "aux6" ) {
|
|
|
|
load_fn = get_aux6;
|
|
|
|
} else if ( loadfn == "aux7" ) {
|
|
|
|
load_fn = get_aux7;
|
|
|
|
} else if ( loadfn == "aux8" ) {
|
|
|
|
load_fn = get_aux8;
|
|
|
|
} else if ( loadfn == "aux9" ) {
|
|
|
|
load_fn = get_aux9;
|
|
|
|
} else if ( loadfn == "aux10" ) {
|
|
|
|
load_fn = get_aux10;
|
|
|
|
} else if ( loadfn == "aux11" ) {
|
|
|
|
load_fn = get_aux11;
|
|
|
|
} else if ( loadfn == "aux12" ) {
|
|
|
|
load_fn = get_aux12;
|
|
|
|
} else if ( loadfn == "aux13" ) {
|
|
|
|
load_fn = get_aux13;
|
|
|
|
} else if ( loadfn == "aux14" ) {
|
|
|
|
load_fn = get_aux14;
|
|
|
|
} else if ( loadfn == "aux15" ) {
|
|
|
|
load_fn = get_aux15;
|
|
|
|
} else if ( loadfn == "aux16" ) {
|
|
|
|
load_fn = get_aux16;
|
|
|
|
} else if ( loadfn == "aux17" ) {
|
|
|
|
load_fn = get_aux17;
|
|
|
|
} else if ( loadfn == "aux18" ) {
|
|
|
|
load_fn = get_aux18;
|
2004-10-20 08:15:55 +00:00
|
|
|
} else
|
|
|
|
#endif
|
2006-06-09 21:29:40 +00:00
|
|
|
if ( loadfn == "ax" ) {
|
2001-09-20 22:10:45 +00:00
|
|
|
load_fn = get_Ax;
|
|
|
|
} else if ( loadfn == "speed" ) {
|
|
|
|
load_fn = get_speed;
|
|
|
|
} else if ( loadfn == "mach" ) {
|
|
|
|
load_fn = get_mach;
|
|
|
|
} else if ( loadfn == "altitude" ) {
|
|
|
|
load_fn = get_altitude;
|
|
|
|
} else if ( loadfn == "agl" ) {
|
|
|
|
load_fn = get_agl;
|
|
|
|
} else if ( loadfn == "framerate" ) {
|
|
|
|
load_fn = get_frame_rate;
|
|
|
|
} else if ( loadfn == "heading" ) {
|
|
|
|
load_fn = get_heading;
|
|
|
|
} else if ( loadfn == "fov" ) {
|
|
|
|
load_fn = get_fov;
|
|
|
|
} else if ( loadfn == "vfc_tris_culled" ) {
|
|
|
|
load_fn = get_vfc_tris_culled;
|
|
|
|
} else if ( loadfn == "vfc_tris_drawn" ) {
|
|
|
|
load_fn = get_vfc_tris_drawn;
|
|
|
|
} else if ( loadfn == "aoa" ) {
|
|
|
|
load_fn = get_aoa;
|
|
|
|
} else if ( loadfn == "latitude" ) {
|
|
|
|
load_fn = get_latitude;
|
|
|
|
} else if ( loadfn == "anzg" ) {
|
|
|
|
load_fn = get_anzg;
|
|
|
|
} else if ( loadfn == "longitude" ) {
|
|
|
|
load_fn = get_longitude;
|
|
|
|
} else if (loadfn=="throttleval") {
|
|
|
|
load_fn = get_throttleval;
|
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
p = (instr_item *) new instr_label ( x,
|
|
|
|
y,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
load_fn,
|
|
|
|
label_format.c_str(),
|
|
|
|
pre_label_string,
|
|
|
|
post_label_string,
|
|
|
|
scaling,
|
|
|
|
options,
|
|
|
|
justification,
|
|
|
|
font_size,
|
|
|
|
blinking,
|
|
|
|
latitude,
|
|
|
|
longitude,
|
2006-06-14 10:30:10 +00:00
|
|
|
label_box,
|
2001-09-20 22:10:45 +00:00
|
|
|
working,
|
2006-06-14 10:30:10 +00:00
|
|
|
digits);
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
return p;
|
2001-01-05 16:44:48 +00:00
|
|
|
} // end readLabel
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
static instr_item *
|
2001-01-05 16:44:48 +00:00
|
|
|
readTBI(const SGPropertyNode * node)
|
|
|
|
{
|
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
instr_item *p;
|
|
|
|
|
|
|
|
name = node->getStringValue("name");
|
|
|
|
x = node->getIntValue("x");
|
|
|
|
y = node->getIntValue("y");
|
|
|
|
width = node->getIntValue("width");
|
|
|
|
height = node->getIntValue("height");
|
|
|
|
maxBankAngle = node->getFloatValue("maxBankAngle");
|
|
|
|
maxSlipAngle = node->getFloatValue("maxSlipAngle");
|
|
|
|
gap_width = node->getIntValue("gap_width");
|
|
|
|
working = node->getBoolValue("working");
|
2006-06-14 10:30:10 +00:00
|
|
|
tsi = node->getBoolValue("tsi");
|
|
|
|
rad = node->getFloatValue("rad");
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
|
|
|
|
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
p = (instr_item *) new fgTBI_instr( x,
|
|
|
|
y,
|
2001-09-20 22:10:45 +00:00
|
|
|
width,
|
|
|
|
height,
|
|
|
|
get_roll,
|
|
|
|
get_sideslip,
|
2006-06-09 21:29:40 +00:00
|
|
|
maxBankAngle,
|
2001-09-20 22:10:45 +00:00
|
|
|
maxSlipAngle,
|
|
|
|
gap_width,
|
|
|
|
working,
|
2006-06-14 10:30:10 +00:00
|
|
|
tsi,
|
|
|
|
rad);
|
2001-09-20 22:10:45 +00:00
|
|
|
|
|
|
|
return p;
|
2001-01-05 16:44:48 +00:00
|
|
|
} //end readTBI
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
static instr_item *
|
I have added Aaron Wilson's virtual 3d runway projection to the HUD.
Aaron says:
I just got the virtual runway hud projection working on all views and
2D & 3D HUDs. It is working awesome(see below). I have attached every
file that was modified (hud.hxx, hud.cxx, and the default.xml for the hud)
and every file that was added (hud_rwy.cxx and runwayinstr.xml).
Just a quick overview of how the instrument works.
The virtual runway is projected by getting the "cockpit view" of the
runway in 3D and projecting the points on to the 2D HUD. Therefore, the
virtual runway will be displayed the same in every view. For example,
you can land an aircraft from the "Tower View" by flying the HUD. Also
if you're in "Cockpit View" and it is centered then the virtual runway
lines will perfectly outline the actual runway. I am getting the active
runway via the wind like done in the ATC classes, which may need changed.
Also, I made the assumption the view 0, in view manager, is always the
cockpit view, which may need changed as well.
The runway configuration file will allow you to specify a center offset
(x,y) and a bounding box (width,height). You can also configure the line
stipple pattern for the outside and the center line. For instance, if
you wanted a 0xFAFA pattern, then specify 64250 as the value. If you
want a solid line, you can specify -1 or 65535 (0xFFFF) and zero will
turn the line off. It also draws a runway indication arrow when the
runway is not in the HUD or it can be drawn all the time if arrow_always
is true. The arrow will point in the direction of the runway (2D) by
rotating around the center at a radius of arrow_radius. If you wish to
turn the arrow off, you must set the arrow_scale <=0. The arrow really
should be 3D arrow that points to the runway (or points in the direction
of the aircraft-to-runway vector).
2004-11-19 18:31:02 +00:00
|
|
|
readRunway(const SGPropertyNode * node) {
|
2006-06-09 21:29:40 +00:00
|
|
|
name = node->getStringValue("name");
|
|
|
|
x = node->getIntValue("x");
|
|
|
|
y = node->getIntValue("y");
|
|
|
|
width = node->getIntValue("width");
|
|
|
|
height = node->getIntValue("height");
|
|
|
|
scaling = node->getDoubleValue("scale");
|
|
|
|
working = node->getBoolValue("working",true);
|
|
|
|
runway_instr *ri = new runway_instr(x,y,width,height,scaling,working);
|
|
|
|
double scale = node->getDoubleValue("arrow_scale",1.0);
|
|
|
|
ri->setDrawArrow((scale>0)?true:false);
|
|
|
|
ri->setDrawArrowAlways((scale>0)?node->getBoolValue("arrow_always"):false);
|
|
|
|
ri->setStippleOutline(node->getIntValue("outer_stipple",0xFFFF));
|
|
|
|
ri->setStippleCenterline(node->getIntValue("center_stipple",0xFFFF));
|
|
|
|
ri->setArrowRotationRadius(node->getDoubleValue("arrow_radius"));
|
|
|
|
ri->setArrowScale(scale);
|
|
|
|
ri->setLineScale(node->getDoubleValue("line_scale",1.0));
|
|
|
|
ri->setScaleDist(node->getDoubleValue("scale_dist_nm"));
|
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
|
|
|
|
return (instr_item *) ri;
|
I have added Aaron Wilson's virtual 3d runway projection to the HUD.
Aaron says:
I just got the virtual runway hud projection working on all views and
2D & 3D HUDs. It is working awesome(see below). I have attached every
file that was modified (hud.hxx, hud.cxx, and the default.xml for the hud)
and every file that was added (hud_rwy.cxx and runwayinstr.xml).
Just a quick overview of how the instrument works.
The virtual runway is projected by getting the "cockpit view" of the
runway in 3D and projecting the points on to the 2D HUD. Therefore, the
virtual runway will be displayed the same in every view. For example,
you can land an aircraft from the "Tower View" by flying the HUD. Also
if you're in "Cockpit View" and it is centered then the virtual runway
lines will perfectly outline the actual runway. I am getting the active
runway via the wind like done in the ATC classes, which may need changed.
Also, I made the assumption the view 0, in view manager, is always the
cockpit view, which may need changed as well.
The runway configuration file will allow you to specify a center offset
(x,y) and a bounding box (width,height). You can also configure the line
stipple pattern for the outside and the center line. For instance, if
you wanted a 0xFAFA pattern, then specify 64250 as the value. If you
want a solid line, you can specify -1 or 65535 (0xFFFF) and zero will
turn the line off. It also draws a runway indication arrow when the
runway is not in the HUD or it can be drawn all the time if arrow_always
is true. The arrow will point in the direction of the runway (2D) by
rotating around the center at a radius of arrow_radius. If you wish to
turn the arrow off, you must set the arrow_scale <=0. The arrow really
should be 3D arrow that points to the runway (or points in the direction
of the aircraft-to-runway vector).
2004-11-19 18:31:02 +00:00
|
|
|
}
|
|
|
|
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
int readInstrument(const SGPropertyNode * node)
|
|
|
|
{
|
2002-03-26 02:38:11 +00:00
|
|
|
static const SGPropertyNode *startup_units_node
|
|
|
|
= fgGetNode("/sim/startup/units");
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
instr_item *HIptr;
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2002-03-26 02:38:11 +00:00
|
|
|
if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
|
2001-06-06 17:43:16 +00:00
|
|
|
strcpy(units, " ft");
|
2001-01-05 16:44:48 +00:00
|
|
|
} else {
|
2001-06-06 17:43:16 +00:00
|
|
|
strcpy(units, " m");
|
2001-01-05 16:44:48 +00:00
|
|
|
}
|
2000-01-10 21:06:39 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * ladder_group = node->getNode("ladders");
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
if (ladder_group != 0) {
|
|
|
|
int nLadders = ladder_group->nChildren();
|
|
|
|
for (int j = 0; j < nLadders; j++) {
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
HIptr = readLadder(ladder_group->getChild(j));
|
|
|
|
HUD_deque.insert( HUD_deque.begin(), HIptr);
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
}// for - ladders
|
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * card_group = node->getNode("cards");
|
|
|
|
if (card_group != 0) {
|
|
|
|
int nCards = card_group->nChildren();
|
|
|
|
for (int j = 0; j < nCards; j++) {
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
HIptr = readCard(card_group->getChild(j));
|
|
|
|
HUD_deque.insert( HUD_deque.begin(), HIptr);
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
}//for - cards
|
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * label_group = node->getNode("labels");
|
|
|
|
if (label_group != 0) {
|
|
|
|
int nLabels = label_group->nChildren();
|
|
|
|
for (int j = 0; j < nLabels; j++) {
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
HIptr = readLabel(label_group->getChild(j));
|
|
|
|
HUD_deque.insert( HUD_deque.begin(), HIptr);
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
}//for - labels
|
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * tbi_group = node->getNode("tbis");
|
|
|
|
if (tbi_group != 0) {
|
|
|
|
int nTbis = tbi_group->nChildren();
|
|
|
|
for (int j = 0; j < nTbis; j++) {
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
HIptr = readTBI(tbi_group->getChild(j));
|
|
|
|
HUD_deque.insert( HUD_deque.begin(), HIptr);
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
}//for - tbis
|
|
|
|
}
|
2006-06-09 21:29:40 +00:00
|
|
|
|
I have added Aaron Wilson's virtual 3d runway projection to the HUD.
Aaron says:
I just got the virtual runway hud projection working on all views and
2D & 3D HUDs. It is working awesome(see below). I have attached every
file that was modified (hud.hxx, hud.cxx, and the default.xml for the hud)
and every file that was added (hud_rwy.cxx and runwayinstr.xml).
Just a quick overview of how the instrument works.
The virtual runway is projected by getting the "cockpit view" of the
runway in 3D and projecting the points on to the 2D HUD. Therefore, the
virtual runway will be displayed the same in every view. For example,
you can land an aircraft from the "Tower View" by flying the HUD. Also
if you're in "Cockpit View" and it is centered then the virtual runway
lines will perfectly outline the actual runway. I am getting the active
runway via the wind like done in the ATC classes, which may need changed.
Also, I made the assumption the view 0, in view manager, is always the
cockpit view, which may need changed as well.
The runway configuration file will allow you to specify a center offset
(x,y) and a bounding box (width,height). You can also configure the line
stipple pattern for the outside and the center line. For instance, if
you wanted a 0xFAFA pattern, then specify 64250 as the value. If you
want a solid line, you can specify -1 or 65535 (0xFFFF) and zero will
turn the line off. It also draws a runway indication arrow when the
runway is not in the HUD or it can be drawn all the time if arrow_always
is true. The arrow will point in the direction of the runway (2D) by
rotating around the center at a radius of arrow_radius. If you wish to
turn the arrow off, you must set the arrow_scale <=0. The arrow really
should be 3D arrow that points to the runway (or points in the direction
of the aircraft-to-runway vector).
2004-11-19 18:31:02 +00:00
|
|
|
const SGPropertyNode * rwy_group = node->getNode("runways");
|
|
|
|
if (rwy_group != 0) {
|
|
|
|
int nRwy = rwy_group->nChildren();
|
|
|
|
for (int j = 0; j < nRwy; j++) {
|
|
|
|
SG_LOG( SG_COCKPIT, SG_DEBUG,
|
|
|
|
"************** Reading runway properties" );
|
|
|
|
HIptr = readRunway(rwy_group->getChild(j));
|
|
|
|
HUD_deque.insert( HUD_deque.begin(), HIptr);
|
|
|
|
|
|
|
|
}//for - runways
|
2006-06-09 21:29:40 +00:00
|
|
|
}
|
2001-06-06 17:43:16 +00:00
|
|
|
return 0;
|
2001-01-05 16:44:48 +00:00
|
|
|
}//end readinstrument
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
int readHud( istream &input )
|
2001-01-05 16:44:48 +00:00
|
|
|
{
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SGPropertyNode root;
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-07-19 04:51:05 +00:00
|
|
|
try {
|
2001-09-20 22:10:45 +00:00
|
|
|
readProperties(input, &root);
|
2001-07-24 23:50:08 +00:00
|
|
|
} catch (const sg_exception &e) {
|
2001-09-20 22:10:45 +00:00
|
|
|
guiErrorMessage("Error reading HUD: ", e);
|
|
|
|
return 0;
|
2001-06-06 17:43:16 +00:00
|
|
|
}
|
2006-06-09 21:29:40 +00:00
|
|
|
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Read properties for " <<
|
|
|
|
root.getStringValue("name"));
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
|
2006-06-09 21:29:40 +00:00
|
|
|
HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Reading Hud instruments");
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * instrument_group = root.getChild("instruments");
|
|
|
|
int nInstruments = instrument_group->nChildren();
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
for (int i = 0; i < nInstruments; i++) {
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
const SGPropertyNode * node = instrument_group->getChild(i);
|
|
|
|
|
|
|
|
SGPath path( globals->get_fg_root() );
|
|
|
|
path.append(node->getStringValue("path"));
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SG_LOG(SG_INPUT, SG_INFO, "Reading Instrument "
|
|
|
|
<< node->getName()
|
|
|
|
<< " from "
|
|
|
|
<< path.str());
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SGPropertyNode root2;
|
2001-09-19 22:23:25 +00:00
|
|
|
try {
|
|
|
|
readProperties(path.str(), &root2);
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
guiErrorMessage("Error reading HUD instrument: ", e);
|
|
|
|
continue;
|
2006-06-09 21:29:40 +00:00
|
|
|
}
|
2001-09-19 22:23:25 +00:00
|
|
|
readInstrument(&root2);
|
2001-06-06 17:43:16 +00:00
|
|
|
}//for loop(i)
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
return 0;
|
2001-01-05 16:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
|
|
|
|
{
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
HUD_style = 1;
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
string hud_path =
|
2006-06-09 21:29:40 +00:00
|
|
|
fgGetString("/sim/hud/path", "Huds/Default/default.xml");
|
2001-06-06 17:43:16 +00:00
|
|
|
SGPath path(globals->get_fg_root());
|
|
|
|
path.append(hud_path);
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
ifstream input(path.c_str());
|
2001-09-20 22:10:45 +00:00
|
|
|
if (!input.good()) {
|
|
|
|
SG_LOG(SG_INPUT, SG_ALERT,
|
|
|
|
"Cannot read Hud configuration from " << path.str());
|
|
|
|
} else {
|
|
|
|
readHud(input);
|
|
|
|
input.close();
|
|
|
|
}
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
fgHUDReshape();
|
2001-01-05 16:44:48 +00:00
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
if ( HUDtext ) {
|
|
|
|
// this chunk of code is not necessarily thread safe if the
|
|
|
|
// compiler optimizer reorders these statements. Note that
|
|
|
|
// "delete ptr" does not set "ptr = NULL". We have to do that
|
|
|
|
// ourselves.
|
|
|
|
fntRenderer *tmp = HUDtext;
|
|
|
|
HUDtext = NULL;
|
|
|
|
delete tmp;
|
|
|
|
}
|
|
|
|
|
2006-06-06 15:34:18 +00:00
|
|
|
FGFontCache *fc = globals->get_fontcache();
|
|
|
|
HUD_Font = fc->getTexFont(fgGetString("/sim/hud/font/name", "Helvetica.txf"));
|
2006-06-06 19:25:33 +00:00
|
|
|
if (!HUD_Font)
|
|
|
|
throw sg_throwable(string("/sim/hud/font/name is not a texture font"));
|
|
|
|
|
2006-06-06 15:34:18 +00:00
|
|
|
HUD_TextSize = fgGetFloat("/sim/hud/font/size", 10);
|
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
HUDtext = new fntRenderer();
|
2006-06-06 15:34:18 +00:00
|
|
|
HUDtext->setFont(HUD_Font);
|
|
|
|
HUDtext->setPointSize(HUD_TextSize);
|
2003-03-21 15:02:23 +00:00
|
|
|
HUD_TextList.setFont( HUDtext );
|
2006-06-07 18:01:19 +00:00
|
|
|
|
2006-06-09 10:53:48 +00:00
|
|
|
if (!HUD)
|
|
|
|
HUD = new HUD_Properties;
|
2001-06-06 17:43:16 +00:00
|
|
|
return 0; // For now. Later we may use this for an error code.
|
1999-05-12 02:04:38 +00:00
|
|
|
|
1998-08-24 20:05:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
|
|
|
|
{
|
1998-10-16 00:53:00 +00:00
|
|
|
|
1999-06-01 21:17:10 +00:00
|
|
|
HUD_style = 2;
|
|
|
|
|
2001-03-24 06:03:11 +00:00
|
|
|
SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
|
1998-10-16 00:53:00 +00:00
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
SGPath path(globals->get_fg_root());
|
|
|
|
path.append("Huds/Minimal/default.xml");
|
2001-01-05 16:44:48 +00:00
|
|
|
|
|
|
|
|
2001-06-06 17:43:16 +00:00
|
|
|
ifstream input(path.c_str());
|
|
|
|
if (!input.good()) {
|
|
|
|
SG_LOG(SG_INPUT, SG_ALERT,
|
|
|
|
"Cannot read Hud configuration from " << path.str());
|
2001-09-20 22:10:45 +00:00
|
|
|
} else {
|
2001-06-06 17:43:16 +00:00
|
|
|
readHud(input);
|
|
|
|
input.close();
|
|
|
|
}
|
1998-10-16 00:53:00 +00:00
|
|
|
|
2006-06-09 10:53:48 +00:00
|
|
|
if (!HUD)
|
|
|
|
HUD = new HUD_Properties;
|
1998-10-16 00:53:00 +00:00
|
|
|
return 0; // For now. Later we may use this for an error code.
|
2001-01-05 16:44:48 +00:00
|
|
|
|
1997-08-29 18:03:19 +00:00
|
|
|
}
|
2006-06-09 21:29:40 +00:00
|
|
|
//$$$ End - added, Neetha, 28 Nov 2k
|
1997-08-29 18:03:19 +00:00
|
|
|
|
1999-06-30 20:21:04 +00:00
|
|
|
|
2000-05-13 00:02:43 +00:00
|
|
|
void fgHUDReshape(void) {
|
2003-03-21 15:02:23 +00:00
|
|
|
#if 0
|
2001-06-30 00:27:13 +00:00
|
|
|
if ( HUDtext ) {
|
2001-07-02 22:11:56 +00:00
|
|
|
// this chunk of code is not necessarily thread safe if the
|
|
|
|
// compiler optimizer reorders these statements. Note that
|
|
|
|
// "delete ptr" does not set "ptr = NULL". We have to do that
|
|
|
|
// ourselves.
|
|
|
|
fntRenderer *tmp = HUDtext;
|
2001-06-30 00:27:13 +00:00
|
|
|
HUDtext = NULL;
|
2001-07-02 22:11:56 +00:00
|
|
|
delete tmp;
|
2001-06-30 00:27:13 +00:00
|
|
|
}
|
2001-06-12 23:37:29 +00:00
|
|
|
|
|
|
|
HUD_TextSize = fgGetInt("/sim/startup/xsize") / 60;
|
|
|
|
HUD_TextSize = 10;
|
|
|
|
HUDtext = new fntRenderer();
|
|
|
|
HUDtext -> setFont ( guiFntHandle ) ;
|
|
|
|
HUDtext -> setPointSize ( HUD_TextSize ) ;
|
|
|
|
HUD_TextList.setFont( HUDtext );
|
2003-03-21 15:02:23 +00:00
|
|
|
#endif
|
2000-05-13 00:02:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-11 02:07:48 +00:00
|
|
|
// 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 ) {
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2003-07-14 13:57:11 +00:00
|
|
|
static const SGPropertyNode *enable3d_node = fgGetNode("/sim/hud/enable3d");
|
2006-06-14 10:30:10 +00:00
|
|
|
if ( HUD_style == 1 && enable3d_node->getBoolValue() ) {
|
2003-03-21 15:02:23 +00:00
|
|
|
fgUpdateHUDVirtual();
|
|
|
|
return;
|
|
|
|
}
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-06-26 18:23:07 +00:00
|
|
|
static const float normal_aspect = float(640) / float(480);
|
2001-10-24 20:28:28 +00:00
|
|
|
// note: aspect_ratio is Y/X
|
|
|
|
float current_aspect = 1.0f/globals->get_current_view()->get_aspect_ratio();
|
2006-06-14 10:30:10 +00:00
|
|
|
if ( current_aspect > normal_aspect ) {
|
2001-06-26 18:23:07 +00:00
|
|
|
float aspect_adjust = current_aspect / normal_aspect;
|
|
|
|
float adjust = 320.0f*aspect_adjust - 320.0f;
|
|
|
|
fgUpdateHUD( -adjust, 0.0f, 640.0f+adjust, 480.0f );
|
|
|
|
} else {
|
|
|
|
float aspect_adjust = normal_aspect / current_aspect;
|
|
|
|
float adjust = 240.0f*aspect_adjust - 240.0f;
|
|
|
|
fgUpdateHUD( 0.0f, -adjust, 640.0f, 480.0f+adjust );
|
|
|
|
}
|
2001-06-13 20:31:49 +00:00
|
|
|
}
|
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
void fgUpdateHUDVirtual()
|
2001-06-13 20:31:49 +00:00
|
|
|
{
|
2003-03-21 15:02:23 +00:00
|
|
|
FGViewer* view = globals->get_current_view();
|
1999-09-11 02:07:48 +00:00
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
// Standard fgfs projection, with essentially meaningless clip
|
|
|
|
// planes (we'll map the whole HUD plane to z=-1)
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
gluPerspective(view->get_v_fov(), 1/view->get_aspect_ratio(), 0.1, 10);
|
|
|
|
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
// Standard fgfs view direction computation
|
|
|
|
float lookat[3];
|
|
|
|
lookat[0] = -sin(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
|
|
|
|
lookat[1] = tan(SG_DEGREES_TO_RADIANS * view->getPitchOffset_deg());
|
|
|
|
lookat[2] = -cos(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
|
2006-06-14 10:30:10 +00:00
|
|
|
if (fabs(lookat[1]) > 9999)
|
|
|
|
lookat[1] = 9999; // FPU sanity
|
2003-03-21 15:02:23 +00:00
|
|
|
gluLookAt(0, 0, 0, lookat[0], lookat[1], lookat[2], 0, 1, 0);
|
|
|
|
|
|
|
|
// Map the -1:1 square to a 55.0x41.25 degree wide patch at z=1.
|
|
|
|
// This is the default fgfs field of view, which the HUD files are
|
|
|
|
// written to assume.
|
|
|
|
float dx = 0.52056705; // tan(55/2)
|
|
|
|
float dy = dx * 0.75; // assumes 4:3 aspect ratio
|
|
|
|
float m[16];
|
|
|
|
m[0] = dx; m[4] = 0; m[ 8] = 0; m[12] = 0;
|
|
|
|
m[1] = 0; m[5] = dy; m[ 9] = 0; m[13] = 0;
|
|
|
|
m[2] = 0; m[6] = 0; m[10] = 1; m[14] = 0;
|
|
|
|
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
|
|
|
|
glMultMatrixf(m);
|
|
|
|
|
|
|
|
// Convert the 640x480 "HUD standard" coordinate space to a square
|
|
|
|
// about the origin in the range [-1:1] at depth of -1
|
|
|
|
glScalef(1./320, 1./240, 1);
|
|
|
|
glTranslatef(-320, -240, -1);
|
|
|
|
|
|
|
|
// Do the deed
|
|
|
|
drawHUD();
|
|
|
|
|
|
|
|
// Clean up our mess
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
2001-09-20 22:10:45 +00:00
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
|
|
|
|
GLfloat x_end, GLfloat y_end )
|
|
|
|
{
|
2001-09-20 22:10:45 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
gluOrtho2D(x_start, x_end, y_start, y_end);
|
2003-03-21 15:02:23 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
|
2003-03-21 15:02:23 +00:00
|
|
|
drawHUD();
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
|
|
|
|
void drawHUD()
|
|
|
|
{
|
2006-06-14 10:30:10 +00:00
|
|
|
if ( !HUD_deque.size() ) // Trust everyone, but ALWAYS cut the cards!
|
2003-03-21 15:02:23 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
HUD_TextList.erase();
|
|
|
|
HUD_LineList.erase();
|
|
|
|
// HUD_StippleLineList.erase();
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
|
2004-01-31 19:47:45 +00:00
|
|
|
static const SGPropertyNode *heading_enabled
|
|
|
|
= fgGetNode("/autopilot/locks/heading", true);
|
|
|
|
static const SGPropertyNode *altitude_enabled
|
|
|
|
= fgGetNode("/autopilot/locks/altitude", true);
|
|
|
|
|
|
|
|
static char hud_hdg_text[256];
|
|
|
|
static char hud_wp0_text[256];
|
|
|
|
static char hud_wp1_text[256];
|
|
|
|
static char hud_wp2_text[256];
|
2004-02-05 23:49:18 +00:00
|
|
|
static char hud_alt_text[256];
|
2001-09-20 22:10:45 +00:00
|
|
|
|
2006-06-09 20:37:16 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
if (HUD->isTransparent())
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
|
|
else
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
if (HUD->isAntialiased()) {
|
2001-09-20 22:10:45 +00:00
|
|
|
glEnable(GL_LINE_SMOOTH);
|
2006-06-08 17:14:59 +00:00
|
|
|
glAlphaFunc(GL_GREATER, HUD->alphaClamp());
|
|
|
|
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
2006-06-10 15:25:48 +00:00
|
|
|
//glLineWidth(1.5);
|
2001-09-20 22:10:45 +00:00
|
|
|
} else {
|
2006-06-10 15:25:48 +00:00
|
|
|
//glLineWidth(1.0);
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
HUD->setColor();
|
2003-03-21 15:02:23 +00:00
|
|
|
for_each(HUD_deque.begin(), HUD_deque.end(), HUDdraw());
|
1999-09-11 02:07:48 +00:00
|
|
|
|
2006-06-09 20:37:16 +00:00
|
|
|
//HUD_TextList.add( fgText(40, 10, get_formated_gmt_time(), 0) );
|
1999-09-11 02:07:48 +00:00
|
|
|
|
2000-01-12 18:09:35 +00:00
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
int apY = 480 - 80;
|
2006-06-09 21:29:40 +00:00
|
|
|
|
|
|
|
|
2004-01-31 19:47:45 +00:00
|
|
|
if (strcmp( heading_enabled->getStringValue(), "dg-heading-hold") == 0 ) {
|
|
|
|
snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
|
|
|
|
fgGetDouble("/autopilot/settings/heading-bug-deg") );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
|
2001-09-20 22:10:45 +00:00
|
|
|
apY -= 15;
|
2004-01-31 19:47:45 +00:00
|
|
|
} else if ( strcmp(heading_enabled->getStringValue(), "true-heading-hold") == 0 ) {
|
|
|
|
snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
|
|
|
|
fgGetDouble("/autopilot/settings/true-heading-deg") );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
|
2001-09-20 22:10:45 +00:00
|
|
|
apY -= 15;
|
2004-01-31 19:47:45 +00:00
|
|
|
|
|
|
|
string wp0_id = fgGetString( "/autopilot/route-manager/wp[0]/id" );
|
|
|
|
if ( wp0_id.length() > 0 ) {
|
2006-06-09 21:29:40 +00:00
|
|
|
snprintf( hud_wp0_text, 256, "%5s %6.1fnm %s", wp0_id.c_str(),
|
2004-01-31 19:47:45 +00:00
|
|
|
fgGetDouble( "/autopilot/route-manager/wp[0]/dist" ),
|
|
|
|
fgGetString( "/autopilot/route-manager/wp[0]/eta" ) );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_wp0_text ) );
|
2001-09-20 22:10:45 +00:00
|
|
|
apY -= 15;
|
|
|
|
}
|
2004-01-31 19:47:45 +00:00
|
|
|
string wp1_id = fgGetString( "/autopilot/route-manager/wp[1]/id" );
|
|
|
|
if ( wp1_id.length() > 0 ) {
|
2006-06-09 21:29:40 +00:00
|
|
|
snprintf( hud_wp1_text, 256, "%5s %6.1fnm %s", wp1_id.c_str(),
|
2004-01-31 19:47:45 +00:00
|
|
|
fgGetDouble( "/autopilot/route-manager/wp[1]/dist" ),
|
|
|
|
fgGetString( "/autopilot/route-manager/wp[1]/eta" ) );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_wp1_text ) );
|
2001-09-20 22:10:45 +00:00
|
|
|
apY -= 15;
|
|
|
|
}
|
2004-01-31 19:47:45 +00:00
|
|
|
string wp2_id = fgGetString( "/autopilot/route-manager/wp-last/id" );
|
|
|
|
if ( wp2_id.length() > 0 ) {
|
2006-06-09 21:29:40 +00:00
|
|
|
snprintf( hud_wp2_text, 256, "%5s %6.1fnm %s", wp2_id.c_str(),
|
2004-01-31 19:47:45 +00:00
|
|
|
fgGetDouble( "/autopilot/route-manager/wp-last/dist" ),
|
|
|
|
fgGetString( "/autopilot/route-manager/wp-last/eta" ) );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_wp2_text ) );
|
|
|
|
apY -= 15;
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
|
|
|
}
|
2006-06-09 21:29:40 +00:00
|
|
|
|
2004-01-31 19:47:45 +00:00
|
|
|
if ( strcmp( altitude_enabled->getStringValue(), "altitude-hold" ) == 0 ) {
|
2004-02-05 23:49:18 +00:00
|
|
|
snprintf( hud_alt_text, 256, "alt = %.0f\n",
|
|
|
|
fgGetDouble("/autopilot/settings/target-altitude-ft") );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
|
|
|
|
apY -= 15;
|
|
|
|
} else if ( strcmp( altitude_enabled->getStringValue(), "agl-hold" ) == 0 ){
|
|
|
|
snprintf( hud_alt_text, 256, "agl = %.0f\n",
|
|
|
|
fgGetDouble("/autopilot/settings/target-agl-ft") );
|
|
|
|
HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
|
2004-01-31 19:47:45 +00:00
|
|
|
apY -= 15;
|
|
|
|
}
|
|
|
|
|
2001-09-20 22:10:45 +00:00
|
|
|
HUD_TextList.draw();
|
|
|
|
HUD_LineList.draw();
|
|
|
|
|
|
|
|
// glEnable(GL_LINE_STIPPLE);
|
|
|
|
// glLineStipple( 1, 0x00FF );
|
|
|
|
// HUD_StippleLineList.draw();
|
|
|
|
// glDisable(GL_LINE_STIPPLE);
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
if (HUD->isAntialiased()) {
|
2006-06-08 17:14:59 +00:00
|
|
|
glDisable(GL_ALPHA_TEST);
|
2001-09-20 22:10:45 +00:00
|
|
|
glDisable(GL_LINE_SMOOTH);
|
2006-06-10 15:25:48 +00:00
|
|
|
//glLineWidth(1.0);
|
2001-09-20 22:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_LIGHTING);
|
1999-09-11 02:07:48 +00:00
|
|
|
}
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
|
|
|
|
|
2006-06-08 17:14:59 +00:00
|
|
|
void fgTextList::draw()
|
|
|
|
{
|
|
|
|
if (!Font)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vector<fgText>::iterator curString = List.begin();
|
|
|
|
vector<fgText>::iterator lastString = List.end();
|
|
|
|
|
|
|
|
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
|
|
|
glEnable(GL_BLEND);
|
2006-06-09 20:37:16 +00:00
|
|
|
if (HUD->isTransparent())
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
|
|
else
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
2006-06-08 17:14:59 +00:00
|
|
|
if (HUD->isAntialiased()) {
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
glAlphaFunc(GL_GREATER, HUD->alphaClamp());
|
|
|
|
}
|
|
|
|
|
|
|
|
Font->begin();
|
|
|
|
for (; curString != lastString; curString++)
|
|
|
|
curString->Draw(Font,curString->digit);
|
|
|
|
Font->end();
|
|
|
|
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glPopAttrib();
|
|
|
|
}
|
|
|
|
|
2006-06-07 18:01:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
// HUD property listener class
|
|
|
|
//
|
2006-06-07 21:41:32 +00:00
|
|
|
HUD_Properties::HUD_Properties() :
|
2006-06-08 17:14:59 +00:00
|
|
|
_current(fgGetNode("/sim/hud/current-color", true)),
|
|
|
|
_visibility(fgGetNode("/sim/hud/visibility", true)),
|
|
|
|
_antialiasing(fgGetNode("/sim/hud/color/antialiased", true)),
|
2006-06-09 20:37:16 +00:00
|
|
|
_transparency(fgGetNode("/sim/hud/color/transparent", true)),
|
2006-06-08 17:14:59 +00:00
|
|
|
_red(fgGetNode("/sim/hud/color/red", true)),
|
|
|
|
_green(fgGetNode("/sim/hud/color/green", true)),
|
|
|
|
_blue(fgGetNode("/sim/hud/color/blue", true)),
|
|
|
|
_alpha(fgGetNode("/sim/hud/color/alpha", true)),
|
|
|
|
_alpha_clamp(fgGetNode("/sim/hud/color/alpha-clamp", true)),
|
2006-06-09 20:37:16 +00:00
|
|
|
_brightness(fgGetNode("/sim/hud/color/brightness", true)),
|
|
|
|
_visible(false),
|
|
|
|
_antialiased(false),
|
|
|
|
_transparent(false),
|
|
|
|
_a(0.67),
|
|
|
|
_cl(0.01)
|
2006-06-07 18:01:19 +00:00
|
|
|
{
|
|
|
|
_visibility->addChangeListener(this);
|
2006-06-08 17:14:59 +00:00
|
|
|
_antialiasing->addChangeListener(this);
|
2006-06-09 20:37:16 +00:00
|
|
|
_transparency->addChangeListener(this);
|
2006-06-08 17:14:59 +00:00
|
|
|
_red->addChangeListener(this);
|
|
|
|
_green->addChangeListener(this);
|
|
|
|
_blue->addChangeListener(this);
|
|
|
|
_alpha->addChangeListener(this);
|
|
|
|
_alpha_clamp->addChangeListener(this);
|
|
|
|
_brightness->addChangeListener(this);
|
|
|
|
_current->addChangeListener(this, true);
|
2006-06-07 18:01:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-08 17:14:59 +00:00
|
|
|
void HUD_Properties::valueChanged(SGPropertyNode *node)
|
2006-06-07 18:01:19 +00:00
|
|
|
{
|
2006-06-08 17:14:59 +00:00
|
|
|
if (!strcmp(node->getName(), "current-color")) {
|
|
|
|
int i = node->getIntValue();
|
|
|
|
if (i < 0)
|
|
|
|
i = 0;
|
|
|
|
SGPropertyNode *n = fgGetNode("/sim/hud/palette", true);
|
|
|
|
if ((n = n->getChild("color", i, false))) {
|
2006-06-10 09:22:27 +00:00
|
|
|
if (n->hasValue("red"))
|
|
|
|
_red->setFloatValue(n->getFloatValue("red", 1.0));
|
|
|
|
if (n->hasValue("green"))
|
|
|
|
_green->setFloatValue(n->getFloatValue("green", 1.0));
|
|
|
|
if (n->hasValue("blue"))
|
|
|
|
_blue->setFloatValue(n->getFloatValue("blue", 1.0));
|
2006-06-08 17:14:59 +00:00
|
|
|
if (n->hasValue("alpha"))
|
2006-06-09 20:37:16 +00:00
|
|
|
_alpha->setFloatValue(n->getFloatValue("alpha", 0.67));
|
2006-06-08 17:14:59 +00:00
|
|
|
if (n->hasValue("alpha-clamp"))
|
|
|
|
_alpha_clamp->setFloatValue(n->getFloatValue("alpha-clamp", 0.01));
|
|
|
|
if (n->hasValue("brightness"))
|
|
|
|
_brightness->setFloatValue(n->getFloatValue("brightness", 0.75));
|
2006-06-09 20:37:16 +00:00
|
|
|
if (n->hasValue("antialiased"))
|
|
|
|
_antialiasing->setBoolValue(n->getBoolValue("antialiased", false));
|
|
|
|
if (n->hasValue("transparent"))
|
|
|
|
_transparency->setBoolValue(n->getBoolValue("transparent", false));
|
2006-06-08 17:14:59 +00:00
|
|
|
}
|
|
|
|
}
|
2006-06-07 18:01:19 +00:00
|
|
|
_visible = _visibility->getBoolValue();
|
2006-06-09 20:37:16 +00:00
|
|
|
_transparent = _transparency->getBoolValue();
|
2006-06-07 18:01:19 +00:00
|
|
|
_antialiased = _antialiasing->getBoolValue();
|
|
|
|
float brt = _brightness->getFloatValue();
|
2006-06-08 17:14:59 +00:00
|
|
|
_r = clamp(brt * _red->getFloatValue());
|
|
|
|
_g = clamp(brt * _green->getFloatValue());
|
|
|
|
_b = clamp(brt * _blue->getFloatValue());
|
|
|
|
_a = clamp(_alpha->getFloatValue());
|
|
|
|
_cl = clamp(_alpha_clamp->getFloatValue());
|
2006-06-07 18:01:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void HUD_Properties::setColor() const
|
|
|
|
{
|
|
|
|
if (_antialiased)
|
|
|
|
glColor4f(_r, _g, _b, _a);
|
|
|
|
else
|
|
|
|
glColor3f(_r, _g, _b);
|
|
|
|
}
|
|
|
|
|