]> git.mxchange.org Git - flightgear.git/blob - src/Controls/controls.cxx
Latest MultiPlayer updates
[flightgear.git] / src / Controls / controls.cxx
1 // controls.cxx -- defines a standard interface to all flight sim controls
2 //
3 // Written by Curtis Olson, started May 1997.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
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 // $Id$
22
23
24 #include "controls.hxx"
25
26 #include <simgear/debug/logstream.hxx>
27 #include <Main/fg_props.hxx>
28
29
30 \f
31 ////////////////////////////////////////////////////////////////////////
32 // Inline utility methods.
33 ////////////////////////////////////////////////////////////////////////
34
35 static inline void
36 CLAMP(double *x, double min, double max )
37 {
38   if ( *x < min ) { *x = min; }
39   if ( *x > max ) { *x = max; }
40 }
41
42 static inline void
43 CLAMP(int *i, int min, int max )
44 {
45   if ( *i < min ) { *i = min; }
46   if ( *i > max ) { *i = max; }
47 }
48
49 \f
50 ////////////////////////////////////////////////////////////////////////
51 // Implementation of FGControls.
52 ////////////////////////////////////////////////////////////////////////
53
54 // Constructor
55 FGControls::FGControls() :
56     aileron( 0.0 ),
57     aileron_trim( 0.0 ),
58     elevator( 0.0 ),
59     elevator_trim( 0.0 ),
60     rudder( 0.0 ),
61     rudder_trim( 0.0 ),
62     flaps( 0.0 ),
63     parking_brake( 0.0 ),
64     speed_brake( 0.0 ),
65     spoilers( 0.0 ),
66     throttle_idle( true ),
67     gear_down( false )
68 {
69 }
70
71
72 void FGControls::reset_all()
73 {
74     set_aileron( 0.0 );
75     set_aileron_trim( 0.0 );
76     set_elevator( 0.0 );
77     set_elevator_trim( 0.0 );
78     set_rudder( 0.0 );
79     set_rudder_trim( 0.0 );
80     set_throttle( ALL_ENGINES, 0.0 );
81     set_starter( ALL_ENGINES, false );
82     set_magnetos( ALL_ENGINES, 0 );
83     set_fuel_pump( ALL_ENGINES, false );
84     throttle_idle = true;
85     set_fuel_selector( ALL_TANKS, true );
86     gear_down = true;
87 }
88
89
90 // Destructor
91 FGControls::~FGControls() {
92 }
93
94
95 void
96 FGControls::init ()
97 {
98     for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
99         throttle[engine] = 0.0;
100         mixture[engine] = 1.0;
101         fuel_pump[engine] = false;
102         prop_advance[engine] = 1.0;
103         magnetos[engine] = 0;
104         starter[engine] = false;
105     }
106
107     for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
108         brake[wheel] = 0.0;
109     }
110
111     auto_coordination = fgGetNode("/sim/auto-coordination", true);
112 }
113
114
115 void
116 FGControls::bind ()
117 {
118   fgTie("/controls/aileron", this,
119         &FGControls::get_aileron, &FGControls::set_aileron);
120   fgSetArchivable("/controls/aileron");
121   fgTie("/controls/aileron-trim", this,
122        &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
123   fgSetArchivable("/controls/aileron-trim");
124   fgTie("/controls/elevator", this,
125        &FGControls::get_elevator, &FGControls::set_elevator);
126   fgSetArchivable("/controls/elevator");
127   fgTie("/controls/elevator-trim", this,
128        &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
129   fgSetArchivable("/controls/elevator-trim");
130   fgTie("/controls/rudder", this,
131        &FGControls::get_rudder, &FGControls::set_rudder);
132   fgSetArchivable("/controls/rudder");
133   fgTie("/controls/rudder-trim", this,
134        &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
135   fgSetArchivable("/controls/rudder-trim");
136   fgTie("/controls/flaps", this,
137        &FGControls::get_flaps, &FGControls::set_flaps);
138   fgSetArchivable("/controls/flaps");
139   int index;
140   for (index = 0; index < MAX_ENGINES; index++) {
141     char name[32];
142     sprintf(name, "/controls/throttle[%d]", index);
143     fgTie(name, this, index,
144           &FGControls::get_throttle, &FGControls::set_throttle);
145     fgSetArchivable(name);
146     sprintf(name, "/controls/mixture[%d]", index);
147     fgTie(name, this, index,
148          &FGControls::get_mixture, &FGControls::set_mixture);
149     fgSetArchivable(name);
150     sprintf(name, "/controls/fuel-pump[%d]", index);
151     fgTie(name, this, index,
152          &FGControls::get_fuel_pump, &FGControls::set_fuel_pump);
153     fgSetArchivable(name);
154     sprintf(name, "/controls/propeller-pitch[%d]", index);
155     fgTie(name, this, index,
156          &FGControls::get_prop_advance, &FGControls::set_prop_advance);
157     fgSetArchivable(name);
158     sprintf(name, "/controls/magnetos[%d]", index);
159     fgTie(name, this, index,
160          &FGControls::get_magnetos, &FGControls::set_magnetos);
161     fgSetArchivable(name);
162     sprintf(name, "/controls/starter[%d]", index);
163     fgTie(name, this, index,
164          &FGControls::get_starter, &FGControls::set_starter);
165     fgSetArchivable(name);
166   }
167   fgTie("/controls/parking-brake", this,
168         &FGControls::get_parking_brake, &FGControls::set_parking_brake);
169   fgSetArchivable("/controls/speed-brake");
170   fgTie("/controls/speed-brake", this,
171         &FGControls::get_speed_brake, &FGControls::set_speed_brake);
172   fgSetArchivable("/controls/speed-brake");
173   fgTie("/controls/spoilers", this,
174         &FGControls::get_spoilers, &FGControls::set_spoilers);
175   fgSetArchivable("/controls/spoilers");
176   for (index = 0; index < MAX_WHEELS; index++) {
177       char name[32];
178       sprintf(name, "/controls/brakes[%d]", index);
179       fgTie(name, this, index,
180             &FGControls::get_brake, &FGControls::set_brake);
181       fgSetArchivable(name);
182   }
183   for (index = 0; index < MAX_TANKS; index++) {
184       char name[32];
185       sprintf(name, "/controls/fuel-selector[%d]", index);
186       fgTie(name, this, index,
187             &FGControls::get_fuel_selector, &FGControls::set_fuel_selector);
188       fgSetArchivable(name);
189   }
190   fgTie("/controls/gear-down", this,
191         &FGControls::get_gear_down, &FGControls::set_gear_down);
192   fgSetArchivable("/controls/gear-down");
193 }
194
195
196 void
197 FGControls::unbind ()
198 {
199                                 // Tie control properties.
200   fgUntie("/controls/aileron");
201   fgUntie("/controls/aileron-trim");
202   fgUntie("/controls/elevator");
203   fgUntie("/controls/elevator-trim");
204   fgUntie("/controls/rudder");
205   fgUntie("/controls/rudder-trim");
206   fgUntie("/controls/flaps");
207   int index;
208   for (index = 0; index < MAX_ENGINES; index++) {
209     char name[32];
210     sprintf(name, "/controls/throttle[%d]", index);
211     fgUntie(name);
212     sprintf(name, "/controls/mixture[%d]", index);
213     fgUntie(name);
214     sprintf(name, "/controls/fuel-pump[%d]", index);
215     fgUntie(name);
216     sprintf(name, "/controls/propeller-pitch[%d]", index);
217     fgUntie(name);
218     sprintf(name, "/controls/magnetos[%d]", index);
219     fgUntie(name);
220     sprintf(name, "/controls/starter[%d]", index);
221     fgUntie(name);
222   }
223   for (index = 0; index < MAX_WHEELS; index++) {
224     char name[32];
225     sprintf(name, "/controls/brakes[%d]", index);
226     fgUntie(name);
227   }
228   fgUntie("/controls/fuel-selector");
229   fgUntie("/controls/gear-down");
230 }
231
232
233 void
234 FGControls::update (double dt)
235 {
236 }
237
238
239 \f
240 ////////////////////////////////////////////////////////////////////////
241 // Setters and adjusters.
242 ////////////////////////////////////////////////////////////////////////
243
244 void
245 FGControls::set_aileron (double pos)
246 {
247   aileron = pos;
248   CLAMP( &aileron, -1.0, 1.0 );
249                         
250   // check for autocoordination
251   if ( auto_coordination->getBoolValue() ) {
252     set_rudder( aileron / 2.0 );
253   }
254 }
255
256 void
257 FGControls::move_aileron (double amt)
258 {
259   aileron += amt;
260   CLAMP( &aileron, -1.0, 1.0 );
261                         
262   // check for autocoordination
263   if ( auto_coordination->getBoolValue() ) {
264     set_rudder( aileron / 2.0 );
265   }
266 }
267
268 void
269 FGControls::set_aileron_trim( double pos )
270 {
271     aileron_trim = pos;
272     CLAMP( &aileron_trim, -1.0, 1.0 );
273 }
274
275 void
276 FGControls::move_aileron_trim( double amt )
277 {
278     aileron_trim += amt;
279     CLAMP( &aileron_trim, -1.0, 1.0 );
280 }
281
282 void
283 FGControls::set_elevator( double pos )
284 {
285     elevator = pos;
286     CLAMP( &elevator, -1.0, 1.0 );
287 }
288
289 void
290 FGControls::move_elevator( double amt )
291 {
292     elevator += amt;
293     CLAMP( &elevator, -1.0, 1.0 );
294 }
295
296 void
297 FGControls::set_elevator_trim( double pos )
298 {
299     elevator_trim = pos;
300     CLAMP( &elevator_trim, -1.0, 1.0 );
301 }
302
303 void
304 FGControls::move_elevator_trim( double amt )
305 {
306     elevator_trim += amt;
307     CLAMP( &elevator_trim, -1.0, 1.0 );
308 }
309
310 void
311 FGControls::set_rudder( double pos )
312 {
313     rudder = pos;
314     CLAMP( &rudder, -1.0, 1.0 );
315 }
316
317 void
318 FGControls::move_rudder( double amt )
319 {
320     rudder += amt;
321     CLAMP( &rudder, -1.0, 1.0 );
322 }
323
324 void
325 FGControls::set_rudder_trim( double pos )
326 {
327     rudder_trim = pos;
328     CLAMP( &rudder_trim, -1.0, 1.0 );
329 }
330
331 void
332 FGControls::move_rudder_trim( double amt )
333 {
334     rudder_trim += amt;
335     CLAMP( &rudder_trim, -1.0, 1.0 );
336 }
337
338 void
339 FGControls::set_flaps( double pos )
340 {
341     flaps = pos;
342     CLAMP( &flaps, 0.0, 1.0 );
343 }
344
345 void
346 FGControls::move_flaps( double amt )
347 {
348     flaps += amt;
349     CLAMP( &flaps, 0.0, 1.0 );
350 }
351
352 void
353 FGControls::set_throttle( int engine, double pos )
354 {
355   if ( engine == ALL_ENGINES ) {
356     for ( int i = 0; i < MAX_ENGINES; i++ ) {
357       throttle[i] = pos;
358       CLAMP( &throttle[i], 0.0, 1.0 );
359     }
360   } else {
361     if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
362       throttle[engine] = pos;
363       CLAMP( &throttle[engine], 0.0, 1.0 );
364     }
365   }
366 }
367
368 void
369 FGControls::move_throttle( int engine, double amt )
370 {
371     if ( engine == ALL_ENGINES ) {
372         for ( int i = 0; i < MAX_ENGINES; i++ ) {
373             throttle[i] += amt;
374             CLAMP( &throttle[i], 0.0, 1.0 );
375         }
376     } else {
377         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
378             throttle[engine] += amt;
379             CLAMP( &throttle[engine], 0.0, 1.0 );
380         }
381     }
382 }
383
384 void
385 FGControls::set_mixture( int engine, double pos )
386 {
387     if ( engine == ALL_ENGINES ) {
388         for ( int i = 0; i < MAX_ENGINES; i++ ) {
389             mixture[i] = pos;
390             CLAMP( &mixture[i], 0.0, 1.0 );
391         }
392     } else {
393         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
394             mixture[engine] = pos;
395             CLAMP( &mixture[engine], 0.0, 1.0 );
396         }
397     }
398 }
399
400 void
401 FGControls::move_mixture( int engine, double amt )
402 {
403     if ( engine == ALL_ENGINES ) {
404         for ( int i = 0; i < MAX_ENGINES; i++ ) {
405             mixture[i] += amt;
406             CLAMP( &mixture[i], 0.0, 1.0 );
407         }
408     } else {
409         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
410             mixture[engine] += amt;
411             CLAMP( &mixture[engine], 0.0, 1.0 );
412         }
413     }
414 }
415
416 void
417 FGControls::set_fuel_pump( int engine, bool val )
418 {
419     if ( engine == ALL_ENGINES ) {
420         for ( int i = 0; i < MAX_ENGINES; i++ ) {
421             fuel_pump[i] = val;
422         }
423     } else {
424         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
425             fuel_pump[engine] = val;
426         }
427     }
428 }
429
430 void
431 FGControls::set_prop_advance( int engine, double pos )
432 {
433     if ( engine == ALL_ENGINES ) {
434         for ( int i = 0; i < MAX_ENGINES; i++ ) {
435             prop_advance[i] = pos;
436             CLAMP( &prop_advance[i], 0.0, 1.0 );
437         }
438     } else {
439         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
440             prop_advance[engine] = pos;
441             CLAMP( &prop_advance[engine], 0.0, 1.0 );
442         }
443     }
444 }
445
446 void
447 FGControls::move_prop_advance( int engine, double amt )
448 {
449     if ( engine == ALL_ENGINES ) {
450         for ( int i = 0; i < MAX_ENGINES; i++ ) {
451             prop_advance[i] += amt;
452             CLAMP( &prop_advance[i], 0.0, 1.0 );
453         }
454     } else {
455         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
456             prop_advance[engine] += amt;
457             CLAMP( &prop_advance[engine], 0.0, 1.0 );
458         }
459     }
460 }
461
462 void
463 FGControls::set_magnetos( int engine, int pos )
464 {
465     if ( engine == ALL_ENGINES ) {
466         for ( int i = 0; i < MAX_ENGINES; i++ ) {
467             magnetos[i] = pos;
468             CLAMP( &magnetos[i], 0, 3 );
469         }
470     } else {
471         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
472             magnetos[engine] = pos;
473             CLAMP( &magnetos[engine], 0, 3 );
474         }
475     }
476 }
477
478 void
479 FGControls::move_magnetos( int engine, int amt )
480 {
481     if ( engine == ALL_ENGINES ) {
482         for ( int i = 0; i < MAX_ENGINES; i++ ) {
483             magnetos[i] += amt;
484             CLAMP( &magnetos[i], 0, 3 );
485         }
486     } else {
487         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
488             magnetos[engine] += amt;
489             CLAMP( &magnetos[engine], 0, 3 );
490         }
491     }
492 }
493
494 void
495 FGControls::set_starter( int engine, bool flag )
496 {
497     if ( engine == ALL_ENGINES ) {
498         for ( int i = 0; i < MAX_ENGINES; i++ ) {
499             starter[i] = flag;
500         }
501     } else {
502         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
503             starter[engine] = flag;
504         }
505     }
506 }
507
508 void
509 FGControls::set_fuel_selector( int tank, bool pos )
510 {
511     if ( tank == ALL_TANKS ) {
512         for ( int i = 0; i < MAX_TANKS; i++ ) {
513             fuel_selector[i] = pos;
514         }
515     } else {
516         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
517             fuel_selector[tank] = pos;
518         }
519     }
520 }
521
522
523 void
524 FGControls::set_parking_brake( double pos )
525 {
526     parking_brake = pos;
527     CLAMP(&parking_brake, 0.0, 1.0);
528 }
529
530 void
531 FGControls::set_speed_brake( double pos )
532 {
533     speed_brake = pos;
534     CLAMP(&speed_brake, 0.0, 1.0);
535 }
536
537 void
538 FGControls::set_spoilers( double pos )
539 {
540     spoilers = pos;
541     CLAMP(&spoilers, 0.0, 1.0);
542 }
543
544 void
545 FGControls::set_brake( int wheel, double pos )
546 {
547     if ( wheel == ALL_WHEELS ) {
548         for ( int i = 0; i < MAX_WHEELS; i++ ) {
549             brake[i] = pos;
550             CLAMP( &brake[i], 0.0, 1.0 );
551         }
552     } else {
553         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
554             brake[wheel] = pos;
555             CLAMP( &brake[wheel], 0.0, 1.0 );
556         }
557     }
558 }
559
560 void
561 FGControls::move_brake( int wheel, double amt )
562 {
563     if ( wheel == ALL_WHEELS ) {
564         for ( int i = 0; i < MAX_WHEELS; i++ ) {
565             brake[i] += amt;
566             CLAMP( &brake[i], 0.0, 1.0 );
567         }
568     } else {
569         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
570             brake[wheel] += amt;
571             CLAMP( &brake[wheel], 0.0, 1.0 );
572         }
573     }
574 }
575
576 void
577 FGControls::set_gear_down( bool gear )
578 {
579   gear_down = gear;
580 }
581
582