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