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