]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/dme.cxx
Restore GPS compatibility with 2.10
[flightgear.git] / src / Instrumentation / dme.cxx
index 754008bd47efdb77c177923ec04541dffc92e272..33ea69279d18b949484a93576a9325951f7ba267 100644 (file)
@@ -8,15 +8,17 @@
 #endif
 
 #include <simgear/compiler.h>
+#include <simgear/sg_inlines.h>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/math/sg_random.h>
+#include <simgear/sound/sample_group.hxx>
 
 #include <Main/fg_props.hxx>
 #include <Navaids/navlist.hxx>
+#include <Sound/audioident.hxx>
 
 #include "dme.hxx"
 
-
 /**
  * Adjust the range.
  *
@@ -39,35 +41,61 @@ adjust_range (double transmitter_elevation_ft, double aircraft_altitude_ft,
     return range_nm + (range_nm * rand * rand);
 }
 
+namespace {
+  
+  class DMEFilter : public FGNavList::TypeFilter
+  {
+  public:
+    DMEFilter() :
+      TypeFilter(FGPositioned::DME),
+      _locEnabled(fgGetBool("/sim/realism/dme-fallback-to-loc", true))
+    {
+      if (_locEnabled) {
+        _mintype = FGPositioned::ILS;
+      }
+    }
+    
+    virtual bool pass(FGPositioned* pos) const
+    {
+      switch (pos->type()) {
+      case FGPositioned::DME: return true;
+      case FGPositioned::ILS:
+      case FGPositioned::LOC: return _locEnabled;
+      default: return false;
+      }
+    }
+    
+  private:
+    const bool _locEnabled;
+  };
+  
+} // of anonymous namespace
+
 
 DME::DME ( SGPropertyNode *node )
     : _last_distance_nm(0),
       _last_frequency_mhz(-1),
       _time_before_search_sec(0),
-      _transmitter_valid(false),
-      _transmitter_elevation_ft(0),
-      _transmitter_range_nm(0),
-      _transmitter_bias(0.0),
+      _navrecord(NULL),
       _name(node->getStringValue("name", "dme")),
-      _num(node->getIntValue("number", 0))
+      _num(node->getIntValue("number", 0)),
+      _audioIdent(NULL)
 {
 }
 
 DME::~DME ()
 {
+    delete _audioIdent;
 }
 
 void
 DME::init ()
 {
-    string branch;
+    std::string branch;
     branch = "/instrumentation/" + _name;
 
     SGPropertyNode *node = fgGetNode(branch.c_str(), _num, true );
 
-    _longitude_node = fgGetNode("/position/longitude-deg", true);
-    _latitude_node = fgGetNode("/position/latitude-deg", true);
-    _altitude_node = fgGetNode("/position/altitude-ft", true);
     _serviceable_node = node->getChild("serviceable", 0, true);
     _electrical_node = fgGetNode("/systems/electrical/outputs/dme", true);
     SGPropertyNode *fnode = node->getChild("frequencies", 0, true);
@@ -77,15 +105,40 @@ DME::init ()
     _distance_node = node->getChild("indicated-distance-nm", 0, true);
     _speed_node = node->getChild("indicated-ground-speed-kt", 0, true);
     _time_node = node->getChild("indicated-time-min", 0, true);
+
+    double d = node->getDoubleValue( "volume", 1.0 );
+    _volume_node = node->getChild("volume", 0, true);
+    _volume_node->setDoubleValue( d );
+
+    bool b = node->getBoolValue( "ident", false );
+    _ident_btn_node = node->getChild("ident", 0, true);
+    _ident_btn_node->setBoolValue( b );
+
+    std::ostringstream temp;
+    temp << _name << "-ident-" << _num;
+    if( NULL == _audioIdent ) 
+        _audioIdent = new DMEAudioIdent( temp.str() );
+    _audioIdent->init();
+
+    reinit();
+}
+
+void
+DME::reinit ()
+{
+    _time_before_search_sec = 0;
 }
 
 void
 DME::update (double delta_time_sec)
 {
+    if( delta_time_sec < SGLimitsd::min() )
+        return;  //paused
+
                                 // Figure out the source
     const char * source = _source_node->getStringValue();
     if (source[0] == '\0') {
-        string branch;
+        std::string branch;
         branch = "/instrumentation/" + _name + "/frequencies/selected-mhz";
         _source_node->setStringValue(branch.c_str());
         source = _source_node->getStringValue();
@@ -97,50 +150,54 @@ DME::update (double delta_time_sec)
         _time_before_search_sec = 0;
         _last_frequency_mhz = frequency_mhz;
     }
+    _frequency_node->setDoubleValue(frequency_mhz);
 
                                 // Get the aircraft position
-    double longitude_rad =
-        _longitude_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double latitude_rad =
-        _latitude_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double altitude_m =
-        _altitude_node->getDoubleValue() * SG_FEET_TO_METER;
-
-                                // On timeout, scan again
+    // On timeout, scan again
     _time_before_search_sec -= delta_time_sec;
-    if (_time_before_search_sec < 0)
-        search(frequency_mhz, longitude_rad,
-               latitude_rad, altitude_m);
+    if (_time_before_search_sec < 0) {
+        _time_before_search_sec = 1.0;
+
+      SGGeod pos(globals->get_aircraft_position());
+      DMEFilter filter;
+      _navrecord = FGNavList::findByFreq(frequency_mhz, pos, &filter);
+    }
 
-                                // If it's off, don't bother.
+    // If it's off, don't bother.
     if (!_serviceable_node->getBoolValue() ||
         !_electrical_node->getBoolValue() ||
-        !_transmitter_valid) {
+        NULL == _navrecord ) {
         _last_distance_nm = 0;
         _in_range_node->setBoolValue(false);
         _distance_node->setDoubleValue(0);
         _speed_node->setDoubleValue(0);
         _time_node->setDoubleValue(0);
+        _audioIdent->setIdent("", 0.0 );
         return;
     }
 
-                                // Calculate the distance to the transmitter
-    SGGeod geod = SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m);
-    SGVec3d location = SGVec3d::fromGeod(geod);
+    // Calculate the distance to the transmitter
+    SGVec3d location = SGVec3d::fromGeod(globals->get_aircraft_position());
     
-    double distance_nm = dist(_transmitter, location) * SG_METER_TO_NM;
+    double distance_nm = dist(_navrecord->cart(), location) * SG_METER_TO_NM;
 
-    double range_nm = adjust_range(_transmitter_elevation_ft,
-                                   altitude_m * SG_METER_TO_FEET,
-                                   _transmitter_range_nm);
+    double range_nm = adjust_range(_navrecord->get_elev_ft(),
+                                   globals->get_aircraft_position().getElevationFt(),
+                                   _navrecord->get_range());
 
     if (distance_nm <= range_nm) {
+        double volume = _volume_node->getDoubleValue();
+        if( false == _ident_btn_node->getBoolValue() )
+            volume = 0.0;
+
+        _audioIdent->setIdent(_navrecord->ident(), volume );
+
         double speed_kt = (fabs(distance_nm - _last_distance_nm) *
                            ((1 / delta_time_sec) * 3600.0));
         _last_distance_nm = distance_nm;
 
         _in_range_node->setBoolValue(true);
-        double tmp_dist = distance_nm - _transmitter_bias;
+        double tmp_dist = distance_nm - _navrecord->get_multiuse();
         if ( tmp_dist < 0.0 ) {
             tmp_dist = 0.0;
         }
@@ -155,29 +212,10 @@ DME::update (double delta_time_sec)
         _distance_node->setDoubleValue(0);
         _speed_node->setDoubleValue(0);
         _time_node->setDoubleValue(0);
+        _audioIdent->setIdent("", 0.0 );
     }
-}
-
-void
-DME::search (double frequency_mhz, double longitude_rad,
-             double latitude_rad, double altitude_m)
-{
-    // reset search time
-    _time_before_search_sec = 1.0;
-
-    // try the ILS list first
     
-    FGNavRecord *dme = globals->get_dmelist()->findByFreq( frequency_mhz,
-      SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m));
-
-    _transmitter_valid = (dme != NULL);
-
-    if ( _transmitter_valid ) {
-        _transmitter = dme->cart();
-        _transmitter_elevation_ft = dme->get_elev_ft();
-        _transmitter_range_nm = dme->get_range();
-        _transmitter_bias = dme->get_multiuse();
-    }
+    _audioIdent->update( delta_time_sec );
 }
 
 // end of dme.cxx