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/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>
|
2016-07-06 11:27:14 +00:00
|
|
|
|
#include <simgear/sound/soundmgr.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"
|
|
|
|
|
|
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"),
|
2011-08-11 22:09:26 +00:00
|
|
|
|
LogClassMapping(SG_ATC, "atc"),
|
|
|
|
|
LogClassMapping(SG_NASAL, "nasal"),
|
2004-10-24 11:05:14 +00:00
|
|
|
|
LogClassMapping(SG_SYSTEMS, "systems"),
|
2011-08-11 22:09:26 +00:00
|
|
|
|
LogClassMapping(SG_AI, "ai"),
|
|
|
|
|
LogClassMapping(SG_ENVIRONMENT, "environment"),
|
|
|
|
|
LogClassMapping(SG_SOUND, "sound"),
|
2012-11-23 20:14:40 +00:00
|
|
|
|
LogClassMapping(SG_NAVAID, "navaid"),
|
2014-05-31 00:43:03 +00:00
|
|
|
|
LogClassMapping(SG_GUI, "gui"),
|
2016-01-16 21:48:50 +00:00
|
|
|
|
LogClassMapping(SG_TERRASYNC, "terrasync"),
|
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 ()
|
|
|
|
|
{
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sgDebugClass classes = sglog().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
|
|
|
|
{
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sgDebugClass classes = sglog().get_log_classes();
|
2001-11-20 22:03:17 +00:00
|
|
|
|
for (int i = 0; log_class_mappings[i].c != SG_UNDEFD; i++) {
|
|
|
|
|
if (name == log_class_mappings[i].name) {
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_classes(sgDebugClass(classes|log_class_mappings[i].c));
|
2001-11-20 22:03:17 +00:00
|
|
|
|
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.
|
|
|
|
|
*/
|
2011-12-11 12:55:56 +00:00
|
|
|
|
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;
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_classes(SG_NONE);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
|
|
|
|
|
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
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_classes(SG_ALL);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_INFO, "Enabled all logging classes: "
|
|
|
|
|
<< getLoggingClasses());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string rest = classes;
|
|
|
|
|
string name = "";
|
2011-12-11 12:55:56 +00:00
|
|
|
|
string::size_type sep = rest.find('|');
|
|
|
|
|
if (sep == string::npos)
|
|
|
|
|
sep = rest.find(',');
|
|
|
|
|
while (sep != string::npos) {
|
2001-11-20 22:03:17 +00:00
|
|
|
|
name = rest.substr(0, sep);
|
|
|
|
|
rest = rest.substr(sep+1);
|
|
|
|
|
addLoggingClass(name);
|
|
|
|
|
sep = rest.find('|');
|
2011-12-11 12:55:56 +00:00
|
|
|
|
if (sep == string::npos)
|
|
|
|
|
sep = rest.find(',');
|
2001-11-20 22:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
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 ()
|
|
|
|
|
{
|
2013-02-06 18:05:45 +00:00
|
|
|
|
switch (sglog().get_log_priority()) {
|
2001-11-20 22:03:17 +00:00
|
|
|
|
case SG_BULK:
|
|
|
|
|
return "bulk";
|
|
|
|
|
case SG_DEBUG:
|
|
|
|
|
return "debug";
|
|
|
|
|
case SG_INFO:
|
|
|
|
|
return "info";
|
|
|
|
|
case SG_WARN:
|
|
|
|
|
return "warn";
|
|
|
|
|
case SG_ALERT:
|
2016-07-20 13:03:15 +00:00
|
|
|
|
case SG_POPUP:
|
2001-11-20 22:03:17 +00:00
|
|
|
|
return "alert";
|
|
|
|
|
default:
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Internal: Unknown logging priority number: "
|
2013-02-06 18:05:45 +00:00
|
|
|
|
<< sglog().get_log_priority());
|
2001-11-20 22:03:17 +00:00
|
|
|
|
return "unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the logging priority.
|
|
|
|
|
*/
|
2011-12-11 12:55:56 +00:00
|
|
|
|
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") {
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_priority(SG_BULK);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
} else if (priority == "debug") {
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_priority(SG_DEBUG);
|
2002-03-20 19:16:13 +00:00
|
|
|
|
} else if (priority.empty() || priority == "info") { // default
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_priority(SG_INFO);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
} else if (priority == "warn") {
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_priority(SG_WARN);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
} else if (priority == "alert") {
|
2013-02-06 18:05:45 +00:00
|
|
|
|
sglog().set_log_priority(SG_ALERT);
|
2001-11-20 22:03:17 +00:00
|
|
|
|
} 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
|
2015-12-31 05:11:54 +00:00
|
|
|
|
SGSoundMgr *smgr = globals->get_subsystem<SGSoundMgr>();
|
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
|
|
|
|
|
2017-03-21 20:43:42 +00:00
|
|
|
|
#ifndef FG_TESTLIB
|
2010-03-27 10:59:04 +00:00
|
|
|
|
// Pause the particle system
|
|
|
|
|
simgear::Particles::setFrozen(f);
|
2017-03-21 20:43:42 +00:00
|
|
|
|
#endif
|
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
|
2010-11-21 23:43:41 +00:00
|
|
|
|
|
|
|
|
|
SGTime * st = globals->get_time_params();
|
|
|
|
|
if (!st) {
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tm * t = st->getGmt();
|
2001-06-05 22:13:26 +00:00
|
|
|
|
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
|
|
|
|
{
|
|
|
|
|
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();
|
2010-11-21 23:43:41 +00:00
|
|
|
|
|
|
|
|
|
fgSetInt("/sim/time/warp", 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];
|
2010-11-21 23:43:41 +00:00
|
|
|
|
SGTime * st = globals->get_time_params();
|
|
|
|
|
if (!st) {
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tm *t = st->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 current heading in degrees.
|
|
|
|
|
*/
|
|
|
|
|
static double
|
|
|
|
|
getHeadingMag ()
|
|
|
|
|
{
|
2012-09-17 23:58:27 +00:00
|
|
|
|
double magheading = fgGetDouble("/orientation/heading-deg") -
|
|
|
|
|
fgGetDouble("/environment/magnetic-variation-deg");
|
2012-01-22 18:15:25 +00:00
|
|
|
|
return SGMiscd::normalizePeriodic(0, 360, 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 ()
|
|
|
|
|
{
|
2012-09-17 23:58:27 +00:00
|
|
|
|
double magtrack = fgGetDouble("/orientation/track-deg") -
|
|
|
|
|
fgGetDouble("/environment/magnetic-variation-deg");
|
2012-01-22 18:15:25 +00:00
|
|
|
|
return SGMiscd::normalizePeriodic(0, 360, magtrack );
|
2010-01-03 09:49:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-18 15:35:54 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Tie the properties.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
SGConstPropertyNode_ptr FGProperties::_longDeg;
|
|
|
|
|
SGConstPropertyNode_ptr FGProperties::_latDeg;
|
|
|
|
|
SGConstPropertyNode_ptr FGProperties::_lonLatformat;
|
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
/*
|
|
|
|
|
* Format the latitude and longitude floats into a character array using a variety of coordinate formats.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
formatLatLongString (double deg, int format, char *buf, char c) {
|
|
|
|
|
double min, sec;
|
|
|
|
|
int sign = deg < 0.0 ? -1 : 1;
|
|
|
|
|
deg = fabs(deg);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
if (format == 0) {
|
2015-07-14 16:57:42 +00:00
|
|
|
|
// d.dddddd' (DDD format).
|
|
|
|
|
snprintf(buf, 32, "%3.6f%c", deg, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
|
|
|
|
} else if (format == 1) {
|
2015-07-14 16:57:42 +00:00
|
|
|
|
// d mm.mmm' (DMM format) -- uses a round-off factor tailored to the
|
2006-06-17 16:33:00 +00:00
|
|
|
|
// required precision of the minutes field (three decimal places),
|
|
|
|
|
// preventing minute values of 60.
|
2015-07-14 16:57:42 +00:00
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
if (min >= 59.9995) {
|
|
|
|
|
min -= 60.0;
|
2015-07-14 16:57:42 +00:00
|
|
|
|
deg += 1.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
}
|
2015-07-14 16:57:42 +00:00
|
|
|
|
snprintf(buf, 32, "%d*%06.3f'%c", int(deg), fabs(min), c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else if (format == 2) {
|
|
|
|
|
// d mm'ss.s" (DMS format) -- uses a round-off factor tailored to the
|
2006-06-17 16:33:00 +00:00
|
|
|
|
// required precision of the seconds field (one decimal place),
|
|
|
|
|
// preventing second values of 60.
|
2015-07-14 16:57:42 +00:00
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
|
|
|
|
sec = (min - int(min)) * 60.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
if (sec >= 59.95) {
|
|
|
|
|
sec -= 60.0;
|
|
|
|
|
min += 1.0;
|
|
|
|
|
if (min >= 60.0) {
|
|
|
|
|
min -= 60.0;
|
2015-07-14 16:57:42 +00:00
|
|
|
|
deg += 1.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-14 16:57:42 +00:00
|
|
|
|
snprintf(buf, 32, "%d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else if (format == 3) {
|
|
|
|
|
// d.dddddd' (signed DDD format).
|
|
|
|
|
snprintf(buf, 32, "%3.6f", sign*deg);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else if (format == 4) {
|
|
|
|
|
// d mm.mmm' (signed DMM format).
|
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
|
|
|
|
if (min >= 59.9995) {
|
|
|
|
|
min -= 60.0;
|
|
|
|
|
deg += 1.0;
|
|
|
|
|
}
|
|
|
|
|
if (sign == 1) {
|
|
|
|
|
snprintf(buf, 32, "%d*%06.3f'", int(deg), fabs(min));
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 32, "-%d*%06.3f'", int(deg), fabs(min));
|
|
|
|
|
}
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else if (format == 5) {
|
|
|
|
|
// d mm'ss.s" (signed DMS format).
|
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
|
|
|
|
sec = (min - int(min)) * 60.0;
|
|
|
|
|
if (sec >= 59.95) {
|
|
|
|
|
sec -= 60.0;
|
|
|
|
|
min += 1.0;
|
|
|
|
|
if (min >= 60.0) {
|
|
|
|
|
min -= 60.0;
|
|
|
|
|
deg += 1.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (sign == 1) {
|
|
|
|
|
snprintf(buf, 32, "%d*%02d'%04.1f\"", int(deg), int(min), fabs(sec));
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 32, "-%d*%02d'%04.1f\"", int(deg), int(min), fabs(sec));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (format == 6) {
|
|
|
|
|
// dd.dddddd X, ddd.dddddd X (zero padded DDD format).
|
|
|
|
|
if (c == 'N' || c == 'S') {
|
|
|
|
|
snprintf(buf, 32, "%09.6f%c", deg, c);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 32, "%010.6f%c", deg, c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (format == 7) {
|
|
|
|
|
// dd mm.mmm' X, ddd mm.mmm' X (zero padded DMM format).
|
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
if (min >= 59.9995) {
|
|
|
|
|
min -= 60.0;
|
2015-07-14 16:57:42 +00:00
|
|
|
|
deg += 1.0;
|
|
|
|
|
}
|
|
|
|
|
if (c == 'N' || c == 'S') {
|
|
|
|
|
snprintf(buf, 32, "%02d*%06.3f'%c", int(deg), fabs(min), c);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 32, "%03d*%06.3f'%c", int(deg), fabs(min), c);
|
2015-12-02 15:16:32 +00:00
|
|
|
|
}
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else if (format == 8) {
|
|
|
|
|
// dd mm'ss.s" X, dd mm'ss.s" X (zero padded DMS format).
|
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
|
|
|
|
sec = (min - int(min)) * 60.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
if (sec >= 59.95) {
|
|
|
|
|
sec -= 60.0;
|
|
|
|
|
min += 1.0;
|
|
|
|
|
if (min >= 60.0) {
|
|
|
|
|
min -= 60.0;
|
2015-07-14 16:57:42 +00:00
|
|
|
|
deg += 1.0;
|
2015-12-02 15:16:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-14 16:57:42 +00:00
|
|
|
|
if (c == 'N' || c == 'S') {
|
|
|
|
|
snprintf(buf, 32, "%02d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 32, "%03d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (format == 9) {
|
|
|
|
|
// dd* mm'.mmm X, ddd* mm'.mmm X (Trinity House Navigation standard).
|
|
|
|
|
min = (deg - int(deg)) * 60.0;
|
|
|
|
|
if (min >= 59.9995) {
|
|
|
|
|
min -= 60.0;
|
|
|
|
|
deg += 1.0;
|
|
|
|
|
}
|
|
|
|
|
if (c == 'N' || c == 'S') {
|
2016-02-11 11:34:13 +00:00
|
|
|
|
snprintf(buf, 32, "%02d* %02d'.%03d%c", int(deg), int(min), int(SGMisc<double>::round((min-int(min))*1000)), c);
|
2015-07-14 16:57:42 +00:00
|
|
|
|
} else {
|
2016-02-11 11:34:13 +00:00
|
|
|
|
snprintf(buf, 32, "%03d* %02d'.%03d%c", int(deg), int(min), int(SGMisc<double>::round((min-int(min))*1000)), c);
|
2015-07-14 16:57:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// Empty the buffer for all invalid formats.
|
|
|
|
|
buf[0] = '\0';
|
2006-06-17 16:33:00 +00:00
|
|
|
|
}
|
2015-07-14 16:57:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
FGProperties::getLongitudeString ()
|
|
|
|
|
{
|
|
|
|
|
static char buf[32];
|
|
|
|
|
double d = _longDeg->getDoubleValue();
|
|
|
|
|
int format = _lonLatformat->getIntValue();
|
|
|
|
|
|
|
|
|
|
char c = d < 0.0 ? 'W' : 'E';
|
|
|
|
|
formatLatLongString(d, format, buf, c);
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
FGProperties::getLatitudeString ()
|
|
|
|
|
{
|
|
|
|
|
static char buf[32];
|
|
|
|
|
double d = _latDeg->getDoubleValue();
|
|
|
|
|
int format = _lonLatformat->getIntValue();
|
|
|
|
|
|
|
|
|
|
char c = d < 0.0 ? 'S' : 'N';
|
|
|
|
|
formatLatLongString(d, format, buf, c);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-07-16 04:35:35 +00:00
|
|
|
|
|
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
|
|
|
|
{
|
2012-11-18 15:35:54 +00:00
|
|
|
|
_longDeg = fgGetNode("/position/longitude-deg", true);
|
|
|
|
|
_latDeg = fgGetNode("/position/latitude-deg", true);
|
|
|
|
|
_lonLatformat = fgGetNode("/sim/lon-lat-format", true);
|
|
|
|
|
|
|
|
|
|
_offset = fgGetNode("/sim/time/local-offset", true);
|
|
|
|
|
|
|
|
|
|
// utc date/time
|
|
|
|
|
_uyear = fgGetNode("/sim/time/utc/year", true);
|
|
|
|
|
_umonth = fgGetNode("/sim/time/utc/month", true);
|
|
|
|
|
_uday = fgGetNode("/sim/time/utc/day", true);
|
|
|
|
|
_uhour = fgGetNode("/sim/time/utc/hour", true);
|
|
|
|
|
_umin = fgGetNode("/sim/time/utc/minute", true);
|
|
|
|
|
_usec = fgGetNode("/sim/time/utc/second", true);
|
|
|
|
|
_uwday = fgGetNode("/sim/time/utc/weekday", true);
|
|
|
|
|
_udsec = fgGetNode("/sim/time/utc/day-seconds", true);
|
|
|
|
|
|
|
|
|
|
// real local date/time
|
|
|
|
|
_ryear = fgGetNode("/sim/time/real/year", true);
|
|
|
|
|
_rmonth = fgGetNode("/sim/time/real/month", true);
|
|
|
|
|
_rday = fgGetNode("/sim/time/real/day", true);
|
|
|
|
|
_rhour = fgGetNode("/sim/time/real/hour", true);
|
|
|
|
|
_rmin = fgGetNode("/sim/time/real/minute", true);
|
|
|
|
|
_rsec = fgGetNode("/sim/time/real/second", true);
|
|
|
|
|
_rwday = fgGetNode("/sim/time/real/weekday", true);
|
|
|
|
|
|
2012-03-04 14:30:08 +00:00
|
|
|
|
_tiedProperties.setRoot(globals->get_props());
|
2002-03-14 00:29:20 +00:00
|
|
|
|
|
2012-03-04 14:30:08 +00:00
|
|
|
|
// Simulation
|
|
|
|
|
_tiedProperties.Tie("/sim/logging/priority", getLoggingPriority, setLoggingPriority);
|
|
|
|
|
_tiedProperties.Tie("/sim/logging/classes", getLoggingClasses, setLoggingClasses);
|
|
|
|
|
_tiedProperties.Tie("/sim/freeze/master", getFreeze, setFreeze);
|
|
|
|
|
|
2016-06-01 21:57:11 +00:00
|
|
|
|
_tiedProperties.Tie<double>("/sim/time/elapsed-sec", getElapsedTime_sec);
|
2012-03-04 14:30:08 +00:00
|
|
|
|
_tiedProperties.Tie("/sim/time/gmt", getDateString, setDateString);
|
2001-07-12 23:35:56 +00:00
|
|
|
|
fgSetArchivable("/sim/time/gmt");
|
2016-06-01 21:57:11 +00:00
|
|
|
|
_tiedProperties.Tie<const char*>("/sim/time/gmt-string", getGMTString);
|
2001-06-05 22:13:26 +00:00
|
|
|
|
|
2012-03-04 14:30:08 +00:00
|
|
|
|
// Position
|
2016-06-01 21:57:11 +00:00
|
|
|
|
_tiedProperties.Tie<const char*>("/position/latitude-string", getLatitudeString);
|
|
|
|
|
_tiedProperties.Tie<const char*>("/position/longitude-string", getLongitudeString);
|
2006-06-17 16:33:00 +00:00
|
|
|
|
|
2012-03-04 14:30:08 +00:00
|
|
|
|
// Orientation
|
2016-06-01 21:57:11 +00:00
|
|
|
|
_tiedProperties.Tie<double>("/orientation/heading-magnetic-deg", getHeadingMag);
|
|
|
|
|
_tiedProperties.Tie<double>("/orientation/track-magnetic-deg", getTrackMag);
|
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
|
|
|
|
{
|
2012-03-04 14:30:08 +00:00
|
|
|
|
_tiedProperties.Untie();
|
2012-11-18 15:35:54 +00:00
|
|
|
|
|
|
|
|
|
// drop static references to properties
|
|
|
|
|
_longDeg = 0;
|
|
|
|
|
_latDeg = 0;
|
|
|
|
|
_lonLatformat = 0;
|
2004-02-20 17:35:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
FGProperties::update (double dt)
|
|
|
|
|
{
|
2012-11-18 15:35:54 +00:00
|
|
|
|
_offset->setIntValue(globals->get_time_params()->get_local_offset());
|
2009-02-15 22:49:51 +00:00
|
|
|
|
|
|
|
|
|
// utc date/time
|
|
|
|
|
struct tm *u = globals->get_time_params()->getGmt();
|
2012-11-18 15:35:54 +00:00
|
|
|
|
_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);
|
2009-02-15 22:49:51 +00:00
|
|
|
|
|
|
|
|
|
// real local date/time
|
|
|
|
|
time_t real = time(0);
|
|
|
|
|
struct tm *r = localtime(&real);
|
2012-11-18 15:35:54 +00:00
|
|
|
|
_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());
|
2014-03-10 17:29:28 +00:00
|
|
|
|
|
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
|
2016-06-23 13:26:34 +00:00
|
|
|
|
fgLoadProps (const std::string& path, SGPropertyNode * props, bool in_fg_root, int default_mode)
|
2003-01-21 02:08:00 +00:00
|
|
|
|
{
|
2016-06-23 13:26:34 +00:00
|
|
|
|
SGPath fullpath;
|
2003-01-21 02:08:00 +00:00
|
|
|
|
if (in_fg_root) {
|
|
|
|
|
SGPath loadpath(globals->get_fg_root());
|
|
|
|
|
loadpath.append(path);
|
2016-06-23 13:26:34 +00:00
|
|
|
|
fullpath = loadpath;
|
2003-01-21 02:08:00 +00:00
|
|
|
|
} else {
|
2016-06-23 13:26:34 +00:00
|
|
|
|
fullpath = SGPath::fromUtf8(path);
|
2003-01-21 02:08:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-25 21:08:52 +00:00
|
|
|
|
long
|
2002-03-19 17:12:13 +00:00
|
|
|
|
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
|
2010-07-01 01:04:16 +00:00
|
|
|
|
fgUntie(const char * name)
|
2002-03-19 17:12:13 +00:00
|
|
|
|
{
|
2010-07-01 01:04:16 +00:00
|
|
|
|
SGPropertyNode* node = globals->get_props()->getNode(name);
|
|
|
|
|
if (!node) {
|
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "fgUntie: unknown property " << name);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!node->isTied()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!node->untie()) {
|
2002-03-19 17:12:13 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN, "Failed to untie property " << name);
|
2010-07-01 01:04:16 +00:00
|
|
|
|
}
|
2002-03-19 17:12:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
// end of fg_props.cxx
|