From 2a73201ca81c8b5ac0f1a4d42a0a1ec5973f10c7 Mon Sep 17 00:00:00 2001
From: curt <curt>
Date: Thu, 26 Sep 2002 16:19:06 +0000
Subject: [PATCH] More code shuffling.

---
 src/Cockpit/Makefile.am       |   1 +
 src/Cockpit/marker_beacon.cxx | 251 ++++++++++++++++++++++++++++++++++
 src/Cockpit/marker_beacon.hxx |  84 ++++++++++++
 src/Cockpit/radiostack.cxx    | 192 ++------------------------
 src/Cockpit/radiostack.hxx    |  30 +---
 5 files changed, 346 insertions(+), 212 deletions(-)
 create mode 100644 src/Cockpit/marker_beacon.cxx
 create mode 100644 src/Cockpit/marker_beacon.hxx

diff --git a/src/Cockpit/Makefile.am b/src/Cockpit/Makefile.am
index 14463061d..6e0a54c9f 100644
--- a/src/Cockpit/Makefile.am
+++ b/src/Cockpit/Makefile.am
@@ -10,6 +10,7 @@ libCockpit_a_SOURCES = \
 	hud_scal.cxx hud_tbi.cxx \
 	kr_87.cxx kr_87.hxx \
 	kt_70.cxx kt_70.hxx \
+	marker_beacon.cxx marker_beacon.hxx \
 	navcom.cxx navcom.hxx \
 	panel.cxx panel.hxx \
         panel_io.cxx panel_io.hxx \
