]> git.mxchange.org Git - flightgear.git/blob - Cockpit/hud.c
453a8dd84dbb62d6d127573466dfcd5766f6989a
[flightgear.git] / Cockpit / hud.c
1 /**************************************************************************
2  * hud.c -- hud defines and prototypes
3  *
4  * Written by Michele America, started September 1997.
5  *
6  * Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25  
26
27 #include <GL/glut.h>
28
29 #include <stdlib.h>
30 #include "hud.h"
31
32 #include "../constants.h"
33
34 #include "../Aircraft/aircraft.h"
35 #include "../Scenery/mesh.h"
36 #include "../Scenery/scenery.h"
37 #include "../Math/mat3.h"
38 #include "../Math/polar.h"
39 #include "../Time/fg_timer.h"
40 #include "../Math/fg_random.h"
41 #include "../Weather/weather.h"
42
43 // #define DEBUG
44
45 #define drawOneLine(x1,y1,x2,y2)  glBegin(GL_LINES);  \
46    glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd();
47    
48 /* textString - Bitmap font string */
49
50 static void textString(int x, int y, char *msg, void *font)
51 {
52         glRasterPos2f(x, y);
53         while (*msg) {
54                 glutBitmapCharacter(font, *msg);
55                 msg++;
56     }
57 }
58
59 /* strokeString - Stroke font string */
60
61 static void strokeString(int x, int y, char *msg, void *font)
62 {
63         glPushMatrix();
64         glTranslatef(x, y, 0);
65         glScalef(.04, .04, .04);
66         while (*msg) {
67                 glutStrokeCharacter(font, *msg);
68                 msg++;
69         }
70         glPopMatrix();
71 }
72
73 /*
74
75         Draws a measuring scale anywhere on the HUD
76                 
77         
78         Needs: HUD_scale struct
79
80 */
81 static void drawscale( int type, int sub_type, int min_value, int orientation, int scr_pos, \
82                 int scr_min, int scr_max, double total_amount, int min_div, int max_div, \
83                 double cur_value )
84 {
85     double vmin, vmax;
86     int marker_x, marker_y;
87     int mid_scr;
88     // int scale_min, scale_max;
89     register i;
90     double factor;
91     char TextScale[80];
92     int condition;
93
94     vmin = cur_value-total_amount/2;
95     vmax = cur_value+total_amount/2;
96     
97     mid_scr = scr_min+(scr_max-scr_min)/2;
98     
99     if( type == VERTICAL )     // Vertical scale
100     {
101         if( orientation == LEFT )
102             marker_x = scr_pos-6;
103         else if( orientation == RIGHT )
104             marker_x = scr_pos;
105         drawOneLine( scr_pos, scr_min, scr_pos, scr_max );
106         if( orientation == LEFT )
107         {
108             drawOneLine( scr_pos-3, scr_min, scr_pos, scr_min );
109             drawOneLine( scr_pos-3, scr_max, scr_pos, scr_max );
110             drawOneLine( scr_pos, mid_scr, scr_pos+6, mid_scr );
111         } else if( orientation == RIGHT )
112         {
113             drawOneLine( scr_pos, scr_min, scr_pos+3, scr_min );
114             drawOneLine( scr_pos, scr_max, scr_pos+3, scr_max );
115             drawOneLine( scr_pos, mid_scr, scr_pos-6, mid_scr );
116         }
117
118         factor = (scr_max-scr_min)/total_amount;
119
120         for( i=vmin; i<=vmax; i+=1 )
121         {
122                 if( sub_type == LIMIT )
123                         condition = i>= min_value;
124                 else if( sub_type == NOLIMIT )
125                         condition = 1;
126                         
127             if( condition )
128             {
129                 marker_y = scr_min+(i-vmin)*factor;
130                 if( i%min_div==0 )
131                     if( orientation == LEFT )
132                     {
133                         drawOneLine( marker_x+3, marker_y, marker_x+6, marker_y );
134                     }
135                     else if( orientation == RIGHT )
136                     {
137                         drawOneLine( marker_x, marker_y, marker_x+3, marker_y );
138                     }
139                 if( i%max_div==0 )
140                 {
141                         drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
142                     sprintf( TextScale, "%d", i );
143                     if( orientation == LEFT )
144                     {
145                         textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
146                     }
147                     else if( orientation == RIGHT )
148                     {
149                         textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
150                     }
151                 }
152             }
153         }
154     }
155     if( type == HORIZONTAL )     // Horizontal scale
156     {
157         if( orientation == TOP )
158             marker_y = scr_pos;
159         else if( orientation == BOTTOM )
160             marker_y = scr_pos-6;
161         drawOneLine( scr_min, scr_pos, scr_max, scr_pos );
162         if( orientation == TOP )
163         {
164                 drawOneLine( scr_min, scr_pos, scr_min, scr_pos-3 );
165             drawOneLine( scr_max, scr_pos, scr_max, scr_pos-3 );
166             drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos-6 );
167         } else if( orientation == BOTTOM )
168         {
169                 drawOneLine( scr_min, scr_pos, scr_min, scr_pos+3 );
170             drawOneLine( scr_max, scr_pos, scr_max, scr_pos+3 );
171             drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos+6 );
172         }
173
174         factor = (scr_max-scr_min)/total_amount;
175
176         for( i=vmin; i<=vmax; i+=1 )
177         {
178                 if( sub_type == LIMIT )
179                         condition = i>= min_value;
180                 else if( sub_type == NOLIMIT )
181                         condition = 1;
182                         
183             if( condition )
184             {
185                 marker_x = scr_min+(i-vmin)*factor;
186                 if( i%min_div==0 )
187                     if( orientation == TOP )
188                     {
189                         drawOneLine( marker_x, marker_y, marker_x, marker_y+3 );
190                         }
191                     else if( orientation == BOTTOM )
192                     {
193                         drawOneLine( marker_x, marker_y+3, marker_x, marker_y+6 );
194                     }
195                 if( i%max_div==0 )
196                 {
197                     sprintf( TextScale, "%d", i );
198                     if( orientation == TOP )
199                     {
200                         drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
201                         textString( marker_x-4*strlen(TextScale), marker_y+14, TextScale, GLUT_BITMAP_8_BY_13 );
202                     }
203                     else if( orientation == BOTTOM )
204                     {
205                         drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
206                         textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
207                     }
208                 }
209             }
210         }
211     }
212
213 }              
214
215 /*
216
217         Draws a climb ladder in the center of the HUD
218                 
219         
220         Needs: HUD_ladder struct
221
222 */
223 static void drawladder( struct HUD_ladder ladder )
224 {
225     double vmin, vmax;
226     double roll_value, pitch_value;
227     double cos_roll, sin_roll;
228     int marker_x, marker_y;
229     int mid_scr;
230     int scr_min, scr_max;
231     int x_ini, x_end;
232     int y_ini, y_end;
233     int new_x_ini, new_x_end;
234     int new_y_ini, new_y_end;
235     register i;
236     double factor;
237     char TextLadder[80];
238     int condition;
239
240         roll_value = (*ladder.load_roll)();
241         pitch_value = (*ladder.load_pitch)()*RAD_TO_DEG;
242         
243     vmin = pitch_value-ladder.width_units/2;
244     vmax = pitch_value+ladder.width_units/2;
245     
246     scr_min = ladder.y_pos-(ladder.scr_height/2);
247     scr_max = scr_min+ladder.scr_height;
248     
249     mid_scr = scr_min+(scr_max-scr_min)/2;
250
251         marker_x = ladder.x_pos-ladder.scr_width/2;
252         
253     factor = (scr_max-scr_min)/ladder.width_units;
254
255     for( i=vmin; i<=vmax; i+=1 )
256     {
257         condition = 1;
258         if( condition )
259         {
260             marker_y = scr_min+(i-vmin)*factor;
261             if( i%ladder.div_units==0 )
262             {
263                 sprintf( TextLadder, "%d", i );
264                 if( ladder.scr_hole == 0 )
265                 {
266                         if( i != 0 )
267                                 x_ini = ladder.x_pos-ladder.scr_width/2;
268                         else
269                                 x_ini = ladder.x_pos-ladder.scr_width/2-10;
270                         y_ini = marker_y;
271                         x_end = ladder.x_pos+ladder.scr_width/2;
272                         y_end = marker_y;
273                                 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
274                                         (y_ini-ladder.y_pos)*sin(roll_value);
275                                 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
276                                         (y_ini-ladder.y_pos)*cos(roll_value);
277                                 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
278                                         (y_end-ladder.y_pos)*sin(roll_value);
279                                 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
280                                         (y_end-ladder.y_pos)*cos(roll_value);
281    
282                                         if( i >= 0 )
283                                         {
284                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
285                         }
286                         else
287                         {
288                                 glEnable(GL_LINE_STIPPLE);
289                                 glLineStipple( 1, 0x00FF );
290                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
291                                 glDisable(GL_LINE_STIPPLE);
292                         }
293                         textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
294                         textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
295                 }
296                 else
297                 {
298                         if( i != 0 )
299                                 x_ini = ladder.x_pos-ladder.scr_width/2;
300                         else
301                                 x_ini = ladder.x_pos-ladder.scr_width/2-10;
302                         y_ini = marker_y;
303                         x_end = ladder.x_pos-ladder.scr_width/2+ladder.scr_hole/2;
304                         y_end = marker_y;
305                                 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
306                                         (y_ini-ladder.y_pos)*sin(roll_value);
307                                 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
308                                         (y_ini-ladder.y_pos)*cos(roll_value);
309                                 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
310                                         (y_end-ladder.y_pos)*sin(roll_value);
311                                 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
312                                         (y_end-ladder.y_pos)*cos(roll_value);
313             
314                         if( i >= 0 )
315                         {
316                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
317                         }
318                         else
319                         {
320                                 glEnable(GL_LINE_STIPPLE);
321                                 glLineStipple( 1, 0x00FF );
322                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
323                                 glDisable(GL_LINE_STIPPLE);
324                         }
325                         textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
326                         
327                         x_ini = ladder.x_pos+ladder.scr_width/2-ladder.scr_hole/2;
328                         y_ini = marker_y;
329                         if( i != 0 )
330                                 x_end = ladder.x_pos+ladder.scr_width/2;
331                         else
332                                 x_end = ladder.x_pos+ladder.scr_width/2+10;
333                         y_end = marker_y;
334                                 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
335                                         (y_ini-ladder.y_pos)*sin(roll_value);
336                                 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
337                                         (y_ini-ladder.y_pos)*cos(roll_value);
338                                 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
339                                         (y_end-ladder.y_pos)*sin(roll_value);
340                                 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
341                                         (y_end-ladder.y_pos)*cos(roll_value);
342             
343                         if( i >= 0 )
344                         {
345                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
346                         }
347                         else
348                         {
349                                 glEnable(GL_LINE_STIPPLE);
350                                 glLineStipple( 1, 0x00FF );
351                                 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
352                                 glDisable(GL_LINE_STIPPLE);
353                         }
354                         textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
355                 }
356             }
357             /* if( i%max_div==0 )
358             {
359                 drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
360                 sprintf( TextScale, "%d", i );
361                 if( orientation == LEFT )
362                 {
363                         textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
364                 }
365                 else if( orientation == RIGHT )
366                 {
367                         textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
368                 }
369             } */
370         }
371     }
372
373 }
374
375 /*
376
377         Draws an artificial horizon line in the center of the HUD
378                 (with or without a center hole)
379         
380         Needs: x_center, y_center, length, hole
381
382 */
383 static void drawhorizon( struct HUD_horizon horizon )
384 {
385         int x_inc1, y_inc1;
386         int x_inc2, y_inc2;
387         struct FLIGHT *f;
388         double sin_bank, cos_bank;
389         double bank_angle;
390               
391         // f = &current_aircraft.flight;
392         
393         bank_angle = (*horizon.load_value)();
394
395         // sin_bank = sin( 2*PI-FG_Phi );
396         // cos_bank = cos( 2*PI-FG_Phi );
397         sin_bank = sin(2*PI-bank_angle);
398         cos_bank = cos(2*PI-bank_angle);
399         x_inc1 = (int)(horizon.scr_width*cos_bank);
400         y_inc1 = (int)(horizon.scr_width*sin_bank);
401         x_inc2 = (int)(horizon.scr_hole*cos_bank);
402         y_inc2 = (int)(horizon.scr_hole*sin_bank);
403         
404         if( horizon.scr_hole == 0 )
405         {
406                 drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
407                                                 horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
408         }
409         else
410         {
411                 drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
412                                                 horizon.x_pos-x_inc2, horizon.y_pos-y_inc2 );
413                 drawOneLine( horizon.x_pos+x_inc2, horizon.y_pos+y_inc2, \
414                                                 horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
415         }       
416 }
417
418 /*
419
420         Draws a label anywhere in the HUD
421         
422         Needs: HUD_label struct
423
424 */      
425 static void drawlabel( struct HUD_label label )
426 {
427         char buffer[80];
428         char string[80];
429         int posincr;
430         int lenstr;
431         
432         if( label.pre_str != NULL && label.post_str != NULL )
433                 sprintf( buffer, "%s%s%s", label.pre_str, label.format, label.post_str );
434         else if( label.pre_str == NULL && label.post_str != NULL )
435                 sprintf( buffer, "%s%s", label.format, label.post_str );
436         else if( label.pre_str != NULL && label.post_str == NULL )
437                 sprintf( buffer, "%s%s", label.pre_str, label.format );
438
439         sprintf( string, buffer, (*label.load_value)() );
440
441 #ifdef DEBUG    
442         printf( buffer );
443         printf( "\n" );
444         printf( string );
445         printf( "\n" );
446 #endif
447
448         lenstr = strlen( string );
449         if( label.justify == LEFT_JUST )
450                 posincr = -lenstr*8;
451         else if( label.justify == CENTER_JUST )
452                 posincr = -lenstr*4;
453         else if( label.justify == RIGHT_JUST )
454                 posincr = 0;
455         
456         if( label.size == SMALL )
457                 textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_8_BY_13);
458         else if( label.size == LARGE )
459                 textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_9_BY_15);
460         
461 }
462
463 double get_speed()
464 {
465         struct FLIGHT *f;
466               
467         f = &current_aircraft.flight;
468         return( FG_V_true_kts );
469 }
470
471 double get_aoa()
472 {
473         struct FLIGHT *f;
474               
475         f = &current_aircraft.flight;
476         return( FG_Gamma_vert_rad*RAD_TO_DEG );
477 }
478
479 double get_roll()
480 {
481         struct FLIGHT *f;
482               
483         f = &current_aircraft.flight;
484         return( FG_Phi );
485 }
486
487 double get_pitch()
488 {
489         struct FLIGHT *f;
490               
491         f = &current_aircraft.flight;
492         return( FG_Theta );
493 }
494
495 double get_heading()
496 {
497         struct FLIGHT *f;
498               
499         f = &current_aircraft.flight;
500         return( FG_Gamma_horiz_rad*RAD_TO_DEG ); 
501 }
502
503 double get_altitude()
504 {
505         struct FLIGHT *f;
506         double rough_elev;
507               
508         f = &current_aircraft.flight;
509         rough_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC,
510                                            FG_Latitude  * RAD_TO_ARCSEC);
511                                                    
512         return( FG_Altitude*FEET_TO_METER-rough_elev );
513 }
514
515 void add_instrument( Hptr hud, HIptr instrument )
516 {
517         HIptr instruments;
518         
519         instruments = hud->instruments;
520         // while( ++instruments
521 }
522
523 Hptr fgHUDInit( struct AIRCRAFT current_aircraft, int color )
524 {
525         Hptr hud;
526         
527         hud = (Hptr)calloc(sizeof(struct HUD),1);
528         if( hud == NULL )
529                 return( NULL );
530                 
531         hud->code = 123;
532         hud->status = 0;
533         
534         // For now let's just hardcode a hud here .
535         // In the future, hud information has to come from the same place 
536         // aircraft information came
537         
538         fgHUDAddHorizon( hud, 590, 50, 40, 20, get_roll );
539         fgHUDAddScale( hud, VERTICAL, 220, 100, 280, 5, 10, LEFT, LEFT, 0, 100, get_speed );
540         fgHUDAddScale( hud, VERTICAL, 440, 100, 280, 1, 5, RIGHT, RIGHT, -MAXINT, 25, get_aoa );
541         fgHUDAddScale( hud, HORIZONTAL, 280, 220, 440, 5, 10, TOP, TOP, 0, 50, get_heading );
542         fgHUDAddLabel( hud, 180, 85, SMALL, NOBLINK, RIGHT_JUST, NULL, " Kts", "%5.0f", get_speed );
543         fgHUDAddLabel( hud, 180, 73, SMALL, NOBLINK, RIGHT_JUST, NULL, " m", "%5.0f", get_altitude );
544         fgHUDAddLadder( hud, 330, 190, 90, 180, 70, 10, NONE, 45, get_roll, get_pitch );
545         
546         return( hud );
547 }
548
549
550 Hptr fgHUDAddHorizon( Hptr hud, int x_pos, int y_pos, int length, \
551                                                 int hole_len, double (*load_value)() )
552 {
553         struct HUD_horizon *horizon;
554         struct HUD_instr *instrument;
555         HIptr tmp_first, tmp_next;
556         
557         tmp_first = hud->instruments;
558         if( tmp_first != NULL )
559                 tmp_next = tmp_first->next;
560         else
561                 tmp_next = NULL;
562         
563         instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
564         if( instrument == NULL )
565                 return( NULL );
566                 
567         horizon = (struct HUD_horizon *)calloc(sizeof(struct HUD_horizon),1);
568         if( horizon == NULL )
569                 return( NULL );
570         
571         instrument->type = ARTIFICIAL_HORIZON;
572         instrument->instr = *horizon;
573         instrument->instr.horizon.x_pos = x_pos;
574         instrument->instr.horizon.y_pos = y_pos;
575         instrument->instr.horizon.scr_width = length;
576         instrument->instr.horizon.scr_hole = hole_len;
577         instrument->instr.horizon.load_value = load_value;
578         instrument->next = tmp_first;
579
580         hud->instruments = instrument;
581
582         return( hud );
583 }
584
585 Hptr fgHUDAddScale( Hptr hud, int type, int scr_pos, int scr_min, int scr_max, int div_min, int div_max, \
586                                         int orientation, int with_min, int min_value, int width_units, double (*load_value)() )
587 {
588         struct HUD_scale *scale;
589         struct HUD_instr *instrument;
590         HIptr tmp_first, tmp_next;
591         
592         tmp_first = hud->instruments;
593         if( tmp_first != NULL )
594                 tmp_next = tmp_first->next;
595         else
596                 tmp_next = NULL;
597         
598         instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
599         if( instrument == NULL )
600                 return( NULL );
601                 
602         scale = (struct HUD_scale *)calloc(sizeof(struct HUD_scale),1);
603         if( scale == NULL )
604                 return( NULL );
605         
606         instrument->type = SCALE;
607         instrument->instr = *scale;
608         instrument->instr.scale.type = type;
609         instrument->instr.scale.scr_pos = scr_pos;
610         instrument->instr.scale.scr_min = scr_min;
611         instrument->instr.scale.scr_max = scr_max;
612         instrument->instr.scale.div_min = div_min;
613         instrument->instr.scale.div_max = div_max;
614         instrument->instr.scale.orientation = orientation;
615         instrument->instr.scale.with_minimum = with_min;
616         instrument->instr.scale.minimum_value = min_value;
617         instrument->instr.scale.width_units = width_units;
618         instrument->instr.scale.load_value = load_value;
619         instrument->next = tmp_first;
620
621         hud->instruments = instrument;
622
623         return( hud );
624 }
625
626 Hptr fgHUDAddLabel( Hptr hud, int x_pos, int y_pos, int size, int blink, int justify, \
627                                         char *pre_str, char *post_str, char *format, double (*load_value)() )
628 {
629         struct HUD_label *label;
630         struct HUD_instr *instrument;
631         HIptr tmp_first, tmp_next;
632         
633         tmp_first = hud->instruments;
634         if( tmp_first != NULL )
635                 tmp_next = tmp_first->next;
636         else
637                 tmp_next = NULL;
638         
639         instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
640         if( instrument == NULL )
641                 return( NULL );
642                 
643         label = (struct HUD_label *)calloc(sizeof(struct HUD_label),1);
644         if( label == NULL )
645                 return( NULL );
646         
647         instrument->type = LABEL;
648         instrument->instr = *label;
649         instrument->instr.label.x_pos = x_pos;
650         instrument->instr.label.y_pos = y_pos;
651         instrument->instr.label.size = size;
652         instrument->instr.label.blink = blink;
653         instrument->instr.label.justify = justify;
654         instrument->instr.label.pre_str = pre_str;
655         instrument->instr.label.post_str = post_str;
656         instrument->instr.label.format = format;
657         instrument->instr.label.load_value = load_value;
658         instrument->next = tmp_first;
659
660         hud->instruments = instrument;
661
662         return( hud );
663 }
664
665 Hptr fgHUDAddLadder( Hptr hud, int x_pos, int y_pos, int scr_width, int scr_height, \
666                                         int hole_len, int div_units, int label_pos, int width_units, \
667                                         double (*load_roll)(), double (*load_pitch)() )
668 {
669         struct HUD_ladder *ladder;
670         struct HUD_instr *instrument;
671         HIptr tmp_first, tmp_next;
672         
673         tmp_first = hud->instruments;
674         if( tmp_first != NULL )
675                 tmp_next = tmp_first->next;
676         else
677                 tmp_next = NULL;
678         
679         instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
680         if( instrument == NULL )
681                 return( NULL );
682                 
683         ladder = (struct HUD_ladder *)calloc(sizeof(struct HUD_ladder),1);
684         if( ladder == NULL )
685                 return( NULL );
686         
687         instrument->type = LADDER;
688         instrument->instr = *ladder;
689         instrument->instr.ladder.type = 0;      // Not used.
690         instrument->instr.ladder.x_pos = x_pos;
691         instrument->instr.ladder.y_pos = y_pos;
692         instrument->instr.ladder.scr_width = scr_width;
693         instrument->instr.ladder.scr_height = scr_height;
694         instrument->instr.ladder.scr_hole = hole_len;
695         instrument->instr.ladder.div_units = div_units;
696         instrument->instr.ladder.label_position = label_pos;
697         instrument->instr.ladder.width_units = width_units;
698         instrument->instr.ladder.load_roll = load_roll;
699         instrument->instr.ladder.load_pitch = load_pitch;
700         instrument->next = tmp_first;
701
702         hud->instruments = instrument;
703
704         return( hud );
705
706 }
707
708 /*
709 Hptr fgHUDAddMovingHorizon( Hptr hud, int x_pos, int y_pos, int length, int hole_len, \
710                                                 int color )
711 {
712
713 }
714
715 Hptr fgHUDAddCircularLadder( Hptr hud, int scr_min, int scr_max, int div_min, int div_max, \
716                                                 int max_value )
717 {
718
719 }
720
721 Hptr fgHUDAddNumDisp( Hptr hud, int x_pos, int y_pos, int size, int color, int blink, \
722                                                 char *pre_str, char *post_str )
723 {
724
725 }
726 */
727
728 void fgUpdateHUD( Hptr hud )
729 {
730         HIptr hud_instr;
731         union HUD_instr_data instr_data;
732               
733         glMatrixMode(GL_PROJECTION);
734         glPushMatrix();
735
736         glLoadIdentity();
737         gluOrtho2D(0, 640, 0, 480);
738         glMatrixMode(GL_MODELVIEW);
739         glPushMatrix();
740         glLoadIdentity();
741          
742         glColor3f(1.0, 1.0, 1.0);
743         glIndexi(7);
744               
745         glDisable(GL_DEPTH_TEST);
746         glDisable(GL_LIGHTING);
747                   
748         glLineWidth(1);
749         glColor3f (0.1, 0.9, 0.1);
750                       
751 #ifdef DEBUG    
752     printf( "HUD Code %d  Status %d\n", hud->code, hud->status ); 
753 #endif
754     hud_instr = hud->instruments;
755         while( hud_instr != NULL )
756         {
757                 instr_data = hud_instr->instr;
758 #ifdef DEBUG
759                 printf("Instr Type %d   SubType %d  Orient %d\n", hud_instr->type, hud_instr->sub_type, hud_instr->orientation );
760 #endif
761                 if( hud_instr->type == ARTIFICIAL_HORIZON )
762                 {
763                         drawhorizon( instr_data.horizon );
764                         /* drawhorizon( instr_data.horizon.x_pos, instr_data.horizon.y_pos, \
765                                 instr_data.horizon.scr_width, instr_data.horizon.scr_hole ); */
766         }
767         else if( hud_instr->type == SCALE )
768         {
769                 drawscale( instr_data.scale.type, instr_data.scale.with_minimum, \
770                                 instr_data.scale.minimum_value, instr_data.scale.orientation, \
771                                 instr_data.scale.scr_pos, instr_data.scale.scr_min, \
772                                 instr_data.scale.scr_max, instr_data.scale.width_units, \
773                                 instr_data.scale.div_min, instr_data.scale.div_max, \
774                                         (*instr_data.scale.load_value)() );                                     
775         }
776         else if( hud_instr->type == LABEL )
777         {
778                 drawlabel( instr_data.label );
779                 /* drawlabel( instr_data.label.x_pos, instr_data.label.y_pos, instr_data.label.size, \
780                                 instr_data.label.blink, instr_data.label.pre_str, instr_data.label.post_str, \
781                                 instr_data.label.format, (*instr_data.label.load_value)() ); */
782         }
783         else if( hud_instr->type == LADDER )
784         {
785                 drawladder( instr_data.ladder );
786         }
787         hud_instr = hud_instr->next;
788     }
789     
790     
791         glEnable(GL_DEPTH_TEST);
792         glEnable(GL_LIGHTING);
793         glMatrixMode(GL_PROJECTION);
794         glPopMatrix();
795         glMatrixMode(GL_MODELVIEW);
796         glPopMatrix();
797                 
798 }
799
800
801 /* $Log$
802 /* Revision 1.1  1997/08/29 18:03:22  curt
803 /* Initial revision.
804 /*
805  */