From 5dbf38c2739b66edc7ad93050d2229536d8f517f Mon Sep 17 00:00:00 2001 From: daveluff Date: Thu, 13 Feb 2003 12:05:19 +0000 Subject: [PATCH] First draft of work by Alexander Kappes to add dynamically driven menu entries to the pop-up ATC dialog, parsing of text input to the ATC system and parameterised transmissions where the speech of a transmission is derived from the intent based on data files potentially allowing users to specify different phrases for each voice instead of being hard-coded. This is a work in progress. --- src/ATC/ATCDialog.cxx | 389 +++++++++++++++++++++++++++++++++++ src/ATC/ATCDialog.hxx | 77 +++++++ src/ATC/transmission.cxx | 96 +++++++++ src/ATC/transmission.hxx | 159 ++++++++++++++ src/ATC/transmissionlist.cxx | 288 ++++++++++++++++++++++++++ src/ATC/transmissionlist.hxx | 80 +++++++ 6 files changed, 1089 insertions(+) create mode 100644 src/ATC/ATCDialog.cxx create mode 100644 src/ATC/ATCDialog.hxx create mode 100644 src/ATC/transmission.cxx create mode 100644 src/ATC/transmission.hxx create mode 100644 src/ATC/transmissionlist.cxx create mode 100644 src/ATC/transmissionlist.hxx diff --git a/src/ATC/ATCDialog.cxx b/src/ATC/ATCDialog.cxx new file mode 100644 index 000000000..c66970f2c --- /dev/null +++ b/src/ATC/ATCDialog.cxx @@ -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
+#include
+#include +#include + +#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 index 000000000..3e8ac1818 --- /dev/null +++ b/src/ATC/ATCDialog.hxx @@ -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 + +#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 > 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 index 000000000..dbec738d1 --- /dev/null +++ b/src/ATC/transmission.cxx @@ -0,0 +1,96 @@ +// FGTransmission - a class to provide transmission control at larger airports. +// +// Written by Alexander Kappes, started March 2002. +// Based on ground.cxx by David Luff, started March 2002. +// +// Copyright (C) 2002 David C. Luff - david.luff@nottingham.ac.uk +// +// 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 "transmission.hxx" + +#include + + +//Constructor +FGTransmission::FGTransmission(){ +} + +//Destructor +FGTransmission::~FGTransmission(){ +} + +void FGTransmission::Init() { +} + +// ============================================================================ +// extract parameters from transmission +// ============================================================================ +TransPar FGTransmission::Parse() { + TransPar tpar; + string tokens[20]; + int msglen,toklen; + char dum; + int i,j,k; + const char *capl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + msglen = strlen( TransText.c_str() ); + + int tkn = 0; + for ( i=0; i < msglen; ++i ) { + if ( TransText.c_str()[i] != ' ' ) { + if ( TransText.c_str()[i] != ',' ) tokens[tkn] += TransText.c_str()[i]; + } else if ( tokens[tkn] != "" ) { + if ( tkn <= 20 ) { + tkn += 1; + } else { + cout << "Too many tokens" << endl; + } + } + } + + for ( i=0; i<20; ++i) { + + if ( tokens[i] == "request" ) { + tpar.request = true; + } else if ( tokens[i] == "approach" ) { + tpar.station = "approach"; + tpar.airport = tokens[i-1]; + } else if ( tokens[i] == "landing" ) { + tpar.intention = "landing"; + for ( j=i+1; j<=i+2; ++j ) { + if ( tokens[j] != "" ) { + toklen = strlen( tokens[j].c_str() ); + bool aid = true; + for ( k=0; k + +#include +#include +#include +#include +#include +#include + +#include
+ +#ifdef SG_HAVE_STD_INCLUDES +# include +#include +#elif defined( SG_HAVE_NATIVE_SGI_COMPILERS ) +# include +#elif defined( __BORLANDC__ ) +# include +#else +# include +#include +#endif + +#if ! defined( SG_HAVE_NATIVE_SGI_COMPILERS ) +SG_USING_STD(istream); +#endif + +SG_USING_STD(string); + +struct TransCode { + int c1; + int c2; + int c3; +}; + +// TransPar - a representation of the logic of a parsed speech transmission +struct TransPar { + string station; + string callsign; + string airport; + string intention; // landing, crossing + string intid; // (airport) ID for intention + bool request; // is the transmission a request or an answer? + int tdir; // turning direction: 1=left, 2=right + double heading; + int VDir; // vertical direction: 1=descent, 2=maintain, 3=climb + double alt; + double miles; + string runway; + double freq; + double time; +}; + +// FGTransmission - a class to encapsulate a speech transmission +class FGTransmission { + + int StationType; // Type of ATC station: 1 Approach + TransCode Code; + string TransText; + string MenuText; + +public: + + FGTransmission(void); + ~FGTransmission(void); + + void Init(); + + inline int get_station() const { return StationType; } + inline TransCode get_code() { return Code; } + inline string get_transtext() { return TransText; } + inline string get_menutext() { return MenuText; } + + // Return the parsed logic of the transmission + TransPar Parse(); + +private: + + friend istream& operator>> ( istream&, FGTransmission& ); + +}; + + +inline istream& +operator >> ( istream& in, FGTransmission& a ) { + char ch; + + static bool first_time = true; + static double julian_date = 0; + static const double MJD0 = 2415020.0; + if ( first_time ) { + julian_date = sgTimeCurrentMJD(0, 0) + MJD0; + first_time = false; + } + in >> a.StationType; + in >> a.Code.c1; + in >> a.Code.c2; + in >> a.Code.c3; + a.TransText = ""; + in >> ch; + if ( ch != '"' ) a.TransText += ch; + while(1) { + //in >> noskipws + in.unsetf(ios::skipws); + in >> ch; + if ( ch != '"' ) a.TransText += ch; + if((ch == '"') || (ch == 0x0A)) { + break; + } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the " + } + in.setf(ios::skipws); + + a.MenuText = ""; + in >> ch; + if ( ch != '"' ) a.MenuText += ch; + while(1) { + //in >> noskipws + in.unsetf(ios::skipws); + in >> ch; + if ( ch != '"' ) a.MenuText += ch; + if((ch == '"') || (ch == 0x0A)) { + break; + } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the " + } + in.setf(ios::skipws); + + //cout << "Code = " << a.Code << " Transmission text = " << a.TransText + // << " Menu text = " << a.MenuText << endl; + + return in >> skipeol; +} + + +#endif // _FG_TRANSMISSION_HXX diff --git a/src/ATC/transmissionlist.cxx b/src/ATC/transmissionlist.cxx new file mode 100644 index 000000000..8d354cc71 --- /dev/null +++ b/src/ATC/transmissionlist.cxx @@ -0,0 +1,288 @@ +// transmissionlist.cxx -- transmission management class +// +// Written by Alexander Kappes, started March 2002. +// Based on navlist.cxx by Curtis Olson, started April 2000. +// +// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "transmissionlist.hxx" + +#include + +static puDialogBox *ATCMenuBox = 0; +static puFrame *ATCMenuFrame = 0; +static puText *ATCMenuBoxMessage = 0; + +FGTransmissionList *current_transmissionlist; + + +// Constructor +FGTransmissionList::FGTransmissionList( void ) { +} + + +// Destructor +FGTransmissionList::~FGTransmissionList( void ) { +} + +/* +// ============================================================================ +// init menu window +// ============================================================================ +void mkATCMenuInit (void) +{ + int dx = 400; + int dy = 100; + int y = (fgGetInt("/sim/startup/ysize") - 10 - dy); + ATCMenuBox = new puDialogBox (10, y); + { + ATCMenuFrame = new puFrame (0,0,400,100); + ATCMenuBoxMessage = new puText (10, 70); + ATCMenuBoxMessage -> setLabel (""); + } + fgSetBool("/sim/atc/menu",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); + fgSetBool("/sim/atc/opt0",false); +} + +// ATC Menu Message Box +void mkATCMenu ( const char *txt ) +{ + ATCMenuBoxMessage = new puText (10, 70); + ATCMenuBoxMessage->setLabel( txt ); + + FG_PUSH_PUI_DIALOG( ATCMenuBox ); +} +*/ + +// load default.transmissions +bool FGTransmissionList::init( SGPath path ) { + FGTransmission a; + + transmissionlist_station.erase( transmissionlist_station.begin(), transmissionlist_station.end() ); + + sg_gzifstream in( path.str() ); + if ( !in.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() ); + exit(-1); + } + + // read in each line of the file + + // in >> skipeol; + // in >> skipcomment; + +#ifdef __MWERKS__ + + char c = 0; + while ( in.get(c) && c != '\0' ) { + in.putback(c); + in >> a; + if ( a.get_type() != '[' ) { + transmissionlist_code[a.get_station()].push_back(a); + } + in >> skipcomment; + } + +#else + + double min = 100000; + double max = 0; + + while ( ! in.eof() ) { + in >> a; + transmissionlist_station[a.get_station()].push_back(a); + + in >> skipcomment; + + if ( a.get_station() < min ) { + min = a.get_station(); + } + if ( a.get_station() > max ) { + max = a.get_station(); + } + cout << a.get_station() << " " << a.get_code().c1 << " " << a.get_code().c2 << " " + << a.get_code().c3 << " " << a.get_transtext() + << " " << a.get_menutext() << endl; + } + +#endif + + // init ATC menu + fgSetBool("/sim/atc/menu",false); + + return true; +} + +// query the database for the specified station type; +// for station see FlightGear/ATC/default.transmissions +bool FGTransmissionList::query_station( const int &station, FGTransmission *t, + int max_trans, int &num_trans ) +{ + transmission_list_type tmissions = transmissionlist_station[station]; + transmission_list_iterator current = tmissions.begin(); + transmission_list_iterator last = tmissions.end(); + + for ( ; current != last ; ++current ) { + if (num_trans < max_trans) { + t[num_trans] = *current; + num_trans += 1; + } + else { + cout << "Transmissionlist error: Too many transmissions" << endl; + } + } + + if ( num_trans != 0 ) return true; + else { + cout << "No transmission with station " << station << "found." << endl; + string empty; + return false; + } +} + +string FGTransmissionList::gen_text(const int &station, const TransCode code, + const TransPar &tpars, const bool ttext ) +{ + const int cmax = 100; + string message; + char tag[4]; + char crej = '@'; + char mes[cmax]; + char dum[cmax]; + char buf[10]; + char *pos; + int len; + FGTransmission t; + + // if (current_transmissionlist->query_station( station, &t ) ) { + transmission_list_type tmissions = transmissionlist_station[station]; + transmission_list_iterator current = tmissions.begin(); + transmission_list_iterator last = tmissions.end(); + + for ( ; current != last ; ++current ) { + if ( current->get_code().c1 == code.c1 && + current->get_code().c2 == code.c2 && + current->get_code().c3 == code.c3 ) { + + if ( ttext ) message = current->get_transtext(); + else message = current->get_menutext(); + strcpy( &mes[0], message.c_str() ); + + while ( strchr(&mes[0], crej) != NULL ) { + pos = strchr( &mes[0], crej ); + bcopy(pos, &tag, 3); + tag[3] = '\0'; + int i; + len = 0; + for ( i=0; i +#include + +#include +#include + +#include + +#include "transmission.hxx" + +SG_USING_STD(map); +SG_USING_STD(vector); + +class FGTransmissionList { + + // convenience types + typedef vector < FGTransmission > transmission_list_type; + typedef transmission_list_type::iterator transmission_list_iterator; + typedef transmission_list_type::const_iterator transmission_list_const_iterator; + + // typedef map < int, transmission_list_type, less > transmission_map_type; + typedef map < int, transmission_list_type > transmission_map_type; + typedef transmission_map_type::iterator transmission_map_iterator; + typedef transmission_map_type::const_iterator transmission_map_const_iterator; + + transmission_map_type transmissionlist_station; + +public: + + FGTransmissionList(); + ~FGTransmissionList(); + + // load the transmission data and build the map + bool init( SGPath path ); + + // query the database for the specified code, + bool query_station( const int &station, FGTransmission *a, int max_trans, int &num_trans ); + + // generate the transmission text given the code of the message + // and the parameters + string gen_text(const int &station, const TransCode code, + const TransPar &tpars, const bool ttext); + +}; + + +void mkATCMenuInit (void); +void mkATCMenu (void); + +extern FGTransmissionList *current_transmissionlist; + + +#endif // _FG_TRANSMISSIONLIST_HXX