Convert all the Nasal wrappers around FGPositioned to use ghost-member-access
Lazy-ness is good. Along the way, expose the course on ILS/LOC navaids to Nasal.
This commit is contained in:
parent
15724a6a44
commit
78afdb3c22
2 changed files with 174 additions and 110 deletions
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/magvar/magvar.hxx>
|
||||
#include <simgear/timing/sg_time.hxx>
|
||||
|
@ -51,6 +52,15 @@ static void positionedGhostDestroy(void* g);
|
|||
static void wayptGhostDestroy(void* g);
|
||||
naGhostType PositionedGhostType = { positionedGhostDestroy, "positioned" };
|
||||
|
||||
static const char* airportGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||
naGhostType AirportGhostType = { positionedGhostDestroy, "airport", airportGhostGetMember, 0 };
|
||||
|
||||
static const char* navaidGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||
naGhostType NavaidGhostType = { positionedGhostDestroy, "navaid", navaidGhostGetMember, 0 };
|
||||
|
||||
static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||
naGhostType RunwayGhostType = { positionedGhostDestroy, "runway", runwayGhostGetMember, 0 };
|
||||
|
||||
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||
|
||||
naGhostType WayptGhostType = { wayptGhostDestroy,
|
||||
|
@ -79,6 +89,27 @@ static FGPositioned* positionedGhost(naRef r)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FGAirport* airportGhost(naRef r)
|
||||
{
|
||||
if (naGhost_type(r) == &AirportGhostType)
|
||||
return (FGAirport*) naGhost_ptr(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FGNavRecord* navaidGhost(naRef r)
|
||||
{
|
||||
if (naGhost_type(r) == &NavaidGhostType)
|
||||
return (FGNavRecord*) naGhost_ptr(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FGRunway* runwayGhost(naRef r)
|
||||
{
|
||||
if (naGhost_type(r) == &RunwayGhostType)
|
||||
return (FGRunway*) naGhost_ptr(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void positionedGhostDestroy(void* g)
|
||||
{
|
||||
FGPositioned* pos = (FGPositioned*)g;
|
||||
|
@ -115,6 +146,36 @@ naRef ghostForPositioned(naContext c, const FGPositioned* pos)
|
|||
return naNewGhost(c, &PositionedGhostType, (void*) pos);
|
||||
}
|
||||
|
||||
naRef ghostForAirport(naContext c, const FGAirport* apt)
|
||||
{
|
||||
if (!apt) {
|
||||
return naNil();
|
||||
}
|
||||
|
||||
FGPositioned::get(apt); // take a ref
|
||||
return naNewGhost2(c, &AirportGhostType, (void*) apt);
|
||||
}
|
||||
|
||||
naRef ghostForNavaid(naContext c, const FGNavRecord* n)
|
||||
{
|
||||
if (!n) {
|
||||
return naNil();
|
||||
}
|
||||
|
||||
FGPositioned::get(n); // take a ref
|
||||
return naNewGhost2(c, &NavaidGhostType, (void*) n);
|
||||
}
|
||||
|
||||
naRef ghostForRunway(naContext c, const FGRunway* r)
|
||||
{
|
||||
if (!r) {
|
||||
return naNil();
|
||||
}
|
||||
|
||||
FGPositioned::get(r); // take a ref
|
||||
return naNewGhost2(c, &RunwayGhostType, (void*) r);
|
||||
}
|
||||
|
||||
naRef ghostForWaypt(naContext c, const flightgear::Waypt* wpt)
|
||||
{
|
||||
if (!wpt) {
|
||||
|
@ -125,34 +186,36 @@ naRef ghostForWaypt(naContext c, const flightgear::Waypt* wpt)
|
|||
return naNewGhost2(c, &WayptGhostType, (void*) wpt);
|
||||
}
|
||||
|
||||
naRef hashForAirport(naContext c, const FGAirport* apt)
|
||||
static const char* airportGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||
{
|
||||
std::string id = apt->ident();
|
||||
std::string name = apt->name();
|
||||
|
||||
// build runways hash
|
||||
naRef rwys = naNewHash(c);
|
||||
const char* fieldName = naStr_data(field);
|
||||
FGAirport* apt = (FGAirport*) g;
|
||||
|
||||
if (!strcmp(fieldName, "parents")) {
|
||||
*out = naNewVector(c);
|
||||
naVec_append(*out, airportPrototype);
|
||||
} else if (!strcmp(fieldName, "id")) *out = stringToNasal(c, apt->ident());
|
||||
else if (!strcmp(fieldName, "name")) *out = stringToNasal(c, apt->name());
|
||||
else if (!strcmp(fieldName, "lat")) *out = naNum(apt->getLatitude());
|
||||
else if (!strcmp(fieldName, "lon")) *out = naNum(apt->getLongitude());
|
||||
else if (!strcmp(fieldName, "elevation")) {
|
||||
*out = naNum(apt->getElevation() * SG_FEET_TO_METER);
|
||||
} else if (!strcmp(fieldName, "has_metar")) {
|
||||
*out = naNum(apt->getMetar());
|
||||
} else if (!strcmp(fieldName, "runways")) {
|
||||
*out = naNewHash(c);
|
||||
for(unsigned int r=0; r<apt->numRunways(); ++r) {
|
||||
FGRunway* rwy(apt->getRunwayByIndex(r));
|
||||
naRef rwyid = stringToNasal(c, rwy->ident());
|
||||
naRef rwydata = hashForRunway(c, rwy);
|
||||
naHash_set(rwys, rwyid, rwydata);
|
||||
naRef rwydata = ghostForRunway(c, rwy);
|
||||
naHash_set(*out, rwyid, rwydata);
|
||||
}
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
naRef aptdata = naNewHash(c);
|
||||
hashset(c, aptdata, "id", stringToNasal(c, id));
|
||||
hashset(c, aptdata, "name", stringToNasal(c, name));
|
||||
hashset(c, aptdata, "lat", naNum(apt->getLatitude()));
|
||||
hashset(c, aptdata, "lon", naNum(apt->getLongitude()));
|
||||
hashset(c, aptdata, "elevation", naNum(apt->getElevation() * SG_FEET_TO_METER));
|
||||
hashset(c, aptdata, "has_metar", naNum(apt->getMetar()));
|
||||
hashset(c, aptdata, "runways", rwys);
|
||||
hashset(c, aptdata, "_positioned", ghostForPositioned(c, apt));
|
||||
naRef parents = naNewVector(c);
|
||||
naVec_append(parents, airportPrototype);
|
||||
hashset(c, aptdata, "parents", parents);
|
||||
|
||||
return aptdata;
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||
|
@ -192,51 +255,58 @@ static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef*
|
|||
return ""; // success
|
||||
}
|
||||
|
||||
naRef hashForRunway(naContext c, FGRunway* rwy)
|
||||
static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||
{
|
||||
naRef rwyid = stringToNasal(c, rwy->ident());
|
||||
naRef rwydata = naNewHash(c);
|
||||
#define HASHSET(s,l,n) naHash_set(rwydata, naStr_fromdata(naNewString(c),s,l),n)
|
||||
HASHSET("id", 2, rwyid);
|
||||
HASHSET("lat", 3, naNum(rwy->latitude()));
|
||||
HASHSET("lon", 3, naNum(rwy->longitude()));
|
||||
HASHSET("heading", 7, naNum(rwy->headingDeg()));
|
||||
HASHSET("length", 6, naNum(rwy->lengthM()));
|
||||
HASHSET("width", 5, naNum(rwy->widthM()));
|
||||
HASHSET("threshold", 9, naNum(rwy->displacedThresholdM()));
|
||||
HASHSET("stopway", 7, naNum(rwy->stopwayM()));
|
||||
|
||||
if (rwy->ILS()) {
|
||||
HASHSET("ils_frequency_mhz", 17, naNum(rwy->ILS()->get_freq() / 100.0));
|
||||
HASHSET("ils", 3, hashForNavRecord(c, rwy->ILS(), SGGeod()));
|
||||
}
|
||||
|
||||
HASHSET("_positioned", 11, ghostForPositioned(c, rwy));
|
||||
#undef HASHSET
|
||||
return rwydata;
|
||||
const char* fieldName = naStr_data(field);
|
||||
FGRunway* rwy = (FGRunway*) g;
|
||||
|
||||
if (!strcmp(fieldName, "id")) *out = stringToNasal(c, rwy->ident());
|
||||
else if (!strcmp(fieldName, "lat")) *out = naNum(rwy->latitude());
|
||||
else if (!strcmp(fieldName, "lon")) *out = naNum(rwy->longitude());
|
||||
else if (!strcmp(fieldName, "heading")) *out = naNum(rwy->headingDeg());
|
||||
else if (!strcmp(fieldName, "length")) *out = naNum(rwy->lengthM());
|
||||
else if (!strcmp(fieldName, "width")) *out = naNum(rwy->widthM());
|
||||
else if (!strcmp(fieldName, "threshold")) *out = naNum(rwy->displacedThresholdM());
|
||||
else if (!strcmp(fieldName, "stopway")) *out = naNum(rwy->stopwayM());
|
||||
else if (!strcmp(fieldName, "ils_frequency_mhz")) {
|
||||
*out = rwy->ILS() ? naNum(rwy->ILS()->get_freq() / 100.0) : naNil();
|
||||
} else if (!strcmp(fieldName, "ils")) {
|
||||
*out = ghostForNavaid(c, rwy->ILS());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
naRef hashForNavRecord(naContext c, const FGNavRecord* nav, const SGGeod& rel)
|
||||
static const char* navaidGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||
{
|
||||
naRef navdata = naNewHash(c);
|
||||
#define HASHSET(s,l,n) naHash_set(navdata, naStr_fromdata(naNewString(c),s,l),n)
|
||||
HASHSET("id", 2, stringToNasal(c, nav->ident()));
|
||||
HASHSET("name", 4, stringToNasal(c, nav->name()));
|
||||
HASHSET("frequency", 9, naNum(nav->get_freq()));
|
||||
HASHSET("lat", 3, naNum(nav->get_lat()));
|
||||
HASHSET("lon", 3, naNum(nav->get_lon()));
|
||||
HASHSET("elevation", 9, naNum(nav->get_elev_ft() * SG_FEET_TO_METER));
|
||||
HASHSET("type", 4, stringToNasal(c, nav->nameForType(nav->type())));
|
||||
|
||||
// FIXME - get rid of these, people should use courseAndDistance instead
|
||||
HASHSET("distance", 8, naNum(SGGeodesy::distanceNm( rel, nav->geod() ) * SG_NM_TO_METER ) );
|
||||
HASHSET("bearing", 7, naNum(SGGeodesy::courseDeg( rel, nav->geod() ) ) );
|
||||
|
||||
// record the real object as a ghost for further operations
|
||||
HASHSET("_positioned",11, ghostForPositioned(c, nav));
|
||||
#undef HASHSET
|
||||
|
||||
return navdata;
|
||||
const char* fieldName = naStr_data(field);
|
||||
FGNavRecord* nav = (FGNavRecord*) g;
|
||||
|
||||
if (!strcmp(fieldName, "id")) *out = stringToNasal(c, nav->ident());
|
||||
else if (!strcmp(fieldName, "name")) *out = stringToNasal(c, nav->name());
|
||||
else if (!strcmp(fieldName, "lat")) *out = naNum(nav->get_lat());
|
||||
else if (!strcmp(fieldName, "lon")) *out = naNum(nav->get_lon());
|
||||
else if (!strcmp(fieldName, "elevation")) {
|
||||
*out = naNum(nav->get_elev_ft() * SG_FEET_TO_METER);
|
||||
} else if (!strcmp(fieldName, "type")) {
|
||||
*out = stringToNasal(c, nav->nameForType(nav->type()));
|
||||
} else if (!strcmp(fieldName, "frequency")) {
|
||||
*out = naNum(nav->get_freq());
|
||||
} else if (!strcmp(fieldName, "course")) {
|
||||
if ((nav->type() == FGPositioned::ILS) || (nav->type() == FGPositioned::LOC)) {
|
||||
double radial = nav->get_multiuse();
|
||||
SG_NORMALIZE_RANGE(radial, 0.0, 360.0);
|
||||
*out = naNum(radial);
|
||||
} else {
|
||||
*out = naNil();
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool hashIsCoord(naRef h)
|
||||
|
@ -264,13 +334,6 @@ bool geodFromHash(naRef ref, SGGeod& result)
|
|||
return true;
|
||||
}
|
||||
|
||||
naRef ghost = naHash_cget(ref, (char*) "_waypt");
|
||||
if (!naIsNil(ghost)) {
|
||||
flightgear::Waypt* w = wayptGhost(ghost);
|
||||
result = w->position();
|
||||
return true;
|
||||
}
|
||||
|
||||
// then check for manual latitude / longitude names
|
||||
naRef lat = naHash_cget(ref, (char*) "lat");
|
||||
naRef lon = naHash_cget(ref, (char*) "lon");
|
||||
|
@ -300,6 +363,29 @@ static int geodFromArgs(naRef* args, int offset, int argc, SGGeod& result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (naIsGhost(args[offset])) {
|
||||
naGhostType* gt = naGhost_type(args[offset]);
|
||||
if (gt == &AirportGhostType) {
|
||||
result = airportGhost(args[offset])->geod();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gt == &NavaidGhostType) {
|
||||
result = navaidGhost(args[offset])->geod();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gt == &RunwayGhostType) {
|
||||
result = runwayGhost(args[offset])->geod();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gt == &WayptGhostType) {
|
||||
result = wayptGhost(args[offset])->position();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (geodFromHash(args[offset], result)) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -462,7 +548,7 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
|
|||
if(!apt) return naNil();
|
||||
}
|
||||
|
||||
return hashForAirport(c, apt);
|
||||
return ghostForAirport(c, apt);
|
||||
}
|
||||
|
||||
static naRef f_findAirportsWithinRange(naContext c, naRef me, int argc, naRef* args)
|
||||
|
@ -488,7 +574,7 @@ static naRef f_findAirportsWithinRange(naContext c, naRef me, int argc, naRef* a
|
|||
|
||||
BOOST_FOREACH(FGPositionedRef a, apts) {
|
||||
FGAirport* apt = (FGAirport*) a.get();
|
||||
naVec_append(r, hashForAirport(c, apt));
|
||||
naVec_append(r, ghostForAirport(c, apt));
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -513,30 +599,15 @@ static naRef f_findAirportsByICAO(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
BOOST_FOREACH(FGPositionedRef a, apts) {
|
||||
FGAirport* apt = (FGAirport*) a.get();
|
||||
naVec_append(r, hashForAirport(c, apt));
|
||||
naVec_append(r, ghostForAirport(c, apt));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static FGAirport* airportFromMe(naRef me)
|
||||
{
|
||||
naRef ghost = naHash_cget(me, (char*) "_positioned");
|
||||
if (naIsNil(ghost)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FGPositioned* pos = positionedGhost(ghost);
|
||||
if (pos && FGAirport::isAirportType(pos)) {
|
||||
return (FGAirport*) pos;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static naRef f_airport_tower(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.tower called on non-airport object");
|
||||
}
|
||||
|
@ -552,7 +623,7 @@ static naRef f_airport_tower(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
static naRef f_airport_comms(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.comms called on non-airport object");
|
||||
}
|
||||
|
@ -581,7 +652,7 @@ static naRef f_airport_comms(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
static naRef f_airport_runway(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.runway called on non-airport object");
|
||||
}
|
||||
|
@ -595,12 +666,12 @@ static naRef f_airport_runway(naContext c, naRef me, int argc, naRef* args)
|
|||
return naNil();
|
||||
}
|
||||
|
||||
return hashForRunway(c, apt->getRunwayByIdent(ident));
|
||||
return ghostForRunway(c, apt->getRunwayByIdent(ident));
|
||||
}
|
||||
|
||||
static naRef f_airport_sids(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.sids called on non-airport object");
|
||||
}
|
||||
|
@ -630,7 +701,7 @@ static naRef f_airport_sids(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
static naRef f_airport_stars(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.stars called on non-airport object");
|
||||
}
|
||||
|
@ -660,7 +731,7 @@ static naRef f_airport_stars(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
static naRef f_airport_parking(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGAirport* apt = airportFromMe(me);
|
||||
FGAirport* apt = airportGhost(me);
|
||||
if (!apt) {
|
||||
naRuntimeError(c, "airport.parking called on non-airport object");
|
||||
}
|
||||
|
@ -757,7 +828,7 @@ static naRef f_navinfo(naContext c, naRef me, int argc, naRef* args)
|
|||
|
||||
naRef reply = naNewVector(c);
|
||||
for( nav_list_type::const_iterator it = navlist.begin(); it != navlist.end(); ++it ) {
|
||||
naVec_append( reply, hashForNavRecord(c, *it, pos) );
|
||||
naVec_append( reply, ghostForNavaid(c, *it) );
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
@ -785,7 +856,7 @@ static naRef f_findNavaidsWithinRange(naContext c, naRef me, int argc, naRef* ar
|
|||
|
||||
BOOST_FOREACH(FGPositionedRef a, navs) {
|
||||
FGNavRecord* nav = (FGNavRecord*) a.get();
|
||||
naVec_append(r, hashForNavRecord(c, nav, pos));
|
||||
naVec_append(r, ghostForNavaid(c, nav));
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -812,7 +883,7 @@ static naRef f_findNavaidByFrequency(naContext c, naRef me, int argc, naRef* arg
|
|||
return naNil();
|
||||
}
|
||||
|
||||
return hashForNavRecord(c, navs.front().ptr(), pos);
|
||||
return ghostForNavaid(c, navs.front().ptr());
|
||||
}
|
||||
|
||||
static naRef f_findNavaidsByFrequency(naContext c, naRef me, int argc, naRef* args)
|
||||
|
@ -835,7 +906,7 @@ static naRef f_findNavaidsByFrequency(naContext c, naRef me, int argc, naRef* ar
|
|||
nav_list_type navs = globals->get_navlist()->findAllByFreq(freqMhz, pos, type);
|
||||
|
||||
BOOST_FOREACH(nav_rec_ptr a, navs) {
|
||||
naVec_append(r, hashForNavRecord(c, a.ptr(), pos));
|
||||
naVec_append(r, ghostForNavaid(c, a.ptr()));
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -861,7 +932,7 @@ static naRef f_findNavaidsByIdent(naContext c, naRef me, int argc, naRef* args)
|
|||
nav_list_type navs = globals->get_navlist()->findByIdentAndFreq(pos, ident, 0.0, type);
|
||||
|
||||
BOOST_FOREACH(nav_rec_ptr a, navs) {
|
||||
naVec_append(r, hashForNavRecord(c, a.ptr(), pos));
|
||||
naVec_append(r, ghostForNavaid(c, a.ptr()));
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -1036,7 +1107,7 @@ static naRef f_waypoint_navaid(naContext c, naRef me, int argc, naRef* args)
|
|||
case FGPositioned::DME:
|
||||
case FGPositioned::TACAN: {
|
||||
FGNavRecord* nav = (FGNavRecord*) pos;
|
||||
return hashForNavRecord(c, nav, globals->get_aircraft_position());
|
||||
return ghostForNavaid(c, nav);
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -1056,7 +1127,7 @@ static naRef f_waypoint_airport(naContext c, naRef me, int argc, naRef* args)
|
|||
return naNil();
|
||||
}
|
||||
|
||||
return hashForAirport(c, (FGAirport*) pos);
|
||||
return ghostForAirport(c, (FGAirport*) pos);
|
||||
}
|
||||
|
||||
static naRef f_waypoint_runway(naContext c, naRef me, int argc, naRef* args)
|
||||
|
@ -1071,7 +1142,7 @@ static naRef f_waypoint_runway(naContext c, naRef me, int argc, naRef* args)
|
|||
return naNil();
|
||||
}
|
||||
|
||||
return hashForRunway(c, (FGRunway*) pos);
|
||||
return ghostForRunway(c, (FGRunway*) pos);
|
||||
}
|
||||
|
||||
// Table of extension functions. Terminate with zeros.
|
||||
|
|
|
@ -25,13 +25,6 @@
|
|||
|
||||
// forward decls
|
||||
class SGGeod;
|
||||
class FGAirport;
|
||||
class FGRunway;
|
||||
class FGNavRecord;
|
||||
|
||||
naRef hashForAirport(naContext c, const FGAirport* apt);
|
||||
naRef hashForRunway(naContext c, FGRunway* rwy);
|
||||
naRef hashForNavRecord(naContext c, const FGNavRecord* nav, const SGGeod& rel);
|
||||
|
||||
bool geodFromHash(naRef ref, SGGeod& result);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue