]> git.mxchange.org Git - flightgear.git/commitdiff
First draft of work by Alexander Kappes to add dynamically driven menu entries to...
authordaveluff <daveluff>
Thu, 13 Feb 2003 12:05:19 +0000 (12:05 +0000)
committerdaveluff <daveluff>
Thu, 13 Feb 2003 12:05:19 +0000 (12:05 +0000)
src/ATC/ATCDialog.cxx [new file with mode: 0644]
src/ATC/ATCDialog.hxx [new file with mode: 0644]
src/ATC/transmission.cxx [new file with mode: 0644]
src/ATC/transmission.hxx [new file with mode: 0644]
src/ATC/transmissionlist.cxx [new file with mode: 0644]
src/ATC/transmissionlist.hxx [new file with mode: 0644]

diff --git a/src/ATC/ATCDialog.cxx b/src/ATC/ATCDialog.cxx
new file mode 100644 (file)
index 0000000..c66970f
--- /dev/null
@@ -0,0 +1,389 @@
+// 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;
+                       }
+               }
+               */      
+       }
+}
+
diff --git a/src/ATC/ATCDialog.hxx b/src/ATC/ATCDialog.hxx
new file mode 100644 (file)
index 0000000..3e8ac18
--- /dev/null
@@ -0,0 +1,77 @@
+// 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
+
diff --git a/src/ATC/transmission.cxx b/src/ATC/transmission.cxx
new file mode 100644 (file)
index 0000000..dbec738
--- /dev/null
@@ -0,0 +1,96 @@
+// 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
diff --git a/src/ATC/transmission.hxx b/src/ATC/transmission.hxx
new file mode 100644 (file)
index 0000000..2b46bec
--- /dev/null
@@ -0,0 +1,159 @@
+// 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
diff --git a/src/ATC/transmissionlist.cxx b/src/ATC/transmissionlist.cxx
new file mode 100644 (file)
index 0000000..8d354cc
--- /dev/null
@@ -0,0 +1,288 @@
+// 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
diff --git a/src/ATC/transmissionlist.hxx b/src/ATC/transmissionlist.hxx
new file mode 100644 (file)
index 0000000..9c75723
--- /dev/null
@@ -0,0 +1,80 @@
+// 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