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