]> git.mxchange.org Git - flightgear.git/commitdiff
David Luff writes:
authorcurt <curt>
Mon, 19 Nov 2001 23:53:36 +0000 (23:53 +0000)
committercurt <curt>
Mon, 19 Nov 2001 23:53:36 +0000 (23:53 +0000)
Heres an update to the ATIS stuff.  In brief:

The possible buffer overflow in the display with wind should
hopefully be fixed.

Temperature is taken from the global temperature property instead
of being hardwired.

The display class now includes an implementation of the member
function to change the repeating message.

The message callsign is no longer hardwired.  The first message
from each station is generated with a random callsign.
Subsequent messages from the same station have the callsign
incremented every hour.  A map of airport-id vs. last callsign and
transmission time is kept for each station that has transmitted for
the duration of the FlightGear session.  The logic might be flaky if
FlightGear is run for more than 24 hours at a stretch between
visiting the same ATIS station though!  (ie I don't check the day.)
This map is kept in the atislist class.  This might not be the best
long-term place for it (in an ATC class of some sort might be
better), but it works for now.

aclocal.m4
src/ATC/ATCdisplay.cxx
src/ATC/ATCdisplay.hxx
src/ATC/atis.cxx
src/ATC/atislist.cxx
src/ATC/atislist.hxx
src/Cockpit/radiostack.cxx
src/GUI/mouse.cxx
src/Include/config.h.in

index 7d5836b91f4d1fbed719541171644fe7ba3a68b6..78a4037e5c412f8cbb48479f9e8cf5998f0aad3e 100644 (file)
@@ -1,4 +1,4 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4-p4
+dnl aclocal.m4 generated automatically by aclocal 1.4
 
 dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
index c3a91ba75327213579fcd467eae0c7e1e938c561..26e66c68516ab8897683132ed4c433980ffa853c 100644 (file)
@@ -37,6 +37,7 @@ FGATCDisplay *current_atcdisplay;
 // Constructor
 FGATCDisplay::FGATCDisplay( void ) {
     rep_msg = false;
+    change_msg_flag = false;
     dsp_offset1 = 0;
     dsp_offset2 = 0;
 }
@@ -53,7 +54,30 @@ void FGATCDisplay::init( void ) {
 // update - this actually draws the visuals and should be called from the main Flightgear rendering loop.
 void FGATCDisplay::update() {
 
+    // These strings are used for temporary storage of the transmission string in order
+    // that the string we view only changes when the next repitition starts scrolling
+    // even though the master string (rep_msg_str) may change at any time.
+    static string msg1 = "";
+    static string msg2 = "";
+
     if(rep_msg) {
+       //cout << "dsp_offset1 = " << dsp_offset1 << " dsp_offset2 = " << dsp_offset2 << endl;
+       if(dsp_offset1 == 0) {
+           msg1 = rep_msg_str;
+       }
+       if(dsp_offset2 == 0) {
+           msg2 = rep_msg_str;
+       }
+       // Check for the situation where one offset is negative and the message is changed
+       if(change_msg_flag) {
+           if(dsp_offset1 < 0) {
+               msg1 = rep_msg_str;
+           } else if(dsp_offset2 < 0) {
+               msg2 = rep_msg_str;
+           }
+           change_msg_flag = false;
+       }
+
        float fps = general.get_frame_rate();
        
        //cout << "In FGATC::update()" << endl;
@@ -62,13 +86,6 @@ void FGATCDisplay::update() {
        int iwidth   = xsize_node->getIntValue();
        int iheight  = ysize_node->getIntValue();
        
-       //TODO - if the string is bigger than the buffer the program exits - we really ought to have a robust check here
-       char buf[256];
-       //float fps = visibility/1600;
-       //      sprintf(buf,"%-4.1f  %7.0f  %7.0f", fps, tris, culled);
-//     sprintf(buf,"%s %-5.1f", "visibility ", visibility);
-       sprintf(buf,"%s", rep_msg_str.c_str());
-       
        glMatrixMode( GL_PROJECTION );
        glPushMatrix();
        glLoadIdentity();
@@ -82,13 +99,13 @@ void FGATCDisplay::update() {
        
        glColor3f( 0.9, 0.4, 0.2 );
        
-//     guiFnt.drawString( buf,
+//     guiFnt.drawString( rep_msg_str.c_str(),
 //         int(iwidth - guiFnt.getStringWidth(buf) - 10 - (int)dsp_offset),
 //         (iheight - 20) );
-       guiFnt.drawString( buf,
+       guiFnt.drawString( msg1.c_str(),
            int(iwidth - 10 - dsp_offset1),
            (iheight - 20) );
-       guiFnt.drawString( buf,
+       guiFnt.drawString( msg2.c_str(),
            int(iwidth - 10 - dsp_offset2),
            (iheight - 20) );
        glEnable( GL_DEPTH_TEST );
@@ -123,7 +140,8 @@ void FGATCDisplay::RegisterRepeatingMessage(string msg) {
 }
 
 void FGATCDisplay::ChangeRepeatingMessage(string newmsg) {
-    //Not implemented yet
+    rep_msg_str = newmsg;
+    change_msg_flag = true;
     return;
 }
 
index 5577c060388956115774aad8a6e087ec9ce11e7a..867dc7ea07942eac8348a7cad5b4e1a542a74860 100644 (file)
@@ -47,6 +47,7 @@ class FGATCDisplay {
 
 private:
     bool rep_msg;              // Flag to indicate there is a repeating transmission to display
+    bool change_msg_flag;      // Flag to indicate that the repeating message has changed
     float dsp_offset1;         // Used to set the correct position of scrolling display
     float dsp_offset2; 
     string rep_msg_str;                // The repeating transmission to play
index 6d49f7a0d5ce3cc7e368abfd66f2524f36bc088f..2d27cf27088001f6d14d4dae0c4ce3e93abaf5cc 100644 (file)
 
 #include <simgear/compiler.h>
 
+#include <stdlib.h>    // atoi()
 #include <string>
 SG_USING_STD(string);
 
-//#include STL_IOSTREAM
-//#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
-//SG_USING_STD(cout);
-//#endif
+#include STL_IOSTREAM
+#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
+SG_USING_STD(cout);
+#endif
 
 //#include <simgear/debug/logstream.hxx>
 //#include <simgear/misc/sgstream.hxx>
-//#include <simgear/math/sg_geodesy.hxx>
 #include <simgear/misc/sg_path.hxx>
 
 //#ifndef FG_OLD_WEATHER
@@ -48,6 +48,41 @@ SG_USING_STD(string);
 #include <Airports/runways.hxx>
 
 #include "atis.hxx"
+#include "atislist.hxx"
+
+string GetPhoneticIdent(int i) {
+// TODO - Check i is between 1 and 26 and wrap if necessary
+    switch(i) {
+    case 1 : return("Alpha");
+    case 2 : return("Bravo");
+    case 3 : return("Charlie");
+    case 4 : return("Delta");
+    case 5 : return("Echo");
+    case 6 : return("Foxtrot");
+    case 7 : return("Golf");
+    case 8 : return("Hotel");
+    case 9 : return("Indigo");
+    case 10 : return("Juliet");
+    case 11 : return("Kilo");
+    case 12 : return("Lima");
+    case 13 : return("Mike");
+    case 14 : return("November");
+    case 15 : return("Oscar");
+    case 16 : return("Papa");
+    case 17 : return("Quebec");
+    case 18 : return("Romeo");
+    case 19 : return("Sierra");
+    case 20 : return("Tango");
+    case 21 : return("Uniform");
+    case 22 : return("Victor");
+    case 23 : return("Whiskey");
+    case 24 : return("X-ray");
+    case 25 : return("Yankee");
+    case 26 : return("Zulu");
+    }
+    // We shouldn't get here
+    return("Error");
+}
 
 // Constructor
 FGATIS::FGATIS() {
@@ -64,6 +99,11 @@ string FGATIS::get_transmission() {
     double visibility;
     double temperature;
     char buf[10];
+    int phonetic_id;
+    string phonetic_id_string;
+    string time_str = fgGetString("sim/time/gmt-string");
+    int hours;
+    int minutes;
 
 // Only update every so-many loops - FIXME - possibly register this with the event scheduler
 // Ack this doesn't work since the static counter is shared between all instances of FGATIS
@@ -76,25 +116,34 @@ string FGATIS::get_transmission() {
        // Start with the transmitted station name.
        transmission += name;
 
+       //cout << "In atis.cxx, time_str = " << time_str << '\n';
        // Add the recording identifier
-       // TODO - this is hardwired for now - ultimately we need to start with a random one and then increment it with each recording
-       transmission += " Charlie";
+       // For now we will assume we only transmit every hour
+       hours = atoi((time_str.substr(1,2)).c_str());   //Warning - this is fragile if the 
+                                                       //time string format changes
+       //cout << "In atis.cxx, hours = " << hours << endl;
+       phonetic_id = current_atislist->GetCallSign(ident, hours, 0);
+       phonetic_id_string = GetPhoneticIdent(phonetic_id);
+       transmission += " ";
+       transmission += phonetic_id_string;
 
        // Output the recording time. - we'll just output the last whole hour for now.
-       string time_str = fgGetString("sim/time/gmt-string");
        // FIXME - this only gets GMT time but that appears to be all the clock outputs for now
        //cout << "in atis.cxx, time = " << time_str << endl;
        transmission = transmission + "  Weather " + time_str.substr(0,3) + "00 hours Zulu";
 
        // Get the temperature
-       // Hardwire the temperature for now - is the local weather database running yet?
-       transmission += "  Temperature 25 degrees Celcius";
+       temperature = fgGetDouble("/environment/weather/temperature-K");
+       sprintf(buf, "%i", int(temperature - 273.15));
+       transmission += "  Temperature ";
+       transmission += buf;
+       transmission += " degrees Celcius";
 
        // Get the pressure / altimeter
 
        // Get the visibility
        visibility = fgGetDouble("/environment/visibility-m");
-       sprintf(buf, "%d", int(visibility/1600));
+       sprintf(buf, "%i", int(visibility/1600));
        transmission += "  Visibility ";
        transmission += buf;
        transmission += " miles";
@@ -128,7 +177,7 @@ string FGATIS::get_transmission() {
            transmission += "  Winds light and variable";
        } else {
            //add a description of the wind to the transmission
-           char buf2[48];
+           char buf2[72];
            sprintf(buf2, "%s %i %s %i %s", "  Winds ", int(speed), " knots from ", int(hdg), " degrees");
            transmission += buf2;
        }
@@ -143,7 +192,8 @@ string FGATIS::get_transmission() {
        // Anything else?
 
        // TODO - unhardwire the identifier
-       transmission += "  Advise controller on initial contact you have Charlie";
+       transmission += "  Advise controller on initial contact you have ";
+       transmission += phonetic_id_string;
 
     //}
 
@@ -153,4 +203,4 @@ string FGATIS::get_transmission() {
 //    }
 
     return(transmission);
-}
\ No newline at end of file
+}
index 54f5ae0eea655f050120fccec7761683339cec17..72e81e903c03d083035669fd012eee5a6a6c1a2f 100644 (file)
@@ -26,6 +26,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sgstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/math/sg_random.h>
 
 #include "atislist.hxx"
 
@@ -147,3 +148,53 @@ bool FGATISList::query( double lon, double lat, double elev, double freq,
 
     return false;
 }
+
+
+int FGATISList::GetCallSign( string apt_id, int hours, int mins )
+{
+    atis_transmission_type tran;
+
+    if(atislog.find(apt_id) == atislog.end()) {
+       // This station has not transmitted yet - return a random identifier
+       // and add the transmission to the log
+       tran.hours = hours;
+       tran.mins = mins;
+       sg_srandom_time();
+       tran.callsign = int(sg_random() * 25) + 1;      // This *should* give a random int between 1 and 26
+       //atislog[apt_id].push_back(tran);
+       atislog[apt_id] = tran;
+    } else {
+       // This station has transmitted - calculate the appropriate identifier
+       // and add the transmission to the log if it has changed
+       tran = atislog[apt_id];
+       // This next bit assumes that no-one comes back to the same ATIS station
+       // after running FlightGear for more than 24 hours !!
+       if((tran.hours == hours) && (tran.mins == mins)) {
+           return(tran.callsign);
+       } else {
+           if(tran.hours == hours) {
+               // The minutes must have changed
+               tran.mins = mins;
+               tran.callsign++;
+           } else {
+               if(hours < tran.hours) {
+                   hours += 24;
+               }
+               tran.callsign += (hours - tran.hours);
+               if(mins != 0) {
+                   // Assume transmissions were made on every hour
+                   tran.callsign++;
+               }
+               tran.hours = hours;
+               tran.mins = mins;
+           }
+           // Wrap if we've exceeded Zulu
+           if(tran.callsign > 26) {
+               tran.callsign -= 26;
+           }
+           // And write the new transmission to the log
+           atislog[apt_id] = tran;
+       }
+    }
+    return(tran.callsign);
+}
index 284a95627b1653d12c7b5574f2599e0fa4975297..795deb3493db0d19e85980155527da0c0b780433 100644 (file)
 
 #include <map>
 #include <vector>
+#include <string>
 
 #include "atis.hxx"
 
 SG_USING_STD(map);
 SG_USING_STD(vector);
+SG_USING_STD(string);
 
 
 class FGATISList {
@@ -49,6 +51,21 @@ class FGATISList {
 
     atis_map_type atislist;
 
+    // Add structure and map for storing a log of atis transmissions
+    // made in this session of FlightGear.  This allows the callsign
+    // to be allocated correctly wrt time.
+    typedef struct {
+       int hours;
+       int mins;
+       int callsign;
+    } atis_transmission_type;
+
+    typedef map < string, atis_transmission_type > atis_log_type;
+    typedef atis_log_type::iterator atis_log_iterator;
+    typedef atis_log_type::const_iterator atis_log_const_iterator;
+
+    atis_log_type atislog;
+
 public:
 
     FGATISList();
@@ -60,6 +77,9 @@ public:
     // query the database for the specified frequency, lon and lat are
     // in degrees, elev is in meters
     bool query( double lon, double lat, double elev, double freq, FGATIS *a );
+
+    // Return the callsign for a transmission given transmission time and airpord id
+    int GetCallSign( string apt_id, int hours, int mins );
 };
 
 
index 25a56c60de0bd7a180597888dbaff65144614048..64f6fe43c2478b843f06d5b86c1f6ad77fb9dc8d 100644 (file)
@@ -429,14 +429,14 @@ FGRadioStack::update()
            // TODO - only get the transmission and register every now and then
            if(dcl_i == 0) {
                transmission = atis.get_transmission();
-               //ChangeRepeatingMessage(transmission);
+               current_atcdisplay->ChangeRepeatingMessage(transmission);
            }
            if(!repeating_message_registered) {
-               current_atcdisplay->RegisterRepeatingMessage( transmission );
+               current_atcdisplay->RegisterRepeatingMessage(transmission);
                repeating_message_registered = true;
            }
            dcl_i++;
-           if(dcl_i == 3000) {
+           if(dcl_i == 2000) {
                dcl_i = 0;
            }
        } else {
index 140591b4d2b412153fe49970935c677c45e5a6aa..9cf80a794a95e96a7bea7d9115fc0c83bc44c3eb 100644 (file)
@@ -270,12 +270,12 @@ void guiMotionFunc ( int x, int y )
 
     if (mouse_mode == MOUSE_POINTER) {
         // TURN MENU ON IF MOUSE AT TOP
-        if( y < 2 ) {
+        if( y == 0 ) {
             if( !gui_menu_on )
                 guiToggleMenu();                       
         }
         // TURN MENU OFF IF MOUSE AT BOTTOM
-        else if( y > wh-2 ) {
+        else if( y > wh-1 ) {
             if( gui_menu_on )
                 guiToggleMenu();                       
         }
index 553a55a5ab56b72ca2443667ba237352e6cec159..3c18956c748fa862c84648c611c235b2e4acbc17 100644 (file)
@@ -1,4 +1,4 @@
-/* src/Include/config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/* src/Include/config.h.in.  Generated automatically from configure.in by autoheader.  */
 
 /* Define to empty if the keyword does not work.  */
 #undef const