Panel updates from David Megginson. Radials can now be adjusted on the fly
by clicking on the knob on the instrument panel.
This commit is contained in:
parent
949fc00815
commit
418279fdd4
12 changed files with 594 additions and 119 deletions
|
@ -533,11 +533,7 @@ void fgCockpitUpdate( void ) {
|
|||
}
|
||||
#endif // #ifdef DISPLAY_COUNTER
|
||||
|
||||
if( current_options.get_panel_status() &&
|
||||
(fabs( current_view.get_view_offset() ) < 0.2) )
|
||||
{
|
||||
xglViewport( 0, 0, iwidth, iheight );
|
||||
xglViewport( 0, 0, iwidth, iheight );
|
||||
|
||||
FGPanel::OurPanel->Update();
|
||||
}
|
||||
current_panel.update();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
#include <Main/options.hxx>
|
||||
#include <Main/views.hxx>
|
||||
#include <Main/bfi.hxx>
|
||||
#include <Objects/texload.h>
|
||||
#include <Autopilot/autopilot.hxx>
|
||||
|
@ -80,12 +81,8 @@ static char * panelGetTime (char * buf)
|
|||
// they're hard-coded.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ssgTexture *
|
||||
createTexture (const char * relativePath)
|
||||
{
|
||||
return FGPanel::OurPanel->createTexture(relativePath);
|
||||
}
|
||||
|
||||
#define createTexture(a) FGTextureManager::createTexture(a)
|
||||
|
||||
/**
|
||||
* Construct an airspeed indicator for a single-engine prop.
|
||||
|
@ -221,6 +218,18 @@ createGyroCompass (int x, int y)
|
|||
{
|
||||
FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
|
||||
|
||||
// Action: move bug counter-clockwise
|
||||
inst->addAction(SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getAPHeading,
|
||||
FGBFI::setAPHeading,
|
||||
-1.0, 0.0, 360.0, true));
|
||||
|
||||
// Action: move bug clockwise
|
||||
inst->addAction(SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getAPHeading,
|
||||
FGBFI::setAPHeading,
|
||||
1.0, 0.0, 360.0, true));
|
||||
|
||||
// Layer 0: compass background
|
||||
// rotates with heading
|
||||
inst->addLayer(0, createTexture("Textures/Panel/gyro-bg.rgb"));
|
||||
|
@ -241,6 +250,15 @@ createGyroCompass (int x, int y)
|
|||
// Layer 2: fixed center
|
||||
inst->addLayer(2, createTexture("Textures/Panel/gyro-fg.rgb"));
|
||||
|
||||
// Layer 3: heading knob
|
||||
// rotates with AP heading
|
||||
inst->addLayer(3, createTexture("Textures/Panel/heading-knob.rgb"));
|
||||
inst->addTransformation(3, FGInstrumentLayer::XSHIFT, SIX_W/2 - 10);
|
||||
inst->addTransformation(3, FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
|
||||
inst->addTransformation(3, FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getAPHeading,
|
||||
-360.0, 360.0, 1.0, 0.0);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
@ -389,49 +407,100 @@ createNAV1 (int x, int y)
|
|||
{
|
||||
FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
|
||||
|
||||
// Action: increase selected radial
|
||||
inst->addAction(SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getNAV1SelRadial,
|
||||
FGBFI::setNAV1SelRadial,
|
||||
1.0, 0.0, 360.0, true));
|
||||
|
||||
// Action: decrease selected radial
|
||||
inst->addAction(SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getNAV1SelRadial,
|
||||
FGBFI::setNAV1SelRadial,
|
||||
-1.0, 0.0, 360.0, true));
|
||||
|
||||
// Layer 0: background
|
||||
inst->addLayer(0, createTexture("Textures/Panel/gyro-bg.rgb"));
|
||||
inst->addTransformation(0, FGInstrumentLayer::ROTATION,
|
||||
FGSteam::get_HackOBS1_deg,
|
||||
FGBFI::getNAV1SelRadial,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
// Layer 1: long needle
|
||||
|
||||
// Layer 1: left-right needle.
|
||||
inst->addLayer(1, createTexture("Textures/Panel/nav-needle.rgb"));
|
||||
inst->addTransformation(1, FGInstrumentLayer::XSHIFT,
|
||||
FGSteam::get_HackVOR1_deg,
|
||||
-10.0, 10.0, SIX_W / 40.0, 0.0);
|
||||
|
||||
// Layer 2: glidescope needle
|
||||
inst->addLayer(2, createTexture("Textures/Panel/nav-needle.rgb"));
|
||||
inst->addTransformation(2, FGInstrumentLayer::YSHIFT,
|
||||
FGSteam::get_HackGS_deg,
|
||||
-1.0, 1.0, SIX_W / 5.0, 0.0);
|
||||
inst->addTransformation(2, FGInstrumentLayer::ROTATION,
|
||||
90 );
|
||||
|
||||
// Layer 3: face with markings
|
||||
inst->addLayer(3, createTexture("Textures/Panel/nav-face.rgb"));
|
||||
|
||||
// Layer 4: heading knob
|
||||
// rotates with selected radial
|
||||
inst->addLayer(4, createTexture("Textures/Panel/heading-knob.rgb"));
|
||||
inst->addTransformation(4, FGInstrumentLayer::XSHIFT, SIX_W/2 - 10);
|
||||
inst->addTransformation(4, FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
|
||||
inst->addTransformation(4, FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getNAV1SelRadial,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a NAV2 gauge (hardwired).
|
||||
* Construct a NAV2 gauge.
|
||||
*/
|
||||
static FGPanelInstrument *
|
||||
createNAV2 (int x, int y)
|
||||
{
|
||||
FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
|
||||
|
||||
// Action: increase selected radial
|
||||
inst->addAction(SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getNAV2SelRadial,
|
||||
FGBFI::setNAV2SelRadial,
|
||||
1.0, 0.0, 360.0, true));
|
||||
|
||||
// Action: decrease selected radial
|
||||
inst->addAction(SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getNAV2SelRadial,
|
||||
FGBFI::setNAV2SelRadial,
|
||||
-1.0, 0.0, 360.0, true));
|
||||
|
||||
// Layer 0: background
|
||||
inst->addLayer(0, createTexture("Textures/Panel/gyro-bg.rgb"));
|
||||
inst->addTransformation(0, FGInstrumentLayer::ROTATION,
|
||||
FGSteam::get_HackOBS2_deg,
|
||||
FGBFI::getNAV2SelRadial,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
|
||||
// Layer 1: left-right needle.
|
||||
inst->addLayer(1, createTexture("Textures/Panel/nav-needle.rgb"));
|
||||
inst->addTransformation(1, FGInstrumentLayer::XSHIFT,
|
||||
FGSteam::get_HackVOR2_deg,
|
||||
-10.0, 10.0, SIX_W / 40.0, 0.0);
|
||||
// inst->addTransformation(1, FGInstrumentLayer::YSHIFT,
|
||||
// -SIX_W / 4.4 );
|
||||
|
||||
// Layer 2: face with markings.
|
||||
inst->addLayer(2, createTexture("Textures/Panel/nav-face.rgb"));
|
||||
|
||||
// Layer 3: heading knob
|
||||
// rotates with selected radial
|
||||
inst->addLayer(3, createTexture("Textures/Panel/heading-knob.rgb"));
|
||||
inst->addTransformation(3, FGInstrumentLayer::XSHIFT, SIX_W/2 - 10);
|
||||
inst->addTransformation(3, FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
|
||||
inst->addTransformation(3, FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getNAV2SelRadial,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
@ -444,80 +513,83 @@ createADF (int x, int y)
|
|||
{
|
||||
FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
|
||||
|
||||
// Action: increase selected rotation
|
||||
inst->addAction(SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getADFRotation,
|
||||
FGBFI::setADFRotation,
|
||||
1.0, 0.0, 360.0, true));
|
||||
|
||||
// Action: decrease selected rotation
|
||||
inst->addAction(SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
|
||||
new FGAdjustAction(FGBFI::getADFRotation,
|
||||
FGBFI::setADFRotation,
|
||||
-1.0, 0.0, 360.0, true));
|
||||
|
||||
// Layer 0: background
|
||||
inst->addLayer(0, createTexture("Textures/Panel/gyro-bg.rgb"));
|
||||
inst->addTransformation(0, FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getADFRotation,
|
||||
0.0, 360.0, 1.0, 0.0);
|
||||
|
||||
// Layer 1: Direction needle.
|
||||
inst->addLayer(1, createTexture("Textures/Panel/long-needle.rgb"));
|
||||
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
|
||||
FGSteam::get_HackADF_deg,
|
||||
-720.0, 720.0, 1.0, 0.0);
|
||||
|
||||
// Layer 2: heading knob
|
||||
// rotates with selected radial
|
||||
inst->addLayer(2, createTexture("Textures/Panel/heading-knob.rgb"));
|
||||
inst->addTransformation(2, FGInstrumentLayer::XSHIFT, SIX_W/2 - 10);
|
||||
inst->addTransformation(2, FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
|
||||
inst->addTransformation(2, FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getADFRotation,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGTextureManager.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
map<const char *,ssgTexture *> FGTextureManager::_textureMap;
|
||||
|
||||
ssgTexture *
|
||||
FGTextureManager::createTexture (const char * relativePath)
|
||||
{
|
||||
ssgTexture *texture;
|
||||
|
||||
texture = _textureMap[relativePath];
|
||||
if (texture == 0) {
|
||||
FGPath tpath(current_options.get_fg_root());
|
||||
tpath.append(relativePath);
|
||||
texture = new ssgTexture((char *)tpath.c_str(), false, false);
|
||||
_textureMap[relativePath] = texture;
|
||||
cerr << "Created texture " << relativePath
|
||||
<< " handle=" << texture->getHandle() << endl;
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGPanel.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGPanel * FGPanel::OurPanel = 0;
|
||||
FGPanel current_panel;
|
||||
|
||||
FGPanel::FGPanel ()
|
||||
: _initialized(false),
|
||||
_visibility(false)
|
||||
{
|
||||
if (OurPanel == 0) {
|
||||
OurPanel = this;
|
||||
} else {
|
||||
FG_LOG(FG_GENERAL, FG_ALERT, "Multiple panels");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int x = SIX_X;
|
||||
int y = SIX_Y;
|
||||
|
||||
_bg = createTexture("Textures/Panel/panel-bg.rgb");
|
||||
|
||||
// Chronometer alone at side
|
||||
x = SIX_X - SIX_SPACING - 8;
|
||||
_instruments.push_back(createChronometer(x, y));
|
||||
|
||||
// Top row
|
||||
x = SIX_X;
|
||||
_instruments.push_back(createAirspeedIndicator(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createHorizon(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createAltimeter(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
_instruments.push_back(createNAV1(x, y));
|
||||
|
||||
// Middle row
|
||||
x = SIX_X;
|
||||
y -= SIX_SPACING;
|
||||
_instruments.push_back(createTurnCoordinator(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createGyroCompass(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createVerticalVelocity(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
_instruments.push_back(createNAV2(x, y));
|
||||
|
||||
// Bottom row
|
||||
x = SIX_X;
|
||||
y -= SIX_SPACING + 10;
|
||||
_instruments.push_back(createControls(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createFlapIndicator(x, y));
|
||||
x += SIX_SPACING;
|
||||
_instruments.push_back(createRPMGauge(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
y += 10;
|
||||
_instruments.push_back(createADF(x, y));
|
||||
}
|
||||
|
||||
FGPanel::~FGPanel ()
|
||||
{
|
||||
OurPanel = 0;
|
||||
|
||||
instrument_list_type::iterator current = _instruments.begin();
|
||||
instrument_list_type::iterator last = _instruments.end();
|
||||
|
||||
|
@ -527,25 +599,76 @@ FGPanel::~FGPanel ()
|
|||
}
|
||||
}
|
||||
|
||||
float
|
||||
FGPanel::get_height () const
|
||||
void
|
||||
FGPanel::addInstrument (FGPanelInstrument * instrument)
|
||||
{
|
||||
return _panel_h;
|
||||
_instruments.push_back(instrument);
|
||||
}
|
||||
|
||||
void
|
||||
FGPanel::ReInit (int x, int y, int finx, int finy)
|
||||
FGPanel::init (int x, int y, int finx, int finy)
|
||||
{
|
||||
_x = x;
|
||||
_y = y;
|
||||
_w = finx - x;
|
||||
_h = finy - y;
|
||||
_panel_h = (int)((finy - y) * 0.5768 + 1);
|
||||
|
||||
// Don't reconstruct all of the
|
||||
// instruments.
|
||||
if (_initialized)
|
||||
return;
|
||||
|
||||
x = SIX_X;
|
||||
y = SIX_Y;
|
||||
|
||||
_bg = createTexture("Textures/Panel/panel-bg.rgb");
|
||||
|
||||
// Chronometer alone at side
|
||||
x = SIX_X - SIX_SPACING - 8;
|
||||
addInstrument(createChronometer(x, y));
|
||||
|
||||
// Top row
|
||||
x = SIX_X;
|
||||
addInstrument(createAirspeedIndicator(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createHorizon(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createAltimeter(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
addInstrument(createNAV1(x, y));
|
||||
|
||||
// Middle row
|
||||
x = SIX_X;
|
||||
y -= SIX_SPACING;
|
||||
addInstrument(createTurnCoordinator(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createGyroCompass(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createVerticalVelocity(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
addInstrument(createNAV2(x, y));
|
||||
|
||||
// Bottom row
|
||||
x = SIX_X;
|
||||
y -= SIX_SPACING + 10;
|
||||
addInstrument(createControls(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createFlapIndicator(x, y));
|
||||
x += SIX_SPACING;
|
||||
addInstrument(createRPMGauge(x, y));
|
||||
x += SIX_SPACING + 20;
|
||||
y += 10;
|
||||
addInstrument(createADF(x, y));
|
||||
}
|
||||
|
||||
void
|
||||
FGPanel::Update () const
|
||||
FGPanel::update () const
|
||||
{
|
||||
// Do nothing if the panel isn't visible.
|
||||
if (!_visibility)
|
||||
return;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
@ -592,22 +715,74 @@ FGPanel::Update () const
|
|||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
}
|
||||
|
||||
ssgTexture *
|
||||
FGPanel::createTexture (const char * relativePath)
|
||||
void
|
||||
FGPanel::setVisibility (bool visibility)
|
||||
{
|
||||
ssgTexture *texture;
|
||||
_visibility = visibility;
|
||||
}
|
||||
|
||||
texture = _textureMap[relativePath];
|
||||
if (texture == 0) {
|
||||
FGPath tpath(current_options.get_fg_root());
|
||||
tpath.append(relativePath);
|
||||
texture = new ssgTexture((char *)tpath.c_str(), false, false);
|
||||
_textureMap[relativePath] = texture;
|
||||
cerr << "Created texture " << relativePath
|
||||
<< " handle=" << texture->getHandle() << endl;
|
||||
bool
|
||||
FGPanel::getVisibility () const
|
||||
{
|
||||
return _visibility;
|
||||
}
|
||||
|
||||
bool
|
||||
FGPanel::doMouseAction (int button, int updown, int x, int y)
|
||||
{
|
||||
// For now, ignore the release
|
||||
if (updown == 1)
|
||||
return true;
|
||||
|
||||
x = (int)(((float)x / current_view.get_winWidth()) * _w);
|
||||
y = (int)(_h - (((float)y / current_view.get_winHeight()) * _h));
|
||||
|
||||
for (int i = 0; i < _instruments.size(); i++) {
|
||||
FGPanelInstrument *inst = _instruments[i];
|
||||
int ix = inst->getXPos();
|
||||
int iy = inst->getYPos();
|
||||
int iw = inst->getWidth() / 2;
|
||||
int ih = inst->getHeight() / 2;
|
||||
if (x >= ix - iw && x < ix + iw && y >= iy - ih && y < iy + ih) {
|
||||
cout << "Do mouse action for component " << i << '\n';
|
||||
return inst->doMouseAction(button, updown, x - ix, y - iy);
|
||||
}
|
||||
}
|
||||
cout << "Did not click on an instrument\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGAdjustAction.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGAdjustAction::FGAdjustAction (getter_type getter, setter_type setter,
|
||||
double increment, double min, double max,
|
||||
bool wrap=false)
|
||||
: _getter(getter), _setter(setter), _increment(increment),
|
||||
_min(min), _max(max), _wrap(wrap)
|
||||
{
|
||||
}
|
||||
|
||||
FGAdjustAction::~FGAdjustAction ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FGAdjustAction::doAction ()
|
||||
{
|
||||
double value = (*_getter)();
|
||||
cout << "Do action; value=" << value << '\n';
|
||||
value += _increment;
|
||||
if (value < _min) {
|
||||
value = (_wrap ? _max : _min);
|
||||
} else if (value > _max) {
|
||||
value = (_wrap ? _min : _max);
|
||||
}
|
||||
cout << "New value is " << value << '\n';
|
||||
(*_setter)(value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -631,6 +806,11 @@ FGPanelInstrument::FGPanelInstrument (int x, int y, int w, int h)
|
|||
|
||||
FGPanelInstrument::~FGPanelInstrument ()
|
||||
{
|
||||
action_list_type::iterator it = _actions.begin();
|
||||
action_list_type::iterator last = _actions.end();
|
||||
for ( ; it != last; it++) {
|
||||
delete it->action;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -659,6 +839,49 @@ FGPanelInstrument::getYPos () const
|
|||
return _y;
|
||||
}
|
||||
|
||||
int
|
||||
FGPanelInstrument::getWidth () const
|
||||
{
|
||||
return _w;
|
||||
}
|
||||
|
||||
int
|
||||
FGPanelInstrument::getHeight () const
|
||||
{
|
||||
return _h;
|
||||
}
|
||||
|
||||
void
|
||||
FGPanelInstrument::addAction (int x, int y, int w, int h,
|
||||
FGPanelAction * action)
|
||||
{
|
||||
FGPanelInstrument::inst_action act;
|
||||
act.x = x;
|
||||
act.y = y;
|
||||
act.w = w;
|
||||
act.h = h;
|
||||
act.action = action;
|
||||
_actions.push_back(act);
|
||||
}
|
||||
|
||||
// Coordinates relative to centre.
|
||||
bool
|
||||
FGPanelInstrument::doMouseAction (int button, int updown, int x, int y)
|
||||
{
|
||||
action_list_type::iterator it = _actions.begin();
|
||||
action_list_type::iterator last = _actions.end();
|
||||
cout << "Mouse action at " << x << ',' << y << '\n';
|
||||
for ( ; it != last; it++) {
|
||||
cout << "Trying action at " << it->x << ',' << it->y << ','
|
||||
<< it->w <<',' << it->h << '\n';
|
||||
if (x >= it->x && x < it->x + it->w && y >= it->y && y < it->y + it->h) {
|
||||
it->action->doAction();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -46,6 +46,20 @@ FG_USING_STD(map);
|
|||
|
||||
class FGPanelInstrument;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Texture manager (should migrate out into FGFS).
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FGTextureManager
|
||||
{
|
||||
public:
|
||||
static ssgTexture * createTexture(const char * relativePath);
|
||||
private:
|
||||
static map<const char *,ssgTexture *>_textureMap;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Instrument panel class.
|
||||
|
@ -58,31 +72,65 @@ public:
|
|||
FGPanel ();
|
||||
virtual ~FGPanel ();
|
||||
|
||||
virtual ssgTexture * createTexture (const char * relativePath);
|
||||
// transfer pointer ownership!!!
|
||||
virtual void addInstrument (FGPanelInstrument * instrument);
|
||||
virtual void init (int x, int y, int finx, int finy);
|
||||
virtual void update () const;
|
||||
|
||||
virtual bool getVisibility () const;
|
||||
virtual void setVisibility (bool visibility);
|
||||
|
||||
// Legacy interface from old panel.
|
||||
static FGPanel * OurPanel;
|
||||
virtual float get_height () const;
|
||||
virtual void ReInit (int x, int y, int finx, int finy);
|
||||
virtual void Update () const;
|
||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||
|
||||
private:
|
||||
|
||||
bool _initialized;
|
||||
bool _visibility;
|
||||
typedef vector<FGPanelInstrument *> instrument_list_type;
|
||||
|
||||
int _x, _y, _w, _h;
|
||||
int _panel_h;
|
||||
|
||||
ssgTexture * _bg;
|
||||
|
||||
// Internalization table.
|
||||
map<const char *,ssgTexture *> _textureMap;
|
||||
|
||||
// List of instruments in panel.
|
||||
instrument_list_type _instruments;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Base class for user action types.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FGPanelAction
|
||||
{
|
||||
public:
|
||||
virtual void doAction () = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Adjustment action.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FGAdjustAction : public FGPanelAction
|
||||
{
|
||||
public:
|
||||
typedef double (*getter_type)();
|
||||
typedef void (*setter_type)(double);
|
||||
|
||||
FGAdjustAction (getter_type getter, setter_type setter, double increment,
|
||||
double min, double max, bool wrap=false);
|
||||
virtual ~FGAdjustAction ();
|
||||
virtual void doAction ();
|
||||
private:
|
||||
getter_type _getter;
|
||||
setter_type _setter;
|
||||
double _increment;
|
||||
double _min;
|
||||
double _max;
|
||||
bool _wrap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Instrument base class.
|
||||
|
@ -102,9 +150,28 @@ public:
|
|||
|
||||
virtual int getXPos () const;
|
||||
virtual int getYPos () const;
|
||||
virtual int getWidth () const;
|
||||
virtual int getHeight () const;
|
||||
|
||||
// Coordinates relative to centre.
|
||||
// Transfer pointer ownership!!
|
||||
virtual void addAction (int x, int y, int w, int h,
|
||||
FGPanelAction * action);
|
||||
|
||||
// Coordinates relative to centre.
|
||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||
|
||||
protected:
|
||||
int _x, _y, _w, _h;
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
FGPanelAction * action;
|
||||
} inst_action;
|
||||
typedef vector<inst_action> action_list_type;
|
||||
action_list_type _actions;
|
||||
};
|
||||
|
||||
|
||||
|
@ -180,6 +247,7 @@ public:
|
|||
|
||||
virtual void draw () const;
|
||||
|
||||
// Transfer pointer ownership!!
|
||||
virtual void addLayer (FGInstrumentLayer *layer);
|
||||
virtual void addLayer (int i, ssgTexture * texture);
|
||||
virtual void addTransformation (int layer,
|
||||
|
@ -253,6 +321,14 @@ private:
|
|||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// The current panel, if any.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern FGPanel current_panel;
|
||||
|
||||
|
||||
|
||||
#endif // __PANEL_HXX
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ FGRadioStack::~FGRadioStack() {
|
|||
void FGRadioStack::update( double lon, double lat, double elev ) {
|
||||
need_update = false;
|
||||
|
||||
// Start with the selected radials.
|
||||
nav1_radial = nav1_selected_radial;
|
||||
nav2_radial = nav2_selected_radial;
|
||||
|
||||
// nav1
|
||||
FGILS ils;
|
||||
if ( current_ilslist->query( lon, lat, elev, nav1_freq,
|
||||
|
|
|
@ -35,6 +35,8 @@ class FGRadioStack {
|
|||
bool nav1_inrange;
|
||||
bool nav1_loc;
|
||||
double nav1_freq;
|
||||
double nav1_alt_freq;
|
||||
double nav1_selected_radial;
|
||||
double nav1_radial;
|
||||
double nav1_lon;
|
||||
double nav1_lat;
|
||||
|
@ -46,6 +48,8 @@ class FGRadioStack {
|
|||
bool nav2_inrange;
|
||||
bool nav2_loc;
|
||||
double nav2_freq;
|
||||
double nav2_alt_freq;
|
||||
double nav2_selected_radial;
|
||||
double nav2_radial;
|
||||
double nav2_lon;
|
||||
double nav2_lat;
|
||||
|
@ -56,6 +60,8 @@ class FGRadioStack {
|
|||
|
||||
bool adf_inrange;
|
||||
double adf_freq;
|
||||
double adf_alt_freq;
|
||||
double adf_rotation;
|
||||
double adf_lon;
|
||||
double adf_lat;
|
||||
double adf_elev;
|
||||
|
@ -69,25 +75,48 @@ public:
|
|||
// Update nav/adf radios based on current postition
|
||||
void update( double lon, double lat, double elev );
|
||||
|
||||
// NAV1 Setters
|
||||
inline void set_nav1_freq( double freq ) {
|
||||
nav1_freq = freq; need_update = true;
|
||||
}
|
||||
inline void set_nav1_radial( double radial ) {
|
||||
nav1_radial = radial; need_update = true;
|
||||
inline void set_nav1_alt_freq( double freq ) { nav1_alt_freq = freq; }
|
||||
inline void set_nav1_sel_radial( double radial ) {
|
||||
nav1_selected_radial = radial; need_update = true;
|
||||
}
|
||||
|
||||
// NAV2 Setters
|
||||
inline void set_nav2_freq( double freq ) {
|
||||
nav2_freq = freq; need_update = true;
|
||||
}
|
||||
|
||||
inline void set_nav2_radial( double radial ) {
|
||||
nav2_radial = radial; need_update = true;
|
||||
inline void set_nav2_alt_freq( double freq ) { nav2_alt_freq = freq; }
|
||||
inline void set_nav2_sel_radial( double radial ) {
|
||||
nav2_selected_radial = radial; need_update = true;
|
||||
}
|
||||
|
||||
// ADF Setters
|
||||
inline void set_adf_freq( double freq ) {
|
||||
adf_freq = freq; need_update = true;
|
||||
}
|
||||
inline void set_adf_alt_freq( double freq ) { adf_alt_freq = freq; }
|
||||
inline void set_adf_rotation( double rot ) { adf_rotation = rot; }
|
||||
|
||||
|
||||
// NAV1 Accessors
|
||||
inline double get_nav1_freq () { return nav1_freq; }
|
||||
inline double get_nav1_alt_freq () { return nav1_alt_freq; }
|
||||
inline double get_nav1_sel_radial () { return nav1_selected_radial; }
|
||||
|
||||
// NAV2 Accessors
|
||||
inline double get_nav2_freq () { return nav2_freq; }
|
||||
inline double get_nav2_alt_freq () { return nav2_alt_freq; }
|
||||
inline double get_nav2_sel_radial () { return nav2_selected_radial; }
|
||||
|
||||
// ADF Accessors
|
||||
inline double get_adf_freq () { return adf_freq; }
|
||||
inline double get_adf_alt_freq () { return adf_alt_freq; }
|
||||
inline double get_adf_rotation () { return adf_rotation; }
|
||||
|
||||
// Calculated values.
|
||||
inline bool get_nav1_inrange() const { return nav1_inrange; }
|
||||
inline bool get_nav1_loc() const { return nav1_loc; }
|
||||
inline double get_nav1_radial() const { return nav1_radial; }
|
||||
|
|
|
@ -641,7 +641,9 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
// If we're in pointer mode, let PUI
|
||||
// know what's going on.
|
||||
if (mouse_mode == MOUSE_POINTER) {
|
||||
puMouse (button, updown, x,y);
|
||||
if (!puMouse (button, updown, x,y)) {
|
||||
current_panel.doMouseAction(button, updown, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
// Register the new position (if it
|
||||
|
@ -680,11 +682,6 @@ void guiFixPanel( void )
|
|||
if( (toggle_pause = !t->getPause()) )
|
||||
t->togglePauseMode();
|
||||
|
||||
// this seems to be the only way to do this :-(
|
||||
// problem is the viewport has been mucked with
|
||||
xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) );
|
||||
FGPanel::OurPanel->ReInit(0, 0, 1024, 768);
|
||||
|
||||
if(toggle_pause)
|
||||
t->togglePauseMode();
|
||||
}
|
||||
|
|
127
src/Main/bfi.cxx
127
src/Main/bfi.cxx
|
@ -39,6 +39,7 @@
|
|||
#include <Autopilot/autopilot.hxx>
|
||||
#include <Time/fg_time.hxx>
|
||||
#include <Time/light.hxx>
|
||||
#include <Cockpit/radiostack.hxx>
|
||||
#ifndef FG_OLD_WEATHER
|
||||
# include <WeatherCM/FGLocalWeatherDatabase.h>
|
||||
#else
|
||||
|
@ -731,6 +732,132 @@ FGBFI::setAPHeading (double heading)
|
|||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Radio navigation.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double
|
||||
FGBFI::getNAV1Freq ()
|
||||
{
|
||||
return current_radiostack->get_nav1_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV1AltFreq ()
|
||||
{
|
||||
return current_radiostack->get_nav1_alt_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV1SelRadial ()
|
||||
{
|
||||
return current_radiostack->get_nav1_sel_radial();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV1Radial ()
|
||||
{
|
||||
return current_radiostack->get_nav1_radial();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV2Freq ()
|
||||
{
|
||||
return current_radiostack->get_nav2_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV2AltFreq ()
|
||||
{
|
||||
return current_radiostack->get_nav2_alt_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV2SelRadial ()
|
||||
{
|
||||
return current_radiostack->get_nav2_sel_radial();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getNAV2Radial ()
|
||||
{
|
||||
return current_radiostack->get_nav2_radial();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getADFFreq ()
|
||||
{
|
||||
return current_radiostack->get_adf_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getADFAltFreq ()
|
||||
{
|
||||
return current_radiostack->get_adf_alt_freq();
|
||||
}
|
||||
|
||||
double
|
||||
FGBFI::getADFRotation ()
|
||||
{
|
||||
return current_radiostack->get_adf_rotation();
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV1Freq (double freq)
|
||||
{
|
||||
current_radiostack->set_nav1_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV1AltFreq (double freq)
|
||||
{
|
||||
current_radiostack->set_nav1_alt_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV1SelRadial (double radial)
|
||||
{
|
||||
current_radiostack->set_nav1_sel_radial(radial);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV2Freq (double freq)
|
||||
{
|
||||
current_radiostack->set_nav2_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV2AltFreq (double freq)
|
||||
{
|
||||
current_radiostack->set_nav2_alt_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setNAV2SelRadial (double radial)
|
||||
{
|
||||
current_radiostack->set_nav2_sel_radial(radial);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setADFFreq (double freq)
|
||||
{
|
||||
current_radiostack->set_adf_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setADFAltFreq (double freq)
|
||||
{
|
||||
current_radiostack->set_adf_alt_freq(freq);
|
||||
}
|
||||
|
||||
void
|
||||
FGBFI::setADFRotation (double rot)
|
||||
{
|
||||
current_radiostack->set_adf_rotation(rot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// GPS
|
||||
|
|
|
@ -123,6 +123,32 @@ public:
|
|||
static void setAPHeadingLock (bool lock);
|
||||
static void setAPHeading (double heading);
|
||||
|
||||
// Radio Navigation
|
||||
static double getNAV1Freq ();
|
||||
static double getNAV1AltFreq ();
|
||||
static double getNAV1SelRadial ();
|
||||
static double getNAV1Radial ();
|
||||
|
||||
static double getNAV2Freq ();
|
||||
static double getNAV2AltFreq ();
|
||||
static double getNAV2SelRadial ();
|
||||
static double getNAV2Radial ();
|
||||
|
||||
static double getADFFreq ();
|
||||
static double getADFAltFreq ();
|
||||
static double getADFRotation ();
|
||||
|
||||
static void setNAV1Freq (double freq);
|
||||
static void setNAV1AltFreq (double freq);
|
||||
static void setNAV1SelRadial (double radial);
|
||||
|
||||
static void setNAV2Freq (double freq);
|
||||
static void setNAV2AltFreq (double freq);
|
||||
static void setNAV2SelRadial (double radial);
|
||||
|
||||
static void setADFFreq (double freq);
|
||||
static void setADFAltFreq (double freq);
|
||||
static void setADFRotation (double rot);
|
||||
|
||||
// GPS
|
||||
static const string getTargetAirport ();
|
||||
|
|
|
@ -476,10 +476,10 @@ bool fgInitSubsystems( void ) {
|
|||
current_radiostack = new FGRadioStack;
|
||||
|
||||
current_radiostack->set_nav1_freq( 110.30 );
|
||||
current_radiostack->set_nav1_radial( 299.0 );
|
||||
current_radiostack->set_nav1_sel_radial( 299.0 );
|
||||
|
||||
current_radiostack->set_nav2_freq( 115.70 );
|
||||
current_radiostack->set_nav2_radial( 45.0 );
|
||||
current_radiostack->set_nav2_sel_radial( 45.0 );
|
||||
|
||||
current_radiostack->set_adf_freq( 266.0 );
|
||||
|
||||
|
@ -495,6 +495,9 @@ bool fgInitSubsystems( void ) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
// Initialize the 2D panel.
|
||||
current_panel.init(0, 0, 1024, 768);
|
||||
|
||||
// Initialize the flight model subsystem data structures base on
|
||||
// above values
|
||||
|
||||
|
|
|
@ -1168,9 +1168,6 @@ void fgReshape( int width, int height ) {
|
|||
// the main loop, so this will now work without seg faulting
|
||||
// the system.
|
||||
current_view.UpdateViewParams(cur_view_fdm);
|
||||
if ( current_options.get_panel_status() ) {
|
||||
FGPanel::OurPanel->ReInit(0, 0, 1024, 768);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -236,12 +236,12 @@ fgOPTIONS::toggle_panel() {
|
|||
|
||||
if( panel_status ) {
|
||||
panel_status = false;
|
||||
current_panel.setVisibility(false);
|
||||
} else {
|
||||
panel_status = true;
|
||||
current_panel.setVisibility(true);
|
||||
}
|
||||
if ( panel_status ) {
|
||||
if( FGPanel::OurPanel == 0)
|
||||
new FGPanel;
|
||||
fov *= 0.4232;
|
||||
} else {
|
||||
fov *= (1.0 / 0.4232);
|
||||
|
@ -610,8 +610,10 @@ int fgOPTIONS::parse_option( const string& arg ) {
|
|||
hud_status = true;
|
||||
} else if ( arg == "--disable-panel" ) {
|
||||
panel_status = false;
|
||||
current_panel.setVisibility(false);
|
||||
} else if ( arg == "--enable-panel" ) {
|
||||
panel_status = true;
|
||||
current_panel.setVisibility(true);
|
||||
fov *= 0.4232;
|
||||
} else if ( arg == "--disable-sound" ) {
|
||||
sound = false;
|
||||
|
|
|
@ -107,11 +107,6 @@ void FGView::Init( void ) {
|
|||
void FGView::UpdateViewParams( const FGInterface& f ) {
|
||||
UpdateViewMath(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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue