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