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