1
0
Fork 0

Use future-proof SGPath APIs.

Remove uses of .str(), .c_str() and some other methods of SGPath.
Pass SGPath directly where possible, or explicitly convert to the
appropriate 8-bit encoding.
This commit is contained in:
James Turner 2016-06-23 14:26:34 +01:00
parent d9129cfe80
commit 6d0c2070fd
65 changed files with 646 additions and 621 deletions

View file

@ -397,7 +397,7 @@ bool FGAIBase::init(bool search_in_AI_path)
BOOST_FOREACH(SGPath p, globals->get_data_paths("AI")) { BOOST_FOREACH(SGPath p, globals->get_data_paths("AI")) {
p.append(model_path); p.append(model_path);
if (p.exists()) { if (p.exists()) {
f = p.str(); f = p.local8BitStr();
break; break;
} }
} // of AI data paths iteration } // of AI data paths iteration

View file

@ -817,12 +817,12 @@ loadRawReplayData(gzContainerReader& input, FGFlightRecorder* pRecorder, replay_
/** Write flight recorder tape with given filename and meta properties to disk */ /** Write flight recorder tape with given filename and meta properties to disk */
bool bool
FGReplay::saveTape(const char* Filename, SGPropertyNode* MetaDataProps) FGReplay::saveTape(const SGPath& Filename, SGPropertyNode* MetaDataProps)
{ {
bool ok = true; bool ok = true;
/* open output stream *******************************************/ /* open output stream *******************************************/
gzContainerWriter output(Filename, FlightRecorderFileMagic); gzContainerWriter output(Filename.local8BitStr(), FlightRecorderFileMagic);
if (!output.good()) if (!output.good())
{ {
SG_LOG(SG_SYSTEMS, SG_ALERT, "Cannot open file" << Filename); SG_LOG(SG_SYSTEMS, SG_ALERT, "Cannot open file" << Filename);
@ -921,7 +921,7 @@ FGReplay::saveTape(const SGPropertyNode* ConfigData)
} }
if (ok) if (ok)
ok &= saveTape(p.c_str(), myMetaData.get()); ok &= saveTape(p, myMetaData.get());
if (ok) if (ok)
guiMessage("Flight recorder tape saved successfully!"); guiMessage("Flight recorder tape saved successfully!");
@ -935,12 +935,12 @@ FGReplay::saveTape(const SGPropertyNode* ConfigData)
* Actual data and signal configuration is not read when in "Preview" mode. * Actual data and signal configuration is not read when in "Preview" mode.
*/ */
bool bool
FGReplay::loadTape(const char* Filename, bool Preview, SGPropertyNode* UserData) FGReplay::loadTape(const SGPath& Filename, bool Preview, SGPropertyNode* UserData)
{ {
bool ok = true; bool ok = true;
/* open input stream ********************************************/ /* open input stream ********************************************/
gzContainerReader input(Filename, FlightRecorderFileMagic); gzContainerReader input(Filename.local8BitStr(), FlightRecorderFileMagic);
if (input.eof() || !input.good()) if (input.eof() || !input.good())
{ {
SG_LOG(SG_SYSTEMS, SG_ALERT, "Cannot open file " << Filename); SG_LOG(SG_SYSTEMS, SG_ALERT, "Cannot open file " << Filename);
@ -1142,6 +1142,6 @@ FGReplay::loadTape(const SGPropertyNode* ConfigData)
tapeDirectory.append(tape); tapeDirectory.append(tape);
tapeDirectory.concat(".fgtape"); tapeDirectory.concat(".fgtape");
SG_LOG(SG_SYSTEMS, MY_SG_DEBUG, "Checking flight recorder file " << tapeDirectory << ", preview: " << Preview); SG_LOG(SG_SYSTEMS, MY_SG_DEBUG, "Checking flight recorder file " << tapeDirectory << ", preview: " << Preview);
return loadTape(tapeDirectory.c_str(), Preview, UserData); return loadTape(tapeDirectory, Preview, UserData);
} }
} }

View file

@ -91,8 +91,8 @@ private:
double get_end_time(); double get_end_time();
bool listTapes(bool SameAircraftFilter, const SGPath& tapeDirectory); bool listTapes(bool SameAircraftFilter, const SGPath& tapeDirectory);
bool saveTape(const char* Filename, SGPropertyNode* MetaData); bool saveTape(const SGPath& Filename, SGPropertyNode* MetaData);
bool loadTape(const char* Filename, bool Preview, SGPropertyNode* UserData); bool loadTape(const SGPath& Filename, bool Preview, SGPropertyNode* UserData);
double sim_time; double sim_time;
double last_mt_time; double last_mt_time;

View file

@ -91,7 +91,7 @@ namespace canvas
{ {
SGPath tpath = globals->resolve_resource_path(path); SGPath tpath = globals->resolve_resource_path(path);
if( !tpath.isNull() ) if( !tpath.isNull() )
return osgDB::readRefImageFile(tpath.c_str()); return osgDB::readRefImageFile(tpath.local8BitStr());
SG_LOG(SG_IO, SG_ALERT, "canvas::Image: No such image: '" << path << "'"); SG_LOG(SG_IO, SG_ALERT, "canvas::Image: No such image: '" << path << "'");
} }

View file

@ -780,7 +780,7 @@ NavDisplay::updateFont()
} }
osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome"); osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome");
osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str(), fontOptions.get()); osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.local8BitStr(), fontOptions.get());
if (font != 0) { if (font != 0) {
_font = font; _font = font;

View file

@ -1084,7 +1084,7 @@ wxRadarBg::updateFont()
} }
osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome"); osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome");
osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str(), fontOptions.get()); osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.local8BitStr(), fontOptions.get());
if (font != 0) { if (font != 0) {
_font = font; _font = font;

View file

@ -52,7 +52,7 @@ void Ephemeris::init()
{ {
SGPath ephem_data_path(globals->get_fg_root()); SGPath ephem_data_path(globals->get_fg_root());
ephem_data_path.append("Astro"); ephem_data_path.append("Astro");
_impl = new SGEphemeris(ephem_data_path.c_str()); _impl = new SGEphemeris(ephem_data_path.local8BitStr());
tieStar("/ephemeris/sun/xs", _impl->get_sun(), &Star::getxs); tieStar("/ephemeris/sun/xs", _impl->get_sun(), &Star::getxs);
tieStar("/ephemeris/sun/ys", _impl->get_sun(), &Star::getys); tieStar("/ephemeris/sun/ys", _impl->get_sun(), &Star::getys);

View file

@ -134,7 +134,7 @@ void CocoaFileDialog::exec()
if (result == NSFileHandlingPanelOKButton) { if (result == NSFileHandlingPanelOKButton) {
completion_path = [[d->panel URL] path]; completion_path = [[d->panel URL] path];
//NSLog(@"the URL is: %@", d->panel URL]); //NSLog(@"the URL is: %@", d->panel URL]);
completion_sgpath = ([completion_path UTF8String]); completion_sgpath = SGPath::fromUtf8([completion_path UTF8String]);
_callback->onFileDialogDone(this, completion_sgpath); _callback->onFileDialogDone(this, completion_sgpath);
} }
}]; }];

View file

