]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud_card.cxx
- remove hud.cxx/readLabel and let the instr_label read its properties
[flightgear.git] / src / Cockpit / hud_card.cxx
1
2 #ifdef HAVE_CONFIG_H
3 #  include "config.h"
4 #endif
5
6 #include <plib/sg.h>
7 #include "hud.hxx"
8
9 #ifdef USE_HUD_TextList
10 #define textString(x, y, text, digit)  TextString(text, x , y ,digit)
11 #else
12 #define textString(x, y, text, digit)  puDrawString(guiFnt, text, x, y)
13 #endif
14
15 //========== Top of hud_card class member definitions =============
16 #include <math.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19
20
21 hud_card::hud_card(
22           int       x,
23           int       y,
24           UINT      width,
25           UINT      height,
26           FLTFNPTR  data_source,
27           UINT      options,
28           float     max_value, // 360
29           float     min_value, // 0
30           float     disp_scaling,
31           UINT      major_divs,
32           UINT      minor_divs,
33           UINT      modulus,  // 360
34           int       dp_showing,
35           float     value_span,
36           string    card_type,
37           bool      tick_bottom,
38           bool      tick_top,
39           bool      tick_right,
40           bool      tick_left,
41           bool      cap_bottom,
42           bool      cap_top,
43           bool      cap_right,
44           bool      cap_left,
45           float     mark_offset,
46           bool      pointer_enable,
47           string    type_pointer,
48           string    type_tick,
49           string    length_tick,
50           bool      working,
51           float     rad,
52           int       divs,
53           int       zooms) :
54     instr_scale(x,y,width,height,
55                  data_source, options,
56                  value_span,
57                  max_value, min_value, disp_scaling,
58                  major_divs, minor_divs, modulus,
59                  working),
60     val_span         (value_span),
61     type             (card_type),
62     draw_tick_bottom (tick_bottom),
63     draw_tick_top    (tick_top),
64     draw_tick_right  (tick_right),
65     draw_tick_left   (tick_left),
66     draw_cap_bottom  (cap_bottom),
67     draw_cap_top     (cap_top),
68     draw_cap_right   (cap_right),
69     draw_cap_left    (cap_left),
70     marker_offset    (mark_offset),
71     pointer          (pointer_enable),
72     pointer_type     (type_pointer),
73     tick_type        (type_tick),
74     tick_length      (length_tick),
75     Maj_div          (major_divs),
76     Min_div          (minor_divs)
77
78 {
79     half_width_units = range_to_show() / 2.0;
80     radius = rad;
81     maxValue = max_value;
82     minValue = min_value;
83     divisions = divs;
84     zoom = zooms;
85
86     //  UINT options     = get_options();
87     //  huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
88     //  huds_right = options & HUDS_RIGHT;
89     //  huds_left = options & HUDS_LEFT;
90     //  huds_vert = options & HUDS_VERT;
91     //  huds_notext = options & HUDS_NOTEXT;
92     //  huds_top = options & HUDS_TOP;
93     //  huds_bottom = options & HUDS_BOTTOM;
94 }
95
96
97 hud_card::~hud_card() { }
98
99
100 hud_card::hud_card(const hud_card & image) :
101     instr_scale((const instr_scale &) image),
102     val_span(image.val_span),
103     type(image.type),
104     half_width_units (image.half_width_units),
105     draw_tick_bottom (image.draw_tick_bottom),
106     draw_tick_top (image.draw_tick_top),
107     draw_tick_right (image.draw_tick_right),
108     draw_tick_left (image.draw_tick_left),
109     draw_cap_bottom (image.draw_cap_bottom),
110     draw_cap_top (image.draw_cap_top),
111     draw_cap_right (image.draw_cap_right),
112     draw_cap_left (image.draw_cap_left),
113     marker_offset (image.marker_offset),
114     pointer (image.pointer),
115     pointer_type (image.pointer_type),
116     tick_type(image.tick_type),
117     tick_length(image.tick_length),
118     Maj_div(image.Maj_div),
119     Min_div(image.Min_div)
120
121 {
122     //  UINT options     = get_options();
123     //  huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
124     //  huds_right = options & HUDS_RIGHT;
125     //  huds_left = options & HUDS_LEFT;
126     //  huds_vert = options & HUDS_VERT;
127     //  huds_notext = options & HUDS_NOTEXT;
128     //  huds_top = options & HUDS_TOP;
129     //  huds_bottom = options & HUDS_BOTTOM;
130 }
131
132
133 void hud_card::draw(void) //  (HUD_scale * pscale)
134 {
135     float vmin = 0.0, vmax = 0.0;
136     float marker_xs;
137     float marker_xe;
138     float marker_ys;
139     float marker_ye;
140     int text_x = 0, text_y = 0;
141     int lenstr;
142     int height, width;
143     int i, last;
144     char TextScale[80];
145     bool condition;
146     int disp_val = 0;
147     int oddtype, k; //odd or even values for ticks
148
149     POINT mid_scr    = get_centroid();
150     float cur_value  = get_value();
151
152     if (!((int)maxValue%2))
153         oddtype = 0; //draw ticks at even values
154     else
155         oddtype = 1; //draw ticks at odd values
156
157     RECT scrn_rect = get_location();
158     UINT options = get_options();
159
160     height = scrn_rect.top + scrn_rect.bottom;
161     width = scrn_rect.left + scrn_rect.right;
162
163     // if type=gauge then display dial
164     if (type == "gauge") {
165         float x,y;
166         float i;
167         y = (float)(scrn_rect.top);
168         x = (float)(scrn_rect.left);
169         glEnable(GL_POINT_SMOOTH);
170         glPointSize(3.0);
171
172         float incr = 360.0 / divisions;
173         for (i = 0.0; i < 360.0; i += incr) {
174             float i1 = i * SGD_DEGREES_TO_RADIANS;
175             float x1 = x + radius*cos(i1);
176             float y1 = y + radius*sin(i1);
177
178             glBegin(GL_POINTS);
179             glVertex2f(x1, y1);
180             glEnd();
181         }
182         glPointSize(1.0);
183         glDisable(GL_POINT_SMOOTH);
184
185
186         if (data_available()) {
187             float offset = 90.0 * SGD_DEGREES_TO_RADIANS;
188             float r1 = 10.0; //size of carrot
189             float theta = get_value();
190
191             float theta1 = -theta*SGD_DEGREES_TO_RADIANS+offset;
192             float x1 = x+radius*cos(theta1);
193             float y1 = y+radius*sin(theta1);
194             float x2 = x1-r1*cos(theta1-30.0*SGD_DEGREES_TO_RADIANS);
195             float y2 = y1-r1*sin(theta1-30.0*SGD_DEGREES_TO_RADIANS);
196             float x3 = x1-r1*cos(theta1+30.0*SGD_DEGREES_TO_RADIANS);
197             float y3 = y1-r1*sin(theta1+30.0*SGD_DEGREES_TO_RADIANS);
198
199             // draw carrot
200             drawOneLine(x1,y1,x2,y2);
201             drawOneLine(x1,y1,x3,y3);
202             sprintf(TextScale,"%3.1f\n",theta);
203
204             // draw value
205             int l = abs((int)theta);
206             if (l) {
207                 if (l < 10)
208                     textString(x, y, TextScale, 0);
209                 else if (l < 100)
210                     textString(x-1.0, y, TextScale, 0);
211                 else if (l<360)
212                     textString(x-2.0, y, TextScale, 0);
213             }
214         } //end type=gauge
215
216     } else {
217         // if its not explicitly a gauge default to tape
218         if (pointer) {
219             if (pointer_type=="moving") {
220                 vmin = minValue;
221                 vmax = maxValue;
222
223             } else {
224                 // default to fixed
225                 vmin   = cur_value - half_width_units; // width units == needle travel
226                 vmax   = cur_value + half_width_units; // or picture unit span.
227                 text_x = mid_scr.x;
228                 text_y = mid_scr.y;
229             }
230
231         } else {
232             vmin   = cur_value - half_width_units; // width units == needle travel
233             vmax   = cur_value + half_width_units; // or picture unit span.
234             text_x = mid_scr.x;
235             text_y = mid_scr.y;
236         }
237
238         // Draw the basic markings for the scale...
239
240         if (huds_vert(options)) { // Vertical scale
241             if (draw_tick_bottom) {
242                 drawOneLine(scrn_rect.left,     // Bottom tick bar
243                             scrn_rect.top,
244                             width,
245                             scrn_rect.top);
246             } // endif draw_tick_bottom
247
248             if (draw_tick_top) {
249                 drawOneLine(scrn_rect.left,    // Top tick bar
250                             height,
251                             width,
252                             height);
253             } // endif draw_tick_top
254
255             marker_xs = scrn_rect.left;  // x start
256             marker_xe = width;           // x extent
257             marker_ye = height;
258
259             //    glBegin(GL_LINES);
260
261             // Bottom tick bar
262             //    glVertex2f(marker_xs, scrn_rect.top);
263             //    glVertex2f(marker_xe, scrn_rect.top);
264
265             // Top tick bar
266             //    glVertex2f(marker_xs, marker_ye);
267             //    glVertex2f(marker_xe, marker_ye);
268             //    glEnd();
269
270
271             // We do not use else in the following so that combining the
272             // two options produces a "caged" display with double
273             // carrots. The same is done for horizontal card indicators.
274
275             // begin vertical/left
276             //First draw capping lines and pointers
277             if (huds_left(options)) {    // Calculate x marker offset
278
279                 if (draw_cap_right) {
280                     drawOneLine(marker_xe, scrn_rect.top,
281                                  marker_xe, marker_ye); // Cap right side
282                 } //endif cap_right
283
284                 marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
285
286                 // drawOneLine(marker_xs, mid_scr.y,
287                 //              marker_xe, mid_scr.y + scrn_rect.right / 6);
288                 // drawOneLine(marker_xs, mid_scr.y,
289                 //              marker_xe, mid_scr.y - scrn_rect.right / 6);
290
291                 // draw pointer
292                 if (pointer) {
293                     if (pointer_type=="moving") {
294                         if (zoom == 0) {
295                             //Code for Moving Type Pointer
296                             float ycentre, ypoint,xpoint;
297                             int range,wth;
298                             if (cur_value > maxValue)
299                                 cur_value = maxValue;
300                             if (cur_value < minValue)
301                                 cur_value = minValue;
302
303                             if (minValue >= 0.0)
304                                 ycentre = scrn_rect.top;
305                             else if (maxValue + minValue == 0.0)
306                                 ycentre = mid_scr.y;
307                             else
308                                 if (oddtype == 1)
309                                     ycentre = scrn_rect.top + (1.0-minValue)*scrn_rect.bottom/(maxValue-minValue);
310                                 else
311                                     ycentre = scrn_rect.top + minValue*scrn_rect.bottom/(maxValue-minValue);
312
313                             range = scrn_rect.bottom;
314                             wth   = scrn_rect.left + scrn_rect.right;
315
316                             if (oddtype == 1)
317                                 ypoint = ycentre + ((cur_value-1.0) * range / val_span);
318                             else
319                                 ypoint = ycentre + (cur_value * range / val_span);
320
321                             xpoint = wth + marker_offset;
322                             drawOneLine(xpoint,ycentre,xpoint,ypoint);
323                             drawOneLine(xpoint,ypoint,xpoint-marker_offset,ypoint);
324                             drawOneLine(xpoint-marker_offset,ypoint,xpoint-5.0,ypoint+5.0);
325                             drawOneLine(xpoint-marker_offset,ypoint,xpoint-5.0,ypoint-5.0);
326                         } //zoom=0
327
328                     } else {
329                         // default to fixed
330                         fixed(marker_offset+marker_xe, text_y + scrn_rect.right / 6,
331                               marker_offset+marker_xs, text_y,marker_offset+marker_xe,
332                               text_y - scrn_rect.right / 6);
333                     }//end pointer type
334                 } //if pointer
335             } //end vertical/left
336
337             // begin vertical/right
338             //First draw capping lines and pointers
339             if (huds_right(options)) {  // We'll default this for now.
340                 if (draw_cap_left) {
341                     drawOneLine(scrn_rect.left, scrn_rect.top,
342                                  scrn_rect.left, marker_ye);  // Cap left side
343                 } //endif cap_left
344
345                 marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
346                 // Indicator carrot
347                 // drawOneLine(scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
348                 //              marker_xe, mid_scr.y);
349                 // drawOneLine(scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
350                 //              marker_xe, mid_scr.y);
351
352                 // draw pointer
353                 if (pointer) {
354                     if (pointer_type == "moving") {
355                         if (zoom == 0) {
356                             //type-fixed & zoom=1, behaviour to be defined
357                             // Code for Moving Type Pointer
358                             float ycentre, ypoint,xpoint;
359                             int range;
360
361                             if (cur_value > maxValue)
362                                 cur_value = maxValue;
363                             if (cur_value < minValue)
364                                 cur_value = minValue;
365
366                             if (minValue >= 0.0)
367                                 ycentre = scrn_rect.top;
368                             else if (maxValue + minValue == 0.0)
369                                 ycentre = mid_scr.y;
370                             else
371                                 if (oddtype == 1)
372                                     ycentre = scrn_rect.top + (1.0-minValue)*scrn_rect.bottom/(maxValue-minValue);
373                                 else
374                                     ycentre = scrn_rect.top + minValue*scrn_rect.bottom/(maxValue-minValue);
375
376                             range = scrn_rect.bottom;
377
378                             if (oddtype == 1)
379                                 ypoint = ycentre + ((cur_value-1.0) * range / val_span);
380                             else
381                                 ypoint = ycentre + (cur_value * range / val_span);
382
383                             xpoint = scrn_rect.left - marker_offset;
384                             drawOneLine(xpoint,ycentre,xpoint,ypoint);
385                             drawOneLine(xpoint,ypoint,xpoint+marker_offset,ypoint);
386                             drawOneLine(xpoint+marker_offset,ypoint,xpoint+5.0,ypoint+5.0);
387                             drawOneLine(xpoint+marker_offset,ypoint,xpoint+5.0,ypoint-5.0);
388                         }
389
390                     } else {
391                         // default to fixed
392                         fixed(-marker_offset+scrn_rect.left, text_y +  scrn_rect.right / 6,
393                                -marker_offset+marker_xe, text_y,-marker_offset+scrn_rect.left,
394                                text_y -  scrn_rect.right / 6);
395                     }
396                 } //if pointer
397             }  //end vertical/right
398
399             // At this point marker x_start and x_end values are transposed.
400             // To keep this from confusing things they are now interchanged.
401             if (huds_both(options)) {
402                 marker_ye = marker_xs;
403                 marker_xs = marker_xe;
404                 marker_xe = marker_ye;
405             }
406
407             // Work through from bottom to top of scale. Calculating where to put
408             // minor and major ticks.
409
410             // draw scale or tape
411
412 //            last = FloatToInt(vmax)+1;
413 //            i = FloatToInt(vmin);
414             last = (int)vmax + 1; // N
415             i = (int)vmin; // N
416
417             if (zoom == 1) {
418                 zoomed_scale((int)vmin, (int)vmax);
419             } else {
420                 for (; i < last; i++) {
421                     condition = true;
422                     if (!modulo()) {
423                         if (i < min_val()) {
424                             condition = false;
425                         }
426                     }
427
428                     if (condition) {  // Show a tick if necessary
429                         // Calculate the location of this tick
430                         marker_ys = scrn_rect.top + ((i - vmin) * factor()/*+.5f*/);
431                         // marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
432                         // Block calculation artifact from drawing ticks below min coordinate.
433                         // Calculation here accounts for text height.
434
435                         if ((marker_ys < (scrn_rect.top + 4))
436                                 | (marker_ys > (height - 4))) {
437                             // Magic numbers!!!
438                             continue;
439                         }
440
441                         if (oddtype == 1)
442                             k = i+1; //enable ticks at odd values
443                         else
444                             k = i;
445
446                         // Minor ticks
447                         if (div_min()) {
448                             // if ((i%div_min()) == 0) {
449                             if (!(k%(int)div_min())) {
450                                 if (((marker_ys - 5) > scrn_rect.top)
451                                         && ((marker_ys + 5) < (height))) {
452
453                                     //vertical/left OR vertical/right
454                                     if (huds_both(options)) {
455                                         if (tick_type=="line") {
456                                             if (tick_length=="variable") {
457                                                 drawOneLine(scrn_rect.left, marker_ys,
458                                                             marker_xs,      marker_ys);
459                                                 drawOneLine(marker_xe,      marker_ys,
460                                                             width,  marker_ys);
461                                             } else {
462                                                 drawOneLine(scrn_rect.left, marker_ys,
463                                                             marker_xs,      marker_ys);
464                                                 drawOneLine(marker_xe,      marker_ys,
465                                                             width,  marker_ys);
466                                             }
467                                         } else if (tick_type == "circle")
468                                             circles(scrn_rect.left,(float)marker_ys,3.0);
469
470                                         else {
471                                             // if neither line nor circle draw default as line
472                                             drawOneLine(scrn_rect.left, marker_ys,
473                                                         marker_xs,      marker_ys);
474                                             drawOneLine(marker_xe,      marker_ys,
475                                                         width,  marker_ys);
476                                         }
477                                         // glBegin(GL_LINES);
478                                         // glVertex2f(scrn_rect.left, marker_ys);
479                                         // glVertex2f(marker_xs,      marker_ys);
480                                         // glVertex2f(marker_xe,      marker_ys);
481                                         // glVertex2f(scrn_rect.left + scrn_rect.right,  marker_ys);
482                                         // glEnd();
483                                         // anything other than huds_both
484
485                                     } else {
486                                         if (huds_left(options)) {
487                                             if (tick_type=="line") {
488                                                 if (tick_length=="variable") {
489                                                     drawOneLine(marker_xs + 4, marker_ys,
490                                                                 marker_xe,     marker_ys);
491                                                 } else {
492                                                     drawOneLine(marker_xs , marker_ys,
493                                                                 marker_xe,     marker_ys);
494                                                 }
495                                             } else if (tick_type=="circle")
496                                                 circles((float)marker_xs + 4, (float)marker_ys,3.0);
497
498                                             else {
499                                                 drawOneLine(marker_xs + 4, marker_ys,
500                                                             marker_xe,     marker_ys);
501                                             }
502                                         }  else {
503                                             if (tick_type=="line") {
504                                                 if (tick_length=="variable") {
505                                                     drawOneLine(marker_xs,     marker_ys,
506                                                                 marker_xe - 4, marker_ys);
507                                                 } else {
508                                                     drawOneLine(marker_xs,     marker_ys,
509                                                                 marker_xe , marker_ys);
510                                                 }
511                                             } else if (tick_type=="circle")
512                                                 circles((float)marker_xe - 4, (float)marker_ys,3.0);
513                                             else {
514                                                 drawOneLine(marker_xs,     marker_ys,
515                                                             marker_xe - 4, marker_ys);
516                                             }
517                                         }
518                                     } //end huds both
519                                 }
520                             } //end draw minor ticks
521                         }  //end minor ticks
522
523                         // Major ticks
524                         if (div_max()) {
525                             if (!(k%(int)div_max())) {
526                                 if (modulo()) {
527                                     disp_val = i % (int) modulo(); // ?????????
528                                     if (disp_val < 0) {
529                                         while (disp_val < 0)
530                                             disp_val += modulo();
531                                     }
532                                 } else {
533                                     disp_val = i;
534                                 }
535
536                                 lenstr = sprintf(TextScale, "%d",
537                                                  FloatToInt(disp_val * data_scaling()/*+.5*/));
538                                 // (int)(disp_val  * data_scaling() +.5));
539                                 /* if (((marker_ys - 8) > scrn_rect.top) &&
540                                    ((marker_ys + 8) < (height))){ */
541                                 // huds_both
542                                 if (huds_both(options)) {
543                                     // drawOneLine(scrn_rect.left, marker_ys,
544                                     //              marker_xs,      marker_ys);
545                                     // drawOneLine(marker_xs, marker_ys,
546                                     //              scrn_rect.left + scrn_rect.right,
547                                     //              marker_ys);
548                                     if (tick_type == "line") {
549                                         glBegin(GL_LINE_STRIP);
550                                         glVertex2f(scrn_rect.left, marker_ys);
551                                         glVertex2f(marker_xs, marker_ys);
552                                         glVertex2f(width, marker_ys);
553                                         glEnd();
554                                     } else if (tick_type == "circle") {
555                                         circles(scrn_rect.left, (float)marker_ys,5.0);
556                                     } else {
557                                         glBegin(GL_LINE_STRIP);
558                                         glVertex2f(scrn_rect.left, marker_ys);
559                                         glVertex2f(marker_xs, marker_ys);
560                                         glVertex2f(width, marker_ys);
561                                         glEnd();
562                                     }
563
564                                     if (!huds_notext(options)) {
565                                         textString (marker_xs + 2,  marker_ys,
566                                                     TextScale,0);
567                                     }
568
569                                 } else {
570                                     /* Changes are made to draw a circle when tick_type="circle" */
571                                     // anything other than huds_both
572                                     if (tick_type=="line") {
573                                         drawOneLine(marker_xs, marker_ys, marker_xe, marker_ys);
574                                     } else if (tick_type=="circle") {
575                                         circles((float)marker_xs + 4, (float)marker_ys,5.0);
576                                     } else {
577                                         drawOneLine(marker_xs, marker_ys, marker_xe, marker_ys);
578                                     }
579
580                                     if (!huds_notext(options)) {
581                                         if (huds_left(options)) {
582                                             textString(marker_xs -  8 * lenstr - 2,
583                                                        marker_ys - 4,
584                                                        TextScale, 0);
585                                         } else {
586                                             textString(marker_xe + 3 * lenstr,
587                                                        marker_ys - 4,
588                                                        TextScale, 0);
589                                         } //End if huds_left
590                                     } //End if !huds_notext
591                                 }  //End if huds-both
592                             }  // End if draw major ticks
593                         }   // End if major ticks
594                     }  // End condition
595                 }  // End for
596             }  //end of zoom
597             // End if VERTICAL SCALE TYPE (tape loop yet to be closed)
598
599         } else {
600             // Horizontal scale by default
601             // left tick bar
602             if (draw_tick_left) {
603                 drawOneLine(scrn_rect.left, scrn_rect.top,
604                             scrn_rect.left, height);
605             }  // endif draw_tick_left
606             // right tick bar
607             if (draw_tick_right) {
608                 drawOneLine(width, scrn_rect.top,
609                             width,
610                             height);
611             }  // endif draw_tick_right
612
613             marker_ys = scrn_rect.top;           // Starting point for
614             marker_ye = height;                  // tick y location calcs
615             marker_xe = width;
616             marker_xs = scrn_rect.left + ((cur_value - vmin) * factor() /*+ .5f*/);
617
618             //    glBegin(GL_LINES);
619             // left tick bar
620             //    glVertex2f(scrn_rect.left, scrn_rect.top);
621             //    glVertex2f(scrn_rect.left, marker_ye);
622
623             // right tick bar
624             //    glVertex2f(marker_xe, scrn_rect.top);
625             //    glVertex2f(marker_xe, marker_ye);
626             //    glEnd();
627
628             if (huds_top(options)) {
629                 if (draw_cap_bottom) {
630                     // Bottom box line
631                     drawOneLine(scrn_rect.left,
632                                 scrn_rect.top,
633                                 width,
634                                 scrn_rect.top);
635                 }  //endif cap_bottom
636
637                 // Tick point adjust
638                 marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;
639                 // Bottom arrow
640                 // drawOneLine(mid_scr.x, marker_ye,
641                 //              mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
642                 // drawOneLine(mid_scr.x, marker_ye,
643                 //              mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
644                 // draw pointer
645                 if (pointer) {
646                     if (pointer_type == "moving") {
647                         if (zoom == 0) {
648                             //Code for Moving Type Pointer
649                             // static float xcentre,xpoint,ypoint;
650                             // static int range;
651                             if (cur_value > maxValue)
652                                 cur_value = maxValue;
653                             if (cur_value < minValue)
654                                 cur_value = minValue;
655
656                             float xcentre = mid_scr.x;
657                             int range = scrn_rect.right;
658                             float xpoint = xcentre + (cur_value * range / val_span);
659                             float ypoint = scrn_rect.top - marker_offset;
660                             drawOneLine(xcentre, ypoint,xpoint,ypoint);
661                             drawOneLine(xpoint,ypoint,xpoint,ypoint+marker_offset);
662                             drawOneLine(xpoint,ypoint+marker_offset,xpoint+5.0,ypoint+5.0);
663                             drawOneLine(xpoint,ypoint+marker_offset,xpoint-5.0,ypoint+5.0);
664                         }
665                     } else {
666                         //default to fixed
667                         fixed(marker_xs - scrn_rect.bottom / 4, scrn_rect.top,
668                                marker_xs, marker_ye, marker_xs + scrn_rect.bottom / 4,scrn_rect.top);
669                     }
670                 }  //if pointer
671             } //End Horizontal scale/top
672
673             if (huds_bottom(options)) {
674                 // Top box line
675                 if (draw_cap_top) {
676                     drawOneLine(scrn_rect.left, height,
677                                  width, height);
678                 }  //endif cap_top
679
680                 // Tick point adjust
681                 marker_ys = height - scrn_rect.bottom / 2;
682                 // Top arrow
683                 //      drawOneLine(mid_scr.x + scrn_rect.bottom / 4,
684                 //                   scrn_rect.top + scrn_rect.bottom,
685                 //                   mid_scr.x, marker_ys);
686                 //      drawOneLine(mid_scr.x - scrn_rect.bottom / 4,
687                 //                   scrn_rect.top + scrn_rect.bottom,
688                 //                   mid_scr.x , marker_ys);
689
690                 // draw pointer
691                 if (pointer) {
692                     if (pointer_type =="moving") {
693                         if (zoom == 0) {
694                             //Code for Moving Type Pointer
695                             // static float xcentre,xpoint,ypoint;
696                             // static int range,hgt;
697                             if (cur_value > maxValue)
698                                 cur_value = maxValue;
699                             if (cur_value < minValue)
700                                 cur_value = minValue;
701
702                             float xcentre = mid_scr.x ;
703                             int range = scrn_rect.right;
704                             int hgt   = scrn_rect.top + scrn_rect.bottom;
705                             float xpoint = xcentre + (cur_value * range / val_span);
706                             float ypoint = hgt + marker_offset;
707                             drawOneLine(xcentre, ypoint,xpoint,ypoint);
708                             drawOneLine(xpoint,ypoint,xpoint,ypoint-marker_offset);
709                             drawOneLine(xpoint,ypoint-marker_offset,xpoint+5.0,ypoint-5.0);
710                             drawOneLine(xpoint,ypoint-marker_offset,xpoint-5.0,ypoint-5.0);
711                         }
712                     } else {
713                         fixed(marker_xs + scrn_rect.bottom / 4, height, marker_xs, marker_ys,
714                               marker_xs - scrn_rect.bottom / 4, height);
715                     }
716                 } //if pointer
717             }  //end horizontal scale bottom
718
719             //    if ((options & HUDS_BOTTOM) == HUDS_BOTTOM) {
720             //      marker_xe = marker_ys;
721             //      marker_ys = marker_ye;
722             //      marker_ye = marker_xe;
723             //      }
724
725             // printf("vmin = %d  vmax = %d\n", (int)vmin, (int)vmax);
726
727             //  last = FloatToInt(vmax)+1;
728             //  i    = FloatToInt(vmin);
729
730             if (zoom == 1) {
731                 zoomed_scale((int)vmin,(int)vmax);
732             } else {
733                 //default to zoom=0
734                 last = (int)vmax + 1;
735                 i = (int)vmin;
736                 for (; i < last; i++) {
737                     // for (i = (int)vmin; i <= (int)vmax; i++)     {
738                     // printf("<*> i = %d\n", i);
739                     condition = true;
740                     if (!modulo()) {
741                         if (i < min_val()) {
742                             condition = false;
743                         }
744                     }
745                     // printf("<**> i = %d\n", i);
746                     if (condition) {
747                         // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
748                         marker_xs = scrn_rect.left + (((i - vmin) * factor()/*+ .5f*/));
749
750                         if (oddtype == 1)
751                             k = i+1; //enable ticks at odd values
752                         else
753                             k = i;
754
755                         if (div_min()) {
756                             //          if ((i%(int)div_min()) == 0) {
757                             //draw minor ticks
758                             if (!(k%(int)div_min())) {
759                                 // draw in ticks only if they aren't too close to the edge.
760                                 if (((marker_xs - 5) > scrn_rect.left)
761                                         && ((marker_xs + 5)< (scrn_rect.left + scrn_rect.right))) {
762
763                                     if (huds_both(options)) {
764                                         if (tick_length == "variable") {
765                                             drawOneLine(marker_xs, scrn_rect.top,
766                                                         marker_xs, marker_ys - 4);
767                                             drawOneLine(marker_xs, marker_ye + 4,
768                                                         marker_xs, height);
769                                         } else {
770                                             drawOneLine(marker_xs, scrn_rect.top,
771                                                         marker_xs, marker_ys);
772                                             drawOneLine(marker_xs, marker_ye,
773                                                         marker_xs, height);
774                                         }
775                                         // glBegin(GL_LINES);
776                                         // glVertex2f(marker_xs, scrn_rect.top);
777                                         // glVertex2f(marker_xs, marker_ys - 4);
778                                         // glVertex2f(marker_xs, marker_ye + 4);
779                                         // glVertex2f(marker_xs, scrn_rect.top + scrn_rect.bottom);
780                                         // glEnd();
781
782                                     } else {
783                                         if (huds_top(options)) {
784                                             //draw minor ticks
785                                             if (tick_length=="variable")
786                                                 drawOneLine(marker_xs,marker_ys,marker_xs,marker_ye-4);
787                                             else
788                                                 drawOneLine(marker_xs,marker_ys,marker_xs,marker_ye);
789
790                                         } else
791                                             if (tick_length=="variable")
792                                                 drawOneLine(marker_xs,marker_ys+4,marker_xs,marker_ye);
793                                             else
794                                                 drawOneLine(marker_xs,marker_ys,marker_xs,marker_ye);
795                                         }
796                                     }
797                                 } //end draw minor ticks
798                             } //end minor ticks
799
800                             //major ticks
801                             if (div_max()) {
802                                 // printf("i = %d\n", i);
803                                 // if ((i%(int)div_max())==0) {
804                                 //     draw major ticks
805
806                                 if (!(k%(int)div_max())) {
807                                     if (modulo()) {
808                                         disp_val = i % (int) modulo(); // ?????????
809                                         if (disp_val < 0) {
810                                             while (disp_val<0)
811                                                 disp_val += modulo();
812                                         }
813                                     } else {
814                                         disp_val = i;
815                                     }
816                                     // printf("disp_val = %d\n", disp_val);
817                                     // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
818                                     lenstr = sprintf(TextScale, "%d",
819                                             // (int)(disp_val  * data_scaling() +.5));
820                                             FloatToInt(disp_val * data_scaling()/*+.5*/));
821
822                                     // Draw major ticks and text only if far enough from the edge.
823                                     if (((marker_xs - 10)> scrn_rect.left)
824                                             && ((marker_xs + 10) < (scrn_rect.left + scrn_rect.right))) {
825                                         if (huds_both(options)) {
826                                             // drawOneLine(marker_xs, scrn_rect.top,
827                                             //              marker_xs, marker_ys);
828                                             // drawOneLine(marker_xs, marker_ye,
829                                             //              marker_xs, scrn_rect.top + scrn_rect.bottom);
830                                             glBegin(GL_LINE_STRIP);
831                                             glVertex2f(marker_xs, scrn_rect.top);
832                                             glVertex2f(marker_xs, marker_ye);
833                                             glVertex2f(marker_xs, height);
834                                             glEnd();
835
836                                             if (!huds_notext(options)) {
837                                                 textString(marker_xs - 4 * lenstr,
838                                                            marker_ys + 4, TextScale, 0);
839                                             }
840                                         } else {
841                                             drawOneLine(marker_xs, marker_ys, marker_xs, marker_ye);
842
843                                         if (!huds_notext(options)) {
844                                             if (huds_top(options)) {
845                                                 textString(marker_xs - 4 * lenstr,
846                                                            height - 10, TextScale, 0);
847
848                                             }  else  {
849                                                 textString(marker_xs - 4 * lenstr,
850                                                            scrn_rect.top, TextScale, 0);
851                                             }
852                                         }
853                                     }
854                                 }
855                             }  //end draw major ticks
856                         } //endif major ticks
857                     }   //end condition
858                 } //end for
859             }  //end zoom
860         } //end horizontal/vertical scale
861     } // end of type tape
862 } //draw
863
864
865
866 void hud_card::circles(float x,float y,float size)
867 {
868     glEnable(GL_POINT_SMOOTH);
869     glPointSize(size);
870
871     glBegin(GL_POINTS);
872     glVertex2f(x,y);
873     glEnd();
874
875     glPointSize(1.0);
876     glDisable(GL_POINT_SMOOTH);
877 }
878
879
880 void hud_card::fixed(float x1, float y1, float x2, float y2, float x3, float y3)
881 {
882     glBegin(GL_LINE_STRIP);
883     glVertex2f(x1, y1);
884     glVertex2f(x2, y2);
885     glVertex2f(x3, y3);
886     glEnd();
887 }
888
889
890 void hud_card::zoomed_scale(int first, int last)
891 {
892     POINT mid_scr    = get_centroid();
893     RECT   scrn_rect = get_location();
894     UINT options     = get_options();
895     char TextScale[80];
896     // int disp_val = 0;
897     int data[80];
898
899     float x,y,w,h,bottom;
900     float cur_value=get_value();
901     if (cur_value > maxValue)
902         cur_value = maxValue;
903     if (cur_value < minValue)
904         cur_value = minValue;
905
906     int a=0;
907
908     while (first <= last) {
909         if ((first % (int)Maj_div) == 0) {
910             data[a] = first;
911             a++ ;
912         }
913         first++;
914     }
915     int centre =a/2;
916
917     if (huds_vert(options)) {
918         x=scrn_rect.left;
919         y=scrn_rect.top;
920         w=scrn_rect.left+scrn_rect.right;
921         h=scrn_rect.top+scrn_rect.bottom;
922         bottom=scrn_rect.bottom;
923
924         float xstart, yfirst, ycentre, ysecond;
925
926         float hgt = bottom * 20.0 /100.0;  // 60% of height should be zoomed
927         yfirst = mid_scr.y - hgt;
928         ycentre = mid_scr.y;
929         ysecond = mid_scr.y + hgt;
930         float range = hgt * 2;
931
932         int i;
933         float factor = range /10.0;
934
935         float hgt1 = bottom * 30.0 /100.0;
936         int  incrs = ((int)val_span - (Maj_div * 2)) / Maj_div ;
937         int  incr = incrs / 2;
938         float factors = hgt1 / incr;
939
940         // begin
941         //this is for moving type pointer
942         static float ycent, ypoint,xpoint;
943         static int wth;
944
945         ycent = mid_scr.y;
946         wth=scrn_rect.left+scrn_rect.right;
947
948         if (cur_value <= data[centre+1])
949             if (cur_value > data[centre]) {
950                 ypoint = ycent + ((cur_value - data[centre]) * hgt/Maj_div);
951             }
952
953         if (cur_value >= data[centre-1])
954             if (cur_value <= data[centre]) {
955                 ypoint = ycent - ((data[centre]-cur_value) * hgt/Maj_div);
956             }
957
958         if (cur_value < data[centre-1])
959             if (cur_value >= minValue) {
960                 float diff  = minValue  - data[centre-1];
961                 float diff1 = cur_value - data[centre-1];
962                 float val = (diff1 * hgt1) / diff;
963
964                 ypoint = ycent - hgt -  val;
965             }
966
967         if (cur_value > data[centre+1])
968             if (cur_value <= maxValue) {
969                 float diff  = maxValue  - data[centre+1];
970                 float diff1 = cur_value - data[centre+1];
971                 float val = (diff1 * hgt1) / diff;
972
973                 ypoint = ycent + hgt +  val;
974             }
975
976         if (huds_left(options)) {
977             xstart = w;
978
979             drawOneLine(xstart, ycentre, xstart - 5.0, ycentre); //centre tick
980
981             sprintf(TextScale,"%3.0f\n",(float)(data[centre] * data_scaling()));
982
983             if (!huds_notext(options)) {
984                 textString (x, ycentre, TextScale, 0);
985             }
986
987             for (i = 1; i < 5; i++) {
988                 yfirst  += factor;
989                 ycentre += factor;
990                 circles(xstart-2.5,yfirst, 3.0);
991                 circles(xstart-2.5,ycentre,3.0);
992             }
993
994             yfirst = mid_scr.y - hgt;
995
996             for (i = 0; i <= incr; i++) {
997                 drawOneLine(xstart, yfirst, xstart - 5.0, yfirst);
998                 drawOneLine(xstart,ysecond, xstart - 5.0,ysecond);
999
1000                 sprintf(TextScale,"%3.0f\n",(float)(data[centre-i-1] * data_scaling()));
1001
1002                 if (!huds_notext(options))
1003                     textString (x, yfirst, TextScale, 0);
1004
1005                 sprintf(TextScale,"%3.0f\n",(float)(data[centre+i+1] * data_scaling()));
1006
1007                 if (!huds_notext(options))
1008                     textString (x, ysecond, TextScale, 0);
1009
1010                 yfirst    -= factors;
1011                 ysecond   += factors;
1012
1013             }
1014
1015             //to draw moving type pointer for left option
1016             //begin
1017             xpoint = wth + 10.0;
1018
1019             if (pointer_type == "moving") {
1020                 drawOneLine(xpoint,ycent,xpoint,ypoint);
1021                 drawOneLine(xpoint,ypoint,xpoint-10.0,ypoint);
1022                 drawOneLine(xpoint-10.0,ypoint,xpoint-5.0,ypoint+5.0);
1023                 drawOneLine(xpoint-10.0,ypoint,xpoint-5.0,ypoint-5.0);
1024             }
1025             //end
1026
1027         } else {
1028             //huds_right
1029             xstart = (x+w)/2;
1030
1031             drawOneLine(xstart, ycentre, xstart + 5.0, ycentre); //centre tick
1032
1033             sprintf(TextScale,"%3.0f\n",(float)(data[centre] * data_scaling()));
1034
1035             if (!huds_notext(options)) {
1036                 textString (w, ycentre, TextScale, 0);
1037             }
1038
1039             for (i = 1; i < 5; i++) {
1040                 yfirst  += factor;
1041                 ycentre += factor;
1042                 circles(xstart+2.5,yfirst, 3.0);
1043                 circles(xstart+2.5,ycentre,3.0);
1044             }
1045
1046             yfirst = mid_scr.y - hgt;
1047
1048             for (i = 0; i <= incr; i++) {
1049                 drawOneLine(xstart, yfirst, xstart + 5.0, yfirst);
1050                 drawOneLine(xstart,ysecond, xstart + 5.0,ysecond);
1051
1052                 sprintf(TextScale,"%3.0f\n",(float)(data[centre-i-1] * data_scaling()));
1053
1054                 if (!huds_notext(options))
1055                     textString(w, yfirst, TextScale, 0);
1056
1057                 sprintf(TextScale,"%3.0f\n",(float)(data[centre+i+1] * data_scaling()));
1058
1059                 if (!huds_notext(options))
1060                     textString(w, ysecond, TextScale, 0);
1061
1062                 yfirst -= factors;
1063                 ysecond += factors;
1064
1065             }
1066
1067             // to draw moving type pointer for right option
1068             //begin
1069             xpoint = scrn_rect.left;
1070
1071             if (pointer_type == "moving") {
1072                 drawOneLine(xpoint,ycent,xpoint,ypoint);
1073                 drawOneLine(xpoint,ypoint,xpoint+10.0,ypoint);
1074                 drawOneLine(xpoint+10.0,ypoint,xpoint+5.0,ypoint+5.0);
1075                 drawOneLine(xpoint+10.0,ypoint,xpoint+5.0,ypoint-5.0);
1076             }
1077             //end
1078         }//end huds_right /left
1079         //end of vertical scale
1080
1081     } else {
1082         //horizontal scale
1083         x=scrn_rect.left;
1084         y=scrn_rect.top;
1085         w=scrn_rect.left+scrn_rect.right;
1086         h=scrn_rect.top+scrn_rect.bottom;
1087         bottom=scrn_rect.right;
1088
1089         float ystart, xfirst, xcentre, xsecond;
1090
1091         float hgt = bottom * 20.0 /100.0;  // 60% of height should be zoomed
1092         xfirst = mid_scr.x - hgt;
1093         xcentre = mid_scr.x;
1094         xsecond = mid_scr.x + hgt;
1095         float range = hgt * 2;
1096
1097         int i;
1098         float factor = range /10.0;
1099
1100         float hgt1 = bottom * 30.0 /100.0;
1101         int  incrs = ((int)val_span - (Maj_div * 2)) / Maj_div ;
1102         int  incr = incrs / 2;
1103         float factors = hgt1 / incr;
1104
1105
1106         //Code for Moving Type Pointer
1107         //begin
1108         static float xcent,xpoint,ypoint;
1109
1110         xcent = mid_scr.x;
1111
1112         if (cur_value <= data[centre+1])
1113             if (cur_value > data[centre]) {
1114                 xpoint = xcent + ((cur_value - data[centre]) * hgt/Maj_div);
1115             }
1116
1117         if (cur_value >= data[centre-1])
1118             if (cur_value <= data[centre]) {
1119                 xpoint = xcent - ((data[centre]-cur_value) * hgt/Maj_div);
1120             }
1121
1122         if (cur_value < data[centre-1])
1123             if (cur_value >= minValue) {
1124                 float diff  = minValue  - data[centre-1];
1125                 float diff1 = cur_value - data[centre-1];
1126                 float val = (diff1 * hgt1) / diff;
1127
1128                 xpoint = xcent - hgt -  val;
1129             }
1130
1131
1132         if (cur_value > data[centre+1])
1133             if (cur_value <= maxValue) {
1134                 float diff  = maxValue  - data[centre+1];
1135                 float diff1 = cur_value - data[centre+1];
1136                 float val = (diff1 * hgt1) / diff;
1137
1138                 xpoint = xcent + hgt +  val;
1139             }
1140
1141         //end
1142         if (huds_top(options)) {
1143
1144             ystart =h;
1145
1146             drawOneLine(xcentre, ystart, xcentre, ystart - 5.0); //centre tick
1147
1148             sprintf(TextScale,"%3.0f\n",(float)(data[centre] * data_scaling()));
1149
1150             if (!huds_notext(options)) {
1151                 textString (xcentre-10.0, y, TextScale, 0);
1152             }
1153
1154             for (i = 1; i < 5; i++) {
1155                 xfirst  += factor;
1156                 xcentre += factor;
1157                 circles(xfirst,  ystart-2.5, 3.0);
1158                 circles(xcentre, ystart-2.5, 3.0);
1159             }
1160
1161             xfirst = mid_scr.x - hgt;
1162
1163             for (i = 0; i <= incr; i++) {
1164                 drawOneLine(xfirst,  ystart, xfirst,  ystart - 5.0);
1165                 drawOneLine(xsecond, ystart, xsecond, ystart - 5.0);
1166
1167                 sprintf(TextScale,"%3.0f\n",(float)(data[centre-i-1] * data_scaling()));
1168
1169                 if (!huds_notext(options))
1170                     textString (xfirst-10.0, y, TextScale, 0);
1171
1172                 sprintf(TextScale,"%3.0f\n",(float)(data[centre+i+1] * data_scaling()));
1173
1174                 if (!huds_notext(options))
1175                     textString (xsecond-10.0, y, TextScale, 0);
1176
1177
1178                 xfirst -= factors;
1179                 xsecond += factors;
1180             }
1181             //this is for moving pointer for top option
1182             //begin
1183
1184             ypoint = scrn_rect.top + scrn_rect.bottom + 10.0;
1185
1186             if (pointer_type == "moving") {
1187                 drawOneLine(xcent, ypoint,xpoint,ypoint);
1188                 drawOneLine(xpoint,ypoint,xpoint,ypoint-10.0);
1189                 drawOneLine(xpoint,ypoint-10.0,xpoint+5.0,ypoint-5.0);
1190                 drawOneLine(xpoint,ypoint-10.0,xpoint-5.0,ypoint-5.0);
1191             }
1192             //end of top option
1193
1194         } else {
1195             //else huds_bottom
1196             ystart = (y + h) / 2;
1197
1198             //drawOneLine(xstart, yfirst,  xstart - 5.0, yfirst);
1199             drawOneLine(xcentre, ystart, xcentre, ystart + 5.0); //centre tick
1200
1201             sprintf(TextScale,"%3.0f\n",(float)(data[centre] * data_scaling()));
1202
1203             if (!huds_notext(options)) {
1204                 textString (xcentre-10.0, h, TextScale, 0);
1205             }
1206
1207             for (i = 1; i < 5; i++) {
1208                 xfirst  += factor;
1209                 xcentre += factor;
1210                 circles(xfirst,  ystart+2.5, 3.0);
1211                 circles(xcentre, ystart+2.5,3.0);
1212             }
1213
1214             xfirst = mid_scr.x - hgt;
1215
1216             for (i = 0; i <= incr; i++) {
1217                 drawOneLine(xfirst, ystart, xfirst, ystart + 5.0);
1218                 drawOneLine(xsecond,ystart, xsecond,ystart + 5.0);
1219
1220                 sprintf(TextScale,"%3.0f\n",(float)(data[centre-i-1] * data_scaling()));
1221
1222                 if (!huds_notext(options))
1223                     textString (xfirst-10.0,h, TextScale, 0);
1224
1225                 sprintf(TextScale,"%3.0f\n",(float)(data[centre+i+1] * data_scaling()));
1226
1227                 if (!huds_notext(options))
1228                     textString (xsecond-10.0,h, TextScale, 0);
1229
1230
1231                 xfirst -= factors;
1232                 xsecond   += factors;
1233
1234             }
1235             //this is for movimg pointer for bottom option
1236             //begin
1237
1238             ypoint = scrn_rect.top - 10.0;
1239             if (pointer_type == "moving") {
1240                 drawOneLine(xcent, ypoint,xpoint,ypoint);
1241                 drawOneLine(xpoint,ypoint,xpoint,ypoint+10.0);
1242                 drawOneLine(xpoint,ypoint+10.0,xpoint+5.0,ypoint+5.0);
1243                 drawOneLine(xpoint,ypoint+10.0,xpoint-5.0,ypoint+5.0);
1244             }
1245         }//end hud_top or hud_bottom
1246     }  //end of horizontal/vertical scales
1247 }//end draw
1248
1249