diff --git a/aclocal.m4 b/aclocal.m4 index 7d5836b91..78a4037e5 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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 diff --git a/src/ATC/ATCdisplay.cxx b/src/ATC/ATCdisplay.cxx index c3a91ba75..26e66c685 100644 --- a/src/ATC/ATCdisplay.cxx +++ b/src/ATC/ATCdisplay.cxx @@ -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; } diff --git a/src/ATC/ATCdisplay.hxx b/src/ATC/ATCdisplay.hxx index 5577c0603..867dc7ea0 100644 --- a/src/ATC/ATCdisplay.hxx +++ b/src/ATC/ATCdisplay.hxx @@ -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 diff --git a/src/ATC/atis.cxx b/src/ATC/atis.cxx index 6d49f7a0d..2d27cf270 100644 --- a/src/ATC/atis.cxx +++ b/src/ATC/atis.cxx @@ -25,17 +25,17 @@ #include +#include // atoi() #include 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 //#include -//#include #include //#ifndef FG_OLD_WEATHER @@ -48,6 +48,41 @@ SG_USING_STD(string); #include #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 +} diff --git a/src/ATC/atislist.cxx b/src/ATC/atislist.cxx index 54f5ae0ee..72e81e903 100644 --- a/src/ATC/atislist.cxx +++ b/src/ATC/atislist.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #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); +} diff --git a/src/ATC/atislist.hxx b/src/ATC/atislist.hxx index 284a95627..795deb349 100644 --- a/src/ATC/atislist.hxx +++ b/src/ATC/atislist.hxx @@ -28,11 +28,13 @@ #include #include +#include #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 ); }; diff --git a/src/Cockpit/radiostack.cxx b/src/Cockpit/radiostack.cxx index 25a56c60d..64f6fe43c 100644 --- a/src/Cockpit/radiostack.cxx +++ b/src/Cockpit/radiostack.cxx @@ -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 { diff --git a/src/GUI/mouse.cxx b/src/GUI/mouse.cxx index 140591b4d..9cf80a794 100644 --- a/src/GUI/mouse.cxx +++ b/src/GUI/mouse.cxx @@ -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(); } diff --git a/src/Include/config.h.in b/src/Include/config.h.in index 553a55a5a..3c18956c7 100644 --- a/src/Include/config.h.in +++ b/src/Include/config.h.in @@ -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