diff --git a/src/Cockpit/marker_beacon.cxx b/src/Cockpit/marker_beacon.cxx
new file mode 100644
index 000000000..941d1e2b4
--- /dev/null
+++ b/src/Cockpit/marker_beacon.cxx
@@ -0,0 +1,251 @@
+// marker_beacon.cxx -- class to manage the marker beacons
+//
+// Written by Curtis Olson, started April 2000.
+//
+// Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>	// snprintf
+
+#include <simgear/compiler.h>
+#include <simgear/math/sg_random.h>
+
+#include <Aircraft/aircraft.hxx>
+#include <Navaids/mkrbeacons.hxx>
+#include <Time/FGEventMgr.hxx>
+
+#include "marker_beacon.hxx"
+
+#include <string>
+SG_USING_STD(string);
+
+
+/**
+ * Boy, this is ugly!  Make the VOR range vary by altitude difference.
+ */
+static double kludgeRange ( double stationElev, double aircraftElev,
+			    double nominalRange)
+{
+				// Assume that the nominal range (usually
+				// 50nm) applies at a 5,000 ft difference.
+				// Just a wild guess!
+  double factor = ((aircraftElev*SG_METER_TO_FEET) - stationElev) / 5000.0;
+  double range = fabs(nominalRange * factor);
+
+				// Clamp the range to keep it sane; for
+				// now, never less than 25% or more than
+				// 500% of nominal range.
+  if (range < nominalRange/4.0) {
+    range = nominalRange/4.0;
+  } else if (range > nominalRange*5.0) {
+    range = nominalRange*5.0;
+  }
+
+  return range;
+}
+
+
+// Constructor
+FGMarkerBeacon::FGMarkerBeacon() :
+    lon_node(fgGetNode("/position/longitude-deg", true)),
+    lat_node(fgGetNode("/position/latitude-deg", true)),
+    alt_node(fgGetNode("/position/altitude-ft", true)),
+    need_update(true),
+    outer_blink(false),
+    middle_blink(false),
+    inner_blink(false)
+{
+    SGPath path( globals->get_fg_root() );
+    SGPath term = path;
+    term.append( "Navaids/range.term" );
+    SGPath low = path;
+    low.append( "Navaids/range.low" );
+    SGPath high = path;
+    high.append( "Navaids/range.high" );
+
+    term_tbl = new SGInterpTable( term.str() );
+    low_tbl = new SGInterpTable( low.str() );
+    high_tbl = new SGInterpTable( high.str() );
+}
+
+
+// Destructor
+FGMarkerBeacon::~FGMarkerBeacon() 
+{
+    delete term_tbl;
+    delete low_tbl;
+    delete high_tbl;
+}
+
+
+void
+FGMarkerBeacon::init ()
+{
+    morse.init();
+    beacon.init();
+    blink.stamp();
+
+    search();
+    update(0);			// FIXME: use dt
+}
+
+
+void
+FGMarkerBeacon::bind ()
+{
+
+    fgTie("/radios/marker-beacon/inner", this,
+	  &FGMarkerBeacon::get_inner_blink);
+
+    fgTie("/radios/marker-beacon/middle", this,
+	  &FGMarkerBeacon::get_middle_blink);
+
+    fgTie("/radios/marker-beacon/outer", this,
+	  &FGMarkerBeacon::get_outer_blink);
+}
+
+
+void
+FGMarkerBeacon::unbind ()
+{
+    fgUntie("/radios/marker-beacon/inner");
+    fgUntie("/radios/marker-beacon/middle");
+    fgUntie("/radios/marker-beacon/outer");
+}
+
+
+// Update the various nav values based on position and valid tuned in navs
+void 
+FGMarkerBeacon::update(double dt) 
+{
+    need_update = false;
+
+    // marker beacon blinking
+    bool light_on = ( outer_blink || middle_blink || inner_blink );
+    SGTimeStamp current;
+    current.stamp();
+
+    if ( light_on && (current - blink > 400000) ) {
+	light_on = false;
+	blink.stamp();
+    } else if ( !light_on && (current - blink > 100000) ) {
+	light_on = true;
+	blink.stamp();
+    }
+
+    if ( outer_marker ) {
+	outer_blink = light_on;
+    } else {
+	outer_blink = false;
+    }
+
+    if ( middle_marker ) {
+	middle_blink = light_on;
+    } else {
+	middle_blink = false;
+    }
+
+    if ( inner_marker ) {
+	inner_blink = light_on;
+    } else {
+	inner_blink = false;
+    }
+
+    // cout << outer_blink << " " << middle_blink << " " << inner_blink << endl;
+}
+
+
+// Update current nav/adf radio stations based on current postition
+void FGMarkerBeacon::search() 
+{
+    static FGMkrBeacon::fgMkrBeacType last_beacon = FGMkrBeacon::NOBEACON;
+
+    double lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
+    double lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
+    double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
+
+    ////////////////////////////////////////////////////////////////////////
+    // Beacons.
+    ////////////////////////////////////////////////////////////////////////
+
+    FGMkrBeacon::fgMkrBeacType beacon_type
+	= current_beacons->query( lon * SGD_RADIANS_TO_DEGREES,
+				  lat * SGD_RADIANS_TO_DEGREES, elev );
+
+    outer_marker = middle_marker = inner_marker = false;
+
+    if ( beacon_type == FGMkrBeacon::OUTER ) {
+	outer_marker = true;
+	// cout << "OUTER MARKER" << endl;
+#ifdef ENABLE_AUDIO_SUPPORT
+	if ( last_beacon != FGMkrBeacon::OUTER ) {
+	    if ( ! globals->get_soundmgr()->exists( "outer-marker" ) ) {
+		FGSimpleSound *sound = beacon.get_outer();
+		sound->set_volume( 0.3 );
+		globals->get_soundmgr()->add( sound, "outer-marker" );
+	    }
+	    if ( !globals->get_soundmgr()->is_playing("outer-marker") ) {
+		globals->get_soundmgr()->play_looped( "outer-marker" );
+	    }
+	}
+#endif
+    } else if ( beacon_type == FGMkrBeacon::MIDDLE ) {
+	middle_marker = true;
+	// cout << "MIDDLE MARKER" << endl;
+#ifdef ENABLE_AUDIO_SUPPORT
+	if ( last_beacon != FGMkrBeacon::MIDDLE ) {
+	    if ( ! globals->get_soundmgr()->exists( "middle-marker" ) ) {
+		FGSimpleSound *sound = beacon.get_middle();
+		sound->set_volume( 0.3 );
+		globals->get_soundmgr()->add( sound, "middle-marker" );
+	    }
+	    if ( !globals->get_soundmgr()->is_playing("middle-marker") ) {
+		globals->get_soundmgr()->play_looped( "middle-marker" );
+	    }
+	}
+#endif
+    } else if ( beacon_type == FGMkrBeacon::INNER ) {
+	inner_marker = true;
+	// cout << "INNER MARKER" << endl;
+#ifdef ENABLE_AUDIO_SUPPORT
+	if ( last_beacon != FGMkrBeacon::INNER ) {
+	    if ( ! globals->get_soundmgr()->exists( "inner-marker" ) ) {
+		FGSimpleSound *sound = beacon.get_inner();
+		sound->set_volume( 0.3 );
+		globals->get_soundmgr()->add( sound, "inner-marker" );
+	    }
+	    if ( !globals->get_soundmgr()->is_playing("inner-marker") ) {
+		globals->get_soundmgr()->play_looped( "inner-marker" );
+	    }
+	}
+#endif
+    } else {
+	// cout << "no marker" << endl;
+#ifdef ENABLE_AUDIO_SUPPORT
+	globals->get_soundmgr()->stop( "outer-marker" );
+	globals->get_soundmgr()->stop( "middle-marker" );
+	globals->get_soundmgr()->stop( "inner-marker" );
+#endif
+    }
+    last_beacon = beacon_type;
+}
diff --git a/src/Cockpit/marker_beacon.hxx b/src/Cockpit/marker_beacon.hxx
new file mode 100644
index 000000000..1a49844dd
--- /dev/null
+++ b/src/Cockpit/marker_beacon.hxx
@@ -0,0 +1,84 @@
+// marker_beacon.hxx -- class to manage the marker beacons
+//
+// Written by Curtis Olson, started April 2000.
+//
+// Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef _FG_MARKER_BEACON_HXX
+#define _FG_MARKER_BEACON_HXX
+
+
+#include <Main/fgfs.hxx>
+#include <Main/fg_props.hxx>
+
+#include <simgear/compiler.h>
+
+#include <simgear/math/interpolater.hxx>
+#include <simgear/timing/timestamp.hxx>
+
+#include <Sound/beacon.hxx>
+#include <Sound/morse.hxx>
+
+
+class FGMarkerBeacon : public FGSubsystem
+{
+    FGBeacon beacon;
+    FGMorse morse;
+
+    SGInterpTable *term_tbl;
+    SGInterpTable *low_tbl;
+    SGInterpTable *high_tbl;
+
+    SGPropertyNode *lon_node;
+    SGPropertyNode *lat_node;
+    SGPropertyNode *alt_node;
+
+    bool need_update;
+
+    bool outer_marker;
+    bool middle_marker;
+    bool inner_marker;
+
+    SGTimeStamp blink;
+    bool outer_blink;
+    bool middle_blink;
+    bool inner_blink;
+
+public:
+
+    FGMarkerBeacon();
+    ~FGMarkerBeacon();
+
+    void init ();
+    void bind ();
+    void unbind ();
+    void update (double dt);
+
+    // Update nav/adf radios based on current postition
+    void search ();
+
+    // Marker Beacon Accessors
+    inline bool get_inner_blink () const { return inner_blink; }
+    inline bool get_middle_blink () const { return middle_blink; }
+    inline bool get_outer_blink () const { return outer_blink; }
+};
+
+
+#endif // _FG_MARKER_BEACON_HXX
diff --git a/src/Cockpit/radiostack.cxx b/src/Cockpit/radiostack.cxx
index 134a6cb76..6566daf7e 100644
--- a/src/Cockpit/radiostack.cxx
+++ b/src/Cockpit/radiostack.cxx
@@ -45,67 +45,19 @@ SG_USING_STD(string);
 FGRadioStack *current_radiostack;
 
 
