]> git.mxchange.org Git - flightgear.git/blob - src/ATC/ATCDialog.cxx
Improved tumbling behaviour -- the AI doesn't just freeze now, but
[flightgear.git] / src / ATC / ATCDialog.cxx
1 // ATCDialog.cxx - Functions and classes to handle the pop-up ATC dialog
2 //
3 // Written by Alexander Kappes and David Luff, started February 2003.
4 //
5 // Copyright (C) 2003  Alexander Kappes and David Luff
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #include <Main/globals.hxx>
22 #include <Main/fgfs.hxx>
23 #include <GUI/gui.h>
24 #include <simgear/misc/commands.hxx>
25
26 #include "ATCDialog.hxx"
27 #include "ATC.hxx"
28 #include "ATCmgr.hxx"
29
30 FGATCDialog *current_atcdialog;
31
32 // For the command manager - maybe eventually this should go in the built in command list
33 static bool do_ATC_dialog(const SGPropertyNode* arg) {
34         globals->get_ATC_mgr()->doPopupDialog();
35         return(true);
36 }
37
38 ATCMenuEntry::ATCMenuEntry() {
39   stationid    = "";
40   stationfr    = 0;
41   transmission = "";
42   menuentry    = "";
43 }
44
45 ATCMenuEntry::~ATCMenuEntry() {
46 }
47
48 static char* t0 = "Request landing clearance";
49 static char* t1 = "Request departure clearance";
50 static char* t2 = "Report Runway vacated";
51 static char** towerOptions = new char*[4];
52
53 // ----------------------- DCL ------------------------------------------
54 // For the ATC dialog - copied from the Autopilot new heading dialog code!
55 static puDialogBox*             atcDialog;
56 static puFrame*                 atcDialogFrame;
57 static puText*                  atcDialogMessage;
58 //static puInput*                       atcDialogInput;
59 static puOneShot*               atcDialogOkButton;
60 static puOneShot*               atcDialogCancelButton;
61 static puButtonBox*             atcDialogCommunicationOptions;
62 // ----------------------------------------------------------------------
63
64 // ------------------------ AK ------------------------------------------
65 static puDialogBox  *ATCMenuBox = 0;
66 static puFrame      *ATCMenuFrame = 0;
67 static puText       *ATCMenuBoxMessage = 0;
68 static puButtonBox      *ATCOptionsList = 0;
69 // ----------------------------------------------------------------------
70
71 // AK
72 static void AKATCDialogOK(puObject *)
73 {
74         switch(ATCOptionsList->getValue()) {
75         case 0:
76                 //cout << "Option 0 chosen\n";
77                 fgSetBool("/sim/atc/opt0",true);
78                 break;
79         case 1:
80                 //cout << "Option 1 chosen\n";
81                 fgSetBool("/sim/atc/opt1",true);
82                 break;
83         case 2:
84                 //cout << "Option 2 chosen\n";
85                 fgSetBool("/sim/atc/opt2",true);
86                 break;
87         case 3:
88                 //cout << "Option 2 chosen\n";
89                 fgSetBool("/sim/atc/opt3",true);
90                 break;
91         default:
92                 break;
93         }
94         FG_POP_PUI_DIALOG( ATCMenuBox );
95 }
96
97 // AK
98 static void AKATCDialogCancel(puObject *)
99 {
100     FG_POP_PUI_DIALOG( ATCMenuBox );
101 }
102
103 // DCL
104 static void ATCDialogCancel(puObject *)
105 {
106     //ATCDialogInput->rejectInput();
107     FG_POP_PUI_DIALOG( atcDialog );
108 }
109
110 // DCL
111 static void ATCDialogOK (puObject *me)
112 {
113         // Note that currently the dialog is hardwired to comm1 only here.
114         switch(globals->get_ATC_mgr()->GetComm1ATCType()) {
115         case INVALID:
116                 break;
117         case ATIS:
118                 break;
119         case TOWER: {
120                 FGTower* twr = (FGTower*)globals->get_ATC_mgr()->GetComm1ATCPointer();
121                 switch(atcDialogCommunicationOptions->getValue()) {
122                 case 0:
123                         //cout << "Option 0 chosen\n";
124                         twr->RequestLandingClearance("golf bravo echo");
125                         break;
126                 case 1:
127                         //cout << "Option 1 chosen\n";
128                         twr->RequestDepartureClearance("golf bravo echo");
129                         break;
130                 case 2:
131                         //cout << "Option 2 chosen\n";
132                         twr->ReportRunwayVacated("golf bravo echo");
133                         break;
134                 default:
135                         break;
136                 }
137                 break;
138         }
139         case GROUND:
140                 break;
141         case APPROACH:
142                 break;
143         default:
144                 break;
145         }
146
147     ATCDialogCancel(me);
148     //if(error) mkDialog(s.c_str());
149 }
150
151 // DCL
152 static void ATCDialog(puObject *cb)
153 {
154     //ApHeadingDialogInput   ->    setValue ( heading );
155     //ApHeadingDialogInput    -> acceptInput();
156     FG_PUSH_PUI_DIALOG(atcDialog);
157 }
158
159 // DCL
160 void ATCDialogInit()
161 {
162         char defaultATCLabel[] = "Enter desired option to communicate with ATC:";
163         char *s;
164
165         // Option lists hardwired per ATC type  
166         towerOptions[0] = new char[strlen(t0)+1];
167         strcpy(towerOptions[0], t0);
168         towerOptions[1] = new char[strlen(t1)+1];
169         strcpy(towerOptions[1], t1);
170         towerOptions[2] = new char[strlen(t2)+1];
171         strcpy(towerOptions[2], t2);
172         towerOptions[3] = NULL;
173         
174         atcDialog = new puDialogBox (150, 50);
175         {
176                 atcDialogFrame   = new puFrame (0, 0, 500, 250);
177                 
178                 atcDialogMessage = new puText          (250, 220);
179                 atcDialogMessage    -> setDefaultValue (defaultATCLabel);
180                 atcDialogMessage    -> getDefaultValue (&s);
181                 atcDialogMessage    -> setLabel        (s);
182                 atcDialogMessage    -> setLabelPlace   (PUPLACE_TOP_CENTERED);
183
184                 atcDialogCommunicationOptions = new puButtonBox (50, 50, 450, 210, NULL, true);
185                 
186                 atcDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
187                 atcDialogOkButton     ->     setLegend         (gui_msg_OK);
188                 atcDialogOkButton     ->     makeReturnDefault (TRUE);
189                 atcDialogOkButton     ->     setCallback       (ATCDialogOK);
190                 
191                 atcDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
192                 atcDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
193                 atcDialogCancelButton ->     setCallback       (ATCDialogCancel);
194                 
195         }
196         FG_FINALIZE_PUI_DIALOG(atcDialog);
197         
198         // Add ATC-dialog to the command list
199         globals->get_commands()->addCommand("ATC-dialog", do_ATC_dialog);
200 }
201
202 ///////////////////////////////////////////////////////////////////////
203 //
204 // ATCDoDialog is in a state of flux at the moment
205 // Stations other than approach are handled by DCL's simple code
206 // Approach is handled by AK's fancy dynamic-list code
207 // Hopefully all interactive stations should go to AK's code eventually
208 //
209 ///////////////////////////////////////////////////////////////////////
210 void ATCDoDialog(atc_type type) {
211         switch(type) {
212         case INVALID:
213                 atcDialogCommunicationOptions->newList(NULL);
214                 atcDialogMessage->setLabel("Not tuned in to any ATC service.");
215                 break;
216         case ATIS:
217                 atcDialogCommunicationOptions->newList(NULL);
218                 atcDialogMessage->setLabel("Tuned in to ATIS: no communication possible.");
219                 break;
220         case TOWER: 
221                 atcDialogCommunicationOptions->newList(towerOptions);
222                 atcDialogMessage->setLabel("Tuned in to Tower - select communication to transmit:");
223                 break;
224         case GROUND:
225                 atcDialogCommunicationOptions->newList(NULL);
226                 atcDialogMessage->setLabel("Tuned in to Ground - select communication to transmit:");
227                 break;
228         case APPROACH:
229                 current_atcdialog->DoDialog();
230                 break;
231         default:
232                 atcDialogCommunicationOptions->newList(NULL);
233                 atcDialogMessage->setLabel("Tuned in to unknown ATC service - enter transmission:");
234                 break;
235         }
236
237         // Third - display the dialog without pausing sim.
238         if(type != APPROACH) {  
239                 ATCDialog(NULL);
240         }
241 }
242
243 void FGATCDialog::Init() {
244 }
245
246 // AK
247 // Add an entry
248 void FGATCDialog::add_entry(string station, string transmission, string menutext ) {
249   
250   ATCMenuEntry a;
251
252   a.stationid = station;
253   a.transmission = transmission;
254   a.menuentry = menutext;
255
256   atcmentrylist_station[station.c_str()].push_back(a);
257
258 }
259
260 // AK
261 // query the database whether the transmission is already registered; 
262 bool FGATCDialog::trans_reg( const string &station, const string &trans ) {
263
264   atcmentry_list_type     atcmlist = atcmentrylist_station[station];
265   atcmentry_list_iterator current  = atcmlist.begin();
266   atcmentry_list_iterator last     = atcmlist.end();
267   
268   for ( ; current != last ; ++current ) {
269     if ( current->transmission == trans ) return true;
270   }
271   return false;
272 }
273
274 // AK
275 // ===================================================
276 // ===  Update ATC menue and look for keys pressed ===
277 // ===================================================
278 void FGATCDialog::DoDialog() {
279         
280         static string mentry[10];
281         static string mtrans[10];
282         char   buf[10];
283         TransPar TPar;
284         FGATC* atcptr = globals->get_ATC_mgr()->GetComm1ATCPointer();   // Hardwired to comm1 at the moment
285         
286         if(atcptr != NULL) {
287                 
288                 atcmentry_list_type     atcmlist = atcmentrylist_station[atcptr->get_ident()];
289                 //atcmentry_list_type     atcmlist = atcmentrylist_station["EGNX"];
290                 atcmentry_list_iterator current  = atcmlist.begin();
291                 atcmentry_list_iterator last     = atcmlist.end();
292                 
293                 // Set all opt flags to false before displaying box
294                 fgSetBool("/sim/atc/opt0",false);
295                 fgSetBool("/sim/atc/opt1",false);
296                 fgSetBool("/sim/atc/opt2",false);
297                 fgSetBool("/sim/atc/opt3",false);
298                 fgSetBool("/sim/atc/opt4",false);
299                 fgSetBool("/sim/atc/opt5",false);
300                 fgSetBool("/sim/atc/opt6",false);
301                 fgSetBool("/sim/atc/opt7",false);
302                 fgSetBool("/sim/atc/opt8",false);
303                 fgSetBool("/sim/atc/opt9",false);
304                 
305                 //int yc = 10;
306                 int yc = 70;
307                 int xsize = 600;
308                 
309                 if ( atcmlist.size() != 0 ){ 
310                         int k=atcmlist.size();
311                         //int k = 3;
312                         //cout << "k = " << k << endl;
313                         int y = (fgGetInt("/sim/startup/ysize") - 200 - 20 - k*20);
314                         ATCMenuBox = new puDialogBox (100, y);
315                         ATCMenuFrame      =  new puFrame (0,0,xsize,yc+40);
316                         // loop over all entries in atcmentrylist
317                         ATCOptionsList = new puButtonBox (50, 50, 450, 50+(k*25), NULL, true);
318                         char** optList = new char*[k+1];
319                         int kk = 0;
320                         for ( ; current != last ; ++current ) {
321                                 string dum;
322                                 sprintf( buf, "%i", kk+1 );
323                                 buf[1] = '\0';
324                                 dum = (string)(buf);
325                                 mentry[kk] = dum + ". " + current->menuentry;
326                                 optList[kk] = new char[strlen(mentry[kk].c_str()) + 1];
327                                 strcpy(optList[kk], mentry[kk].c_str());
328                                 //cout << "optList[" << kk << "] = " << optList[kk] << endl; 
329                                 mtrans[kk] =              current->transmission;
330                                 //ATCMenuBoxMessage =  new puText (10, yc);
331                                 //ATCMenuBoxMessage ->     setLabel( mentry[kk].c_str() );
332                                 yc += 20;
333                                 ++kk;
334                         } 
335                         yc += 2*20;
336                         optList[k] = NULL;
337                         ATCOptionsList->newList(optList);
338                 } else {
339                         int y = (fgGetInt("/sim/startup/ysize") - 100 - 20 );
340                         ATCMenuBox = new puDialogBox (10, y);
341                         ATCMenuFrame      =  new puFrame (0,0,xsize,yc+40);
342                         ATCMenuBoxMessage =  new puText (10, yc-10);
343                         ATCMenuBoxMessage ->     setLabel( "No transmission available" );
344                 }
345                 
346                 ATCMenuBoxMessage =  new puText (10, yc+10);
347                 ATCMenuBoxMessage ->     setLabel( "ATC Menu" );
348                 atcDialogOkButton     =  new puOneShot         ((xsize/2)-85, 10, (xsize/2)-25, 50);
349                 atcDialogOkButton     ->     setLegend         (gui_msg_OK);
350                 atcDialogOkButton     ->     makeReturnDefault (TRUE);
351                 atcDialogOkButton     ->     setCallback       (AKATCDialogOK);
352                 
353                 atcDialogCancelButton =  new puOneShot         ((xsize/2)+25, 10, (xsize/2)+85, 50);
354                 atcDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
355                 atcDialogCancelButton ->     setCallback       (AKATCDialogCancel);
356                 FG_FINALIZE_PUI_DIALOG( ATCMenuBox );
357                 FG_PUSH_PUI_DIALOG( ATCMenuBox );
358                 
359                 
360                 /*      
361                 if ( atckey != -1 && TransDisplayed && mtrans[atckey-1].c_str() != "" ) {
362                         cout << mtrans[atckey-1].c_str() << endl;
363                         TPar = current_transmissionlist->extract_transpar( mtrans[atckey-1].c_str() );
364                         current_atcmentrylist->reset = true;
365                         current_transparlist->add_entry( TPar );
366                         
367                         //    transpar_list_type test = current_transparlist;
368                         // transpar_list_iterator current = test.begin();
369                         //for ( ; current != test.end(); ++current ) {
370                                 // current->tpar.intention;
371                         //}
372                 }
373                 
374                 if ( current_atcmentrylist->freq != (int)(comm1_freq*100.0 + 0.5) ) {
375                         current_atcmentrylist->reset = true;
376                 }
377                 
378                 // reset (delete) ATCmenue list if reset is true
379                 if ( current_atcmentrylist->reset == true ) {
380                         delete ( current_atcmentrylist );
381                         current_atcmentrylist = new FGatcmentryList;
382                         current_atcmentrylist->init( (int)(comm1_freq*100.0 + 0.5) );
383                         if ( TransDisplayed ) {
384                                 FG_POP_PUI_DIALOG( ATCMenuBox ); 
385                                 TransDisplayed = false;
386                         }
387                 }
388                 */      
389         }
390 }
391