--- /dev/null
+// ATCDialog.cxx - Functions and classes to handle the pop-up ATC dialog
+//
+// Written by Alexander Kappes and David Luff, started February 2003.
+//
+// Copyright (C) 2003 Alexander Kappes and David Luff
+//
+// 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.
+
+#include <Main/globals.hxx>
+#include <Main/fgfs.hxx>
+#include <GUI/gui.h>
+#include <simgear/misc/commands.hxx>
+
+#include "ATCDialog.hxx"
+#include "ATC.hxx"
+#include "ATCmgr.hxx"
+
+FGATCDialog *current_atcdialog;
+
+// For the command manager - maybe eventually this should go in the built in command list
+static bool do_ATC_dialog(const SGPropertyNode* arg) {
+ globals->get_ATC_mgr()->doPopupDialog();
+ return(true);
+}
+
+ATCMenuEntry::ATCMenuEntry() {
+ stationid = "";
+ stationfr = 0;
+ transmission = "";
+ menuentry = "";
+}
+
+ATCMenuEntry::~ATCMenuEntry() {
+}
+
+static char* t0 = "Request landing clearance";
+static char* t1 = "Request departure clearance";
+static char* t2 = "Report Runway vacated";
+static char** towerOptions = new char*[4];
+
+// ----------------------- DCL ------------------------------------------
+// For the ATC dialog - copied from the Autopilot new heading dialog code!
+static puDialogBox* atcDialog;
+static puFrame* atcDialogFrame;
+static puText* atcDialogMessage;
+//static puInput* atcDialogInput;
+static puOneShot* atcDialogOkButton;
+static puOneShot* atcDialogCancelButton;
+static puButtonBox* atcDialogCommunicationOptions;
+// ----------------------------------------------------------------------
+
+// ------------------------ AK ------------------------------------------
+static puDialogBox *ATCMenuBox = 0;
+static puFrame *ATCMenuFrame = 0;
+static puText *ATCMenuBoxMessage = 0;
+static puButtonBox *ATCOptionsList = 0;
+// ----------------------------------------------------------------------
+
+// AK
+static void AKATCDialogOK(puObject *)
+{
+ switch(atcDialogCommunicationOptions->getValue()) {
+ case 0:
+ //cout << "Option 0 chosen\n";
+ fgSetBool("/sim/atc/opt0",true);
+ break;
+ case 1:
+ //cout << "Option 1 chosen\n";
+ fgSetBool("/sim/atc/opt1",true);
+ break;
+ case 2:
+ //cout << "Option 2 chosen\n";
+ fgSetBool("/sim/atc/opt2",true);
+ break;
+ case 3:
+ //cout << "Option 2 chosen\n";
+ fgSetBool("/sim/atc/opt3",true);
+ break;
+ default:
+ break;
+ }
+ FG_POP_PUI_DIALOG( ATCMenuBox );
+}
+
+// AK
+static void AKATCDialogCancel(puObject *)
+{
+ FG_POP_PUI_DIALOG( ATCMenuBox );
+}
+
+// DCL
+static void ATCDialogCancel(puObject *)
+{
+ //ATCDialogInput->rejectInput();
+ FG_POP_PUI_DIALOG( atcDialog );
+}
+
+// DCL
+static void ATCDialogOK (puObject *me)
+{
+ // Note that currently the dialog is hardwired to comm1 only here.
+ switch(globals->get_ATC_mgr()->GetComm1ATCType()) {
+ case INVALID:
+ break;
+ case ATIS:
+ break;
+ case TOWER: {
+ FGTower* twr = (FGTower*)globals->get_ATC_mgr()->GetComm1ATCPointer();
+ switch(atcDialogCommunicationOptions->getValue()) {
+ case 0:
+ //cout << "Option 0 chosen\n";
+ twr->RequestLandingClearance("golf bravo echo");
+ break;
+ case 1:
+ //cout << "Option 1 chosen\n";
+ twr->RequestDepartureClearance("golf bravo echo");
+ break;
+ case 2:
+ //cout << "Option 2 chosen\n";
+ twr->ReportRunwayVacated("golf bravo echo");
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GROUND:
+ break;
+ case APPROACH:
+ break;
+ default:
+ break;
+ }
+
+ ATCDialogCancel(me);
+ //if(error) mkDialog(s.c_str());
+}
+
+// DCL
+static void ATCDialog(puObject *cb)
+{
+ //ApHeadingDialogInput -> setValue ( heading );
+ //ApHeadingDialogInput -> acceptInput();
+ FG_PUSH_PUI_DIALOG(atcDialog);
+}
+
+// DCL
+void ATCDialogInit()
+{
+ char defaultATCLabel[] = "Enter desired option to communicate with ATC:";
+ char *s;
+
+ // Option lists hardwired per ATC type
+ towerOptions[0] = new char[strlen(t0)+1];
+ strcpy(towerOptions[0], t0);
+ towerOptions[1] = new char[strlen(t1)+1];
+ strcpy(towerOptions[1], t1);
+ towerOptions[2] = new char[strlen(t2)+1];
+ strcpy(towerOptions[2], t2);
+ towerOptions[3] = NULL;
+
+ atcDialog = new puDialogBox (150, 50);
+ {
+ atcDialogFrame = new puFrame (0, 0, 500, 250);
+
+ atcDialogMessage = new puText (250, 220);
+ atcDialogMessage -> setDefaultValue (defaultATCLabel);
+ atcDialogMessage -> getDefaultValue (&s);
+ atcDialogMessage -> setLabel (s);
+ atcDialogMessage -> setLabelPlace (PUPLACE_TOP_CENTERED);
+
+ atcDialogCommunicationOptions = new puButtonBox (50, 50, 450, 210, NULL, true);
+
+ atcDialogOkButton = new puOneShot (50, 10, 110, 50);
+ atcDialogOkButton -> setLegend (gui_msg_OK);
+ atcDialogOkButton -> makeReturnDefault (TRUE);
+ atcDialogOkButton -> setCallback (ATCDialogOK);
+
+ atcDialogCancelButton = new puOneShot (140, 10, 210, 50);
+ atcDialogCancelButton -> setLegend (gui_msg_CANCEL);
+ atcDialogCancelButton -> setCallback (ATCDialogCancel);
+
+ }
+ FG_FINALIZE_PUI_DIALOG(atcDialog);
+
+ // Add ATC-dialog to the command list
+ globals->get_commands()->addCommand("ATC-dialog", do_ATC_dialog);
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// ATCDoDialog is in a state of flux at the moment
+// Stations other than approach are handled by DCL's simple code
+// Approach is handled by AK's fancy dynamic-list code
+// Hopefully all interactive stations should go to AK's code eventually
+//
+///////////////////////////////////////////////////////////////////////
+void ATCDoDialog(atc_type type) {
+ switch(type) {
+ case INVALID:
+ atcDialogCommunicationOptions->newList(NULL);
+ atcDialogMessage->setLabel("Not tuned in to any ATC service.");
+ break;
+ case ATIS:
+ atcDialogCommunicationOptions->newList(NULL);
+ atcDialogMessage->setLabel("Tuned in to ATIS: no communication possible.");
+ break;
+ case TOWER:
+ atcDialogCommunicationOptions->newList(towerOptions);
+ atcDialogMessage->setLabel("Tuned in to Tower - select communication to transmit:");
+ break;
+ case GROUND:
+ atcDialogCommunicationOptions->newList(NULL);
+ atcDialogMessage->setLabel("Tuned in to Ground - select communication to transmit:");
+ break;
+ case APPROACH:
+ current_atcdialog->DoDialog();
+ break;
+ default:
+ atcDialogCommunicationOptions->newList(NULL);
+ atcDialogMessage->setLabel("Tuned in to unknown ATC service - enter transmission:");
+ break;
+ }
+
+ // Third - display the dialog without pausing sim.
+ if(type != APPROACH) {
+ ATCDialog(NULL);
+ }
+}
+
+void FGATCDialog::Init() {
+}
+
+// AK
+// Add an entry
+void FGATCDialog::add_entry(string station, string transmission, string menutext ) {
+
+ ATCMenuEntry a;
+
+ a.stationid = station;
+ a.transmission = transmission;
+ a.menuentry = menutext;
+
+ atcmentrylist_station[station.c_str()].push_back(a);
+
+}
+
+// AK
+// query the database whether the transmission is already registered;
+bool FGATCDialog::trans_reg( const string &station, const string &trans ) {
+
+ atcmentry_list_type atcmlist = atcmentrylist_station[station];
+ atcmentry_list_iterator current = atcmlist.begin();
+ atcmentry_list_iterator last = atcmlist.end();
+
+ for ( ; current != last ; ++current ) {
+ if ( current->transmission == trans ) return true;
+ }
+ return false;
+}
+
+// AK
+// ===================================================
+// === Update ATC menue and look for keys pressed ===
+// ===================================================
+void FGATCDialog::DoDialog() {
+
+ static string mentry[10];
+ static string mtrans[10];
+ char buf[10];
+ TransPar TPar;
+ FGATC* atcptr = globals->get_ATC_mgr()->GetComm1ATCPointer(); // Hardwired to comm1 at the moment
+
+ if(atcptr != NULL) {
+
+ atcmentry_list_type atcmlist = atcmentrylist_station[atcptr->get_ident()];
+ //atcmentry_list_type atcmlist = atcmentrylist_station["EGNX"];
+ atcmentry_list_iterator current = atcmlist.begin();
+ atcmentry_list_iterator last = atcmlist.end();
+
+ // Set all opt flags to false before displaying box
+ fgSetBool("/sim/atc/opt0",false);
+ fgSetBool("/sim/atc/opt1",false);
+ fgSetBool("/sim/atc/opt2",false);
+ fgSetBool("/sim/atc/opt3",false);
+ fgSetBool("/sim/atc/opt4",false);
+ fgSetBool("/sim/atc/opt5",false);
+ fgSetBool("/sim/atc/opt6",false);
+ fgSetBool("/sim/atc/opt7",false);
+ fgSetBool("/sim/atc/opt8",false);
+ fgSetBool("/sim/atc/opt9",false);
+
+ //int yc = 10;
+ int yc = 70;
+ int xsize = 600;
+ if ( atcmlist.size() != 0 ){
+ int k=atcmlist.size();
+ //int k = 3;
+ //cout << "k = " << k << endl;
+ int y = (fgGetInt("/sim/startup/ysize") - 200 - 20 - k*20);
+ ATCMenuBox = new puDialogBox (100, y);
+ // loop over all entries in atcmentrylist
+ ATCOptionsList = new puButtonBox (50, 50, 450, 50+(k*25), NULL, true);
+ char** optList = new char*[k+1];
+ int kk = 0;
+ for ( ; current != last ; ++current ) {
+ string dum;
+ sprintf( buf, "%i", kk+1 );
+ buf[1] = '\0';
+ dum = (string)(buf);
+ mentry[kk] = dum + ". " + current->menuentry;
+ optList[kk] = new char[strlen(mentry[kk].c_str()) + 1];
+ strcpy(optList[kk], mentry[kk].c_str());
+ //cout << "optList[" << kk << "] = " << optList[kk] << endl;
+ mtrans[kk] = current->transmission;
+ //ATCMenuBoxMessage = new puText (10, yc);
+ //ATCMenuBoxMessage -> setLabel( mentry[kk].c_str() );
+ yc += 20;
+ ++kk;
+ }
+ yc += 2*20;
+ optList[k] = NULL;
+ ATCOptionsList->newList(optList);
+ } else {
+ int y = (fgGetInt("/sim/startup/ysize") - 100 - 20 );
+ ATCMenuBox = new puDialogBox (10, y);
+ ATCMenuBoxMessage = new puText (10, yc-10);
+ ATCMenuBoxMessage -> setLabel( "No transmission available" );
+ }
+
+ ATCMenuBoxMessage = new puText (10, yc+10);
+ ATCMenuBoxMessage -> setLabel( "ATC Menu" );
+ ATCMenuFrame = new puFrame (0,0,xsize,yc+40);
+ atcDialogOkButton = new puOneShot ((xsize/2)-85, 10, (xsize/2)-25, 50);
+ atcDialogOkButton -> setLegend (gui_msg_OK);
+ atcDialogOkButton -> makeReturnDefault (TRUE);
+ atcDialogOkButton -> setCallback (AKATCDialogOK);
+
+ atcDialogCancelButton = new puOneShot ((xsize/2)+25, 10, (xsize/2)+85, 50);
+ atcDialogCancelButton -> setLegend (gui_msg_CANCEL);
+ atcDialogCancelButton -> setCallback (AKATCDialogCancel);
+ FG_FINALIZE_PUI_DIALOG( ATCMenuBox );
+ FG_PUSH_PUI_DIALOG( ATCMenuBox );
+
+
+ /*
+ if ( atckey != -1 && TransDisplayed && mtrans[atckey-1].c_str() != "" ) {
+ cout << mtrans[atckey-1].c_str() << endl;
+ TPar = current_transmissionlist->extract_transpar( mtrans[atckey-1].c_str() );
+ current_atcmentrylist->reset = true;
+ current_transparlist->add_entry( TPar );
+
+ // transpar_list_type test = current_transparlist;
+ // transpar_list_iterator current = test.begin();
+ //for ( ; current != test.end(); ++current ) {
+ // current->tpar.intention;
+ //}
+ }
+
+ if ( current_atcmentrylist->freq != (int)(comm1_freq*100.0 + 0.5) ) {
+ current_atcmentrylist->reset = true;
+ }
+
+ // reset (delete) ATCmenue list if reset is true
+ if ( current_atcmentrylist->reset == true ) {
+ delete ( current_atcmentrylist );
+ current_atcmentrylist = new FGatcmentryList;
+ current_atcmentrylist->init( (int)(comm1_freq*100.0 + 0.5) );
+ if ( TransDisplayed ) {
+ FG_POP_PUI_DIALOG( ATCMenuBox );
+ TransDisplayed = false;
+ }
+ }
+ */
+ }
+}
+
--- /dev/null
+// ATCDialog.hxx - Functions and classes to handle the pop-up ATC dialog
+//
+// Written by Alexander Kappes and David Luff, started February 2003.
+//
+// Copyright (C) 2003 Alexander Kappes and David Luff
+//
+// 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.
+
+#ifndef ATC_DIALOG_HXX
+#define ATC_DIALOG_HXX
+
+#include <simgear/compiler.h>
+
+#include "ATC.hxx"
+
+// ATCMenuEntry - an encapsulation of an entry in the ATC dialog
+struct ATCMenuEntry {
+
+ string stationid; // ID of transmitting station
+ int stationfr; // ?
+ string transmission; // Actual speech of transmission
+ string menuentry; // Shortened version for display in the dialog
+
+ ATCMenuEntry();
+ ~ATCMenuEntry();
+};
+
+// convenience types
+typedef vector < ATCMenuEntry > atcmentry_list_type;
+typedef atcmentry_list_type::iterator atcmentry_list_iterator;
+typedef atcmentry_list_type::const_iterator atcmentry_list_const_iterator;
+
+// typedef map < string, atcmentry_list_type, less<string> > atcmentry_map_type;
+typedef map < string, atcmentry_list_type > atcmentry_map_type;
+typedef atcmentry_map_type::iterator atcmentry_map_iterator;
+typedef atcmentry_map_type::const_iterator atcmentry_map_const_iterator;
+
+void ATCDialogInit();
+
+void ATCDoDialog(atc_type type);
+
+class FGATCDialog {
+
+public:
+
+ void Init();
+
+ void DoDialog();
+
+ void add_entry( string station, string transmission, string menutext );
+
+ bool trans_reg( const string &station, const string &trans );
+
+private:
+
+ atcmentry_map_type atcmentrylist_station;
+
+ int freq;
+ bool reset;
+};
+
+extern FGATCDialog *current_atcdialog;
+
+#endif // ATC_DIALOG_HXX
+
--- /dev/null
+// FGTransmission - a class to provide transmission control at larger airports.\r
+//\r
+// Written by Alexander Kappes, started March 2002.\r
+// Based on ground.cxx by David Luff, started March 2002.\r
+//\r
+// Copyright (C) 2002 David C. Luff - david.luff@nottingham.ac.uk\r
+//\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License as\r
+// published by the Free Software Foundation; either version 2 of the\r
+// License, or (at your option) any later version.\r
+//\r
+// This program is distributed in the hope that it will be useful, but\r
+// WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+// General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+\r
+#include "transmission.hxx"\r
+\r
+#include <simgear/misc/sg_path.hxx>\r
+\r
+\r
+//Constructor\r
+FGTransmission::FGTransmission(){\r
+}\r
+\r
+//Destructor\r
+FGTransmission::~FGTransmission(){\r
+}\r
+\r
+void FGTransmission::Init() {\r
+}\r
+\r
+// ============================================================================\r
+// extract parameters from transmission\r
+// ============================================================================\r
+TransPar FGTransmission::Parse() {\r
+ TransPar tpar;\r
+ string tokens[20];\r
+ int msglen,toklen;\r
+ char dum;\r
+ int i,j,k;\r
+ const char *capl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";\r
+\r
+ msglen = strlen( TransText.c_str() );\r
+\r
+ int tkn = 0;\r
+ for ( i=0; i < msglen; ++i ) {\r
+ if ( TransText.c_str()[i] != ' ' ) {\r
+ if ( TransText.c_str()[i] != ',' ) tokens[tkn] += TransText.c_str()[i];\r
+ } else if ( tokens[tkn] != "" ) {\r
+ if ( tkn <= 20 ) {\r
+ tkn += 1;\r
+ } else {\r
+ cout << "Too many tokens" << endl;\r
+ }\r
+ }\r
+ }\r
+\r
+ for ( i=0; i<20; ++i) {\r
+ \r
+ if ( tokens[i] == "request" ) {\r
+ tpar.request = true;\r
+ } else if ( tokens[i] == "approach" ) { \r
+ tpar.station = "approach";\r
+ tpar.airport = tokens[i-1];\r
+ } else if ( tokens[i] == "landing" ) { \r
+ tpar.intention = "landing";\r
+ for ( j=i+1; j<=i+2; ++j ) {\r
+ if ( tokens[j] != "" ) {\r
+ toklen = strlen( tokens[j].c_str() );\r
+ bool aid = true;\r
+ for ( k=0; k<toklen; ++k )\r
+ if ( ! strpbrk( &tokens[j].c_str()[k], capl )) {\r
+ aid = false;\r
+ break;\r
+ }\r
+ if ( aid ) tpar.intid = tokens[j];\r
+ }\r
+ }\r
+ } else if ( tokens[i] == "Player" ) { \r
+ tpar.callsign = tokens[i];\r
+ }\r
+ }\r
+\r
+ //cout << tpar.airport << endl;\r
+ //cout << tpar.request << endl;\r
+ //cout << tpar.intention << endl;\r
+ //cout << tpar.intid << endl;\r
+\r
+ return tpar;\r
+}\r
--- /dev/null
+// transmission.hxx -- Transmission class\r
+//\r
+// Written by Alexander Kappes, started March 2002.\r
+// Based on nav.hxx by Curtis Olson, started April 2000.\r
+//\r
+// Copyright (C) 2001 David C. Luff - david.luff@nottingham.ac.uk\r
+//\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License as\r
+// published by the Free Software Foundation; either version 2 of the\r
+// License, or (at your option) any later version.\r
+//\r
+// This program is distributed in the hope that it will be useful, but\r
+// WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+// General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+\r
+\r
+#ifndef _FG_TRANSMISSION_HXX\r
+#define _FG_TRANSMISSION_HXX\r
+\r
+#include <stdio.h>\r
+\r
+#include <simgear/compiler.h>\r
+#include <simgear/math/sg_geodesy.hxx>\r
+#include <simgear/misc/sgstream.hxx>\r
+#include <simgear/magvar/magvar.hxx>\r
+#include <simgear/timing/sg_time.hxx>\r
+#include <simgear/bucket/newbucket.hxx>\r
+\r
+#include <Main/fg_props.hxx>\r
+\r
+#ifdef SG_HAVE_STD_INCLUDES\r
+# include <istream>\r
+#include <iomanip>\r
+#elif defined( SG_HAVE_NATIVE_SGI_COMPILERS )\r
+# include <iostream.h>\r
+#elif defined( __BORLANDC__ )\r
+# include <iostream>\r
+#else\r
+# include <istream.h>\r
+#include <iomanip.h>\r
+#endif\r
+\r
+#if ! defined( SG_HAVE_NATIVE_SGI_COMPILERS )\r
+SG_USING_STD(istream);\r
+#endif\r
+\r
+SG_USING_STD(string);\r
+\r
+struct TransCode {\r
+ int c1;\r
+ int c2;\r
+ int c3;\r
+};\r
+\r
+// TransPar - a representation of the logic of a parsed speech transmission\r
+struct TransPar {\r
+ string station;\r
+ string callsign;\r
+ string airport;\r
+ string intention; // landing, crossing\r
+ string intid; // (airport) ID for intention\r
+ bool request; // is the transmission a request or an answer?\r
+ int tdir; // turning direction: 1=left, 2=right\r
+ double heading;\r
+ int VDir; // vertical direction: 1=descent, 2=maintain, 3=climb\r
+ double alt;\r
+ double miles;\r
+ string runway;\r
+ double freq;\r
+ double time;\r
+};\r
+\r
+// FGTransmission - a class to encapsulate a speech transmission\r
+class FGTransmission {\r
+\r
+ int StationType; // Type of ATC station: 1 Approach\r
+ TransCode Code;\r
+ string TransText;\r
+ string MenuText;\r
+\r
+public:\r
+\r
+ FGTransmission(void);\r
+ ~FGTransmission(void);\r
+\r
+ void Init();\r
+\r
+ inline int get_station() const { return StationType; }\r
+ inline TransCode get_code() { return Code; }\r
+ inline string get_transtext() { return TransText; }\r
+ inline string get_menutext() { return MenuText; }\r
+\r
+ // Return the parsed logic of the transmission \r
+ TransPar Parse();\r
+\r
+private:\r
+\r
+ friend istream& operator>> ( istream&, FGTransmission& );\r
+\r
+};\r
+\r
+\r
+inline istream&\r
+operator >> ( istream& in, FGTransmission& a ) {\r
+ char ch;\r
+ \r
+ static bool first_time = true;\r
+ static double julian_date = 0;\r
+ static const double MJD0 = 2415020.0;\r
+ if ( first_time ) {\r
+ julian_date = sgTimeCurrentMJD(0, 0) + MJD0;\r
+ first_time = false;\r
+ }\r
+ in >> a.StationType;\r
+ in >> a.Code.c1;\r
+ in >> a.Code.c2;\r
+ in >> a.Code.c3;\r
+ a.TransText = "";\r
+ in >> ch;\r
+ if ( ch != '"' ) a.TransText += ch;\r
+ while(1) {\r
+ //in >> noskipws\r
+ in.unsetf(ios::skipws);\r
+ in >> ch;\r
+ if ( ch != '"' ) a.TransText += ch;\r
+ if((ch == '"') || (ch == 0x0A)) {\r
+ break;\r
+ } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "\r
+ }\r
+ in.setf(ios::skipws);\r
+ \r
+ a.MenuText = "";\r
+ in >> ch;\r
+ if ( ch != '"' ) a.MenuText += ch;\r
+ while(1) {\r
+ //in >> noskipws\r
+ in.unsetf(ios::skipws);\r
+ in >> ch;\r
+ if ( ch != '"' ) a.MenuText += ch;\r
+ if((ch == '"') || (ch == 0x0A)) {\r
+ break;\r
+ } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "\r
+ }\r
+ in.setf(ios::skipws);\r
+ \r
+ //cout << "Code = " << a.Code << " Transmission text = " << a.TransText \r
+ // << " Menu text = " << a.MenuText << endl;\r
+ \r
+ return in >> skipeol;\r
+}\r
+\r
+\r
+#endif // _FG_TRANSMISSION_HXX\r
--- /dev/null
+// transmissionlist.cxx -- transmission management class\r
+//\r
+// Written by Alexander Kappes, started March 2002.\r
+// Based on navlist.cxx by Curtis Olson, started April 2000.\r
+//\r
+// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org\r
+//\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License as\r
+// published by the Free Software Foundation; either version 2 of the\r
+// License, or (at your option) any later version.\r
+//\r
+// This program is distributed in the hope that it will be useful, but\r
+// WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+// General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+//\r
+// $Id$\r
+\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
+#include <simgear/debug/logstream.hxx>\r
+#include <simgear/misc/sgstream.hxx>\r
+#include <simgear/math/sg_geodesy.hxx>\r
+\r
+#include "transmissionlist.hxx"\r
+\r
+#include <GUI/gui.h>\r
+\r
+static puDialogBox *ATCMenuBox = 0;\r
+static puFrame *ATCMenuFrame = 0;\r
+static puText *ATCMenuBoxMessage = 0;\r
+\r
+FGTransmissionList *current_transmissionlist;\r
+\r
+\r
+// Constructor\r
+FGTransmissionList::FGTransmissionList( void ) {\r
+}\r
+\r
+\r
+// Destructor\r
+FGTransmissionList::~FGTransmissionList( void ) {\r
+}\r
+\r
+/*\r
+// ============================================================================\r
+// init menu window\r
+// ============================================================================\r
+void mkATCMenuInit (void)\r
+{\r
+ int dx = 400;\r
+ int dy = 100;\r
+ int y = (fgGetInt("/sim/startup/ysize") - 10 - dy);\r
+ ATCMenuBox = new puDialogBox (10, y);\r
+ {\r
+ ATCMenuFrame = new puFrame (0,0,400,100);\r
+ ATCMenuBoxMessage = new puText (10, 70);\r
+ ATCMenuBoxMessage -> setLabel ("");\r
+ }\r
+ fgSetBool("/sim/atc/menu",false);\r
+ fgSetBool("/sim/atc/opt1",false);\r
+ fgSetBool("/sim/atc/opt2",false);\r
+ fgSetBool("/sim/atc/opt3",false);\r
+ fgSetBool("/sim/atc/opt4",false);\r
+ fgSetBool("/sim/atc/opt5",false);\r
+ fgSetBool("/sim/atc/opt6",false);\r
+ fgSetBool("/sim/atc/opt7",false);\r
+ fgSetBool("/sim/atc/opt8",false);\r
+ fgSetBool("/sim/atc/opt9",false);\r
+ fgSetBool("/sim/atc/opt0",false);\r
+}\r
+\r
+// ATC Menu Message Box\r
+void mkATCMenu ( const char *txt )\r
+{\r
+ ATCMenuBoxMessage = new puText (10, 70);\r
+ ATCMenuBoxMessage->setLabel( txt );\r
+\r
+ FG_PUSH_PUI_DIALOG( ATCMenuBox );\r
+}\r
+*/\r
+\r
+// load default.transmissions\r
+bool FGTransmissionList::init( SGPath path ) {\r
+ FGTransmission a;\r
+\r
+ transmissionlist_station.erase( transmissionlist_station.begin(), transmissionlist_station.end() );\r
+\r
+ sg_gzifstream in( path.str() );\r
+ if ( !in.is_open() ) {\r
+ SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );\r
+ exit(-1);\r
+ }\r
+\r
+ // read in each line of the file\r
+\r
+ // in >> skipeol;\r
+ // in >> skipcomment;\r
+\r
+#ifdef __MWERKS__\r
+\r
+ char c = 0;\r
+ while ( in.get(c) && c != '\0' ) {\r
+ in.putback(c);\r
+ in >> a;\r
+ if ( a.get_type() != '[' ) {\r
+ transmissionlist_code[a.get_station()].push_back(a);\r
+ }\r
+ in >> skipcomment;\r
+ }\r
+\r
+#else\r
+\r
+ double min = 100000;\r
+ double max = 0;\r
+\r
+ while ( ! in.eof() ) {\r
+ in >> a;\r
+ transmissionlist_station[a.get_station()].push_back(a);\r
+ \r
+ in >> skipcomment;\r
+\r
+ if ( a.get_station() < min ) {\r
+ min = a.get_station();\r
+ }\r
+ if ( a.get_station() > max ) {\r
+ max = a.get_station();\r
+ }\r
+ cout << a.get_station() << " " << a.get_code().c1 << " " << a.get_code().c2 << " "\r
+ << a.get_code().c3 << " " << a.get_transtext() \r
+ << " " << a.get_menutext() << endl;\r
+ }\r
+ \r
+#endif\r
+\r
+ // init ATC menu\r
+ fgSetBool("/sim/atc/menu",false);\r
+\r
+ return true;\r
+}\r
+\r
+// query the database for the specified station type; \r
+// for station see FlightGear/ATC/default.transmissions\r
+bool FGTransmissionList::query_station( const int &station, FGTransmission *t,\r
+ int max_trans, int &num_trans ) \r
+{\r
+ transmission_list_type tmissions = transmissionlist_station[station];\r
+ transmission_list_iterator current = tmissions.begin();\r
+ transmission_list_iterator last = tmissions.end();\r
+\r
+ for ( ; current != last ; ++current ) {\r
+ if (num_trans < max_trans) {\r
+ t[num_trans] = *current;\r
+ num_trans += 1;\r
+ }\r
+ else {\r
+ cout << "Transmissionlist error: Too many transmissions" << endl; \r
+ }\r
+ }\r
+\r
+ if ( num_trans != 0 ) return true;\r
+ else {\r
+ cout << "No transmission with station " << station << "found." << endl;\r
+ string empty;\r
+ return false;\r
+ }\r
+}\r
+\r
+string FGTransmissionList::gen_text(const int &station, const TransCode code, \r
+ const TransPar &tpars, const bool ttext )\r
+{\r
+ const int cmax = 100;\r
+ string message;\r
+ char tag[4];\r
+ char crej = '@';\r
+ char mes[cmax];\r
+ char dum[cmax];\r
+ char buf[10];\r
+ char *pos;\r
+ int len;\r
+ FGTransmission t;\r
+\r
+ // if (current_transmissionlist->query_station( station, &t ) ) { \r
+ transmission_list_type tmissions = transmissionlist_station[station];\r
+ transmission_list_iterator current = tmissions.begin();\r
+ transmission_list_iterator last = tmissions.end();\r
+ \r
+ for ( ; current != last ; ++current ) {\r
+ if ( current->get_code().c1 == code.c1 && \r
+ current->get_code().c2 == code.c2 &&\r
+ current->get_code().c3 == code.c3 ) {\r
+ \r
+ if ( ttext ) message = current->get_transtext();\r
+ else message = current->get_menutext();\r
+ strcpy( &mes[0], message.c_str() ); \r
+ \r
+ while ( strchr(&mes[0], crej) != NULL ) {\r
+ pos = strchr( &mes[0], crej );\r
+ bcopy(pos, &tag, 3);\r
+ tag[3] = '\0';\r
+ int i;\r
+ len = 0;\r
+ for ( i=0; i<cmax; i++ ) {\r
+ if ( mes[i] == crej ) {\r
+ len = i; \r
+ break;\r
+ }\r
+ }\r
+ strncpy( &dum[0], &mes[0], len );\r
+ dum[len] = '\0';\r
+ \r
+ if ( strcmp ( tag, "@ST" ) == 0 )\r
+ strcat( &dum[0], tpars.station.c_str() );\r
+ else if ( strcmp ( tag, "@AP" ) == 0 )\r
+ strcat( &dum[0], tpars.airport.c_str() );\r
+ else if ( strcmp ( tag, "@CS" ) == 0 ) \r
+ strcat( &dum[0], tpars.callsign.c_str() );\r
+ else if ( strcmp ( tag, "@TD" ) == 0 ) {\r
+ if ( tpars.tdir == 1 ) {\r
+ char buf[] = "left";\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else {\r
+ char buf[] = "right";\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ }\r
+ else if ( strcmp ( tag, "@HE" ) == 0 ) {\r
+ char buf[10];\r
+ sprintf( buf, "%i", (int)(tpars.heading) );\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( strcmp ( tag, "@VD" ) == 0 ) {\r
+ if ( tpars.VDir == 1 ) {\r
+ char buf[] = "Descent and maintain";\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( tpars.VDir == 2 ) {\r
+ char buf[] = "Maintain";\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( tpars.VDir == 3 ) {\r
+ char buf[] = "Climb and maintain";\r
+ strcat( &dum[0], &buf[0] );\r
+ } \r
+ }\r
+ else if ( strcmp ( tag, "@AL" ) == 0 ) {\r
+ char buf[10];\r
+ sprintf( buf, "%i", (int)(tpars.alt) );\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( strcmp ( tag, "@MI" ) == 0 ) {\r
+ char buf[10];\r
+ sprintf( buf, "%3.1f", tpars.miles );\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( strcmp ( tag, "@FR" ) == 0 ) {\r
+ char buf[10];\r
+ sprintf( buf, "%6.2f", tpars.freq );\r
+ strcat( &dum[0], &buf[0] );\r
+ }\r
+ else if ( strcmp ( tag, "@RW" ) == 0 )\r
+ strcat( &dum[0], tpars.runway.c_str() );\r
+ else {\r
+ cout << "Tag " << tag << " not found" << endl;\r
+ break;\r
+ }\r
+ strcat( &dum[0], &mes[len+3] );\r
+ strcpy( &mes[0], &dum[0] );\r
+ }\r
+\r
+ //cout << mes << endl; \r
+ break;\r
+ }\r
+ }\r
+ if ( mes != "" ) return mes;\r
+ else return "No transmission found";\r
+}\r
+\r
+\r
--- /dev/null
+// transmissionlist.hxx -- transmission management class\r
+//\r
+// Written by Alexander Kappes, started March 2002.\r
+// Based on navlist.hxx by Curtis Olson, started April 2000.\r
+//\r
+// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org\r
+//\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License as\r
+// published by the Free Software Foundation; either version 2 of the\r
+// License, or (at your option) any later version.\r
+//\r
+// This program is distributed in the hope that it will be useful, but\r
+// WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+// General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+//\r
+\r
+\r
+#ifndef _FG_TRANSMISSIONLIST_HXX\r
+#define _FG_TRANSMISSIONLIST_HXX\r
+\r
+\r
+#include <simgear/compiler.h>\r
+#include <simgear/misc/sg_path.hxx>\r
+\r
+#include <map>\r
+#include <vector>\r
+\r
+#include <plib/pu.h>\r
+\r
+#include "transmission.hxx"\r
+\r
+SG_USING_STD(map);\r
+SG_USING_STD(vector);\r
+\r
+class FGTransmissionList {\r
+\r
+ // convenience types\r
+ typedef vector < FGTransmission > transmission_list_type;\r
+ typedef transmission_list_type::iterator transmission_list_iterator;\r
+ typedef transmission_list_type::const_iterator transmission_list_const_iterator;\r
+ \r
+ // typedef map < int, transmission_list_type, less<int> > transmission_map_type;\r
+ typedef map < int, transmission_list_type > transmission_map_type;\r
+ typedef transmission_map_type::iterator transmission_map_iterator;\r
+ typedef transmission_map_type::const_iterator transmission_map_const_iterator;\r
+ \r
+ transmission_map_type transmissionlist_station;\r
+ \r
+public:\r
+ \r
+ FGTransmissionList();\r
+ ~FGTransmissionList();\r
+ \r
+ // load the transmission data and build the map\r
+ bool init( SGPath path );\r
+ \r
+ // query the database for the specified code,\r
+ bool query_station( const int &station, FGTransmission *a, int max_trans, int &num_trans );\r
+\r
+ // generate the transmission text given the code of the message \r
+ // and the parameters\r
+ string gen_text(const int &station, const TransCode code,\r
+ const TransPar &tpars, const bool ttext);\r
+\r
+};\r
+\r
+\r
+void mkATCMenuInit (void);\r
+void mkATCMenu (void);\r
+\r
+extern FGTransmissionList *current_transmissionlist;\r
+\r
+\r
+#endif // _FG_TRANSMISSIONLIST_HXX\r