+++ /dev/null
-// sp_panel.cxx - default, 2D single-engine prop instrument panel
-//
-// Written by David Megginson, started January 2000.
-//
-// 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 <map>
-
-#include <simgear/debug/logstream.hxx>
-
-#include <Main/bfi.hxx>
-#include <Main/globals.hxx>
-
-#include "panel.hxx"
-#include "steam.hxx"
-#include "radiostack.hxx"
-
-FG_USING_STD(map);
-
- // Macros for instrument sizes
- // (these aren't used consistently
- // anyway, and should probably be
- // removed).
-#define SIX_X 200
-#define SIX_Y 345
-#define SIX_W 128
-#define SIX_SPACING (SIX_W + 5)
-#define SMALL_W 112
-
-#define createTexture(a) FGTextureManager::createTexture(a)
-#define V(n) (current_properties.getValue(n, true))
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Static functions for obtaining settings.
-//
-// These are all temporary, and should be moved somewhere else
-// as soon as convenient.
-////////////////////////////////////////////////////////////////////////
-
-static const string &panelGetTime ()
-{
- static string out; // FIXME: not thread-safe
- char buf[16];
- struct tm * t = globals->get_time_params()->getGmt();
- sprintf(buf, " %.2d:%.2d:%.2d",
- t->tm_hour, t->tm_min, t->tm_sec);
- out = buf;
- return out;
-}
-
-static bool panelGetNAV1TO ()
-{
- if (current_radiostack->get_nav1_inrange()) {
- double heading = current_radiostack->get_nav1_heading();
- double radial = current_radiostack->get_nav1_radial();
- double var = FGBFI::getMagVar();
- if (current_radiostack->get_nav1_loc()) {
- double offset = fabs(heading - radial);
- return (offset<= 8.0 || offset >= 352.0);
- } else {
- double offset =
- fabs(heading - var - radial);
- return (offset <= 20.0 || offset >= 340.0);
- }
- } else {
- return false;
- }
-}
-
-static bool panelGetNAV1FROM ()
-{
- if (current_radiostack->get_nav1_inrange()) {
- double heading = current_radiostack->get_nav1_heading();
- double radial = current_radiostack->get_nav1_radial();
- double var = FGBFI::getMagVar();
- if (current_radiostack->get_nav1_loc()) {
- double offset = fabs(heading - radial);
- return (offset >= 172.0 && offset<= 188.0);
- } else {
- double offset =
- fabs(heading - var - radial);
- return (offset >= 160.0 && offset <= 200.0);
- }
- } else {
- return false;
- }
-}
-
-static bool panelGetNAV2TO ()
-{
- if (current_radiostack->get_nav2_inrange()) {
- double heading = current_radiostack->get_nav2_heading();
- double radial = current_radiostack->get_nav2_radial();
- double var = FGBFI::getMagVar();
- if (current_radiostack->get_nav2_loc()) {
- double offset = fabs(heading - radial);
- return (offset<= 8.0 || offset >= 352.0);
- } else {
- double offset =
- fabs(heading - var - radial);
- return (offset <= 20.0 || offset >= 340.0);
- }
- } else {
- return false;
- }
-}
-
-static bool panelGetNAV2FROM ()
-{
- if (current_radiostack->get_nav2_inrange()) {
- double heading = current_radiostack->get_nav2_heading();
- double radial = current_radiostack->get_nav2_radial();
- double var = FGBFI::getMagVar();
- if (current_radiostack->get_nav2_loc()) {
- double offset = fabs(heading - radial);
- return (offset >= 172.0 && offset<= 188.0);
- } else {
- double offset =
- fabs(heading - var - radial);
- return (offset >= 160.0 && offset <= 200.0);
- }
- } else {
- return false;
- }
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Cropped textures, with string keys.
-////////////////////////////////////////////////////////////////////////
-
- // External representation of data.
-struct TextureData
-{
- const char * name; // the cropped texture's name
- const char * path; // the source texture file
-
- // the rectangular area containing
- // the texture (0.0-1.0)
- float xMin, yMin, xMax, yMax;
-};
-
-
- // This table is temporarily hard-coded,
- // but soon it will be initialized from
- // an XML file at runtime.
-TextureData textureData[] = {
-{"compassFront", "Textures/Panel.old/misc-1.rgb",
- 48.0/128.0, 0.0, 1.0, 24.0/128.0},
-{"airspeedBG", "Textures/Panel.old/faces-2.rgb",
- 0, 0.5, 0.5, 1.0},
-{"longNeedle", "Textures/Panel.old/misc-1.rgb",
- 102.0/128.0, 100.0/128.0, 107.0/128.0, 1.0},
-{"horizonBG", "Textures/Panel.old/faces-2.rgb",
- 0.5, 0.5, 1.0, 1.0},
-{"horizonFloat", "Textures/Panel.old/misc-1.rgb",
- 15.0/32.0, 54.0/128.0, 28.0/32.0, 87.0/128.0},
-{"horizonRim", "Textures/Panel.old/faces-2.rgb",
- 0, 0, 0.5, 0.5},
-{"horizonFront", "Textures/Panel.old/faces-2.rgb",
- 0.5, 0.0, 1.0, 0.5},
-{"altimeterBG", "Textures/Panel.old/faces-1.rgb",
- 0.5, 0.5, 1.0, 1.0},
-{"shortNeedle", "Textures/Panel.old/misc-1.rgb",
- 107.0/128.0, 110.0/128.0, 113.0/128.0, 1.0},
-{"bug", "Textures/Panel.old/misc-1.rgb",
- 108.0/128.0, 104.0/128.0, 112.0/128.0, 108.0/128.0},
-{"turnBG", "Textures/Panel.old/faces-1.rgb",
- 0.5, 0.0, 1.0, 0.5},
-{"turnPlane", "Textures/Panel.old/misc-1.rgb",
- 0.0, 3.0/8.0, 3.0/8.0, 0.5},
-{"turnBall", "Textures/Panel.old/misc-1.rgb",
- 108.0/128.0, 100.0/128.0, 112.0/128.0, 104.0/128.0},
-{"compassBG", "Textures/Panel.old/faces-1.rgb",
- 0.0, 0.5, 0.5, 1.0},
-{"compassCenter", "Textures/Panel.old/misc-1.rgb",
- 15.0/32.0, 11.0/16.0, 25.0/32.0, 1.0},
-{"headingKnob", "Textures/Panel.old/misc-1.rgb",
- 0, 64.0/128.0, 21.0/128.0, 85.0/128.0},
-{"knob", "Textures/Panel.old/misc-1.rgb",
- 79.0/128.0, 31.0/128.0, 101.0/128.0, 53.0/128.0},
-{"verticalBG", "Textures/Panel.old/faces-1.rgb",
- 0.0, 0.0, 0.5, 0.5},
-{"rpmBG", "Textures/Panel.old/faces-3.rgb",
- 0.0, 0.5, 0.5, 1.0},
-{"flapsBG", "Textures/Panel.old/faces-3.rgb",
- 0.5, 0.5, 1.0, 1.0},
-{"clockBG", "Textures/Panel.old/faces-3.rgb",
- 0.5, 0.0, 1.0, 0.5},
-{"controlsBG", "Textures/Panel.old/faces-3.rgb",
- 0.0, 0.0, 0.5, 0.5},
-{"navFG", "Textures/Panel.old/misc-1.rgb",
- 0, 0, 0.25, 5.0/16.0},
-{"obsKnob", "Textures/Panel.old/misc-1.rgb",
- 0.0, 86.0/128.0, 21.0/128.0, 107.0/128.0},
-{"toFlag", "Textures/Panel.old/misc-1.rgb",
- 120.0/128.0, 74.0/128.0, 1.0, 80.0/128.0},
-{"fromFlag", "Textures/Panel.old/misc-1.rgb",
- 120.0/128.0, 80.0/128.0, 1.0, 86.0/128.0},
-{"offFlag", "Textures/Panel.old/misc-1.rgb",
- 120.0/128.0, 0.5, 1.0, 70.0/128.0},
-{"navNeedle", "Textures/Panel.old/misc-1.rgb",
- 56.0/128.0, 0.5, 58.0/128.0, 1.0},
-{"adfNeedle", "Textures/Panel.old/misc-1.rgb",
- 120.0/128.0, 88.0/128.0, 1.0, 1.0},
-{"adfKnob", "Textures/Panel.old/misc-1.rgb",
- 0.0, 107.0/128.0, 21.0/128.0, 1.0},
-{"adfPlane", "Textures/Panel.old/misc-1.rgb",
- 102.0/128.0, 32.0/128.0, 1.0, 48.0/128.0},
-{"adfFace", "Textures/Panel.old/faces-4.rgb",
- 0.0, 0.5, 0.5, 1.0},
-{"navRadioBG", "Textures/Panel.old/radios-1.rgb",
- 0.0, 0.75, 1.0, 1.0},
-{"adfRadioBG", "Textures/Panel.old/radios-1.rgb",
- 0.0, 0.5, 1.0, 0.75},
-{"autopilotBG", "Textures/Panel.old/radios-1.rgb",
- 0.0, 0.375, 1.0, 0.5},
-{"hdgButtonOn", "Textures/Panel.old/misc-1.rgb",
- 39.0/128.0, 118.0/128.0, 54.0/128.0, 128.0/128.0},
-{"hdgButtonOff", "Textures/Panel.old/misc-1.rgb",
- 22.0/128.0, 118.0/128.0, 37.0/128.0, 128.0/128.0},
-{"navButtonOn", "Textures/Panel.old/misc-1.rgb",
- 39.0/128.0, 106.0/128.0, 54.0/128.0, 116.0/128.0},
-{"navButtonOff", "Textures/Panel.old/misc-1.rgb",
- 22.0/128.0, 106.0/128.0, 37.0/128.0, 116.0/128.0},
-{"altButtonOn", "Textures/Panel.old/misc-1.rgb",
- 39.0/128.0, 82.0/128.0, 54.0/128.0, 92.0/128.0},
-{"altButtonOff", "Textures/Panel.old/misc-1.rgb",
- 22.0/128.0, 82.0/128.0, 37.0/128.0, 92.0/128.0},
-{"dmeBG", "Textures/Panel.old/radios-1.rgb",
- 0.0, 0.25, 0.375, 0.375},
-{"compassRibbon", "Textures/Panel.old/compass-ribbon.rgb",
- 0.0, 0.0, 1.0, 1.0},
-{0, 0}
-};
-
- // Internal representation of
- // data.
-map<const char *,CroppedTexture> tex;
-
-
-
-/**
- * Ugly kludge to delay texture loading.
- */
-class MyTexturedLayer : public FGTexturedLayer
-{
-public:
- MyTexturedLayer (const char * name, int w = -1, int h = -1)
- : FGTexturedLayer(w, h), _name(name), _textureLoaded(false) {}
-
- virtual void draw ();
- virtual CroppedTexture &getTexture ();
-
-private:
- const char * _name;
- mutable bool _textureLoaded;
-};
-
-CroppedTexture &
-MyTexturedLayer::getTexture ()
-{
- MyTexturedLayer * me = (MyTexturedLayer *)this;
- if (!_textureLoaded) {
- _textureLoaded = true;
- me->setTexture(tex[_name]);
- }
- return FGTexturedLayer::getTexture();
-}
-
-void
-MyTexturedLayer::draw ()
-{
- getTexture();
- FGTexturedLayer::draw();
-}
-
-
-
-/**
- * Populate the textureMap from the data table.
- */
-static void
-setupTextures ()
-{
- for (int i = 0; textureData[i].name; i++) {
- tex[textureData[i].name] =
- CroppedTexture(textureData[i].path, textureData[i].xMin,
- textureData[i].yMin, textureData[i].xMax,
- textureData[i].yMax);
- }
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Special class for magnetic compass ribbon layer.
-////////////////////////////////////////////////////////////////////////
-
-class MagRibbon : public MyTexturedLayer
-{
-public:
- MagRibbon (int w, int h);
- virtual ~MagRibbon () {}
-
- virtual void draw ();
-};
-
-MagRibbon::MagRibbon (int w, int h)
- : MyTexturedLayer("compassRibbon", w, h)
-{
-}
-
-void
-MagRibbon::draw ()
-{
- double heading = FGSteam::get_MH_deg();
- double xoffset, yoffset;
-
- while (heading >= 360.0) {
- heading -= 360.0;
- }
- while (heading < 0.0) {
- heading += 360.0;
- }
-
- if (heading >= 60.0 && heading <= 180.0) {
- xoffset = heading / 240.0;
- yoffset = 0.75;
- } else if (heading >= 150.0 && heading <= 270.0) {
- xoffset = (heading - 90.0) / 240.0;
- yoffset = 0.50;
- } else if (heading >= 240.0 && heading <= 360.0) {
- xoffset = (heading - 180.0) / 240.0;
- yoffset = 0.25;
- } else {
- if (heading < 270.0)
- heading += 360.0;
- xoffset = (heading - 270.0) / 240.0;
- yoffset = 0.0;
- }
-
- xoffset = 1.0 - xoffset;
- // Adjust to put the number in the centre
- xoffset -= 0.25;
-
- CroppedTexture &t = getTexture();
- t.minX = xoffset;
- t.minY = yoffset;
- t.maxX = xoffset + 0.5;
- t.maxY = yoffset + 0.25;
- MyTexturedLayer::draw();
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Instruments.
-////////////////////////////////////////////////////////////////////////
-
-struct TransData
-{
- enum Type {
- End = 0,
- Rotation,
- XShift,
- YShift
- };
- Type type;
- const char * propName;
- float min, max, factor, offset;
-};
-
-struct LayerData
-{
- FGInstrumentLayer * layer;
- TransData transformations[16];
-};
-
-struct InstrumentData
-{
- const char * name;
- int x, y, w, h;
- FGPanelAction * actions[16];
- LayerData layers[16];
-};
-
-InstrumentData instruments[] =
-{
-
- {"magcompass", 768, 459, SIX_W, SIX_W/2, {}, {
- {new MagRibbon(int(SIX_W*0.8), int(SIX_W*0.2))},
- {new MyTexturedLayer("compassFront", SIX_W, SIX_W*(24.0/80.0))}
- }},
-
- {"airspeed", SIX_X, SIX_Y, SIX_W, SIX_W, {}, {
- {new MyTexturedLayer("airspeedBG", -1, -1)},
- {new MyTexturedLayer("longNeedle", int(SIX_W*(5.0/64.0)),
- int(SIX_W*(7.0/16.0))), {
- {TransData::Rotation, "/steam/airspeed",
- 30.0, 220.0, 36.0/20.0, -54.0},
- {TransData::YShift, 0,
- 0.0, 0.0, 0.0, SIX_W*(12.0/64.0)}
- }}
- }},
-
- {"horizon", SIX_X + SIX_SPACING, SIX_Y, SIX_W, SIX_W, {}, {
- {new MyTexturedLayer("horizonBG", -1, -1), {
- {TransData::Rotation, "/orientation/roll", -360.0, 360.0, -1.0, 0.0}
- }},
- {new MyTexturedLayer("horizonFloat",
- int(SIX_W * (13.0/16.0)), int(SIX_W * (33.0/64.0))), {
- {TransData::Rotation, "/orientation/roll", -360.0, 360.0, -1.0, 0.0},
- {TransData::YShift, "/orientation/pitch",
- -20.0, 20.0, -(1.5/160.0)*SIX_W, 0.0}
- }},
- {new MyTexturedLayer("horizonRim", -1, -1), {
- {TransData::Rotation, "/orientation/roll", -360.0, 360.0, -1.0, 0.0}
- }},
- {new MyTexturedLayer("horizonFront", -1, -1)}
- }},
-
- {"altimeter", SIX_X + SIX_SPACING + SIX_SPACING, SIX_Y, SIX_W, SIX_W, {}, {
- {new MyTexturedLayer("altimeterBG", -1, -1)},
- {new MyTexturedLayer("longNeedle",
- int(SIX_W*(5.0/64.0)), int(SIX_W*(7.0/16.0))), {
- {TransData::Rotation, "/steam/altitude",
- 0.0, 100000.0, 360.0/1000.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W*(12.0/64.0)}
- }},
- {new MyTexturedLayer("shortNeedle",
- int(SIX_W*(6.0/64.0)), int(SIX_W*(18.0/64.0))), {
- {TransData::Rotation, "/steam/altitude",
- 0.0, 100000.0, 360.0/10000.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W/8.0}
- }},
- {new MyTexturedLayer("bug", int(SIX_W*(4.0/64.0)), int(SIX_W*(4.0/64.0))), {
- {TransData::Rotation, "/steam/altitude",
- 0.0, 100000.0, 360.0/100000.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W/2.0-4}
- }},
- }},
-
- {"turn", SIX_X, SIX_Y-SIX_SPACING, SIX_W, SIX_W, {}, {
- {new MyTexturedLayer("turnBG", -1, -1)},
- {new MyTexturedLayer("turnPlane", int(SIX_W * 0.75), int(SIX_W * 0.25)), {
- {TransData::Rotation, "/steam/turn-rate", -2.5, 2.5, 20.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, int(SIX_W * 0.0625)}
- }},
- {new MyTexturedLayer("turnBall",
- int(SIX_W * (4.0/64.0)), int(SIX_W * (4.0/64.0))), {
- {TransData::Rotation, "/steam/slip-skid",
- -0.1, 0.1, 400.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -(SIX_W/4)+4}
- }}
- }},
-
- {"verticalVelocity", SIX_X+SIX_SPACING+SIX_SPACING, SIX_Y-SIX_SPACING,
- SIX_W, SIX_W, {}, {
- {new MyTexturedLayer("verticalBG", -1, -1)},
- {new MyTexturedLayer("longNeedle",
- int(SIX_W*(5.0/64.0)), int(SIX_W*(7.0/16.0))), {
- {TransData::Rotation, "/steam/vertical-speed",
- -2000.0, 2000.0, 42.0/500.0, 270.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W*12.0/64.0}
- }}
- }},
-
- {"controls", SIX_X, SIX_Y-(SIX_SPACING*2), SMALL_W, SMALL_W, {}, {
- {new MyTexturedLayer("controlsBG", -1, -1)},
- {new MyTexturedLayer("bug", int(SIX_W*4.0/64.0), int(SIX_W*4.0/64.0)), {
- {TransData::XShift, "/controls/aileron",
- -1.0, 1.0, SMALL_W*0.75/2.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, (SIX_W/2.0)-12.0}
- }},
- {new MyTexturedLayer("bug", int(SIX_W*4.0/64.0), int(SIX_W*4.0/64.0)), {
- {TransData::Rotation, 0, 0.0, 0.0, 0.0, 180.0},
- {TransData::XShift, "/controls/rudder",
- -1.0, 1.0, -SMALL_W*0.75/2.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W/2.0-12.0}
- }},
- {new MyTexturedLayer("bug", int(SIX_W*4.0/64.0), int(SIX_W*4.0/64.0)), {
- {TransData::Rotation, 0, 0.0, 0.0, 0.0, 270.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SMALL_W*3.0/8.0},
- {TransData::XShift, "/controls/elevator-trim",
- -1.0, 1.0, SMALL_W*0.75/2.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, (SIX_W/2.0)-12.0}
- }},
- {new MyTexturedLayer("bug", int(SIX_W*4.0/64.0), int(SIX_W*4.0/64.0)), {
- {TransData::Rotation, 0, 0.0, 0.0, 0.0, 90.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SMALL_W*(3.0/8.0)},
- {TransData::XShift, "/controls/elevator",
- -1.0, 1.0, -SMALL_W*0.75/2.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, (SIX_W/2.0)-12.0}
- }}
- }},
-
- {"flaps", SIX_X+SIX_SPACING, SIX_Y-(SIX_SPACING*2), SMALL_W, SMALL_W, {}, {
- {new MyTexturedLayer("flapsBG", -1, -1)},
- {new MyTexturedLayer("longNeedle",
- int(SIX_W*(5.0/64.0)), int(SIX_W*(7.0/16.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, -(SMALL_W/4) + (SMALL_W/16)},
- {TransData::Rotation, "/controls/flaps", 0.0, 1.0, 120.0, 30.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W*12.0/64.0}
- }}
- }},
-
- {"rpm", SIX_X+(SIX_SPACING*2), SIX_Y-(SIX_SPACING*2), SMALL_W, SMALL_W, {}, {
- {new MyTexturedLayer("rpmBG", -1, -1)},
- {new MyTexturedLayer("longNeedle",
- int(SIX_W*(5.0/64.0)), int(SIX_W*(7.0/16.0))), {
- {TransData::Rotation, "/controls/throttle", 0.0, 100.0, 300.0, -150.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SIX_W*12.0/64.0}
- }}
- }},
-
- {"gyro", SIX_X+SIX_SPACING, SIX_Y-SIX_SPACING, SIX_W, SIX_W, {
- new FGAdjustAction(0, SIX_W/2-SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/autopilot/settings/heading-magnetic"),
- -1.0, -360.0, 360.0, true),
- new FGAdjustAction(0, SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/autopilot/settings/heading-magnetic"),
- 1.0, -360.0, 360.0, true),
- new FGAdjustAction(1, SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/autopilot/settings/heading-magnetic"),
- -5.0, -360.0, 360.0, true),
- new FGAdjustAction(1, SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/autopilot/settings/heading-magnetic"),
- 5.0, -360.0, 360.0, true),
- new FGAdjustAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/steam/gyro-compass-error"),
- -1.0, -360.0, 360.0, true),
- new FGAdjustAction(0, -SIX_W/2+SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/steam/gyro-compass-error"),
- 1.0, -360.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/steam/gyro-compass-error"),
- -5.0, -360.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2+SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/steam/gyro-compass-error"),
- 5.0, -360.0, 360.0, true)
- }, {
- {new MyTexturedLayer("compassBG", -1, -1), {
- {TransData::Rotation, "/steam/gyro-compass", -720.0, 720.0, -1.0, 0.0}
- }},
- {new MyTexturedLayer("bug",
- int(SIX_W*(4.0/64.0)), int(SIX_W*(4.0/64.0))), {
- {TransData::Rotation, "/autopilot/settings/heading",
- -720.0, 720.0, 1.0, 180.0},
- {TransData::Rotation, "/steam/gyro-compass", -720.0, 720.0, -1.0, 0.0},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -(SIX_W/2.0)+4}
- }},
- {new MyTexturedLayer("compassCenter", int(SIX_W*0.625), int(SIX_W*0.625))},
- {new MyTexturedLayer("headingKnob",
- int(SIX_W*(21.0/112.0)), int(SIX_W*(21.0/112.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, SIX_W/2-10},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::Rotation, "/autopilot/settings/heading",
- -360.0, 360.0, 1.0, 0.0}
- }},
- {new MyTexturedLayer("knob",
- int(SIX_W*(22.0/112.0)), int(SIX_W*(22.0/112.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10}
- }}
-
- }},
-
- {"chronometer", SIX_X-SIX_SPACING-8, SIX_Y, SMALL_W, SMALL_W, {}, {
- {new MyTexturedLayer("clockBG")},
- {new FGTextLayer(SMALL_W, SMALL_W,
- new FGTextLayer::Chunk(FGTextLayer::TEXT_VALUE,
- V("/panel/time"))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, SMALL_W*-0.38},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, SMALL_W*-0.06}
- }}
- }},
-
- {"nav1", SIX_X+(SIX_SPACING*3)+20, SIX_Y, SIX_W, SIX_W, {
- new FGAdjustAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav1/radials/selected"),
- 1.0, 0.0, 360.0, true),
- new FGAdjustAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav1/radials/selected"),
- -1.0, 0.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav1/radials/selected"),
- 5.0, 0.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav1/radials/selected"),
- -5.0, 0.0, 360.0, true)
- }, {
- {new MyTexturedLayer("compassBG"), {
- {TransData::Rotation, "/radios/nav1/radials/selected",
- -360.0, 360.0, -1.0, 0.0}
- }},
- {new MyTexturedLayer("navFG", SIX_W/2, int(SIX_W*(5.0/8.0)))},
- {new MyTexturedLayer("obsKnob", int(SIX_W*(21.0/112.0)),
- int(SIX_W*(21.0/112.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::Rotation, "/radios/nav1/radials/selected",
- -360.0, 360.0, 1.0, 0.0}
- }},
- {new FGSwitchLayer(SIX_W/8, SIX_W/8, V("/panel/vor1/to-flag"),
- new MyTexturedLayer("toFlag", SIX_W/8, SIX_W/8),
- new FGSwitchLayer(SIX_W/8, SIX_W/8,
- V("/panel/vor1/from-flag"),
- new MyTexturedLayer("fromFlag",
- SIX_W/8,
- SIX_W/8),
- new MyTexturedLayer("offFlag",
- SIX_W/8,
- SIX_W/8))), {
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -int(SIX_W*0.1875)}
- }},
- {new MyTexturedLayer("navNeedle", SIX_W/32, SIX_W/2), {
- {TransData::XShift, "/steam/vor1",
- -10.0, 10.0, SIX_W/40.0, 0.0}
- }},
- {new MyTexturedLayer("navNeedle", SIX_W/32, SIX_W/2), {
- {TransData::YShift, "/steam/glidescope1", -1.0, 1.0, SIX_W/5.0, 0.0},
- {TransData::Rotation, 0, 0.0, 0.0, 0.0, 90}
- }}
- }},
-
- {"nav2", SIX_X+(SIX_SPACING*3)+20, SIX_Y-SIX_SPACING, SIX_W, SIX_W, {
- new FGAdjustAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav2/radials/selected"),
- 1.0, 0.0, 360.0, true),
- new FGAdjustAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav2/radials/selected"),
- -1.0, 0.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav2/radials/selected"),
- 5.0, 0.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/nav2/radials/selected"),
- -5.0, 0.0, 360.0, true)
- }, {
- {new MyTexturedLayer("compassBG"), {
- {TransData::Rotation, "/radios/nav2/radials/selected",
- -360.0, 360.0, -1.0, 0.0}
- }},
- {new MyTexturedLayer("navFG", SIX_W/2, int(SIX_W*(5.0/8.0)))},
- {new MyTexturedLayer("obsKnob", int(SIX_W*(21.0/112.0)),
- int(SIX_W*(21.0/112.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::Rotation, "/radios/nav2/radials/selected",
- -360.0, 360.0, 1.0, 0.0}
- }},
- {new FGSwitchLayer(SIX_W/8, SIX_W/8, V("/panel/vor2/to-flag"),
- new MyTexturedLayer("toFlag", SIX_W/8, SIX_W/8),
- new FGSwitchLayer(SIX_W/8, SIX_W/8,
- V("/panel/vor2/from-flag"),
- new MyTexturedLayer("fromFlag",
- SIX_W/8,
- SIX_W/8),
- new MyTexturedLayer("offFlag",
- SIX_W/8,
- SIX_W/8))), {
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -int(SIX_W*0.1875)}
- }},
- {new MyTexturedLayer("navNeedle", SIX_W/32, SIX_W/2), {
- {TransData::XShift, "/steam/vor2",
- -10.0, 10.0, SIX_W/40.0, 0.0}
- }}
- }},
-
- {"adf", SIX_X+(SIX_SPACING*3)+20, SIX_Y-(SIX_SPACING*2), SIX_W, SIX_W, {
- new FGAdjustAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/adf/rotation"),
- -1.0, 0.0, 360.0, true),
- new FGAdjustAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/adf/rotation"),
- 1.0, 0.0, 360.0, true),
- new FGAdjustAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/adf/rotation"),
- -5.0, 0.0, 360.0, true),
-
- new FGAdjustAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
- V("/radios/adf/rotation"),
- 5.0, 0.0, 360.0, true)
- },{
- {new MyTexturedLayer("compassBG"), {
- {TransData::Rotation, "/radios/adf/rotation", 0.0, 360.0, 1.0, 0.0}
- }},
- {new MyTexturedLayer("adfFace", -1, -1), {}},
- {new MyTexturedLayer("adfNeedle", SIX_W/8, int(SIX_W*0.625)), {
- {TransData::Rotation, "/steam/adf", -720.0, 720.0, 1.0, 0.0}
- }},
- {new MyTexturedLayer("adfKnob", int(SIX_W*(21.0/112.0)),
- int(SIX_W*(21.0/112.0))), {
- {TransData::XShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::YShift, 0, 0.0, 0.0, 0.0, -SIX_W/2+10},
- {TransData::Rotation, "/radios/adf/rotation", 0.0, 360.0, 1.0, 0.0}
- }}
- }},
-
- {0}
-
-};
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Static factory functions to create textured gauges.
-//
-// These will be replaced first with a giant table, and then with
-// configuration files read from an external source, but for now
-// they're hard-coded.
-////////////////////////////////////////////////////////////////////////
-
-
-/**
- * Create Nav-Com radio 1.
- */
-static FGPanelInstrument *
-createNavCom1 (int x, int y)
-{
- FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
-
- // Use the button to swap standby and active
- // NAV frequencies
- inst->addAction(new FGSwapAction(0, int(SIX_W * .375),
- -SIX_W/4, SIX_W/4, SIX_W/4,
- V("/radios/nav1/frequencies/selected"),
- V("/radios/nav1/frequencies/standby")));
-
- // Use the knob to tune the standby NAV
- inst->addAction(new FGAdjustAction(0, SIX_W-SIX_W/4, -SIX_W/4,
- SIX_W/8, SIX_W/4,
- V("/radios/nav1/frequencies/standby"),
- -0.05, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(0, SIX_W-SIX_W/8, -SIX_W/4,
- SIX_W/8, SIX_W/4,
- V("/radios/nav1/frequencies/standby"),
- 0.05, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(1, SIX_W-SIX_W/4, -SIX_W/4,
- SIX_W/8, SIX_W/4,
- V("/radios/nav1/frequencies/standby"),
- -0.5, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(1, SIX_W-SIX_W/8, -SIX_W/4,
- SIX_W/8, SIX_W/4,
- V("/radios/nav1/frequencies/standby"),
- 0.5, 108.0, 117.95, true));
-
- // Layer 0: background
- inst->addLayer(tex["navRadioBG"], SIX_W*2, SIX_W/2);
-
- // Layer 1: NAV frequencies
- FGTextLayer * text = new FGTextLayer(SIX_W*2, SMALL_W/2);
- text->addChunk(new
- FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/nav1/frequencies/selected"),
- "%.2f"));
- text->addChunk(new
- FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/nav1/frequencies/standby"),
- "%7.2f"));
- text->setPointSize(14);
- text->setColor(1.0, 0.5, 0.0);
- inst->addLayer(text);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 0.0, 3));
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::YSHIFT, 0,
- 0.0, 0.0, 0.0, 5));
-
- return inst;
-}
-
-
-/**
- * Create Nav-Com radio 2.
- */
-static FGPanelInstrument *
-createNavCom2 (int x, int y)
-{
- FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
-
- // Use the button to swap standby and active
- // NAV frequencies
- inst->addAction(new FGSwapAction(0, int(SIX_W * .375), -SIX_W/4, SIX_W/4, SIX_W/4,
- V("/radios/nav2/frequencies/selected"),
- V("/radios/nav2/frequencies/standby")));
-
- // Use the knob to tune the standby NAV
- inst->addAction(new FGAdjustAction(0, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
- V("/radios/nav2/frequencies/standby"),
- -0.05, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(0, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
- V("/radios/nav2/frequencies/standby"),
- 0.05, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(1, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
- V("/radios/nav2/frequencies/standby"),
- -0.5, 108.0, 117.95, true));
- inst->addAction(new FGAdjustAction(1, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
- V("/radios/nav2/frequencies/standby"),
- 0.5, 108.0, 117.95, true));
-
- // Layer 0: background
- inst->addLayer(tex["navRadioBG"], SIX_W*2, SIX_W/2);
-
- // Layer 1: NAV frequencies
- FGTextLayer * text = new FGTextLayer(SIX_W*2, SIX_W/2);
- text->addChunk(new
- FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/nav2/frequencies/selected"),
- "%.2f"));
- text->addChunk(new
- FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/nav2/frequencies/standby"),
- "%7.2f"));
- text->setPointSize(14);
- text->setColor(1.0, 0.5, 0.0);
- inst->addLayer(text);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 1.0, 3));
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::YSHIFT, 0,
- 0.0, 0.0, 1.0, 5));
-
- return inst;
-}
-
-
-/**
- * Create ADF radio.
- */
-static FGPanelInstrument *
-createADFRadio (int x, int y)
-{
- FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
-
- // Use the knob to tune the standby NAV
- inst->addAction(new FGAdjustAction(0, int(SIX_W * 0.7), int(-SIX_W * 0.07),
- int(SIX_W * 0.09), int(SIX_W * 0.14),
- V("/radios/adf/frequencies/selected"),
- -1.0, 100.0, 1299, true));
- inst->addAction(new FGAdjustAction(0, int(SIX_W * 0.79), int(-SIX_W * 0.07),
- int(SIX_W * 0.09), int(SIX_W * 0.14),
- V("/radios/adf/frequencies/selected"),
- 1.0, 100.0, 1299, true));
- inst->addAction(new FGAdjustAction(1, int(SIX_W * 0.7), int(-SIX_W * 0.07),
- int(SIX_W * 0.09), int(SIX_W * 0.14),
- V("/radios/adf/frequencies/selected"),
- -25.0, 100.0, 1299, true));
- inst->addAction(new FGAdjustAction(1, int(SIX_W * 0.79), int(-SIX_W * 0.07),
- int(SIX_W * 0.09), int(SIX_W * 0.14),
- V("/radios/adf/frequencies/selected"),
- 25.0, 100.0, 1299, true));
-
- // Layer 0: background
- inst->addLayer(tex["adfRadioBG"], SIX_W*2, SIX_W/2);
-
- // Layer: ADF frequency
- FGTextLayer * text = new FGTextLayer(SIX_W*2, SIX_W/2);
- text->addChunk(new
- FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/adf/frequencies/selected"),
- "%4.0f"));
- text->setPointSize(14);
- text->setColor(1.0, 0.5, 0.0);
- inst->addLayer(text);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 1.0, -SIX_W + 18));
-
- return inst;
-}
-
-
-/**
- * Construct the autopilot.
- */
-
-FGPanelInstrument *
-createAP (int x, int y)
-{
- FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/4);
-
- // Action: select HDG button
- inst->addAction(new FGToggleAction(0, int(-SIX_W*0.6125), -SIX_W/16, SIX_W/4, SIX_W/8,
- V("/autopilot/locks/heading")));
-
- // Action: select NAV button
- inst->addAction(new FGToggleAction(0, int(-SIX_W*0.3625), -SIX_W/16, SIX_W/4, SIX_W/8,
- V("/autopilot/locks/nav1")));
-
- // Action: select ALT button
- inst->addAction(new FGToggleAction(0, int(-SIX_W*0.1125), -SIX_W/16, SIX_W/4, SIX_W/8,
- V("/autopilot/locks/altitude")));
-
- // Layer: AP background
- inst->addLayer(tex["autopilotBG"], SIX_W*2, SIX_W/4);
-
- // Display HDG button
- FGSwitchLayer * sw =
- new FGSwitchLayer(SIX_W/4, SIX_W/8, V("/autopilot/locks/heading"),
- new FGTexturedLayer(tex["hdgButtonOn"], SIX_W/4, SIX_W/8),
- new FGTexturedLayer(tex["hdgButtonOff"], SIX_W/4, SIX_W/8));
- inst->addLayer(sw);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 1.0, -SIX_W * 0.5));
-
- // Display NAV button
- sw = new FGSwitchLayer(SIX_W/4, SIX_W/8, V("/autopilot/locks/nav1"),
- new FGTexturedLayer(tex["navButtonOn"], SIX_W/4, SIX_W/8),
- new FGTexturedLayer(tex["navButtonOff"], SIX_W/4, SIX_W/8));
- inst->addLayer(sw);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 1.0, -SIX_W * 0.25));
-
- // Display ALT button
- sw = new FGSwitchLayer(SIX_W/4, SIX_W/8, V("/autopilot/locks/altitude"),
- new FGTexturedLayer(tex["altButtonOn"], SIX_W/4, SIX_W/8),
- new FGTexturedLayer(tex["altButtonOff"], SIX_W/4, SIX_W/8));
- inst->addLayer(sw);
-
- return inst;
-}
-
-FGPanelInstrument *
-createDME (int x, int y)
-{
- FGLayeredInstrument * inst =
- new FGLayeredInstrument(x, y, int(SIX_W * 0.75), int(SIX_W * 0.25));
-
- // Layer: background
- inst->addLayer(tex["dmeBG"]);
-
- // Layer: current distance
-
- FGTextLayer * text1 = new FGTextLayer(SIX_W/2, SIX_W/4);
- text1->addChunk(new FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE,
- V("/radios/nav1/dme/distance"),
- "%05.1f",
- METER_TO_NM));
- text1->setPointSize(12);
- text1->setColor(1.0, 0.5, 0.0);
-
- FGTextLayer * text2 = new FGTextLayer(SIX_W/2, SIX_W/4);
- text2->addChunk(new FGTextLayer::Chunk("---.-"));
- text2->setPointSize(12);
- text2->setColor(1.0, 0.5, 0.0);
-
- FGSwitchLayer * sw =
- new FGSwitchLayer(SIX_W/2, SIX_W/4, V("/radios/nav1/dme/in-range"),
- text1, text2);
-
- inst->addLayer(sw);
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::XSHIFT, 0,
- 0.0, 0.0, 1.0, -20));
- inst->addTransformation
- (new FGPanelTransformation(FGPanelTransformation::YSHIFT, 0,
- 0.0, 0.0, 1.0, -6));
-
- return inst;
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Construct a panel for a small, single-prop plane.
-////////////////////////////////////////////////////////////////////////
-
-FGPanel *
-fgCreateSmallSinglePropPanel (int xpos, int ypos, int finx, int finy)
-{
- int w = finx - xpos;
- int h = finy - ypos;
- FGPanel * panel = new FGPanel(xpos, ypos, w, h);
- int x, y;
-
- // Tie local functions
- // FIXME: define these elsewhere...
- current_properties.tieString("/panel/time", panelGetTime);
- current_properties.tieBool("/panel/vor1/to-flag", panelGetNAV1TO);
- current_properties.tieBool("/panel/vor1/from-flag", panelGetNAV1FROM);
- current_properties.tieBool("/panel/vor2/to-flag", panelGetNAV2TO);
- current_properties.tieBool("/panel/vor2/from-flag", panelGetNAV2FROM);
-
- setupTextures();
-
- // Read gauges from data table.
- for (int i = 0; instruments[i].name; i++) {
- InstrumentData &gauge = instruments[i];
- FGLayeredInstrument * inst =
- new FGLayeredInstrument(gauge.x, gauge.y, gauge.w, gauge.h);
-
- int j;
- for (j = 0; gauge.actions[j]; j++) {
- inst->addAction(gauge.actions[j]);
- }
-
- for (j = 0; gauge.layers[j].layer; j++) {
- LayerData &layer = gauge.layers[j];
-// inst->addLayer(tex[layer.textureName], layer.w, layer.h);
- inst->addLayer(layer.layer);
-
- for (int k = 0; layer.transformations[k].type; k++) {
- TransData &trans = layer.transformations[k];
- FGPanelTransformation::Type type = FGPanelTransformation::XSHIFT;
- switch (trans.type) {
- case TransData::Rotation:
- type = FGPanelTransformation::ROTATION;
- break;
- case TransData::XShift:
- type = FGPanelTransformation::XSHIFT;
- break;
- case TransData::YShift:
- type = FGPanelTransformation::YSHIFT;
- break;
- default:
- break;
- }
- if (trans.propName != 0) {
- inst->addTransformation
- (new FGPanelTransformation(type, V(trans.propName),
- trans.min, trans.max,
- trans.factor, trans.offset));
- } else {
- inst->addTransformation
- (new FGPanelTransformation(type, 0,
- 0.0, 0.0, 1.0, trans.offset));
- }
- }
-
- }
- panel->addInstrument(inst);
- }
-
- x = SIX_X;
- y = SIX_Y;
-
- // Set the background texture
- panel->setBackground(createTexture("Textures/Panel.old/panel-bg.rgb"));
-
- // Radio stack
- x = SIX_X + (SIX_SPACING * 5);
- y = SIX_Y;
- panel->addInstrument(createDME(x, y));
- y -= (int)(SIX_W * 0.375);
- panel->addInstrument(createNavCom1(x, y));
- y -= SIX_W / 2;
- panel->addInstrument(createNavCom2(x, y));
- y -= SIX_W / 2;
- panel->addInstrument(createADFRadio(x, y));
- y -= (int)(SIX_W * 0.375);
- panel->addInstrument(createAP(x, y));
-
- return panel;
-}
-
-// end of sp_panel.cxx