// 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.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
# include <config.h>
#endif
-#ifdef HAVE_WINDOWS_H
-# include <windows.h>
-#endif
-
#include <string.h> // for strcmp()
#include <simgear/compiler.h>
-#include <simgear/misc/exception.hxx>
-
-#include <simgear/misc/sg_path.hxx>
+#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/props.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
-#include STL_IOSTREAM
-#include STL_FSTREAM
-#include STL_STRING
+#include <istream>
+#include <fstream>
+#include <string>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <GUI/gui.h>
-#include "panel.hxx"
-#include "steam.hxx"
+// #include "panel.hxx"
#include "panel_io.hxx"
+#include <Instrumentation/KLN89/kln89.hxx>
-#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS)
-SG_USING_STD(istream);
-SG_USING_STD(ifstream);
-#endif
-SG_USING_STD(string);
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Built-in layer for the magnetic compass ribbon layer.
-//
-// TODO: move this out into a special directory for built-in
-// layers of various sorts.
-////////////////////////////////////////////////////////////////////////
-
-class FGMagRibbon : public FGTexturedLayer
-{
-public:
- FGMagRibbon (int w, int h);
- virtual ~FGMagRibbon () {}
-
- virtual void draw ();
-};
-
-FGMagRibbon::FGMagRibbon (int w, int h)
- : FGTexturedLayer(w, h)
-{
- FGCroppedTexture texture("Aircraft/Instruments/Textures/compass-ribbon.rgb");
- setTexture(texture);
-}
-
-void
-FGMagRibbon::draw ()
-{
- double heading = FGSteam::get_MH_deg();
- double xoffset, yoffset;
+//built-in layers
+#include "built_in/FGMagRibbon.hxx"
- 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;
-
- FGCroppedTexture &t = getTexture();
- t.setCrop(xoffset, yoffset, xoffset + 0.5, yoffset + 0.25);
- FGTexturedLayer::draw();
-}
+using std::istream;
+using std::ifstream;
+using std::string;
\f
////////////////////////////////////////////////////////////////////////
static void
-readConditions (FGConditional * component, const SGPropertyNode * node)
+readConditions (SGConditional *component, const SGPropertyNode *node)
{
const SGPropertyNode * conditionNode = node->getChild("condition");
if (conditionNode != 0)
// The top level is implicitly AND
- component->setCondition(fgReadCondition(conditionNode));
+ component->setCondition(sgReadCondition(globals->get_props(),
+ conditionNode) );
}
static FGPanelAction *
readAction (const SGPropertyNode * node, float w_scale, float h_scale)
{
+ unsigned int i, j;
+ SGPropertyNode *binding;
+ vector<SGPropertyNode_ptr>bindings = node->getChildren("binding");
+
+ // button-less actions are fired initially
+ if (!node->hasValue("w") || !node->hasValue("h")) {
+ for (i = 0; i < bindings.size(); i++) {
+ SGBinding b(bindings[i], globals->get_props());
+ b.fire();
+ }
+ return 0;
+ }
+
string name = node->getStringValue("name");
int button = node->getIntValue("button");
int y = int(node->getIntValue("y") * h_scale);
int w = int(node->getIntValue("w") * w_scale);
int h = int(node->getIntValue("h") * h_scale);
+ bool repeatable = node->getBoolValue("repeatable", true);
- FGPanelAction * action = new FGPanelAction(button, x, y, w, h);
+ FGPanelAction * action = new FGPanelAction(button, x, y, w, h, repeatable);
- vector<const SGPropertyNode *>bindings = node->getChildren("binding");
- for (unsigned int i = 0; i < bindings.size(); i++) {
+ SGPropertyNode * dest = fgGetNode("/sim/bindings/panel", true);
+
+ for (i = 0; i < bindings.size(); i++) {
SG_LOG(SG_INPUT, SG_INFO, "Reading binding "
- << bindings[i]->getStringValue("command"));
- action->addBinding(new FGBinding(bindings[i])); // TODO: allow modifiers
+ << bindings[i]->getStringValue("command"));
+
+ j = 0;
+ while (dest->getChild("binding", j))
+ j++;
+
+ binding = dest->getChild("binding", j, true);
+ copyProperties(bindings[i], binding);
+ action->addBinding(new SGBinding(binding, globals->get_props()), 0);
+ }
+
+ if (node->hasChild("mod-up")) {
+ bindings = node->getChild("mod-up")->getChildren("binding");
+ for (i = 0; i < bindings.size(); i++) {
+ j = 0;
+ while (dest->getChild("binding", j))
+ j++;
+
+ binding = dest->getChild("binding", j, true);
+ copyProperties(bindings[i], binding);
+ action->addBinding(new SGBinding(binding, globals->get_props()), 1);
+ }
}
readConditions(action, node);
SGPropertyNode * target = 0;
if (type.empty()) {
- SG_LOG( SG_COCKPIT, SG_ALERT,
+ SG_LOG( SG_COCKPIT, SG_INFO,
"No type supplied for transformation " << name
<< " assuming \"rotation\"" );
type = "rotation";
t->node = target;
t->min = node->getFloatValue("min", -9999999);
t->max = node->getFloatValue("max", 99999999);
+ t->has_mod = node->hasChild("modulator");
+ if (t->has_mod)
+ t->mod = node->getFloatValue("modulator");
t->factor = node->getFloatValue("scale", 1.0);
t->offset = node->getFloatValue("offset", 0.0);
const SGPropertyNode * trans_table = node->getNode("interpolation");
if (trans_table != 0) {
SG_LOG( SG_COCKPIT, SG_INFO, "Found interpolation table with "
- << trans_table->nChildren() << "children" );
- t->table = new SGInterpTable();
- for(int i = 0; i < trans_table->nChildren(); i++) {
- const SGPropertyNode * node = trans_table->getChild(i);
- if (!strcmp(node->getName(), "entry")) {
- double ind = node->getDoubleValue("ind", 0.0);
- double dep = node->getDoubleValue("dep", 0.0);
- SG_LOG( SG_COCKPIT, SG_INFO, "Adding interpolation entry "
- << ind << "==>" << dep );
- t->table->addEntry(ind, dep);
- } else {
- SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName()
- << " in interpolation" );
- }
- }
+ << trans_table->nChildren() << " children" );
+ t->table = new SGInterpTable(trans_table);
} else {
t->table = 0;
}
else if (type == "number-value") {
string propName = node->getStringValue("property");
float scale = node->getFloatValue("scale", 1.0);
+ float offset = node->getFloatValue("offset", 0.0);
+ bool truncation = node->getBoolValue("truncate", false);
SGPropertyNode * target = fgGetNode(propName.c_str(), true);
chunk = new FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE, target,
- format, scale);
+ format, scale, offset, truncation);
}
// Unknown type.
string type = node->getStringValue("type");
int w = node->getIntValue("w", -1);
int h = node->getIntValue("h", -1);
+ bool emissive = node->getBoolValue("emissive", false);
if (w != -1)
w = int(w * w_scale);
if (h != -1)
if (type.empty()) {
- SG_LOG( SG_COCKPIT, SG_ALERT,
+ SG_LOG( SG_COCKPIT, SG_INFO,
"No type supplied for layer " << name
<< " assuming \"texture\"" );
type = "texture";
if (type == "texture") {
FGCroppedTexture texture = readTexture(node->getNode("texture"));
layer = new FGTexturedLayer(texture, w, h);
+ if (emissive) {
+ FGTexturedLayer *tl=(FGTexturedLayer*)layer;
+ tl->setEmissive(true);
+ }
+
}
// A group of sublayers.
layer = new FGGroupLayer();
for (int i = 0; i < node->nChildren(); i++) {
const SGPropertyNode * child = node->getChild(i);
- cerr << "Trying child " << child->getName() << endl;
- if (!strcmp(child->getName(), "layer")) {
- cerr << "succeeded!" << endl;
+ if (!strcmp(child->getName(), "layer"))
((FGGroupLayer *)layer)->addLayer(readLayer(child, w_scale, h_scale));
- }
}
}
tlayer->setPointSize(pointSize);
// Set the font.
- string fontName = node->getStringValue("font", "default");
+ string fontName = node->getStringValue("font", "Helvetica");
tlayer->setFontName(fontName);
const SGPropertyNode * chunk_group = node->getNode("chunks");
// A switch instrument layer.
else if (type == "switch") {
- SGPropertyNode * target =
- fgGetNode(node->getStringValue("property"), true);
- FGInstrumentLayer * layer1 =
- readLayer(node->getNode("layer[0]"), w_scale, h_scale);
- FGInstrumentLayer * layer2 =
- readLayer(node->getNode("layer[1]"), w_scale, h_scale);
- layer = new FGSwitchLayer(w, h, target, layer1, layer2);
+ layer = new FGSwitchLayer();
+ for (int i = 0; i < node->nChildren(); i++) {
+ const SGPropertyNode * child = node->getChild(i);
+ if (!strcmp(child->getName(), "layer"))
+ ((FGGroupLayer *)layer)->addLayer(readLayer(child, w_scale, h_scale));
+ }
}
// A built-in instrument layer.
static FGPanelInstrument *
readInstrument (const SGPropertyNode * node)
{
- const string &name = node->getStringValue("name");
+ const string name = node->getStringValue("name");
int x = node->getIntValue("x", -1);
int y = node->getIntValue("y", -1);
int real_w = node->getIntValue("w", -1);
if (!fgHasNode("/sim/panel/y-offset"))
fgSetInt("/sim/panel/y-offset", root->getIntValue("y-offset", 0));
+ panel->setAutohide(root->getBoolValue("autohide", true));
+
//
// Assign the background texture, if any, or a bogus chequerboard.
//
for (int i = 0; i < nInstruments; i++) {
const SGPropertyNode * node = instrument_group->getChild(i);
if (!strcmp(node->getName(), "instrument")) {
- FGPanelInstrument * instrument = readInstrument(node);
- if (instrument != 0)
- panel->addInstrument(instrument);
+ FGPanelInstrument * instrument = readInstrument(node);
+ if (instrument != 0)
+ panel->addInstrument(instrument);
+ } else if (!strcmp(node->getName(), "special-instrument")) {
+ //cout << "Special instrument found in instruments section!\n";
+ const string name = node->getStringValue("name");
+ if (name == "KLN89 GPS") {
+ //cout << "Special instrument is KLN89\n";
+
+ int x = node->getIntValue("x", -1);
+ int y = node->getIntValue("y", -1);
+ int real_w = node->getIntValue("w", -1);
+ int real_h = node->getIntValue("h", -1);
+ int w = node->getIntValue("w-base", -1);
+ int h = node->getIntValue("h-base", -1);
+
+ if (x == -1 || y == -1) {
+ SG_LOG( SG_COCKPIT, SG_ALERT,
+ "x and y positions must be specified and > 0" );
+ return 0;
+ }
+
+ float w_scale = 1.0;
+ float h_scale = 1.0;
+ if (real_w != -1) {
+ w_scale = float(real_w) / float(w);
+ w = real_w;
+ }
+ if (real_h != -1) {
+ h_scale = float(real_h) / float(h);
+ h = real_h;
+ }
+
+ SG_LOG( SG_COCKPIT, SG_DEBUG, "Reading instrument " << name );
+
+ // Warning - hardwired size!!!
+ RenderArea2D* instrument = new RenderArea2D(158, 40, 158, 40, x, y);
+ KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
+ if (gps == NULL) {
+ gps = new KLN89(instrument);
+ globals->add_subsystem("kln89", gps);
+ }
+ //gps->init(); // init seems to get called automagically.
+ FGSpecialInstrument* gpsinst = new FGSpecialInstrument(gps);
+ panel->addInstrument(gpsinst);
+ } else {
+ SG_LOG( SG_COCKPIT, SG_WARN, "Unknown special instrument found" );
+ }
} else {
- SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName()
- << " in instruments section" );
+ SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName()
+ << " in instruments section" );
}
}
}