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