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