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  - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22 
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26 
27 #include <Main/fg_props.hxx>
28 #include <simgear/sg_inlines.h>
29 #include "controls.hxx"
30 
31 ////////////////////////////////////////////////////////////////////////
32 // Implementation of FGControls.
33 ////////////////////////////////////////////////////////////////////////
34 
35 // Constructor
FGControls()36 FGControls::FGControls() :
37     flaps( 0.0 ),
38     slats( 0.0 ),
39     antiskid( true ),
40     tailhook( false ),
41     launchbar( false ),
42     tailwheel_lock( true ),
43     battery_switch( true ),
44     external_power( false ),
45     APU_generator( false ),
46     APU_bleed( false ),
47     mode( 0 ),
48     dump( false ),
49     outflow_valve( 0.0 ),
50     taxi_light( false ),
51     logo_lights( false ),
52     nav_lights( false ),
53     beacon( false ),
54     strobe( false ),
55     panel_norm( 0.0 ),
56     instruments_norm( 0.0 ),
57     dome_norm( 0.0 ),
58     station_select( 1 ),
59     release_ALL( false ),
60     vertical_adjust( 0.0 ),
61     fore_aft_adjust( 0.0 ),
62     cmd_selector_valve( 0 ),
63     off_start_run( 0 ),
64     heading_select( 0.0 ),
65     altitude_select( 50000.0 ),
66     bank_angle_select( 30.0 ),
67     vertical_speed_select( 0.0 ),
68     speed_select( 0.0 ),
69     mach_select( 0.0 ),
70     vertical_mode( 0 ),
71     lateral_mode( 0 )
72 {
73     auto_coordination = fgGetNode("/controls/flight/auto-coordination", true);
74     auto_coordination_factor = fgGetNode("/controls/flight/auto-coordination-factor", false );
75     if( NULL == auto_coordination_factor ) {
76       auto_coordination_factor = fgGetNode("/controls/flight/auto-coordination-factor", true );
77       auto_coordination_factor->setDoubleValue( 0.5 );
78     }
79 
80     reset_all();
81 }
82 
83 
reset_all()84 void FGControls::reset_all()
85 {
86     set_aileron( 0.0 );
87     set_aileron_trim( 0.0 );
88     set_elevator( 0.0 );
89     set_elevator_trim( 0.0 );
90     set_rudder( 0.0 );
91     set_rudder_trim( 0.0 );
92     BLC = false;
93     set_spoilers( 0.0 );
94     set_speedbrake( 0.0 );
95     set_wing_sweep( 0.0 );
96     wing_fold = false;
97     drag_chute = false;
98     set_throttle( ALL_ENGINES, 0.0 );
99     set_starter( ALL_ENGINES, false );
100     set_magnetos( ALL_ENGINES, 0 );
101     set_fuel_pump( ALL_ENGINES, false );
102     set_fire_switch( ALL_ENGINES, false );
103     set_fire_bottle_discharge( ALL_ENGINES, false );
104     set_cutoff( ALL_ENGINES, true );
105     set_nitrous_injection( ALL_ENGINES, false );
106     set_cowl_flaps_norm( ALL_ENGINES, 1.0 );
107     set_feather( ALL_ENGINES, false );
108     set_ignition( ALL_ENGINES, false );
109     set_augmentation( ALL_ENGINES, false );
110     set_reverser( ALL_ENGINES, false );
111     set_water_injection( ALL_ENGINES, false );
112     set_condition( ALL_ENGINES, 1.0 );
113     throttle_idle = true;
114     set_fuel_selector( ALL_TANKS, true );
115     dump_valve = false;
116     steering =  0.0;
117     nose_wheel_steering = true;
118     gear_down = true;
119     tailhook = false;
120     launchbar = false;
121     catapult_launch_cmd = false;
122     tailwheel_lock = true;
123     set_carb_heat( ALL_ENGINES, false );
124     set_inlet_heat( ALL_ENGINES, false );
125     wing_heat = false;
126     pitot_heat = true;
127     wiper = 0;
128     window_heat = false;
129     set_engine_pump( ALL_HYD_SYSTEMS, true );
130     set_electric_pump( ALL_HYD_SYSTEMS, true );
131     landing_lights = false;
132     turn_off_lights = false;
133     master_arm = false;
134     set_ejection_seat( ALL_EJECTION_SEATS, false );
135     set_eseat_status( ALL_EJECTION_SEATS, SEAT_SAFED );
136     set_cmd_selector_valve( CMD_SEL_NORM );
137     APU_fire_switch = false;
138     autothrottle_arm = false;
139     autothrottle_engage = false;
140     set_autopilot_engage( ALL_AUTOPILOTS, false );
141 
142     brake_left = brake_right
143       = copilot_brake_left = copilot_brake_right
144       = brake_parking = 0.0;
145 
146     set_fuel_selector(ALL_TANKS, false);
147     set_to_engine(ALL_TANKS, 0);
148     set_to_tank(ALL_TANKS, 0);
149     set_boost_pump(ALL_TANKS, false);
150 
151     set_alternate_extension(ALL_WHEELS, false);
152 
153     set_mixture(ALL_ENGINES, 1.0);
154     set_prop_advance(ALL_ENGINES, 1.0);
155     set_generator_breaker(ALL_ENGINES, false);
156     set_bus_tie(ALL_ENGINES, false);
157     set_engine_bleed(ALL_ENGINES, false);
158     set_feed_tank(ALL_ENGINES, -1); // feed off
159     set_cowl_flaps_norm(ALL_ENGINES, 0.0);
160 }
161 
162 
163 // Destructor
~FGControls()164 FGControls::~FGControls()
165 {
166 }
167 
168 
169 void
init()170 FGControls::init ()
171 {
172 }
173 
174 void
reinit()175 FGControls::reinit()
176 {
177   reset_all();
178 }
179 
_SetRoot(simgear::TiedPropertyList & tiedProperties,const char * root,int index=0)180 static inline void _SetRoot( simgear::TiedPropertyList & tiedProperties, const char * root, int index = 0 )
181 {
182     tiedProperties.setRoot( fgGetNode( root, index, true ) );
183 }
184 
185 void
bind()186 FGControls::bind ()
187 {
188     reset_all();
189     int index, i;
190 
191     // flight controls
192     _SetRoot( _tiedProperties, "/controls/flight" );
193 
194     _tiedProperties.Tie( "aileron", this, &FGControls::get_aileron, &FGControls::set_aileron )
195         ->setAttribute( SGPropertyNode::ARCHIVE, true );
196 
197     _tiedProperties.Tie( "aileron-trim", this, &FGControls::get_aileron_trim, &FGControls::set_aileron_trim )
198         ->setAttribute( SGPropertyNode::ARCHIVE, true );
199 
200     _tiedProperties.Tie( "elevator", this, &FGControls::get_elevator, &FGControls::set_elevator )
201         ->setAttribute( SGPropertyNode::ARCHIVE, true );
202 
203     _tiedProperties.Tie( "elevator-trim", this, &FGControls::get_elevator_trim, &FGControls::set_elevator_trim )
204         ->setAttribute( SGPropertyNode::ARCHIVE, true );
205 
206     _tiedProperties.Tie( "rudder", this, &FGControls::get_rudder, &FGControls::set_rudder )
207         ->setAttribute( SGPropertyNode::ARCHIVE, true );
208 
209     _tiedProperties.Tie( "rudder-trim", this, &FGControls::get_rudder_trim, &FGControls::set_rudder_trim )
210         ->setAttribute( SGPropertyNode::ARCHIVE, true );
211 
212     _tiedProperties.Tie( "flaps", this, &FGControls::get_flaps, &FGControls::set_flaps )
213         ->setAttribute( SGPropertyNode::ARCHIVE, true );
214 
215     _tiedProperties.Tie( "slats", this, &FGControls::get_slats, &FGControls::set_slats )
216         ->setAttribute( SGPropertyNode::ARCHIVE, true );
217 
218     _tiedProperties.Tie( "BLC", this, &FGControls::get_BLC, &FGControls::set_BLC )
219         ->setAttribute( SGPropertyNode::ARCHIVE, true );
220 
221     _tiedProperties.Tie( "spoilers", this, &FGControls::get_spoilers, &FGControls::set_spoilers )
222         ->setAttribute( SGPropertyNode::ARCHIVE, true );
223 
224     _tiedProperties.Tie( "speedbrake", this, &FGControls::get_speedbrake, &FGControls::set_speedbrake )
225         ->setAttribute( SGPropertyNode::ARCHIVE, true );
226 
227     _tiedProperties.Tie( "wing-sweep", this, &FGControls::get_wing_sweep, &FGControls::set_wing_sweep )
228         ->setAttribute( SGPropertyNode::ARCHIVE, true );
229 
230     _tiedProperties.Tie( "wing-fold", this, &FGControls::get_wing_fold, &FGControls::set_wing_fold )
231         ->setAttribute( SGPropertyNode::ARCHIVE, true );
232 
233     _tiedProperties.Tie( "drag-chute", this, &FGControls::get_drag_chute, &FGControls::set_drag_chute )
234         ->setAttribute( SGPropertyNode::ARCHIVE, true );
235 
236     // engines
237     _tiedProperties.setRoot( fgGetNode("/controls/engines", true ) );
238 
239     _tiedProperties.Tie( "throttle_idle", this, &FGControls::get_throttle_idle, &FGControls::set_throttle_idle )
240         ->setAttribute( SGPropertyNode::ARCHIVE, true );
241 
242     for (index = 0; index < MAX_ENGINES; index++) {
243         _SetRoot(_tiedProperties, "/controls/engines/engine", index );
244 
245         _tiedProperties.Tie( "throttle", this, index, &FGControls::get_throttle, &FGControls::set_throttle )
246             ->setAttribute( SGPropertyNode::ARCHIVE, true );
247 
248         _tiedProperties.Tie( "starter", this, index, &FGControls::get_starter, &FGControls::set_starter )
249             ->setAttribute( SGPropertyNode::ARCHIVE, true );
250 
251         _tiedProperties.Tie( "fuel-pump", this, index, &FGControls::get_fuel_pump, &FGControls::set_fuel_pump )
252             ->setAttribute( SGPropertyNode::ARCHIVE, true );
253 
254         _tiedProperties.Tie( "fire-switch", this, index, &FGControls::get_fire_switch, &FGControls::set_fire_switch )
255             ->setAttribute( SGPropertyNode::ARCHIVE, true );
256 
257         _tiedProperties.Tie( "fire-bottle-discharge", this, index, &FGControls::get_fire_bottle_discharge, &FGControls::set_fire_bottle_discharge )
258             ->setAttribute( SGPropertyNode::ARCHIVE, true );
259 
260         _tiedProperties.Tie( "cutoff", this, index, &FGControls::get_cutoff, &FGControls::set_cutoff )
261             ->setAttribute( SGPropertyNode::ARCHIVE, true );
262 
263         _tiedProperties.Tie( "mixture", this, index, &FGControls::get_mixture, &FGControls::set_mixture )
264             ->setAttribute( SGPropertyNode::ARCHIVE, true );
265 
266         _tiedProperties.Tie( "propeller-pitch", this, index, &FGControls::get_prop_advance, &FGControls::set_prop_advance )
267             ->setAttribute( SGPropertyNode::ARCHIVE, true );
268 
269         _tiedProperties.Tie( "magnetos", this, index, &FGControls::get_magnetos, &FGControls::set_magnetos )
270             ->setAttribute( SGPropertyNode::ARCHIVE, true );
271 
272         _tiedProperties.Tie( "feed_tank", this, index, &FGControls::get_feed_tank, &FGControls::set_feed_tank )
273             ->setAttribute( SGPropertyNode::ARCHIVE, true );
274 
275         _tiedProperties.Tie( "WEP", this, index, &FGControls::get_nitrous_injection, &FGControls::set_nitrous_injection )
276             ->setAttribute( SGPropertyNode::ARCHIVE, true );
277 
278         _tiedProperties.Tie( "cowl-flaps-norm", this, index, &FGControls::get_cowl_flaps_norm, &FGControls::set_cowl_flaps_norm )
279             ->setAttribute( SGPropertyNode::ARCHIVE, true );
280 
281         _tiedProperties.Tie( "propeller-feather", this, index, &FGControls::get_feather, &FGControls::set_feather )
282             ->setAttribute( SGPropertyNode::ARCHIVE, true );
283 
284         _tiedProperties.Tie( "ignition", this, index, &FGControls::get_ignition, &FGControls::set_ignition )
285             ->setAttribute( SGPropertyNode::ARCHIVE, true );
286 
287         _tiedProperties.Tie( "augmentation", this, index, &FGControls::get_augmentation, &FGControls::set_augmentation )
288             ->setAttribute( SGPropertyNode::ARCHIVE, true );
289 
290         _tiedProperties.Tie( "reverser", this, index, &FGControls::get_reverser, &FGControls::set_reverser )
291             ->setAttribute( SGPropertyNode::ARCHIVE, true );
292 
293         _tiedProperties.Tie( "water-injection", this, index, &FGControls::get_water_injection, &FGControls::set_water_injection )
294             ->setAttribute( SGPropertyNode::ARCHIVE, true );
295 
296         _tiedProperties.Tie( "condition", this, index, &FGControls::get_condition, &FGControls::set_condition )
297             ->setAttribute( SGPropertyNode::ARCHIVE, true );
298     }
299 
300     // fuel
301     _SetRoot( _tiedProperties, "/controls/fuel" );
302 
303     _tiedProperties.Tie( "dump-valve", this, &FGControls::get_dump_valve, &FGControls::set_dump_valve)
304         ->setAttribute( SGPropertyNode::ARCHIVE, true );
305 
306     for (index = 0; index < MAX_TANKS; index++) {
307         _SetRoot( _tiedProperties, "/controls/fuel/tank", index );
308 
309         _tiedProperties.Tie( "fuel_selector", this, index, &FGControls::get_fuel_selector, &FGControls::set_fuel_selector)
310             ->setAttribute( SGPropertyNode::ARCHIVE, true );
311 
312         _tiedProperties.Tie( "to_engine", this, index, &FGControls::get_to_engine, &FGControls::set_to_engine)
313             ->setAttribute( SGPropertyNode::ARCHIVE, true );
314 
315         _tiedProperties.Tie( "to_tank", this, index, &FGControls::get_to_tank, &FGControls::set_to_tank)
316             ->setAttribute( SGPropertyNode::ARCHIVE, true );
317 
318         for (i = 0; i < MAX_BOOSTPUMPS; i++) {
319             _tiedProperties.Tie( "boost-pump", i,
320                 this, index * 2 + i, &FGControls::get_boost_pump, &FGControls::set_boost_pump)
321                 ->setAttribute( SGPropertyNode::ARCHIVE, true );
322         }
323     }
324 
325     // gear
326     _SetRoot( _tiedProperties, "/controls/gear" );
327 
328     _tiedProperties.Tie( "brake-left", this, &FGControls::get_brake_left, &FGControls::set_brake_left)
329         ->setAttribute( SGPropertyNode::ARCHIVE, true );
330 
331     _tiedProperties.Tie( "brake-right", this, &FGControls::get_brake_right, &FGControls::set_brake_right)
332         ->setAttribute( SGPropertyNode::ARCHIVE, true );
333 
334     _tiedProperties.Tie( "copilot-brake-left", this, &FGControls::get_copilot_brake_left, &FGControls::set_copilot_brake_left)
335         ->setAttribute( SGPropertyNode::ARCHIVE, true );
336 
337     _tiedProperties.Tie( "copilot-brake-right", this, &FGControls::get_copilot_brake_right, &FGControls::set_copilot_brake_right)
338         ->setAttribute( SGPropertyNode::ARCHIVE, true );
339 
340     _tiedProperties.Tie( "brake-parking", this, &FGControls::get_brake_parking, &FGControls::set_brake_parking)
341         ->setAttribute( SGPropertyNode::ARCHIVE, true );
342 
343     _tiedProperties.Tie( "steering", this, &FGControls::get_steering, &FGControls::set_steering)
344         ->setAttribute( SGPropertyNode::ARCHIVE, true );
345 
346     _tiedProperties.Tie( "nose-wheel-steering", this, &FGControls::get_nose_wheel_steering, &FGControls::set_nose_wheel_steering)
347         ->setAttribute( SGPropertyNode::ARCHIVE, true );
348 
349     _tiedProperties.Tie( "gear-down", this, &FGControls::get_gear_down, &FGControls::set_gear_down)
350         ->setAttribute( SGPropertyNode::ARCHIVE, true );
351 
352     _tiedProperties.Tie( "antiskid", this, &FGControls::get_antiskid, &FGControls::set_antiskid)
353         ->setAttribute( SGPropertyNode::ARCHIVE, true );
354 
355     _tiedProperties.Tie( "tailhook", this, &FGControls::get_tailhook, &FGControls::set_tailhook)
356         ->setAttribute( SGPropertyNode::ARCHIVE, true );
357 
358     _tiedProperties.Tie( "launchbar", this, &FGControls::get_launchbar, &FGControls::set_launchbar)
359         ->setAttribute( SGPropertyNode::ARCHIVE, true );
360 
361     _tiedProperties.Tie( "catapult-launch-cmd", this, &FGControls::get_catapult_launch_cmd, &FGControls::set_catapult_launch_cmd)
362         ->setAttribute( SGPropertyNode::ARCHIVE, true );
363 
364     _tiedProperties.Tie( "tailwheel-lock", this, &FGControls::get_tailwheel_lock, &FGControls::set_tailwheel_lock)
365         ->setAttribute( SGPropertyNode::ARCHIVE, true );
366 
367     for (index = 0; index < MAX_WHEELS; index++) {
368         _SetRoot( _tiedProperties, "/controls/gear/wheel", index );
369         _tiedProperties.Tie( "alternate-extension", this, index, &FGControls::get_alternate_extension, &FGControls::set_alternate_extension)
370             ->setAttribute( SGPropertyNode::ARCHIVE, true );
371     }
372 
373     // anti-ice
374     _SetRoot( _tiedProperties, "/controls/anti-ice" );
375 
376     _tiedProperties.Tie( "wing-heat", this, &FGControls::get_wing_heat, &FGControls::set_wing_heat)
377         ->setAttribute( SGPropertyNode::ARCHIVE, true );
378 
379     _tiedProperties.Tie( "pitot-heat", this, &FGControls::get_pitot_heat, &FGControls::set_pitot_heat)
380         ->setAttribute( SGPropertyNode::ARCHIVE, true );
381 
382     _tiedProperties.Tie( "wiper", this, &FGControls::get_wiper, &FGControls::set_wiper)
383         ->setAttribute( SGPropertyNode::ARCHIVE, true );
384 
385     _tiedProperties.Tie( "window-heat", this, &FGControls::get_window_heat, &FGControls::set_window_heat)
386         ->setAttribute( SGPropertyNode::ARCHIVE, true );
387 
388     for (index = 0; index < MAX_ENGINES; index++) {
389         _SetRoot( _tiedProperties, "/controls/anti-ice/engine", index );
390 
391         _tiedProperties.Tie( "carb-heat", this, index, &FGControls::get_carb_heat, &FGControls::set_carb_heat)
392             ->setAttribute( SGPropertyNode::ARCHIVE, true );
393 
394         _tiedProperties.Tie( "inlet-heat", this, index, &FGControls::get_inlet_heat, &FGControls::set_inlet_heat)
395             ->setAttribute( SGPropertyNode::ARCHIVE, true );
396     }
397 
398     // hydraulics
399     for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
400         _SetRoot( _tiedProperties, "/controls/hydraulic/system", index );
401 
402         _tiedProperties.Tie( "engine-pump", this, index, &FGControls::get_engine_pump, &FGControls::set_engine_pump)
403             ->setAttribute( SGPropertyNode::ARCHIVE, true );
404 
405         _tiedProperties.Tie( "electric-pump", this, index, &FGControls::get_electric_pump, &FGControls::set_electric_pump)
406             ->setAttribute( SGPropertyNode::ARCHIVE, true );
407     }
408 
409     // electric
410     _SetRoot( _tiedProperties, "/controls/electric" );
411 
412     _tiedProperties.Tie( "battery-switch", this, &FGControls::get_battery_switch, &FGControls::set_battery_switch)
413         ->setAttribute( SGPropertyNode::ARCHIVE, true );
414 
415     _tiedProperties.Tie( "external-power", this, &FGControls::get_external_power, &FGControls::set_external_power)
416         ->setAttribute( SGPropertyNode::ARCHIVE, true );
417 
418     _tiedProperties.Tie( "APU-generator", this, &FGControls::get_APU_generator, &FGControls::set_APU_generator)
419         ->setAttribute( SGPropertyNode::ARCHIVE, true );
420 
421     for (index = 0; index < MAX_ENGINES; index++) {
422         _SetRoot( _tiedProperties, "/controls/electric/engine", index );
423 
424         _tiedProperties.Tie( "generator", this, index, &FGControls::get_generator_breaker, &FGControls::set_generator_breaker)
425             ->setAttribute( SGPropertyNode::ARCHIVE, true );
426 
427         _tiedProperties.Tie( "bus-tie", this, index, &FGControls::get_bus_tie, &FGControls::set_bus_tie)
428             ->setAttribute( SGPropertyNode::ARCHIVE, true );
429     }
430 
431     // pneumatic
432     _SetRoot( _tiedProperties, "/controls/pneumatic" );
433 
434     _tiedProperties.Tie( "APU-bleed", this, &FGControls::get_APU_bleed, &FGControls::set_APU_bleed)
435         ->setAttribute( SGPropertyNode::ARCHIVE, true );
436 
437     for (index = 0; index < MAX_ENGINES; index++) {
438         _SetRoot( _tiedProperties, "/controls/pneumatic/engine", index );
439 
440         _tiedProperties.Tie( "bleed", this, index, &FGControls::get_engine_bleed, &FGControls::set_engine_bleed)
441             ->setAttribute( SGPropertyNode::ARCHIVE, true );
442     }
443 
444     // pressurization
445     _SetRoot( _tiedProperties, "/controls/pressurization" );
446 
447     _tiedProperties.Tie( "mode", this, &FGControls::get_mode, &FGControls::set_mode)
448         ->setAttribute( SGPropertyNode::ARCHIVE, true );
449 
450     _tiedProperties.Tie( "dump", this, &FGControls::get_dump, &FGControls::set_dump)
451         ->setAttribute( SGPropertyNode::ARCHIVE, true );
452 
453     _tiedProperties.Tie( "outflow-valve", this, &FGControls::get_outflow_valve, &FGControls::set_outflow_valve)
454         ->setAttribute( SGPropertyNode::ARCHIVE, true );
455 
456     for (index = 0; index < MAX_PACKS; index++) {
457         _SetRoot( _tiedProperties, "/controls/pressurization/pack", index );
458 
459         _tiedProperties.Tie( "pack-on", this, index, &FGControls::get_pack_on, &FGControls::set_pack_on)
460             ->setAttribute( SGPropertyNode::ARCHIVE, true );
461     }
462 
463     // lights
464     _SetRoot( _tiedProperties, "/controls/lighting" );
465 
466     _tiedProperties.Tie( "landing-lights", this, &FGControls::get_landing_lights, &FGControls::set_landing_lights)
467         ->setAttribute( SGPropertyNode::ARCHIVE, true );
468 
469     _tiedProperties.Tie( "turn-off-lights", this, &FGControls::get_turn_off_lights, &FGControls::set_turn_off_lights)
470         ->setAttribute( SGPropertyNode::ARCHIVE, true );
471 
472     _tiedProperties.Tie( "taxi-light", this, &FGControls::get_taxi_light, &FGControls::set_taxi_light)
473         ->setAttribute( SGPropertyNode::ARCHIVE, true );
474 
475     _tiedProperties.Tie( "logo-lights", this, &FGControls::get_logo_lights, &FGControls::set_logo_lights)
476         ->setAttribute( SGPropertyNode::ARCHIVE, true );
477 
478     _tiedProperties.Tie( "nav-lights", this, &FGControls::get_nav_lights, &FGControls::set_nav_lights)
479         ->setAttribute( SGPropertyNode::ARCHIVE, true );
480 
481     _tiedProperties.Tie( "beacon", this, &FGControls::get_beacon, &FGControls::set_beacon)
482         ->setAttribute( SGPropertyNode::ARCHIVE, true );
483 
484     _tiedProperties.Tie( "strobe", this, &FGControls::get_strobe, &FGControls::set_strobe)
485         ->setAttribute( SGPropertyNode::ARCHIVE, true );
486 
487     _tiedProperties.Tie( "panel-norm", this, &FGControls::get_panel_norm, &FGControls::set_panel_norm)
488         ->setAttribute( SGPropertyNode::ARCHIVE, true );
489 
490     _tiedProperties.Tie( "instruments-norm", this, &FGControls::get_instruments_norm, &FGControls::set_instruments_norm)
491         ->setAttribute( SGPropertyNode::ARCHIVE, true );
492 
493     _tiedProperties.Tie( "dome-norm", this, &FGControls::get_dome_norm, &FGControls::set_dome_norm)
494         ->setAttribute( SGPropertyNode::ARCHIVE, true );
495 
496     // armament
497     _SetRoot( _tiedProperties, "/controls/armament" );
498 
499     _tiedProperties.Tie( "master-arm", this, &FGControls::get_master_arm, &FGControls::set_master_arm)
500         ->setAttribute( SGPropertyNode::ARCHIVE, true );
501 
502     _tiedProperties.Tie( "station-select", this, &FGControls::get_station_select, &FGControls::set_station_select)
503         ->setAttribute( SGPropertyNode::ARCHIVE, true );
504 
505     _tiedProperties.Tie( "release-all", this, &FGControls::get_release_ALL, &FGControls::set_release_ALL)
506         ->setAttribute( SGPropertyNode::ARCHIVE, true );
507 
508     for (index = 0; index < MAX_STATIONS; index++) {
509         _SetRoot( _tiedProperties, "/controls/armament/station", index );
510 
511         _tiedProperties.Tie( "stick-size", this, index, &FGControls::get_stick_size, &FGControls::set_stick_size)
512             ->setAttribute( SGPropertyNode::ARCHIVE, true );
513 
514         _tiedProperties.Tie( "release-stick", this, index, &FGControls::get_release_stick, &FGControls::set_release_stick)
515             ->setAttribute( SGPropertyNode::ARCHIVE, true );
516 
517         _tiedProperties.Tie( "release-all", this, index, &FGControls::get_release_all, &FGControls::set_release_all)
518             ->setAttribute( SGPropertyNode::ARCHIVE, true );
519 
520         _tiedProperties.Tie( "jettison-all", this, index, &FGControls::get_jettison_all, &FGControls::set_jettison_all)
521             ->setAttribute( SGPropertyNode::ARCHIVE, true );
522     }
523 
524     // seat
525     _SetRoot( _tiedProperties, "/controls/seat" );
526 
527     _tiedProperties.Tie( "vertical-adjust", this, &FGControls::get_vertical_adjust, &FGControls::set_vertical_adjust)
528         ->setAttribute( SGPropertyNode::ARCHIVE, true );
529 
530     _tiedProperties.Tie( "fore-aft-adjust", this, &FGControls::get_fore_aft_adjust, &FGControls::set_fore_aft_adjust)
531         ->setAttribute( SGPropertyNode::ARCHIVE, true );
532 
533     _tiedProperties.Tie( "cmd_selector_valve", this, &FGControls::get_cmd_selector_valve, &FGControls::set_cmd_selector_valve)
534         ->setAttribute( SGPropertyNode::ARCHIVE, true );
535 
536     for (index = 0; index < MAX_EJECTION_SEATS; index++) {
537         _SetRoot( _tiedProperties, "/controls/seat/eject", index );
538 
539         _tiedProperties.Tie( "initiate", this, index, &FGControls::get_ejection_seat, &FGControls::set_ejection_seat)
540             ->setAttribute( SGPropertyNode::ARCHIVE, true );
541 
542         _tiedProperties.Tie( "status", this, index, &FGControls::get_eseat_status, &FGControls::set_eseat_status)
543             ->setAttribute( SGPropertyNode::ARCHIVE, true );
544     }
545 
546     // APU
547     _SetRoot( _tiedProperties, "/controls/APU" );
548 
549     _tiedProperties.Tie( "off-start-run", this, &FGControls::get_off_start_run, &FGControls::set_off_start_run)
550         ->setAttribute( SGPropertyNode::ARCHIVE, true );
551 
552     _tiedProperties.Tie( "fire-switch", this, &FGControls::get_APU_fire_switch, &FGControls::set_APU_fire_switch)
553         ->setAttribute( SGPropertyNode::ARCHIVE, true );
554 
555     // autoflight
556     for (index = 0; index < MAX_AUTOPILOTS; index++) {
557 
558         _SetRoot( _tiedProperties, "/controls/autoflight/autopilot", index );
559 
560         _tiedProperties.Tie( "engage", this, index, &FGControls::get_autopilot_engage, &FGControls::set_autopilot_engage)
561             ->setAttribute( SGPropertyNode::ARCHIVE, true );
562     }
563 
564     _SetRoot( _tiedProperties, "/controls/autoflight/" );
565 
566     _tiedProperties.Tie( "autothrottle-arm", this, &FGControls::get_autothrottle_arm, &FGControls::set_autothrottle_arm)
567         ->setAttribute( SGPropertyNode::ARCHIVE, true );
568 
569     _tiedProperties.Tie( "autothrottle-engage", this, &FGControls::get_autothrottle_engage, &FGControls::set_autothrottle_engage)
570         ->setAttribute( SGPropertyNode::ARCHIVE, true );
571 
572     _tiedProperties.Tie( "heading-select", this, &FGControls::get_heading_select, &FGControls::set_heading_select)
573         ->setAttribute( SGPropertyNode::ARCHIVE, true );
574 
575     _tiedProperties.Tie( "altitude-select", this, &FGControls::get_altitude_select, &FGControls::set_altitude_select)
576         ->setAttribute( SGPropertyNode::ARCHIVE, true );
577 
578     _tiedProperties.Tie( "bank-angle-select", this, &FGControls::get_bank_angle_select, &FGControls::set_bank_angle_select)
579         ->setAttribute( SGPropertyNode::ARCHIVE, true );
580 
581     _tiedProperties.Tie( "vertical-speed-select", this, &FGControls::get_vertical_speed_select, &FGControls::set_vertical_speed_select)
582         ->setAttribute( SGPropertyNode::ARCHIVE, true );
583 
584     _tiedProperties.Tie( "speed-select", this, &FGControls::get_speed_select, &FGControls::set_speed_select)
585         ->setAttribute( SGPropertyNode::ARCHIVE, true );
586 
587     _tiedProperties.Tie( "mach-select", this, &FGControls::get_mach_select, &FGControls::set_mach_select)
588         ->setAttribute( SGPropertyNode::ARCHIVE, true );
589 
590     _tiedProperties.Tie( "vertical-mode", this, &FGControls::get_vertical_mode, &FGControls::set_vertical_mode)
591         ->setAttribute( SGPropertyNode::ARCHIVE, true );
592 
593     _tiedProperties.Tie( "lateral-mode", this, &FGControls::get_lateral_mode, &FGControls::set_lateral_mode)
594         ->setAttribute( SGPropertyNode::ARCHIVE, true );
595 }
596 
unbind()597 void FGControls::unbind ()
598 {
599     _tiedProperties.Untie();
600 }
601 
602 
603 void
update(double dt)604 FGControls::update (double dt)
605 {
606   SG_UNUSED(dt);
607 
608   // nothing here, don't call again
609   suspend();
610 }
611 
612 ////////////////////////////////////////////////////////////////////////
613 // Setters and adjusters.
614 ////////////////////////////////////////////////////////////////////////
615 
616 void
set_aileron(double pos)617 FGControls::set_aileron (double pos)
618 {
619     aileron = pos;
620     SG_CLAMP_RANGE<double>( aileron, -1.0, 1.0 );
621     do_autocoordination();
622 }
623 
624 void
move_aileron(double amt)625 FGControls::move_aileron (double amt)
626 {
627     aileron += amt;
628     SG_CLAMP_RANGE<double>( aileron, -1.0, 1.0 );
629     do_autocoordination();
630 }
631 
632 void
set_aileron_trim(double pos)633 FGControls::set_aileron_trim( double pos )
634 {
635     aileron_trim = pos;
636     SG_CLAMP_RANGE<double>( aileron_trim, -1.0, 1.0 );
637 }
638 
639 void
move_aileron_trim(double amt)640 FGControls::move_aileron_trim( double amt )
641 {
642     aileron_trim += amt;
643     SG_CLAMP_RANGE<double>( aileron_trim, -1.0, 1.0 );
644 }
645 
646 void
set_elevator(double pos)647 FGControls::set_elevator( double pos )
648 {
649     elevator = pos;
650     SG_CLAMP_RANGE<double>( elevator, -1.0, 1.0 );
651 }
652 
653 void
move_elevator(double amt)654 FGControls::move_elevator( double amt )
655 {
656     elevator += amt;
657     SG_CLAMP_RANGE<double>( elevator, -1.0, 1.0 );
658 }
659 
660 void
set_elevator_trim(double pos)661 FGControls::set_elevator_trim( double pos )
662 {
663     elevator_trim = pos;
664     SG_CLAMP_RANGE<double>( elevator_trim, -1.0, 1.0 );
665 }
666 
667 void
move_elevator_trim(double amt)668 FGControls::move_elevator_trim( double amt )
669 {
670     elevator_trim += amt;
671     SG_CLAMP_RANGE<double>( elevator_trim, -1.0, 1.0 );
672 }
673 
674 void
set_rudder(double pos)675 FGControls::set_rudder( double pos )
676 {
677     rudder = pos;
678     SG_CLAMP_RANGE<double>( rudder, -1.0, 1.0 );
679 }
680 
681 void
move_rudder(double amt)682 FGControls::move_rudder( double amt )
683 {
684     rudder += amt;
685     SG_CLAMP_RANGE<double>( rudder, -1.0, 1.0 );
686 }
687 
688 void
set_rudder_trim(double pos)689 FGControls::set_rudder_trim( double pos )
690 {
691     rudder_trim = pos;
692     SG_CLAMP_RANGE<double>( rudder_trim, -1.0, 1.0 );
693 }
694 
695 void
move_rudder_trim(double amt)696 FGControls::move_rudder_trim( double amt )
697 {
698     rudder_trim += amt;
699     SG_CLAMP_RANGE<double>( rudder_trim, -1.0, 1.0 );
700 }
701 
702 void
set_flaps(double pos)703 FGControls::set_flaps( double pos )
704 {
705     flaps = pos;
706     SG_CLAMP_RANGE<double>( flaps, 0.0, 1.0 );
707 }
708 
709 void
move_flaps(double amt)710 FGControls::move_flaps( double amt )
711 {
712     flaps += amt;
713     SG_CLAMP_RANGE<double>( flaps, 0.0, 1.0 );
714 }
715 
716 void
set_slats(double pos)717 FGControls::set_slats( double pos )
718 {
719     slats = pos;
720     SG_CLAMP_RANGE<double>( slats, 0.0, 1.0 );
721 }
722 
723 void
move_slats(double amt)724 FGControls::move_slats( double amt )
725 {
726     slats += amt;
727     SG_CLAMP_RANGE<double>( slats, 0.0, 1.0 );
728 }
729 
730 void
set_BLC(bool val)731 FGControls::set_BLC( bool val )
732 {
733     BLC = val;
734 }
735 
736 void
set_spoilers(double pos)737 FGControls::set_spoilers( double pos )
738 {
739     spoilers = pos;
740     SG_CLAMP_RANGE<double>( spoilers, 0.0, 1.0 );
741 }
742 
743 void
move_spoilers(double amt)744 FGControls::move_spoilers( double amt )
745 {
746     spoilers += amt;
747     SG_CLAMP_RANGE<double>( spoilers, 0.0, 1.0 );
748 }
749 
750 void
set_speedbrake(double pos)751 FGControls::set_speedbrake( double pos )
752 {
753     speedbrake = pos;
754     SG_CLAMP_RANGE<double>( speedbrake, 0.0, 1.0 );
755 }
756 
757 void
move_speedbrake(double amt)758 FGControls::move_speedbrake( double amt )
759 {
760     speedbrake += amt;
761     SG_CLAMP_RANGE<double>( speedbrake, 0.0, 1.0 );
762 }
763 
764 void
set_wing_sweep(double pos)765 FGControls::set_wing_sweep( double pos )
766 {
767     wing_sweep = pos;
768     SG_CLAMP_RANGE<double>( wing_sweep, 0.0, 1.0 );
769 }
770 
771 void
move_wing_sweep(double amt)772 FGControls::move_wing_sweep( double amt )
773 {
774     wing_sweep += amt;
775     SG_CLAMP_RANGE<double>( wing_sweep, 0.0, 1.0 );
776 }
777 
778 void
set_wing_fold(bool val)779 FGControls::set_wing_fold( bool val )
780 {
781     wing_fold = val;
782 }
783 
784 void
set_drag_chute(bool val)785 FGControls::set_drag_chute( bool val )
786 {
787     drag_chute = val;
788 }
789 
790 void
set_throttle_idle(bool val)791 FGControls::set_throttle_idle( bool val )
792 {
793     throttle_idle = val;
794 }
795 
796 void
set_throttle(int engine,double pos)797 FGControls::set_throttle( int engine, double pos )
798 {
799     if ( engine == ALL_ENGINES ) {
800         for ( int i = 0; i < MAX_ENGINES; i++ ) {
801             throttle[i] = pos;
802             SG_CLAMP_RANGE<double>( throttle[i], 0.0, 1.0 );
803         }
804     } else {
805         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
806             throttle[engine] = pos;
807             SG_CLAMP_RANGE<double>( throttle[engine], 0.0, 1.0 );
808         }
809     }
810 }
811 
812 void
move_throttle(int engine,double amt)813 FGControls::move_throttle( int engine, double amt )
814 {
815     if ( engine == ALL_ENGINES ) {
816         for ( int i = 0; i < MAX_ENGINES; i++ ) {
817             throttle[i] += amt;
818             SG_CLAMP_RANGE<double>( throttle[i], 0.0, 1.0 );
819         }
820     } else {
821         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
822             throttle[engine] += amt;
823             SG_CLAMP_RANGE<double>( throttle[engine], 0.0, 1.0 );
824         }
825     }
826 }
827 
828 void
set_starter(int engine,bool flag)829 FGControls::set_starter( int engine, bool flag )
830 {
831     if ( engine == ALL_ENGINES ) {
832         for ( int i = 0; i < MAX_ENGINES; i++ ) {
833             starter[i] = flag;
834         }
835     } else {
836         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
837             starter[engine] = flag;
838         }
839     }
840 }
841 
842 void
set_fuel_pump(int engine,bool val)843 FGControls::set_fuel_pump( int engine, bool val )
844 {
845     if ( engine == ALL_ENGINES ) {
846         for ( int i = 0; i < MAX_ENGINES; i++ ) {
847             fuel_pump[i] = val;
848         }
849     } else {
850         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
851             fuel_pump[engine] = val;
852         }
853     }
854 }
855 
856 void
set_fire_switch(int engine,bool val)857 FGControls::set_fire_switch( int engine, bool val )
858 {
859     if ( engine == ALL_ENGINES ) {
860         for ( int i = 0; i < MAX_ENGINES; i++ ) {
861             fire_switch[i] = val;
862         }
863     } else {
864         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
865             fire_switch[engine] = val;
866         }
867     }
868 }
869 
870 void
set_fire_bottle_discharge(int engine,bool val)871 FGControls::set_fire_bottle_discharge( int engine, bool val )
872 {
873     if ( engine == ALL_ENGINES ) {
874         for ( int i = 0; i < MAX_ENGINES; i++ ) {
875             fire_bottle_discharge[i] = val;
876         }
877     } else {
878         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
879             fire_bottle_discharge[engine] = val;
880         }
881     }
882 }
883 
884 void
set_cutoff(int engine,bool val)885 FGControls::set_cutoff( int engine, bool val )
886 {
887     if ( engine == ALL_ENGINES ) {
888         for ( int i = 0; i < MAX_ENGINES; i++ ) {
889             cutoff[i] = val;
890         }
891     } else {
892         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
893             cutoff[engine] = val;
894         }
895     }
896 }
897 
898 void
set_feed_tank(int engine,int tank)899 FGControls::set_feed_tank( int engine, int tank )
900 {
901     if ( engine == ALL_ENGINES ) {
902         for ( int i = 0; i < MAX_ENGINES; i++ ) {
903             feed_tank[i] = tank;
904             SG_CLAMP_RANGE<int>( feed_tank[i], -1, 4 );
905         }
906     } else {
907         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
908             feed_tank[engine] = tank;
909             SG_CLAMP_RANGE<int>( feed_tank[engine], -1, 4 );
910         }
911     }
912     //   feed_tank[engine] = engine;
913 }
914 
915 
916 void
set_mixture(int engine,double pos)917 FGControls::set_mixture( int engine, double pos )
918 {
919     if ( engine == ALL_ENGINES ) {
920         for ( int i = 0; i < MAX_ENGINES; i++ ) {
921             mixture[i] = pos;
922             SG_CLAMP_RANGE<double>( mixture[i], 0.0, 1.0 );
923         }
924     } else {
925         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
926             mixture[engine] = pos;
927             SG_CLAMP_RANGE<double>( mixture[engine], 0.0, 1.0 );
928         }
929     }
930 }
931 
932 void
move_mixture(int engine,double amt)933 FGControls::move_mixture( int engine, double amt )
934 {
935     if ( engine == ALL_ENGINES ) {
936         for ( int i = 0; i < MAX_ENGINES; i++ ) {
937             mixture[i] += amt;
938             SG_CLAMP_RANGE<double>( mixture[i], 0.0, 1.0 );
939         }
940     } else {
941         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
942             mixture[engine] += amt;
943             SG_CLAMP_RANGE<double>( mixture[engine], 0.0, 1.0 );
944         }
945     }
946 }
947 
948 void
set_prop_advance(int engine,double pos)949 FGControls::set_prop_advance( int engine, double pos )
950 {
951     if ( engine == ALL_ENGINES ) {
952         for ( int i = 0; i < MAX_ENGINES; i++ ) {
953             prop_advance[i] = pos;
954             SG_CLAMP_RANGE<double>( prop_advance[i], 0.0, 1.0 );
955         }
956     } else {
957         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
958             prop_advance[engine] = pos;
959             SG_CLAMP_RANGE<double>( prop_advance[engine], 0.0, 1.0 );
960         }
961     }
962 }
963 
964 void
move_prop_advance(int engine,double amt)965 FGControls::move_prop_advance( int engine, double amt )
966 {
967     if ( engine == ALL_ENGINES ) {
968         for ( int i = 0; i < MAX_ENGINES; i++ ) {
969             prop_advance[i] += amt;
970             SG_CLAMP_RANGE<double>( prop_advance[i], 0.0, 1.0 );
971         }
972     } else {
973         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
974             prop_advance[engine] += amt;
975             SG_CLAMP_RANGE<double>( prop_advance[engine], 0.0, 1.0 );
976         }
977     }
978 }
979 
980 void
set_magnetos(int engine,int pos)981 FGControls::set_magnetos( int engine, int pos )
982 {
983     if ( engine == ALL_ENGINES ) {
984         for ( int i = 0; i < MAX_ENGINES; i++ ) {
985             magnetos[i] = pos;
986             SG_CLAMP_RANGE<int>( magnetos[i], 0, 3 );
987         }
988     } else {
989         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
990             magnetos[engine] = pos;
991             SG_CLAMP_RANGE<int>( magnetos[engine], 0, 3 );
992         }
993     }
994 }
995 
996 void
move_magnetos(int engine,int amt)997 FGControls::move_magnetos( int engine, int amt )
998 {
999     if ( engine == ALL_ENGINES ) {
1000         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1001             magnetos[i] += amt;
1002             SG_CLAMP_RANGE<int>( magnetos[i], 0, 3 );
1003         }
1004     } else {
1005         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1006             magnetos[engine] += amt;
1007             SG_CLAMP_RANGE<int>( magnetos[engine], 0, 3 );
1008         }
1009     }
1010 }
1011 
1012 void
set_nitrous_injection(int engine,bool val)1013 FGControls::set_nitrous_injection( int engine, bool val )
1014 {
1015     if ( engine == ALL_ENGINES ) {
1016         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1017             nitrous_injection[i] = val;
1018         }
1019     } else {
1020         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1021             nitrous_injection[engine] = val;
1022         }
1023     }
1024 }
1025 
1026 
1027 void
set_cowl_flaps_norm(int engine,double pos)1028 FGControls::set_cowl_flaps_norm( int engine, double pos )
1029 {
1030     if ( engine == ALL_ENGINES ) {
1031         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1032             cowl_flaps_norm[i] = pos;
1033             SG_CLAMP_RANGE<double>( cowl_flaps_norm[i], 0.0, 1.0 );
1034         }
1035     } else {
1036         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1037             cowl_flaps_norm[engine] = pos;
1038             SG_CLAMP_RANGE<double>( cowl_flaps_norm[engine], 0.0, 1.0 );
1039         }
1040     }
1041 }
1042 
1043 void
move_cowl_flaps_norm(int engine,double amt)1044 FGControls::move_cowl_flaps_norm( int engine, double amt )
1045 {
1046     if ( engine == ALL_ENGINES ) {
1047         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1048             cowl_flaps_norm[i] += amt;
1049             SG_CLAMP_RANGE<double>( cowl_flaps_norm[i], 0.0, 1.0 );
1050         }
1051     } else {
1052         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1053             cowl_flaps_norm[engine] += amt;
1054             SG_CLAMP_RANGE<double>( cowl_flaps_norm[engine], 0.0, 1.0 );
1055         }
1056     }
1057 }
1058 
1059 void
set_feather(int engine,bool val)1060 FGControls::set_feather( int engine, bool val )
1061 {
1062     if ( engine == ALL_ENGINES ) {
1063         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1064             feather[i] = val;
1065         }
1066     } else {
1067         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1068             feather[engine] = val;
1069         }
1070     }
1071 }
1072 
1073 void
set_ignition(int engine,int pos)1074 FGControls::set_ignition( int engine, int pos )
1075 {
1076     if ( engine == ALL_ENGINES ) {
1077         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1078             ignition[i] = pos;
1079             SG_CLAMP_RANGE<int>( ignition[i], 0, 3 );
1080         }
1081     } else {
1082         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1083             ignition[engine] = pos;
1084             SG_CLAMP_RANGE<int>( ignition[engine], 0, 3 );
1085         }
1086     }
1087 }
1088 
1089 void
set_augmentation(int engine,bool val)1090 FGControls::set_augmentation( int engine, bool val )
1091 {
1092     if ( engine == ALL_ENGINES ) {
1093         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1094             augmentation[i] = val;
1095         }
1096     } else {
1097         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1098             augmentation[engine] = val;
1099         }
1100     }
1101 }
1102 
1103 void
set_reverser(int engine,bool val)1104 FGControls::set_reverser( int engine, bool val )
1105 {
1106     if ( engine == ALL_ENGINES ) {
1107         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1108             reverser[i] = val;
1109         }
1110     } else {
1111         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1112             reverser[engine] = val;
1113         }
1114     }
1115 }
1116 
1117 void
set_water_injection(int engine,bool val)1118 FGControls::set_water_injection( int engine, bool val )
1119 {
1120     if ( engine == ALL_ENGINES ) {
1121         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1122             water_injection[i] = val;
1123         }
1124     } else {
1125         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1126             water_injection[engine] = val;
1127         }
1128     }
1129 }
1130 
1131 void
set_condition(int engine,double val)1132 FGControls::set_condition( int engine, double val )
1133 {
1134     if ( engine == ALL_ENGINES ) {
1135         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1136             condition[i] = val;
1137             SG_CLAMP_RANGE<double>( condition[i], 0.0, 1.0 );
1138         }
1139     } else {
1140         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1141             condition[engine] = val;
1142             SG_CLAMP_RANGE<double>( condition[engine], 0.0, 1.0 );
1143         }
1144     }
1145 }
1146 
1147 void
set_dump_valve(bool val)1148 FGControls::set_dump_valve( bool val )
1149 {
1150     dump_valve = val;
1151 }
1152 
1153 
1154 void
set_fuel_selector(int tank,bool pos)1155 FGControls::set_fuel_selector( int tank, bool pos )
1156 {
1157     if ( tank == ALL_TANKS ) {
1158         for ( int i = 0; i < MAX_TANKS; i++ ) {
1159             fuel_selector[i] = pos;
1160         }
1161     } else {
1162         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1163             fuel_selector[tank] = pos;
1164         }
1165     }
1166 }
1167 
1168 void
set_to_engine(int tank,int engine)1169 FGControls::set_to_engine( int tank, int engine )
1170 {
1171     if ( tank == ALL_TANKS ) {
1172         for ( int i = 0; i < MAX_TANKS; i++ ) {
1173             to_engine[i] = engine;
1174         }
1175     } else {
1176         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1177             to_engine[tank] = engine;
1178         }
1179     }
1180 }
1181 
1182 void
set_to_tank(int tank,int dest_tank)1183 FGControls::set_to_tank( int tank, int dest_tank )
1184 {
1185     if ( tank == ALL_TANKS ) {
1186         for ( int i = 0; i < MAX_TANKS; i++ ) {
1187             to_tank[i] = dest_tank;
1188         }
1189     } else {
1190         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1191             to_tank[tank] = dest_tank;
1192         }
1193     }
1194 }
1195 
1196 void
set_boost_pump(int index,bool val)1197 FGControls::set_boost_pump( int index, bool val )
1198 {
1199     if ( index == -1 ) {
1200         for ( int i = 0; i < (MAX_TANKS * MAX_BOOSTPUMPS); i++ ) {
1201             boost_pump[i] = val;
1202         }
1203     } else {
1204         if ( (index >= 0) && (index < (MAX_TANKS * MAX_BOOSTPUMPS)) ) {
1205             boost_pump[index] = val;
1206         }
1207     }
1208 }
1209 
1210 
1211 void
set_brake_left(double pos)1212 FGControls::set_brake_left( double pos )
1213 {
1214     brake_left = pos;
1215     SG_CLAMP_RANGE<double>(brake_left, 0.0, 1.0);
1216 }
1217 
1218 void
move_brake_left(double amt)1219 FGControls::move_brake_left( double amt )
1220 {
1221     brake_left += amt;
1222     SG_CLAMP_RANGE<double>( brake_left, 0.0, 1.0 );
1223 }
1224 
1225 void
set_brake_right(double pos)1226 FGControls::set_brake_right( double pos )
1227 {
1228     brake_right = pos;
1229     SG_CLAMP_RANGE<double>(brake_right, 0.0, 1.0);
1230 }
1231 
1232 void
move_brake_right(double amt)1233 FGControls::move_brake_right( double amt )
1234 {
1235     brake_right += amt;
1236     SG_CLAMP_RANGE<double>( brake_right, 0.0, 1.0 );
1237 }
1238 
1239 void
set_copilot_brake_left(double pos)1240 FGControls::set_copilot_brake_left( double pos )
1241 {
1242     copilot_brake_left = pos;
1243     SG_CLAMP_RANGE<double>(brake_left, 0.0, 1.0);
1244 }
1245 
1246 void
set_copilot_brake_right(double pos)1247 FGControls::set_copilot_brake_right( double pos )
1248 {
1249     copilot_brake_right = pos;
1250     SG_CLAMP_RANGE<double>(brake_right, 0.0, 1.0);
1251 }
1252 
1253 void
set_brake_parking(double pos)1254 FGControls::set_brake_parking( double pos )
1255 {
1256     brake_parking = pos;
1257     SG_CLAMP_RANGE<double>(brake_parking, 0.0, 1.0);
1258 }
1259 
1260 void
set_steering(double angle)1261 FGControls::set_steering( double angle )
1262 {
1263     steering = angle;
1264     SG_CLAMP_RANGE<double>(steering, -80.0, 80.0);
1265 }
1266 
1267 void
set_nose_wheel_steering(bool nws)1268 FGControls::set_nose_wheel_steering( bool nws )
1269 {
1270     nose_wheel_steering = nws;
1271 }
1272 
1273 void
move_steering(double angle)1274 FGControls::move_steering( double angle )
1275 {
1276     steering += angle;
1277     SG_CLAMP_RANGE<double>(steering, -80.0, 80.0);
1278 }
1279 
1280 void
set_gear_down(bool gear)1281 FGControls::set_gear_down( bool gear )
1282 {
1283     gear_down = gear;
1284 }
1285 
1286 void
set_antiskid(bool state)1287 FGControls::set_antiskid( bool state )
1288 {
1289     antiskid = state;
1290 }
1291 
1292 void
set_tailhook(bool state)1293 FGControls::set_tailhook( bool state )
1294 {
1295     tailhook = state;
1296 }
1297 
1298 void
set_launchbar(bool state)1299 FGControls::set_launchbar( bool state )
1300 {
1301     launchbar = state;
1302 }
1303 
1304 void
set_catapult_launch_cmd(bool state)1305 FGControls::set_catapult_launch_cmd( bool state )
1306 {
1307     catapult_launch_cmd = state;
1308 }
1309 
1310 void
set_tailwheel_lock(bool state)1311 FGControls::set_tailwheel_lock( bool state )
1312 {
1313     tailwheel_lock = state;
1314 }
1315 
1316 
1317 void
set_alternate_extension(int wheel,bool val)1318 FGControls::set_alternate_extension( int wheel, bool val )
1319 {
1320     if ( wheel == ALL_WHEELS ) {
1321         for ( int i = 0; i < MAX_WHEELS; i++ ) {
1322             alternate_extension[i] = val;
1323         }
1324     } else {
1325         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
1326             alternate_extension[wheel] = val;
1327         }
1328     }
1329 }
1330 
1331 void
set_wing_heat(bool state)1332 FGControls::set_wing_heat( bool state )
1333 {
1334     wing_heat = state;
1335 }
1336 
1337 void
set_pitot_heat(bool state)1338 FGControls::set_pitot_heat( bool state )
1339 {
1340     pitot_heat = state;
1341 }
1342 
1343 void
set_wiper(int state)1344 FGControls::set_wiper( int state )
1345 {
1346     wiper = state;
1347 }
1348 
1349 void
set_window_heat(bool state)1350 FGControls::set_window_heat( bool state )
1351 {
1352     window_heat = state;
1353 }
1354 
1355 void
set_carb_heat(int engine,bool val)1356 FGControls::set_carb_heat( int engine, bool val )
1357 {
1358     if ( engine == ALL_ENGINES ) {
1359         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1360             carb_heat[i] = val;
1361         }
1362     } else {
1363         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1364             carb_heat[engine] = val;
1365         }
1366     }
1367 }
1368 
1369 void
set_inlet_heat(int engine,bool val)1370 FGControls::set_inlet_heat( int engine, bool val )
1371 {
1372     if ( engine == ALL_ENGINES ) {
1373         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1374             inlet_heat[i] = val;
1375         }
1376     } else {
1377         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1378             inlet_heat[engine] = val;
1379         }
1380     }
1381 }
1382 
1383 void
set_engine_pump(int system,bool val)1384 FGControls::set_engine_pump( int system, bool val )
1385 {
1386     if ( system == ALL_HYD_SYSTEMS ) {
1387         for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
1388             engine_pump[i] = val;
1389         }
1390     } else {
1391         if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
1392             engine_pump[system] = val;
1393         }
1394     }
1395 }
1396 
1397 void
set_electric_pump(int system,bool val)1398 FGControls::set_electric_pump( int system, bool val )
1399 {
1400     if ( system == ALL_HYD_SYSTEMS ) {
1401         for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
1402             electric_pump[i] = val;
1403         }
1404     } else {
1405         if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
1406             electric_pump[system] = val;
1407         }
1408     }
1409 }
1410 
1411 void
set_battery_switch(bool state)1412 FGControls::set_battery_switch( bool state )
1413 {
1414     battery_switch = state;
1415 }
1416 
1417 void
set_external_power(bool state)1418 FGControls::set_external_power( bool state )
1419 {
1420     external_power = state;
1421 }
1422 
1423 void
set_APU_generator(bool state)1424 FGControls::set_APU_generator( bool state )
1425 {
1426     APU_generator = state;
1427 }
1428 
1429 void
set_generator_breaker(int engine,bool val)1430 FGControls::set_generator_breaker( int engine, bool val )
1431 {
1432     if ( engine == ALL_ENGINES ) {
1433         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1434             generator_breaker[i] = val;
1435         }
1436     } else {
1437         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1438             generator_breaker[engine] = val;
1439         }
1440     }
1441 }
1442 
1443 void
set_bus_tie(int engine,bool val)1444 FGControls::set_bus_tie( int engine, bool val )
1445 {
1446     if ( engine == ALL_ENGINES ) {
1447         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1448             bus_tie[i] = val;
1449         }
1450     } else {
1451         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1452             bus_tie[engine] = val;
1453         }
1454     }
1455 }
1456 
1457 void
set_APU_bleed(bool state)1458 FGControls::set_APU_bleed( bool state )
1459 {
1460     APU_bleed = state;
1461 }
1462 
1463 void
set_engine_bleed(int engine,bool val)1464 FGControls::set_engine_bleed( int engine, bool val )
1465 {
1466     if ( engine == ALL_ENGINES ) {
1467         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1468             engine_bleed[i] = val;
1469         }
1470     } else {
1471         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1472             engine_bleed[engine] = val;
1473         }
1474     }
1475 }
1476 
1477 void
set_mode(int new_mode)1478 FGControls::set_mode( int new_mode )
1479 {
1480     mode = new_mode;
1481 }
1482 
1483 void
set_outflow_valve(double pos)1484 FGControls::set_outflow_valve( double pos )
1485 {
1486     outflow_valve = pos;
1487     SG_CLAMP_RANGE<double>( outflow_valve, 0.0, 1.0 );
1488 }
1489 
1490 void
move_outflow_valve(double amt)1491 FGControls::move_outflow_valve( double amt )
1492 {
1493     outflow_valve += amt;
1494     SG_CLAMP_RANGE<double>( outflow_valve, 0.0, 1.0 );
1495 }
1496 
1497 void
set_dump(bool state)1498 FGControls::set_dump( bool state )
1499 {
1500     dump = state;
1501 }
1502 
1503 void
set_pack_on(int pack,bool val)1504 FGControls::set_pack_on( int pack, bool val )
1505 {
1506     if ( pack == ALL_PACKS ) {
1507         for ( int i = 0; i < MAX_PACKS; i++ ) {
1508             pack_on[i] = val;
1509         }
1510     } else {
1511         if ( (pack >= 0) && (pack < MAX_PACKS) ) {
1512             pack_on[pack] = val;
1513         }
1514     }
1515 }
1516 
1517 void
set_landing_lights(bool state)1518 FGControls::set_landing_lights( bool state )
1519 {
1520     landing_lights = state;
1521 }
1522 
1523 void
set_turn_off_lights(bool state)1524 FGControls::set_turn_off_lights( bool state )
1525 {
1526     turn_off_lights = state;
1527 }
1528 
1529 void
set_taxi_light(bool state)1530 FGControls::set_taxi_light( bool state )
1531 {
1532     taxi_light = state;
1533 }
1534 
1535 void
set_logo_lights(bool state)1536 FGControls::set_logo_lights( bool state )
1537 {
1538     logo_lights = state;
1539 }
1540 
1541 void
set_nav_lights(bool state)1542 FGControls::set_nav_lights( bool state )
1543 {
1544     nav_lights = state;
1545 }
1546 
1547 void
set_beacon(bool state)1548 FGControls::set_beacon( bool state )
1549 {
1550     beacon = state;
1551 }
1552 
1553 void
set_strobe(bool state)1554 FGControls::set_strobe( bool state )
1555 {
1556     strobe = state;
1557 }
1558 
1559 void
set_panel_norm(double intensity)1560 FGControls::set_panel_norm( double intensity )
1561 {
1562     panel_norm = intensity;
1563     SG_CLAMP_RANGE<double>( panel_norm, 0.0, 1.0 );
1564 }
1565 
1566 void
move_panel_norm(double amt)1567 FGControls::move_panel_norm( double amt )
1568 {
1569     panel_norm += amt;
1570     SG_CLAMP_RANGE<double>( panel_norm, 0.0, 1.0 );
1571 }
1572 
1573 void
set_instruments_norm(double intensity)1574 FGControls::set_instruments_norm( double intensity )
1575 {
1576     instruments_norm = intensity;
1577     SG_CLAMP_RANGE<double>( instruments_norm, 0.0, 1.0 );
1578 }
1579 
1580 void
move_instruments_norm(double amt)1581 FGControls::move_instruments_norm( double amt )
1582 {
1583     instruments_norm += amt;
1584     SG_CLAMP_RANGE<double>( instruments_norm, 0.0, 1.0 );
1585 }
1586 
1587 void
set_dome_norm(double intensity)1588 FGControls::set_dome_norm( double intensity )
1589 {
1590     dome_norm = intensity;
1591     SG_CLAMP_RANGE<double>( dome_norm, 0.0, 1.0 );
1592 }
1593 
1594 void
move_dome_norm(double amt)1595 FGControls::move_dome_norm( double amt )
1596 {
1597     dome_norm += amt;
1598     SG_CLAMP_RANGE<double>( dome_norm, 0.0, 1.0 );
1599 }
1600 
1601 void
set_master_arm(bool val)1602 FGControls::set_master_arm( bool val )
1603 {
1604     master_arm = val;
1605 }
1606 
1607 void
set_station_select(int station)1608 FGControls::set_station_select( int station )
1609 {
1610     station_select = station;
1611     SG_CLAMP_RANGE<int>( station_select, 0, MAX_STATIONS );
1612 }
1613 
1614 void
set_release_ALL(bool val)1615 FGControls::set_release_ALL( bool val )
1616 {
1617     release_ALL = val;
1618 }
1619 
1620 void
set_stick_size(int station,int size)1621 FGControls::set_stick_size( int station, int size )
1622 {
1623     if ( station == ALL_STATIONS ) {
1624         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1625             stick_size[i] = size;
1626             SG_CLAMP_RANGE<int>( stick_size[i], 1, 20 );
1627         }
1628     } else {
1629         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1630             stick_size[station] = size;
1631             SG_CLAMP_RANGE<int>( stick_size[station], 1, 20 );
1632         }
1633     }
1634 }
1635 
1636 void
set_release_stick(int station,bool val)1637 FGControls::set_release_stick( int station, bool val )
1638 {
1639     if ( station == ALL_STATIONS ) {
1640         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1641             release_stick[i] = val;
1642         }
1643     } else {
1644         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1645             release_stick[station] = val;
1646         }
1647     }
1648 }
1649 
1650 void
set_release_all(int station,bool val)1651 FGControls::set_release_all( int station, bool val )
1652 {
1653     if ( station == ALL_STATIONS ) {
1654         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1655             release_all[i] = val;
1656         }
1657     } else {
1658         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1659             release_all[station] = val;
1660         }
1661     }
1662 }
1663 
1664 void
set_jettison_all(int station,bool val)1665 FGControls::set_jettison_all( int station, bool val )
1666 {
1667     if ( station == ALL_STATIONS ) {
1668         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1669             jettison_all[i] = val;
1670         }
1671     } else {
1672         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1673             jettison_all[station] = val;
1674         }
1675     }
1676 }
1677 
1678 void
set_vertical_adjust(double pos)1679 FGControls::set_vertical_adjust( double pos )
1680 {
1681     vertical_adjust = pos;
1682     SG_CLAMP_RANGE<double>( vertical_adjust, -1.0, 1.0 );
1683 }
1684 
1685 void
move_vertical_adjust(double amt)1686 FGControls::move_vertical_adjust( double amt )
1687 {
1688     vertical_adjust += amt;
1689     SG_CLAMP_RANGE<double>( vertical_adjust, -1.0, 1.0 );
1690 }
1691 
1692 void
set_fore_aft_adjust(double pos)1693 FGControls::set_fore_aft_adjust( double pos )
1694 {
1695     fore_aft_adjust = pos;
1696     SG_CLAMP_RANGE<double>( fore_aft_adjust, -1.0, 1.0 );
1697 }
1698 
1699 void
move_fore_aft_adjust(double amt)1700 FGControls::move_fore_aft_adjust( double amt )
1701 {
1702     fore_aft_adjust += amt;
1703     SG_CLAMP_RANGE<double>( fore_aft_adjust, -1.0, 1.0 );
1704 }
1705 
1706 void
set_ejection_seat(int which_seat,bool val)1707 FGControls::set_ejection_seat( int which_seat, bool val )
1708 {
1709     if ( which_seat == ALL_EJECTION_SEATS ) {
1710         for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
1711             eject[i] = val;
1712         }
1713     } else {
1714         if ( (which_seat >= 0) && (which_seat < MAX_EJECTION_SEATS) ) {
1715             if ( eseat_status[which_seat] == SEAT_SAFED ||
1716                 eseat_status[which_seat] == SEAT_FAIL )
1717             {
1718                 // we can never eject if SEAT_SAFED or SEAT_FAIL
1719                 val = false;
1720             }
1721 
1722             eject[which_seat] = val;
1723         }
1724     }
1725 }
1726 
1727 void
set_eseat_status(int which_seat,int val)1728 FGControls::set_eseat_status( int which_seat, int val )
1729 {
1730     if ( which_seat == ALL_EJECTION_SEATS ) {
1731         for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
1732             eseat_status[i] = val;
1733         }
1734     } else {
1735         if ( (which_seat >=0) && (which_seat < MAX_EJECTION_SEATS) ) {
1736             eseat_status[which_seat] = val;
1737         }
1738     }
1739 }
1740 
1741 void
set_cmd_selector_valve(int val)1742 FGControls::set_cmd_selector_valve( int val )
1743 {
1744     cmd_selector_valve = val;
1745 }
1746 
1747 
1748 void
set_off_start_run(int pos)1749 FGControls::set_off_start_run( int pos )
1750 {
1751     off_start_run = pos;
1752     SG_CLAMP_RANGE<int>( off_start_run, 0, 3 );
1753 }
1754 
1755 void
set_APU_fire_switch(bool val)1756 FGControls::set_APU_fire_switch( bool val )
1757 {
1758     APU_fire_switch = val;
1759 }
1760 
1761 void
set_autothrottle_arm(bool val)1762 FGControls::set_autothrottle_arm( bool val )
1763 {
1764     autothrottle_arm = val;
1765 }
1766 
1767 void
set_autothrottle_engage(bool val)1768 FGControls::set_autothrottle_engage( bool val )
1769 {
1770     autothrottle_engage = val;
1771 }
1772 
1773 void
set_heading_select(double heading)1774 FGControls::set_heading_select( double heading )
1775 {
1776     heading_select = heading;
1777     SG_CLAMP_RANGE<double>( heading_select, 0.0, 360.0 );
1778 }
1779 
1780 void
move_heading_select(double amt)1781 FGControls::move_heading_select( double amt )
1782 {
1783     heading_select += amt;
1784     SG_CLAMP_RANGE<double>( heading_select, 0.0, 360.0 );
1785 }
1786 
1787 void
set_altitude_select(double altitude)1788 FGControls::set_altitude_select( double altitude )
1789 {
1790     altitude_select = altitude;
1791     SG_CLAMP_RANGE<double>( altitude_select, -1000.0, 100000.0 );
1792 }
1793 
1794 void
move_altitude_select(double amt)1795 FGControls::move_altitude_select( double amt )
1796 {
1797     altitude_select += amt;
1798     SG_CLAMP_RANGE<double>( altitude_select, -1000.0, 100000.0 );
1799 }
1800 
1801 void
set_bank_angle_select(double angle)1802 FGControls::set_bank_angle_select( double angle )
1803 {
1804     bank_angle_select = angle;
1805     SG_CLAMP_RANGE<double>( bank_angle_select, 10.0, 30.0 );
1806 }
1807 
1808 void
move_bank_angle_select(double amt)1809 FGControls::move_bank_angle_select( double amt )
1810 {
1811     bank_angle_select += amt;
1812     SG_CLAMP_RANGE<double>( bank_angle_select, 10.0, 30.0 );
1813 }
1814 
1815 void
set_vertical_speed_select(double speed)1816 FGControls::set_vertical_speed_select( double speed )
1817 {
1818     vertical_speed_select = speed;
1819     SG_CLAMP_RANGE<double>( vertical_speed_select, -3000.0, 4000.0 );
1820 }
1821 
1822 void
move_vertical_speed_select(double amt)1823 FGControls::move_vertical_speed_select( double amt )
1824 {
1825     vertical_speed_select += amt;
1826     SG_CLAMP_RANGE<double>( vertical_speed_select, -3000.0, 4000.0 );
1827 }
1828 
1829 void
set_speed_select(double speed)1830 FGControls::set_speed_select( double speed )
1831 {
1832     speed_select = speed;
1833     SG_CLAMP_RANGE<double>( speed_select, 60.0, 400.0 );
1834 }
1835 
1836 void
move_speed_select(double amt)1837 FGControls::move_speed_select( double amt )
1838 {
1839     speed_select += amt;
1840     SG_CLAMP_RANGE<double>( speed_select, 60.0, 400.0 );
1841 }
1842 
1843 void
set_mach_select(double mach)1844 FGControls::set_mach_select( double mach )
1845 {
1846     mach_select = mach;
1847     SG_CLAMP_RANGE<double>( mach_select, 0.4, 4.0 );
1848 }
1849 
1850 void
move_mach_select(double amt)1851 FGControls::move_mach_select( double amt )
1852 {
1853     mach_select += amt;
1854     SG_CLAMP_RANGE<double>( mach_select, 0.4, 4.0 );
1855 }
1856 
1857 void
set_vertical_mode(int mode)1858 FGControls::set_vertical_mode( int mode )
1859 {
1860     vertical_mode = mode;
1861     SG_CLAMP_RANGE<int>( vertical_mode, 0, 4 );
1862 }
1863 
1864 void
set_lateral_mode(int mode)1865 FGControls::set_lateral_mode( int mode )
1866 {
1867     lateral_mode = mode;
1868     SG_CLAMP_RANGE<int>( lateral_mode, 0, 4 );
1869 }
1870 
1871 void
set_autopilot_engage(int ap,bool val)1872 FGControls::set_autopilot_engage( int ap, bool val )
1873 {
1874     if ( ap == ALL_AUTOPILOTS ) {
1875         for ( int i = 0; i < MAX_AUTOPILOTS; i++ ) {
1876             autopilot_engage[i] = val;
1877         }
1878     } else {
1879         if ( (ap >= 0) && (ap < MAX_AUTOPILOTS) ) {
1880             autopilot_engage[ap] = val;
1881         }
1882     }
1883 }
1884 
1885 // Register the subsystem.
1886 SGSubsystemMgr::Registrant<FGControls> registrantFGControls;
1887