]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_tape.cxx
- collect drawing primitives in the Item base class
[flightgear.git] / src / Instrumentation / HUD / HUD_tape.cxx
1 // HUD_tape.cxx -- HUD Tape Instrument
2 //
3 // Written by Michele America, started September 1997.
4 //
5 // Copyright (C) 1997  Michele F. America  [micheleamerica#geocities:com]
6 // Copyright (C) 2006  Melchior FRANZ  [mfranz#aon:at]
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
22 #include "HUD.hxx"
23
24
25 HUD::Tape::Tape(HUD *hud, const SGPropertyNode *n, float x, float y) :
26     Scale(hud, n, x, y),
27     _draw_tick_bottom(n->getBoolValue("tick-bottom", false)),
28     _draw_tick_top(n->getBoolValue("tick-top", false)),
29     _draw_tick_right(n->getBoolValue("tick-right", false)),
30     _draw_tick_left(n->getBoolValue("tick-left", false)),
31     _draw_cap_bottom(n->getBoolValue("cap-bottom", false)),
32     _draw_cap_top(n->getBoolValue("cap-top", false)),
33     _draw_cap_right(n->getBoolValue("cap-right", false)),
34     _draw_cap_left(n->getBoolValue("cap-left", false)),
35     _marker_offset(n->getFloatValue("marker-offset", 0.0)),
36     _pointer(n->getBoolValue("enable-pointer", true)),
37     _zoom(n->getIntValue("zoom"))
38 {
39     _half_width_units = range_to_show() / 2.0;
40
41     const char *s = n->getStringValue("pointer-type");
42     _pointer_type = strcmp(s, "moving") ? FIXED : MOVING;    // "fixed", "moving"
43
44     s = n->getStringValue("tick-type");
45     _tick_type = strcmp(s, "circle") ? LINE : CIRCLE;        // "circle", "line"
46
47     s = n->getStringValue("tick-length");                    // "variable", "constant"
48     _tick_length = strcmp(s, "constant") ? VARIABLE : CONSTANT;
49 }
50
51
52 void HUD::Tape::draw(void) //  (HUD_scale * pscale)
53 {
54     if (!_input.isValid())
55         return;
56
57     float vmin = 0.0, vmax = 0.0;
58     float marker_xs;
59     float marker_xe;
60     float marker_ys;
61     float marker_ye;
62     float text_x = 0.0, text_y = 0.0;
63     int lenstr;
64     float height, width;
65     int i, last;
66     const int BUFSIZE = 80;
67     char buf[BUFSIZE];
68     bool condition;
69     int disp_val = 0;
70     int oddtype, k; //odd or even values for ticks
71
72     Point mid_scr = get_centroid();
73     float cur_value = _input.getFloatValue();
74
75     if ((int)_input.max() & 1)
76         oddtype = 1; //draw ticks at odd values
77     else
78         oddtype = 0; //draw ticks at even values
79
80     Rect scrn_rect = get_location();
81
82     height = scrn_rect.top + scrn_rect.bottom;
83     width = scrn_rect.left + scrn_rect.right;
84
85
86     if (_pointer) {
87         if (_pointer_type == MOVING) {
88             vmin = _input.min();
89             vmax = _input.max();
90
91         } else {
92             // default to fixed
93             vmin = cur_value - _half_width_units; // width units == needle travel
94             vmax = cur_value + _half_width_units; // or picture unit span.
95             text_x = mid_scr.x;
96             text_y = mid_scr.y;
97         }
98
99     } else {
100         vmin = cur_value - _half_width_units; // width units == needle travel
101         vmax = cur_value + _half_width_units; // or picture unit span.
102         text_x = mid_scr.x;
103         text_y = mid_scr.y;
104     }
105
106     // Draw the basic markings for the scale...
107
108     if (option_vert()) { // Vertical scale
109         // Bottom tick bar
110         if (_draw_tick_bottom)
111             draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
112
113         // Top tick bar
114         if (_draw_tick_top)
115             draw_line(scrn_rect.left, height, width, height);
116
117         marker_xs = scrn_rect.left;  // x start
118         marker_xe = width;           // x extent
119         marker_ye = height;
120
121         //    glBegin(GL_LINES);
122
123         // Bottom tick bar
124         //    glVertex2f(marker_xs, scrn_rect.top);
125         //    glVertex2f(marker_xe, scrn_rect.top);
126
127         // Top tick bar
128         //    glVertex2f(marker_xs, marker_ye);
129         //    glVertex2f(marker_xe, marker_ye);
130         //    glEnd();
131
132
133         // We do not use else in the following so that combining the
134         // two options produces a "caged" display with double
135         // carrots. The same is done for horizontal card indicators.
136
137         // begin vertical/left
138         //First draw capping lines and pointers
139         if (option_left()) {    // Calculate x marker offset
140
141             if (_draw_cap_right) {
142                 // Cap right side
143                 draw_line(marker_xe, scrn_rect.top, marker_xe, marker_ye);
144             }
145
146             marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
147
148             // draw_line(marker_xs, mid_scr.y,
149             //              marker_xe, mid_scr.y + scrn_rect.right / 6);
150             // draw_line(marker_xs, mid_scr.y,
151             //              marker_xe, mid_scr.y - scrn_rect.right / 6);
152
153             // draw pointer
154             if (_pointer) {
155                 if (_pointer_type == MOVING) {
156                     if (_zoom == 0) {
157                         //Code for Moving Type Pointer
158                         float ycentre, ypoint, xpoint;
159                         float range, wth;
160                         if (cur_value > _input.max())
161                             cur_value = _input.max();
162                         if (cur_value < _input.min())
163                             cur_value = _input.min();
164
165                         if (_input.min() >= 0.0)
166                             ycentre = scrn_rect.top;
167                         else if (_input.max() + _input.min() == 0.0)
168                             ycentre = mid_scr.y;
169                         else if (oddtype == 1)
170                             ycentre = scrn_rect.top + (1.0 - _input.min()) * scrn_rect.bottom
171                                     / (_input.max() - _input.min());
172                         else
173                             ycentre = scrn_rect.top + _input.min() * scrn_rect.bottom
174                                     / (_input.max() - _input.min());
175
176                         range = scrn_rect.bottom;
177                         wth = scrn_rect.left + scrn_rect.right;
178
179                         if (oddtype == 1)
180                             ypoint = ycentre + ((cur_value - 1.0) * range / _val_span);
181                         else
182                             ypoint = ycentre + (cur_value * range / _val_span);
183
184                         xpoint = wth + _marker_offset;
185                         draw_line(xpoint, ycentre, xpoint, ypoint);
186                         draw_line(xpoint, ypoint, xpoint - _marker_offset, ypoint);
187                         draw_line(xpoint - _marker_offset, ypoint, xpoint - 5.0, ypoint + 5.0);
188                         draw_line(xpoint - _marker_offset, ypoint, xpoint - 5.0, ypoint - 5.0);
189                     } //_zoom=0
190
191                 } else {
192                     // default to fixed
193                     fixed(_marker_offset + marker_xe, text_y + scrn_rect.right / 6,
194                             _marker_offset + marker_xs, text_y, _marker_offset + marker_xe,
195                             text_y - scrn_rect.right / 6);
196                 }//end pointer type
197             } //if pointer
198         } //end vertical/left
199
200         // begin vertical/right
201         //First draw capping lines and pointers
202         if (option_right()) {  // We'll default this for now.
203             if (_draw_cap_left) {
204                 // Cap left side
205                 draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, marker_ye);
206             } //endif cap_left
207
208             marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
209             // Indicator carrot
210             // draw_line(scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
211             //              marker_xe, mid_scr.y);
212             // draw_line(scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
213             //              marker_xe, mid_scr.y);
214
215             // draw pointer
216             if (_pointer) {
217                 if (_pointer_type == MOVING) {
218                     if (_zoom == 0) {
219                         //type-fixed & _zoom=1, behaviour to be defined
220                         // Code for Moving Type Pointer
221                         float ycentre, ypoint, xpoint;
222                         float range;
223
224                         if (cur_value > _input.max())
225                             cur_value = _input.max();
226                         if (cur_value < _input.min())
227                             cur_value = _input.min();
228
229                         if (_input.min() >= 0.0)
230                             ycentre = scrn_rect.top;
231                         else if (_input.max() + _input.min() == 0.0)
232                             ycentre = mid_scr.y;
233                         else if (oddtype == 1)
234                             ycentre = scrn_rect.top + (1.0 - _input.min()) * scrn_rect.bottom / (_input.max() - _input.min());
235                         else
236                             ycentre = scrn_rect.top + _input.min() * scrn_rect.bottom / (_input.max() - _input.min());
237
238                         range = scrn_rect.bottom;
239
240                         if (oddtype == 1)
241                             ypoint = ycentre + ((cur_value - 1.0) * range / _val_span);
242                         else
243                             ypoint = ycentre + (cur_value * range / _val_span);
244
245                         xpoint = scrn_rect.left - _marker_offset;
246                         draw_line(xpoint, ycentre, xpoint, ypoint);
247                         draw_line(xpoint, ypoint, xpoint + _marker_offset, ypoint);
248                         draw_line(xpoint + _marker_offset, ypoint, xpoint + 5.0, ypoint + 5.0);
249                         draw_line(xpoint + _marker_offset, ypoint, xpoint + 5.0, ypoint - 5.0);
250                     }
251
252                 } else {
253                     // default to fixed
254                     fixed(-_marker_offset + scrn_rect.left, text_y +  scrn_rect.right / 6,
255                             -_marker_offset + marker_xe, text_y, -_marker_offset + scrn_rect.left,
256                             text_y - scrn_rect.right / 6);
257                 }
258             } //if pointer
259         }  //end vertical/right
260
261         // At this point marker x_start and x_end values are transposed.
262         // To keep this from confusing things they are now interchanged.
263         if (option_both()) {
264             marker_ye = marker_xs;
265             marker_xs = marker_xe;
266             marker_xe = marker_ye;
267         }
268
269         // Work through from bottom to top of scale. Calculating where to put
270         // minor and major ticks.
271
272         // draw scale or tape
273         last = (int)vmax + 1; // N
274         i = (int)vmin; // N
275
276         if (_zoom == 1) {
277             zoomed_scale((int)vmin, (int)vmax);
278         } else {
279             for (; i < last; i++) {
280                 condition = true;
281                 if (!modulo() && i < _input.min())
282                     condition = false;
283
284                 if (condition) {  // Show a tick if necessary
285                     // Calculate the location of this tick
286                     marker_ys = scrn_rect.top + ((i - vmin) * factor()/*+.5f*/);
287                     // marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
288                     // Block calculation artifact from drawing ticks below min coordinate.
289                     // Calculation here accounts for text height.
290
291                     if ((marker_ys < (scrn_rect.top + 4))
292                             || (marker_ys > (height - 4))) {
293                         // Magic numbers!!!
294                         continue;
295                     }
296
297                     if (oddtype == 1)
298                         k = i + 1; //enable ticks at odd values
299                     else
300                         k = i;
301
302                     // Minor ticks
303                     if (_minor_divs) {
304                         // if ((i % _minor_divs) == 0) {
305                         if (!(k % (int)_minor_divs)) {
306                             if (((marker_ys - 5) > scrn_rect.top)
307                                     && ((marker_ys + 5) < (height))) {
308
309                                 //vertical/left OR vertical/right
310                                 if (option_both()) {
311                                     if (_tick_type == LINE) {
312                                         if (_tick_length == VARIABLE) {
313                                             draw_line(scrn_rect.left, marker_ys,
314                                                     marker_xs, marker_ys);
315                                             draw_line(marker_xe, marker_ys,
316                                                     width, marker_ys);
317                                         } else {
318                                             draw_line(scrn_rect.left, marker_ys,
319                                                     marker_xs, marker_ys);
320                                             draw_line(marker_xe, marker_ys,
321                                                     width, marker_ys);
322                                         }
323
324                                     } else if (_tick_type == CIRCLE) {
325                                         draw_bullet(scrn_rect.left,(float)marker_ys, 3.0);
326
327                                     } else {
328                                         // if neither line nor circle draw default as line
329                                         draw_line(scrn_rect.left, marker_ys,
330                                                 marker_xs, marker_ys);
331                                         draw_line(marker_xe, marker_ys,
332                                                 width, marker_ys);
333                                     }
334                                     // glBegin(GL_LINES);
335                                     // glVertex2f(scrn_rect.left, marker_ys);
336                                     // glVertex2f(marker_xs,      marker_ys);
337                                     // glVertex2f(marker_xe,      marker_ys);
338                                     // glVertex2f(scrn_rect.left + scrn_rect.right,  marker_ys);
339                                     // glEnd();
340                                     // anything other than option_both
341
342                                 } else {
343                                     if (option_left()) {
344                                         if (_tick_type == LINE) {
345                                             if (_tick_length == VARIABLE) {
346                                                 draw_line(marker_xs + 4, marker_ys,
347                                                         marker_xe, marker_ys);
348                                             } else {
349                                                 draw_line(marker_xs, marker_ys,
350                                                         marker_xe, marker_ys);
351                                             }
352                                         } else if (_tick_type == CIRCLE) {
353                                             draw_bullet((float)marker_xs + 4, (float)marker_ys, 3.0);
354
355                                         } else {
356                                             draw_line(marker_xs + 4, marker_ys,
357                                                     marker_xe, marker_ys);
358                                         }
359
360                                     }  else {
361                                         if (_tick_type == LINE) {
362                                             if (_tick_length == VARIABLE) {
363                                                 draw_line(marker_xs, marker_ys,
364                                                         marker_xe - 4, marker_ys);
365                                             } else {
366                                                 draw_line(marker_xs, marker_ys,
367                                                         marker_xe, marker_ys);
368                                             }
369
370                                         } else if (_tick_type == CIRCLE) {
371                                             draw_bullet((float)marker_xe - 4, (float)marker_ys, 3.0);
372                                         } else {
373                                             draw_line(marker_xs, marker_ys,
374                                                     marker_xe - 4, marker_ys);
375                                         }
376                                     }
377                                 } //end huds both
378                             }
379                         } //end draw minor ticks
380                     }  //end minor ticks
381
382                     // Major ticks
383                     if (_major_divs) {
384                         if (!(k % (int)_major_divs)) {
385
386                             if (modulo()) {
387                                 disp_val = i % (int) modulo(); // ?????????
388                                 if (disp_val < 0) {
389                                     while (disp_val < 0)
390                                         disp_val += modulo();
391                                 }
392                             } else {
393                                 disp_val = i;
394                             }
395
396 // FIXME what nonsense is this?!?
397                             lenstr = snprintf(buf, BUFSIZE, "%d", int(disp_val * _input.factor()/*+.5*/));   // was data_scaling ... makes no sense at all
398                             // (int)(disp_val  * data_scaling() +.5));
399                             /* if (((marker_ys - 8) > scrn_rect.top) &&
400                                ((marker_ys + 8) < (height))){ */
401                             // option_both
402                             if (option_both()) {
403                                 // draw_line(scrn_rect.left, marker_ys,
404                                 //              marker_xs,      marker_ys);
405                                 // draw_line(marker_xs, marker_ys,
406                                 //              scrn_rect.left + scrn_rect.right,
407                                 //              marker_ys);
408                                 if (_tick_type == LINE) {
409                                     glBegin(GL_LINE_STRIP);
410                                     glVertex2f(scrn_rect.left, marker_ys);
411                                     glVertex2f(marker_xs, marker_ys);
412                                     glVertex2f(width, marker_ys);
413                                     glEnd();
414
415                                 } else if (_tick_type == CIRCLE) {
416                                     draw_bullet(scrn_rect.left, (float)marker_ys, 5.0);
417
418                                 } else {
419                                     glBegin(GL_LINE_STRIP);
420                                     glVertex2f(scrn_rect.left, marker_ys);
421                                     glVertex2f(marker_xs, marker_ys);
422                                     glVertex2f(width, marker_ys);
423                                     glEnd();
424                                 }
425
426                                 if (!option_notext())
427                                     draw_text(marker_xs + 2, marker_ys, buf, 0);
428
429                             } else {
430                                 /* Changes are made to draw a circle when tick_type=CIRCLE */
431                                 // anything other than option_both
432                                 if (_tick_type == LINE)
433                                     draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
434                                 else if (_tick_type == CIRCLE)
435                                     draw_bullet((float)marker_xs + 4, (float)marker_ys, 5.0);
436                                 else
437                                     draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
438
439                                 if (!option_notext()) {
440                                     if (option_left()) {
441                                         draw_text(marker_xs - 8 * lenstr - 2,
442                                                 marker_ys - 4, buf, 0);
443                                     } else {
444                                         draw_text(marker_xe + 3 * lenstr,
445                                                 marker_ys - 4, buf, 0);
446                                     } //End if option_left
447                                 } //End if !option_notext
448                             }  //End if huds-both
449                         }  // End if draw major ticks
450                     }   // End if major ticks
451                 }  // End condition
452             }  // End for
453         }  //end of zoom
454         // End if VERTICAL SCALE TYPE (tape loop yet to be closed)
455
456     } else {
457         // Horizontal scale by default
458         // left tick bar
459         if (_draw_tick_left)
460             draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
461
462         // right tick bar
463         if (_draw_tick_right)
464             draw_line(width, scrn_rect.top, width, height);
465
466         marker_ys = scrn_rect.top;    // Starting point for
467         marker_ye = height;           // tick y location calcs
468         marker_xe = width;
469         marker_xs = scrn_rect.left + ((cur_value - vmin) * factor() /*+ .5f*/);
470
471         //    glBegin(GL_LINES);
472         // left tick bar
473         //    glVertex2f(scrn_rect.left, scrn_rect.top);
474         //    glVertex2f(scrn_rect.left, marker_ye);
475
476         // right tick bar
477         //    glVertex2f(marker_xe, scrn_rect.top);
478         //    glVertex2f(marker_xe, marker_ye);
479         //    glEnd();
480
481         if (option_top()) {
482             // Bottom box line
483             if (_draw_cap_bottom)
484                 draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
485
486             // Tick point adjust
487             marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;
488             // Bottom arrow
489             // draw_line(mid_scr.x, marker_ye,
490             //              mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
491             // draw_line(mid_scr.x, marker_ye,
492             //              mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
493             // draw pointer
494             if (_pointer) {
495                 if (_pointer_type == MOVING) {
496                     if (_zoom == 0) {
497                         //Code for Moving Type Pointer
498                         // static float xcentre, xpoint, ypoint;
499                         // static int range;
500                         if (cur_value > _input.max())
501                             cur_value = _input.max();
502                         if (cur_value < _input.min())
503                             cur_value = _input.min();
504
505                         float xcentre = mid_scr.x;
506                         float range = scrn_rect.right;
507                         float xpoint = xcentre + (cur_value * range / _val_span);
508                         float ypoint = scrn_rect.top - _marker_offset;
509                         draw_line(xcentre, ypoint, xpoint, ypoint);
510                         draw_line(xpoint, ypoint, xpoint, ypoint + _marker_offset);
511                         draw_line(xpoint, ypoint + _marker_offset, xpoint + 5.0, ypoint + 5.0);
512                         draw_line(xpoint, ypoint + _marker_offset, xpoint - 5.0, ypoint + 5.0);
513                     }
514
515                 } else {
516                     //default to fixed
517                     fixed(marker_xs - scrn_rect.bottom / 4, scrn_rect.top, marker_xs,
518                             marker_ye, marker_xs + scrn_rect.bottom / 4, scrn_rect.top);
519                 }
520             }  //if pointer
521         } //End Horizontal scale/top
522
523         if (option_bottom()) {
524             // Top box line
525             if (_draw_cap_top)
526                 draw_line(scrn_rect.left, height, width, height);
527
528             // Tick point adjust
529             marker_ys = height - scrn_rect.bottom / 2;
530             // Top arrow
531             //      draw_line(mid_scr.x + scrn_rect.bottom / 4,
532             //                   scrn_rect.top + scrn_rect.bottom,
533             //                   mid_scr.x, marker_ys);
534             //      draw_line(mid_scr.x - scrn_rect.bottom / 4,
535             //                   scrn_rect.top + scrn_rect.bottom,
536             //                   mid_scr.x , marker_ys);
537
538             // draw pointer
539             if (_pointer) {
540                 if (_pointer_type == MOVING) {
541                     if (_zoom == 0) {
542                         //Code for Moving Type Pointer
543                         // static float xcentre, xpoint, ypoint;
544                         // static int range, hgt;
545                         if (cur_value > _input.max())
546                             cur_value = _input.max();
547                         if (cur_value < _input.min())
548                             cur_value = _input.min();
549
550                         float xcentre = mid_scr.x ;
551                         float range = scrn_rect.right;
552                         float hgt = scrn_rect.top + scrn_rect.bottom;
553                         float xpoint = xcentre + (cur_value * range / _val_span);
554                         float ypoint = hgt + _marker_offset;
555                         draw_line(xcentre, ypoint, xpoint, ypoint);
556                         draw_line(xpoint, ypoint, xpoint, ypoint - _marker_offset);
557                         draw_line(xpoint, ypoint - _marker_offset, xpoint + 5.0, ypoint - 5.0);
558                         draw_line(xpoint, ypoint - _marker_offset, xpoint - 5.0, ypoint - 5.0);
559                     }
560                 } else {
561                     fixed(marker_xs + scrn_rect.bottom / 4, height, marker_xs, marker_ys,
562                             marker_xs - scrn_rect.bottom / 4, height);
563                 }
564             } //if pointer
565         }  //end horizontal scale bottom
566
567
568         if (_zoom == 1) {
569             zoomed_scale((int)vmin,(int)vmax);
570         } else {
571             //default to _zoom=0
572             last = (int)vmax + 1;
573             i = (int)vmin;
574             for (; i < last; i++) {
575                 // for (i = (int)vmin; i <= (int)vmax; i++)     {
576                 // printf("<*> i = %d\n", i);
577                 condition = true;
578                 if (!modulo() && i < _input.min())
579                     condition = false;
580
581                 // printf("<**> i = %d\n", i);
582                 if (condition) {
583                     // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
584                     marker_xs = scrn_rect.left + (((i - vmin) * factor()/*+ .5f*/));
585
586                     if (oddtype == 1)
587                         k = i + 1; //enable ticks at odd values
588                     else
589                         k = i;
590
591                     if (_minor_divs) {
592                         //          if ((i % (int)_minor_divs) == 0) {
593                         //draw minor ticks
594                         if (!(k % (int)_minor_divs)) {
595                             // draw in ticks only if they aren't too close to the edge.
596                             if (((marker_xs - 5) > scrn_rect.left)
597                                     && ((marker_xs + 5)< (scrn_rect.left + scrn_rect.right))) {
598
599                                 if (option_both()) {
600                                     if (_tick_length == VARIABLE) {
601                                         draw_line(marker_xs, scrn_rect.top,
602                                                 marker_xs, marker_ys - 4);
603                                         draw_line(marker_xs, marker_ye + 4,
604                                                 marker_xs, height);
605                                     } else {
606                                         draw_line(marker_xs, scrn_rect.top,
607                                                 marker_xs, marker_ys);
608                                         draw_line(marker_xs, marker_ye,
609                                                 marker_xs, height);
610                                     }
611                                     // glBegin(GL_LINES);
612                                     // glVertex2f(marker_xs, scrn_rect.top);
613                                     // glVertex2f(marker_xs, marker_ys - 4);
614                                     // glVertex2f(marker_xs, marker_ye + 4);
615                                     // glVertex2f(marker_xs, scrn_rect.top + scrn_rect.bottom);
616                                     // glEnd();
617
618                                 } else {
619                                     if (option_top()) {
620                                         //draw minor ticks
621                                         if (_tick_length == VARIABLE)
622                                             draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
623                                         else
624                                             draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
625
626                                     } else if (_tick_length == VARIABLE) {
627                                         draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
628                                     } else {
629                                         draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
630                                     }
631                                 }
632                             }
633                         } //end draw minor ticks
634                     } //end minor ticks
635
636                     //major ticks
637                     if (_major_divs) {
638                         // printf("i = %d\n", i);
639                         // if ((i % (int)_major_divs)==0) {
640                         //     draw major ticks
641
642                         if (!(k % (int)_major_divs)) {
643                             if (modulo()) {
644                                 disp_val = i % (int) modulo(); // ?????????
645                                 if (disp_val < 0) {
646                                     while (disp_val<0)
647                                         disp_val += modulo();
648                                 }
649                             } else {
650                                 disp_val = i;
651                             }
652                             // printf("disp_val = %d\n", disp_val);
653                             // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
654                             lenstr = snprintf(buf, BUFSIZE, "%d",
655                                     // (int)(disp_val  * data_scaling() +.5));
656                                     int(disp_val * _input.factor() /*+.5*/));  // was data_scaling() ... makes no sense at all
657
658                             // Draw major ticks and text only if far enough from the edge.
659                             if (((marker_xs - 10)> scrn_rect.left)
660                                     && ((marker_xs + 10) < (scrn_rect.left + scrn_rect.right))) {
661                                 if (option_both()) {
662                                     // draw_line(marker_xs, scrn_rect.top,
663                                     //              marker_xs, marker_ys);
664                                     // draw_line(marker_xs, marker_ye,
665                                     //              marker_xs, scrn_rect.top + scrn_rect.bottom);
666                                     glBegin(GL_LINE_STRIP);
667                                     glVertex2f(marker_xs, scrn_rect.top);
668                                     glVertex2f(marker_xs, marker_ye);
669                                     glVertex2f(marker_xs, height);
670                                     glEnd();
671
672                                     if (!option_notext()) {
673                                         draw_text(marker_xs - 4 * lenstr,
674                                                 marker_ys + 4, buf, 0);
675                                     }
676                                 } else {
677                                     draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
678
679                                     if (!option_notext()) {
680                                         if (option_top()) {
681                                             draw_text(marker_xs - 4 * lenstr,
682                                                     height - 10, buf, 0);
683
684                                         }  else  {
685                                             draw_text(marker_xs - 4 * lenstr,
686                                                     scrn_rect.top, buf, 0);
687                                         }
688                                     }
689                                 }
690                             }
691                         }  //end draw major ticks
692                     } //endif major ticks
693                 }   //end condition
694             } //end for
695         }  //end zoom
696     } //end horizontal/vertical scale
697 } //draw
698
699
700
701 void HUD::Tape::fixed(float x1, float y1, float x2, float y2, float x3, float y3)
702 {
703     glBegin(GL_LINE_STRIP);
704     glVertex2f(x1, y1);
705     glVertex2f(x2, y2);
706     glVertex2f(x3, y3);
707     glEnd();
708 }
709
710
711 void HUD::Tape::zoomed_scale(int first, int last)
712 {
713     Point mid_scr = get_centroid();
714     Rect scrn_rect = get_location();
715     const int BUFSIZE = 80;
716     char buf[BUFSIZE];
717     int data[80];
718
719     float x, y, w, h, bottom;
720     float cur_value = _input.getFloatValue();
721     if (cur_value > _input.max())
722         cur_value = _input.max();
723     if (cur_value < _input.min())
724         cur_value = _input.min();
725
726     int a = 0;
727
728     while (first <= last) {
729         if ((first % (int)_major_divs) == 0) {
730             data[a] = first;
731             a++ ;
732         }
733         first++;
734     }
735     int centre = a / 2;
736
737     if (option_vert()) {
738         x = scrn_rect.left;
739         y = scrn_rect.top;
740         w = scrn_rect.left + scrn_rect.right;
741         h = scrn_rect.top + scrn_rect.bottom;
742         bottom = scrn_rect.bottom;
743
744         float xstart, yfirst, ycentre, ysecond;
745
746         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
747         yfirst = mid_scr.y - hgt;
748         ycentre = mid_scr.y;
749         ysecond = mid_scr.y + hgt;
750         float range = hgt * 2;
751
752         int i;
753         float factor = range / 10.0;
754
755         float hgt1 = bottom * 30.0 / 100.0;
756         int  incrs = ((int)_val_span - (_major_divs * 2)) / _major_divs ;
757         int  incr = incrs / 2;
758         float factors = hgt1 / incr;
759
760         // begin
761         //this is for moving type pointer
762         static float ycent, ypoint, xpoint;
763         static float wth;
764
765         ycent = mid_scr.y;
766         wth = scrn_rect.left + scrn_rect.right;
767
768         if (cur_value <= data[centre + 1])
769             if (cur_value > data[centre]) {
770                 ypoint = ycent + ((cur_value - data[centre]) * hgt / _major_divs);
771             }
772
773         if (cur_value >= data[centre - 1])
774             if (cur_value <= data[centre]) {
775                 ypoint = ycent - ((data[centre] - cur_value) * hgt / _major_divs);
776             }
777
778         if (cur_value < data[centre - 1])
779             if (cur_value >= _input.min()) {
780                 float diff  = _input.min() - data[centre - 1];
781                 float diff1 = cur_value - data[centre - 1];
782                 float val = (diff1 * hgt1) / diff;
783
784                 ypoint = ycent - hgt - val;
785             }
786
787         if (cur_value > data[centre + 1])
788             if (cur_value <= _input.max()) {
789                 float diff  = _input.max() - data[centre + 1];
790                 float diff1 = cur_value - data[centre + 1];
791                 float val = (diff1 * hgt1) / diff;
792
793                 ypoint = ycent + hgt + val;
794             }
795
796         if (option_left()) {
797             xstart = w;
798
799             draw_line(xstart, ycentre, xstart - 5.0, ycentre); //centre tick
800
801             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes not sense at all
802
803             if (!option_notext())
804                 draw_text(x, ycentre, buf, 0);
805
806             for (i = 1; i < 5; i++) {
807                 yfirst += factor;
808                 ycentre += factor;
809                 draw_bullet(xstart - 2.5, yfirst, 3.0);
810                 draw_bullet(xstart - 2.5, ycentre, 3.0);
811             }
812
813             yfirst = mid_scr.y - hgt;
814
815             for (i = 0; i <= incr; i++) {
816                 draw_line(xstart, yfirst, xstart - 5.0, yfirst);
817                 draw_line(xstart, ysecond, xstart - 5.0, ysecond);
818
819                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor()));  // was data_scaling() ... makes no sense at all
820
821                 if (!option_notext())
822                     draw_text(x, yfirst, buf, 0);
823
824                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
825
826                 if (!option_notext())
827                     draw_text(x, ysecond, buf, 0);
828
829                 yfirst -= factors;
830                 ysecond += factors;
831
832             }
833
834             //to draw moving type pointer for left option
835             //begin
836             xpoint = wth + 10.0;
837
838             if (_pointer_type == MOVING) {
839                 draw_line(xpoint, ycent, xpoint, ypoint);
840                 draw_line(xpoint, ypoint, xpoint - 10.0, ypoint);
841                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint + 5.0);
842                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint - 5.0);
843             }
844             //end
845
846         } else {
847             //option_right
848             xstart = (x + w) / 2;
849
850             draw_line(xstart, ycentre, xstart + 5.0, ycentre); //centre tick
851
852             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
853
854             if (!option_notext())
855                 draw_text(w, ycentre, buf, 0);
856
857             for (i = 1; i < 5; i++) {
858                 yfirst += factor;
859                 ycentre += factor;
860                 draw_bullet(xstart + 2.5, yfirst, 3.0);
861                 draw_bullet(xstart + 2.5, ycentre, 3.0);
862             }
863
864             yfirst = mid_scr.y - hgt;
865
866             for (i = 0; i <= incr; i++) {
867                 draw_line(xstart, yfirst, xstart + 5.0, yfirst);
868                 draw_line(xstart, ysecond, xstart + 5.0, ysecond);
869
870                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
871
872                 if (!option_notext())
873                     draw_text(w, yfirst, buf, 0);
874
875                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor()));
876
877                 if (!option_notext())
878                     draw_text(w, ysecond, buf, 0);
879
880                 yfirst -= factors;
881                 ysecond += factors;
882
883             }
884
885             // to draw moving type pointer for right option
886             //begin
887             xpoint = scrn_rect.left;
888
889             if (_pointer_type == MOVING) {
890                 draw_line(xpoint, ycent, xpoint, ypoint);
891                 draw_line(xpoint, ypoint, xpoint + 10.0, ypoint);
892                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint + 5.0);
893                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint - 5.0);
894             }
895             //end
896         }//end option_right /left
897         //end of vertical scale
898
899     } else {
900         //horizontal scale
901         x = scrn_rect.left;
902         y = scrn_rect.top;
903         w = scrn_rect.left + scrn_rect.right;
904         h = scrn_rect.top + scrn_rect.bottom;
905         bottom = scrn_rect.right;
906
907         float ystart, xfirst, xcentre, xsecond;
908
909         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
910         xfirst = mid_scr.x - hgt;
911         xcentre = mid_scr.x;
912         xsecond = mid_scr.x + hgt;
913         float range = hgt * 2;
914
915         int i;
916         float factor = range / 10.0;
917
918         float hgt1 = bottom * 30.0 / 100.0;
919         int  incrs = ((int)_val_span - (_major_divs * 2)) / _major_divs ;
920         int  incr = incrs / 2;
921         float factors = hgt1 / incr;
922
923
924         //Code for Moving Type Pointer
925         //begin
926         static float xcent, xpoint, ypoint;
927
928         xcent = mid_scr.x;
929
930         if (cur_value <= data[centre + 1])
931             if (cur_value > data[centre]) {
932                 xpoint = xcent + ((cur_value - data[centre]) * hgt / _major_divs);
933             }
934
935         if (cur_value >= data[centre - 1])
936             if (cur_value <= data[centre]) {
937                 xpoint = xcent - ((data[centre] - cur_value) * hgt / _major_divs);
938             }
939
940         if (cur_value < data[centre - 1])
941             if (cur_value >= _input.min()) {
942                 float diff = _input.min() - data[centre - 1];
943                 float diff1 = cur_value - data[centre - 1];
944                 float val = (diff1 * hgt1) / diff;
945
946                 xpoint = xcent - hgt - val;
947             }
948
949
950         if (cur_value > data[centre + 1])
951             if (cur_value <= _input.max()) {
952                 float diff = _input.max() - data[centre + 1];
953                 float diff1 = cur_value - data[centre + 1];
954                 float val = (diff1 * hgt1) / diff;
955
956                 xpoint = xcent + hgt + val;
957             }
958
959         //end
960         if (option_top()) {
961             ystart = h;
962             draw_line(xcentre, ystart, xcentre, ystart - 5.0); //centre tick
963
964             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor()));  // was data_scaling() ... makes no sense at all
965
966             if (!option_notext())
967                 draw_text(xcentre - 10.0, y, buf, 0);
968
969             for (i = 1; i < 5; i++) {
970                 xfirst += factor;
971                 xcentre += factor;
972                 draw_bullet(xfirst, ystart - 2.5, 3.0);
973                 draw_bullet(xcentre, ystart - 2.5, 3.0);
974             }
975
976             xfirst = mid_scr.x - hgt;
977
978             for (i = 0; i <= incr; i++) {
979                 draw_line(xfirst, ystart, xfirst,  ystart - 5.0);
980                 draw_line(xsecond, ystart, xsecond, ystart - 5.0);
981
982                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
983
984                 if (!option_notext())
985                     draw_text(xfirst - 10.0, y, buf, 0);
986
987                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
988
989                 if (!option_notext())
990                     draw_text(xsecond - 10.0, y, buf, 0);
991
992
993                 xfirst -= factors;
994                 xsecond += factors;
995             }
996             //this is for moving pointer for top option
997             //begin
998
999             ypoint = scrn_rect.top + scrn_rect.bottom + 10.0;
1000
1001             if (_pointer_type == MOVING) {
1002                 draw_line(xcent, ypoint, xpoint, ypoint);
1003                 draw_line(xpoint, ypoint, xpoint, ypoint - 10.0);
1004                 draw_line(xpoint, ypoint - 10.0, xpoint + 5.0, ypoint - 5.0);
1005                 draw_line(xpoint, ypoint - 10.0, xpoint - 5.0, ypoint - 5.0);
1006             }
1007             //end of top option
1008
1009         } else {
1010             //else option_bottom
1011             ystart = (y + h) / 2;
1012
1013             //draw_line(xstart, yfirst,  xstart - 5.0, yfirst);
1014             draw_line(xcentre, ystart, xcentre, ystart + 5.0); //centre tick
1015
1016             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
1017
1018             if (!option_notext())
1019                 draw_text(xcentre - 10.0, h, buf, 0);
1020
1021             for (i = 1; i < 5; i++) {
1022                 xfirst += factor;
1023                 xcentre += factor;
1024                 draw_bullet(xfirst, ystart + 2.5, 3.0);
1025                 draw_bullet(xcentre, ystart + 2.5, 3.0);
1026             }
1027
1028             xfirst = mid_scr.x - hgt;
1029
1030             for (i = 0; i <= incr; i++) {
1031                 draw_line(xfirst, ystart, xfirst, ystart + 5.0);
1032                 draw_line(xsecond, ystart, xsecond, ystart + 5.0);
1033
1034                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
1035
1036                 if (!option_notext())
1037                     draw_text(xfirst - 10.0, h, buf, 0);
1038
1039                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
1040
1041                 if (!option_notext())
1042                     draw_text(xsecond - 10.0, h, buf, 0);
1043
1044                 xfirst -= factors;
1045                 xsecond   += factors;
1046             }
1047             //this is for movimg pointer for bottom option
1048             //begin
1049
1050             ypoint = scrn_rect.top - 10.0;
1051             if (_pointer_type == MOVING) {
1052                 draw_line(xcent, ypoint, xpoint, ypoint);
1053                 draw_line(xpoint, ypoint, xpoint, ypoint + 10.0);
1054                 draw_line(xpoint, ypoint + 10.0, xpoint + 5.0, ypoint + 5.0);
1055                 draw_line(xpoint, ypoint + 10.0, xpoint - 5.0, ypoint + 5.0);
1056             }
1057         }//end hud_top or hud_bottom
1058     }  //end of horizontal/vertical scales
1059 }//end draw
1060
1061