]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_tape.cxx
new HUD (work in progress)
[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     pointer_type(n->getStringValue("pointer-type")),
38     tick_type(n->getStringValue("tick-type")), // 'circle' or 'line'
39     tick_length(n->getStringValue("tick-length")), // for variable length
40     zoom(n->getIntValue("zoom"))
41 {
42     half_width_units = range_to_show() / 2.0;
43 }
44
45
46 void HUD::Tape::draw(void) //  (HUD_scale * pscale)
47 {
48     if (!_input.isValid())
49         return;
50
51     float vmin = 0.0, vmax = 0.0;
52     float marker_xs;
53     float marker_xe;
54     float marker_ys;
55     float marker_ye;
56     float text_x = 0.0, text_y = 0.0;
57     int lenstr;
58     float height, width;
59     int i, last;
60     const int BUFSIZE = 80;
61     char buf[BUFSIZE];
62     bool condition;
63     int disp_val = 0;
64     int oddtype, k; //odd or even values for ticks
65
66     Point mid_scr = get_centroid();
67     float cur_value = _input.getFloatValue();
68
69     if ((int)_input.max() & 1)
70         oddtype = 1; //draw ticks at odd values
71     else
72         oddtype = 0; //draw ticks at even values
73
74     Rect scrn_rect = get_location();
75
76     height = scrn_rect.top + scrn_rect.bottom;
77     width = scrn_rect.left + scrn_rect.right;
78
79
80     // was: if (type != "gauge") { ... until end
81     // if its not explicitly a gauge default to tape
82     if (pointer) {
83         if (pointer_type == "moving") {
84             vmin = _input.min();
85             vmax = _input.max();
86
87         } else {
88             // default to 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     // Draw the basic markings for the scale...
103
104     if (option_vert()) { // Vertical scale
105         // Bottom tick bar
106         if (draw_tick_bottom)
107             draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
108
109         // Top tick bar
110         if (draw_tick_top)
111             draw_line(scrn_rect.left, height, width, height);
112
113         marker_xs = scrn_rect.left;  // x start
114         marker_xe = width;           // x extent
115         marker_ye = height;
116
117         //    glBegin(GL_LINES);
118
119         // Bottom tick bar
120         //    glVertex2f(marker_xs, scrn_rect.top);
121         //    glVertex2f(marker_xe, scrn_rect.top);
122
123         // Top tick bar
124         //    glVertex2f(marker_xs, marker_ye);
125         //    glVertex2f(marker_xe, marker_ye);
126         //    glEnd();
127
128
129         // We do not use else in the following so that combining the
130         // two options produces a "caged" display with double
131         // carrots. The same is done for horizontal card indicators.
132
133         // begin vertical/left
134         //First draw capping lines and pointers
135         if (option_left()) {    // Calculate x marker offset
136
137             if (draw_cap_right) {
138                 // Cap right side
139                 draw_line(marker_xe, scrn_rect.top, marker_xe, marker_ye);
140             }
141
142             marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
143
144             // draw_line(marker_xs, mid_scr.y,
145             //              marker_xe, mid_scr.y + scrn_rect.right / 6);
146             // draw_line(marker_xs, mid_scr.y,
147             //              marker_xe, mid_scr.y - scrn_rect.right / 6);
148
149             // draw pointer
150             if (pointer) {
151                 if (pointer_type == "moving") {
152                     if (zoom == 0) {
153                         //Code for Moving Type Pointer
154                         float ycentre, ypoint, xpoint;
155                         float range, wth;
156                         if (cur_value > _input.max())
157                             cur_value = _input.max();
158                         if (cur_value < _input.min())
159                             cur_value = _input.min();
160
161                         if (_input.min() >= 0.0)
162                             ycentre = scrn_rect.top;
163                         else if (_input.max() + _input.min() == 0.0)
164                             ycentre = mid_scr.y;
165                         else if (oddtype == 1)
166                             ycentre = scrn_rect.top + (1.0 - _input.min()) * scrn_rect.bottom
167                                     / (_input.max() - _input.min());
168                         else
169                             ycentre = scrn_rect.top + _input.min() * scrn_rect.bottom
170                                     / (_input.max() - _input.min());
171
172                         range = scrn_rect.bottom;
173                         wth = scrn_rect.left + scrn_rect.right;
174
175                         if (oddtype == 1)
176                             ypoint = ycentre + ((cur_value - 1.0) * range / val_span);
177                         else
178                             ypoint = ycentre + (cur_value * range / val_span);
179
180                         xpoint = wth + marker_offset;
181                         draw_line(xpoint, ycentre, xpoint, ypoint);
182                         draw_line(xpoint, ypoint, xpoint - marker_offset, ypoint);
183                         draw_line(xpoint - marker_offset, ypoint, xpoint - 5.0, ypoint + 5.0);
184                         draw_line(xpoint - marker_offset, ypoint, xpoint - 5.0, ypoint - 5.0);
185                     } //zoom=0
186
187                 } else {
188                     // default to fixed
189                     fixed(marker_offset + marker_xe, text_y + scrn_rect.right / 6,
190                             marker_offset + marker_xs, text_y, marker_offset + marker_xe,
191                             text_y - scrn_rect.right / 6);
192                 }//end pointer type
193             } //if pointer
194         } //end vertical/left
195
196         // begin vertical/right
197         //First draw capping lines and pointers
198         if (option_right()) {  // We'll default this for now.
199             if (draw_cap_left) {
200                 // Cap left side
201                 draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, marker_ye);
202             } //endif cap_left
203
204             marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
205             // Indicator carrot
206             // draw_line(scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
207             //              marker_xe, mid_scr.y);
208             // draw_line(scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
209             //              marker_xe, mid_scr.y);
210
211             // draw pointer
212             if (pointer) {
213                 if (pointer_type == "moving") {
214                     if (zoom == 0) {
215                         //type-fixed & zoom=1, behaviour to be defined
216                         // Code for Moving Type Pointer
217                         float ycentre, ypoint, xpoint;
218                         float range;
219
220                         if (cur_value > _input.max())
221                             cur_value = _input.max();
222                         if (cur_value < _input.min())
223                             cur_value = _input.min();
224
225                         if (_input.min() >= 0.0)
226                             ycentre = scrn_rect.top;
227                         else if (_input.max() + _input.min() == 0.0)
228                             ycentre = mid_scr.y;
229                         else if (oddtype == 1)
230                             ycentre = scrn_rect.top + (1.0 - _input.min()) * scrn_rect.bottom / (_input.max() - _input.min());
231                         else
232                             ycentre = scrn_rect.top + _input.min() * scrn_rect.bottom / (_input.max() - _input.min());
233
234                         range = scrn_rect.bottom;
235
236                         if (oddtype == 1)
237                             ypoint = ycentre + ((cur_value - 1.0) * range / val_span);
238                         else
239                             ypoint = ycentre + (cur_value * range / val_span);
240
241                         xpoint = scrn_rect.left - marker_offset;
242                         draw_line(xpoint, ycentre, xpoint, ypoint);
243                         draw_line(xpoint, ypoint, xpoint + marker_offset, ypoint);
244                         draw_line(xpoint + marker_offset, ypoint, xpoint + 5.0, ypoint + 5.0);
245                         draw_line(xpoint + marker_offset, ypoint, xpoint + 5.0, ypoint - 5.0);
246                     }
247
248                 } else {
249                     // default to fixed
250                     fixed(-marker_offset + scrn_rect.left, text_y +  scrn_rect.right / 6,
251                             -marker_offset + marker_xe, text_y, -marker_offset + scrn_rect.left,
252                             text_y - scrn_rect.right / 6);
253                 }
254             } //if pointer
255         }  //end vertical/right
256
257         // At this point marker x_start and x_end values are transposed.
258         // To keep this from confusing things they are now interchanged.
259         if (option_both()) {
260             marker_ye = marker_xs;
261             marker_xs = marker_xe;
262             marker_xe = marker_ye;
263         }
264
265         // Work through from bottom to top of scale. Calculating where to put
266         // minor and major ticks.
267
268         // draw scale or tape
269
270 //        last = float_to_int(vmax)+1;
271 //        i = float_to_int(vmin);
272         last = (int)vmax + 1; // N
273         i = (int)vmin; // N
274
275         if (zoom == 1) {
276             zoomed_scale((int)vmin, (int)vmax);
277         } else {
278             for (; i < last; i++) {
279                 condition = true;
280                 if (!modulo() && i < _input.min())
281                     condition = false;
282
283                 if (condition) {  // Show a tick if necessary
284                     // Calculate the location of this tick
285                     marker_ys = scrn_rect.top + ((i - vmin) * factor()/*+.5f*/);
286                     // marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
287                     // Block calculation artifact from drawing ticks below min coordinate.
288                     // Calculation here accounts for text height.
289
290                     if ((marker_ys < (scrn_rect.top + 4))
291                             || (marker_ys > (height - 4))) {
292                         // Magic numbers!!!
293                         continue;
294                     }
295
296                     if (oddtype == 1)
297                         k = i + 1; //enable ticks at odd values
298                     else
299                         k = i;
300
301                     // Minor ticks
302                     if (_minor_divs) {
303                         // if ((i % _minor_divs) == 0) {
304                         if (!(k % (int)_minor_divs)) {
305                             if (((marker_ys - 5) > scrn_rect.top)
306                                     && ((marker_ys + 5) < (height))) {
307
308                                 //vertical/left OR vertical/right
309                                 if (option_both()) {
310                                     if (tick_type == "line") {
311                                         if (tick_length == "variable") {
312                                             draw_line(scrn_rect.left, marker_ys,
313                                                     marker_xs, marker_ys);
314                                             draw_line(marker_xe, marker_ys,
315                                                     width, marker_ys);
316                                         } else {
317                                             draw_line(scrn_rect.left, marker_ys,
318                                                     marker_xs, marker_ys);
319                                             draw_line(marker_xe, marker_ys,
320                                                     width, marker_ys);
321                                         }
322
323                                     } else if (tick_type == "circle") {
324                                         circle(scrn_rect.left,(float)marker_ys, 3.0);
325
326                                     } else {
327                                         // if neither line nor circle draw default as line
328                                         draw_line(scrn_rect.left, marker_ys,
329                                                 marker_xs, marker_ys);
330                                         draw_line(marker_xe, marker_ys,
331                                                 width, marker_ys);
332                                     }
333                                     // glBegin(GL_LINES);
334                                     // glVertex2f(scrn_rect.left, marker_ys);
335                                     // glVertex2f(marker_xs,      marker_ys);
336                                     // glVertex2f(marker_xe,      marker_ys);
337                                     // glVertex2f(scrn_rect.left + scrn_rect.right,  marker_ys);
338                                     // glEnd();
339                                     // anything other than option_both
340
341                                 } else {
342                                     if (option_left()) {
343                                         if (tick_type == "line") {
344                                             if (tick_length == "variable") {
345                                                 draw_line(marker_xs + 4, marker_ys,
346                                                         marker_xe, marker_ys);
347                                             } else {
348                                                 draw_line(marker_xs, marker_ys,
349                                                         marker_xe, marker_ys);
350                                             }
351                                         } else if (tick_type == "circle") {
352                                             circle((float)marker_xs + 4, (float)marker_ys, 3.0);
353
354                                         } else {
355                                             draw_line(marker_xs + 4, marker_ys,
356                                                     marker_xe, marker_ys);
357                                         }
358
359                                     }  else {
360                                         if (tick_type == "line") {
361                                             if (tick_length == "variable") {
362                                                 draw_line(marker_xs, marker_ys,
363                                                         marker_xe - 4, marker_ys);
364                                             } else {
365                                                 draw_line(marker_xs, marker_ys,
366                                                         marker_xe, marker_ys);
367                                             }
368
369                                         } else if (tick_type == "circle") {
370                                             circle((float)marker_xe - 4, (float)marker_ys, 3.0);
371                                         } else {
372                                             draw_line(marker_xs, marker_ys,
373                                                     marker_xe - 4, marker_ys);
374                                         }
375                                     }
376                                 } //end huds both
377                             }
378                         } //end draw minor ticks
379                     }  //end minor ticks
380
381                     // Major ticks
382                     if (_major_divs) {
383                         if (!(k % (int)_major_divs)) {
384
385                             if (modulo()) {
386                                 disp_val = i % (int) modulo(); // ?????????
387                                 if (disp_val < 0) {
388                                     while (disp_val < 0)
389                                         disp_val += modulo();
390                                 }
391                             } else {
392                                 disp_val = i;
393                             }
394
395 // FIXME what nonsense is this?!?
396                             lenstr = snprintf(buf, BUFSIZE, "%d", int(disp_val * _input.factor()/*+.5*/));   // was data_scaling ... makes no sense at all
397                             // (int)(disp_val  * data_scaling() +.5));
398                             /* if (((marker_ys - 8) > scrn_rect.top) &&
399                                ((marker_ys + 8) < (height))){ */
400                             // option_both
401                             if (option_both()) {
402                                 // draw_line(scrn_rect.left, marker_ys,
403                                 //              marker_xs,      marker_ys);
404                                 // draw_line(marker_xs, marker_ys,
405                                 //              scrn_rect.left + scrn_rect.right,
406                                 //              marker_ys);
407                                 if (tick_type == "line") {
408                                     glBegin(GL_LINE_STRIP);
409                                     glVertex2f(scrn_rect.left, marker_ys);
410                                     glVertex2f(marker_xs, marker_ys);
411                                     glVertex2f(width, marker_ys);
412                                     glEnd();
413
414                                 } else if (tick_type == "circle") {
415                                     circle(scrn_rect.left, (float)marker_ys, 5.0);
416
417                                 } else {
418                                     glBegin(GL_LINE_STRIP);
419                                     glVertex2f(scrn_rect.left, marker_ys);
420                                     glVertex2f(marker_xs, marker_ys);
421                                     glVertex2f(width, marker_ys);
422                                     glEnd();
423                                 }
424
425                                 if (!option_notext())
426                                     draw_text(marker_xs + 2, marker_ys, buf, 0);
427
428                             } else {
429                                 /* Changes are made to draw a circle when tick_type="circle" */
430                                 // anything other than option_both
431                                 if (tick_type == "line")
432                                     draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
433                                 else if (tick_type == "circle")
434                                     circle((float)marker_xs + 4, (float)marker_ys, 5.0);
435                                 else
436                                     draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
437
438                                 if (!option_notext()) {
439                                     if (option_left()) {
440                                         draw_text(marker_xs - 8 * lenstr - 2,
441                                                 marker_ys - 4, buf, 0);
442                                     } else {
443                                         draw_text(marker_xe + 3 * lenstr,
444                                                 marker_ys - 4, buf, 0);
445                                     } //End if option_left
446                                 } //End if !option_notext
447                             }  //End if huds-both
448                         }  // End if draw major ticks
449                     }   // End if major ticks
450                 }  // End condition
451             }  // End for
452         }  //end of zoom
453         // End if VERTICAL SCALE TYPE (tape loop yet to be closed)
454
455     } else {
456         // Horizontal scale by default
457         // left tick bar
458         if (draw_tick_left)
459             draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
460
461         // right tick bar
462         if (draw_tick_right)
463             draw_line(width, scrn_rect.top, width, height);
464
465         marker_ys = scrn_rect.top;    // Starting point for
466         marker_ye = height;           // tick y location calcs
467         marker_xe = width;
468         marker_xs = scrn_rect.left + ((cur_value - vmin) * factor() /*+ .5f*/);
469
470         //    glBegin(GL_LINES);
471         // left tick bar
472         //    glVertex2f(scrn_rect.left, scrn_rect.top);
473         //    glVertex2f(scrn_rect.left, marker_ye);
474
475         // right tick bar
476         //    glVertex2f(marker_xe, scrn_rect.top);
477         //    glVertex2f(marker_xe, marker_ye);
478         //    glEnd();
479
480         if (option_top()) {
481             // Bottom box line
482             if (draw_cap_bottom)
483                 draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
484
485             // Tick point adjust
486             marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;
487             // Bottom arrow
488             // draw_line(mid_scr.x, marker_ye,
489             //              mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
490             // draw_line(mid_scr.x, marker_ye,
491             //              mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
492             // draw pointer
493             if (pointer) {
494                 if (pointer_type == "moving") {
495                     if (zoom == 0) {
496                         //Code for Moving Type Pointer
497                         // static float xcentre, xpoint, ypoint;
498                         // static int range;
499                         if (cur_value > _input.max())
500                             cur_value = _input.max();
501                         if (cur_value < _input.min())
502                             cur_value = _input.min();
503
504                         float xcentre = mid_scr.x;
505                         float range = scrn_rect.right;
506                         float xpoint = xcentre + (cur_value * range / val_span);
507                         float ypoint = scrn_rect.top - marker_offset;
508                         draw_line(xcentre, ypoint, xpoint, ypoint);
509                         draw_line(xpoint, ypoint, xpoint, ypoint + marker_offset);
510                         draw_line(xpoint, ypoint + marker_offset, xpoint + 5.0, ypoint + 5.0);
511                         draw_line(xpoint, ypoint + marker_offset, xpoint - 5.0, ypoint + 5.0);
512                     }
513
514                 } else {
515                     //default to fixed
516                     fixed(marker_xs - scrn_rect.bottom / 4, scrn_rect.top, marker_xs,
517                             marker_ye, marker_xs + scrn_rect.bottom / 4, scrn_rect.top);
518                 }
519             }  //if pointer
520         } //End Horizontal scale/top
521
522         if (option_bottom()) {
523             // Top box line
524             if (draw_cap_top)
525                 draw_line(scrn_rect.left, height, width, height);
526
527             // Tick point adjust
528             marker_ys = height - scrn_rect.bottom / 2;
529             // Top arrow
530             //      draw_line(mid_scr.x + scrn_rect.bottom / 4,
531             //                   scrn_rect.top + scrn_rect.bottom,
532             //                   mid_scr.x, marker_ys);
533             //      draw_line(mid_scr.x - scrn_rect.bottom / 4,
534             //                   scrn_rect.top + scrn_rect.bottom,
535             //                   mid_scr.x , marker_ys);
536
537             // draw pointer
538             if (pointer) {
539                 if (pointer_type == "moving") {
540                     if (zoom == 0) {
541                         //Code for Moving Type Pointer
542                         // static float xcentre, xpoint, ypoint;
543                         // static int range, hgt;
544                         if (cur_value > _input.max())
545                             cur_value = _input.max();
546                         if (cur_value < _input.min())
547                             cur_value = _input.min();
548
549                         float xcentre = mid_scr.x ;
550                         float range = scrn_rect.right;
551                         float hgt = scrn_rect.top + scrn_rect.bottom;
552                         float xpoint = xcentre + (cur_value * range / val_span);
553                         float ypoint = hgt + marker_offset;
554                         draw_line(xcentre, ypoint, xpoint, ypoint);
555                         draw_line(xpoint, ypoint, xpoint, ypoint - marker_offset);
556                         draw_line(xpoint, ypoint - marker_offset, xpoint + 5.0, ypoint - 5.0);
557                         draw_line(xpoint, ypoint - marker_offset, xpoint - 5.0, ypoint - 5.0);
558                     }
559                 } else {
560                     fixed(marker_xs + scrn_rect.bottom / 4, height, marker_xs, marker_ys,
561                             marker_xs - scrn_rect.bottom / 4, height);
562                 }
563             } //if pointer
564         }  //end horizontal scale bottom
565
566
567         if (zoom == 1) {
568             zoomed_scale((int)vmin,(int)vmax);
569         } else {
570             //default to zoom=0
571             last = (int)vmax + 1;
572             i = (int)vmin;
573             for (; i < last; i++) {
574                 // for (i = (int)vmin; i <= (int)vmax; i++)     {
575                 // printf("<*> i = %d\n", i);
576                 condition = true;
577                 if (!modulo() && i < _input.min())
578                     condition = false;
579
580                 // printf("<**> i = %d\n", i);
581                 if (condition) {
582                     // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
583                     marker_xs = scrn_rect.left + (((i - vmin) * factor()/*+ .5f*/));
584
585                     if (oddtype == 1)
586                         k = i + 1; //enable ticks at odd values
587                     else
588                         k = i;
589
590                     if (_minor_divs) {
591                         //          if ((i % (int)_minor_divs) == 0) {
592                         //draw minor ticks
593                         if (!(k % (int)_minor_divs)) {
594                             // draw in ticks only if they aren't too close to the edge.
595                             if (((marker_xs - 5) > scrn_rect.left)
596                                     && ((marker_xs + 5)< (scrn_rect.left + scrn_rect.right))) {
597
598                                 if (option_both()) {
599                                     if (tick_length == "variable") {
600                                         draw_line(marker_xs, scrn_rect.top,
601                                                 marker_xs, marker_ys - 4);
602                                         draw_line(marker_xs, marker_ye + 4,
603                                                 marker_xs, height);
604                                     } else {
605                                         draw_line(marker_xs, scrn_rect.top,
606                                                 marker_xs, marker_ys);
607                                         draw_line(marker_xs, marker_ye,
608                                                 marker_xs, height);
609                                     }
610                                     // glBegin(GL_LINES);
611                                     // glVertex2f(marker_xs, scrn_rect.top);
612                                     // glVertex2f(marker_xs, marker_ys - 4);
613                                     // glVertex2f(marker_xs, marker_ye + 4);
614                                     // glVertex2f(marker_xs, scrn_rect.top + scrn_rect.bottom);
615                                     // glEnd();
616
617                                 } else {
618                                     if (option_top()) {
619                                         //draw minor ticks
620                                         if (tick_length == "variable")
621                                             draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
622                                         else
623                                             draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
624
625                                     } else if (tick_length == "variable") {
626                                         draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
627                                     } else {
628                                         draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
629                                     }
630                                 }
631                             }
632                         } //end draw minor ticks
633                     } //end minor ticks
634
635                     //major ticks
636                     if (_major_divs) {
637                         // printf("i = %d\n", i);
638                         // if ((i % (int)_major_divs)==0) {
639                         //     draw major ticks
640
641                         if (!(k % (int)_major_divs)) {
642                             if (modulo()) {
643                                 disp_val = i % (int) modulo(); // ?????????
644                                 if (disp_val < 0) {
645                                     while (disp_val<0)
646                                         disp_val += modulo();
647                                 }
648                             } else {
649                                 disp_val = i;
650                             }
651                             // printf("disp_val = %d\n", disp_val);
652                             // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
653                             lenstr = snprintf(buf, BUFSIZE, "%d",
654                                     // (int)(disp_val  * data_scaling() +.5));
655                                     int(disp_val * _input.factor() /*+.5*/));  // was data_scaling() ... makes no sense at all
656
657                             // Draw major ticks and text only if far enough from the edge.
658                             if (((marker_xs - 10)> scrn_rect.left)
659                                     && ((marker_xs + 10) < (scrn_rect.left + scrn_rect.right))) {
660                                 if (option_both()) {
661                                     // draw_line(marker_xs, scrn_rect.top,
662                                     //              marker_xs, marker_ys);
663                                     // draw_line(marker_xs, marker_ye,
664                                     //              marker_xs, scrn_rect.top + scrn_rect.bottom);
665                                     glBegin(GL_LINE_STRIP);
666                                     glVertex2f(marker_xs, scrn_rect.top);
667                                     glVertex2f(marker_xs, marker_ye);
668                                     glVertex2f(marker_xs, height);
669                                     glEnd();
670
671                                     if (!option_notext()) {
672                                         draw_text(marker_xs - 4 * lenstr,
673                                                 marker_ys + 4, buf, 0);
674                                     }
675                                 } else {
676                                     draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
677
678                                     if (!option_notext()) {
679                                         if (option_top()) {
680                                             draw_text(marker_xs - 4 * lenstr,
681                                                     height - 10, buf, 0);
682
683                                         }  else  {
684                                             draw_text(marker_xs - 4 * lenstr,
685                                                     scrn_rect.top, buf, 0);
686                                         }
687                                     }
688                                 }
689                             }
690                         }  //end draw major ticks
691                     } //endif major ticks
692                 }   //end condition
693             } //end for
694         }  //end zoom
695     } //end horizontal/vertical scale
696 } //draw
697
698
699
700 void HUD::Tape::circle(float x, float y, float size)
701 {
702     glEnable(GL_POINT_SMOOTH);
703     glPointSize(size);
704
705     glBegin(GL_POINTS);
706     glVertex2f(x, y);
707     glEnd();
708
709     glPointSize(1.0);
710     glDisable(GL_POINT_SMOOTH);
711 }
712
713
714 void HUD::Tape::fixed(float x1, float y1, float x2, float y2, float x3, float y3)
715 {
716     glBegin(GL_LINE_STRIP);
717     glVertex2f(x1, y1);
718     glVertex2f(x2, y2);
719     glVertex2f(x3, y3);
720     glEnd();
721 }
722
723
724 void HUD::Tape::zoomed_scale(int first, int last)
725 {
726     Point mid_scr = get_centroid();
727     Rect scrn_rect = get_location();
728     const int BUFSIZE = 80;
729     char buf[BUFSIZE];
730     int data[80];
731
732     float x, y, w, h, bottom;
733     float cur_value = _input.getFloatValue();
734     if (cur_value > _input.max())
735         cur_value = _input.max();
736     if (cur_value < _input.min())
737         cur_value = _input.min();
738
739     int a = 0;
740
741     while (first <= last) {
742         if ((first % (int)_major_divs) == 0) {
743             data[a] = first;
744             a++ ;
745         }
746         first++;
747     }
748     int centre = a / 2;
749
750     if (option_vert()) {
751         x = scrn_rect.left;
752         y = scrn_rect.top;
753         w = scrn_rect.left + scrn_rect.right;
754         h = scrn_rect.top + scrn_rect.bottom;
755         bottom = scrn_rect.bottom;
756
757         float xstart, yfirst, ycentre, ysecond;
758
759         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
760         yfirst = mid_scr.y - hgt;
761         ycentre = mid_scr.y;
762         ysecond = mid_scr.y + 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)) / _major_divs ;
770         int  incr = incrs / 2;
771         float factors = hgt1 / incr;
772
773         // begin
774         //this is for moving type pointer
775         static float ycent, ypoint, xpoint;
776         static float wth;
777
778         ycent = mid_scr.y;
779         wth = scrn_rect.left + scrn_rect.right;
780
781         if (cur_value <= data[centre + 1])
782             if (cur_value > data[centre]) {
783                 ypoint = ycent + ((cur_value - data[centre]) * hgt / _major_divs);
784             }
785
786         if (cur_value >= data[centre - 1])
787             if (cur_value <= data[centre]) {
788                 ypoint = ycent - ((data[centre] - cur_value) * hgt / _major_divs);
789             }
790
791         if (cur_value < data[centre - 1])
792             if (cur_value >= _input.min()) {
793                 float diff  = _input.min() - data[centre - 1];
794                 float diff1 = cur_value - data[centre - 1];
795                 float val = (diff1 * hgt1) / diff;
796
797                 ypoint = ycent - hgt - val;
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                 ypoint = ycent + hgt + val;
807             }
808
809         if (option_left()) {
810             xstart = w;
811
812             draw_line(xstart, ycentre, xstart - 5.0, ycentre); //centre tick
813
814             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes not sense at all
815
816             if (!option_notext())
817                 draw_text(x, ycentre, buf, 0);
818
819             for (i = 1; i < 5; i++) {
820                 yfirst += factor;
821                 ycentre += factor;
822                 circle(xstart - 2.5, yfirst, 3.0);
823                 circle(xstart - 2.5, ycentre, 3.0);
824             }
825
826             yfirst = mid_scr.y - hgt;
827
828             for (i = 0; i <= incr; i++) {
829                 draw_line(xstart, yfirst, xstart - 5.0, yfirst);
830                 draw_line(xstart, ysecond, xstart - 5.0, ysecond);
831
832                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor()));  // was data_scaling() ... makes no sense at all
833
834                 if (!option_notext())
835                     draw_text(x, yfirst, buf, 0);
836
837                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
838
839                 if (!option_notext())
840                     draw_text(x, ysecond, buf, 0);
841
842                 yfirst -= factors;
843                 ysecond += factors;
844
845             }
846
847             //to draw moving type pointer for left option
848             //begin
849             xpoint = wth + 10.0;
850
851             if (pointer_type == "moving") {
852                 draw_line(xpoint, ycent, xpoint, ypoint);
853                 draw_line(xpoint, ypoint, xpoint - 10.0, ypoint);
854                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint + 5.0);
855                 draw_line(xpoint - 10.0, ypoint, xpoint - 5.0, ypoint - 5.0);
856             }
857             //end
858
859         } else {
860             //option_right
861             xstart = (x + w) / 2;
862
863             draw_line(xstart, ycentre, xstart + 5.0, ycentre); //centre tick
864
865             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
866
867             if (!option_notext())
868                 draw_text(w, ycentre, buf, 0);
869
870             for (i = 1; i < 5; i++) {
871                 yfirst += factor;
872                 ycentre += factor;
873                 circle(xstart + 2.5, yfirst, 3.0);
874                 circle(xstart + 2.5, ycentre, 3.0);
875             }
876
877             yfirst = mid_scr.y - hgt;
878
879             for (i = 0; i <= incr; i++) {
880                 draw_line(xstart, yfirst, xstart + 5.0, yfirst);
881                 draw_line(xstart, ysecond, xstart + 5.0, ysecond);
882
883                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
884
885                 if (!option_notext())
886                     draw_text(w, yfirst, buf, 0);
887
888                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor()));
889
890                 if (!option_notext())
891                     draw_text(w, ysecond, buf, 0);
892
893                 yfirst -= factors;
894                 ysecond += factors;
895
896             }
897
898             // to draw moving type pointer for right option
899             //begin
900             xpoint = scrn_rect.left;
901
902             if (pointer_type == "moving") {
903                 draw_line(xpoint, ycent, xpoint, ypoint);
904                 draw_line(xpoint, ypoint, xpoint + 10.0, ypoint);
905                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint + 5.0);
906                 draw_line(xpoint + 10.0, ypoint, xpoint + 5.0, ypoint - 5.0);
907             }
908             //end
909         }//end option_right /left
910         //end of vertical scale
911
912     } else {
913         //horizontal scale
914         x = scrn_rect.left;
915         y = scrn_rect.top;
916         w = scrn_rect.left + scrn_rect.right;
917         h = scrn_rect.top + scrn_rect.bottom;
918         bottom = scrn_rect.right;
919
920         float ystart, xfirst, xcentre, xsecond;
921
922         float hgt = bottom * 20.0 / 100.0;  // 60% of height should be zoomed
923         xfirst = mid_scr.x - hgt;
924         xcentre = mid_scr.x;
925         xsecond = mid_scr.x + hgt;
926         float range = hgt * 2;
927
928         int i;
929         float factor = range / 10.0;
930
931         float hgt1 = bottom * 30.0 / 100.0;
932         int  incrs = ((int)val_span - (_major_divs * 2)) / _major_divs ;
933         int  incr = incrs / 2;
934         float factors = hgt1 / incr;
935
936
937         //Code for Moving Type Pointer
938         //begin
939         static float xcent, xpoint, ypoint;
940
941         xcent = mid_scr.x;
942
943         if (cur_value <= data[centre + 1])
944             if (cur_value > data[centre]) {
945                 xpoint = xcent + ((cur_value - data[centre]) * hgt / _major_divs);
946             }
947
948         if (cur_value >= data[centre - 1])
949             if (cur_value <= data[centre]) {
950                 xpoint = xcent - ((data[centre] - cur_value) * hgt / _major_divs);
951             }
952
953         if (cur_value < data[centre - 1])
954             if (cur_value >= _input.min()) {
955                 float diff = _input.min() - data[centre - 1];
956                 float diff1 = cur_value - data[centre - 1];
957                 float val = (diff1 * hgt1) / diff;
958
959                 xpoint = xcent - hgt - val;
960             }
961
962
963         if (cur_value > data[centre + 1])
964             if (cur_value <= _input.max()) {
965                 float diff = _input.max() - data[centre + 1];
966                 float diff1 = cur_value - data[centre + 1];
967                 float val = (diff1 * hgt1) / diff;
968
969                 xpoint = xcent + hgt + val;
970             }
971
972         //end
973         if (option_top()) {
974             ystart = h;
975             draw_line(xcentre, ystart, xcentre, ystart - 5.0); //centre tick
976
977             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor()));  // was data_scaling() ... makes no sense at all
978
979             if (!option_notext())
980                 draw_text(xcentre - 10.0, y, buf, 0);
981
982             for (i = 1; i < 5; i++) {
983                 xfirst += factor;
984                 xcentre += factor;
985                 circle(xfirst, ystart - 2.5, 3.0);
986                 circle(xcentre, ystart - 2.5, 3.0);
987             }
988
989             xfirst = mid_scr.x - hgt;
990
991             for (i = 0; i <= incr; i++) {
992                 draw_line(xfirst, ystart, xfirst,  ystart - 5.0);
993                 draw_line(xsecond, ystart, xsecond, ystart - 5.0);
994
995                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
996
997                 if (!option_notext())
998                     draw_text(xfirst - 10.0, y, buf, 0);
999
1000                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
1001
1002                 if (!option_notext())
1003                     draw_text(xsecond - 10.0, y, buf, 0);
1004
1005
1006                 xfirst -= factors;
1007                 xsecond += factors;
1008             }
1009             //this is for moving pointer for top option
1010             //begin
1011
1012             ypoint = scrn_rect.top + scrn_rect.bottom + 10.0;
1013
1014             if (pointer_type == "moving") {
1015                 draw_line(xcent, ypoint, xpoint, ypoint);
1016                 draw_line(xpoint, ypoint, xpoint, ypoint - 10.0);
1017                 draw_line(xpoint, ypoint - 10.0, xpoint + 5.0, ypoint - 5.0);
1018                 draw_line(xpoint, ypoint - 10.0, xpoint - 5.0, ypoint - 5.0);
1019             }
1020             //end of top option
1021
1022         } else {
1023             //else option_bottom
1024             ystart = (y + h) / 2;
1025
1026             //draw_line(xstart, yfirst,  xstart - 5.0, yfirst);
1027             draw_line(xcentre, ystart, xcentre, ystart + 5.0); //centre tick
1028
1029             snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre] * _input.factor())); // was data_scaling() ... makes no sense at all
1030
1031             if (!option_notext())
1032                 draw_text(xcentre - 10.0, h, buf, 0);
1033
1034             for (i = 1; i < 5; i++) {
1035                 xfirst += factor;
1036                 xcentre += factor;
1037                 circle(xfirst, ystart + 2.5, 3.0);
1038                 circle(xcentre, ystart + 2.5, 3.0);
1039             }
1040
1041             xfirst = mid_scr.x - hgt;
1042
1043             for (i = 0; i <= incr; i++) {
1044                 draw_line(xfirst, ystart, xfirst, ystart + 5.0);
1045                 draw_line(xsecond, ystart, xsecond, ystart + 5.0);
1046
1047                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre - i - 1] * _input.factor())); // was data_scaling() ... makes no sense at all
1048
1049                 if (!option_notext())
1050                     draw_text(xfirst - 10.0, h, buf, 0);
1051
1052                 snprintf(buf, BUFSIZE, "%3.0f\n", (float)(data[centre + i + 1] * _input.factor())); // was data_scaling() ... makes no sense at all
1053
1054                 if (!option_notext())
1055                     draw_text(xsecond - 10.0, h, buf, 0);
1056
1057                 xfirst -= factors;
1058                 xsecond   += factors;
1059             }
1060             //this is for movimg pointer for bottom option
1061             //begin
1062
1063             ypoint = scrn_rect.top - 10.0;
1064             if (pointer_type == "moving") {
1065                 draw_line(xcent, ypoint, xpoint, ypoint);
1066                 draw_line(xpoint, ypoint, xpoint, ypoint + 10.0);
1067                 draw_line(xpoint, ypoint + 10.0, xpoint + 5.0, ypoint + 5.0);
1068                 draw_line(xpoint, ypoint + 10.0, xpoint - 5.0, ypoint + 5.0);
1069             }
1070         }//end hud_top or hud_bottom
1071     }  //end of horizontal/vertical scales
1072 }//end draw
1073
1074