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