]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_tape.cxx
96a52802e4cff4777e11c5f1985a5fb887d00528
[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;
42     s = n->getStringValue("pointer-type");
43     _pointer_type = strcmp(s, "moving") ? FIXED : MOVING;    // "fixed", "moving"
44
45     s = n->getStringValue("tick-type");
46     _tick_type = strcmp(s, "circle") ? LINE : CIRCLE;        // "circle", "line"
47
48     s = n->getStringValue("tick-length");                    // "variable", "constant"
49     _tick_length = strcmp(s, "constant") ? VARIABLE : CONSTANT;
50 }
51
52
53 void HUD::Tape::draw(void) //  (HUD_scale * pscale)
54 {
55     if (!_input.isValid())
56         return;
57
58     float vmin = 0.0, vmax = 0.0;
59     float marker_xs;
60     float marker_xe;
61     float marker_ys;
62     float marker_ye;
63     float text_x = 0.0, text_y = 0.0;
64     const int BUFSIZE = 80;
65     char buf[BUFSIZE];
66     int oddtype;
67 //    int k; //odd or even values for ticks             // FIXME odd scale
68
69     float cur_value = _input.getFloatValue();
70
71     if (int(floorf(_input.max() + 0.5)) & 1)
72         oddtype = 1; //draw ticks at odd values
73     else
74         oddtype = 0; //draw ticks at even values
75
76     float top = _y + _h;
77     float right = _x + _w;
78
79
80     if (_pointer) {
81         if (_pointer_type == MOVING) {
82             vmin = _input.min();
83             vmax = _input.max();
84
85         } else { // FIXED
86             vmin = cur_value - _half_width_units; // width units == needle travel
87             vmax = cur_value + _half_width_units; // or picture unit span.
88             text_x = _center_x;
89             text_y = _center_y;
90         }
91
92     } else {
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 = _center_x;
96         text_y = _center_y;
97     }
98
99
100 ///////////////////////////////////////////////////////////////////////////////
101 // VERTICAL SCALE
102 ///////////////////////////////////////////////////////////////////////////////
103
104     // Draw the basic markings for the scale...
105
106     if (option_vert()) { // Vertical scale
107         // Bottom tick bar
108         if (_draw_tick_bottom)
109             draw_line(_x, _y, right, _y);
110
111         // Top tick bar
112         if (_draw_tick_top)
113             draw_line(_x, top, right, top);
114
115         marker_xs = _x;       // x start
116         marker_xe = right;    // x extent
117         marker_ye = top;
118
119         //    glBegin(GL_LINES);
120
121         // Bottom tick bar
122         //    glVertex2f(marker_xs, _y);
123         //    glVertex2f(marker_xe, _y);
124
125         // Top tick bar
126         //    glVertex2f(marker_xs, marker_ye);
127         //    glVertex2f(marker_xe, marker_ye);
128         //    glEnd();
129
130
131         // We do not use else in the following so that combining the
132         // two options produces a "caged" display with double
133         // carrots. The same is done for horizontal card indicators.
134
135         // begin vertical/left
136         //First draw capping lines and pointers
137         if (option_left()) {    // Calculate x marker offset
138
139             if (_draw_cap_right)
140                 draw_line(marker_xe, _y, marker_xe, marker_ye);
141
142             marker_xs = marker_xe - _w / 3.0;
143
144             // draw_line(marker_xs, _center_y, marker_xe, _center_y + _w / 6);
145             // draw_line(marker_xs, _center_y, marker_xe, _center_y - _w / 6);
146
147             // draw pointer
148             if (_pointer) {
149                 if (_pointer_type == MOVING) {
150                     if (!_zoom) {
151                         //Code for Moving Type Pointer
152                         float ycentre, ypoint, xpoint;
153                         float range, right;
154
155                         if (_input.min() >= 0.0)
156                             ycentre = _y;
157                         else if (_input.max() + _input.min() == 0.0)
158                             ycentre = _center_y;
159                         else if (oddtype)
160                             ycentre = _y + (1.0 - _input.min()) * _h / (_input.max() - _input.min());
161                         else
162                             ycentre = _y + _input.min() * _h / (_input.max() - _input.min());
163
164                         range = _h;
165                         right = _x + _w;
166
167                         if (oddtype)
168                             ypoint = ycentre + ((cur_value - 1.0) * range / _val_span);
169                         else
170                             ypoint = ycentre + (cur_value * range / _val_span);
171
172                         xpoint = right + _marker_offset;
173                         draw_line(xpoint, ycentre, xpoint, ypoint);
174                         draw_line(xpoint, ypoint, xpoint - _marker_offset, ypoint);
175                         draw_line(xpoint - _marker_offset, ypoint, xpoint - 5.0, ypoint + 5.0);
176                         draw_line(xpoint - _marker_offset, ypoint, xpoint - 5.0, ypoint - 5.0);
177                     } // !_zoom
178
179                 } else {
180                     // default to fixed
181                     draw_fixed_pointer(_marker_offset + marker_xe, text_y + _w / 6,
182                             _marker_offset + marker_xs, text_y, _marker_offset + marker_xe,
183                             text_y - _w / 6);
184                 } // end pointer type
185             } // if pointer
186         } // end vertical/left
187
188
189         // begin vertical/right
190         // First draw capping lines and pointers
191         if (option_right()) {
192
193             if (_draw_cap_left)
194                 draw_line(_x, _y, _x, marker_ye);
195
196             marker_xe = _x + _w / 3.0;
197             // Indicator carrot
198             // draw_line(_x, _center_y +  _w / 6, marker_xe, _center_y);
199             // draw_line(_x, _center_y -  _w / 6, marker_xe, _center_y);
200
201             // draw pointer
202             if (_pointer) {
203                 if (_pointer_type == MOVING) {
204                     if (!_zoom) {
205                         // type-fixed & _zoom=1, behaviour to be defined
206                         // Code for Moving Type Pointer
207                         float ycentre, ypoint, xpoint;
208                         float range;
209
210                         if (_input.min() >= 0.0)
211                             ycentre = _y;
212                         else if (_input.max() + _input.min() == 0.0)
213                             ycentre = _center_y;
214                         else if (oddtype)
215                             ycentre = _y + (1.0 - _input.min()) * _h / (_input.max() - _input.min());
216                         else
217                             ycentre = _y + _input.min() * _h / (_input.max() - _input.min());
218
219                         range = _h;
220
221                         if (oddtype)
222                             ypoint = ycentre + ((cur_value - 1.0) * range / _val_span);
223                         else
224                             ypoint = ycentre + (cur_value * range / _val_span);
225
226                         xpoint = _x - _marker_offset;
227                         draw_line(xpoint, ycentre, xpoint, ypoint);
228                         draw_line(xpoint, ypoint, xpoint + _marker_offset, ypoint);
229                         draw_line(xpoint + _marker_offset, ypoint, xpoint + 5.0, ypoint + 5.0);
230                         draw_line(xpoint + _marker_offset, ypoint, xpoint + 5.0, ypoint - 5.0);
231                     }
232
233                 } else {
234                     // default to fixed
235                     draw_fixed_pointer(-_marker_offset + _x, text_y +  _w / 6,
236                             -_marker_offset + marker_xe, text_y, -_marker_offset + _x,
237                             text_y - _w / 6);
238                 }
239             } // if pointer
240         } // end vertical/right
241
242
243         // At this point marker x_start and x_end values are transposed.
244         // To keep this from confusing things they are now swapped.
245         if (option_both())
246             marker_ye = marker_xs, marker_xs = marker_xe, marker_xe = marker_ye;
247
248
249
250         // Work through from bottom to top of scale. Calculating where to put
251         // minor and major ticks.
252
253         // draw scale or tape
254         if (_zoom) {
255             zoomed_scale((int)vmin, (int)vmax);
256         } else {
257
258             int div_ratio;
259             if (_minor_divs != 0.0f)
260                 div_ratio = int(_major_divs / _minor_divs + 0.5f);
261             else
262                 div_ratio = 0, _minor_divs = _major_divs;               // FIXME move that into Scale/Constructor ?
263
264             float vstart = floorf(vmin / _major_divs) * _major_divs;
265             float min_diff = _w / 6.0;    // length difference between major & minor tick
266
267             // FIXME consider oddtype
268             for (int i = 0; ; i++) {
269                 float v = vstart + i * _minor_divs;
270
271                 if (!_modulo)
272                     if (v < _input.min())
273                         continue;
274                     else if (v > _input.max())
275                         break;
276
277                 float y = _y + (v - vmin) * factor();
278
279                 if (y < _y + 4)
280                     continue;
281                 if (y > top - 4)
282                     break;
283
284                 if (div_ratio && i % div_ratio) { // minor div
285                     if (option_both()) {
286                         if (_tick_type == LINE) {
287                             if (_tick_length == VARIABLE) {
288                                 draw_line(_x, y, marker_xs, y);
289                                 draw_line(marker_xe, y, right, y);
290                             } else {
291                                 draw_line(_x, y, marker_xs, y);
292                                 draw_line(marker_xe, y, right, y);
293                             }
294
295                         } else { // _tick_type == CIRCLE
296                             draw_bullet(_x, y, 3.0);
297                         }
298
299                         // glBegin(GL_LINES);
300                         // glVertex2f(_x, y);
301                         // glVertex2f(marker_xs,      y);
302                         // glVertex2f(marker_xe,      y);
303                         // glVertex2f(_x + _w,  y);
304                         // glEnd();
305                         // anything other than huds_both
306
307                     } else if (option_left()) {
308                         if (_tick_type == LINE) {
309                             if (_tick_length == VARIABLE) {
310                                 draw_line(marker_xs + min_diff, y, marker_xe, y);
311                             } else {
312                                 draw_line(marker_xs, y, marker_xe, y);
313                             }
314                         } else { // _tick_type == CIRCLE
315                             draw_bullet(marker_xs + 4, y, 3.0);
316                         }
317
318                     } else { // if (option_right())
319                         if (_tick_type == LINE) {
320                             if (_tick_length == VARIABLE) {
321                                 draw_line(marker_xs, y, marker_xe - min_diff, y);
322                             } else {
323                                 draw_line(marker_xs, y, marker_xe, y);
324                             }
325
326                         } else { // _tick_type == CIRCLE
327                             draw_bullet(marker_xe - 4, y, 3.0);
328                         }
329                     } // end huds both
330
331                 } else { // major div
332                     int display_value = int(v);
333                     if (_modulo)
334                         display_value %= _modulo;
335
336                     snprintf(buf, BUFSIZE, "%d", display_value);
337
338                     if (option_both()) {
339                         // draw_line(_x, y, marker_xs, y);
340                         // draw_line(marker_xs, y, _x + _w, y);
341                         if (_tick_type == LINE) {
342                             glBegin(GL_LINE_STRIP);
343                             glVertex2f(_x, y);
344                             glVertex2f(marker_xs, y);
345                             glVertex2f(right, y);
346                             glEnd();
347
348                         } else { // _tick_type == CIRCLE
349                             draw_bullet(_x, y, 5.0);
350                         }
351
352                         if (!option_notext())
353                             draw_text(marker_xs, y, buf, HUDText::CENTER);
354
355                     } else {
356                         if (_tick_type == LINE)
357                             draw_line(marker_xs, y, marker_xe, y);
358                         else // _tick_type == CIRCLE
359                             draw_bullet(marker_xs + 4, y, 5.0);
360
361                         if (!option_notext()) {
362                             if (option_left())
363                                 draw_text(marker_xs, y, buf, HUDText::RIGHT|HUDText::VCENTER);
364                             else
365                                 draw_text(marker_xe + 1.0, y, buf, HUDText::LEFT|HUDText::VCENTER);
366                         }
367                     } // End if huds-both
368                 }
369             }
370         } // end of zoom
371
372
373 ///////////////////////////////////////////////////////////////////////////////
374 // HORIZONTAL SCALE
375 ///////////////////////////////////////////////////////////////////////////////
376
377
378     } else {
379         // left tick bar
380         if (_draw_tick_left)
381             draw_line(_x, _y, _x, top);
382
383         // right tick bar
384         if (_draw_tick_right)
385             draw_line(right, _y, right, top);
386
387         marker_ys = _y;    // Starting point for
388         marker_ye = top;           // tick y location calcs
389         marker_xe = right;
390         marker_xs = _x + ((cur_value - vmin) * factor());
391
392         //    glBegin(GL_LINES);
393         // left tick bar
394         //    glVertex2f(_x, _y);
395         //    glVertex2f(_x, marker_ye);
396
397         // right tick bar
398         //    glVertex2f(marker_xe, _y);
399         //    glVertex2f(marker_xe, marker_ye);
400         //    glEnd();
401
402         if (option_top()) {
403             if (_draw_cap_bottom)
404                 draw_line(_x, _y, right, _y);
405
406             // Tick point adjust
407             marker_ye  = _y + _h / 2;
408             // Bottom arrow
409             // draw_line(_center_x, marker_ye, _center_x - _h / 4, _y);
410             // draw_line(_center_x, marker_ye, _center_x + _h / 4, _y);
411             // draw pointer
412             if (_pointer) {
413                 if (_pointer_type == MOVING) {
414                     if (!_zoom) {
415                         //Code for Moving Type Pointer
416
417                         float xcentre = _center_x;
418                         float range = _w;
419                         float xpoint = xcentre + (cur_value * range / _val_span);
420                         float ypoint = _y - _marker_offset;
421                         draw_line(xcentre, ypoint, xpoint, ypoint);
422                         draw_line(xpoint, ypoint, xpoint, ypoint + _marker_offset);
423                         draw_line(xpoint, ypoint + _marker_offset, xpoint + 5.0, ypoint + 5.0);
424                         draw_line(xpoint, ypoint + _marker_offset, xpoint - 5.0, ypoint + 5.0);
425                     }
426
427                 } else {
428                     //default to fixed
429                     draw_fixed_pointer(marker_xs - _h / 4, _y, marker_xs,
430                             marker_ye, marker_xs + _h / 4, _y);
431                 }
432             }
433         } // End Horizontal scale/top
434
435         if (option_bottom()) {
436             if (_draw_cap_top)
437                 draw_line(_x, top, right, top);
438
439             // Tick point adjust
440             marker_ys = top - _h / 2;
441             // Top arrow
442             // draw_line(_center_x + _h / 4, _y + _h, _center_x, marker_ys);
443             // draw_line(_center_x - _h / 4, _y + _h, _center_x , marker_ys);
444
445             // draw pointer
446             if (_pointer) {
447                 if (_pointer_type == MOVING) {
448                     if (!_zoom) {
449                         //Code for Moving Type Pointer
450
451                         float xcentre = _center_x;
452                         float range = _w;
453                         float hgt = _y + _h;
454                         float xpoint = xcentre + (cur_value * range / _val_span);
455                         float ypoint = hgt + _marker_offset;
456                         draw_line(xcentre, ypoint, xpoint, ypoint);
457                         draw_line(xpoint, ypoint, xpoint, ypoint - _marker_offset);
458                         draw_line(xpoint, ypoint - _marker_offset, xpoint + 5.0, ypoint - 5.0);
459                         draw_line(xpoint, ypoint - _marker_offset, xpoint - 5.0, ypoint - 5.0);
460                     }
461                 } else {
462                     draw_fixed_pointer(marker_xs + _h / 4, top, marker_xs, marker_ys,
463                             marker_xs - _h / 4, top);
464                 }
465             }
466         } //end horizontal scale bottom
467
468
469         if (_zoom) {
470             zoomed_scale((int)vmin,(int)vmax);
471         } else {
472             int div_ratio;                                      // FIXME abstract that out of hor/vert
473             if (_minor_divs != 0.0f)
474                 div_ratio = int(_major_divs / _minor_divs + 0.5f);
475             else
476                 div_ratio = 0, _minor_divs = _major_divs;                       // FIXME move that into Scale/Constructor ?
477
478             float vstart = floorf(vmin / _major_divs) * _major_divs;
479             float min_diff = _h / 6.0;    // length difference between major & minor tick
480
481             // FIXME consider oddtype
482             for (int i = 0; ; i++) {
483                 float v = vstart + i * _minor_divs;
484
485                 if (!_modulo)
486                     if (v < _input.min())
487                         continue;
488                     else if (v > _input.max())
489                         break;
490
491                 float x = _x + (v - vmin) * factor();
492
493                 if (x < _x + 4)
494                     continue;
495                 if (x > right - 4)
496                     break;
497
498                 if (div_ratio && i % div_ratio) { // minor div
499                     if (option_both()) {
500                         if (_tick_length == VARIABLE) {
501                             draw_line(x, _y, x, marker_ys - 4);
502                             draw_line(x, marker_ye + 4, x, top);
503                         } else {
504                             draw_line(x, _y, x, marker_ys);
505                             draw_line(x, marker_ye, x, top);
506                         }
507                         // glBegin(GL_LINES);
508                         // glVertex2f(x, _y);
509                         // glVertex2f(x, marker_ys - 4);
510                         // glVertex2f(x, marker_ye + 4);
511                         // glVertex2f(x, _y + _h);
512                         // glEnd();
513
514                     } else {
515                         if (option_top()) {
516                             // draw minor ticks
517                             if (_tick_length == VARIABLE)
518                                 draw_line(x, marker_ys, x, marker_ye - min_diff);
519                             else
520                                 draw_line(x, marker_ys, x, marker_ye);
521
522                         } else if (_tick_length == VARIABLE) {
523                             draw_line(x, marker_ys + 4, x, marker_ye);
524                         } else {
525                             draw_line(x, marker_ys, x, marker_ye);
526                         }
527                     }
528
529                 } else { // major divs
530                     int display_value = int(v);
531                     if (_modulo)
532                         display_value %= _modulo;
533
534                     snprintf(buf, BUFSIZE, "%d", display_value);
535
536                     // Draw major ticks and text only if far enough from the edge.                      // FIXME
537                     if (x < _x + 10 || x + 10 > _x + _w)
538                         continue;
539
540                     if (option_both()) {
541                         // draw_line(x, _y,
542                         //              x, marker_ys);
543                         // draw_line(x, marker_ye,
544                         //              x, _y + _h);
545                         glBegin(GL_LINE_STRIP);
546                         glVertex2f(x, _y);
547                         glVertex2f(x, marker_ye);
548                         glVertex2f(x, top);
549                         glEnd();
550
551                         if (!option_notext())
552                             draw_text(x, marker_ys, buf, HUDText::CENTER);
553
554                     } else {
555                         draw_line(x, marker_ys, x, marker_ye);
556
557                         if (!option_notext()) {
558                             if (option_top())
559                                 draw_text(x, top, buf, HUDText::TOP|HUDText::HCENTER);
560                             else
561                                 draw_text(x, _y, buf, HUDText::BOTTOM|HUDText::HCENTER);
562                         }
563                     }
564                 }
565             } // end for
566         } // end zoom
567     } // end horizontal/vertical scale
568 }
569
570
571 void HUD::Tape::draw_fixed_pointer(float x1, float y1, float x2, float y2, float x3, float y3)
572 {
573     glBegin(GL_LINE_STRIP);
574     glVertex2f(x1, y1);
575     glVertex2f(x2, y2);
576     glVertex2f(x3, y3);
577     glEnd();
578 }
579
580
581 void HUD::Tape::zoomed_scale(int first, int last)
582 {
583     const int BUFSIZE = 80;
584     char buf[BUFSIZE];
585     int data[80];
586
587     float x, y, w, h, bottom;
588     float cur_value = _input.getFloatValue();
589     int a = 0;
590
591     while (first <= last) {
592         if ((first % (int)_major_divs) == 0) {
593             data[a] = first;
594             a++;
595         }
596         first++;
597     }
598     int centre = a / 2;
599
600     if (option_vert()) {
601         x = _x;
602         y = _y;
603         w = _x + _w;
604         h = _y + _h;
605         bottom = _h;
606
607         float xstart, yfirst, ycentre, ysecond;
608
609         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
610         yfirst = _center_y - hgt;
611         ycentre = _center_y;
612         ysecond = _center_y + hgt;
613         float range = hgt * 2;
614
615         int i;
616         float factor = range / 10.0;
617
618         float hgt1 = bottom * 30.0 / 100.0;
619         int  incrs = int((_val_span - _major_divs * 2.0) / _major_divs);
620         int  incr = incrs / 2;
621         float factors = hgt1 / incr;
622
623         // moving type pointer
624         float ypoint, xpoint;
625         float ycent = _center_y;
626         float right = _x + _w;
627
628         if (cur_value <= data[centre + 1])
629             if (cur_value > data[centre]) {
630                 ypoint = ycent + ((cur_value - data[centre]) * hgt / _major_divs);
631             }
632
633         if (cur_value >= data[centre - 1])
634             if (cur_value <= data[centre]) {
635                 ypoint = ycent - ((data[centre] - cur_value) * hgt / _major_divs);
636             }
637
638         if (cur_value < data[centre - 1])
639             if (cur_value >= _input.min()) {
640                 float diff  = _input.min() - data[centre - 1];
641                 float diff1 = cur_value - data[centre - 1];
642                 float val = (diff1 * hgt1) / diff;
643
644                 ypoint = ycent - hgt - val;
645             }
646
647         if (cur_value > data[centre + 1])
648             if (cur_value <= _input.max()) {
649                 float diff  = _input.max() - data[centre + 1];
650                 float diff1 = cur_value - data[centre + 1];
651                 float val = (diff1 * hgt1) / diff;
652
653                 ypoint = ycent + hgt + val;
654             }
655
656         if (option_left()) {
657             xstart = w;
658
659             draw_line(xstart, ycentre, xstart - 5.0, ycentre); //centre tick
660
661             snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre] * _input.factor())); // was data_scaling() ... makes not sense at all
662
663             if (!option_notext())
664                 draw_text(x, ycentre, buf, 0);
665
666             for (i = 1; i < 5; i++) {
667                 yfirst += factor;
668                 ycentre += factor;
669                 draw_bullet(xstart - 2.5, yfirst, 3.0);
670                 draw_bullet(xstart - 2.5, ycentre, 3.0);
671             }
672
673             yfirst = _center_y - hgt;
674
675             for (i = 0; i <= incr; i++) {
676                 draw_line(xstart, yfirst, xstart - 5.0, yfirst);
677                 draw_line(xstart, ysecond, xstart - 5.0, ysecond);
678
679                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre - i - 1] * _input.factor()));  // was data_scaling() ... makes no sense at all
680
681                 if (!option_notext())
682                     draw_text(x, yfirst, buf, 0);
683
684                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
685
686                 if (!option_notext())
687                     draw_text(x, ysecond, buf, 0);
688
689                 yfirst -= factors;
690                 ysecond += factors;
691
692             }
693
694             //to draw moving type pointer for left option
695             //begin
696             xpoint = right + 10.0;
697
698             if (_pointer_type == MOVING) {
699                 draw_line(xpoint, ycent, xpoint, ypoint);
700                 draw_line(xpoint, ypoint, xpoint - 10.0, ypoint);
701                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint + 5.0);
702                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint - 5.0);
703             }
704             //end
705
706         } else {
707             //option_right
708             xstart = (x + w) / 2;
709
710             draw_line(xstart, ycentre, xstart + 5.0, ycentre); //centre tick
711
712             snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
713
714             if (!option_notext())
715                 draw_text(w, ycentre, buf, 0);
716
717             for (i = 1; i < 5; i++) {
718                 yfirst += factor;
719                 ycentre += factor;
720                 draw_bullet(xstart + 2.5, yfirst, 3.0);
721                 draw_bullet(xstart + 2.5, ycentre, 3.0);
722             }
723
724             yfirst = _center_y - hgt;
725
726             for (i = 0; i <= incr; i++) {
727                 draw_line(xstart, yfirst, xstart + 5.0, yfirst);
728                 draw_line(xstart, ysecond, xstart + 5.0, ysecond);
729
730                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
731
732                 if (!option_notext())
733                     draw_text(w, yfirst, buf, 0);
734
735                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre + i + 1] * _input.factor()));
736
737                 if (!option_notext())
738                     draw_text(w, ysecond, buf, 0);
739
740                 yfirst -= factors;
741                 ysecond += factors;
742
743             }
744
745             // to draw moving type pointer for right option
746             //begin
747             xpoint = _x;
748
749             if (_pointer_type == MOVING) {
750                 draw_line(xpoint, ycent, xpoint, ypoint);
751                 draw_line(xpoint, ypoint, xpoint + 10.0, ypoint);
752                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint + 5.0);
753                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint - 5.0);
754             }
755             //end
756         }//end option_right /left
757         //end of vertical scale
758
759     } else {
760         //horizontal scale
761         x = _x;
762         y = _y;
763         w = _x + _w;
764         h = _y + _h;
765         bottom = _w;
766
767         float ystart, xfirst, xcentre, xsecond;
768
769         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
770         xfirst = _center_x - hgt;
771         xcentre = _center_x;
772         xsecond = _center_x + hgt;
773         float range = hgt * 2;
774
775         int i;
776         float factor = range / 10.0;
777
778         float hgt1 = bottom * 30.0 / 100.0;
779         int  incrs = int((_val_span - _major_divs * 2.0) / _major_divs);
780         int  incr = incrs / 2;
781         float factors = hgt1 / incr;
782
783
784         //Code for Moving Type Pointer
785         //begin
786         static float xcent, xpoint, ypoint;                             // FIXME really static?
787
788         xcent = _center_x;
789
790         if (cur_value <= data[centre + 1])
791             if (cur_value > data[centre]) {
792                 xpoint = xcent + ((cur_value - data[centre]) * hgt / _major_divs);
793             }
794
795         if (cur_value >= data[centre - 1])
796             if (cur_value <= data[centre]) {
797                 xpoint = xcent - ((data[centre] - cur_value) * hgt / _major_divs);
798             }
799
800         if (cur_value < data[centre - 1])
801             if (cur_value >= _input.min()) {
802                 float diff = _input.min() - data[centre - 1];
803                 float diff1 = cur_value - data[centre - 1];
804                 float val = (diff1 * hgt1) / diff;
805
806                 xpoint = xcent - hgt - val;
807             }
808
809
810         if (cur_value > data[centre + 1])
811             if (cur_value <= _input.max()) {
812                 float diff = _input.max() - data[centre + 1];
813                 float diff1 = cur_value - data[centre + 1];
814                 float val = (diff1 * hgt1) / diff;
815
816                 xpoint = xcent + hgt + val;
817             }
818
819         //end
820         if (option_top()) {
821             ystart = h;
822             draw_line(xcentre, ystart, xcentre, ystart - 5.0); //centre tick
823
824             snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre] * _input.factor()));  // was data_scaling() ... makes no sense at all
825
826             if (!option_notext())
827                 draw_text(xcentre - 10.0, y, buf, 0);
828
829             for (i = 1; i < 5; i++) {
830                 xfirst += factor;
831                 xcentre += factor;
832                 draw_bullet(xfirst, ystart - 2.5, 3.0);
833                 draw_bullet(xcentre, ystart - 2.5, 3.0);
834             }
835
836             xfirst = _center_x - hgt;
837
838             for (i = 0; i <= incr; i++) {
839                 draw_line(xfirst, ystart, xfirst,  ystart - 5.0);
840                 draw_line(xsecond, ystart, xsecond, ystart - 5.0);
841
842                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
843
844                 if (!option_notext())
845                     draw_text(xfirst - 10.0, y, buf, 0);
846
847                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
848
849                 if (!option_notext())
850                     draw_text(xsecond - 10.0, y, buf, 0);
851
852
853                 xfirst -= factors;
854                 xsecond += factors;
855             }
856             //this is for moving pointer for top option
857             //begin
858
859             ypoint = _y + _h + 10.0;
860
861             if (_pointer_type == MOVING) {
862                 draw_line(xcent, ypoint, xpoint, ypoint);
863                 draw_line(xpoint, ypoint, xpoint, ypoint - 10.0);
864                 draw_line(xpoint, ypoint - 10.0, xpoint + 5.0, ypoint - 5.0);
865                 draw_line(xpoint, ypoint - 10.0, xpoint - 5.0, ypoint - 5.0);
866             }
867             //end of top option
868
869         } else {
870             //else option_bottom
871             ystart = (y + h) / 2;
872
873             //draw_line(xstart, yfirst,  xstart - 5.0, yfirst);
874             draw_line(xcentre, ystart, xcentre, ystart + 5.0); //centre tick
875
876             snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
877
878             if (!option_notext())
879                 draw_text(xcentre - 10.0, h, buf, 0);
880
881             for (i = 1; i < 5; i++) {
882                 xfirst += factor;
883                 xcentre += factor;
884                 draw_bullet(xfirst, ystart + 2.5, 3.0);
885                 draw_bullet(xcentre, ystart + 2.5, 3.0);
886             }
887
888             xfirst = _center_x - hgt;
889
890             for (i = 0; i <= incr; i++) {
891                 draw_line(xfirst, ystart, xfirst, ystart + 5.0);
892                 draw_line(xsecond, ystart, xsecond, ystart + 5.0);
893
894                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
895
896                 if (!option_notext())
897                     draw_text(xfirst - 10.0, h, buf, 0);
898
899                 snprintf(buf, BUFSIZE, "%3.0f\n", float(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
900
901                 if (!option_notext())
902                     draw_text(xsecond - 10.0, h, buf, 0);
903
904                 xfirst -= factors;
905                 xsecond   += factors;
906             }
907             //this is for movimg pointer for bottom option
908             //begin
909
910             ypoint = _y - 10.0;
911             if (_pointer_type == MOVING) {
912                 draw_line(xcent, ypoint, xpoint, ypoint);
913                 draw_line(xpoint, ypoint, xpoint, ypoint + 10.0);
914                 draw_line(xpoint, ypoint + 10.0, xpoint + 5.0, ypoint + 5.0);
915                 draw_line(xpoint, ypoint + 10.0, xpoint - 5.0, ypoint + 5.0);
916             }
917         }//end hud_top or hud_bottom
918     }  //end of horizontal/vertical scales
919 }//end draw
920
921