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