@ -40,9 +40,9 @@ public:
NSCursor* cocoaCursorForKey(FGMouseCursor::Cursor aKey) NSCursor* cocoaCursorForKey(FGMouseCursor::Cursor aKey)
{ {
NSImage* img = nil; NSImage* img = nil;
NSString* path = [NSString stringWithCString:globals->get_fg_root().c_str() std::string p = globals->get_fg_root().utf8Str();
encoding:NSUTF8StringEncoding]; NSString* path = [NSString stringWithCString:p.c_str() encoding:NSUTF8StringEncoding];
path = [path stringByAppendingPathComponent:@"gui"]; path = [path stringByAppendingPathComponent:@"gui"];
switch (aKey) { switch (aKey) {

View file

@ -207,7 +207,8 @@ bool FGFontCache::initializeFonts()
{ {
static std::string fontext("txf"); static std::string fontext("txf");
init(); init();
ulDir* fontdir = ulOpenDir(_path.c_str()); std::string fontPath = _path.local8BitStr();
ulDir* fontdir = ulOpenDir(fontPath.c_str());
if (!fontdir) if (!fontdir)
return false; return false;
const ulDirEnt *dirEntry; const ulDirEnt *dirEntry;
@ -216,7 +217,8 @@ bool FGFontCache::initializeFonts()
path.append(dirEntry->d_name); path.append(dirEntry->d_name);
if (path.extension() == fontext) { if (path.extension() == fontext) {
fntTexFont* f = new fntTexFont; fntTexFont* f = new fntTexFont;
if (f->load((char *)path.c_str())) std::string ps = path.local8BitStr();
if (f->load(ps.c_str()))
_texFonts[std::string(dirEntry->d_name)] = f; _texFonts[std::string(dirEntry->d_name)] = f;
else else
delete f; delete f;

View file

@ -141,7 +141,7 @@ InstallSceneryDialog::InstallSceneryDialog(QWidget *parent, QString downloadDir)
{ {
ui->setupUi(this); ui->setupUi(this);
if (m_downloadDir.isEmpty()) { if (m_downloadDir.isEmpty()) {
m_downloadDir = QString::fromStdString(flightgear::defaultDownloadDir()); m_downloadDir = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
} }
QString baseIntroString = ui->introText->text(); QString baseIntroString = ui->introText->text();

View file

@ -51,14 +51,14 @@ void PUIFileDialog::exec()
SGPropertyNode_ptr dlg = _dialogRoot->getChild("dialog", 0, true); SGPropertyNode_ptr dlg = _dialogRoot->getChild("dialog", 0, true);
SGPath dlgXML = globals->resolve_resource_path("gui/dialogs/file-select.xml"); SGPath dlgXML = globals->resolve_resource_path("gui/dialogs/file-select.xml");
readProperties(dlgXML.str(), dlg); readProperties(dlgXML, dlg);
dlg->setStringValue("name", name); dlg->setStringValue("name", name);
gui->newDialog(dlg); gui->newDialog(dlg);
_dialogRoot->setStringValue("title", _title); _dialogRoot->setStringValue("title", _title);
_dialogRoot->setStringValue("button", _buttonText); _dialogRoot->setStringValue("button", _buttonText);
_dialogRoot->setStringValue("directory", _initialPath.str()); _dialogRoot->setStringValue("directory", _initialPath.utf8Str());
_dialogRoot->setStringValue("selection", _placeholder); _dialogRoot->setStringValue("selection", _placeholder);
// convert patterns vector into pattern nodes // convert patterns vector into pattern nodes

View file

@ -339,7 +339,7 @@ void AddOnsPage::updateUi()
{ {
QString s = m_downloadDir; QString s = m_downloadDir;
if (s.isEmpty()) { if (s.isEmpty()) {
s = QString::fromStdString(flightgear::defaultDownloadDir()); s = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
s.append(tr(" (default)")); s.append(tr(" (default)"));
m_ui->clearDownloadDir->setEnabled(false); m_ui->clearDownloadDir->setEnabled(false);
} else { } else {

View file

@ -649,7 +649,7 @@ void QtLauncher::setSceneryPaths()
// append the TerraSync path // append the TerraSync path
QString downloadDir = settings.value("download-dir").toString(); QString downloadDir = settings.value("download-dir").toString();
if (downloadDir.isEmpty()) { if (downloadDir.isEmpty()) {
downloadDir = QString::fromStdString(flightgear::defaultDownloadDir()); downloadDir = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
} }
SGPath terraSyncDir(downloadDir.toStdString()); SGPath terraSyncDir(downloadDir.toStdString());
@ -947,7 +947,7 @@ void QtLauncher::onToggleTerrasync(bool enabled)
QSettings settings; QSettings settings;
QString downloadDir = settings.value("download-dir").toString(); QString downloadDir = settings.value("download-dir").toString();
if (downloadDir.isEmpty()) { if (downloadDir.isEmpty()) {
downloadDir = QString::fromStdString(flightgear::defaultDownloadDir()); downloadDir = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
} }
QFileInfo info(downloadDir); QFileInfo info(downloadDir);

View file

@ -181,7 +181,7 @@ bool openBrowser(const std::string& aAddress)
SGPath path(address); SGPath path(address);
path = globals->resolve_maybe_aircraft_path(address); path = globals->resolve_maybe_aircraft_path(address);
if (!path.isNull()) if (!path.isNull())
address = path.str(); address = path.local8BitStr();
else else
{ {
mkDialog ("Sorry, file not found!"); mkDialog ("Sorry, file not found!");
@ -521,7 +521,8 @@ namespace
// to be executed in graphics context (maybe separate thread) // to be executed in graphics context (maybe separate thread)
void run(osg::GraphicsContext* gc) void run(osg::GraphicsContext* gc)
{ {
_result = sg_glDumpWindow(_path.c_str(), std::string ps = _path.local8BitStr();
_result = sg_glDumpWindow(ps.c_str(),
_xsize, _xsize,
_ysize); _ysize);
} }
@ -533,7 +534,7 @@ namespace
{ {
globals->get_event_mgr()->removeTask("SnapShotTimer"); globals->get_event_mgr()->removeTask("SnapShotTimer");
fgSetString("/sim/paths/screenshot-last", _path.c_str()); fgSetString("/sim/paths/screenshot-last", _path.utf8Str());
fgSetBool("/sim/signals/screenshot", _result); fgSetBool("/sim/signals/screenshot", _result);
fgSetMouseCursor(_mouse); fgSetMouseCursor(_mouse);

View file

@ -250,7 +250,7 @@ NewGUI::getDialogProperties (const string &name)
SGPath path = _dialog_names[name]; SGPath path = _dialog_names[name];
SGPropertyNode_ptr props = new SGPropertyNode; SGPropertyNode_ptr props = new SGPropertyNode;
try { try {
readProperties(path.str(), props); readProperties(path, props);
} catch (const sg_exception &) { } catch (const sg_exception &) {
SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << path); SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << path);
return NULL; return NULL;
@ -328,7 +328,7 @@ NewGUI::readDir (const SGPath& path)
simgear::Dir dir(path); simgear::Dir dir(path);
if( !dir.exists() ) if( !dir.exists() )
{ {
SG_LOG(SG_INPUT, SG_INFO, "directory does not exist: " << path.str()); SG_LOG(SG_INPUT, SG_INFO, "directory does not exist: " << path);
return; return;
} }
@ -339,7 +339,7 @@ NewGUI::readDir (const SGPath& path)
BOOST_FOREACH(SGPath xmlPath, xmls) { BOOST_FOREACH(SGPath xmlPath, xmls) {
if (!cache->isCachedFileModified(xmlPath)) { if (!cache->isCachedFileModified(xmlPath)) {
// cached, easy // cached, easy
string name = cache->readStringProperty(xmlPath.str()); string name = cache->readStringProperty(xmlPath.utf8Str());
_dialog_names[name] = xmlPath; _dialog_names[name] = xmlPath;
continue; continue;
} }
@ -347,7 +347,7 @@ NewGUI::readDir (const SGPath& path)
// we need to parse the actual XML // we need to parse the actual XML
SGPropertyNode_ptr props = new SGPropertyNode; SGPropertyNode_ptr props = new SGPropertyNode;
try { try {
readProperties(xmlPath.str(), props); readProperties(xmlPath, props);
} catch (const sg_exception &) { } catch (const sg_exception &) {
SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << xmlPath); SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << xmlPath);
continue; continue;
@ -364,7 +364,7 @@ NewGUI::readDir (const SGPath& path)
// update cached values // update cached values
if (!cache->isReadOnly()) { if (!cache->isReadOnly()) {
cache->stampCacheFile(xmlPath); cache->stampCacheFile(xmlPath);
cache->writeStringProperty(xmlPath.str(), name); cache->writeStringProperty(xmlPath.utf8Str(), name);
} }
} // of directory children iteration } // of directory children iteration

View file

@ -75,8 +75,8 @@ FGDeviceConfigurationMap::configurationForDeviceName(const std::string& name)
SGPropertyNode_ptr result(new SGPropertyNode); SGPropertyNode_ptr result(new SGPropertyNode);
try { try {
readProperties(it->second.str(), result); readProperties(it->second, result);
result->setStringValue("source", it->second.c_str()); result->setStringValue("source", it->second.utf8Str());
} catch (sg_exception&) { } catch (sg_exception&) {
SG_LOG(SG_INPUT, SG_WARN, "parse failure reading:" << it->second); SG_LOG(SG_INPUT, SG_WARN, "parse failure reading:" << it->second);
return NULL; return NULL;
@ -126,7 +126,7 @@ void FGDeviceConfigurationMap::readCachedData(const SGPath& path)
{ {
flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); flightgear::NavDataCache* cache = flightgear::NavDataCache::instance();
NamePathMap::iterator it; NamePathMap::iterator it;
BOOST_FOREACH(string s, cache->readStringListProperty(path.str())) { BOOST_FOREACH(string s, cache->readStringListProperty(path.utf8Str())) {
// important - only insert if not already present. This ensures // important - only insert if not already present. This ensures
// user configs can override those in the base package, since they are // user configs can override those in the base package, since they are
// searched first. // searched first.
@ -139,10 +139,10 @@ void FGDeviceConfigurationMap::readCachedData(const SGPath& path)
void FGDeviceConfigurationMap::refreshCacheForFile(const SGPath& path) void FGDeviceConfigurationMap::refreshCacheForFile(const SGPath& path)
{ {
SG_LOG(SG_INPUT, SG_DEBUG, "Reading device file " << path.str()); SG_LOG(SG_INPUT, SG_DEBUG, "Reading device file " << path);
SGPropertyNode_ptr n(new SGPropertyNode); SGPropertyNode_ptr n(new SGPropertyNode);
try { try {
readProperties(path.str(), n); readProperties(path, n);
} catch (sg_exception&) { } catch (sg_exception&) {
SG_LOG(SG_INPUT, SG_ALERT, "parse failure reading:" << path); SG_LOG(SG_INPUT, SG_ALERT, "parse failure reading:" << path);
return; return;
@ -161,5 +161,5 @@ void FGDeviceConfigurationMap::refreshCacheForFile(const SGPath& path)
flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); flightgear::NavDataCache* cache = flightgear::NavDataCache::instance();
cache->stampCacheFile(path); cache->stampCacheFile(path);
cache->writeStringListProperty(path.str(), names); cache->writeStringListProperty(path.utf8Str(), names);
} }

View file

@ -258,7 +258,7 @@ static string fgScanForOption( const string& option, int argc, char **argv ) {
// Scan the user config files for the specified option and return // Scan the user config files for the specified option and return
// the value. // the value.
static string fgScanForOption( const string& option, const string& path ) { static string fgScanForOption( const string& option, const SGPath& path ) {
sg_gzifstream in( path ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
return ""; return "";
@ -311,7 +311,7 @@ static string fgScanForOption( const string& option ) {
if ( homedir != NULL ) { if ( homedir != NULL ) {
SGPath config( homedir ); SGPath config( homedir );
config.append( ".fgfsrc" ); config.append( ".fgfsrc" );
arg = fgScanForOption( option, config.str() ); arg = fgScanForOption( option, config );
} }
} }

View file

@ -31,6 +31,7 @@
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <osg/GLU> #include <osg/GLU>
@ -144,7 +145,7 @@ void HUD::init()
_font_renderer->setPointSize(_font_size); _font_renderer->setPointSize(_font_size);
_text_list.setFont(_font_renderer); _text_list.setFont(_font_renderer);
_loaded = false; _loaded = false;
currentColorChanged(); currentColorChanged();
_currentPath->fireValueChanged(); _currentPath->fireValueChanged();
} }
@ -157,13 +158,13 @@ void HUD::deinit()
end = _ladders.end(); end = _ladders.end();
for (it = _ladders.begin(); it != end; ++it) for (it = _ladders.begin(); it != end; ++it)
delete *it; delete *it;
_items.clear(); _items.clear();
_ladders.clear(); _ladders.clear();
delete _clip_box; delete _clip_box;
_clip_box = NULL; _clip_box = NULL;
_loaded = false; _loaded = false;
} }
@ -374,9 +375,9 @@ int HUD::load(const char *file, float x, float y, int level, const string& inden
} }
int ret = 0; int ret = 0;
ifstream input(path.c_str()); sg_ifstream input(path);
if (!input.good()) { if (!input.good()) {
SG_LOG(SG_INPUT, SG_ALERT, "HUD: Cannot read configuration from '" << path.c_str() << "'"); SG_LOG(SG_INPUT, SG_ALERT, "HUD: Cannot read configuration from '" << path << "'");
return 0x4; return 0x4;
} }
@ -458,17 +459,17 @@ void HUD::valueChanged(SGPropertyNode *node)
if (_listener_active) if (_listener_active)
return; return;
_listener_active = true; _listener_active = true;
bool loadNow = false; bool loadNow = false;
_visible = _visibility->getBoolValue(); _visible = _visibility->getBoolValue();
if (_visible && !_loaded) { if (_visible && !_loaded) {
loadNow = true; loadNow = true;
} }
if (!strcmp(node->getName(), "current-path") && _visible) { if (!strcmp(node->getName(), "current-path") && _visible) {
loadNow = true; loadNow = true;
} }
if (loadNow) { if (loadNow) {
int pathIndex = _currentPath->getIntValue(); int pathIndex = _currentPath->getIntValue();
SGPropertyNode* pathNode = fgGetNode("/sim/hud/path", pathIndex); SGPropertyNode* pathNode = fgGetNode("/sim/hud/path", pathIndex);
@ -477,19 +478,19 @@ void HUD::valueChanged(SGPropertyNode *node)
path = pathNode->getStringValue(); path = pathNode->getStringValue();
SG_LOG(SG_INSTR, SG_INFO, "will load Hud from " << path); SG_LOG(SG_INSTR, SG_INFO, "will load Hud from " << path);
} }
_loaded = true; _loaded = true;
load(path.c_str()); load(path.c_str());
} }
if (!strcmp(node->getName(), "current-color")) { if (!strcmp(node->getName(), "current-color")) {
currentColorChanged(); currentColorChanged();
} }
_scr_width = _scr_widthN->getIntValue(); _scr_width = _scr_widthN->getIntValue();
_scr_height = _scr_heightN->getIntValue(); _scr_height = _scr_heightN->getIntValue();
_3Denabled = _3DenabledN->getBoolValue(); _3Denabled = _3DenabledN->getBoolValue();
_transparent = _transparency->getBoolValue(); _transparent = _transparency->getBoolValue();
_antialiased = _antialiasing->getBoolValue(); _antialiased = _antialiasing->getBoolValue();
@ -511,12 +512,12 @@ void HUD::currentColorChanged()
if (index < 0) { if (index < 0) {
index = 0; index = 0;
} }
n = n->getChild("color", index, false); n = n->getChild("color", index, false);
if (!n) { if (!n) {
return; return;
} }
if (n->hasValue("red")) if (n->hasValue("red"))
_red->setFloatValue(n->getFloatValue("red", 1.0)); _red->setFloatValue(n->getFloatValue("red", 1.0));
if (n->hasValue("green")) if (n->hasValue("green"))

View file

@ -27,6 +27,7 @@
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/timing/sg_time.hxx> #include <simgear/timing/sg_time.hxx>
#include <simgear/magvar/magvar.hxx> #include <simgear/magvar/magvar.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
@ -74,19 +75,19 @@ GPSWpTypeFromFGPosType(FGPositioned::Type aType)
case FGPositioned::SEAPORT: case FGPositioned::SEAPORT:
case FGPositioned::HELIPORT: case FGPositioned::HELIPORT:
return GPS_WP_APT; return GPS_WP_APT;
case FGPositioned::VOR: case FGPositioned::VOR:
return GPS_WP_VOR; return GPS_WP_VOR;
case FGPositioned::NDB: case FGPositioned::NDB:
return GPS_WP_NDB; return GPS_WP_NDB;
case FGPositioned::WAYPOINT: case FGPositioned::WAYPOINT:
return GPS_WP_USR; return GPS_WP_USR;
case FGPositioned::FIX: case FGPositioned::FIX:
return GPS_WP_INT; return GPS_WP_INT;
default: default:
return GPS_WP_USR; return GPS_WP_USR;
} }
@ -97,8 +98,8 @@ GPSWaypoint* GPSWaypoint::createFromPositioned(const FGPositioned* aPos)
if (!aPos) { if (!aPos) {
return NULL; // happens if find returns no match return NULL; // happens if find returns no match
} }
return new GPSWaypoint(aPos->ident(), return new GPSWaypoint(aPos->ident(),
aPos->latitude() * SG_DEGREES_TO_RADIANS, aPos->latitude() * SG_DEGREES_TO_RADIANS,
aPos->longitude() * SG_DEGREES_TO_RADIANS, aPos->longitude() * SG_DEGREES_TO_RADIANS,
GPSWpTypeFromFGPosType(aPos->type()) GPSWpTypeFromFGPosType(aPos->type())
@ -160,7 +161,7 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) {
_grnd_speed_node = fgGetNode("/instrumentation/gps/indicated-ground-speed-kt", true); _grnd_speed_node = fgGetNode("/instrumentation/gps/indicated-ground-speed-kt", true);
_true_track_node = fgGetNode("/instrumentation/gps/indicated-track-true-deg", true); _true_track_node = fgGetNode("/instrumentation/gps/indicated-track-true-deg", true);
_mag_track_node = fgGetNode("/instrumentation/gps/indicated-track-magnetic-deg", true); _mag_track_node = fgGetNode("/instrumentation/gps/indicated-track-magnetic-deg", true);
// Use FG's position values at construction in case FG's gps has not run first update yet. // Use FG's position values at construction in case FG's gps has not run first update yet.
_lon = fgGetDouble("/position/longitude-deg") * SG_DEGREES_TO_RADIANS; _lon = fgGetDouble("/position/longitude-deg") * SG_DEGREES_TO_RADIANS;
_lat = fgGetDouble("/position/latitude-deg") * SG_DEGREES_TO_RADIANS; _lat = fgGetDouble("/position/latitude-deg") * SG_DEGREES_TO_RADIANS;
@ -175,7 +176,7 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) {
_groundSpeed_kts = 0.0; _groundSpeed_kts = 0.0;
_track = 0.0; _track = 0.0;
_magTrackDeg = 0.0; _magTrackDeg = 0.0;
// Sensible defaults. These can be overriden by derived classes if desired. // Sensible defaults. These can be overriden by derived classes if desired.
_cdiScales.clear(); _cdiScales.clear();
_cdiScales.push_back(5.0); _cdiScales.push_back(5.0);
@ -186,9 +187,9 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) {
_sourceCdiScaleIndex = 0; _sourceCdiScaleIndex = 0;
_cdiScaleTransition = false; _cdiScaleTransition = false;
_currentCdiScale = 5.0; _currentCdiScale = 5.0;
_cleanUpPage = -1; _cleanUpPage = -1;
_activeWaypoint.id.clear(); _activeWaypoint.id.clear();
_dist2Act = 0.0; _dist2Act = 0.0;
_crosstrackDist = 0.0; _crosstrackDist = 0.0;
@ -202,15 +203,15 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) {
_powerOnTime.set_min(0); _powerOnTime.set_min(0);
_powerOnTimerSet = false; _powerOnTimerSet = false;
_alarmSet = false; _alarmSet = false;
// Configuration Initialisation // Configuration Initialisation
// Should this be in kln89.cxx ? // Should this be in kln89.cxx ?
_turnAnticipationEnabled = false; _turnAnticipationEnabled = false;
_messageStack.clear(); _messageStack.clear();
_dto = false; _dto = false;
_approachLoaded = false; _approachLoaded = false;
_approachArm = false; _approachArm = false;
_approachReallyArmed = false; _approachReallyArmed = false;
@ -229,7 +230,7 @@ void DCLGPS::draw(osg::State& state) {
} }
void DCLGPS::init() { void DCLGPS::init() {
// Not sure if this should be here, but OK for now. // Not sure if this should be here, but OK for now.
CreateDefaultFlightPlans(); CreateDefaultFlightPlans();
@ -253,7 +254,7 @@ void DCLGPS::unbind() {
void DCLGPS::update(double dt) { void DCLGPS::update(double dt) {
//cout << "update called!\n"; //cout << "update called!\n";
_lon = _lon_node->getDoubleValue() * SG_DEGREES_TO_RADIANS; _lon = _lon_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
_lat = _lat_node->getDoubleValue() * SG_DEGREES_TO_RADIANS; _lat = _lat_node->getDoubleValue() * SG_DEGREES_TO_RADIANS;
_alt = _alt_node->getDoubleValue(); _alt = _alt_node->getDoubleValue();
@ -271,12 +272,12 @@ void DCLGPS::update(double dt) {
} }
_checkLon = _gpsLon; _checkLon = _gpsLon;
_checkLat = _gpsLat; _checkLat = _gpsLat;
// TODO - check for unit power before running this. // TODO - check for unit power before running this.
if(!_powerOnTimerSet) { if(!_powerOnTimerSet) {
SetPowerOnTimer(); SetPowerOnTimer();
} }
// Check if an alarm timer has expired // Check if an alarm timer has expired
if(_alarmSet) { if(_alarmSet) {
if(_alarmTime.hr() == atoi(fgGetString("/instrumentation/clock/indicated-hour")) if(_alarmTime.hr() == atoi(fgGetString("/instrumentation/clock/indicated-hour"))
@ -285,7 +286,7 @@ void DCLGPS::update(double dt) {
_alarmSet = false; _alarmSet = false;
} }
} }
if(!_departed) { if(!_departed) {
if(_groundSpeed_kts > 30.0) { if(_groundSpeed_kts > 30.0) {
_departed = true; _departed = true;
@ -315,7 +316,7 @@ void DCLGPS::update(double dt) {
//cout << "Error, in leg mode with flightplan of 2 or more waypoints, but either active or from wp is NULL!\n"; //cout << "Error, in leg mode with flightplan of 2 or more waypoints, but either active or from wp is NULL!\n";
OrientateToActiveFlightPlan(); OrientateToActiveFlightPlan();
} }
// Approach stuff // Approach stuff
if(_approachLoaded) { if(_approachLoaded) {
if(!_approachReallyArmed && !_approachActive) { if(!_approachReallyArmed && !_approachActive) {
@ -366,7 +367,7 @@ void DCLGPS::update(double dt) {
} }
} }
} }
// CDI scale transition stuff // CDI scale transition stuff
if(_cdiScaleTransition) { if(_cdiScaleTransition) {
if(fabs(_currentCdiScale - _cdiScales[_targetCdiScaleIndex]) < 0.001) { if(fabs(_currentCdiScale - _cdiScales[_targetCdiScaleIndex]) < 0.001) {
@ -374,7 +375,7 @@ void DCLGPS::update(double dt) {
_currentCdiScaleIndex = _targetCdiScaleIndex; _currentCdiScaleIndex = _targetCdiScaleIndex;
_cdiScaleTransition = false; _cdiScaleTransition = false;
} else { } else {
double scaleDiff = (_targetCdiScaleIndex > _sourceCdiScaleIndex double scaleDiff = (_targetCdiScaleIndex > _sourceCdiScaleIndex
? _cdiScales[_sourceCdiScaleIndex] - _cdiScales[_targetCdiScaleIndex] ? _cdiScales[_sourceCdiScaleIndex] - _cdiScales[_targetCdiScaleIndex]
: _cdiScales[_targetCdiScaleIndex] - _cdiScales[_sourceCdiScaleIndex]); : _cdiScales[_targetCdiScaleIndex] - _cdiScales[_sourceCdiScaleIndex]);
//cout << "ScaleDiff = " << scaleDiff << '\n'; //cout << "ScaleDiff = " << scaleDiff << '\n';
@ -399,8 +400,8 @@ void DCLGPS::update(double dt) {
} else { } else {
_currentCdiScale = _cdiScales[_currentCdiScaleIndex]; _currentCdiScale = _cdiScales[_currentCdiScaleIndex];
} }
// Urgh - I've been setting the heading bug based on DTK, // Urgh - I've been setting the heading bug based on DTK,
// bug I think it should be based on heading re. active waypoint // bug I think it should be based on heading re. active waypoint
// based on what the sim does after the final waypoint is passed. // based on what the sim does after the final waypoint is passed.
@ -413,7 +414,7 @@ void DCLGPS::update(double dt) {
_dtkMag = GetMagHeadingFromTo(_fromWaypoint->lat, _fromWaypoint->lon, _activeWaypoint->lat, _activeWaypoint->lon); _dtkMag = GetMagHeadingFromTo(_fromWaypoint->lat, _fromWaypoint->lon, _activeWaypoint->lat, _activeWaypoint->lon);
// Don't change the heading bug if speed is too low otherwise it flickers to/from at rest // Don't change the heading bug if speed is too low otherwise it flickers to/from at rest
if(_groundSpeed_ms > 5) { if(_groundSpeed_ms > 5) {
//cout << "track = " << _track << ", dtk = " << _dtkTrue << '\n'; //cout << "track = " << _track << ", dtk = " << _dtkTrue << '\n';
double courseDev = _track - _dtkTrue; double courseDev = _track - _dtkTrue;
//cout << "courseDev = " << courseDev << ", normalized = "; //cout << "courseDev = " << courseDev << ", normalized = ";
SG_NORMALIZE_RANGE(courseDev, -180.0, 180.0); SG_NORMALIZE_RANGE(courseDev, -180.0, 180.0);
@ -429,7 +430,7 @@ void DCLGPS::update(double dt) {
if(!_activeWaypoint.id.empty()) { if(!_activeWaypoint.id.empty()) {
double hdgTrue = GetGreatCircleCourse(_gpsLat, _gpsLon, _activeWaypoint.lat, _activeWaypoint.lon) * SG_RADIANS_TO_DEGREES; double hdgTrue = GetGreatCircleCourse(_gpsLat, _gpsLon, _activeWaypoint.lat, _activeWaypoint.lon) * SG_RADIANS_TO_DEGREES;
if(_groundSpeed_ms > 5) { if(_groundSpeed_ms > 5) {
//cout << "track = " << _track << ", hdgTrue = " << hdgTrue << '\n'; //cout << "track = " << _track << ", hdgTrue = " << hdgTrue << '\n';
double courseDev = _track - hdgTrue; double courseDev = _track - hdgTrue;
//cout << "courseDev = " << courseDev << ", normalized = "; //cout << "courseDev = " << courseDev << ", normalized = ";
SG_NORMALIZE_RANGE(courseDev, -180.0, 180.0); SG_NORMALIZE_RANGE(courseDev, -180.0, 180.0);
@ -444,7 +445,7 @@ void DCLGPS::update(double dt) {
_dtkMag = 0.0; _dtkMag = 0.0;
} }
} }
_dist2Act = GetGreatCircleDistance(_gpsLat, _gpsLon, _activeWaypoint.lat, _activeWaypoint.lon) * SG_NM_TO_METER; _dist2Act = GetGreatCircleDistance(_gpsLat, _gpsLon, _activeWaypoint.lat, _activeWaypoint.lon) * SG_NM_TO_METER;
if(_groundSpeed_ms > 10.0) { if(_groundSpeed_ms > 10.0) {
_eta = _dist2Act / _groundSpeed_ms; _eta = _dist2Act / _groundSpeed_ms;
@ -498,12 +499,12 @@ void DCLGPS::update(double dt) {
} else { } else {
_eta = 0.0; _eta = 0.0;
} }
/* /*
// First attempt at a sensible cross-track correction calculation // First attempt at a sensible cross-track correction calculation
// Uh? - I think this is implemented further down the file! // Uh? - I think this is implemented further down the file!
if(_fromWaypoint != NULL) { if(_fromWaypoint != NULL) {
} else { } else {
_crosstrackDist = 0.0; _crosstrackDist = 0.0;
} }
@ -511,10 +512,10 @@ void DCLGPS::update(double dt) {
} }
} }
/* /*
Expand a SIAP ident to the full procedure name (as shown on the approach chart). Expand a SIAP ident to the full procedure name (as shown on the approach chart).
NOTE: Some of this is inferred from data, some is from documentation. NOTE: Some of this is inferred from data, some is from documentation.
Example expansions from ARINC 424-18 [and the airport they're taken from]: Example expansions from ARINC 424-18 [and the airport they're taken from]:
"R10LY" <--> "RNAV (GPS) Y RWY 10 L" [KBOI] "R10LY" <--> "RNAV (GPS) Y RWY 10 L" [KBOI]
"R10-Z" <--> "RNAV (GPS) Z RWY 10" [KHTO] "R10-Z" <--> "RNAV (GPS) Z RWY 10" [KHTO]
@ -526,7 +527,7 @@ void DCLGPS::update(double dt) {
"VDM-A" <--> "VOR/DME or GPS-A" [KEAG] "VDM-A" <--> "VOR/DME or GPS-A" [KEAG]
"VDMB" <--> "VOR/DME or GPS-B" [KDKX] "VDMB" <--> "VOR/DME or GPS-B" [KDKX]
"VORA" <--> "VOR or GPS-A" [KEMT] "VORA" <--> "VOR or GPS-A" [KEMT]
It seems that there are 2 basic types of expansions; those that include It seems that there are 2 basic types of expansions; those that include
the runway and those that don't. Of those that don't, it seems that 2 the runway and those that don't. Of those that don't, it seems that 2
different positions within the string to encode the identifying letter different positions within the string to encode the identifying letter
@ -535,7 +536,7 @@ void DCLGPS::update(double dt) {
string DCLGPS::ExpandSIAPIdent(const string& ident) { string DCLGPS::ExpandSIAPIdent(const string& ident) {
string name; string name;
bool has_rwy = false; bool has_rwy = false;
switch(ident[0]) { switch(ident[0]) {
case 'N': name = "NDB or GPS"; has_rwy = false; break; case 'N': name = "NDB or GPS"; has_rwy = false; break;
case 'P': name = "GPS"; has_rwy = true; break; case 'P': name = "GPS"; has_rwy = true; break;
@ -549,18 +550,18 @@ string DCLGPS::ExpandSIAPIdent(const string& ident) {
default: // TODO output a log message default: // TODO output a log message
break; break;
} }
if(has_rwy) { if(has_rwy) {
// Add the identifying letter if present // Add the identifying letter if present
if(ident.size() == 5) { if(ident.size() == 5) {
name += ' '; name += ' ';
name += ident[4]; name += ident[4];
} }
// Add the runway // Add the runway
name += " RWY "; name += " RWY ";
name += ident.substr(1, 2); name += ident.substr(1, 2);
// Add a left/right/centre indication if present. // Add a left/right/centre indication if present.
if(ident.size() > 3) { if(ident.size() > 3) {
if((ident[3] != '-') && (ident[3] != ' ')) { // Early versions of the spec allowed a blank instead of a dash so check for both if((ident[3] != '-') && (ident[3] != ' ')) { // Early versions of the spec allowed a blank instead of a dash so check for both
@ -580,7 +581,7 @@ string DCLGPS::ExpandSIAPIdent(const string& ident) {
// No suffix letter // No suffix letter
} }
} }
return(name); return(name);
} }
@ -602,15 +603,15 @@ string DCLGPS::ExpandSIAPIdent(const string& ident) {
"PG" => Runway record. "PG" => Runway record.
"PP" => Path point record. ??? "PP" => Path point record. ???
"PS" => MSA record (minimum safe altitude). "PS" => MSA record (minimum safe altitude).
------ The following is for "PF", approach segment ------- ------ The following is for "PF", approach segment -------
Col 14-19: SIAP ident for this approach (left justified). This is a standardised abbreviated approach name. Col 14-19: SIAP ident for this approach (left justified). This is a standardised abbreviated approach name.
e.g. "R10LZ" expands to "RNAV (GPS) Z RWY 10 L". See the comment block for ExpandSIAPIdent for full details. e.g. "R10LZ" expands to "RNAV (GPS) Z RWY 10 L". See the comment block for ExpandSIAPIdent for full details.
Col 20: Route type. This is tricky - I don't have full documentation and am having to guess a bit. Col 20: Route type. This is tricky - I don't have full documentation and am having to guess a bit.
'A' => Arrival route? This seems to be used to encode arrival routes from the IAF to the approach proper. 'A' => Arrival route? This seems to be used to encode arrival routes from the IAF to the approach proper.
Note that the final fix of the arrival route is duplicated in the approach proper. Note that the final fix of the arrival route is duplicated in the approach proper.
'D' => VOR/DME or GPS 'D' => VOR/DME or GPS
'N' => NDB or GPS 'N' => NDB or GPS
'P' => GPS (ARINC 424-18), GPS and RNAV (GPS) (ARINC 424-15 and before). 'P' => GPS (ARINC 424-18), GPS and RNAV (GPS) (ARINC 424-15 and before).
'R' => RNAV (GPS) (ARINC 424-18). 'R' => RNAV (GPS) (ARINC 424-18).
@ -651,11 +652,11 @@ void DCLGPS::LoadApproachData() {
GPSWaypoint* wp; GPSWaypoint* wp;
GPSFlightPlan* fp; GPSFlightPlan* fp;
const GPSWaypoint* cwp; const GPSWaypoint* cwp;
std::ifstream fin; sg_ifstream fin;
SGPath path = globals->get_fg_root(); SGPath path = globals->get_fg_root();
path.append("Navaids/rnav.dat"); path.append("Navaids/rnav.dat");
fin.open(path.c_str(), ios::in); fin.open(path, ios::in);
if(!fin) { if(!fin) {
//cout << "Unable to open input file " << path.c_str() << '\n'; //cout << "Unable to open input file " << path.c_str() << '\n';
return; return;
@ -664,7 +665,7 @@ void DCLGPS::LoadApproachData() {
} }
char tmp[256]; char tmp[256];
string s; string s;
string apt_ident; // This gets set to the ICAO code of the current airport being processed. string apt_ident; // This gets set to the ICAO code of the current airport being processed.
string iap_ident; // The abbreviated name of the current approach being processed. string iap_ident; // The abbreviated name of the current approach being processed.
string wp_ident; // The ident of the waypoint of the current line string wp_ident; // The ident of the waypoint of the current line
@ -681,13 +682,13 @@ void DCLGPS::LoadApproachData() {
char last_route_type = 0; char last_route_type = 0;
char route_type; char route_type;
char waypoint_fix_type; // This is the waypoint type from col 43, i.e. the type of fix. May be blank. char waypoint_fix_type; // This is the waypoint type from col 43, i.e. the type of fix. May be blank.
int j; int j;
// Debugging info // Debugging info
unsigned int nLoaded = 0; unsigned int nLoaded = 0;
unsigned int nErrors = 0; unsigned int nErrors = 0;
//for(i=0; i<64; ++i) { //for(i=0; i<64; ++i) {
while(!fin.eof()) { while(!fin.eof()) {
fin.getline(tmp, 256); fin.getline(tmp, 256);
@ -761,7 +762,7 @@ void DCLGPS::LoadApproachData() {
iap_in_progress = true; iap_in_progress = true;
iap_error = false; iap_error = false;
} }
// Route type // Route type
route_type = s[19]; route_type = s[19];
sequence_number = atoi(s.substr(26,3).c_str()); sequence_number = atoi(s.substr(26,3).c_str());
@ -775,7 +776,7 @@ void DCLGPS::LoadApproachData() {
break; break;
} }
} }
// Ignore lines with no waypoint ID for now - these are normally part of the // Ignore lines with no waypoint ID for now - these are normally part of the
// missed approach procedure, and we don't use them in the KLN89. // missed approach procedure, and we don't use them in the KLN89.
if(!wp_ident.empty()) { if(!wp_ident.empty()) {
@ -825,12 +826,12 @@ void DCLGPS::LoadApproachData() {
case ' ': w.appType = GPS_APP_NONE; break; case ' ': w.appType = GPS_APP_NONE; break;
//default: cout << "Unknown waypoint_fix_type: \'" << waypoint_fix_type << "\' [" << apt_ident << ", " << iap_ident << "]\n"; //default: cout << "Unknown waypoint_fix_type: \'" << waypoint_fix_type << "\' [" << apt_ident << ", " << iap_ident << "]\n";
} }
if(wp_error) { if(wp_error) {
//cout << "Unable to find waypoint " << w.id << " [" << apt_ident << ", " << iap_ident << "]\n"; //cout << "Unable to find waypoint " << w.id << " [" << apt_ident << ", " << iap_ident << "]\n";
iap_error = true; iap_error = true;
} }
if(!wp_error) { if(!wp_error) {
if(route_in_progress) { if(route_in_progress) {
if(sequence_number > last_sequence_number) { if(sequence_number > last_sequence_number) {
@ -928,7 +929,7 @@ void DCLGPS::LoadApproachData() {
} }
} }
} }
// If we get to the end of the file, load any approach that is still in progress // If we get to the end of the file, load any approach that is still in progress
// TODO - sanity check that the approach has all the required elements // TODO - sanity check that the approach has all the required elements
if(iap_in_progress) { if(iap_in_progress) {
@ -941,20 +942,20 @@ void DCLGPS::LoadApproachData() {
nLoaded++; nLoaded++;
} }
} }
//cout << "Done loading approach database\n"; //cout << "Done loading approach database\n";
//cout << "Loaded: " << nLoaded << '\n'; //cout << "Loaded: " << nLoaded << '\n';
//cout << "Failed: " << nErrors << '\n'; //cout << "Failed: " << nErrors << '\n';
fin.close(); fin.close();
} }
GPSWaypoint* DCLGPS::GetActiveWaypoint() { GPSWaypoint* DCLGPS::GetActiveWaypoint() {
return &_activeWaypoint; return &_activeWaypoint;
} }
// Returns meters // Returns meters
float DCLGPS::GetDistToActiveWaypoint() { float DCLGPS::GetDistToActiveWaypoint() {
return _dist2Act; return _dist2Act;
} }
@ -1023,7 +1024,7 @@ void DCLGPS::ToggleOBSMode() {
// //
// If the KLN89 is not connected to an external indicator, then: // If the KLN89 is not connected to an external indicator, then:
// If there is an active waypoint, the OBS heading is set such that the // If there is an active waypoint, the OBS heading is set such that the
// deviation indicator remains at the same deviation (i.e. set to DTK, // deviation indicator remains at the same deviation (i.e. set to DTK,
// although there may be some small difference). // although there may be some small difference).
// //
// If there is not an active waypoint, I am not sure what value should be // If there is not an active waypoint, I am not sure what value should be
@ -1042,11 +1043,11 @@ void DCLGPS::ToggleOBSMode() {
// TODO - what should we really do here? // TODO - what should we really do here?
_obsHeading = 0; _obsHeading = 0;
} }
// Valid OBS heading values are 0 -> 359 degrees inclusive (from kln89 simulator). // Valid OBS heading values are 0 -> 359 degrees inclusive (from kln89 simulator).
if(_obsHeading > 359) _obsHeading -= 360; if(_obsHeading > 359) _obsHeading -= 360;
if(_obsHeading < 0) _obsHeading += 360; if(_obsHeading < 0) _obsHeading += 360;
// TODO - the _fromWaypoint location will change as the OBS heading changes. // TODO - the _fromWaypoint location will change as the OBS heading changes.
// Might need to store the OBS initiation position somewhere in case it is needed again. // Might need to store the OBS initiation position somewhere in case it is needed again.
SetOBSFromWaypoint(); SetOBSFromWaypoint();
@ -1057,7 +1058,7 @@ void DCLGPS::ToggleOBSMode() {
void DCLGPS::SetOBSFromWaypoint() { void DCLGPS::SetOBSFromWaypoint() {
if(!_obsMode) return; if(!_obsMode) return;
if(_activeWaypoint.id.empty()) return; if(_activeWaypoint.id.empty()) return;
// TODO - base the 180 deg correction on the to/from flag. // TODO - base the 180 deg correction on the to/from flag.
_fromWaypoint = GetPositionOnMagRadial(_activeWaypoint, 10, _obsHeading + 180.0); _fromWaypoint = GetPositionOnMagRadial(_activeWaypoint, 10, _obsHeading + 180.0);
_fromWaypoint.type = GPS_WP_VIRT; _fromWaypoint.type = GPS_WP_VIRT;
@ -1120,7 +1121,7 @@ double DCLGPS::GetTimeToWaypoint(const string& id) {
if(_groundSpeed_kts < 30.0) { if(_groundSpeed_kts < 30.0) {
return(-1.0); return(-1.0);
} }
double eta = 0.0; double eta = 0.0;
int n1 = GetActiveWaypointIndex(); int n1 = GetActiveWaypointIndex();
int n2 = GetWaypointIndex(id); int n2 = GetWaypointIndex(id);
@ -1201,7 +1202,7 @@ int DCLGPS::GetWaypointIndex(const string& id) {
void DCLGPS::OrientateToFlightPlan(GPSFlightPlan* fp) { void DCLGPS::OrientateToFlightPlan(GPSFlightPlan* fp) {
//cout << "Orientating...\n"; //cout << "Orientating...\n";
//cout << "_lat = " << _lat << ", _lon = " << _lon << ", _gpsLat = " << _gpsLat << ", gpsLon = " << _gpsLon << '\n'; //cout << "_lat = " << _lat << ", _lon = " << _lon << ", _gpsLat = " << _gpsLat << ", gpsLon = " << _gpsLon << '\n';
if(fp->IsEmpty()) { if(fp->IsEmpty()) {
_activeWaypoint.id.clear(); _activeWaypoint.id.clear();
_navFlagged = true; _navFlagged = true;
@ -1226,18 +1227,18 @@ void DCLGPS::OrientateToFlightPlan(GPSFlightPlan* fp) {
double d0 = fabs(CalcCrossTrackDeviation(*fp->waypoints[i-1], *fp->waypoints[i])); double d0 = fabs(CalcCrossTrackDeviation(*fp->waypoints[i-1], *fp->waypoints[i]));
// That is the shortest distance away we could be though - check for // That is the shortest distance away we could be though - check for
// longer distances if we are 'off the end' of the leg. // longer distances if we are 'off the end' of the leg.
double ht1 = GetGreatCircleCourse(fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon, double ht1 = GetGreatCircleCourse(fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon,
fp->waypoints[i]->lat, fp->waypoints[i]->lon) fp->waypoints[i]->lat, fp->waypoints[i]->lon)
* SG_RADIANS_TO_DEGREES; * SG_RADIANS_TO_DEGREES;
// not simply the reverse of the above due to great circle navigation. // not simply the reverse of the above due to great circle navigation.
double ht2 = GetGreatCircleCourse(fp->waypoints[i]->lat, fp->waypoints[i]->lon, double ht2 = GetGreatCircleCourse(fp->waypoints[i]->lat, fp->waypoints[i]->lon,
fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon) fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon)
* SG_RADIANS_TO_DEGREES; * SG_RADIANS_TO_DEGREES;
double hw1 = GetGreatCircleCourse(_gpsLat, _gpsLon, double hw1 = GetGreatCircleCourse(_gpsLat, _gpsLon,
fp->waypoints[i]->lat, fp->waypoints[i]->lon) fp->waypoints[i]->lat, fp->waypoints[i]->lon)
* SG_RADIANS_TO_DEGREES; * SG_RADIANS_TO_DEGREES;
double hw2 = GetGreatCircleCourse(_gpsLat, _gpsLon, double hw2 = GetGreatCircleCourse(_gpsLat, _gpsLon,
fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon) fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon)
* SG_RADIANS_TO_DEGREES; * SG_RADIANS_TO_DEGREES;
double h1 = ht1 - hw1; double h1 = ht1 - hw1;
double h2 = ht2 - hw2; double h2 = ht2 - hw2;
@ -1270,7 +1271,7 @@ void DCLGPS::OrientateToFlightPlan(GPSFlightPlan* fp) {
void DCLGPS::OrientateToActiveFlightPlan() { void DCLGPS::OrientateToActiveFlightPlan() {
OrientateToFlightPlan(_activeFP); OrientateToFlightPlan(_activeFP);
} }
/***************************************/ /***************************************/
@ -1367,12 +1368,12 @@ public:
GPSWaypoint* DCLGPS::FindFirstById(const string& id) const GPSWaypoint* DCLGPS::FindFirstById(const string& id) const
{ {
DCLGPSFilter filter; DCLGPSFilter filter;
FGPositionedList matches = FGPositioned::findAllWithIdent(id, &filter, false); FGPositionedList matches = FGPositioned::findAllWithIdent(id, &filter, false);
if (matches.empty()) { if (matches.empty()) {
return NULL; return NULL;
} }
FGPositioned::sortByRange(matches, SGGeod::fromRad(_lon, _lat)); FGPositioned::sortByRange(matches, SGGeod::fromRad(_lon, _lat));
return GPSWaypoint::createFromPositioned(matches.front()); return GPSWaypoint::createFromPositioned(matches.front());
} }
@ -1389,13 +1390,13 @@ FGPositioned* DCLGPS::FindTypedFirstById(const string& id, FGPositioned::Type ty
{ {
multi = false; multi = false;
FGPositioned::TypeFilter filter(ty); FGPositioned::TypeFilter filter(ty);
FGPositionedList matches = FGPositionedList matches =
FGPositioned::findAllWithIdent(id, &filter, exact); FGPositioned::findAllWithIdent(id, &filter, exact);
if (matches.empty()) { if (matches.empty()) {
return NULL; return NULL;
} }
FGPositioned::sortByRange(matches, SGGeod::fromRad(_lon, _lat)); FGPositioned::sortByRange(matches, SGGeod::fromRad(_lon, _lat));
return matches.front(); return matches.front();
} }
@ -1420,14 +1421,14 @@ const FGAirport* DCLGPS::FindFirstAptById(const string& id, bool &multi, bool ex
return dynamic_cast<FGAirport*>(FindTypedFirstById(id, FGPositioned::AIRPORT, multi, exact)); return dynamic_cast<FGAirport*>(FindTypedFirstById(id, FGPositioned::AIRPORT, multi, exact));
} }
FGNavRecord* DCLGPS::FindClosestVor(double lat_rad, double lon_rad) { FGNavRecord* DCLGPS::FindClosestVor(double lat_rad, double lon_rad) {
FGPositioned::TypeFilter filter(FGPositioned::VOR); FGPositioned::TypeFilter filter(FGPositioned::VOR);
double cutoff = 1000; // nautical miles double cutoff = 1000; // nautical miles
FGPositionedRef v = FGPositioned::findClosest(SGGeod::fromRad(lon_rad, lat_rad), cutoff, &filter); FGPositionedRef v = FGPositioned::findClosest(SGGeod::fromRad(lon_rad, lat_rad), cutoff, &filter);
if (!v) { if (!v) {
return NULL; return NULL;
} }
return dynamic_cast<FGNavRecord*>(v.ptr()); return dynamic_cast<FGNavRecord*>(v.ptr());
} }
@ -1465,9 +1466,9 @@ d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
A mathematically equivalent formula, which is less subject to rounding error for short distances is: A mathematically equivalent formula, which is less subject to rounding error for short distances is:
d=2*asin(sqrt((sin((lat1-lat2)/2))^2 + d=2*asin(sqrt((sin((lat1-lat2)/2))^2 +
cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
*/ */
// Returns distance in nm, takes lat & lon in RADIANS // Returns distance in nm, takes lat & lon in RADIANS
@ -1477,7 +1478,7 @@ double DCLGPS::GetGreatCircleDistance(double lat1, double lon1, double lat2, dou
return(Rad2Nm(d)); return(Rad2Nm(d));
} }
// fmod dosen't do what we want :-( // fmod dosen't do what we want :-(
static double mod(double d1, double d2) { static double mod(double d1, double d2) {
return(d1 - d2*floor(d1/d2)); return(d1 - d2*floor(d1/d2));
} }
@ -1513,7 +1514,7 @@ double DCLGPS::GetGreatCircleCourse (double lat1, double lon1, double lat2, doub
} }
cout << h * SG_RADIANS_TO_DEGREES << '\n'; cout << h * SG_RADIANS_TO_DEGREES << '\n';
*/ */
return( mod(atan2(sin(lon2-lon1)*cos(lat2), return( mod(atan2(sin(lon2-lon1)*cos(lat2),
cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1)), cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1)),
2.0*SG_PI) ); 2.0*SG_PI) );
@ -1532,10 +1533,10 @@ GPSWaypoint DCLGPS::GetPositionOnMagRadial(const GPSWaypoint& wp1, double d, dou
GPSWaypoint DCLGPS::GetPositionOnRadial(const GPSWaypoint& wp1, double d, double h) { GPSWaypoint DCLGPS::GetPositionOnRadial(const GPSWaypoint& wp1, double d, double h) {
while(h < 0.0) h += 360.0; while(h < 0.0) h += 360.0;
while(h > 360.0) h -= 360.0; while(h > 360.0) h -= 360.0;
h *= SG_DEGREES_TO_RADIANS; h *= SG_DEGREES_TO_RADIANS;
d *= (SG_PI / (180.0 * 60.0)); d *= (SG_PI / (180.0 * 60.0));
double lat=asin(sin(wp1.lat)*cos(d)+cos(wp1.lat)*sin(d)*cos(h)); double lat=asin(sin(wp1.lat)*cos(d)+cos(wp1.lat)*sin(d)*cos(h));
double lon; double lon;
if(cos(lat)==0) { if(cos(lat)==0) {
@ -1543,7 +1544,7 @@ GPSWaypoint DCLGPS::GetPositionOnRadial(const GPSWaypoint& wp1, double d, double
} else { } else {
lon=mod(wp1.lon+asin(sin(h)*sin(d)/cos(lat))+SG_PI,2*SG_PI)-SG_PI; lon=mod(wp1.lon+asin(sin(h)*sin(d)/cos(lat))+SG_PI,2*SG_PI)-SG_PI;
} }
GPSWaypoint wp; GPSWaypoint wp;
wp.lat = lat; wp.lat = lat;
wp.lon = lon; wp.lon = lon;
@ -1560,18 +1561,18 @@ double DCLGPS::CalcCrossTrackDeviation() const {
double DCLGPS::CalcCrossTrackDeviation(const GPSWaypoint& wp1, const GPSWaypoint& wp2) const { double DCLGPS::CalcCrossTrackDeviation(const GPSWaypoint& wp1, const GPSWaypoint& wp2) const {
//if(wp1 == NULL || wp2 == NULL) return(0.0); //if(wp1 == NULL || wp2 == NULL) return(0.0);
if(wp1.id.empty() || wp2.id.empty()) return(0.0); if(wp1.id.empty() || wp2.id.empty()) return(0.0);
double xtd = asin(sin(Nm2Rad(GetGreatCircleDistance(wp1.lat, wp1.lon, _gpsLat, _gpsLon))) double xtd = asin(sin(Nm2Rad(GetGreatCircleDistance(wp1.lat, wp1.lon, _gpsLat, _gpsLon)))
* sin(GetGreatCircleCourse(wp1.lat, wp1.lon, _gpsLat, _gpsLon) - GetGreatCircleCourse(wp1.lat, wp1.lon, wp2.lat, wp2.lon))); * sin(GetGreatCircleCourse(wp1.lat, wp1.lon, _gpsLat, _gpsLon) - GetGreatCircleCourse(wp1.lat, wp1.lon, wp2.lat, wp2.lon)));
return(Rad2Nm(xtd)); return(Rad2Nm(xtd));
} }
AlignedProjection::AlignedProjection() AlignedProjection::AlignedProjection()
{ {
SGGeod g; // ctor initializes to zero SGGeod g; // ctor initializes to zero
Init( g, 0.0 ); Init( g, 0.0 );
} }
AlignedProjection::AlignedProjection(const SGGeod& centre, double heading) AlignedProjection::AlignedProjection(const SGGeod& centre, double heading)
{ {
Init( centre, heading ); Init( centre, heading );
} }
@ -1614,4 +1615,3 @@ SGGeod AlignedProjection::ConvertFromLocal(const SGVec3d& pt) {
return SGGeod::fromRadM(_origin.getLongitudeRad()+delta_lon, _origin.getLatitudeRad()+delta_lat, pt.z()); return SGGeod::fromRadM(_origin.getLongitudeRad()+delta_lon, _origin.getLatitudeRad()+delta_lat, pt.z());
} }

View file

@ -73,10 +73,10 @@ void FGInstrumentMgr::init()
} }
SGPath config = globals->resolve_aircraft_path(path_n->getStringValue()); SGPath config = globals->resolve_aircraft_path(path_n->getStringValue());
SG_LOG( SG_COCKPIT, SG_INFO, "Reading instruments from " << config.str() ); SG_LOG( SG_COCKPIT, SG_INFO, "Reading instruments from " << config );
try { try {
readProperties( config.str(), config_props ); readProperties( config, config_props );
if (!build(config_props)) { if (!build(config_props)) {
throw sg_exception( throw sg_exception(
"Detected an internal inconsistency in the instrumentation\n" "Detected an internal inconsistency in the instrumentation\n"
@ -84,7 +84,7 @@ void FGInstrumentMgr::init()
} }
} catch (const sg_exception& e) { } catch (const sg_exception& e) {
SG_LOG(SG_COCKPIT, SG_ALERT, "Failed to load instrumentation system model: " SG_LOG(SG_COCKPIT, SG_ALERT, "Failed to load instrumentation system model: "
<< config.str() << ":" << e.getFormattedMessage() ); << config << ":" << e.getFormattedMessage() );
} }

View file

@ -140,9 +140,9 @@ FGNavRadio::FGNavRadio(SGPropertyNode *node) :
SGPath high = path; SGPath high = path;
high.append( "Navaids/range.high" ); high.append( "Navaids/range.high" );
static_terminalRangeInterp.reset(new SGInterpTable(term.str())); static_terminalRangeInterp.reset(new SGInterpTable(term));
static_lowRangeInterp.reset(new SGInterpTable(low.str())); static_lowRangeInterp.reset(new SGInterpTable(low));
static_highRangeInterp.reset(new SGInterpTable(high.str())); static_highRangeInterp.reset(new SGInterpTable(high));
} }
string branch("/instrumentation/" + _name); string branch("/instrumentation/" + _name);

View file

@ -307,12 +307,12 @@ void NavRadioComponent::update( double dt, const SGGeod & aircraftPosition )
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
static std::string VORTablePath( const char * name ) static SGPath VORTablePath( const char * name )
{ {
SGPath path( globals->get_fg_root() ); SGPath path( globals->get_fg_root() );
path.append( "Navaids" ); path.append( "Navaids" );
path.append(name); path.append(name);
return path.str(); return path;
} }
class VOR : public NavRadioComponentWithIdent { class VOR : public NavRadioComponentWithIdent {

View file

@ -539,12 +539,12 @@ do_materials_reload (const SGPropertyNode * arg)
SGPath mpath( globals->get_fg_root() ); SGPath mpath( globals->get_fg_root() );
mpath.append( fgGetString("/sim/rendering/materials-file") ); mpath.append( fgGetString("/sim/rendering/materials-file") );
bool loaded = new_matlib->load(globals->get_fg_root().local8BitStr(), bool loaded = new_matlib->load(globals->get_fg_root().local8BitStr(),
mpath.str(), mpath.local8BitStr(),
globals->get_props()); globals->get_props());
if ( ! loaded ) { if ( ! loaded ) {
SG_LOG( SG_GENERAL, SG_ALERT, SG_LOG( SG_GENERAL, SG_ALERT,
"Error loading materials file " << mpath.str() ); "Error loading materials file " << mpath );
return false; return false;
} }
@ -1121,7 +1121,7 @@ static bool
do_load_xml_to_proptree(const SGPropertyNode * arg) do_load_xml_to_proptree(const SGPropertyNode * arg)
{ {
SGPath file(arg->getStringValue("filename")); SGPath file(arg->getStringValue("filename"));
if (file.str().empty()) if (file.isNull())
return false; return false;
if (file.extension() != "xml") if (file.extension() != "xml")
@ -1130,27 +1130,27 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
std::string icao = arg->getStringValue("icao"); std::string icao = arg->getStringValue("icao");
if (icao.empty()) { if (icao.empty()) {
if (file.isRelative()) { if (file.isRelative()) {
SGPath absPath = globals->resolve_maybe_aircraft_path(file.str()); SGPath absPath = globals->resolve_maybe_aircraft_path(file.utf8Str());
if (!absPath.isNull()) if (!absPath.isNull())
file = absPath; file = absPath;
else else
{ {
SG_LOG(SG_IO, SG_ALERT, "loadxml: Cannot find XML property file '" SG_LOG(SG_IO, SG_ALERT, "loadxml: Cannot find XML property file '"
<< file.str() << "'."); << file << "'.");
return false; return false;
} }
} }
} else { } else {
if (!XMLLoader::findAirportData(icao, file.str(), file)) { if (!XMLLoader::findAirportData(icao, file.utf8Str(), file)) {
SG_LOG(SG_IO, SG_INFO, "loadxml: failed to find airport data for " SG_LOG(SG_IO, SG_INFO, "loadxml: failed to find airport data for "
<< file.str() << " at ICAO:" << icao); << file << " at ICAO:" << icao);
return false; return false;
} }
} }
std::string validated_path = fgValidatePath(file, false); std::string validated_path = fgValidatePath(file, false);
if (validated_path.empty()) { if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied " SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file << "' denied "
"(unauthorized directory - authorization no longer follows symlinks; to authorize reading additional directories, add them to --fg-aircraft)"); "(unauthorized directory - authorization no longer follows symlinks; to authorize reading additional directories, add them to --fg-aircraft)");
return false; return false;
} }
@ -1225,7 +1225,7 @@ static bool
do_save_xml_from_proptree(const SGPropertyNode * arg) do_save_xml_from_proptree(const SGPropertyNode * arg)
{ {
SGPath file(arg->getStringValue("filename")); SGPath file(arg->getStringValue("filename"));
if (file.str().empty()) if (file.isNull())
return false; return false;
if (file.extension() != "xml") if (file.extension() != "xml")
@ -1233,7 +1233,7 @@ do_save_xml_from_proptree(const SGPropertyNode * arg)
std::string validated_path = fgValidatePath(file, true); std::string validated_path = fgValidatePath(file, true);
if (validated_path.empty()) { if (validated_path.empty()) {
SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied " SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file << "' denied "
"(unauthorized directory - authorization no longer follows symlinks)"); "(unauthorized directory - authorization no longer follows symlinks)");
return false; return false;
} }
@ -1367,7 +1367,7 @@ do_set_scenery_paths(const SGPropertyNode* arg)
// no scenery paths set *at all*, use the data in FG_ROOT // no scenery paths set *at all*, use the data in FG_ROOT
SGPath root(globals->get_fg_root()); SGPath root(globals->get_fg_root());
root.append("Scenery"); root.append("Scenery");
globals->append_fg_scenery(root.str()); globals->append_fg_scenery(root);
} }
return true; return true;

View file

@ -210,7 +210,7 @@ public:
SG_LOG(SG_GENERAL, SG_INFO, "found aircraft in dir: " << aircraftDir ); SG_LOG(SG_GENERAL, SG_INFO, "found aircraft in dir: " << aircraftDir );
try { try {
readProperties(setFile.str(), globals->get_props()); readProperties(setFile, globals->get_props());
} catch ( const sg_exception &e ) { } catch ( const sg_exception &e ) {
SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage()); SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage());
flightgear::fatalMessageBox("Error reading aircraft", flightgear::fatalMessageBox("Error reading aircraft",
@ -234,7 +234,7 @@ public:
if (!checkCache()) { if (!checkCache()) {
// prepare cache for re-scan // prepare cache for re-scan
SGPropertyNode *n = _cache->getNode("fg-root", true); SGPropertyNode *n = _cache->getNode("fg-root", true);
n->setStringValue(globals->get_fg_root().c_str()); n->setStringValue(globals->get_fg_root().utf8Str());
n->setAttribute(SGPropertyNode::USERARCHIVE, true); n->setAttribute(SGPropertyNode::USERARCHIVE, true);
n = _cache->getNode("fg-aircraft", true); n = _cache->getNode("fg-aircraft", true);
n->setStringValue(getAircraftPaths().c_str()); n->setStringValue(getAircraftPaths().c_str());
@ -244,7 +244,7 @@ public:
visitAircraftPaths(); visitAircraftPaths();
} }
if (_foundPath.str().empty()) { if (_foundPath.isNull()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find specified aircraft: " << aircraft ); SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find specified aircraft: " << aircraft );
flightgear::fatalMessageBox("Aircraft not found", flightgear::fatalMessageBox("Aircraft not found",
"The requested aircraft '" + aircraft + "' could not be found in any of the search paths"); "The requested aircraft '" + aircraft + "' could not be found in any of the search paths");
@ -252,15 +252,15 @@ public:
return false; return false;
} }
SG_LOG(SG_GENERAL, SG_INFO, "Loading aircraft -set file from:" << _foundPath.str()); SG_LOG(SG_GENERAL, SG_INFO, "Loading aircraft -set file from:" << _foundPath);
fgSetString( "/sim/aircraft-dir", _foundPath.dir().c_str()); fgSetString( "/sim/aircraft-dir", _foundPath.dir().c_str());
if (!_foundPath.exists()) { if (!_foundPath.exists()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to find -set file:" << _foundPath.str()); SG_LOG(SG_GENERAL, SG_ALERT, "Unable to find -set file:" << _foundPath);
return false; return false;
} }
try { try {
readProperties(_foundPath.str(), globals->get_props()); readProperties(_foundPath, globals->get_props());
} catch ( const sg_exception &e ) { } catch ( const sg_exception &e ) {
SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage()); SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage());
flightgear::fatalMessageBox("Error reading aircraft", flightgear::fatalMessageBox("Error reading aircraft",
@ -400,10 +400,11 @@ bool fgInitHome()
char buf[16]; char buf[16];
bool result = false; bool result = false;
std::string ps = pidPath.local8BitStr();
#if defined(SG_WINDOWS) #if defined(SG_WINDOWS)
size_t len = snprintf(buf, 16, "%d", _getpid()); size_t len = snprintf(buf, 16, "%d", _getpid());
HANDLE f = CreateFileA(pidPath.c_str(), GENERIC_READ | GENERIC_WRITE, HANDLE f = CreateFileA(ps.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, /* sharing */ FILE_SHARE_READ, /* sharing */
NULL, /* security attributes */ NULL, /* security attributes */
CREATE_NEW, /* error if already exists */ CREATE_NEW, /* error if already exists */
@ -419,10 +420,10 @@ bool fgInitHome()
// POSIX, do open+unlink trick to the file is deleted on exit, even if we // POSIX, do open+unlink trick to the file is deleted on exit, even if we
// crash or exit(-1) // crash or exit(-1)
ssize_t len = snprintf(buf, 16, "%d", getpid()); ssize_t len = snprintf(buf, 16, "%d", getpid());
int fd = ::open(pidPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644); int fd = ::open(ps.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
if (fd >= 0) { if (fd >= 0) {
result = ::write(fd, buf, len) == len; result = ::write(fd, buf, len) == len;
if( ::unlink(pidPath.c_str()) != 0 ) // delete file when app quits if( ::unlink(ps.c_str()) != 0 ) // delete file when app quits
result = false; result = false;
} }
#endif #endif
@ -432,7 +433,7 @@ bool fgInitHome()
if (!result) { if (!result) {
flightgear::fatalMessageBox("File permissions problem", flightgear::fatalMessageBox("File permissions problem",
"Can't write to user-data storage folder, check file permissions and FG_HOME.", "Can't write to user-data storage folder, check file permissions and FG_HOME.",
"User-data at:" + dataPath.str()); "User-data at:" + dataPath.utf8Str());
} }
return result; return result;
} }
@ -453,7 +454,7 @@ int fgInitConfig ( int argc, char **argv, bool reinit )
SGPropertyNode *home = fgGetNode("/sim", true); SGPropertyNode *home = fgGetNode("/sim", true);
home->removeChild("fg-home", 0); home->removeChild("fg-home", 0);
home = home->getChild("fg-home", 0, true); home = home->getChild("fg-home", 0, true);
home->setStringValue(dataPath.c_str()); home->setStringValue(dataPath.utf8Str());
home->setAttribute(SGPropertyNode::WRITE, false); home->setAttribute(SGPropertyNode::WRITE, false);
fgSetDefaults(); fgSetDefaults();
@ -540,7 +541,7 @@ int fgInitAircraft(bool reinit)
// set aircraft-dir to short circuit the search process // set aircraft-dir to short circuit the search process
InstallRef acftInstall = acftPackage->install(); InstallRef acftInstall = acftPackage->install();
fgSetString("/sim/aircraft-dir", acftInstall->path().c_str()); fgSetString("/sim/aircraft-dir", acftInstall->path().utf8Str());
// overwrite the fully qualified ID with the aircraft one, so the // overwrite the fully qualified ID with the aircraft one, so the
// code in FindAndCacheAircraft works as normal // code in FindAndCacheAircraft works as normal
@ -649,7 +650,7 @@ bool fgInitGeneral() {
SGPropertyNode *curr = fgGetNode("/sim", true); SGPropertyNode *curr = fgGetNode("/sim", true);
curr->removeChild("fg-current", 0); curr->removeChild("fg-current", 0);
curr = curr->getChild("fg-current", 0, true); curr = curr->getChild("fg-current", 0, true);
curr->setStringValue(cwd.path().str()); curr->setStringValue(cwd.path().utf8Str());
curr->setAttribute(SGPropertyNode::WRITE, false); curr->setAttribute(SGPropertyNode::WRITE, false);
fgSetBool("/sim/startup/stdout-to-terminal", isatty(1) != 0 ); fgSetBool("/sim/startup/stdout-to-terminal", isatty(1) != 0 );
@ -731,7 +732,7 @@ void fgCreateSubsystems(bool duringReset) {
SGPath mpath( globals->get_fg_root() ); SGPath mpath( globals->get_fg_root() );
mpath.append( fgGetString("/sim/rendering/materials-file") ); mpath.append( fgGetString("/sim/rendering/materials-file") );
if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(), mpath.str(), if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(), mpath.local8BitStr(),
globals->get_props()) ) { globals->get_props()) ) {
throw sg_io_exception("Error loading materials file", mpath); throw sg_io_exception("Error loading materials file", mpath);
} }
@ -1137,7 +1138,7 @@ void fgInitPackageRoot()
packageAircraftDir.append("Aircraft"); packageAircraftDir.append("Aircraft");
SG_LOG(SG_GENERAL, SG_INFO, "init package root at:" << packageAircraftDir.str()); SG_LOG(SG_GENERAL, SG_INFO, "init package root at:" << packageAircraftDir);
SGSharedPtr<Root> pkgRoot(new Root(packageAircraftDir, FLIGHTGEAR_VERSION)); SGSharedPtr<Root> pkgRoot(new Root(packageAircraftDir, FLIGHTGEAR_VERSION));

View file

@ -684,15 +684,15 @@ fgLoadFlight (std::istream &input)
bool bool
fgLoadProps (const char * path, SGPropertyNode * props, bool in_fg_root, int default_mode) fgLoadProps (const std::string& path, SGPropertyNode * props, bool in_fg_root, int default_mode)
{ {
string fullpath; SGPath fullpath;
if (in_fg_root) { if (in_fg_root) {
SGPath loadpath(globals->get_fg_root()); SGPath loadpath(globals->get_fg_root());
loadpath.append(path); loadpath.append(path);
fullpath = loadpath.str(); fullpath = loadpath;
} else { } else {
fullpath = path; fullpath = SGPath::fromUtf8(path);
} }
try { try {

View file

@ -79,7 +79,7 @@ extern bool fgLoadFlight (std::istream &input);
* @return true if the properties loaded successfully, false * @return true if the properties loaded successfully, false
* otherwise. * otherwise.
*/ */
extern bool fgLoadProps (const char * path, SGPropertyNode * props, extern bool fgLoadProps (const std::string& path, SGPropertyNode * props,
bool in_fg_root = true, int default_mode = 0); bool in_fg_root = true, int default_mode = 0);
void setLoggingClasses (const char * c); void setLoggingClasses (const char * c);

View file

@ -361,7 +361,7 @@ void FGGlobals::append_fg_scenery (const SGPath &path, bool secure)
// tell the ResouceManager about the scenery path // tell the ResouceManager about the scenery path
// needed to load Models from this scenery path // needed to load Models from this scenery path
simgear::ResourceManager::instance()->addBasePath(abspath.str(), simgear::ResourceManager::instance()->addBasePath(abspath.local8BitStr(),
simgear::ResourceManager::PRIORITY_DEFAULT); simgear::ResourceManager::PRIORITY_DEFAULT);
simgear::Dir dir(abspath); simgear::Dir dir(abspath);
@ -611,7 +611,7 @@ FGGlobals::resetPropertyRoot()
SGPropertyNode *n = props->getNode("/sim", true); SGPropertyNode *n = props->getNode("/sim", true);
n->removeChild("fg-root", 0); n->removeChild("fg-root", 0);
n = n->getChild("fg-root", 0, true); n = n->getChild("fg-root", 0, true);
n->setStringValue(fg_root.c_str()); n->setStringValue(fg_root.utf8Str());
n->setAttribute(SGPropertyNode::WRITE, false); n->setAttribute(SGPropertyNode::WRITE, false);
} }
@ -637,9 +637,9 @@ FGGlobals::loadUserSettings(const SGPath& dataPath)
SGPath autosaveFile = simgear::Dir(dataPath).file(autosaveName()); SGPath autosaveFile = simgear::Dir(dataPath).file(autosaveName());
SGPropertyNode autosave; SGPropertyNode autosave;
if (autosaveFile.exists()) { if (autosaveFile.exists()) {
SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << autosaveFile.str()); SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << autosaveFile);
try { try {
readProperties(autosaveFile.str(), &autosave, SGPropertyNode::USERARCHIVE); readProperties(autosaveFile, &autosave, SGPropertyNode::USERARCHIVE);
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_INPUT, SG_WARN, "failed to read user settings:" << e.getMessage() SG_LOG(SG_INPUT, SG_WARN, "failed to read user settings:" << e.getMessage()
<< "(from " << e.getOrigin() << ")"); << "(from " << e.getOrigin() << ")");
@ -664,9 +664,9 @@ FGGlobals::saveUserSettings()
SGPath autosaveFile(globals->get_fg_home()); SGPath autosaveFile(globals->get_fg_home());
autosaveFile.append(autosaveName()); autosaveFile.append(autosaveName());
autosaveFile.create_dir( 0700 ); autosaveFile.create_dir( 0700 );
SG_LOG(SG_IO, SG_INFO, "Saving user settings to " << autosaveFile.str()); SG_LOG(SG_IO, SG_INFO, "Saving user settings to " << autosaveFile);
try { try {
writeProperties(autosaveFile.str(), globals->get_props(), false, SGPropertyNode::USERARCHIVE); writeProperties(autosaveFile, globals->get_props(), false, SGPropertyNode::USERARCHIVE);
} catch (const sg_exception &e) { } catch (const sg_exception &e) {
guiErrorMessage("Error writing autosave:", e); guiErrorMessage("Error writing autosave:", e);
} }

View file

@ -216,15 +216,15 @@ FGLocale::loadResource(SGPropertyNode* localeNode, const char* resource)
path.append(path_str); path.append(path_str);
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings for '" << SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings for '" <<
localeNode->getStringValue("lang", "<none>") localeNode->getStringValue("lang", "<none>")
<<"' from " << path.str()); <<"' from " << path);
// load the actual file // load the actual file
try try
{ {
readProperties(path.str(), stringNode->getNode(resource, 0, true)); readProperties(path, stringNode->getNode(resource, 0, true));
} catch (const sg_exception &e) } catch (const sg_exception &e)
{ {
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path.str() << SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path <<
". Error: " << e.getFormattedMessage()); ". Error: " << e.getFormattedMessage());
return false; return false;
} }

View file

@ -140,7 +140,7 @@ static void initTerrasync()
} }
} }
fgSetString("/sim/terrasync/cache-path", tsyncCache.c_str()); fgSetString("/sim/terrasync/cache-path", tsyncCache.utf8Str());
simgear::SGTerraSync* terra_sync = new simgear::SGTerraSync(); simgear::SGTerraSync* terra_sync = new simgear::SGTerraSync();
terra_sync->setRoot(globals->get_props()); terra_sync->setRoot(globals->get_props());
@ -171,10 +171,10 @@ static void fgSetVideoOptions()
} }
path.append(renderer+".xml"); path.append(renderer+".xml");
if (path.exists()) { if (path.exists()) {
SG_LOG(SG_INPUT, SG_INFO, "Reading video settings from " << path.str()); SG_LOG(SG_INPUT, SG_INFO, "Reading video settings from " << path);
try { try {
SGPropertyNode *r_prop = fgGetNode("/sim/rendering"); SGPropertyNode *r_prop = fgGetNode("/sim/rendering");
readProperties(path.str(), r_prop); readProperties(path, r_prop);
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_INPUT, SG_WARN, "failed to read video settings:" << e.getMessage() SG_LOG(SG_INPUT, SG_WARN, "failed to read video settings:" << e.getMessage()
<< "(from " << e.getOrigin() << ")"); << "(from " << e.getOrigin() << ")");

View file

@ -221,7 +221,7 @@ void fgSetDefaults ()
fgSetString("/sim/multiplay/txhost", ""); fgSetString("/sim/multiplay/txhost", "");
fgSetInt("/sim/multiplay/rxport", 0); fgSetInt("/sim/multiplay/rxport", 0);
fgSetInt("/sim/multiplay/txport", 0); fgSetInt("/sim/multiplay/txport", 0);
SGPropertyNode* v = globals->get_props()->getNode("/sim/version", true); SGPropertyNode* v = globals->get_props()->getNode("/sim/version", true);
v->setValueReadOnly("flightgear", FLIGHTGEAR_VERSION); v->setValueReadOnly("flightgear", FLIGHTGEAR_VERSION);
v->setValueReadOnly("simgear", SG_STRINGIZE(SIMGEAR_VERSION)); v->setValueReadOnly("simgear", SG_STRINGIZE(SIMGEAR_VERSION));
@ -237,7 +237,7 @@ void fgSetDefaults ()
#else #else
v->setValueReadOnly("nightly-build", false); v->setValueReadOnly("nightly-build", false);
#endif #endif
char* envp = ::getenv( "http_proxy" ); char* envp = ::getenv( "http_proxy" );
if( envp != NULL ) if( envp != NULL )
fgSetupProxy( envp ); fgSetupProxy( envp );
@ -255,33 +255,33 @@ public:
{ {
_minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all")); _minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all"));
} }
void show(const vector<SGPath> & path_list) void show(const vector<SGPath> & path_list)
{ {
for (vector<SGPath>::const_iterator p = path_list.begin(); for (vector<SGPath>::const_iterator p = path_list.begin();
p != path_list.end(); ++p) p != path_list.end(); ++p)
visitDir(*p, 0); visitDir(*p, 0);
simgear::requestConsole(); // ensure console is shown on Windows simgear::requestConsole(); // ensure console is shown on Windows
std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC()); std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
cout << "Available aircraft:" << endl; cout << "Available aircraft:" << endl;
for ( unsigned int i = 0; i < _aircraft.size(); i++ ) { for ( unsigned int i = 0; i < _aircraft.size(); i++ ) {
cout << _aircraft[i] << endl; cout << _aircraft[i] << endl;
} }
} }
private: private:
virtual VisitResult visit(const SGPath& path) virtual VisitResult visit(const SGPath& path)
{ {
SGPropertyNode root; SGPropertyNode root;
try { try {
readProperties(path.str(), &root); readProperties(path, &root);
} catch (sg_exception& ) { } catch (sg_exception& ) {
return VISIT_CONTINUE; return VISIT_CONTINUE;
} }
int maturity = 0; int maturity = 0;
string descStr(" "); string descStr(" ");
descStr += path.file(); descStr += path.file();
@ -290,7 +290,7 @@ private:
if (nPos == (int)(descStr.size() - 8)) { if (nPos == (int)(descStr.size() - 8)) {
descStr.resize(nPos); descStr.resize(nPos);
} }
SGPropertyNode *node = root.getNode("sim"); SGPropertyNode *node = root.getNode("sim");
if (node) { if (node) {
SGPropertyNode* desc = node->getNode("description"); SGPropertyNode* desc = node->getNode("description");
@ -298,7 +298,7 @@ private:
if (node->hasValue("status")) { if (node->hasValue("status")) {
maturity = getNumMaturity(node->getStringValue("status")); maturity = getNumMaturity(node->getStringValue("status"));
} }
if (desc) { if (desc) {
if (descStr.size() <= 27+3) { if (descStr.size() <= 27+3) {
descStr.append(29+3-descStr.size(), ' '); descStr.append(29+3-descStr.size(), ' ');
@ -309,32 +309,32 @@ private:
descStr += desc->getStringValue(); descStr += desc->getStringValue();
} }
} // of have 'sim' node } // of have 'sim' node
if (maturity >= _minStatus) { if (maturity >= _minStatus) {
_aircraft.push_back(descStr); _aircraft.push_back(descStr);
} }
return VISIT_CONTINUE; return VISIT_CONTINUE;
} }
int getNumMaturity(const char * str) int getNumMaturity(const char * str)
{ {
// changes should also be reflected in $FG_ROOT/data/options.xml & // changes should also be reflected in $FG_ROOT/data/options.xml &
// $FG_ROOT/data/Translations/string-default.xml // $FG_ROOT/data/Translations/string-default.xml
const char* levels[] = {"alpha","beta","early-production","production"}; const char* levels[] = {"alpha","beta","early-production","production"};
if (!strcmp(str, "all")) { if (!strcmp(str, "all")) {
return 0; return 0;
} }
for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++) for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++)
if (strcmp(str,levels[i])==0) if (strcmp(str,levels[i])==0)
return i; return i;
return 0; return 0;
} }
// recommended in Meyers, Effective STL when internationalization and embedded // recommended in Meyers, Effective STL when internationalization and embedded
// NULLs aren't an issue. Much faster than the STL or Boost lex versions. // NULLs aren't an issue. Much faster than the STL or Boost lex versions.
struct ciLessLibC : public std::binary_function<string, string, bool> struct ciLessLibC : public std::binary_function<string, string, bool>
@ -344,7 +344,7 @@ private:
return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0; return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0;
} }
}; };
int _minStatus; int _minStatus;
string_list _aircraft; string_list _aircraft;
}; };
@ -360,7 +360,7 @@ void fgShowAircraft(const vector<SGPath> &path_list)
{ {
ShowAircraft s; ShowAircraft s;
s.show(path_list); s.show(path_list);
#ifdef _MSC_VER #ifdef _MSC_VER
cout << "Hit a key to continue..." << endl; cout << "Hit a key to continue..." << endl;
std::cin.get(); std::cin.get();
@ -1411,22 +1411,22 @@ fgOptSetProperty(const char* raw)
string::size_type pos = arg.find('='); string::size_type pos = arg.find('=');
if (pos == arg.npos || pos == 0 || pos + 1 == arg.size()) if (pos == arg.npos || pos == 0 || pos + 1 == arg.size())
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
string name = arg.substr(0, pos); string name = arg.substr(0, pos);
string value = arg.substr(pos + 1); string value = arg.substr(pos + 1);
string type; string type;
pos = name.find(':'); pos = name.find(':');
if (pos != name.npos && pos != 0 && pos + 1 != name.size()) { if (pos != name.npos && pos != 0 && pos + 1 != name.size()) {
type = name.substr(0, pos); type = name.substr(0, pos);
name = name.substr(pos + 1); name = name.substr(pos + 1);
} }
SGPropertyNode *n = fgGetNode(name.c_str(), true); SGPropertyNode *n = fgGetNode(name.c_str(), true);
bool writable = n->getAttribute(SGPropertyNode::WRITE); bool writable = n->getAttribute(SGPropertyNode::WRITE);
if (!writable) if (!writable)
n->setAttribute(SGPropertyNode::WRITE, true); n->setAttribute(SGPropertyNode::WRITE, true);
bool ret = false; bool ret = false;
if (type.empty()) if (type.empty())
ret = n->setUnspecifiedValue(value.c_str()); ret = n->setUnspecifiedValue(value.c_str());
@ -1442,7 +1442,7 @@ fgOptSetProperty(const char* raw)
ret = n->setIntValue(atoi(value.c_str())); ret = n->setIntValue(atoi(value.c_str()));
else if (type == "b" || type == "bool") else if (type == "b" || type == "bool")
ret = n->setBoolValue(value == "true" || atoi(value.c_str()) != 0); ret = n->setBoolValue(value == "true" || atoi(value.c_str()) != 0);
if (!writable) if (!writable)
n->setAttribute(SGPropertyNode::WRITE, false); n->setAttribute(SGPropertyNode::WRITE, false);
return ret ? FG_OPTIONS_OK : FG_OPTIONS_ERROR; return ret ? FG_OPTIONS_OK : FG_OPTIONS_ERROR;
@ -1455,7 +1455,7 @@ fgOptLoadTape(const char* arg)
class DelayedTapeLoader : SGPropertyChangeListener { class DelayedTapeLoader : SGPropertyChangeListener {
public: public:
DelayedTapeLoader( const char * tape ) : DelayedTapeLoader( const char * tape ) :
_tape(tape) _tape(SGPath::fromLocal8Bit(tape))
{ {
SGPropertyNode_ptr n = fgGetNode("/sim/signals/fdm-initialized", true); SGPropertyNode_ptr n = fgGetNode("/sim/signals/fdm-initialized", true);
n->addChangeListener( this ); n->addChangeListener( this );
@ -1470,14 +1470,14 @@ fgOptLoadTape(const char* arg)
// tell the replay subsystem to load the tape // tell the replay subsystem to load the tape
FGReplay* replay = (FGReplay*) globals->get_subsystem("replay"); FGReplay* replay = (FGReplay*) globals->get_subsystem("replay");
SGPropertyNode_ptr arg = new SGPropertyNode(); SGPropertyNode_ptr arg = new SGPropertyNode();
arg->setStringValue("tape", _tape ); arg->setStringValue("tape", _tape.utf8Str() );
arg->setBoolValue( "same-aircraft", 0 ); arg->setBoolValue( "same-aircraft", 0 );
replay->loadTape(arg); replay->loadTape(arg);
delete this; // commence suicide delete this; // commence suicide
} }
private: private:
std::string _tape; SGPath _tape;
}; };
@ -1739,24 +1739,24 @@ namespace flightgear
/** /**
* internal storage of a value->option binding * internal storage of a value->option binding
*/ */
class OptionValue class OptionValue
{ {
public: public:
OptionValue(OptionDesc* d, const string& v) : OptionValue(OptionDesc* d, const string& v) :
desc(d), value(v) desc(d), value(v)
{;} {;}
OptionDesc* desc; OptionDesc* desc;
string value; string value;
}; };
typedef std::vector<OptionValue> OptionValueVec; typedef std::vector<OptionValue> OptionValueVec;
typedef std::map<string, OptionDesc*> OptionDescDict; typedef std::map<string, OptionDesc*> OptionDescDict;
class Options::OptionsPrivate class Options::OptionsPrivate
{ {
public: public:
OptionValueVec::const_iterator findValue(const string& key) const OptionValueVec::const_iterator findValue(const string& key) const
{ {
OptionValueVec::const_iterator it = values.begin(); OptionValueVec::const_iterator it = values.begin();
@ -1764,12 +1764,12 @@ public:
if (!it->desc) { if (!it->desc) {
continue; // ignore markers continue; // ignore markers
} }
if (it->desc->option == key) { if (it->desc->option == key) {
return it; return it;
} }
} // of set values iteration } // of set values iteration
return it; // not found return it; // not found
} }
@ -1785,26 +1785,26 @@ public:
return it; return it;
} }
} // of set values iteration } // of set values iteration
return it; // not found return it; // not found
} }
OptionDesc* findOption(const string& key) const OptionDesc* findOption(const string& key) const
{ {
OptionDescDict::const_iterator it = options.find(key); OptionDescDict::const_iterator it = options.find(key);
if (it == options.end()) { if (it == options.end()) {
return NULL; return NULL;
} }
return it->second; return it->second;
} }
int processOption(OptionDesc* desc, const string& arg_value) int processOption(OptionDesc* desc, const string& arg_value)
{ {
if (!desc) { if (!desc) {
return FG_OPTIONS_OK; // tolerate marker options return FG_OPTIONS_OK; // tolerate marker options
} }
switch ( desc->type & 0xffff ) { switch ( desc->type & 0xffff ) {
case OPTION_BOOL: case OPTION_BOOL:
fgSetBool( desc->property, desc->b_param ); fgSetBool( desc->property, desc->b_param );
@ -1865,14 +1865,14 @@ public:
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
} }
break; break;
case OPTION_IGNORE: case OPTION_IGNORE:
break; break;
} }
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
/** /**
* insert a marker value into the values vector. This is necessary * insert a marker value into the values vector. This is necessary
* when processing options, to ensure the correct ordering, where we scan * when processing options, to ensure the correct ordering, where we scan
@ -1882,7 +1882,7 @@ public:
{ {
values.push_back(OptionValue(NULL, "-")); values.push_back(OptionValue(NULL, "-"));
} }
/** /**
* given a current iterator into the values, find the preceding group marker, * given a current iterator into the values, find the preceding group marker,
* or return the beginning of the value vector. * or return the beginning of the value vector.
@ -1894,29 +1894,29 @@ public:
return pos; // found a marker, we're done return pos; // found a marker, we're done
} }
} }
return pos; return pos;
} }
bool showHelp, bool showHelp,
verbose, verbose,
showAircraft, showAircraft,
shouldLoadDefaultConfig; shouldLoadDefaultConfig;
OptionDescDict options; OptionDescDict options;
OptionValueVec values; OptionValueVec values;
simgear::PathList propertyFiles; simgear::PathList propertyFiles;
}; };
Options* Options::sharedInstance() Options* Options::sharedInstance()
{ {
if (shared_instance == NULL) { if (shared_instance == NULL) {
shared_instance = new Options; shared_instance = new Options;
} }
return shared_instance; return shared_instance;
} }
Options::Options() : Options::Options() :
p(new OptionsPrivate()) p(new OptionsPrivate())
{ {
@ -1924,7 +1924,7 @@ Options::Options() :
p->verbose = false; p->verbose = false;
p->showAircraft = false; p->showAircraft = false;
p->shouldLoadDefaultConfig = true; p->shouldLoadDefaultConfig = true;
// build option map // build option map
OptionDesc *desc = &fgOptionArray[ 0 ]; OptionDesc *desc = &fgOptionArray[ 0 ];
while ( desc->option != 0 ) { while ( desc->option != 0 ) {
@ -1932,11 +1932,11 @@ Options::Options() :
++desc; ++desc;
} }
} }
Options::~Options() Options::~Options()
{ {
} }
void Options::init(int argc, char **argv, const SGPath& appDataPath) void Options::init(int argc, char **argv, const SGPath& appDataPath)
{ {
// first, process the command line // first, process the command line
@ -1947,21 +1947,21 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
inOptions = true; inOptions = true;
continue; continue;
} }
int result = parseOption(argv[i]); int result = parseOption(argv[i]);
processArgResult(result); processArgResult(result);
} else { } else {
// XML properties file // XML properties file
SGPath f(argv[i]); SGPath f = SGPath::fromLocal8Bit(argv[i]);
if (!f.exists()) { if (!f.exists()) {
SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << f.str()); SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << f);
} else { } else {
p->propertyFiles.push_back(f); p->propertyFiles.push_back(f);
} }
} }
} // of arguments iteration } // of arguments iteration
p->insertGroupMarker(); // command line is one group p->insertGroupMarker(); // command line is one group
// establish log-level before anything else - otherwise it is not possible // establish log-level before anything else - otherwise it is not possible
// to show extra (debug/info/warning) messages for the start-up phase. // to show extra (debug/info/warning) messages for the start-up phase.
fgOptLogLevel(valueForOption("log-level", "alert").c_str()); fgOptLogLevel(valueForOption("log-level", "alert").c_str());
@ -1970,43 +1970,38 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
setupRoot(argc, argv); setupRoot(argc, argv);
return; return;
} }
// then config files // then config files
SGPath config; SGPath config;
std::string homedir;
if (getenv("HOME")) {
homedir = getenv("HOME"); if( !hostname.empty() ) {
}
if( !homedir.empty() && !hostname.empty() ) {
// Check for ~/.fgfsrc.hostname // Check for ~/.fgfsrc.hostname
config.set(homedir); config = SGPath::home();
config.append(".fgfsrc"); config.append(".fgfsrc");
config.concat( "." ); config.concat( "." );
config.concat( hostname ); config.concat( hostname );
readConfig(config); readConfig(config);
} }
// Check for ~/.fgfsrc // Check for ~/.fgfsrc
if( !homedir.empty() ) { config = SGPath::home();
config.set(homedir);
config.append(".fgfsrc"); config.append(".fgfsrc");
readConfig(config); readConfig(config);
}
// check for a config file in app data // check for a config file in app data
SGPath appDataConfig(appDataPath); SGPath appDataConfig(appDataPath);
appDataConfig.append("fgfsrc"); appDataConfig.append("fgfsrc");
if (appDataConfig.exists()) { if (appDataConfig.exists()) {
readConfig(appDataConfig); readConfig(appDataConfig);
} }
// setup FG_ROOT // setup FG_ROOT
setupRoot(argc, argv); setupRoot(argc, argv);
// system.fgfsrc is disabled, as we no longer allow anything in fgdata to set // system.fgfsrc is disabled, as we no longer allow anything in fgdata to set
// fg-root/fg-home/fg-aircraft and hence control what files Nasal can access // fg-root/fg-home/fg-aircraft and hence control what files Nasal can access
std::string name_for_error = homedir.empty() ? appDataConfig.str() : config.str(); std::string name_for_error = config.utf8Str();
if( ! hostname.empty() ) { if( ! hostname.empty() ) {
config = globals->get_fg_root(); config = globals->get_fg_root();
config.append( "system.fgfsrc" ); config.append( "system.fgfsrc" );
@ -2014,7 +2009,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
config.concat( hostname ); config.concat( hostname );
if (config.exists()) { if (config.exists()) {
flightgear::fatalMessageBox("Unsupported configuration", flightgear::fatalMessageBox("Unsupported configuration",
"You have a " + config.str() + " file, which is no longer processed for security reasons", "You have a " + config.utf8Str() + " file, which is no longer processed for security reasons",
"If you created this file intentionally, please move it to " + name_for_error); "If you created this file intentionally, please move it to " + name_for_error);
} }
} }
@ -2023,7 +2018,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
config.append( "system.fgfsrc" ); config.append( "system.fgfsrc" );
if (config.exists()) { if (config.exists()) {
flightgear::fatalMessageBox("Unsupported configuration", flightgear::fatalMessageBox("Unsupported configuration",
"You have a " + config.str() + " file, which is no longer processed for security reasons", "You have a " + config.utf8Str() + " file, which is no longer processed for security reasons",
"If you created this file intentionally, please move it to " + name_for_error); "If you created this file intentionally, please move it to " + name_for_error);
} }
} }
@ -2050,14 +2045,14 @@ void Options::initAircraft()
} else if (isOptionSet("vehicle")) { } else if (isOptionSet("vehicle")) {
aircraft = valueForOption("vehicle"); aircraft = valueForOption("vehicle");
} }
if (!aircraft.empty()) { if (!aircraft.empty()) {
SG_LOG(SG_INPUT, SG_INFO, "aircraft = " << aircraft ); SG_LOG(SG_INPUT, SG_INFO, "aircraft = " << aircraft );
fgSetString("/sim/aircraft", aircraft.c_str() ); fgSetString("/sim/aircraft", aircraft.c_str() );
} else { } else {
SG_LOG(SG_INPUT, SG_INFO, "No user specified aircraft, using default" ); SG_LOG(SG_INPUT, SG_INFO, "No user specified aircraft, using default" );
} }
if (p->showAircraft) { if (p->showAircraft) {
PathList path_list; PathList path_list;
@ -2079,7 +2074,7 @@ void Options::initAircraft()
fgShowAircraft(path_list); fgShowAircraft(path_list);
exit(0); exit(0);
} }
if (isOptionSet("aircraft-dir")) { if (isOptionSet("aircraft-dir")) {
SGPath aircraftDirPath(valueForOption("aircraft-dir")); SGPath aircraftDirPath(valueForOption("aircraft-dir"));
@ -2098,7 +2093,7 @@ void Options::initAircraft()
fgSetString("/sim/aircraft-state", stateName); fgSetString("/sim/aircraft-state", stateName);
} }
} }
void Options::processArgResult(int result) void Options::processArgResult(int result)
{ {
if ((result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR)) if ((result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR))
@ -2111,13 +2106,13 @@ void Options::processArgResult(int result)
p->shouldLoadDefaultConfig = false; p->shouldLoadDefaultConfig = false;
} else if (result == FG_OPTIONS_SHOW_SOUND_DEVICES) { } else if (result == FG_OPTIONS_SHOW_SOUND_DEVICES) {
SGSoundMgr smgr; SGSoundMgr smgr;
smgr.init(); smgr.init();
string vendor = smgr.get_vendor(); string vendor = smgr.get_vendor();
string renderer = smgr.get_renderer(); string renderer = smgr.get_renderer();
cout << renderer << " provided by " << vendor << endl; cout << renderer << " provided by " << vendor << endl;
cout << endl << "No. Device" << endl; cout << endl << "No. Device" << endl;
vector <const char*>devices = smgr.get_available_devices(); vector <const char*>devices = smgr.get_available_devices();
for (vector <const char*>::size_type i=0; i<devices.size(); i++) { for (vector <const char*>::size_type i=0; i<devices.size(); i++) {
cout << i << ". \"" << devices[i] << "\"" << endl; cout << i << ". \"" << devices[i] << "\"" << endl;
@ -2129,30 +2124,30 @@ void Options::processArgResult(int result)
exit(0); exit(0);
} }
} }
void Options::readConfig(const SGPath& path) void Options::readConfig(const SGPath& path)
{ {
sg_gzifstream in( path.str() ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
return; return;
} }
SG_LOG( SG_GENERAL, SG_INFO, "Processing config file: " << path.str() ); SG_LOG( SG_GENERAL, SG_INFO, "Processing config file: " << path );
in >> skipcomment; in >> skipcomment;
while ( ! in.eof() ) { while ( ! in.eof() ) {
string line; string line;
getline( in, line, '\n' ); getline( in, line, '\n' );
// catch extraneous (DOS) line ending character // catch extraneous (DOS) line ending character
int i; int i;
for (i = line.length(); i > 0; i--) for (i = line.length(); i > 0; i--)
if (line[i - 1] > 32) if (line[i - 1] > 32)
break; break;
line = line.substr( 0, i ); line = line.substr( 0, i );
if ( parseOption( line ) == FG_OPTIONS_ERROR ) { if ( parseOption( line ) == FG_OPTIONS_ERROR ) {
cerr << endl << "Config file parse error: " << path.str() << " '" cerr << endl << "Config file parse error: " << path << " '"
<< line << "'" << endl; << line << "'" << endl;
p->showHelp = true; p->showHelp = true;
} }
@ -2161,7 +2156,7 @@ void Options::readConfig(const SGPath& path)
p->insertGroupMarker(); // each config file is a group p->insertGroupMarker(); // each config file is a group
} }
int Options::parseOption(const string& s) int Options::parseOption(const string& s)
{ {
if ((s == "--help") || (s=="-h")) { if ((s == "--help") || (s=="-h")) {
@ -2189,7 +2184,7 @@ int Options::parseOption(const string& s)
SG_LOG(SG_GENERAL, SG_ALERT, "malformed property option:" << s); SG_LOG(SG_GENERAL, SG_ALERT, "malformed property option:" << s);
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
} }
p->values.push_back(OptionValue(desc, s.substr(7))); p->values.push_back(OptionValue(desc, s.substr(7)));
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} else if ( s.find( "--" ) == 0 ) { } else if ( s.find( "--" ) == 0 ) {
@ -2201,14 +2196,14 @@ int Options::parseOption(const string& s)
key = s.substr( 2, eqPos - 2 ); key = s.substr( 2, eqPos - 2 );
value = s.substr( eqPos + 1); value = s.substr( eqPos + 1);
} }
return addOption(key, value); return addOption(key, value);
} else { } else {
flightgear::modalMessageBox("Unknown option", "Unknown command-line option: " + s); flightgear::modalMessageBox("Unknown option", "Unknown command-line option: " + s);
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
} }
} }
int Options::addOption(const string &key, const string &value) int Options::addOption(const string &key, const string &value)
{ {
OptionDesc* desc = p->findOption(key); OptionDesc* desc = p->findOption(key);
@ -2216,7 +2211,7 @@ int Options::addOption(const string &key, const string &value)
flightgear::modalMessageBox("Unknown option", "Unknown command-line option: " + key); flightgear::modalMessageBox("Unknown option", "Unknown command-line option: " + key);
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
} }
if (!(desc->type & OPTION_MULTI)) { if (!(desc->type & OPTION_MULTI)) {
OptionValueVec::const_iterator it = p->findValue(key); OptionValueVec::const_iterator it = p->findValue(key);
if (it != p->values.end()) { if (it != p->values.end()) {
@ -2224,7 +2219,7 @@ int Options::addOption(const string &key, const string &value)
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
} }
p->values.push_back(OptionValue(desc, value)); p->values.push_back(OptionValue(desc, value));
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
@ -2244,7 +2239,7 @@ int Options::setOption(const string &key, const string &value)
p->values.erase(it); p->values.erase(it);
} }
} }
p->values.push_back(OptionValue(desc, value)); p->values.push_back(OptionValue(desc, value));
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
@ -2262,14 +2257,14 @@ bool Options::isOptionSet(const string &key) const
OptionValueVec::const_iterator it = p->findValue(key); OptionValueVec::const_iterator it = p->findValue(key);
return (it != p->values.end()); return (it != p->values.end());
} }
string Options::valueForOption(const string& key, const string& defValue) const string Options::valueForOption(const string& key, const string& defValue) const
{ {
OptionValueVec::const_iterator it = p->findValue(key); OptionValueVec::const_iterator it = p->findValue(key);
if (it == p->values.end()) { if (it == p->values.end()) {
return defValue; return defValue;
} }
return it->value; return it->value;
} }
@ -2281,16 +2276,16 @@ string_list Options::valuesForOption(const std::string& key) const
if (!it->desc) { if (!it->desc) {
continue; // ignore marker values continue; // ignore marker values
} }
if (it->desc->option == key) { if (it->desc->option == key) {
result.push_back(it->value); result.push_back(it->value);
} }
} }
return result; return result;
} }
string defaultDownloadDir() SGPath defaultDownloadDir()
{ {
#if defined(SG_WINDOWS) #if defined(SG_WINDOWS)
SGPath p(SGPath::documents()); SGPath p(SGPath::documents());
@ -2298,7 +2293,7 @@ string defaultDownloadDir()
#else #else
SGPath p(globals->get_fg_home()); SGPath p(globals->get_fg_home());
#endif #endif
return p.str(); return p;
} }
OptionResult Options::processOptions() OptionResult Options::processOptions()
@ -2313,7 +2308,7 @@ OptionResult Options::processOptions()
showUsage(); showUsage();
return FG_OPTIONS_EXIT; return FG_OPTIONS_EXIT;
} }
// processing order is complicated. We must process groups LIFO, but the // processing order is complicated. We must process groups LIFO, but the
// values *within* each group in FIFO order, to retain consistency with // values *within* each group in FIFO order, to retain consistency with
// older versions of FG, and existing user configs. // older versions of FG, and existing user configs.
@ -2325,17 +2320,17 @@ OptionResult Options::processOptions()
OptionValueVec::const_iterator groupBegin = p->rfindGroup(groupEnd); OptionValueVec::const_iterator groupBegin = p->rfindGroup(groupEnd);
// run over the group in FIFO order // run over the group in FIFO order
OptionValueVec::const_iterator it; OptionValueVec::const_iterator it;
for (it = groupBegin; it != groupEnd; ++it) { for (it = groupBegin; it != groupEnd; ++it) {
int result = p->processOption(it->desc, it->value); int result = p->processOption(it->desc, it->value);
switch(result) switch(result)
{ {
case FG_OPTIONS_ERROR: case FG_OPTIONS_ERROR:
showUsage(); showUsage();
return FG_OPTIONS_ERROR; return FG_OPTIONS_ERROR;
case FG_OPTIONS_EXIT: case FG_OPTIONS_EXIT:
return FG_OPTIONS_EXIT; return FG_OPTIONS_EXIT;
default: default:
break; break;
} }
@ -2343,14 +2338,14 @@ OptionResult Options::processOptions()
SG_LOG(SG_GENERAL, SG_INFO, "\toption:" << it->desc->option << " = " << it->value); SG_LOG(SG_GENERAL, SG_INFO, "\toption:" << it->desc->option << " = " << it->value);
} }
} }
groupEnd = groupBegin; groupEnd = groupBegin;
} }
BOOST_FOREACH(const SGPath& file, p->propertyFiles) { BOOST_FOREACH(const SGPath& file, p->propertyFiles) {
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
"Reading command-line property file " << file.str()); "Reading command-line property file " << file);
readProperties(file.str(), globals->get_props()); readProperties(file, globals->get_props());
} }
// now options are process, do supplemental fixup // now options are process, do supplemental fixup
@ -2360,8 +2355,8 @@ OptionResult Options::processOptions()
} }
// download dir fix-up // download dir fix-up
string downloadDir = simgear::strutils::strip(fgGetString("/sim/paths/download-dir")); SGPath downloadDir = SGPath::fromUtf8(fgGetString("/sim/paths/download-dir"));
if (downloadDir.empty()) { if (downloadDir.isNull()) {
downloadDir = defaultDownloadDir(); downloadDir = defaultDownloadDir();
SG_LOG(SG_GENERAL, SG_INFO, "Using default download dir: " << downloadDir); SG_LOG(SG_GENERAL, SG_INFO, "Using default download dir: " << downloadDir);
} else { } else {
@ -2373,11 +2368,11 @@ OptionResult Options::processOptions()
} }
// terrasync directory fixup // terrasync directory fixup
string terrasyncDir = simgear::strutils::strip(fgGetString("/sim/terrasync/scenery-dir")); SGPath terrasyncDir = SGPath::fromUtf8(fgGetString("/sim/terrasync/scenery-dir"));
if (terrasyncDir.empty()) { if (terrasyncDir.isNull()) {
SGPath p(downloadDir); SGPath p(downloadDir);
p.append("TerraSync"); p.append("TerraSync");
terrasyncDir = p.str(); terrasyncDir = p;
simgear::Dir d(terrasyncDir); simgear::Dir d(terrasyncDir);
if (!d.exists()) { if (!d.exists()) {
@ -2385,7 +2380,7 @@ OptionResult Options::processOptions()
} }
SG_LOG(SG_GENERAL, SG_INFO, "Using default TerraSync: " << terrasyncDir); SG_LOG(SG_GENERAL, SG_INFO, "Using default TerraSync: " << terrasyncDir);
fgSetString("/sim/terrasync/scenery-dir", p.str()); fgSetString("/sim/terrasync/scenery-dir", p.utf8Str());
} else { } else {
SG_LOG(SG_GENERAL, SG_INFO, "Using explicit TerraSync dir: " << terrasyncDir); SG_LOG(SG_GENERAL, SG_INFO, "Using explicit TerraSync dir: " << terrasyncDir);
} }
@ -2397,9 +2392,9 @@ OptionResult Options::processOptions()
// is enabled or not. This allows us to toggle terrasync on/off at // is enabled or not. This allows us to toggle terrasync on/off at
// runtime and have things work as expected // runtime and have things work as expected
const PathList& scenery_paths(globals->get_fg_scenery()); const PathList& scenery_paths(globals->get_fg_scenery());
if (std::find(scenery_paths.begin(), scenery_paths.end(), SGPath(terrasyncDir)) == scenery_paths.end()) { if (std::find(scenery_paths.begin(), scenery_paths.end(), terrasyncDir) == scenery_paths.end()) {
// terrasync dir is not in the scenery paths, add it // terrasync dir is not in the scenery paths, add it
globals->append_fg_scenery(SGPath(terrasyncDir)); globals->append_fg_scenery(terrasyncDir);
} }
if (addFGDataScenery) { if (addFGDataScenery) {
@ -2412,14 +2407,14 @@ OptionResult Options::processOptions()
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
void Options::showUsage() const void Options::showUsage() const
{ {
fgOptLogLevel( "alert" ); fgOptLogLevel( "alert" );
FGLocale *locale = globals->get_locale(); FGLocale *locale = globals->get_locale();
SGPropertyNode options_root; SGPropertyNode options_root;
simgear::requestConsole(); // ensure console is shown on Windows simgear::requestConsole(); // ensure console is shown on Windows
cout << endl; cout << endl;
@ -2430,7 +2425,7 @@ void Options::showUsage() const
cout << "Make sure the file options.xml is located in the FlightGear base directory," << endl; cout << "Make sure the file options.xml is located in the FlightGear base directory," << endl;
cout << "and the location of the base directory is specified by setting $FG_ROOT or" << endl; cout << "and the location of the base directory is specified by setting $FG_ROOT or" << endl;
cout << "by adding --fg-root=path as a program argument." << endl; cout << "by adding --fg-root=path as a program argument." << endl;
exit(-1); exit(-1);
} }
@ -2451,23 +2446,23 @@ void Options::showUsage() const
if (usage) { if (usage) {
cout << usage << endl; cout << usage << endl;
} }
vector<SGPropertyNode_ptr>section = options->getChildren("section"); vector<SGPropertyNode_ptr>section = options->getChildren("section");
for (unsigned int j = 0; j < section.size(); j++) { for (unsigned int j = 0; j < section.size(); j++) {
string msg = ""; string msg = "";
vector<SGPropertyNode_ptr>option = section[j]->getChildren("option"); vector<SGPropertyNode_ptr>option = section[j]->getChildren("option");
for (unsigned int k = 0; k < option.size(); k++) { for (unsigned int k = 0; k < option.size(); k++) {
SGPropertyNode *name = option[k]->getNode("name"); SGPropertyNode *name = option[k]->getNode("name");
SGPropertyNode *short_name = option[k]->getNode("short"); SGPropertyNode *short_name = option[k]->getNode("short");
SGPropertyNode *key = option[k]->getNode("key"); SGPropertyNode *key = option[k]->getNode("key");
SGPropertyNode *arg = option[k]->getNode("arg"); SGPropertyNode *arg = option[k]->getNode("arg");
bool brief = option[k]->getNode("brief") != 0; bool brief = option[k]->getNode("brief") != 0;
if ((brief || p->verbose) && name) { if ((brief || p->verbose) && name) {
string tmp = name->getStringValue(); string tmp = name->getStringValue();
if (key){ if (key){
tmp.append(":"); tmp.append(":");
tmp.append(key->getStringValue()); tmp.append(key->getStringValue());
@ -2480,7 +2475,7 @@ void Options::showUsage() const
tmp.append(", -"); tmp.append(", -");
tmp.append(short_name->getStringValue()); tmp.append(short_name->getStringValue());
} }
if (tmp.size() <= 25) { if (tmp.size() <= 25) {
msg+= " --"; msg+= " --";
msg += tmp; msg += tmp;
@ -2492,7 +2487,7 @@ void Options::showUsage() const
} }
// There may be more than one <description> tag associated // There may be more than one <description> tag associated
// with one option // with one option
vector<SGPropertyNode_ptr> desc; vector<SGPropertyNode_ptr> desc;
desc = option[k]->getChildren("description"); desc = option[k]->getChildren("description");
if (! desc.empty()) { if (! desc.empty()) {
@ -2503,20 +2498,20 @@ void Options::showUsage() const
vector<SGPropertyNode_ptr>trans_desc = locale->getLocalizedStrings(t.c_str(),"options"); vector<SGPropertyNode_ptr>trans_desc = locale->getLocalizedStrings(t.c_str(),"options");
for ( unsigned int m = 0; m < trans_desc.size(); m++ ) { for ( unsigned int m = 0; m < trans_desc.size(); m++ ) {
string t_str = trans_desc[m]->getStringValue(); string t_str = trans_desc[m]->getStringValue();
if ((m > 0) || ((l > 0) && m == 0)) { if ((m > 0) || ((l > 0) && m == 0)) {
msg.append( 32, ' '); msg.append( 32, ' ');
} }
// If the string is too large to fit on the screen, // If the string is too large to fit on the screen,
// then split it up in several pieces. // then split it up in several pieces.
while ( t_str.size() > 47 ) { while ( t_str.size() > 47 ) {
string::size_type m = t_str.rfind(' ', 47); string::size_type m = t_str.rfind(' ', 47);
msg += t_str.substr(0, m) + '\n'; msg += t_str.substr(0, m) + '\n';
msg.append( 32, ' '); msg.append( 32, ' ');
t_str.erase(t_str.begin(), t_str.begin() + m + 1); t_str.erase(t_str.begin(), t_str.begin() + m + 1);
} }
msg += t_str + '\n'; msg += t_str + '\n';
@ -2525,7 +2520,7 @@ void Options::showUsage() const
} }
} }
} }
const char* name = locale->getLocalizedString(section[j]->getStringValue("name"),"options"); const char* name = locale->getLocalizedString(section[j]->getStringValue("name"),"options");
if (!msg.empty() && name) { if (!msg.empty() && name) {
cout << endl << name << ":" << endl; cout << endl << name << ":" << endl;
@ -2533,7 +2528,7 @@ void Options::showUsage() const
msg.erase(); msg.erase();
} }
} }
if ( !p->verbose ) { if ( !p->verbose ) {
const char* verbose_help = locale->getLocalizedString(options->getStringValue("verbose-help"),"options"); const char* verbose_help = locale->getLocalizedString(options->getStringValue("verbose-help"),"options");
if (verbose_help) if (verbose_help)
@ -2544,27 +2539,27 @@ void Options::showUsage() const
std::cin.get(); std::cin.get();
#endif #endif
} }
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
SGPath Options::platformDefaultRoot() const SGPath Options::platformDefaultRoot() const
{ {
return "../data"; return SGPath::fromUtf8("../data");
} }
#elif defined(SG_WINDOWS) #elif defined(SG_WINDOWS)
SGPath Options::platformDefaultRoot() const SGPath Options::platformDefaultRoot() const
{ {
return "..\\data"; return SGPath::fromUtf8("..\\data");
} }
#elif defined(SG_MAC) #elif defined(SG_MAC)
// platformDefaultRoot defined in CocoaHelpers.mm // platformDefaultRoot defined in CocoaHelpers.mm
#else #else
SGPath Options::platformDefaultRoot() const SGPath Options::platformDefaultRoot() const
{ {
return SGPath(PKGLIBDIR); return SGPath::fromUtf8(PKGLIBDIR);
} }
#endif #endif
void Options::setupRoot(int argc, char **argv) void Options::setupRoot(int argc, char **argv)
{ {
SGPath root; SGPath root;
@ -2592,8 +2587,8 @@ void Options::setupRoot(int argc, char **argv)
SG_LOG(SG_GENERAL, SG_INFO, "Qt launcher set fg_root = " << root ); SG_LOG(SG_GENERAL, SG_INFO, "Qt launcher set fg_root = " << root );
} }
} }
} }
globals->set_fg_root(root); globals->set_fg_root(root);
static char required_version[] = FLIGHTGEAR_VERSION; static char required_version[] = FLIGHTGEAR_VERSION;
string base_version = fgBasePackageVersion(root); string base_version = fgBasePackageVersion(root);
@ -2616,7 +2611,7 @@ void Options::setupRoot(int argc, char **argv)
exit(-1); exit(-1);
} }
if (base_version != required_version) { if (base_version != required_version) {
flightgear::fatalMessageBox("Base package version mismatch", flightgear::fatalMessageBox("Base package version mismatch",
"Version check failed: please check your installation.", "Version check failed: please check your installation.",
@ -2628,7 +2623,7 @@ void Options::setupRoot(int argc, char **argv)
} }
#endif #endif
} }
bool Options::shouldLoadDefaultConfig() const bool Options::shouldLoadDefaultConfig() const
{ {
return p->shouldLoadDefaultConfig; return p->shouldLoadDefaultConfig;
@ -2655,9 +2650,8 @@ bool Options::checkForArg(int argc, char* argv[], const char* checkArg)
return true; return true;
} }
} }
return false; return false;
} }
} // of namespace flightgear
} // of namespace flightgear

View file

@ -42,7 +42,7 @@ namespace flightgear
* Documents (FlightGear), on Unixes we default to FG_HOME, which is * Documents (FlightGear), on Unixes we default to FG_HOME, which is
* typically invisible. * typically invisible.
*/ */
std::string defaultDownloadDir(); SGPath defaultDownloadDir();
/// option processing can have various result values /// option processing can have various result values
/// depending on what the user requested. Note processOptions only /// depending on what the user requested. Note processOptions only

View file

@ -213,24 +213,24 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
string acfile = fgGetString("/sim/aircraft") + string(".xml"); string acfile = fgGetString("/sim/aircraft") + string(".xml");
acData.append(acfile); acData.append(acfile);
SGPropertyNode root; SGPropertyNode root;
readProperties(acData.str(), &root); readProperties(acData, &root);
SGPropertyNode * node = root.getNode("sim"); SGPropertyNode * node = root.getNode("sim");
fltType = node->getStringValue("aircraft-class", "NONE" ); fltType = node->getStringValue("aircraft-class", "NONE" );
acOperator = node->getStringValue("aircraft-operator", "NONE" ); acOperator = node->getStringValue("aircraft-operator", "NONE" );
} catch (const sg_exception &) { } catch (const sg_exception &) {
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
"Could not load aircraft aircrat type and operator information from: " << acData.str() << ". Using defaults"); "Could not load aircraft aircrat type and operator information from: " << acData << ". Using defaults");
// cout << path.str() << endl; // cout << path.str() << endl;
} }
if (fltType.empty() || fltType == "NONE") { if (fltType.empty() || fltType == "NONE") {
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
"Aircraft type information not found in: " << acData.str() << ". Using default value"); "Aircraft type information not found in: " << acData << ". Using default value");
fltType = fgGetString("/sim/aircraft-class" ); fltType = fgGetString("/sim/aircraft-class" );
} }
if (acOperator.empty() || fltType == "NONE") { if (acOperator.empty() || fltType == "NONE") {
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
"Aircraft operator information not found in: " << acData.str() << ". Using default value"); "Aircraft operator information not found in: " << acData << ". Using default value");
acOperator = fgGetString("/sim/aircraft-operator" ); acOperator = fgGetString("/sim/aircraft-operator" );
} }

View file

@ -191,6 +191,6 @@ std::string fgValidatePath (const std::string& path, bool write)
// no match found // no match found
return ""; return "";
} }
std::string fgValidatePath(const SGPath& path, bool write) { return fgValidatePath(path.str(),write); } std::string fgValidatePath(const SGPath& path, bool write) { return fgValidatePath(path.utf8Str(),write); }
// end of util.cxx // end of util.cxx

View file

@ -30,10 +30,10 @@
static osg::Node * static osg::Node *
fgLoad3DModelPanel(const std::string &path, SGPropertyNode *prop_root) fgLoad3DModelPanel(const SGPath &path, SGPropertyNode *prop_root)
{ {
bool loadPanels = true; bool loadPanels = true;
osg::Node* node = simgear::SGModelLib::loadModel(path, prop_root, NULL, loadPanels); osg::Node* node = simgear::SGModelLib::loadModel(path.local8BitStr(), prop_root, NULL, loadPanels);
if (node) if (node)
node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
return node; return node;
@ -82,7 +82,7 @@ FGAircraftModel::init ()
osg::Node* node = NULL; osg::Node* node = NULL;
try { try {
node = fgLoad3DModelPanel( resolvedPath.str(), globals->get_props()); node = fgLoad3DModelPanel( resolvedPath, globals->get_props());
} catch (const sg_exception &ex) { } catch (const sg_exception &ex) {
SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to load aircraft from " << path << ':'); SG_LOG(SG_AIRCRAFT, SG_ALERT, "Failed to load aircraft from " << path << ':');
SG_LOG(SG_AIRCRAFT, SG_ALERT, " " << ex.getFormattedMessage()); SG_LOG(SG_AIRCRAFT, SG_ALERT, " " << ex.getFormattedMessage());
@ -110,7 +110,7 @@ FGAircraftModel::init ()
// no models loaded, load the glider instead // no models loaded, load the glider instead
if (!_aircraft.get()) { if (!_aircraft.get()) {
SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)"); SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)");
osg::Node* model = fgLoad3DModelPanel( "Models/Geometry/glider.ac", osg::Node* model = fgLoad3DModelPanel( SGPath::fromLocal8Bit("Models/Geometry/glider.ac"),
globals->get_props()); globals->get_props());
_aircraft.reset(new SGModelPlacement); _aircraft.reset(new SGModelPlacement);
_aircraft->init(model); _aircraft->init(model);

View file

@ -576,7 +576,7 @@ void FlightPlan::setApproach(flightgear::Approach *app)
bool FlightPlan::save(const SGPath& path) bool FlightPlan::save(const SGPath& path)
{ {
SG_LOG(SG_NAVAID, SG_INFO, "Saving route to " << path.str()); SG_LOG(SG_NAVAID, SG_INFO, "Saving route to " << path);
try { try {
SGPropertyNode_ptr d(new SGPropertyNode); SGPropertyNode_ptr d(new SGPropertyNode);
d->setIntValue("version", 2); d->setIntValue("version", 2);
@ -615,10 +615,10 @@ bool FlightPlan::save(const SGPath& path)
Waypt* wpt = _legs[i]->waypoint(); Waypt* wpt = _legs[i]->waypoint();
wpt->saveAsNode(routeNode->getChild("wp", i, true)); wpt->saveAsNode(routeNode->getChild("wp", i, true));
} // of waypoint iteration } // of waypoint iteration
writeProperties(path.str(), d, true /* write-all */); writeProperties(path, d, true /* write-all */);
return true; return true;
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_ALERT, "Failed to save flight-plan '" << path.str() << "'. " << e.getMessage()); SG_LOG(SG_NAVAID, SG_ALERT, "Failed to save flight-plan '" << path << "'. " << e.getMessage());
return false; return false;
} }
} }
@ -627,12 +627,12 @@ bool FlightPlan::load(const SGPath& path)
{ {
if (!path.exists()) if (!path.exists())
{ {
SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << path.str() SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << path
<< "'. The file does not exist."); << "'. The file does not exist.");
return false; return false;
} }
SG_LOG(SG_NAVAID, SG_INFO, "going to read flight-plan from:" << path.str()); SG_LOG(SG_NAVAID, SG_INFO, "going to read flight-plan from:" << path);
bool Status = false; bool Status = false;
lockDelegate(); lockDelegate();
@ -727,7 +727,7 @@ bool FlightPlan::loadGpxFormat(const SGPath& path)
GpxXmlVisitor gpxVistor(this); GpxXmlVisitor gpxVistor(this);
try try
{ {
readXML(path.str(), gpxVistor); readXML(path.local8BitStr(), gpxVistor);
} catch (sg_exception& e) } catch (sg_exception& e)
{ {
// XML parsing fails => not a GPX XML file // XML parsing fails => not a GPX XML file
@ -750,7 +750,7 @@ bool FlightPlan::loadXmlFormat(const SGPath& path)
{ {
SGPropertyNode_ptr routeData(new SGPropertyNode); SGPropertyNode_ptr routeData(new SGPropertyNode);
try { try {
readProperties(path.str(), routeData); readProperties(path, routeData);
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << e.getOrigin() SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << e.getOrigin()
<< "'. " << e.getMessage()); << "'. " << e.getMessage());
@ -949,7 +949,7 @@ bool FlightPlan::loadPlainTextFormat(const SGPath& path)
_legs.push_back(new Leg(this, w)); _legs.push_back(new Leg(this, w));
} // of line iteration } // of line iteration
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load route from: '" << path.str() << "'. " << e.getMessage()); SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load route from: '" << path << "'. " << e.getMessage());
_legs.clear(); _legs.clear();
return false; return false;
} }

View file

@ -44,7 +44,7 @@ void NavdataVisitor::startElement(const char* name, const XMLAttributes &atts)
if (tag == "Airport") { if (tag == "Airport") {
string icao(atts.getValue("ICAOcode")); string icao(atts.getValue("ICAOcode"));
if (_airport->ident() != icao) { if (_airport->ident() != icao) {
throw sg_format_exception("Airport and ICAO mismatch", icao, _path.str()); throw sg_format_exception("Airport and ICAO mismatch", icao, _path.utf8Str());
} }
} else if (tag == "Sid") { } else if (tag == "Sid") {
string ident(atts.getValue("Name")); string ident(atts.getValue("Name"));

View file

@ -91,9 +91,10 @@ namespace flightgear
void SHPParser::parsePolyLines(const SGPath& aPath, PolyLine::Type aTy, void SHPParser::parsePolyLines(const SGPath& aPath, PolyLine::Type aTy,
PolyLineList& aResult, bool aClosed) PolyLineList& aResult, bool aClosed)
{ {
gzFile file = gzopen(aPath.c_str(), "rb"); std::string s = aPath.local8BitStr();
gzFile file = gzopen(s.c_str(), "rb");
if (!file) { if (!file) {
throw sg_io_exception("couldn't open file:" + aPath.str()); throw sg_io_exception("couldn't open file:", aPath);
} }
try { try {

View file

@ -129,10 +129,10 @@ void Airway::load(const SGPath& path)
//int airwayIndex = 0; //int airwayIndex = 0;
//FGNode *n; //FGNode *n;
sg_gzifstream in( path.str() ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path );
throw sg_io_exception("Could not open airways data", sg_location(path.str())); throw sg_io_exception("Could not open airways data", path);
} }
// toss the first two lines of the file // toss the first two lines of the file
in >> skipeol; in >> skipeol;

View file

@ -50,7 +50,7 @@ const unsigned int LINES_IN_FIX_DAT = 119724;
void loadFixes(const SGPath& path) void loadFixes(const SGPath& path)
{ {
sg_gzifstream in( path.str() ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
throw sg_io_exception("Cannot open file:", path); throw sg_io_exception("Cannot open file:", path);
} }

View file

@ -265,9 +265,9 @@ const unsigned int LINES_IN_NAV_DAT = 26775;
// load and initialize the navigational databases // load and initialize the navigational databases
bool navDBInit(const SGPath& path) bool navDBInit(const SGPath& path)
{ {
sg_gzifstream in( path.str() ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path );
return false; return false;
} }
@ -299,11 +299,11 @@ bool navDBInit(const SGPath& path)
bool loadCarrierNav(const SGPath& path) bool loadCarrierNav(const SGPath& path)
{ {
SG_LOG( SG_NAVAID, SG_DEBUG, "opening file: " << path.str() ); SG_LOG( SG_NAVAID, SG_DEBUG, "opening file: " << path );
sg_gzifstream incarrier( path.str() ); sg_gzifstream incarrier( path );
if ( !incarrier.is_open() ) { if ( !incarrier.is_open() ) {
SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path );
return false; return false;
} }
@ -318,11 +318,11 @@ bool loadCarrierNav(const SGPath& path)
bool loadTacan(const SGPath& path, FGTACANList *channellist) bool loadTacan(const SGPath& path, FGTACANList *channellist)
{ {
SG_LOG( SG_NAVAID, SG_DEBUG, "opening file: " << path.str() ); SG_LOG( SG_NAVAID, SG_DEBUG, "opening file: " << path );
sg_gzifstream inchannel( path.str() ); sg_gzifstream inchannel( path );
if ( !inchannel.is_open() ) { if ( !inchannel.is_open() ) {
SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path );
return false; return false;
} }

View file

@ -92,9 +92,9 @@ static PositionedID readPOIFromStream(std::istream& aStream, NavDataCache* cache
// load and initialize the POI database // load and initialize the POI database
bool poiDBInit(const SGPath& path) bool poiDBInit(const SGPath& path)
{ {
sg_gzifstream in( path.str() ); sg_gzifstream in( path );
if ( !in.is_open() ) { if ( !in.is_open() ) {
SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() ); SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path );
return false; return false;
} }

View file

@ -63,7 +63,7 @@ bool isMachRestrict(RouteRestriction rr)
{ {
return (rr == SPEED_RESTRICT_MACH) || (rr == SPEED_COMPUTED_MACH); return (rr == SPEED_RESTRICT_MACH) || (rr == SPEED_COMPUTED_MACH);
} }
Waypt::Waypt(RouteBase* aOwner) : Waypt::Waypt(RouteBase* aOwner) :
_altitudeFt(0.0), _altitudeFt(0.0),
_speed(0.0), _speed(0.0),
@ -78,23 +78,23 @@ Waypt::Waypt(RouteBase* aOwner) :
Waypt::~Waypt() Waypt::~Waypt()
{ {
} }
std::string Waypt::ident() const std::string Waypt::ident() const
{ {
return ""; return "";
} }
bool Waypt::flag(WayptFlag aFlag) const bool Waypt::flag(WayptFlag aFlag) const
{ {
return ((_flags & aFlag) != 0); return ((_flags & aFlag) != 0);
} }
void Waypt::setFlag(WayptFlag aFlag, bool aV) void Waypt::setFlag(WayptFlag aFlag, bool aV)
{ {
if (aFlag == 0) { if (aFlag == 0) {
throw sg_range_exception("invalid waypoint flag set"); throw sg_range_exception("invalid waypoint flag set");
} }
_flags = (_flags & ~aFlag); _flags = (_flags & ~aFlag);
if (aV) _flags |= aFlag; if (aV) _flags |= aFlag;
} }
@ -105,7 +105,7 @@ bool Waypt::matches(Waypt* aOther) const
if (ident() != aOther->ident()) { // cheap check first if (ident() != aOther->ident()) { // cheap check first
return false; return false;
} }
return matches(aOther->position()); return matches(aOther->position());
} }
@ -133,7 +133,7 @@ double Waypt::speedKts() const
assert(_speedRestrict != SPEED_RESTRICT_MACH); assert(_speedRestrict != SPEED_RESTRICT_MACH);
return speed(); return speed();
} }
double Waypt::speedMach() const double Waypt::speedMach() const
{ {
assert(_speedRestrict == SPEED_RESTRICT_MACH); assert(_speedRestrict == SPEED_RESTRICT_MACH);
@ -145,19 +145,19 @@ double Waypt::magvarDeg() const
if (_magVarDeg == NO_MAG_VAR) { if (_magVarDeg == NO_MAG_VAR) {
// derived classes with a default pos must override this method // derived classes with a default pos must override this method
assert(!(position() == SGGeod())); assert(!(position() == SGGeod()));
double jd = globals->get_time_params()->getJD(); double jd = globals->get_time_params()->getJD();
_magVarDeg = sgGetMagVar(position(), jd) * SG_RADIANS_TO_DEGREES; _magVarDeg = sgGetMagVar(position(), jd) * SG_RADIANS_TO_DEGREES;
} }
return _magVarDeg; return _magVarDeg;
} }
double Waypt::headingRadialDeg() const double Waypt::headingRadialDeg() const
{ {
return 0.0; return 0.0;
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// persistence // persistence
@ -170,9 +170,9 @@ static RouteRestriction restrictionFromString(const char* aStr)
if (l == "below") return RESTRICT_BELOW; if (l == "below") return RESTRICT_BELOW;
if (l == "none") return RESTRICT_NONE; if (l == "none") return RESTRICT_NONE;
if (l == "mach") return SPEED_RESTRICT_MACH; if (l == "mach") return SPEED_RESTRICT_MACH;
if (l.empty()) return RESTRICT_NONE; if (l.empty()) return RESTRICT_NONE;
throw sg_io_exception("unknown restriction specification:" + l, throw sg_io_exception("unknown restriction specification:" + l,
"Route restrictFromString"); "Route restrictFromString");
} }
@ -184,7 +184,7 @@ static const char* restrictionToString(RouteRestriction aRestrict)
case RESTRICT_ABOVE: return "above"; case RESTRICT_ABOVE: return "above";
case RESTRICT_NONE: return "none"; case RESTRICT_NONE: return "none";
case SPEED_RESTRICT_MACH: return "mach"; case SPEED_RESTRICT_MACH: return "mach";
default: default:
throw sg_exception("invalid route restriction", throw sg_exception("invalid route restriction",
"Route restrictToString"); "Route restrictToString");
@ -222,17 +222,17 @@ Waypt* Waypt::createInstance(RouteBase* aOwner, const std::string& aTypeName)
throw sg_exception("broken factory method for type:" + aTypeName, throw sg_exception("broken factory method for type:" + aTypeName,
"Waypt::createInstance"); "Waypt::createInstance");
} }
return r; return r;
} }
WayptRef Waypt::createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp) WayptRef Waypt::createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp)
{ {
if (!aProp->hasChild("type")) { if (!aProp->hasChild("type")) {
throw sg_io_exception("bad props node, no type provided", throw sg_io_exception("bad props node, no type provided",
"Waypt::createFromProperties"); "Waypt::createFromProperties");
} }
try { try {
WayptRef nd(createInstance(aOwner, aProp->getStringValue("type"))); WayptRef nd(createInstance(aOwner, aProp->getStringValue("type")));
nd->initFromProperties(aProp); nd->initFromProperties(aProp);
@ -240,14 +240,14 @@ WayptRef Waypt::createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_GENERAL, SG_WARN, "failed to create waypoint, trying basic:" << e.getMessage()); SG_LOG(SG_GENERAL, SG_WARN, "failed to create waypoint, trying basic:" << e.getMessage());
} }
// if we failed to make the waypoint, try again making a basic waypoint. // if we failed to make the waypoint, try again making a basic waypoint.
// this handles the case where a navaid waypoint is missing, for example // this handles the case where a navaid waypoint is missing, for example
WayptRef nd(new BasicWaypt(aOwner)); WayptRef nd(new BasicWaypt(aOwner));
nd->initFromProperties(aProp); nd->initFromProperties(aProp);
return nd; return nd;
} }
void Waypt::saveAsNode(SGPropertyNode* n) const void Waypt::saveAsNode(SGPropertyNode* n) const
{ {
n->setStringValue("type", type()); n->setStringValue("type", type());
@ -257,40 +257,40 @@ void Waypt::saveAsNode(SGPropertyNode* n) const
void Waypt::initFromProperties(SGPropertyNode_ptr aProp) void Waypt::initFromProperties(SGPropertyNode_ptr aProp)
{ {
if (aProp->hasChild("generated")) { if (aProp->hasChild("generated")) {
setFlag(WPT_GENERATED, aProp->getBoolValue("generated")); setFlag(WPT_GENERATED, aProp->getBoolValue("generated"));
} }
if (aProp->hasChild("overflight")) { if (aProp->hasChild("overflight")) {
setFlag(WPT_OVERFLIGHT, aProp->getBoolValue("overflight")); setFlag(WPT_OVERFLIGHT, aProp->getBoolValue("overflight"));
} }
if (aProp->hasChild("arrival")) { if (aProp->hasChild("arrival")) {
setFlag(WPT_ARRIVAL, aProp->getBoolValue("arrival")); setFlag(WPT_ARRIVAL, aProp->getBoolValue("arrival"));
} }
if (aProp->hasChild("approach")) { if (aProp->hasChild("approach")) {
setFlag(WPT_APPROACH, aProp->getBoolValue("approach")); setFlag(WPT_APPROACH, aProp->getBoolValue("approach"));
} }
if (aProp->hasChild("departure")) { if (aProp->hasChild("departure")) {
setFlag(WPT_DEPARTURE, aProp->getBoolValue("departure")); setFlag(WPT_DEPARTURE, aProp->getBoolValue("departure"));
} }
if (aProp->hasChild("miss")) { if (aProp->hasChild("miss")) {
setFlag(WPT_MISS, aProp->getBoolValue("miss")); setFlag(WPT_MISS, aProp->getBoolValue("miss"));
} }
if (aProp->hasChild("alt-restrict")) { if (aProp->hasChild("alt-restrict")) {
_altRestrict = restrictionFromString(aProp->getStringValue("alt-restrict")); _altRestrict = restrictionFromString(aProp->getStringValue("alt-restrict"));
_altitudeFt = aProp->getDoubleValue("altitude-ft"); _altitudeFt = aProp->getDoubleValue("altitude-ft");
} }
if (aProp->hasChild("speed-restrict")) { if (aProp->hasChild("speed-restrict")) {
_speedRestrict = restrictionFromString(aProp->getStringValue("speed-restrict")); _speedRestrict = restrictionFromString(aProp->getStringValue("speed-restrict"));
_speed = aProp->getDoubleValue("speed"); _speed = aProp->getDoubleValue("speed");
} }
} }
void Waypt::writeToProperties(SGPropertyNode_ptr aProp) const void Waypt::writeToProperties(SGPropertyNode_ptr aProp) const
@ -302,28 +302,28 @@ void Waypt::writeToProperties(SGPropertyNode_ptr aProp) const
if (flag(WPT_DEPARTURE)) { if (flag(WPT_DEPARTURE)) {
aProp->setBoolValue("departure", true); aProp->setBoolValue("departure", true);
} }
if (flag(WPT_ARRIVAL)) { if (flag(WPT_ARRIVAL)) {
aProp->setBoolValue("arrival", true); aProp->setBoolValue("arrival", true);
} }
if (flag(WPT_APPROACH)) { if (flag(WPT_APPROACH)) {
aProp->setBoolValue("approach", true); aProp->setBoolValue("approach", true);
} }
if (flag(WPT_MISS)) { if (flag(WPT_MISS)) {
aProp->setBoolValue("miss", true); aProp->setBoolValue("miss", true);
} }
if (flag(WPT_GENERATED)) { if (flag(WPT_GENERATED)) {
aProp->setBoolValue("generated", true); aProp->setBoolValue("generated", true);
} }
if (_altRestrict != RESTRICT_NONE) { if (_altRestrict != RESTRICT_NONE) {
aProp->setStringValue("alt-restrict", restrictionToString(_altRestrict)); aProp->setStringValue("alt-restrict", restrictionToString(_altRestrict));
aProp->setDoubleValue("altitude-ft", _altitudeFt); aProp->setDoubleValue("altitude-ft", _altitudeFt);
} }
if (_speedRestrict != RESTRICT_NONE) { if (_speedRestrict != RESTRICT_NONE) {
aProp->setStringValue("speed-restrict", restrictionToString(_speedRestrict)); aProp->setStringValue("speed-restrict", restrictionToString(_speedRestrict));
aProp->setDoubleValue("speed", _speed); aProp->setDoubleValue("speed", _speed);
@ -333,22 +333,21 @@ void Waypt::writeToProperties(SGPropertyNode_ptr aProp) const
void RouteBase::dumpRouteToKML(const WayptVec& aRoute, const std::string& aName) void RouteBase::dumpRouteToKML(const WayptVec& aRoute, const std::string& aName)
{ {
SGPath p = "/Users/jmt/Desktop/" + aName + ".kml"; SGPath p = "/Users/jmt/Desktop/" + aName + ".kml";
std::fstream f; sg_ofstream f(p);
f.open(p.str().c_str(), fstream::out | fstream::app);
if (!f.is_open()) { if (!f.is_open()) {
SG_LOG(SG_NAVAID, SG_WARN, "unable to open:" << p.str()); SG_LOG(SG_NAVAID, SG_WARN, "unable to open:" << p);
return; return;
} }
// pre-amble // pre-amble
f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
"<Document>\n"; "<Document>\n";
dumpRouteToKMLLineString(aName, aRoute, f); dumpRouteToKMLLineString(aName, aRoute, f);
// post-amble // post-amble
f << "</Document>\n" f << "</Document>\n"
"</kml>" << endl; "</kml>" << endl;
f.close(); f.close();
} }
@ -362,13 +361,13 @@ void RouteBase::dumpRouteToKMLLineString(const std::string& aIdent,
aStream << "<LineString>\n"; aStream << "<LineString>\n";
aStream << "<tessellate>1</tessellate>\n"; aStream << "<tessellate>1</tessellate>\n";
aStream << "<coordinates>\n"; aStream << "<coordinates>\n";
// waypoints // waypoints
for (unsigned int i=0; i<aRoute.size(); ++i) { for (unsigned int i=0; i<aRoute.size(); ++i) {
SGGeod pos = aRoute[i]->position(); SGGeod pos = aRoute[i]->position();
aStream << pos.getLongitudeDeg() << "," << pos.getLatitudeDeg() << " " << endl; aStream << pos.getLongitudeDeg() << "," << pos.getLatitudeDeg() << " " << endl;
} }
// postable // postable
aStream << "</coordinates>\n" aStream << "</coordinates>\n"
"</LineString>\n" "</LineString>\n"
@ -380,14 +379,14 @@ void RouteBase::loadAirportProcedures(const SGPath& aPath, FGAirport* aApt)
assert(aApt); assert(aApt);
try { try {
NavdataVisitor visitor(aApt, aPath); NavdataVisitor visitor(aApt, aPath);
readXML(aPath.str(), visitor); readXML(aPath.local8BitStr(), visitor);
} catch (sg_io_exception& ex) { } catch (sg_io_exception& ex) {
SG_LOG(SG_NAVAID, SG_WARN, "failure parsing procedures: " << aPath.str() << SG_LOG(SG_NAVAID, SG_WARN, "failure parsing procedures: " << aPath <<
"\n\t" << ex.getMessage() << "\n\tat:" << ex.getLocation().asString()); "\n\t" << ex.getMessage() << "\n\tat:" << ex.getLocation().asString());
} catch (sg_exception& ex) { } catch (sg_exception& ex) {
SG_LOG(SG_NAVAID, SG_WARN, "failure parsing procedures: " << aPath.str() << SG_LOG(SG_NAVAID, SG_WARN, "failure parsing procedures: " << aPath <<
"\n\t" << ex.getMessage()); "\n\t" << ex.getMessage());
} }
} }
} // of namespace flightgear } // of namespace flightgear

View file

@ -151,19 +151,19 @@ bool FGATCMain::open() {
exit( -1 ); exit( -1 );
} }
if ( input0_path.str().length() ) { if ( !input0_path.isNull() ) {
input0 = new FGATCInput( 0, input0_path ); input0 = new FGATCInput( 0, input0_path );
input0->open(); input0->open();
} }
if ( input1_path.str().length() ) { if ( !input1_path.isNull() ) {
input1 = new FGATCInput( 1, input1_path ); input1 = new FGATCInput( 1, input1_path );
input1->open(); input1->open();
} }
if ( output0_path.str().length() ) { if ( !output0_path.isNull() ) {
output0 = new FGATCOutput( 0, output0_path ); output0 = new FGATCOutput( 0, output0_path );
output0->open( lock0_fd ); output0->open( lock0_fd );
} }
if ( output1_path.str().length() ) { if ( !output1_path.isNull() ) {
output1 = new FGATCOutput( 1, output1_path ); output1 = new FGATCOutput( 1, output1_path );
output1->open( lock1_fd ); output1->open( lock1_fd );
} }

View file

@ -758,11 +758,11 @@ FGGeneric::reinit()
path.append(file_name.c_str()); path.append(file_name.c_str());
SG_LOG(SG_NETWORK, SG_INFO, "Reading communication protocol from " SG_LOG(SG_NETWORK, SG_INFO, "Reading communication protocol from "
<< path.str()); << path);
SGPropertyNode root; SGPropertyNode root;
try { try {
readProperties(path.str(), &root); readProperties(path, &root);
} catch (const sg_exception & ex) { } catch (const sg_exception & ex) {
SG_LOG(SG_NETWORK, SG_ALERT, SG_LOG(SG_NETWORK, SG_ALERT,
"Unable to load the protocol configuration file: " << ex.getFormattedMessage() ); "Unable to load the protocol configuration file: " << ex.getFormattedMessage() );

View file

@ -96,7 +96,8 @@ static cJSON * CatalogToJson( simgear::pkg::Catalog * c )
cJSON * json = cJSON_CreateObject(); cJSON * json = cJSON_CreateObject();
if( c ) { if( c ) {
cJSON_AddItemToObject(json, "id", cJSON_CreateString( c->id().c_str() )); cJSON_AddItemToObject(json, "id", cJSON_CreateString( c->id().c_str() ));
cJSON_AddItemToObject(json, "installRoot", cJSON_CreateString( c->installRoot().str().c_str() )); std::string s = c->installRoot().utf8Str();
cJSON_AddItemToObject(json, "installRoot", cJSON_CreateString( s.c_str() ));
cJSON_AddItemToObject(json, "url", cJSON_CreateString( c->url().c_str() )); cJSON_AddItemToObject(json, "url", cJSON_CreateString( c->url().c_str() ));
cJSON_AddItemToObject(json, "description", cJSON_CreateString( c->description().c_str() )); cJSON_AddItemToObject(json, "description", cJSON_CreateString( c->description().c_str() ));
cJSON_AddItemToObject(json, "packages", PackageListToJson(c->packages()) ); cJSON_AddItemToObject(json, "packages", PackageListToJson(c->packages()) );
@ -112,8 +113,8 @@ static string PackageRootCommand( simgear::pkg::Root* packageRoot, const string
cJSON * json = cJSON_CreateObject(); cJSON * json = cJSON_CreateObject();
if( command == "path" ) { if( command == "path" ) {
std::string p = packageRoot->path().utf8Str();
cJSON_AddItemToObject(json, "path", cJSON_CreateString( packageRoot->path().str().c_str() )); cJSON_AddItemToObject(json, "path", cJSON_CreateString( p.c_str() ));
} else if( command == "version" ) { } else if( command == "version" ) {

View file

@ -1,5 +1,5 @@
// antenna.cxx -- implementation of FGRadioAntenna // antenna.cxx -- implementation of FGRadioAntenna
// Class to represent a virtual radio antenna properties // Class to represent a virtual radio antenna properties
// Written by Adrian Musceac YO8RZZ, started December 2011. // Written by Adrian Musceac YO8RZZ, started December 2011.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
@ -26,12 +26,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <fstream> #include <fstream>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
#include <simgear/misc/sgstream.hxx>
#include "antenna.hxx" #include "antenna.hxx"
using namespace std; using namespace std;
FGRadioAntenna::FGRadioAntenna(string type) { FGRadioAntenna::FGRadioAntenna(string type) {
_mirror_y = 1; // normally we want to mirror these axis because the pattern is simetric _mirror_y = 1; // normally we want to mirror these axis because the pattern is simetric
_mirror_z = 1; _mirror_z = 1;
_invert_ground = 0; // TODO: use for inverting the antenna ground, for instance aircraft body reflection _invert_ground = 0; // TODO: use for inverting the antenna ground, for instance aircraft body reflection
@ -48,7 +50,7 @@ FGRadioAntenna::~FGRadioAntenna() {
// WIP // WIP
double FGRadioAntenna::calculate_gain(double bearing, double angle) { double FGRadioAntenna::calculate_gain(double bearing, double angle) {
// TODO: what if the pattern is assimetric? // TODO: what if the pattern is assimetric?
bearing = fabs(bearing); bearing = fabs(bearing);
if (bearing > 180) if (bearing > 180)
@ -61,18 +63,18 @@ double FGRadioAntenna::calculate_gain(double bearing, double angle) {
//cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl; //cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl;
for (unsigned i =0; i < _pattern.size(); i++) { for (unsigned i =0; i < _pattern.size(); i++) {
AntennaGain *point_gain = _pattern[i]; AntennaGain *point_gain = _pattern[i];
if ( (azimuth == point_gain->azimuth) && (elevation == point_gain->elevation)) { if ( (azimuth == point_gain->azimuth) && (elevation == point_gain->elevation)) {
return point_gain->gain; return point_gain->gain;
} }
} }
return 0; return 0;
} }
void FGRadioAntenna::load_NEC_antenna_pattern(string type) { void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
//SGPath pattern_file(globals->get_fg_home()); //SGPath pattern_file(globals->get_fg_home());
SGPath pattern_file(globals->get_fg_root()); SGPath pattern_file(globals->get_fg_root());
pattern_file.append("Navaids/Antennas"); pattern_file.append("Navaids/Antennas");
@ -80,7 +82,7 @@ void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
if (!pattern_file.exists()) { if (!pattern_file.exists()) {
return; return;
} }
ifstream file_in(pattern_file.c_str()); sg_ifstream file_in(pattern_file);
int heading, elevation; int heading, elevation;
double gain; double gain;
while(!file_in.eof()) { while(!file_in.eof()) {

View file

@ -1736,7 +1736,8 @@ static naRef f_route(naContext c, naRef me, int argc, naRef* args)
flightgear::FlightPlan* fp = new flightgear::FlightPlan; flightgear::FlightPlan* fp = new flightgear::FlightPlan;
SGPath path(naStr_data(args[0])); SGPath path(naStr_data(args[0]));
if (!path.exists()) { if (!path.exists()) {
naRuntimeError(c, "flightplan, no file at path %s", path.c_str()); std::string pdata = path.utf8Str();
naRuntimeError(c, "flightplan, no file at path %s", pdata.c_str());
} }
if (!fp->load(path)) { if (!fp->load(path)) {

View file

@ -42,12 +42,12 @@ SGPath::Permissions checkIORules(const SGPath& path)
// SGPath caches permissions, which breaks for relative paths // SGPath caches permissions, which breaks for relative paths
// if the current directory changes // if the current directory changes
SG_LOG(SG_NASAL, SG_ALERT, "os.path: file operation on '" << SG_LOG(SG_NASAL, SG_ALERT, "os.path: file operation on '" <<
path.str() << "' access denied (relative paths not accepted; use " path<< "' access denied (relative paths not accepted; use "
"realpath() to make a path absolute)"); "realpath() to make a path absolute)");
} }
perm.read = path.isAbsolute() && !fgValidatePath(path.str(), false).empty(); perm.read = path.isAbsolute() && !fgValidatePath(path, false).empty();
perm.write = path.isAbsolute() && !fgValidatePath(path.str(), true ).empty(); perm.write = path.isAbsolute() && !fgValidatePath(path, true ).empty();
return perm; return perm;
} }
@ -56,7 +56,7 @@ SGPath::Permissions checkIORules(const SGPath& path)
static naRef validatedPathToNasal( const nasal::CallContext& ctx, static naRef validatedPathToNasal( const nasal::CallContext& ctx,
const SGPath& p ) const SGPath& p )
{ {
return ctx.to_nasal( SGPathRef(new SGPath(p.str(), &checkIORules)) ); return ctx.to_nasal( SGPathRef(new SGPath(p.utf8Str(), &checkIORules)) );
} }
/** /**
@ -73,6 +73,11 @@ static int f_path_create_dir(SGPath& p, const nasal::CallContext& ctx)
return p.create_dir(ctx.getArg<mode_t>(0, 0755) & 0775); return p.create_dir(ctx.getArg<mode_t>(0, 0755) & 0775);
} }
static void f_path_set(SGPath& p, const nasal::CallContext& ctx)
{
p = SGPath::fromUtf8(ctx.getArg<std::string>(0), p.getPermissionChecker());
}
/** /**
* os.path.desktop() * os.path.desktop()
*/ */
@ -113,9 +118,8 @@ naRef initNasalSGPath(naRef globals, naContext c)
// See: http://docs.freeflightsim.org/simgear/classSGPath.html // See: http://docs.freeflightsim.org/simgear/classSGPath.html
NasalSGPath::init("os.path") NasalSGPath::init("os.path")
.method("set", &SGPath::set) .method("set", &f_path_set)
.method("append", &SGPath::append) .method("append", &SGPath::append)
.method("add", &SGPath::add)
.method("concat", &SGPath::concat) .method("concat", &SGPath::concat)
.member("realpath", &SGPath::realpath) .member("realpath", &SGPath::realpath)
@ -126,8 +130,7 @@ naRef initNasalSGPath(naRef globals, naContext c)
.member("extension", &SGPath::extension) .member("extension", &SGPath::extension)
.member("lower_extension", &SGPath::lower_extension) .member("lower_extension", &SGPath::lower_extension)
.member("complete_lower_extension", &SGPath::complete_lower_extension) .member("complete_lower_extension", &SGPath::complete_lower_extension)
.member("str", &SGPath::str) .member("str", &SGPath::utf8Str)
.member("str_native", &SGPath::str_native)
.member("mtime", &SGPath::modTime) .member("mtime", &SGPath::modTime)
.method("exists", &SGPath::exists) .method("exists", &SGPath::exists)

View file

@ -608,8 +608,8 @@ static naRef f_resolveDataPath(naContext c, naRef me, int argc, naRef* args)
naRuntimeError(c, "bad arguments to resolveDataPath()"); naRuntimeError(c, "bad arguments to resolveDataPath()");
SGPath p = globals->resolve_maybe_aircraft_path(naStr_data(args[0])); SGPath p = globals->resolve_maybe_aircraft_path(naStr_data(args[0]));
const char* pdata = p.c_str(); std::string pdata = p.utf8Str();
return naStr_fromdata(naNewString(c), const_cast<char*>(pdata), strlen(pdata)); return naStr_fromdata(naNewString(c), const_cast<char*>(pdata.c_str()), pdata.length());
} }
static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args) static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args)
@ -618,8 +618,8 @@ static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args)
naRuntimeError(c, "bad arguments to findDataDir()"); naRuntimeError(c, "bad arguments to findDataDir()");
SGPath p = globals->find_data_dir(naStr_data(args[0])); SGPath p = globals->find_data_dir(naStr_data(args[0]));
const char* pdata = p.c_str(); std::string pdata = p.utf8Str();
return naStr_fromdata(naNewString(c), const_cast<char*>(pdata), strlen(pdata)); return naStr_fromdata(naNewString(c), const_cast<char*>(pdata.c_str()), pdata.length());
} }
class NasalCommand : public SGCommandMgr::Command class NasalCommand : public SGCommandMgr::Command
@ -1032,7 +1032,7 @@ void FGNasalSys::addModule(string moduleName, simgear::PathList scripts)
SGPropertyNode* module_node = nasal->getChild(moduleName,0,true); SGPropertyNode* module_node = nasal->getChild(moduleName,0,true);
for (unsigned int i=0; i<scripts.size(); ++i) { for (unsigned int i=0; i<scripts.size(); ++i) {
SGPropertyNode* pFileNode = module_node->getChild("file",i,true); SGPropertyNode* pFileNode = module_node->getChild("file",i,true);
pFileNode->setStringValue(scripts[i].c_str()); pFileNode->setStringValue(scripts[i].utf8Str());
} }
if (!module_node->hasChild("enabled",0)) if (!module_node->hasChild("enabled",0))
{ {
@ -1146,15 +1146,16 @@ void FGNasalSys::logError(naContext context)
bool FGNasalSys::loadModule(SGPath file, const char* module) bool FGNasalSys::loadModule(SGPath file, const char* module)
{ {
int len = 0; int len = 0;
char* buf = readfile(file.c_str(), &len); std::string pdata = file.local8BitStr();
char* buf = readfile(pdata.c_str(), &len);
if(!buf) { if(!buf) {
SG_LOG(SG_NASAL, SG_ALERT, SG_LOG(SG_NASAL, SG_ALERT,
"Nasal error: could not read script file " << file.c_str() "Nasal error: could not read script file " << file
<< " into module " << module); << " into module " << module);
return false; return false;
} }
bool ok = createModule(module, file.c_str(), buf, len); bool ok = createModule(module, pdata.c_str(), buf, len);
delete[] buf; delete[] buf;
return ok; return ok;
} }

View file

@ -116,14 +116,14 @@ FGFX::init()
return; return;
} }
SG_LOG(SG_SOUND, SG_INFO, "Reading sound " << node->getName() SG_LOG(SG_SOUND, SG_INFO, "Reading sound " << node->getName()
<< " from " << path.str()); << " from " << path);
SGPropertyNode root; SGPropertyNode root;
try { try {
readProperties(path.str(), &root); readProperties(path, &root);
} catch (const sg_exception &) { } catch (const sg_exception &) {
SG_LOG(SG_SOUND, SG_ALERT, SG_LOG(SG_SOUND, SG_ALERT,
"Error reading file '" << path.str() << '\''); "Error reading file '" << path << '\'');
return; return;
} }

View file

@ -382,7 +382,7 @@ void FGElectricalSystem::init () {
<< config.str() ); << config.str() );
#endif #endif
try { try {
readProperties( config.str(), config_props ); readProperties( config, config_props );
if ( build(config_props) ) { if ( build(config_props) ) {
enabled = true; enabled = true;
@ -392,7 +392,7 @@ void FGElectricalSystem::init () {
} catch (const sg_exception&) { } catch (const sg_exception&) {
SG_LOG( SG_SYSTEMS, SG_ALERT, SG_LOG( SG_SYSTEMS, SG_ALERT,
"Failed to load electrical system model: " "Failed to load electrical system model: "
<< config.str() ); << config );
} }
} else { } else {
SG_LOG( SG_SYSTEMS, SG_INFO, SG_LOG( SG_SYSTEMS, SG_INFO,

View file

@ -38,16 +38,16 @@ FGSystemMgr::FGSystemMgr ()
SGPath config = globals->resolve_aircraft_path(path_n->getStringValue()); SGPath config = globals->resolve_aircraft_path(path_n->getStringValue());
SG_LOG( SG_SYSTEMS, SG_INFO, "Reading systems from " SG_LOG( SG_SYSTEMS, SG_INFO, "Reading systems from "
<< config.str() ); << config );
try try
{ {
readProperties( config.str(), config_props ); readProperties( config, config_props );
build(config_props); build(config_props);
} }
catch( const sg_exception& ) catch( const sg_exception& )
{ {
SG_LOG( SG_SYSTEMS, SG_ALERT, "Failed to load systems system model: " SG_LOG( SG_SYSTEMS, SG_ALERT, "Failed to load systems system model: "
<< config.str() ); << config );
} }
} else { } else {

View file

@ -335,7 +335,7 @@ void TimeManager::updateLocalTime()
{ {
SGPath zone(globals->get_fg_root()); SGPath zone(globals->get_fg_root());
zone.append("Timezone"); zone.append("Timezone");
_impl->updateLocal(globals->get_aircraft_position(), zone.str()); _impl->updateLocal(globals->get_aircraft_position(), zone.local8BitStr());
} }
void TimeManager::initTimeOffset() void TimeManager::initTimeOffset()

View file

@ -105,20 +105,20 @@ void FGLight::init () {
// initialize ambient, diffuse and specular tables // initialize ambient, diffuse and specular tables
SGPath ambient_path = path; SGPath ambient_path = path;
ambient_path.append( "Lighting/ambient" ); ambient_path.append( "Lighting/ambient" );
_ambient_tbl = new SGInterpTable( ambient_path.str() ); _ambient_tbl = new SGInterpTable( ambient_path );
SGPath diffuse_path = path; SGPath diffuse_path = path;
diffuse_path.append( "Lighting/diffuse" ); diffuse_path.append( "Lighting/diffuse" );
_diffuse_tbl = new SGInterpTable( diffuse_path.str() ); _diffuse_tbl = new SGInterpTable( diffuse_path );
SGPath specular_path = path; SGPath specular_path = path;
specular_path.append( "Lighting/specular" ); specular_path.append( "Lighting/specular" );
_specular_tbl = new SGInterpTable( specular_path.str() ); _specular_tbl = new SGInterpTable( specular_path );
// initialize sky table // initialize sky table
SGPath sky_path = path; SGPath sky_path = path;
sky_path.append( "Lighting/sky" ); sky_path.append( "Lighting/sky" );
_sky_tbl = new SGInterpTable( sky_path.str() ); _sky_tbl = new SGInterpTable( sky_path );
globals->get_event_mgr()->addTask("updateSunPos", this, globals->get_event_mgr()->addTask("updateSunPos", this,
&FGLight::updateSunPos, 0.5 ); &FGLight::updateSunPos, 0.5 );

View file

@ -19,19 +19,19 @@
* *
**************************************************************************/ **************************************************************************/
/* /*
* Traffic manager parses airlines timetable-like data and uses this to * Traffic manager parses airlines timetable-like data and uses this to
* determine the approximate position of each AI aircraft in its database. * determine the approximate position of each AI aircraft in its database.
* When an AI aircraft is close to the user's position, a more detailed * When an AI aircraft is close to the user's position, a more detailed
* AIModels based simulation is set up. * AIModels based simulation is set up.
* *
* I'm currently assuming the following simplifications: * I'm currently assuming the following simplifications:
* 1) The earth is a perfect sphere * 1) The earth is a perfect sphere
* 2) Each aircraft flies a perfect great circle route. * 2) Each aircraft flies a perfect great circle route.
* 3) Each aircraft flies at a constant speed (with infinite accelerations and * 3) Each aircraft flies at a constant speed (with infinite accelerations and
* decelerations) * decelerations)
* 4) Each aircraft leaves at exactly the departure time. * 4) Each aircraft leaves at exactly the departure time.
* 5) Each aircraft arrives at exactly the specified arrival time. * 5) Each aircraft arrives at exactly the specified arrival time.
* *
* *
*****************************************************************************/ *****************************************************************************/
@ -54,6 +54,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/misc/sg_dir.hxx> #include <simgear/misc/sg_dir.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
@ -84,7 +85,7 @@ using std::string;
using std::vector; using std::vector;
/** /**
* Thread encapsulating parsing the traffic schedules. * Thread encapsulating parsing the traffic schedules.
*/ */
class ScheduleParseThread : public SGThread, public XMLVisitor class ScheduleParseThread : public SGThread, public XMLVisitor
{ {
@ -100,9 +101,9 @@ public:
offset(0), offset(0),
heavy(false) heavy(false)
{ {
} }
// if we're destroyed while running, ensure the thread exits cleanly // if we're destroyed while running, ensure the thread exits cleanly
~ScheduleParseThread() ~ScheduleParseThread()
{ {
@ -115,18 +116,18 @@ public:
_lock.unlock(); _lock.unlock();
} }
} }
void setTrafficDirs(const PathList& dirs) void setTrafficDirs(const PathList& dirs)
{ {
_trafficDirPaths = dirs; _trafficDirPaths = dirs;
} }
bool isFinished() const bool isFinished() const
{ {
SGGuard<SGMutex> g(_lock); SGGuard<SGMutex> g(_lock);
return _isFinished; return _isFinished;
} }
virtual void run() virtual void run()
{ {
BOOST_FOREACH(SGPath p, _trafficDirPaths) { BOOST_FOREACH(SGPath p, _trafficDirPaths) {
@ -135,23 +136,23 @@ public:
return; return;
} }
} }
SGGuard<SGMutex> g(_lock); SGGuard<SGMutex> g(_lock);
_isFinished = true; _isFinished = true;
} }
void startXML() void startXML()
{ {
//cout << "Start XML" << endl; //cout << "Start XML" << endl;
requiredAircraft = ""; requiredAircraft = "";
homePort = ""; homePort = "";
} }
void endXML() void endXML()
{ {
//cout << "End XML" << endl; //cout << "End XML" << endl;
} }
void startElement(const char *name, void startElement(const char *name,
const XMLAttributes & atts) const XMLAttributes & atts)
{ {
@ -166,17 +167,17 @@ public:
SGPath path = globals->get_fg_root(); SGPath path = globals->get_fg_root();
path.append("/Traffic/"); path.append("/Traffic/");
path.append(attval); path.append(attval);
readXML(path.str(), *this); readXML(path.local8BitStr(), *this);
} }
elementValueStack.push_back(""); elementValueStack.push_back("");
// cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl; // cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
} }
void endElement(const char *name) void endElement(const char *name)
{ {
//cout << "End element " << name << endl; //cout << "End element " << name << endl;
const string & value = elementValueStack.back(); const string & value = elementValueStack.back();
if (!strcmp(name, "model")) if (!strcmp(name, "model"))
mdl = value; mdl = value;
else if (!strcmp(name, "livery")) else if (!strcmp(name, "livery"))
@ -228,7 +229,7 @@ public:
//cerr << "Pusing back flight " << callsign << endl; //cerr << "Pusing back flight " << callsign << endl;
//cerr << callsign << " " << fltrules << " "<< departurePort << " " << arrivalPort << " " //cerr << callsign << " " << fltrules << " "<< departurePort << " " << arrivalPort << " "
// << cruiseAlt << " " << departureTime<< " "<< arrivalTime << " " << repeat << endl; // << cruiseAlt << " " << departureTime<< " "<< arrivalTime << " " << repeat << endl;
//Prioritize aircraft //Prioritize aircraft
string apt = fgGetString("/sim/presets/airport-id"); string apt = fgGetString("/sim/presets/airport-id");
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl; //cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
@ -264,7 +265,7 @@ public:
<< departureTime << "," << departureTime << ","
<< arrivalTime << "," << repeat << "," << requiredAircraft); << arrivalTime << "," << repeat << "," << requiredAircraft);
} }
_trafficManager->flights[requiredAircraft].push_back(new FGScheduledFlight(callsign, _trafficManager->flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
fltrules, fltrules,
departurePort, departurePort,
@ -278,46 +279,46 @@ public:
} else if (!strcmp(name, "aircraft")) { } else if (!strcmp(name, "aircraft")) {
endAircraft(); endAircraft();
} }
elementValueStack.pop_back(); elementValueStack.pop_back();
} }
void data(const char *s, int len) void data(const char *s, int len)
{ {
string token = string(s, len); string token = string(s, len);
//cout << "Character data " << string(s,len) << endl; //cout << "Character data " << string(s,len) << endl;
elementValueStack.back() += token; elementValueStack.back() += token;
} }
void pi(const char *target, const char *data) void pi(const char *target, const char *data)
{ {
//cout << "Processing instruction " << target << ' ' << data << endl; //cout << "Processing instruction " << target << ' ' << data << endl;
} }
void warning(const char *message, int line, int column) void warning(const char *message, int line, int column)
{ {
SG_LOG(SG_IO, SG_WARN, SG_LOG(SG_IO, SG_WARN,
"Warning: " << message << " (" << line << ',' << column << ')'); "Warning: " << message << " (" << line << ',' << column << ')');
} }
void error(const char *message, int line, int column) void error(const char *message, int line, int column)
{ {
SG_LOG(SG_IO, SG_ALERT, SG_LOG(SG_IO, SG_ALERT,
"Error: " << message << " (" << line << ',' << column << ')'); "Error: " << message << " (" << line << ',' << column << ')');
} }
private: private:
void endAircraft() void endAircraft()
{ {
string isHeavy = heavy ? "true" : "false"; string isHeavy = heavy ? "true" : "false";
if (missingModels.find(mdl) != missingModels.end()) { if (missingModels.find(mdl) != missingModels.end()) {
// don't stat() or warn again // don't stat() or warn again
requiredAircraft = homePort = ""; requiredAircraft = homePort = "";
return; return;
} }
if (!FGAISchedule::validModelPath(mdl)) { if (!FGAISchedule::validModelPath(mdl)) {
missingModels.insert(mdl); missingModels.insert(mdl);
#if defined(ENABLE_DEV_WARNINGS) #if defined(ENABLE_DEV_WARNINGS)
@ -326,7 +327,7 @@ private:
requiredAircraft = homePort = ""; requiredAircraft = homePort = "";
return; return;
} }
int proportion = int proportion =
(int) (fgGetDouble("/sim/traffic-manager/proportion") * 100); (int) (fgGetDouble("/sim/traffic-manager/proportion") * 100);
int randval = rand() & 100; int randval = rand() & 100;
@ -334,13 +335,13 @@ private:
requiredAircraft = homePort = ""; requiredAircraft = homePort = "";
return; return;
} }
if (fgGetBool("/sim/traffic-manager/dumpdata") == true) { if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft
<< "," << acType << "," << livery << "," << "," << acType << "," << livery << ","
<< airline << "," << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl); << airline << "," << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl);
} }
if (requiredAircraft == "") { if (requiredAircraft == "") {
char buffer[16]; char buffer[16];
snprintf(buffer, 16, "%d", acCounter); snprintf(buffer, 16, "%d", acCounter);
@ -349,7 +350,7 @@ private:
if (homePort == "") { if (homePort == "") {
homePort = departurePort; homePort = departurePort;
} }
// caution, modifying the scheduled aircraft strucutre from the // caution, modifying the scheduled aircraft strucutre from the
// 'wrong' thread. This is safe becuase FGTrafficManager won't touch // 'wrong' thread. This is safe becuase FGTrafficManager won't touch
// the structure while we exist. // the structure while we exist.
@ -364,49 +365,49 @@ private:
m_class, m_class,
flighttype, flighttype,
radius, offset)); radius, offset));
acCounter++; acCounter++;
requiredAircraft = ""; requiredAircraft = "";
homePort = ""; homePort = "";
score = 0; score = 0;
} }
void parseTrafficDir(const SGPath& path) void parseTrafficDir(const SGPath& path)
{ {
SGTimeStamp st; SGTimeStamp st;
st.stamp(); st.stamp();
simgear::Dir trafficDir(path); simgear::Dir trafficDir(path);
simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT); simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
BOOST_FOREACH(SGPath p, d) { BOOST_FOREACH(SGPath p, d) {
simgear::Dir d2(p); simgear::Dir d2(p);
SG_LOG(SG_AI, SG_INFO, "parsing traffic in:" << p); SG_LOG(SG_AI, SG_INFO, "parsing traffic in:" << p);
simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml"); simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
BOOST_FOREACH(SGPath xml, trafficFiles) { BOOST_FOREACH(SGPath xml, trafficFiles) {
readXML(xml.str(), *this); readXML(xml.local8BitStr(), *this);
if (_cancelThread) { if (_cancelThread) {
return; return;
} }
} }
} // of sub-directories iteration } // of sub-directories iteration
SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec"); SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec");
} }
FGTrafficManager* _trafficManager; FGTrafficManager* _trafficManager;
mutable SGMutex _lock; mutable SGMutex _lock;
bool _isFinished; bool _isFinished;
bool _cancelThread; bool _cancelThread;
simgear::PathList _trafficDirPaths; simgear::PathList _trafficDirPaths;
// parser state // parser state
string_list elementValueStack; string_list elementValueStack;
// record model paths which are missing, to avoid duplicate // record model paths which are missing, to avoid duplicate
// warnings when parsing traffic schedules. // warnings when parsing traffic schedules.
std::set<std::string> missingModels; std::set<std::string> missingModels;
std::string mdl, livery, registration, callsign, fltrules, std::string mdl, livery, registration, callsign, fltrules,
port, timeString, departurePort, departureTime, arrivalPort, arrivalTime, port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
repeat, acType, airline, m_class, flighttype, requiredAircraft, homePort; repeat, acType, airline, m_class, flighttype, requiredAircraft, homePort;
@ -444,13 +445,13 @@ void FGTrafficManager::shutdown()
scheduleParser.reset(); scheduleParser.reset();
doingInit = false; doingInit = false;
} }
return; return;
} }
// Save the heuristics data // Save the heuristics data
bool saveData = false; bool saveData = false;
std::ofstream cachefile; sg_ofstream cachefile;
if (fgGetBool("/sim/traffic-manager/heuristics")) { if (fgGetBool("/sim/traffic-manager/heuristics")) {
SGPath cacheData(globals->get_fg_home()); SGPath cacheData(globals->get_fg_home());
cacheData.append("ai"); cacheData.append("ai");
@ -462,23 +463,23 @@ void FGTrafficManager::shutdown()
airport[0], airport[1], airport[2]); airport[0], airport[1], airport[2]);
cacheData.append(buffer); cacheData.append(buffer);
cacheData.append(airport + "-cache.txt"); cacheData.append(airport + "-cache.txt");
// Note: Intuitively, this doesn't make sense, but I do need to create the full file path first // Note: Intuitively, this doesn't make sense, but I do need to create the full file path first
// before creating the directories. The SimGear fgpath code has changed so that it first chops off // before creating the directories. The SimGear fgpath code has changed so that it first chops off
// the trailing dir separator and then determines the directory part of the file path by searching // the trailing dir separator and then determines the directory part of the file path by searching
// for the last dir separator. Effecively, this causes a full element of the directory tree to be // for the last dir separator. Effecively, this causes a full element of the directory tree to be
// skipped. // skipped.
SG_LOG(SG_GENERAL, SG_DEBUG, "Trying to create dir for : " << cacheData.c_str()); SG_LOG(SG_GENERAL, SG_DEBUG, "Trying to create dir for : " << cacheData);
if (!cacheData.exists()) { if (!cacheData.exists()) {
cacheData.create_dir(0755); cacheData.create_dir(0755);
} }
saveData = true; saveData = true;
cachefile.open(cacheData.str().c_str()); cachefile.open(cacheData);
cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl; cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl;
} }
} }
BOOST_FOREACH(FGAISchedule* acft, scheduledAircraft) { BOOST_FOREACH(FGAISchedule* acft, scheduledAircraft) {
if (saveData) { if (saveData) {
cachefile << acft->getRegistration() << " " cachefile << acft->getRegistration() << " "
@ -507,7 +508,7 @@ void FGTrafficManager::init()
} }
// TorstenD: don't start the traffic manager before the FDM is initialized // TorstenD: don't start the traffic manager before the FDM is initialized
// The FDM needs the scenery loaded and will wait for our spawned AIModels PagedLOD Nodes // The FDM needs the scenery loaded and will wait for our spawned AIModels PagedLOD Nodes
// to appear if they are close (less than 1000m) to our position // to appear if they are close (less than 1000m) to our position
if( !fgGetBool("/sim/signals/fdm-initialized") ) if( !fgGetBool("/sim/signals/fdm-initialized") )
return; return;
@ -521,22 +522,22 @@ void FGTrafficManager::init()
terraSync->scheduleDataDir("AI/Traffic"); terraSync->scheduleDataDir("AI/Traffic");
trafficSyncRequested = true; trafficSyncRequested = true;
} }
if (terraSync->isDataDirPending("AI/Traffic")) { if (terraSync->isDataDirPending("AI/Traffic")) {
return; // remain in the init state return; // remain in the init state
} }
SG_LOG(SG_AI, SG_INFO, "Traffic files sync complete"); SG_LOG(SG_AI, SG_INFO, "Traffic files sync complete");
} }
doingInit = true; doingInit = true;
if (string(fgGetString("/sim/traffic-manager/datafile")).empty()) { if (string(fgGetString("/sim/traffic-manager/datafile")).empty()) {
simgear::PathList dirs = globals->get_data_paths("AI/Traffic"); simgear::PathList dirs = globals->get_data_paths("AI/Traffic");
// temporary flag to restrict loading while traffic data is found // temporary flag to restrict loading while traffic data is found
// through terrasync /and/ fgdata. Ultimately we *do* want to be able to // through terrasync /and/ fgdata. Ultimately we *do* want to be able to
// overlay sources. // overlay sources.
if (dirs.size() > 1) { if (dirs.size() > 1) {
SGPath p = dirs.back(); SGPath p = dirs.back();
if (simgear::strutils::starts_with(p.utf8Str(), if (simgear::strutils::starts_with(p.utf8Str(),
@ -545,12 +546,12 @@ void FGTrafficManager::init()
dirs.pop_back(); dirs.pop_back();
} }
} }
if (dirs.empty()) { if (dirs.empty()) {
doingInit = false; doingInit = false;
return; return;
} }
scheduleParser.reset(new ScheduleParseThread(this)); scheduleParser.reset(new ScheduleParseThread(this));
scheduleParser->setTrafficDirs(dirs); scheduleParser->setTrafficDirs(dirs);
scheduleParser->start(); scheduleParser->start();
@ -563,7 +564,7 @@ void FGTrafficManager::init()
// use a SchedulerParser to parse, but run it in this thread, // use a SchedulerParser to parse, but run it in this thread,
// i.e don't start it // i.e don't start it
ScheduleParseThread parser(this); ScheduleParseThread parser(this);
readXML(path.str(), parser); readXML(path.local8BitStr(), parser);
} }
} else if (path.extension() == "conf") { } else if (path.extension() == "conf") {
if (path.exists()) { if (path.exists()) {
@ -571,7 +572,7 @@ void FGTrafficManager::init()
} }
} else { } else {
SG_LOG(SG_AI, SG_ALERT, SG_LOG(SG_AI, SG_ALERT,
"Unknown data format " << path.str() "Unknown data format " << path
<< " for traffic"); << " for traffic");
} }
//exit(1); //exit(1);
@ -597,12 +598,12 @@ void FGTrafficManager::finishInit()
} }
#endif #endif
} }
sort(scheduledAircraft.begin(), scheduledAircraft.end(), sort(scheduledAircraft.begin(), scheduledAircraft.end(),
compareSchedules); compareSchedules);
currAircraft = scheduledAircraft.begin(); currAircraft = scheduledAircraft.begin();
currAircraftClosest = scheduledAircraft.begin(); currAircraftClosest = scheduledAircraft.begin();
doingInit = false; doingInit = false;
inited = true; inited = true;
} }
@ -612,7 +613,7 @@ void FGTrafficManager::loadHeuristics()
if (!fgGetBool("/sim/traffic-manager/heuristics")) { if (!fgGetBool("/sim/traffic-manager/heuristics")) {
return; return;
} }
HeuristicMap heurMap; HeuristicMap heurMap;
//cerr << "Processing Heuristics" << endl; //cerr << "Processing Heuristics" << endl;
// Load the heuristics data // Load the heuristics data
@ -627,11 +628,11 @@ void FGTrafficManager::loadHeuristics()
cacheData.append(airport + "-cache.txt"); cacheData.append(airport + "-cache.txt");
string revisionStr; string revisionStr;
if (cacheData.exists()) { if (cacheData.exists()) {
std::ifstream data(cacheData.c_str()); sg_ifstream data(cacheData);
data >> revisionStr; data >> revisionStr;
if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") { if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") {
SG_LOG(SG_AI, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " << SG_LOG(SG_AI, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " <<
cacheData.c_str() << " for Airport " << airport); cacheData << " for Airport " << airport);
} else { } else {
while (1) { while (1) {
Heuristic h; // = new Heuristic; Heuristic h; // = new Heuristic;
@ -650,8 +651,8 @@ void FGTrafficManager::loadHeuristics()
} }
} }
} }
} }
for(currAircraft = scheduledAircraft.begin(); currAircraft != scheduledAircraft.end(); ++currAircraft) { for(currAircraft = scheduledAircraft.begin(); currAircraft != scheduledAircraft.end(); ++currAircraft) {
const string& registration = (*currAircraft)->getRegistration(); const string& registration = (*currAircraft)->getRegistration();
HeuristicMapIterator itr = heurMap.find(registration); HeuristicMapIterator itr = heurMap.find(registration);
@ -714,21 +715,21 @@ void FGTrafficManager::update(double dt)
if (!doingInit) { if (!doingInit) {
init(); init();
} }
if (!doingInit || !scheduleParser->isFinished()) { if (!doingInit || !scheduleParser->isFinished()) {
return; return;
} }
finishInit(); finishInit();
} }
if (scheduledAircraft.empty()) { if (scheduledAircraft.empty()) {
return; return;
} }
SGVec3d userCart = globals->get_aircraft_position_cart(); SGVec3d userCart = globals->get_aircraft_position_cart();
if (currAircraft == scheduledAircraft.end()) { if (currAircraft == scheduledAircraft.end()) {
currAircraft = scheduledAircraft.begin(); currAircraft = scheduledAircraft.begin();
} }
@ -761,7 +762,8 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
string buffString; string buffString;
vector <string> tokens, depTime,arrTime; vector <string> tokens, depTime,arrTime;
vector <string>::iterator it; vector <string>::iterator it;
std::ifstream infile(infileName.str().c_str());
sg_ifstream infile(infileName);
while (1) { while (1) {
infile.getline(buffer, 256); infile.getline(buffer, 256);
if (infile.eof()) { if (infile.eof()) {
@ -778,10 +780,10 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
if (!tokens.empty()) { if (!tokens.empty()) {
if (tokens[0] == string("AC")) { if (tokens[0] == string("AC")) {
if (tokens.size() != 13) { if (tokens.size() != 13) {
throw sg_io_exception("Error parsing traffic file @ " + buffString, sg_location(infileName.str())); throw sg_io_exception("Error parsing traffic file @ " + buffString, infileName);
} }
model = tokens[12]; model = tokens[12];
livery = tokens[6]; livery = tokens[6];
homePort = tokens[1]; homePort = tokens[1];
@ -798,25 +800,25 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
FlightType = tokens[9]; FlightType = tokens[9];
radius = atof(tokens[8].c_str()); radius = atof(tokens[8].c_str());
offset = atof(tokens[7].c_str());; offset = atof(tokens[7].c_str());;
if (!FGAISchedule::validModelPath(model)) { if (!FGAISchedule::validModelPath(model)) {
SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" << SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" <<
model << " from " << infileName.str()); model << " from " << infileName);
} else { } else {
SG_LOG(SG_AI, SG_INFO, "Adding Aircraft" << model << " " << livery << " " << homePort << " " SG_LOG(SG_AI, SG_INFO, "Adding Aircraft" << model << " " << livery << " " << homePort << " "
<< registration << " " << flightReq << " " << isHeavy << registration << " " << flightReq << " " << isHeavy
<< " " << acType << " " << airline << " " << m_class << " " << acType << " " << airline << " " << m_class
<< " " << FlightType << " " << radius << " " << offset); << " " << FlightType << " " << radius << " " << offset);
scheduledAircraft.push_back(new FGAISchedule(model, scheduledAircraft.push_back(new FGAISchedule(model,
livery, livery,
homePort, homePort,
registration, registration,
flightReq, flightReq,
isHeavy, isHeavy,
acType, acType,
airline, airline,
m_class, m_class,
FlightType, FlightType,
radius, radius,
offset)); offset));
@ -825,7 +827,7 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
if (tokens[0] == string("FLIGHT")) { if (tokens[0] == string("FLIGHT")) {
//cerr << "Found flight " << buffString << " size is : " << tokens.size() << endl; //cerr << "Found flight " << buffString << " size is : " << tokens.size() << endl;
if (tokens.size() != 10) { if (tokens.size() != 10) {
SG_LOG(SG_AI, SG_ALERT, "Error parsing traffic file " << infileName.str() << " at " << buffString); SG_LOG(SG_AI, SG_ALERT, "Error parsing traffic file " << infileName << " at " << buffString);
exit(1); exit(1);
} }
string callsign = tokens[1]; string callsign = tokens[1];
@ -879,7 +881,7 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
<< cruiseAlt << " " << cruiseAlt << " "
<< departureTime << " " << departureTime << " "
<< arrivalTime << " " << arrivalTime << " "
<< repeat << " " << repeat << " "
<< requiredAircraft); << requiredAircraft);
flights[requiredAircraft].push_back(new FGScheduledFlight(callsign, flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
@ -920,5 +922,3 @@ void FGTrafficManager::Tokenize(const string& str,
pos = str.find_first_of(delimiters, lastPos); pos = str.find_first_of(delimiters, lastPos);
} }
} }

View file

@ -194,7 +194,8 @@ fgviewerMain(int argc, char** argv)
SGPath mpath( globals->get_fg_root() ); SGPath mpath( globals->get_fg_root() );
mpath.append( fgGetString("/sim/rendering/materials-file") ); mpath.append( fgGetString("/sim/rendering/materials-file") );
if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(), mpath.str(), if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(),
mpath.local8BitStr(),
globals->get_props()) ) { globals->get_props()) ) {
throw sg_io_exception("Error loading materials file", mpath); throw sg_io_exception("Error loading materials file", mpath);
} }

View file

@ -596,11 +596,11 @@ FGRenderer::init( void )
texture_path.append("Textures"); texture_path.append("Textures");
texture_path.append("Sky"); texture_path.append("Sky");
for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) { for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) {
SGCloudLayer * layer = new SGCloudLayer(texture_path.str()); SGCloudLayer * layer = new SGCloudLayer(texture_path.local8BitStr());
_sky->add_cloud_layer(layer); _sky->add_cloud_layer(layer);
} }
_sky->texture_path( texture_path.str() ); _sky->texture_path( texture_path.local8BitStr() );
if (!_classicalRenderer) { if (!_classicalRenderer) {
eventHandler->setChangeStatsCameraRenderOrder( true ); eventHandler->setChangeStatsCameraRenderOrder( true );

View file

@ -231,7 +231,7 @@ static osg::Node* fgCreateSplashCamera()
SGSharedPtr<SGPropertyNode> style = fgGetNode("/sim/gui/style[0]", true); SGSharedPtr<SGPropertyNode> style = fgGetNode("/sim/gui/style[0]", true);
osg::Texture2D* splashTexture = new osg::Texture2D; osg::Texture2D* splashTexture = new osg::Texture2D;
splashTexture->setImage(osgDB::readImageFile(tpath.c_str())); splashTexture->setImage(osgDB::readImageFile(tpath.local8BitStr()));
osg::Camera* camera = new osg::Camera; osg::Camera* camera = new osg::Camera;
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
@ -318,7 +318,7 @@ static osg::Node* fgCreateSplashCamera()
FGFontCache* fontCache = FGFontCache::instance(); FGFontCache* fontCache = FGFontCache::instance();
osgText::Text* text = new osgText::Text; osgText::Text* text = new osgText::Text;
std::string fn = style->getStringValue("fonts/splash", ""); std::string fn = style->getStringValue("fonts/splash", "");
text->setFont(fontCache->getfntpath(fn).str()); text->setFont(fontCache->getfntpath(fn).local8BitStr());
text->setCharacterSize(0.06); text->setCharacterSize(0.06);
text->setColor(osg::Vec4(1, 1, 1, 1)); text->setColor(osg::Vec4(1, 1, 1, 1));
text->setPosition(osg::Vec3(0, -0.92, 0)); text->setPosition(osg::Vec3(0, -0.92, 0));
@ -329,7 +329,7 @@ static osg::Node* fgCreateSplashCamera()
geode->addDrawable(text); geode->addDrawable(text);
osgText::Text* spinnertext = new osgText::Text; osgText::Text* spinnertext = new osgText::Text;
spinnertext->setFont(fontCache->getfntpath(fn).str()); spinnertext->setFont(fontCache->getfntpath(fn).local8BitStr());
spinnertext->setCharacterSize(0.06); spinnertext->setCharacterSize(0.06);
spinnertext->setColor(osg::Vec4(1, 1, 1, 1)); spinnertext->setColor(osg::Vec4(1, 1, 1, 1));
spinnertext->setPosition(osg::Vec3(0, -0.97, 0)); spinnertext->setPosition(osg::Vec3(0, -0.97, 0));
@ -340,7 +340,7 @@ static osg::Node* fgCreateSplashCamera()
geode->addDrawable(spinnertext); geode->addDrawable(spinnertext);
text = new osgText::Text; text = new osgText::Text;
text->setFont(fontCache->getfntpath(fn).str()); text->setFont(fontCache->getfntpath(fn).local8BitStr());
text->setCharacterSize(0.08); text->setCharacterSize(0.08);
text->setColor(osg::Vec4(1, 1, 1, 1)); text->setColor(osg::Vec4(1, 1, 1, 1));
text->setPosition(osg::Vec3(0, 0.92, 0)); text->setPosition(osg::Vec3(0, 0.92, 0));
@ -351,7 +351,7 @@ static osg::Node* fgCreateSplashCamera()
text = new osgText::Text; text = new osgText::Text;
text->setFont(fontCache->getfntpath(fn).str()); text->setFont(fontCache->getfntpath(fn).local8BitStr());
text->setCharacterSize(0.06); text->setCharacterSize(0.06);
text->setColor(osg::Vec4(1, 1, 1, 1)); text->setColor(osg::Vec4(1, 1, 1, 1));
text->setPosition(osg::Vec3(0, 0.82, 0)); text->setPosition(osg::Vec3(0, 0.82, 0));

View file

@ -261,8 +261,10 @@ bool UGTrack::load_flight( const string &path ) {
// open the gps file // open the gps file
file = path; file.append( "gps.dat.gz" ); file = path; file.append( "gps.dat.gz" );
if ( (fgps = gzopen( file.c_str(), "r" )) == NULL ) { std::string fdata = file.local8BitStr();
printf("Cannot open %s\n", file.c_str());
if ( (fgps = gzopen( fdata.c_str(), "r" )) == NULL ) {
printf("Cannot open %s\n", fdata.c_str());
return false; return false;
} }
@ -274,8 +276,9 @@ bool UGTrack::load_flight( const string &path ) {
// open the imu file // open the imu file
file = path; file.append( "imu.dat.gz" ); file = path; file.append( "imu.dat.gz" );
if ( (fimu = gzopen( file.c_str(), "r" )) == NULL ) { fdata = file.local8BitStr();
printf("Cannot open %s\n", file.c_str()); if ( (fimu = gzopen( fdata.c_str(), "r" )) == NULL ) {
printf("Cannot open %s\n", fdata.c_str());
return false; return false;
} }
@ -287,8 +290,10 @@ bool UGTrack::load_flight( const string &path ) {
// open the nav file // open the nav file
file = path; file.append( "nav.dat.gz" ); file = path; file.append( "nav.dat.gz" );
if ( (fnav = gzopen( file.c_str(), "r" )) == NULL ) { fdata = file.local8BitStr();
printf("Cannot open %s\n", file.c_str());
if ( (fnav = gzopen( fdata.c_str(), "r" )) == NULL ) {
printf("Cannot open %s\n", fdata.c_str());
return false; return false;
} }
@ -301,8 +306,10 @@ bool UGTrack::load_flight( const string &path ) {
// open the servo file // open the servo file
file = path; file.append( "servo.dat.gz" ); file = path; file.append( "servo.dat.gz" );
if ( (fservo = gzopen( file.c_str(), "r" )) == NULL ) { fdata = file.local8BitStr();
printf("Cannot open %s\n", file.c_str());
if ( (fservo = gzopen( fdata.c_str(), "r" )) == NULL ) {
printf("Cannot open %s\n", fdata.c_str());
return false; return false;
} }
@ -314,8 +321,10 @@ bool UGTrack::load_flight( const string &path ) {
// open the health file // open the health file
file = path; file.append( "health.dat.gz" ); file = path; file.append( "health.dat.gz" );
if ( (fhealth = gzopen( file.c_str(), "r" )) == NULL ) { fdata = file.local8BitStr();
printf("Cannot open %s\n", file.c_str());
if ( (fhealth = gzopen( fdata.c_str(), "r" )) == NULL ) {
printf("Cannot open %s\n", fdata.c_str());
return false; return false;
} }

View file

@ -105,21 +105,23 @@ main(int argc, char** argv)
fg_root = PKGLIBDIR; fg_root = PKGLIBDIR;
} }
std::string fg_scenery; SGPath fg_scenery;
if (arguments.read("--fg-scenery", fg_scenery)) { std::string s;
} else if (const char *fg_scenery_env = std::getenv("FG_SCENERY")) { if (arguments.read("--fg-scenery", s)) {
fg_scenery = fg_scenery_env; fg_scenery = SGPath::fromLocal8Bit(s.c_str());
} else if (std::getenv("FG_SCENERY")) {
fg_scenery = SGPath::fromEnv("FG_SCENERY");
} else { } else {
SGPath path(fg_root); SGPath path(fg_root);
path.append("Scenery"); path.append("Scenery");
fg_scenery = path.str(); fg_scenery = path;
} }
SGSharedPtr<SGPropertyNode> props = new SGPropertyNode; SGSharedPtr<SGPropertyNode> props = new SGPropertyNode;
try { try {
SGPath preferencesFile = fg_root; SGPath preferencesFile = fg_root;
preferencesFile.append("preferences.xml"); preferencesFile.append("preferences.xml");
readProperties(preferencesFile.str(), props); readProperties(preferencesFile, props);
} catch (...) { } catch (...) {
// In case of an error, at least make summer :) // In case of an error, at least make summer :)
props->getNode("sim/startup/season", true)->setStringValue("summer"); props->getNode("sim/startup/season", true)->setStringValue("summer");
@ -140,7 +142,7 @@ main(int argc, char** argv)
SGPath mpath(fg_root); SGPath mpath(fg_root);
mpath.append("Materials/default/materials.xml"); mpath.append("Materials/default/materials.xml");
try { try {
ml->load(fg_root, mpath.str(), props); ml->load(fg_root, mpath.local8BitStr(), props);
} catch (...) { } catch (...) {
SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n" SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n"
<< "Probably FG_ROOT is not properly set."); << "Probably FG_ROOT is not properly set.");
@ -153,7 +155,7 @@ main(int argc, char** argv)
options = new simgear::SGReaderWriterOptions(*ropt); options = new simgear::SGReaderWriterOptions(*ropt);
else else
options = new simgear::SGReaderWriterOptions; options = new simgear::SGReaderWriterOptions;
osgDB::convertStringPathIntoFilePathList(fg_scenery, osgDB::convertStringPathIntoFilePathList(fg_scenery.local8BitStr(),
options->getDatabasePathList()); options->getDatabasePathList());
options->setMaterialLib(ml); options->setMaterialLib(ml);
options->setPropertyNode(props); options->setPropertyNode(props);

View file

@ -175,9 +175,9 @@ void FGFontCache::init()
if (!_initialized) { if (!_initialized) {
char *envp = ::getenv("FG_FONTS"); char *envp = ::getenv("FG_FONTS");
if (envp != NULL) { if (envp != NULL) {
_path.set(envp); _path = SGPath::fromEnv("FG_FONTS");
} else { } else {
_path.set(ApplicationProperties::GetRootPath("Fonts").str()); _path = ApplicationProperties::GetRootPath("Fonts");
} }
_initialized = true; _initialized = true;
} }
@ -204,7 +204,8 @@ bool FGFontCache::initializeFonts()
{ {
static std::string fontext("txf"); static std::string fontext("txf");
init(); init();
ulDir* fontdir = ulOpenDir(_path.c_str()); std::string pdata = _path.local8BitStr();
ulDir* fontdir = ulOpenDir(pdata.c_str());
if (!fontdir) if (!fontdir)
return false; return false;
const ulDirEnt *dirEntry; const ulDirEnt *dirEntry;
@ -212,8 +213,9 @@ bool FGFontCache::initializeFonts()
SGPath path(_path); SGPath path(_path);
path.append(dirEntry->d_name); path.append(dirEntry->d_name);
if (path.extension() == fontext) { if (path.extension() == fontext) {
std::string fdata = path.local8BitStr();
fntTexFont* f = new fntTexFont; fntTexFont* f = new fntTexFont;
if (f->load((char *)path.c_str())) if (f->load((char *)fdata.c_str()))
_texFonts[std::string(dirEntry->d_name)] = f; _texFonts[std::string(dirEntry->d_name)] = f;
else else
delete f; delete f;

View file

@ -153,7 +153,7 @@ FGPanelApplication::FGPanelApplication( int argc, char ** argv ) :
try { try {
SGPath tpath = ApplicationProperties::GetRootPath( panelFilename.c_str() ); SGPath tpath = ApplicationProperties::GetRootPath( panelFilename.c_str() );
readProperties( tpath.str(), ApplicationProperties::Properties ); readProperties( tpath, ApplicationProperties::Properties );
} }
catch( sg_io_exception & e ) { catch( sg_io_exception & e ) {
cerr << e.getFormattedMessage() << endl; cerr << e.getFormattedMessage() << endl;
@ -353,7 +353,7 @@ SGPath ApplicationProperties::GetCwd()
buf[511] = '\0'; buf[511] = '\0';
if (cwd) if (cwd)
{ {
path = cwd; path = SGPath::fromLocal8Bit(cwd);
} }
return path; return path;
} }

View file

@ -117,8 +117,8 @@ void FGCroppedTexture::bind( bool doGLBind )
loader = textureLoader[extension]; loader = textureLoader[extension];
} }
_texture = loader->loadTexture( tpath.c_str() ); _texture = loader->loadTexture( tpath.local8BitStr() );
SG_LOG( SG_COCKPIT, SG_DEBUG, "Texture " << tpath.c_str() << " loaded from file as #" << _texture ); SG_LOG( SG_COCKPIT, SG_DEBUG, "Texture " << tpath << " loaded from file as #" << _texture );
cache[_path] = _texture; cache[_path] = _texture;
} }

View file

@ -60,29 +60,33 @@ main(int argc, char** argv)
sglog().set_log_classes(SG_ALL); sglog().set_log_classes(SG_ALL);
sglog().set_log_priority(SG_ALERT); sglog().set_log_priority(SG_ALERT);
std::string fg_root; SGPath fg_root;
if (arguments.read("--fg-root", fg_root)) { std::string r;
} else if (const char *fg_root_env = std::getenv("FG_ROOT")) { if (arguments.read("--fg-root", r)) {
fg_root = fg_root_env; fg_root = SGPath::fromLocal8Bit(r.c_str());
} else if (std::getenv("FG_ROOT")) {
fg_root = SGPath::fromEnv("FG_ROOT");
} else { } else {
fg_root = PKGLIBDIR; fg_root = SGPath(PKGLIBDIR);
} }
std::string fg_scenery; SGPath fg_scenery;
if (arguments.read("--fg-scenery", fg_scenery)) { std::string s;
} else if (const char *fg_scenery_env = std::getenv("FG_SCENERY")) { if (arguments.read("--fg-scenery", s)) {
fg_scenery = fg_scenery_env; fg_scenery = SGPath::fromLocal8Bit(s.c_str());
} else if (std::getenv("FG_SCENERY")) {
fg_scenery = SGPath::fromEnv("FG_SCENERY");
} else { } else {
SGPath path(fg_root); SGPath path(fg_root);
path.append("Scenery"); path.append("Scenery");
fg_scenery = path.str(); fg_scenery = path;
} }
SGSharedPtr<SGPropertyNode> props = new SGPropertyNode; SGSharedPtr<SGPropertyNode> props = new SGPropertyNode;
try { try {
SGPath preferencesFile = fg_root; SGPath preferencesFile = fg_root;
preferencesFile.append("preferences.xml"); preferencesFile.append("preferences.xml");
readProperties(preferencesFile.str(), props); readProperties(preferencesFile, props);
} catch (...) { } catch (...) {
// In case of an error, at least make summer :) // In case of an error, at least make summer :)
props->getNode("sim/startup/season", true)->setStringValue("summer"); props->getNode("sim/startup/season", true)->setStringValue("summer");
@ -183,12 +187,12 @@ main(int argc, char** argv)
SGPath mpath(fg_root); SGPath mpath(fg_root);
mpath.append("Materials/default/materials.xml"); mpath.append("Materials/default/materials.xml");
try { try {
ml->load(fg_root, mpath.str(), props); ml->load(fg_root.local8BitStr(), mpath.local8BitStr(), props);
} catch (...) { } catch (...) {
SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n" SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n"
<< "Probably FG_ROOT is not properly set."); << "Probably FG_ROOT is not properly set.");
} }
simgear::SGModelLib::init(fg_root, props); simgear::SGModelLib::init(fg_root.local8BitStr(), props);
// Set up the reader/writer options // Set up the reader/writer options
osg::ref_ptr<simgear::SGReaderWriterOptions> options; osg::ref_ptr<simgear::SGReaderWriterOptions> options;
@ -196,11 +200,11 @@ main(int argc, char** argv)
options = new simgear::SGReaderWriterOptions(*ropt); options = new simgear::SGReaderWriterOptions(*ropt);
else else
options = new simgear::SGReaderWriterOptions; options = new simgear::SGReaderWriterOptions;
osgDB::convertStringPathIntoFilePathList(fg_scenery, osgDB::convertStringPathIntoFilePathList(fg_scenery.local8BitStr(),
options->getDatabasePathList()); options->getDatabasePathList());
options->setMaterialLib(ml); options->setMaterialLib(ml);
options->setPropertyNode(props); options->setPropertyNode(props);
options->setPluginStringData("SimGear::FG_ROOT", fg_root); options->setPluginStringData("SimGear::FG_ROOT", fg_root.local8BitStr());
// Omit building bounding volume trees, as the viewer will not run a simulation // Omit building bounding volume trees, as the viewer will not run a simulation
options->setPluginStringData("SimGear::BOUNDINGVOLUMES", "OFF"); options->setPluginStringData("SimGear::BOUNDINGVOLUMES", "OFF");
viewer.setReaderWriterOptions(options.get()); viewer.setReaderWriterOptions(options.get());