I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
// fg_props.cxx -- support for FlightGear properties.
|
2001-01-05 17:37:59 +00:00
|
|
|
|
//
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
// Written by David Megginson, started 2000.
|
2001-01-05 17:37:59 +00:00
|
|
|
|
//
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
// Copyright (C) 2000, 2001 David Megginson - david@megginson.com
|
2001-01-05 17:37:59 +00:00
|
|
|
|
//
|
|
|
|
|
// 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.
|
2001-01-05 17:37:59 +00:00
|
|
|
|
//
|
|
|
|
|
// $Id$
|
|
|
|
|
|
2001-04-02 02:59:31 +00:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2006-02-18 13:58:09 +00:00
|
|
|
|
# include "config.h"
|
2001-04-02 02:59:31 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2006-02-18 13:58:09 +00:00
|
|
|
|
#include <simgear/compiler.h>
|
2003-09-24 17:20:55 +00:00
|
|
|
|
#include <simgear/structure/exception.hxx>
|
2008-07-31 12:04:32 +00:00
|
|
|
|
#include <simgear/props/props_io.hxx>
|
|
|
|
|
|
2002-03-16 00:18:38 +00:00
|
|
|
|
#include <simgear/magvar/magvar.hxx>
|
|
|
|
|
#include <simgear/timing/sg_time.hxx>
|
2002-11-06 18:57:31 +00:00
|
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2010-03-27 10:59:04 +00:00
|
|
|
|
#include <simgear/scene/model/particles.hxx>
|
2004-04-24 19:28:12 +00:00
|
|
|
|
#include <simgear/sound/soundmgr_openal.hxx>
|
2001-07-19 04:51:05 +00:00
|
|
|
|
|
2001-06-05 22:13:26 +00:00
|
|
|
|
#include <Aircraft/aircraft.hxx>
|
2008-07-29 08:27:48 +00:00
|
|
|
|
#include <FDM/flight.hxx>
|
2001-07-19 04:51:05 +00:00
|
|
|
|
#include <GUI/gui.h>
|
|
|
|
|
|
2002-01-06 16:51:31 +00:00
|
|
|
|
#include "globals.hxx"
|
2001-01-05 17:37:59 +00:00
|
|
|
|
#include "fg_props.hxx"
|
|
|
|
|
|
|
|
|
|
|
2001-10-05 20:27:43 +00:00
|
|
|
|
static bool winding_ccw = true; // FIXME: temporary
|
2001-07-16 04:35:35 +00:00
|
|
|
|
|
|
|
|
|
static bool fdm_data_logging = false; // FIXME: temporary
|
|
|
|
|
|
2002-04-19 04:00:02 +00:00
|
|
|
|
static bool frozen = false; // FIXME: temporary
|
|
|
|
|
|
2008-07-31 12:04:32 +00:00
|
|
|
|
using std::string;
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Default property bindings (not yet handled by any module).
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2001-11-20 22:03:17 +00:00
|
|
|
|
struct LogClassMapping {
|
|
|
|
|
sgDebugClass c;
|
|
|
|
|
string name;
|
2001-12-09 05:20:13 +00:00
|
|
|
|
LogClassMapping(sgDebugClass cc, string nname) { c = cc; name = nname; }
|
2001-11-20 22:03:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
LogClassMapping log_class_mappings [] = {
|
2001-12-09 05:20:13 +00:00
|
|
|
|
LogClassMapping(SG_NONE, "none"),
|
|
|
|
|
LogClassMapping(SG_TERRAIN, "terrain"),
|
|
|
|
|
LogClassMapping(SG_ASTRO, "astro"),
|
|
|
|
|
LogClassMapping(SG_FLIGHT, "flight"),
|
|
|
|
|
LogClassMapping(SG_INPUT, "input"),
|
|
|
|
|
LogClassMapping(SG_GL, "gl"),
|
|
|
|
|
LogClassMapping(SG_VIEW, "view"),
|
|
|
|
|
LogClassMapping(SG_COCKPIT, "cockpit"),
|
|
|
|
|
LogClassMapping(SG_GENERAL, "general"),
|
|
|
|
|
LogClassMapping(SG_MATH, "math"),
|
|
|
|
|
LogClassMapping(SG_EVENT, "event"),
|
|
|
|
|
LogClassMapping(SG_AIRCRAFT, "aircraft"),
|
|
|
|
|
LogClassMapping(SG_AUTOPILOT, "autopilot"),
|
|
|
|
|
LogClassMapping(SG_IO, "io"),
|
|
|
|
|
LogClassMapping(SG_CLIPPER, "clipper"),
|
|
|
|
|
LogClassMapping(SG_NETWORK, "network"),
|
2004-10-24 11:05:14 +00:00
|
|
|
|
LogClassMapping(SG_INSTR, "instrumentation"),
|
|
|
|
|
LogClassMapping(SG_SYSTEMS, "systems"),
|
2001-12-09 05:20:13 +00:00
|
|
|
|
LogClassMapping(SG_UNDEFD, "")
|
2001-11-20 22:03:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the logging classes.
|
|
|
|
|
*/
|
2009-12-30 16:34:58 +00:00
|
|
|
|
// XXX Making the result buffer be global is a band-aid that hopefully
|
|
|
|
|
// delays its destruction 'til after its last use.
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
string loggingResult;
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-19 17:12:13 +00:00
|
|
|
|
static const char *
|
2001-11-20 22:03:17 +00:00
|
|
|
|
getLoggingClasses ()
|
|
|
|
|
{
|
|
|
|
|
sgDebugClass classes = logbuf::get_log_classes();
|
2009-12-30 16:34:58 +00:00
|
|
|
|
loggingResult.clear();
|
2001-11-20 22:03:17 +00:00
|
|
|
|
for (int i = 0; log_class_mappings[i].c != SG_UNDEFD; i++) {
|
|
|
|
|
if ((classes&log_class_mappings[i].c) > 0) {
|
2009-12-30 16:34:58 +00:00
|
|
|
|
if (!loggingResult.empty())
|
|
|
|
|
loggingResult += '|';
|
|
|
|
|
loggingResult += log_class_mappings[i].name;
|
2001-11-20 22:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-12-30 16:34:58 +00:00
|
|
|
|
return loggingResult.c_str();
|
2001-11-20 22:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-03-19 17:12:13 +00:00
|
|
|
|
static void
|
|
|
|
|
addLoggingClass (const string &name)
|
2001-11-20 22:03:17 +00:00
|
|
|
|
{
|
|
|
|
|
sgDebugClass classes = logbuf::get_log_classes();
|
|
|
|
|
for (int i = 0; log_class_mappings[i].c != SG_UNDEFD; i++) {
|
|
|
|
|
if (name == log_class_mappings[i].name) {
|
|
|
|
|
logbuf::set_log_classes(sgDebugClass(classes|log_class_mappings[i].c));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Unknown logging class: " << name);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the logging classes.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
setLoggingClasses (const char * c)
|
2001-11-20 22:03:17 +00:00
|
|
|
|
{
|
2002-03-19 17:12:13 +00:00
|
|
|
|
string classes = c;
|
2001-11-20 22:03:17 +00:00
|
|
|
|
logbuf::set_log_classes(SG_NONE);
|
|
|
|
|
|
|
|
|
|
if (classes == "none") {
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Disabled all logging classes");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-20 19:16:13 +00:00
|
|
|
|
if (classes.empty() || classes == "all") { // default
|
2001-11-20 22:03:17 +00:00
|
|
|
|
logbuf::set_log_classes(SG_ALL);
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Enabled all logging classes: "
|
|
|
|
|
<< getLoggingClasses());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string rest = classes;
|
|
|
|
|
string name = "";
|
|
|
|
|
int sep = rest.find('|');
|
|
|
|
|
while (sep > 0) {
|
|
|
|
|
name = rest.substr(0, sep);
|
|
|
|
|
rest = rest.substr(sep+1);
|
|
|
|
|
addLoggingClass(name);
|
|
|
|
|
sep = rest.find('|');
|
|
|
|
|
}
|
|
|
|
|
addLoggingClass(rest);
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Set logging classes to "
|
|
|
|
|
<< getLoggingClasses());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the logging priority.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
static const char *
|
2001-11-20 22:03:17 +00:00
|
|
|
|
getLoggingPriority ()
|
|
|
|
|
{
|
|
|
|
|
switch (logbuf::get_log_priority()) {
|
|
|
|
|
case SG_BULK:
|
|
|
|
|
return "bulk";
|
|
|
|
|
case SG_DEBUG:
|
|
|
|
|
return "debug";
|
|
|
|
|
case SG_INFO:
|
|
|
|
|
return "info";
|
|
|
|
|
case SG_WARN:
|
|
|
|
|
return "warn";
|
|
|
|
|
case SG_ALERT:
|
|
|
|
|
return "alert";
|
|
|
|
|
default:
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Internal: Unknown logging priority number: "
|
|
|
|
|
<< logbuf::get_log_priority());
|
|
|
|
|
return "unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the logging priority.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
setLoggingPriority (const char * p)
|
2001-11-20 22:03:17 +00:00
|
|
|
|
{
|
2003-11-25 17:10:36 +00:00
|
|
|
|
if (p == 0)
|
|
|
|
|
return;
|
2002-03-19 17:12:13 +00:00
|
|
|
|
string priority = p;
|
2001-11-20 22:03:17 +00:00
|
|
|
|
if (priority == "bulk") {
|
|
|
|
|
logbuf::set_log_priority(SG_BULK);
|
|
|
|
|
} else if (priority == "debug") {
|
|
|
|
|
logbuf::set_log_priority(SG_DEBUG);
|
2002-03-20 19:16:13 +00:00
|
|
|
|
} else if (priority.empty() || priority == "info") { // default
|
2001-11-20 22:03:17 +00:00
|
|
|
|
logbuf::set_log_priority(SG_INFO);
|
|
|
|
|
} else if (priority == "warn") {
|
|
|
|
|
logbuf::set_log_priority(SG_WARN);
|
|
|
|
|
} else if (priority == "alert") {
|
|
|
|
|
logbuf::set_log_priority(SG_ALERT);
|
|
|
|
|
} else {
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Unknown logging priority " << priority);
|
|
|
|
|
}
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Logging priority is " << getLoggingPriority());
|
2001-11-20 22:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-06-26 21:59:59 +00:00
|
|
|
|
|
2002-04-19 04:00:02 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the current frozen state.
|
|
|
|
|
*/
|
|
|
|
|
static bool
|
|
|
|
|
getFreeze ()
|
|
|
|
|
{
|
|
|
|
|
return frozen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the current frozen state.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
setFreeze (bool f)
|
|
|
|
|
{
|
2002-12-11 21:07:30 +00:00
|
|
|
|
frozen = f;
|
|
|
|
|
|
|
|
|
|
// Stop sound on a pause
|
2009-10-24 08:31:37 +00:00
|
|
|
|
SGSoundMgr *smgr = globals->get_soundmgr();
|
2009-10-04 13:52:53 +00:00
|
|
|
|
if ( smgr != NULL ) {
|
2002-12-11 21:07:30 +00:00
|
|
|
|
if ( f ) {
|
2009-10-04 13:52:53 +00:00
|
|
|
|
smgr->suspend();
|
2009-11-30 12:05:20 +00:00
|
|
|
|
} else if (fgGetBool("/sim/sound/working")) {
|
2009-10-04 13:52:53 +00:00
|
|
|
|
smgr->resume();
|
2002-12-11 21:07:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2010-03-27 10:59:04 +00:00
|
|
|
|
|
|
|
|
|
// Pause the particle system
|
|
|
|
|
simgear::Particles::setFrozen(f);
|
2002-04-19 04:00:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-03-12 16:29:32 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the number of milliseconds elapsed since simulation started.
|
|
|
|
|
*/
|
2002-04-20 14:52:43 +00:00
|
|
|
|
static double
|
2002-05-11 16:28:50 +00:00
|
|
|
|
getElapsedTime_sec ()
|
2002-03-12 16:29:32 +00:00
|
|
|
|
{
|
2002-05-11 16:28:50 +00:00
|
|
|
|
return globals->get_sim_time_sec();
|
2002-03-12 16:29:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-06-05 22:13:26 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the current Zulu time.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
static const char *
|
2001-06-05 22:13:26 +00:00
|
|
|
|
getDateString ()
|
|
|
|
|
{
|
2002-04-07 21:20:16 +00:00
|
|
|
|
static char buf[64]; // FIXME
|
2001-06-05 22:13:26 +00:00
|
|
|
|
struct tm * t = globals->get_time_params()->getGmt();
|
|
|
|
|
sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
|
|
|
|
|
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
|
|
|
|
t->tm_hour, t->tm_min, t->tm_sec);
|
2002-04-07 21:20:16 +00:00
|
|
|
|
return buf;
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the current Zulu time.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
setDateString (const char * date_string)
|
2001-06-05 22:13:26 +00:00
|
|
|
|
{
|
2002-02-11 23:33:20 +00:00
|
|
|
|
static const SGPropertyNode *cur_time_override
|
|
|
|
|
= fgGetNode("/sim/time/cur-time-override", true);
|
|
|
|
|
|
2001-06-05 22:13:26 +00:00
|
|
|
|
SGTime * st = globals->get_time_params();
|
|
|
|
|
struct tm * current_time = st->getGmt();
|
|
|
|
|
struct tm new_time;
|
|
|
|
|
|
|
|
|
|
// Scan for basic ISO format
|
|
|
|
|
// YYYY-MM-DDTHH:MM:SS
|
2002-03-19 17:12:13 +00:00
|
|
|
|
int ret = sscanf(date_string, "%d-%d-%dT%d:%d:%d",
|
2001-06-05 22:13:26 +00:00
|
|
|
|
&(new_time.tm_year), &(new_time.tm_mon),
|
|
|
|
|
&(new_time.tm_mday), &(new_time.tm_hour),
|
|
|
|
|
&(new_time.tm_min), &(new_time.tm_sec));
|
|
|
|
|
|
|
|
|
|
// Be pretty picky about this, so
|
|
|
|
|
// that strange things don't happen
|
|
|
|
|
// if the save file has been edited
|
|
|
|
|
// by hand.
|
|
|
|
|
if (ret != 6) {
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_INPUT, SG_WARN, "Date/time string " << date_string
|
2001-06-05 22:13:26 +00:00
|
|
|
|
<< " not in YYYY-MM-DDTHH:MM:SS format; skipped");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OK, it looks like we got six
|
|
|
|
|
// values, one way or another.
|
|
|
|
|
new_time.tm_year -= 1900;
|
|
|
|
|
new_time.tm_mon -= 1;
|
|
|
|
|
|
|
|
|
|
// Now, tell flight gear to use
|
|
|
|
|
// the new time. This was far
|
|
|
|
|
// too difficult, by the way.
|
|
|
|
|
long int warp =
|
|
|
|
|
mktime(&new_time) - mktime(current_time) + globals->get_warp();
|
|
|
|
|
double lon = current_aircraft.fdm_state->get_Longitude();
|
|
|
|
|
double lat = current_aircraft.fdm_state->get_Latitude();
|
|
|
|
|
globals->set_warp(warp);
|
2002-02-11 23:33:20 +00:00
|
|
|
|
st->update(lon, lat, cur_time_override->getLongValue(), warp);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the GMT as a string.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
static const char *
|
2001-06-05 22:13:26 +00:00
|
|
|
|
getGMTString ()
|
|
|
|
|
{
|
2006-06-17 18:25:12 +00:00
|
|
|
|
static char buf[16];
|
2002-02-11 23:33:20 +00:00
|
|
|
|
struct tm *t = globals->get_time_params()->getGmt();
|
2006-06-17 18:25:12 +00:00
|
|
|
|
snprintf(buf, 16, "%.2d:%.2d:%.2d",
|
|
|
|
|
t->tm_hour, t->tm_min, t->tm_sec);
|
2002-04-07 21:20:16 +00:00
|
|
|
|
return buf;
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the magnetic variation
|
|
|
|
|
*/
|
|
|
|
|
static double
|
|
|
|
|
getMagVar ()
|
|
|
|
|
{
|
|
|
|
|
return globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the magnetic dip
|
|
|
|
|
*/
|
|
|
|
|
static double
|
|
|
|
|
getMagDip ()
|
|
|
|
|
{
|
|
|
|
|
return globals->get_mag()->get_magdip() * SGD_RADIANS_TO_DEGREES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the current heading in degrees.
|
|
|
|
|
*/
|
|
|
|
|
static double
|
|
|
|
|
getHeadingMag ()
|
|
|
|
|
{
|
2003-07-01 08:19:41 +00:00
|
|
|
|
double magheading;
|
|
|
|
|
magheading = current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES - getMagVar();
|
|
|
|
|
if (magheading < 0) magheading += 360;
|
|
|
|
|
return magheading;
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-01-03 09:49:28 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the current track in degrees.
|
|
|
|
|
*/
|
|
|
|
|
static double
|
|
|
|
|
getTrackMag ()
|
|
|
|
|
{
|
|
|
|
|
double magtrack;
|
|
|
|
|
magtrack = current_aircraft.fdm_state->get_Track() - getMagVar();
|
|
|
|
|
if (magtrack < 0) magtrack += 360;
|
|
|
|
|
return magtrack;
|
|
|
|
|
}
|
|
|
|
|
|
2001-06-26 21:59:59 +00:00
|
|
|
|
static long
|
|
|
|
|
getWarp ()
|
|
|
|
|
{
|
|
|
|
|
return globals->get_warp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setWarp (long warp)
|
|
|
|
|
{
|
|
|
|
|
globals->set_warp(warp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static long
|
|
|
|
|
getWarpDelta ()
|
|
|
|
|
{
|
|
|
|
|
return globals->get_warp_delta();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setWarpDelta (long delta)
|
|
|
|
|
{
|
|
|
|
|
globals->set_warp_delta(delta);
|
|
|
|
|
}
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
2001-07-16 04:35:35 +00:00
|
|
|
|
static bool
|
|
|
|
|
getWindingCCW ()
|
|
|
|
|
{
|
|
|
|
|
return winding_ccw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setWindingCCW (bool state)
|
|
|
|
|
{
|
|
|
|
|
winding_ccw = state;
|
|
|
|
|
if ( winding_ccw )
|
|
|
|
|
glFrontFace ( GL_CCW );
|
|
|
|
|
else
|
|
|
|
|
glFrontFace ( GL_CW );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
getFDMDataLogging ()
|
|
|
|
|
{
|
|
|
|
|
return fdm_data_logging;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setFDMDataLogging (bool state)
|
|
|
|
|
{
|
|
|
|
|
// kludge; no getter or setter available
|
|
|
|
|
if (state != fdm_data_logging) {
|
|
|
|
|
fgToggleFDMdataLogging();
|
|
|
|
|
fdm_data_logging = state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-06-17 16:33:00 +00:00
|
|
|
|
static const char *
|
|
|
|
|
getLongitudeString ()
|
|
|
|
|
{
|
|
|
|
|
static SGConstPropertyNode_ptr n = fgGetNode("/position/longitude-deg", true);
|
|
|
|
|
static SGConstPropertyNode_ptr f = fgGetNode("/sim/lon-lat-format", true);
|
|
|
|
|
static char buf[32];
|
|
|
|
|
double d = n->getDoubleValue();
|
|
|
|
|
int format = f->getIntValue();
|
2006-06-17 18:08:53 +00:00
|
|
|
|
char c = d < 0.0 ? 'W' : 'E';
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
if (format == 0) {
|
2006-06-17 18:08:53 +00:00
|
|
|
|
snprintf(buf, 32, "%3.6f%c", d, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
} else if (format == 1) {
|
|
|
|
|
// dd mm.mmm' (DMM-Format) -- uses a round-off factor tailored to the
|
|
|
|
|
// required precision of the minutes field (three decimal places),
|
|
|
|
|
// preventing minute values of 60.
|
|
|
|
|
double deg = fabs(d) + 5.0E-4 / 60.0;
|
|
|
|
|
double min = fabs(deg - int(deg)) * 60.0 - 4.999E-4;
|
2006-06-17 18:08:53 +00:00
|
|
|
|
snprintf(buf, 32, "%d*%06.3f%c", int(d < 0.0 ? -deg : deg), min, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// mm'ss.s'' (DMS-Format) -- uses a round-off factor tailored to the
|
|
|
|
|
// required precision of the seconds field (one decimal place),
|
|
|
|
|
// preventing second values of 60.
|
|
|
|
|
double deg = fabs(d) + 0.05 / 3600.0;
|
|
|
|
|
double min = (deg - int(deg)) * 60.0;
|
|
|
|
|
double sec = (min - int(min)) * 60.0 - 0.049;
|
|
|
|
|
snprintf(buf, 32, "%d*%02d %04.1f%c", int(d < 0.0 ? -deg : deg),
|
2006-06-17 18:08:53 +00:00
|
|
|
|
int(min), fabs(sec), c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
}
|
2007-10-27 17:16:00 +00:00
|
|
|
|
buf[31] = '\0';
|
2006-06-17 16:33:00 +00:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
getLatitudeString ()
|
|
|
|
|
{
|
|
|
|
|
static SGConstPropertyNode_ptr n = fgGetNode("/position/latitude-deg", true);
|
|
|
|
|
static SGConstPropertyNode_ptr f = fgGetNode("/sim/lon-lat-format", true);
|
|
|
|
|
static char buf[32];
|
|
|
|
|
double d = n->getDoubleValue();
|
|
|
|
|
int format = f->getIntValue();
|
2006-06-17 18:08:53 +00:00
|
|
|
|
char c = d < 0.0 ? 'S' : 'N';
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
if (format == 0) {
|
2006-06-17 18:08:53 +00:00
|
|
|
|
snprintf(buf, 32, "%3.6f%c", d, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
} else if (format == 1) {
|
|
|
|
|
double deg = fabs(d) + 5.0E-4 / 60.0;
|
|
|
|
|
double min = fabs(deg - int(deg)) * 60.0 - 4.999E-4;
|
2006-06-17 18:08:53 +00:00
|
|
|
|
snprintf(buf, 32, "%d*%06.3f%c", int(d < 0.0 ? -deg : deg), min, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
double deg = fabs(d) + 0.05 / 3600.0;
|
|
|
|
|
double min = (deg - int(deg)) * 60.0;
|
|
|
|
|
double sec = (min - int(min)) * 60.0 - 0.049;
|
|
|
|
|
snprintf(buf, 32, "%d*%02d %04.1f%c", int(d < 0.0 ? -deg : deg),
|
2006-06-17 18:08:53 +00:00
|
|
|
|
int(min), fabs(sec), c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
}
|
2007-10-27 17:16:00 +00:00
|
|
|
|
buf[31] = '\0';
|
2006-06-17 16:33:00 +00:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-07-16 04:35:35 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Tie the properties.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
2004-02-20 17:35:33 +00:00
|
|
|
|
FGProperties::FGProperties ()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FGProperties::~FGProperties ()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2001-06-05 22:13:26 +00:00
|
|
|
|
void
|
2004-02-20 17:35:33 +00:00
|
|
|
|
FGProperties::init ()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
FGProperties::bind ()
|
2001-06-05 22:13:26 +00:00
|
|
|
|
{
|
|
|
|
|
// Simulation
|
2001-11-20 22:03:17 +00:00
|
|
|
|
fgTie("/sim/logging/priority", getLoggingPriority, setLoggingPriority);
|
|
|
|
|
fgTie("/sim/logging/classes", getLoggingClasses, setLoggingClasses);
|
2002-04-19 04:00:02 +00:00
|
|
|
|
fgTie("/sim/freeze/master", getFreeze, setFreeze);
|
2002-03-14 00:29:20 +00:00
|
|
|
|
|
2002-05-11 16:28:50 +00:00
|
|
|
|
fgTie("/sim/time/elapsed-sec", getElapsedTime_sec);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
fgTie("/sim/time/gmt", getDateString, setDateString);
|
2001-07-12 23:35:56 +00:00
|
|
|
|
fgSetArchivable("/sim/time/gmt");
|
2001-06-05 22:13:26 +00:00
|
|
|
|
fgTie("/sim/time/gmt-string", getGMTString);
|
|
|
|
|
|
2006-06-17 16:33:00 +00:00
|
|
|
|
// Position
|
|
|
|
|
fgTie("/position/latitude-string", getLatitudeString);
|
|
|
|
|
fgTie("/position/longitude-string", getLongitudeString);
|
|
|
|
|
|
2001-06-05 22:13:26 +00:00
|
|
|
|
// Orientation
|
2001-07-02 22:27:24 +00:00
|
|
|
|
fgTie("/orientation/heading-magnetic-deg", getHeadingMag);
|
2010-01-03 09:49:28 +00:00
|
|
|
|
fgTie("/orientation/track-magnetic-deg", getTrackMag);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
2001-07-02 22:27:24 +00:00
|
|
|
|
fgTie("/environment/magnetic-variation-deg", getMagVar);
|
|
|
|
|
fgTie("/environment/magnetic-dip-deg", getMagDip);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
2001-07-02 16:44:02 +00:00
|
|
|
|
fgTie("/sim/time/warp", getWarp, setWarp, false);
|
2001-06-26 21:59:59 +00:00
|
|
|
|
fgTie("/sim/time/warp-delta", getWarpDelta, setWarpDelta);
|
2001-07-16 04:35:35 +00:00
|
|
|
|
|
|
|
|
|
// Misc. Temporary junk.
|
2001-10-05 20:27:43 +00:00
|
|
|
|
fgTie("/sim/temp/winding-ccw", getWindingCCW, setWindingCCW, false);
|
2001-07-16 04:35:35 +00:00
|
|
|
|
fgTie("/sim/temp/fdm-data-logging", getFDMDataLogging, setFDMDataLogging);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2004-02-20 17:35:33 +00:00
|
|
|
|
FGProperties::unbind ()
|
2001-06-05 22:13:26 +00:00
|
|
|
|
{
|
2004-02-20 17:35:33 +00:00
|
|
|
|
// Simulation
|
|
|
|
|
fgUntie("/sim/logging/priority");
|
|
|
|
|
fgUntie("/sim/logging/classes");
|
|
|
|
|
fgUntie("/sim/freeze/master");
|
|
|
|
|
|
|
|
|
|
fgUntie("/sim/time/elapsed-sec");
|
|
|
|
|
fgUntie("/sim/time/gmt");
|
|
|
|
|
fgUntie("/sim/time/gmt-string");
|
2006-06-17 16:33:00 +00:00
|
|
|
|
// Position
|
|
|
|
|
fgUntie("/position/latitude-string");
|
|
|
|
|
fgUntie("/position/longitude-string");
|
2004-02-20 17:35:33 +00:00
|
|
|
|
|
|
|
|
|
// Orientation
|
|
|
|
|
fgUntie("/orientation/heading-magnetic-deg");
|
2010-01-03 09:49:28 +00:00
|
|
|
|
fgUntie("/orientation/track-magnetic-deg");
|
2004-02-20 17:35:33 +00:00
|
|
|
|
|
|
|
|
|
// Environment
|
|
|
|
|
fgUntie("/environment/magnetic-variation-deg");
|
|
|
|
|
fgUntie("/environment/magnetic-dip-deg");
|
|
|
|
|
|
|
|
|
|
fgUntie("/sim/time/warp");
|
|
|
|
|
fgUntie("/sim/time/warp-delta");
|
|
|
|
|
|
|
|
|
|
// Misc. Temporary junk.
|
|
|
|
|
fgUntie("/sim/temp/winding-ccw");
|
|
|
|
|
fgUntie("/sim/temp/full-screen");
|
|
|
|
|
fgUntie("/sim/temp/fdm-data-logging");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
FGProperties::update (double dt)
|
|
|
|
|
{
|
2009-02-15 22:49:51 +00:00
|
|
|
|
static SGPropertyNode_ptr offset = fgGetNode("/sim/time/local-offset", true);
|
|
|
|
|
offset->setIntValue(globals->get_time_params()->get_local_offset());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// utc date/time
|
|
|
|
|
static SGPropertyNode_ptr uyear = fgGetNode("/sim/time/utc/year", true);
|
|
|
|
|
static SGPropertyNode_ptr umonth = fgGetNode("/sim/time/utc/month", true);
|
|
|
|
|
static SGPropertyNode_ptr uday = fgGetNode("/sim/time/utc/day", true);
|
|
|
|
|
static SGPropertyNode_ptr uhour = fgGetNode("/sim/time/utc/hour", true);
|
|
|
|
|
static SGPropertyNode_ptr umin = fgGetNode("/sim/time/utc/minute", true);
|
|
|
|
|
static SGPropertyNode_ptr usec = fgGetNode("/sim/time/utc/second", true);
|
|
|
|
|
static SGPropertyNode_ptr uwday = fgGetNode("/sim/time/utc/weekday", true);
|
|
|
|
|
static SGPropertyNode_ptr udsec = fgGetNode("/sim/time/utc/day-seconds", true);
|
|
|
|
|
|
|
|
|
|
struct tm *u = globals->get_time_params()->getGmt();
|
|
|
|
|
uyear->setIntValue(u->tm_year + 1900);
|
|
|
|
|
umonth->setIntValue(u->tm_mon + 1);
|
|
|
|
|
uday->setIntValue(u->tm_mday);
|
|
|
|
|
uhour->setIntValue(u->tm_hour);
|
|
|
|
|
umin->setIntValue(u->tm_min);
|
|
|
|
|
usec->setIntValue(u->tm_sec);
|
|
|
|
|
uwday->setIntValue(u->tm_wday);
|
|
|
|
|
|
|
|
|
|
udsec->setIntValue(u->tm_hour * 3600 + u->tm_min * 60 + u->tm_sec);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// real local date/time
|
|
|
|
|
static SGPropertyNode_ptr ryear = fgGetNode("/sim/time/real/year", true);
|
|
|
|
|
static SGPropertyNode_ptr rmonth = fgGetNode("/sim/time/real/month", true);
|
|
|
|
|
static SGPropertyNode_ptr rday = fgGetNode("/sim/time/real/day", true);
|
|
|
|
|
static SGPropertyNode_ptr rhour = fgGetNode("/sim/time/real/hour", true);
|
|
|
|
|
static SGPropertyNode_ptr rmin = fgGetNode("/sim/time/real/minute", true);
|
|
|
|
|
static SGPropertyNode_ptr rsec = fgGetNode("/sim/time/real/second", true);
|
|
|
|
|
static SGPropertyNode_ptr rwday = fgGetNode("/sim/time/real/weekday", true);
|
|
|
|
|
|
|
|
|
|
time_t real = time(0);
|
|
|
|
|
struct tm *r = localtime(&real);
|
|
|
|
|
ryear->setIntValue(r->tm_year + 1900);
|
|
|
|
|
rmonth->setIntValue(r->tm_mon + 1);
|
|
|
|
|
rday->setIntValue(r->tm_mday);
|
|
|
|
|
rhour->setIntValue(r->tm_hour);
|
|
|
|
|
rmin->setIntValue(r->tm_min);
|
|
|
|
|
rsec->setIntValue(r->tm_sec);
|
|
|
|
|
rwday->setIntValue(r->tm_wday);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Save and restore.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Save the current state of the simulator to a stream.
|
|
|
|
|
*/
|
|
|
|
|
bool
|
2008-07-31 12:04:32 +00:00
|
|
|
|
fgSaveFlight (std::ostream &output, bool write_all)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
2002-03-14 14:25:30 +00:00
|
|
|
|
|
2002-11-15 21:13:29 +00:00
|
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
|
fgSetArchivable("/sim/presets/onground");
|
|
|
|
|
fgSetBool("/sim/presets/trim", false);
|
|
|
|
|
fgSetArchivable("/sim/presets/trim");
|
|
|
|
|
fgSetString("/sim/presets/speed-set", "UVW");
|
|
|
|
|
fgSetArchivable("/sim/presets/speed-set");
|
2002-03-14 14:25:30 +00:00
|
|
|
|
|
2001-07-19 04:51:05 +00:00
|
|
|
|
try {
|
2002-03-03 22:48:40 +00:00
|
|
|
|
writeProperties(output, globals->get_props(), write_all);
|
2001-07-24 23:51:47 +00:00
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
|
guiErrorMessage("Error saving flight: ", e);
|
2001-07-19 04:51:05 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2001-01-05 17:37:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Restore the current state of the simulator from a stream.
|
|
|
|
|
*/
|
|
|
|
|
bool
|
2008-07-31 12:04:32 +00:00
|
|
|
|
fgLoadFlight (std::istream &input)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
2001-01-19 22:57:24 +00:00
|
|
|
|
SGPropertyNode props;
|
2001-07-19 04:51:05 +00:00
|
|
|
|
try {
|
|
|
|
|
readProperties(input, &props);
|
2001-07-24 23:51:47 +00:00
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
|
guiErrorMessage("Error reading saved flight: ", e);
|
2001-01-19 22:57:24 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2002-03-14 14:25:30 +00:00
|
|
|
|
|
2002-11-15 21:13:29 +00:00
|
|
|
|
fgSetBool("/sim/presets/onground", false);
|
|
|
|
|
fgSetBool("/sim/presets/trim", false);
|
|
|
|
|
fgSetString("/sim/presets/speed-set", "UVW");
|
2002-03-14 14:25:30 +00:00
|
|
|
|
|
2001-07-19 04:51:05 +00:00
|
|
|
|
copyProperties(&props, globals->get_props());
|
|
|
|
|
// When loading a flight, make it the
|
|
|
|
|
// new initial state.
|
|
|
|
|
globals->saveInitialState();
|
2001-05-18 20:30:36 +00:00
|
|
|
|
return true;
|
2001-01-05 17:37:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-08-03 00:19:41 +00:00
|
|
|
|
|
2003-01-21 02:08:00 +00:00
|
|
|
|
bool
|
2005-12-17 15:34:37 +00:00
|
|
|
|
fgLoadProps (const char * path, SGPropertyNode * props, bool in_fg_root, int default_mode)
|
2003-01-21 02:08:00 +00:00
|
|
|
|
{
|
|
|
|
|
string fullpath;
|
|
|
|
|
if (in_fg_root) {
|
|
|
|
|
SGPath loadpath(globals->get_fg_root());
|
|
|
|
|
loadpath.append(path);
|
|
|
|
|
fullpath = loadpath.str();
|
|
|
|
|
} else {
|
|
|
|
|
fullpath = path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2005-12-17 15:34:37 +00:00
|
|
|
|
readProperties(fullpath, props, default_mode);
|
2003-01-21 02:08:00 +00:00
|
|
|
|
} catch (const sg_exception &e) {
|
|
|
|
|
guiErrorMessage("Error reading properties: ", e);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2002-11-06 18:57:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-03-19 17:12:13 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Property convenience functions.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
SGPropertyNode *
|
|
|
|
|
fgGetNode (const char * path, bool create)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getNode(path, create);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SGPropertyNode *
|
|
|
|
|
fgGetNode (const char * path, int index, bool create)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getNode(path, index, create);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgHasNode (const char * path)
|
|
|
|
|
{
|
|
|
|
|
return (fgGetNode(path, false) != 0);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-18 03:27:21 +00:00
|
|
|
|
void
|
|
|
|
|
fgAddChangeListener (SGPropertyChangeListener * listener, const char * path)
|
|
|
|
|
{
|
|
|
|
|
fgGetNode(path, true)->addChangeListener(listener);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fgAddChangeListener (SGPropertyChangeListener * listener,
|
|
|
|
|
const char * path, int index)
|
|
|
|
|
{
|
|
|
|
|
fgGetNode(path, index, true)->addChangeListener(listener);
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-19 17:12:13 +00:00
|
|
|
|
bool
|
|
|
|
|
fgGetBool (const char * name, bool defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getBoolValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fgGetInt (const char * name, int defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getIntValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fgGetLong (const char * name, long defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getLongValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float
|
|
|
|
|
fgGetFloat (const char * name, float defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getFloatValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
fgGetDouble (const char * name, double defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getDoubleValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
fgGetString (const char * name, const char * defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->getStringValue(name, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetBool (const char * name, bool val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setBoolValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetInt (const char * name, int val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setIntValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetLong (const char * name, long val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setLongValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetFloat (const char * name, float val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setFloatValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetDouble (const char * name, double val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setDoubleValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
fgSetString (const char * name, const char * val)
|
|
|
|
|
{
|
|
|
|
|
return globals->get_props()->setStringValue(name, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fgSetArchivable (const char * name, bool state)
|
|
|
|
|
{
|
|
|
|
|
SGPropertyNode * node = globals->get_props()->getNode(name);
|
|
|
|
|
if (node == 0)
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2002-03-19 17:12:13 +00:00
|
|
|
|
"Attempt to set archive flag for non-existant property "
|
|
|
|
|
<< name);
|
|
|
|
|
else
|
|
|
|
|
node->setAttribute(SGPropertyNode::ARCHIVE, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fgSetReadable (const char * name, bool state)
|
|
|
|
|
{
|
|
|
|
|
SGPropertyNode * node = globals->get_props()->getNode(name);
|
|
|
|
|
if (node == 0)
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2002-03-19 17:12:13 +00:00
|
|
|
|
"Attempt to set read flag for non-existant property "
|
|
|
|
|
<< name);
|
|
|
|
|
else
|
|
|
|
|
node->setAttribute(SGPropertyNode::READ, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fgSetWritable (const char * name, bool state)
|
|
|
|
|
{
|
|
|
|
|
SGPropertyNode * node = globals->get_props()->getNode(name);
|
|
|
|
|
if (node == 0)
|
2003-11-25 17:10:36 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_DEBUG,
|
2002-03-19 17:12:13 +00:00
|
|
|
|
"Attempt to set write flag for non-existant property "
|
|
|
|
|
<< name);
|
|
|
|
|
else
|
|
|
|
|
node->setAttribute(SGPropertyNode::WRITE, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fgUntie (const char * name)
|
|
|
|
|
{
|
|
|
|
|
if (!globals->get_props()->untie(name))
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Failed to untie property " << name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
// end of fg_props.cxx
|