1 // sp_panel.cxx - default, 2D single-engine prop instrument panel
3 // Written by David Megginson, started January 2000.
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <simgear/debug/logstream.hxx>
30 #include <Main/bfi.hxx>
31 #include <Time/fg_time.hxx>
36 // Macros for instrument sizes
37 // (these aren't used consistently
38 // anyway, and should probably be
43 #define SIX_SPACING (SIX_W + 5)
48 ////////////////////////////////////////////////////////////////////////
49 // Static functions for obtaining settings.
50 ////////////////////////////////////////////////////////////////////////
52 static char * panelGetTime ()
54 static char buf[1024]; // FIXME: not thread-safe
55 struct tm * t = FGTime::cur_time_params->getGmt();
56 sprintf(buf, " %.2d:%.2d:%.2d",
57 t->tm_hour, t->tm_min, t->tm_sec);
63 ////////////////////////////////////////////////////////////////////////
64 // Static factory functions to create textured gauges.
66 // These will be replaced first with a giant table, and then with
67 // configuration files read from an external source, but for now
68 // they're hard-coded.
69 ////////////////////////////////////////////////////////////////////////
72 #define createTexture(a) FGTextureManager::createTexture(a)
75 * Construct an airspeed indicator for a single-engine prop.
77 static FGPanelInstrument *
78 createAirspeedIndicator (int x, int y)
80 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
82 // Layer 0: gauge background.
83 inst->addLayer(createTexture("Textures/Panel/airspeed.rgb"));
86 // Rotates with airspeed.
87 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
88 inst->addTransformation(FGInstrumentLayer::ROTATION,
89 FGSteam::get_ASI_kias,
90 30.0, 220.0, 36.0 / 20.0, -54.0);
96 * Construct an artificial horizon.
98 static FGPanelInstrument *
99 createHorizon (int x, int y)
101 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
103 // Layer 0: coloured background
104 // moves with roll only
105 inst->addLayer(createTexture("Textures/Panel/horizon-bg.rgb"));
106 inst->addTransformation(FGInstrumentLayer::ROTATION,
108 -360.0, 360.0, -1.0, 0.0);
110 // Layer 1: floating horizon
111 // moves with roll and pitch
112 inst->addLayer(createTexture("Textures/Panel/horizon-float.rgb"));
113 inst->addTransformation(FGInstrumentLayer::ROTATION,
115 -360.0, 360.0, -1.0, 0.0);
116 inst->addTransformation(FGInstrumentLayer::YSHIFT,
118 -20.0, 20.0, -(1.5 / 160.0) * SIX_W, 0.0);
121 // moves with roll only
122 inst->addLayer(createTexture("Textures/Panel/horizon-rim.rgb"));
123 inst->addTransformation(FGInstrumentLayer::ROTATION,
125 -360.0, 360.0, -1.0, 0.0);
127 // Layer 3: glass front of gauge
128 // fixed, with markings
129 inst->addLayer(createTexture("Textures/Panel/horizon-fg.rgb"));
136 * Construct an altimeter.
138 static FGPanelInstrument *
139 createAltimeter (int x, int y)
141 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
143 // Layer 0: gauge background
144 inst->addLayer(createTexture("Textures/Panel/altimeter.rgb"));
146 // Layer 1: hundreds needle (long)
147 // moves with altitude
148 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
149 inst->addTransformation(FGInstrumentLayer::ROTATION,
151 0.0, 100000.0, 360.0 / 1000.0, 0.0);
153 // Layer 2: thousands needle (short)
154 // moves with altitude
155 inst->addLayer(createTexture("Textures/Panel/short-needle.rgb"));
156 inst->addTransformation(FGInstrumentLayer::ROTATION,
158 0.0, 100000.0, 360.0 / 10000.0, 0.0);
160 // Layer 3: ten thousands bug (outside)
161 // moves with altitude
162 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
163 inst->addTransformation(FGInstrumentLayer::ROTATION,
165 0.0, 100000.0, 360.0 / 100000.0, 0.0);
172 * Construct a turn coordinator.
174 static FGPanelInstrument *
175 createTurnCoordinator (int x, int y)
177 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
179 // Layer 0: background
180 inst->addLayer(createTexture("Textures/Panel/turn-bg.rgb"));
182 // Layer 1: little plane
184 inst->addLayer(createTexture("Textures/Panel/turn.rgb"));
185 inst->addTransformation(FGInstrumentLayer::ROTATION,
187 -2.5, 2.5, 20.0, 0.0);
189 // Layer 2: little ball
190 // moves with slip/skid
191 inst->addLayer(createTexture("Textures/Panel/ball.rgb"));
192 inst->addTransformation(FGInstrumentLayer::ROTATION,
194 -0.1, 0.1, -450.0, 0.0);
201 * Construct a gyro compass.
203 static FGPanelInstrument *
204 createGyroCompass (int x, int y)
206 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
208 // Action: move heading bug
209 inst->addAction(0, SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
210 new FGAdjustAction(FGBFI::getAPHeading,
212 -1.0, -360.0, 360.0, true));
213 inst->addAction(0, SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
214 new FGAdjustAction(FGBFI::getAPHeading,
216 1.0, -360.0, 360.0, true));
217 inst->addAction(1, SIX_W/2 - SIX_W/5, -SIX_W/2, SIX_W/10, SIX_W/5,
218 new FGAdjustAction(FGBFI::getAPHeading,
220 -5.0, -360.0, 360.0, true));
221 inst->addAction(1, SIX_W/2 - SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
222 new FGAdjustAction(FGBFI::getAPHeading,
224 5.0, -360.0, 360.0, true));
226 // Layer 0: compass background
227 // rotates with heading
228 inst->addLayer(createTexture("Textures/Panel/gyro-bg.rgb"));
229 inst->addTransformation(FGInstrumentLayer::ROTATION,
231 -720.0, 720.0, -1.0, 0.0);
233 // Layer 1: heading bug
234 // rotates with heading and AP heading
235 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
236 inst->addTransformation(FGInstrumentLayer::ROTATION,
238 -720.0, 720.0, -1.0, 0.0);
239 inst->addTransformation(FGInstrumentLayer::ROTATION,
241 -720.0, 720.0, 1.0, 0.0);
243 // Layer 2: fixed center
244 inst->addLayer(createTexture("Textures/Panel/gyro-fg.rgb"));
246 // Layer 3: heading knob
247 // rotates with AP heading
248 inst->addLayer(new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
249 SIX_W/4, SIX_W/4, 0.0, 0.25, 0.25, 0.5));
250 inst->addTransformation(FGInstrumentLayer::XSHIFT, SIX_W/2 - 10);
251 inst->addTransformation(FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
252 inst->addTransformation(FGInstrumentLayer::ROTATION,
254 -360.0, 360.0, 1.0, 0.0);
261 * Construct a vertical velocity indicator.
263 static FGPanelInstrument *
264 createVerticalVelocity (int x, int y)
266 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
268 // Layer 0: gauge background
269 inst->addLayer(createTexture("Textures/Panel/vertical.rgb"));
272 // moves with vertical velocity
273 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
274 inst->addTransformation(FGInstrumentLayer::ROTATION,
275 FGSteam::get_VSI_fps,
276 -2000.0, 2000.0, 42.0/500.0, 270.0);
283 * Construct an RPM gauge.
285 static FGPanelInstrument *
286 createRPMGauge (int x, int y)
288 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SMALL_W, SMALL_W);
290 // Layer 0: gauge background
291 inst->addLayer(createTexture("Textures/Panel/rpm.rgb"));
293 // Layer 1: long needle
294 // FIXME: moves with throttle (for now)
295 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
296 inst->addTransformation(FGInstrumentLayer::ROTATION,
298 0.0, 100.0, 300.0, -150.0);
305 * Construct a flap position indicator.
307 static FGPanelInstrument *
308 createFlapIndicator (int x, int y)
310 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SMALL_W, SMALL_W);
312 // Layer 0: gauge background
313 inst->addLayer(createTexture("Textures/Panel/flaps.rgb"));
315 // Layer 1: long needle
316 // shifted over, rotates with flap position
317 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
318 inst->addTransformation(FGInstrumentLayer::XSHIFT,
319 -(SMALL_W / 4) + (SMALL_W / 16));
320 inst->addTransformation(FGInstrumentLayer::ROTATION,
322 0.0, 1.0, 120.0, 30.0);
327 static FGPanelInstrument *
328 createChronometer (int x, int y)
330 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SMALL_W, SMALL_W);
332 // Layer 0: gauge background
333 inst->addLayer(createTexture("Textures/Panel/clock.rgb"));
336 // displays current GMT
337 FGTextLayer * text = new FGTextLayer(SMALL_W, SMALL_W);
338 text->addChunk(new FGTextLayer::Chunk(panelGetTime));
339 text->setPointSize(14);
340 text->setColor(0.2, 0.2, 0.2);
341 inst->addLayer(text);
342 inst->addTransformation(FGInstrumentLayer::XSHIFT, SMALL_W * -0.38);
343 inst->addTransformation(FGInstrumentLayer::YSHIFT, SMALL_W * -0.06);
350 * Construct control-position indicators.
352 static FGPanelInstrument *
353 createControls (int x, int y)
355 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SMALL_W, SMALL_W);
357 // Layer 0: gauge background
358 inst->addLayer(createTexture("Textures/Panel/controls.rgb"));
361 // moves left-right with aileron
362 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
363 inst->addTransformation(FGInstrumentLayer::XSHIFT, FGBFI::getAileron,
364 -1.0, 1.0, SMALL_W * .75 / 2.0, 0.0);
367 // moves left-right with rudder
368 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
369 inst->addTransformation(FGInstrumentLayer::ROTATION, 180.0);
370 inst->addTransformation(FGInstrumentLayer::XSHIFT, FGBFI::getRudder,
371 -1.0, 1.0, -SMALL_W * .75 / 2.0, 0.0);
374 // moves up-down with elevator trim
375 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
376 inst->addTransformation(FGInstrumentLayer::ROTATION, 270.0);
377 inst->addTransformation(FGInstrumentLayer::YSHIFT,
378 -SMALL_W * (3.0 / 8.0));
379 inst->addTransformation(FGInstrumentLayer::XSHIFT, FGBFI::getElevatorTrim,
380 -1.0, 1.0, SMALL_W * .75 / 2.0, 0.0);
383 // moves up-down with elevator
384 inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
385 inst->addTransformation(FGInstrumentLayer::ROTATION, 90.0);
386 inst->addTransformation(FGInstrumentLayer::YSHIFT,
387 -SMALL_W * (3.0 / 8.0));
388 inst->addTransformation(FGInstrumentLayer::XSHIFT, FGBFI::getElevator,
389 -1.0, 1.0, -SMALL_W * .75 / 2.0, 0.0);
396 * Construct a NAV1 gauge (hardwired).
398 static FGPanelInstrument *
399 createNAV1 (int x, int y)
401 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
403 // Action: change selected radial.
404 inst->addAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
405 new FGAdjustAction(FGBFI::getNAV1SelRadial,
406 FGBFI::setNAV1SelRadial,
407 1.0, 0.0, 360.0, true));
408 inst->addAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
409 new FGAdjustAction(FGBFI::getNAV1SelRadial,
410 FGBFI::setNAV1SelRadial,
411 -1.0, 0.0, 360.0, true));
412 inst->addAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
413 new FGAdjustAction(FGBFI::getNAV1SelRadial,
414 FGBFI::setNAV1SelRadial,
415 5.0, 0.0, 360.0, true));
416 inst->addAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
417 new FGAdjustAction(FGBFI::getNAV1SelRadial,
418 FGBFI::setNAV1SelRadial,
419 -5.0, 0.0, 360.0, true));
421 // Layer 0: background
422 inst->addLayer(createTexture("Textures/Panel/gyro-bg.rgb"));
423 inst->addTransformation(FGInstrumentLayer::ROTATION,
424 FGBFI::getNAV1SelRadial,
425 -360.0, 360.0, -1.0, 0.0);
427 // Layer 1: left-right needle.
428 inst->addLayer(createTexture("Textures/Panel/nav-needle.rgb"));
429 inst->addTransformation(FGInstrumentLayer::XSHIFT,
430 FGSteam::get_HackVOR1_deg,
431 -10.0, 10.0, SIX_W / 40.0, 0.0);
433 // Layer 2: glidescope needle
434 inst->addLayer(createTexture("Textures/Panel/nav-needle.rgb"));
435 inst->addTransformation(FGInstrumentLayer::YSHIFT,
436 FGSteam::get_HackGS_deg,
437 -1.0, 1.0, SIX_W / 5.0, 0.0);
438 inst->addTransformation(FGInstrumentLayer::ROTATION,
441 // Layer 3: face with markings
442 inst->addLayer(createTexture("Textures/Panel/nav-face.rgb"));
444 // Layer 4: heading knob
445 // rotates with selected radial
446 FGTexturedLayer * layer =
447 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
448 SIX_W/4, SIX_W/4, 0.0, 0.5, 0.25, 0.75);
449 inst->addLayer(layer);
450 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W/2 + 10);
451 inst->addTransformation(FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
452 inst->addTransformation(FGInstrumentLayer::ROTATION,
453 FGBFI::getNAV1SelRadial,
454 -360.0, 360.0, 1.0, 0.0);
461 * Construct a NAV2 gauge.
463 static FGPanelInstrument *
464 createNAV2 (int x, int y)
466 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
468 // Action: change selected radial.
469 inst->addAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
470 new FGAdjustAction(FGBFI::getNAV2SelRadial,
471 FGBFI::setNAV2SelRadial,
472 1.0, 0.0, 360.0, true));
473 inst->addAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
474 new FGAdjustAction(FGBFI::getNAV2SelRadial,
475 FGBFI::setNAV2SelRadial,
476 -1.0, 0.0, 360.0, true));
477 inst->addAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
478 new FGAdjustAction(FGBFI::getNAV2SelRadial,
479 FGBFI::setNAV2SelRadial,
480 5.0, 0.0, 360.0, true));
481 inst->addAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
482 new FGAdjustAction(FGBFI::getNAV2SelRadial,
483 FGBFI::setNAV2SelRadial,
484 -5.0, 0.0, 360.0, true));
486 // Layer 0: background
487 inst->addLayer(createTexture("Textures/Panel/gyro-bg.rgb"));
488 inst->addTransformation(FGInstrumentLayer::ROTATION,
489 FGBFI::getNAV2SelRadial,
490 -360.0, 360.0, -1.0, 0.0);
492 // Layer 1: left-right needle.
493 inst->addLayer(createTexture("Textures/Panel/nav-needle.rgb"));
494 inst->addTransformation(FGInstrumentLayer::XSHIFT,
495 FGSteam::get_HackVOR2_deg,
496 -10.0, 10.0, SIX_W / 40.0, 0.0);
497 // inst->addTransformation(FGInstrumentLayer::YSHIFT,
500 // Layer 2: face with markings.
501 inst->addLayer(createTexture("Textures/Panel/nav-face.rgb"));
503 // Layer 3: heading knob
504 // rotates with selected radial
505 FGTexturedLayer * layer =
506 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
507 SIX_W/4, SIX_W/4, 0.0, 0.5, 0.25, 0.75);
508 inst->addLayer(layer);
509 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W/2 + 10);
510 inst->addTransformation(FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
511 inst->addTransformation(FGInstrumentLayer::ROTATION,
512 FGBFI::getNAV2SelRadial,
513 -360.0, 360.0, 1.0, 0.0);
520 * Construct an ADF gauge.
522 static FGPanelInstrument *
523 createADF (int x, int y)
525 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W, SIX_W);
527 // Action: change selected rotation.
528 inst->addAction(0, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
529 new FGAdjustAction(FGBFI::getADFRotation,
530 FGBFI::setADFRotation,
531 -1.0, 0.0, 360.0, true));
532 inst->addAction(0, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
533 new FGAdjustAction(FGBFI::getADFRotation,
534 FGBFI::setADFRotation,
535 1.0, 0.0, 360.0, true));
536 inst->addAction(1, -SIX_W/2, -SIX_W/2, SIX_W/10, SIX_W/5,
537 new FGAdjustAction(FGBFI::getADFRotation,
538 FGBFI::setADFRotation,
539 -5.0, 0.0, 360.0, true));
540 inst->addAction(1, -SIX_W/2 + SIX_W/10, -SIX_W/2, SIX_W/10, SIX_W/5,
541 new FGAdjustAction(FGBFI::getADFRotation,
542 FGBFI::setADFRotation,
543 5.0, 0.0, 360.0, true));
545 // Layer 0: background
546 inst->addLayer(createTexture("Textures/Panel/gyro-bg.rgb"));
547 inst->addTransformation(FGInstrumentLayer::ROTATION,
548 FGBFI::getADFRotation,
549 0.0, 360.0, 1.0, 0.0);
551 // Layer 1: Direction needle.
552 inst->addLayer(createTexture("Textures/Panel/long-needle.rgb"));
553 inst->addTransformation(FGInstrumentLayer::ROTATION,
554 FGSteam::get_HackADF_deg,
555 -720.0, 720.0, 1.0, 0.0);
557 // Layer 2: heading knob
558 // rotates with selected radial
559 FGTexturedLayer * layer =
560 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
561 SIX_W/4, SIX_W/4, 0.0, 0.75, 0.25, 1.0);
562 inst->addLayer(layer);
563 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W/2 + 10);
564 inst->addTransformation(FGInstrumentLayer::YSHIFT, -SIX_W/2 + 10);
565 inst->addTransformation(FGInstrumentLayer::ROTATION,
566 FGBFI::getADFRotation,
567 -360.0, 360.0, -1.0, 0.0);
573 * Create Nav-Com radio 1.
575 static FGPanelInstrument *
576 createNavCom1 (int x, int y)
578 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
580 // Use the button to swap standby and active
582 inst->addAction(0, SIX_W * .375, -SIX_W/4, SIX_W/4, SIX_W/4,
583 new FGSwapAction(FGBFI::getNAV1Freq,
585 FGBFI::getNAV1AltFreq,
586 FGBFI::setNAV1AltFreq));
588 // Use the knob to tune the standby NAV
589 inst->addAction(0, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
590 new FGAdjustAction(FGBFI::getNAV1AltFreq,
591 FGBFI::setNAV1AltFreq,
592 -0.05, 108.0, 117.95, true));
593 inst->addAction(0, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
594 new FGAdjustAction(FGBFI::getNAV1AltFreq,
595 FGBFI::setNAV1AltFreq,
596 0.05, 108.0, 117.95, true));
597 inst->addAction(1, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
598 new FGAdjustAction(FGBFI::getNAV1AltFreq,
599 FGBFI::setNAV1AltFreq,
600 -0.5, 108.0, 117.95, true));
601 inst->addAction(1, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
602 new FGAdjustAction(FGBFI::getNAV1AltFreq,
603 FGBFI::setNAV1AltFreq,
604 0.5, 108.0, 117.95, true));
606 // Layer 0: background
607 FGTexturedLayer * layer =
608 new FGTexturedLayer(createTexture("Textures/Panel/radios.rgb"),
609 SIX_W*2, SIX_W/2, 0.0, 0.75, 1.0, 1.0);
610 inst->addLayer(layer);
612 // Layer 1: NAV frequencies
613 FGTextLayer * text = new FGTextLayer(SIX_W*2, SMALL_W/2);
614 text->addChunk(new FGTextLayer::Chunk(FGBFI::getNAV1Freq, "%.2f"));
615 text->addChunk(new FGTextLayer::Chunk(FGBFI::getNAV1AltFreq, "%7.2f"));
616 text->setPointSize(14);
617 text->setColor(1.0, 0.5, 0.0);
618 inst->addLayer(text);
619 inst->addTransformation(FGInstrumentLayer::XSHIFT, 3);
620 inst->addTransformation(FGInstrumentLayer::YSHIFT, 5);
627 * Create Nav-Com radio 2.
629 static FGPanelInstrument *
630 createNavCom2 (int x, int y)
632 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
634 // Use the button to swap standby and active
636 inst->addAction(0, SIX_W * .375, -SIX_W/4, SIX_W/4, SIX_W/4,
637 new FGSwapAction(FGBFI::getNAV2Freq,
639 FGBFI::getNAV2AltFreq,
640 FGBFI::setNAV2AltFreq));
642 // Use the knob to tune the standby NAV
643 inst->addAction(0, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
644 new FGAdjustAction(FGBFI::getNAV2AltFreq,
645 FGBFI::setNAV2AltFreq,
646 -0.05, 108.0, 117.95, true));
647 inst->addAction(0, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
648 new FGAdjustAction(FGBFI::getNAV2AltFreq,
649 FGBFI::setNAV2AltFreq,
650 0.05, 108.0, 117.95, true));
651 inst->addAction(1, SIX_W-SIX_W/4, -SIX_W/4, SIX_W/8, SIX_W/4,
652 new FGAdjustAction(FGBFI::getNAV2AltFreq,
653 FGBFI::setNAV2AltFreq,
654 -0.5, 108.0, 117.95, true));
655 inst->addAction(1, SIX_W-SIX_W/8, -SIX_W/4, SIX_W/8, SIX_W/4,
656 new FGAdjustAction(FGBFI::getNAV2AltFreq,
657 FGBFI::setNAV2AltFreq,
658 0.5, 108.0, 117.95, true));
660 // Layer 0: background
661 FGTexturedLayer * layer =
662 new FGTexturedLayer(createTexture("Textures/Panel/radios.rgb"),
663 SIX_W*2, SIX_W/2, 0.0, 0.75, 1.0, 1.0);
664 inst->addLayer(layer);
666 // Layer 1: NAV frequencies
667 FGTextLayer * text = new FGTextLayer(SIX_W*2, SIX_W/2);
668 text->addChunk(new FGTextLayer::Chunk(FGBFI::getNAV2Freq, "%.2f"));
669 text->addChunk(new FGTextLayer::Chunk(FGBFI::getNAV2AltFreq, "%7.2f"));
670 text->setPointSize(14);
671 text->setColor(1.0, 0.5, 0.0);
672 inst->addLayer(text);
673 inst->addTransformation(FGInstrumentLayer::XSHIFT, 3);
674 inst->addTransformation(FGInstrumentLayer::YSHIFT, 5);
683 static FGPanelInstrument *
684 createADFRadio (int x, int y)
686 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/2);
688 // Use the knob to tune the standby NAV
689 inst->addAction(0, SIX_W * 0.7, -SIX_W * 0.07, SIX_W * 0.09, SIX_W * 0.14,
690 new FGAdjustAction(FGBFI::getADFFreq,
692 -1.0, 100.0, 1299, true));
693 inst->addAction(0, SIX_W * 0.79, -SIX_W * 0.07, SIX_W * 0.09, SIX_W * 0.14,
694 new FGAdjustAction(FGBFI::getADFFreq,
696 1.0, 100.0, 1299, true));
697 inst->addAction(1, SIX_W * 0.7, -SIX_W * 0.07, SIX_W * 0.09, SIX_W * 0.14,
698 new FGAdjustAction(FGBFI::getADFFreq,
700 -25.0, 100.0, 1299, true));
701 inst->addAction(1, SIX_W * 0.79, -SIX_W * 0.07, SIX_W * 0.09, SIX_W * 0.14,
702 new FGAdjustAction(FGBFI::getADFFreq,
704 25.0, 100.0, 1299, true));
706 // Layer 0: background
707 FGTexturedLayer * layer =
708 new FGTexturedLayer(createTexture("Textures/Panel/radios.rgb"),
709 SIX_W*2, SIX_W/2, 0.0, 0.5, 1.0, 0.75);
710 inst->addLayer(layer);
712 // Layer: ADF frequency
713 FGTextLayer * text = new FGTextLayer(SIX_W*2, SIX_W/2);
714 text->addChunk(new FGTextLayer::Chunk(FGBFI::getADFFreq, "%4.0f"));
715 text->setPointSize(14);
716 text->setColor(1.0, 0.5, 0.0);
717 inst->addLayer(text);
718 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W + 18);
725 * Construct the autopilot.
729 createAP (int x, int y)
731 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y, SIX_W*2, SIX_W/4);
733 // Action: select HDG button
734 inst->addAction(0, -SIX_W*0.6125, -SIX_W/16, SIX_W/4, SIX_W/8,
735 new FGToggleAction(FGBFI::getAPHeadingLock,
736 FGBFI::setAPHeadingLock));
738 // Action: select NAV button
739 inst->addAction(0, -SIX_W*0.3625, -SIX_W/16, SIX_W/4, SIX_W/8,
740 new FGToggleAction(FGBFI::getAPNAV1Lock,
741 FGBFI::setAPNAV1Lock));
743 // Action: select ALT button
744 inst->addAction(0, -SIX_W*0.1125, -SIX_W/16, SIX_W/4, SIX_W/8,
745 new FGToggleAction(FGBFI::getAPAltitudeLock,
746 FGBFI::setAPAltitudeLock));
748 // Layer: AP background
749 FGTexturedLayer * layer;
750 layer = new FGTexturedLayer(createTexture("Textures/Panel/radios.rgb"),
752 0.0, 0.375, 1.0, 0.5);
753 inst->addLayer(layer);
755 // Display HDG button
756 FGTexturedLayer *l1 =
757 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
759 7.0/16.0, 27.0/32.0, 9.0/16.0, 15.0/16.0);
760 FGTexturedLayer *l2 =
761 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
763 1.0/4.0, 27.0/32.0, 3.0/8.0, 15.0/16.0);
765 new FGSwitchLayer(SIX_W/4, SIX_W/8, FGBFI::getAPHeadingLock, l1, l2);
767 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W * 0.5);
769 // Display NAV button
771 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
773 7.0/16.0, 3.0/4.0, 9.0/16.0, 27.0/32.0);
775 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
777 1.0/4.0, 3.0/4.0, 3.0/8.0, 27.0/32.0);
779 new FGSwitchLayer(SIX_W/4, SIX_W/8, FGBFI::getAPNAV1Lock, l1, l2);
781 inst->addTransformation(FGInstrumentLayer::XSHIFT, -SIX_W * 0.25);
783 // Display ALT button
785 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
787 7.0/16.0, 9.0/16.0, 9.0/16.0, 21.0/32.0);
789 new FGTexturedLayer(createTexture("Textures/Panel/knobs.rgb"),
791 1.0/4.0, 9.0/16.0, 3.0/8.0, 21.0/32.0);
793 new FGSwitchLayer(SIX_W/4, SIX_W/8, FGBFI::getAPAltitudeLock, l1, l2);
800 createDME (int x, int y)
802 FGLayeredInstrument * inst = new FGLayeredInstrument(x, y,
807 FGTexturedLayer * layer =
808 new FGTexturedLayer(createTexture("Textures/Panel/radios.rgb"),
809 SIX_W * 0.75, SIX_W * 0.25,
810 0.0, 0.25, 0.375, 0.375);
811 inst->addLayer(layer);
813 // Layer: current distance
814 FGTextLayer * text = new FGTextLayer(SIX_W/2, SIX_W/4);
815 text->addChunk(new FGTextLayer::Chunk(FGBFI::getNAV1Dist, "%05.1f",
817 text->setPointSize(14);
818 text->setColor(1.0, 0.5, 0.0);
819 inst->addLayer(text);
820 inst->addTransformation(FGInstrumentLayer::XSHIFT, -20);
821 inst->addTransformation(FGInstrumentLayer::YSHIFT, -6);
828 ////////////////////////////////////////////////////////////////////////
829 // Construct a panel for a small, single-prop plane.
830 ////////////////////////////////////////////////////////////////////////
833 fgCreateSmallSinglePropPanel (int x, int y, int finx, int finy)
835 FGPanel * panel = new FGPanel(x, y, finx - x, finy - y);
840 // Set the background texture
841 panel->setBackground(createTexture("Textures/Panel/panel-bg.rgb"));
843 // Chronometer alone at side
844 x = SIX_X - SIX_SPACING - 8;
845 panel->addInstrument(createChronometer(x, y));
849 panel->addInstrument(createAirspeedIndicator(x, y));
851 panel->addInstrument(createHorizon(x, y));
853 panel->addInstrument(createAltimeter(x, y));
854 x += SIX_SPACING + 20;
855 panel->addInstrument(createNAV1(x, y));
860 panel->addInstrument(createTurnCoordinator(x, y));
862 panel->addInstrument(createGyroCompass(x, y));
864 panel->addInstrument(createVerticalVelocity(x, y));
865 x += SIX_SPACING + 20;
866 panel->addInstrument(createNAV2(x, y));
870 y -= SIX_SPACING + 10;
871 panel->addInstrument(createControls(x, y));
873 panel->addInstrument(createFlapIndicator(x, y));
875 panel->addInstrument(createRPMGauge(x, y));
876 x += SIX_SPACING + 20;
878 panel->addInstrument(createADF(x, y));
881 x = SIX_X + (SIX_SPACING * 5);
883 panel->addInstrument(createDME(x, y));
884 y -= (int)(SIX_W * 0.375);
885 panel->addInstrument(createNavCom1(x, y));
887 panel->addInstrument(createNavCom2(x, y));
889 panel->addInstrument(createADFRadio(x, y));
890 y -= (int)(SIX_W * 0.375);
891 panel->addInstrument(createAP(x, y));
896 // end of sp_panel.cxx