-/**
- * Boy, this is ugly!  Make the VOR range vary by altitude difference.
- */
-static double kludgeRange ( double stationElev, double aircraftElev,
-			    double nominalRange)
-{
-				// Assume that the nominal range (usually
-				// 50nm) applies at a 5,000 ft difference.
-				// Just a wild guess!
-  double factor = ((aircraftElev*SG_METER_TO_FEET) - stationElev) / 5000.0;
-  double range = fabs(nominalRange * factor);
-
-				// Clamp the range to keep it sane; for
-				// now, never less than 25% or more than
-				// 500% of nominal range.
-  if (range < nominalRange/4.0) {
-    range = nominalRange/4.0;
-  } else if (range > nominalRange*5.0) {
-    range = nominalRange*5.0;
-  }
-
-  return range;
-}
-
-
 // Constructor
-FGRadioStack::FGRadioStack() :
-    lon_node(fgGetNode("/position/longitude-deg", true)),
-    lat_node(fgGetNode("/position/latitude-deg", true)),
-    alt_node(fgGetNode("/position/altitude-ft", true)),
-    need_update(true),
-    outer_blink(false),
-    middle_blink(false),
-    inner_blink(false)
-{
-    SGPath path( globals->get_fg_root() );
-    SGPath term = path;
-    term.append( "Navaids/range.term" );
-    SGPath low = path;
-    low.append( "Navaids/range.low" );
-    SGPath high = path;
-    high.append( "Navaids/range.high" );
-
-    term_tbl = new SGInterpTable( term.str() );
-    low_tbl = new SGInterpTable( low.str() );
-    high_tbl = new SGInterpTable( high.str() );
+FGRadioStack::FGRadioStack() {
 }
 
 
 // Destructor
 FGRadioStack::~FGRadioStack() 
 {
+    adf.unbind();
+    beacon.unbind();
     navcom1.unbind();
     navcom2.unbind();
-    adf.unbind();
     xponder.unbind();
-    unbind();			// FIXME: should be called externally
-
-    delete term_tbl;
-    delete low_tbl;
-    delete high_tbl;
 }
 
 
@@ -119,23 +71,11 @@ FGRadioStack::init ()
     navcom2.init();
 
     adf.init();
+    beacon.init();
     xponder.init();
 
-    morse.init();
-    beacon.init();
-    blink.stamp();
-
     search();
-    navcom1.search();
-    navcom2.search();
-    adf.search();
-    xponder.search();
-
     update(0);			// FIXME: use dt
-    navcom1.update(0);
-    navcom2.update(0);
-    adf.update(0);
-    xponder.update(0);
 
     // Search radio database once per second
     global_events.Register( "fgRadioSearch()",
@@ -147,17 +87,8 @@ FGRadioStack::init ()
 void
 FGRadioStack::bind ()
 {
-
-    fgTie("/radios/marker-beacon/inner", this,
-	  &FGRadioStack::get_inner_blink);
-
-    fgTie("/radios/marker-beacon/middle", this,
-	  &FGRadioStack::get_middle_blink);
-
-    fgTie("/radios/marker-beacon/outer", this,
-	  &FGRadioStack::get_outer_blink);
-
     adf.bind();
+    beacon.bind();
     dme.bind();
     navcom1.set_bind_index( 0 );
     navcom1.bind();
@@ -170,11 +101,8 @@ FGRadioStack::bind ()
 void
 FGRadioStack::unbind ()
 {
-    fgUntie("/radios/marker-beacon/inner");
-    fgUntie("/radios/marker-beacon/middle");
-    fgUntie("/radios/marker-beacon/outer");
-
     adf.unbind();
+    beacon.unbind();
     dme.unbind();
     navcom1.unbind();
     navcom2.unbind();
@@ -186,126 +114,22 @@ FGRadioStack::unbind ()
 void 
 FGRadioStack::update(double dt) 
 {
-    need_update = false;
-
     adf.update( dt );
+    beacon.update( dt );
     navcom1.update( dt );
     navcom2.update( dt );
     dme.update( dt );           // dme is updated after the navcom's
     xponder.update( dt );
-
-    // marker beacon blinking
-    bool light_on = ( outer_blink || middle_blink || inner_blink );
-    SGTimeStamp current;
-    current.stamp();
-
-    if ( light_on && (current - blink > 400000) ) {
-	light_on = false;
-	blink.stamp();
-    } else if ( !light_on && (current - blink > 100000) ) {
-	light_on = true;
-	blink.stamp();
-    }
-
-    if ( outer_marker ) {
-	outer_blink = light_on;
-    } else {
-	outer_blink = false;
-    }
-
-    if ( middle_marker ) {
-	middle_blink = light_on;
-    } else {
-	middle_blink = false;
-    }
-
-    if ( inner_marker ) {
-	inner_blink = light_on;
-    } else {
-	inner_blink = false;
-    }
-
-    // cout << outer_blink << " " << middle_blink << " " << inner_blink << endl;
 }
 
 
 // Update current nav/adf radio stations based on current postition
 void FGRadioStack::search() 
 {
-    static FGMkrBeacon::fgMkrBeacType last_beacon = FGMkrBeacon::NOBEACON;
-
-    double lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
-
     adf.search();
+    beacon.search();
     navcom1.search();
     navcom2.search();
     dme.search();
     xponder.search();
-
-    ////////////////////////////////////////////////////////////////////////
-    // Beacons.
-    ////////////////////////////////////////////////////////////////////////
-
-    FGMkrBeacon::fgMkrBeacType beacon_type
-	= current_beacons->query( lon * SGD_RADIANS_TO_DEGREES,
-				  lat * SGD_RADIANS_TO_DEGREES, elev );
-
-    outer_marker = middle_marker = inner_marker = false;
-
-    if ( beacon_type == FGMkrBeacon::OUTER ) {
-	outer_marker = true;
-	// cout << "OUTER MARKER" << endl;
-#ifdef ENABLE_AUDIO_SUPPORT
-	if ( last_beacon != FGMkrBeacon::OUTER ) {
-	    if ( ! globals->get_soundmgr()->exists( "outer-marker" ) ) {
-		FGSimpleSound *sound = beacon.get_outer();
-		sound->set_volume( 0.3 );
-		globals->get_soundmgr()->add( sound, "outer-marker" );
-	    }
-	    if ( !globals->get_soundmgr()->is_playing("outer-marker") ) {
-		globals->get_soundmgr()->play_looped( "outer-marker" );
-	    }
-	}
-#endif
-    } else if ( beacon_type == FGMkrBeacon::MIDDLE ) {
-	middle_marker = true;
-	// cout << "MIDDLE MARKER" << endl;
-#ifdef ENABLE_AUDIO_SUPPORT
-	if ( last_beacon != FGMkrBeacon::MIDDLE ) {
-	    if ( ! globals->get_soundmgr()->exists( "middle-marker" ) ) {
-		FGSimpleSound *sound = beacon.get_middle();
-		sound->set_volume( 0.3 );
-		globals->get_soundmgr()->add( sound, "middle-marker" );
-	    }
-	    if ( !globals->get_soundmgr()->is_playing("middle-marker") ) {
-		globals->get_soundmgr()->play_looped( "middle-marker" );
-	    }
-	}
-#endif
-    } else if ( beacon_type == FGMkrBeacon::INNER ) {
-	inner_marker = true;
-	// cout << "INNER MARKER" << endl;
-#ifdef ENABLE_AUDIO_SUPPORT
-	if ( last_beacon != FGMkrBeacon::INNER ) {
-	    if ( ! globals->get_soundmgr()->exists( "inner-marker" ) ) {
-		FGSimpleSound *sound = beacon.get_inner();
-		sound->set_volume( 0.3 );
-		globals->get_soundmgr()->add( sound, "inner-marker" );
-	    }
-	    if ( !globals->get_soundmgr()->is_playing("inner-marker") ) {
-		globals->get_soundmgr()->play_looped( "inner-marker" );
-	    }
-	}
-#endif
-    } else {
-	// cout << "no marker" << endl;
-#ifdef ENABLE_AUDIO_SUPPORT
-	globals->get_soundmgr()->stop( "outer-marker" );
-	globals->get_soundmgr()->stop( "middle-marker" );
-	globals->get_soundmgr()->stop( "inner-marker" );
-#endif
-    }
-    last_beacon = beacon_type;
 }
diff --git a/src/Cockpit/radiostack.hxx b/src/Cockpit/radiostack.hxx
index 17f5e6013..10d59cf09 100644
--- a/src/Cockpit/radiostack.hxx
+++ b/src/Cockpit/radiostack.hxx
@@ -41,37 +41,16 @@
 #include "dme.hxx"
 #include "kr_87.hxx"            // ADF
 #include "kt_70.hxx"            // Transponder
+#include "marker_beacon.hxx"
 #include "navcom.hxx"
 
 
 class FGRadioStack : public FGSubsystem
 {
-    FGBeacon beacon;
-    FGMorse morse;
-
-    SGInterpTable *term_tbl;
-    SGInterpTable *low_tbl;
-    SGInterpTable *high_tbl;
-
-    SGPropertyNode *lon_node;
-    SGPropertyNode *lat_node;
-    SGPropertyNode *alt_node;
-    SGPropertyNode *dme_bus_power;
-
-    bool need_update;
-
-    bool outer_marker;
-    bool middle_marker;
-    bool inner_marker;
-
-    SGTimeStamp blink;
-    bool outer_blink;
-    bool middle_blink;
-    bool inner_blink;
-
     FGDME dme;
     FGKR_87 adf;                // King KR 87 Digital ADF model
     FGKT_70 xponder;            // Bendix/King KT 70 Panel-Mounted Transponder
+    FGMarkerBeacon beacon;
     FGNavCom navcom1;
     FGNavCom navcom2;
 
@@ -90,11 +69,6 @@ public:
 
     inline FGNavCom *get_navcom1() { return &navcom1; }
     inline FGNavCom *get_navcom2() { return &navcom2; }
-
-    // Marker Beacon Accessors
-    inline bool get_inner_blink () const { return inner_blink; }
-    inline bool get_middle_blink () const { return middle_blink; }
-    inline bool get_outer_blink () const { return outer_blink; }
 };