]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_instrument.cxx
Reset: work with threaded OSG modes
[flightgear.git] / src / Instrumentation / HUD / HUD_instrument.cxx
1 // HUD_instrument.cxx -- HUD Common Instrument Base
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 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include <simgear/math/SGLimits.hxx>
27 #include <simgear/props/condition.hxx>
28
29 #include "HUD.hxx"
30 #include "HUD_private.hxx"
31
32 #include <Main/globals.hxx>
33
34 using std::vector;
35
36 HUD::Item::Item(HUD *hud, const SGPropertyNode *n, float x, float y) :
37     _hud(hud),
38     _name(n->getStringValue("name", "[unnamed]")),
39     _options(0),
40     _condition(0),
41     _digits(n->getIntValue("digits"))
42 {
43     const SGPropertyNode *node = n->getNode("condition");
44     if (node)
45         _condition = sgReadCondition(globals->get_props(), node);
46
47     _x = n->getFloatValue("x") + x;
48     _y = n->getFloatValue("y") + y;
49     _w = n->getFloatValue("width");
50     _h = n->getFloatValue("height");
51
52     vector<SGPropertyNode_ptr> opt = n->getChildren("option");
53     for (unsigned int i = 0; i < opt.size(); i++) {
54         const char *o = opt[i]->getStringValue();
55         if (!strcmp(o, "vertical"))
56             _options |= VERTICAL;
57         else if (!strcmp(o, "horizontal"))
58             _options |= HORIZONTAL;
59         else if (!strcmp(o, "top"))
60             _options |= TOP;
61         else if (!strcmp(o, "left"))
62             _options |= LEFT;
63         else if (!strcmp(o, "bottom"))
64             _options |= BOTTOM;
65         else if (!strcmp(o, "right"))
66             _options |= RIGHT;
67         else if (!strcmp(o, "both"))
68             _options |= (LEFT|RIGHT);
69         else if (!strcmp(o, "noticks"))
70             _options |= NOTICKS;
71         else if (!strcmp(o, "notext"))
72             _options |= NOTEXT;
73         else
74             SG_LOG(SG_INPUT, SG_WARN, "HUD: unsupported option: " << o);
75     }
76
77     // Set up convenience values for centroid of the box and
78     // the span values according to orientation
79
80     if (_options & VERTICAL) {
81         _scr_span = _h;
82     } else {
83         _scr_span = _w;
84     }
85
86     _center_x = _x + _w / 2.0;
87     _center_y = _y + _h / 2.0;
88 }
89
90
91 bool HUD::Item::isEnabled()
92 {
93     return _condition ? _condition->test() : true;
94 }
95
96
97 void HUD::Item::draw_line(float x1, float y1, float x2, float y2)
98 {
99     _hud->_line_list.add(LineSegment(x1, y1, x2, y2));
100 }
101
102
103 void HUD::Item::draw_stipple_line(float x1, float y1, float x2, float y2)
104 {
105     _hud->_stipple_line_list.add(LineSegment(x1, y1, x2, y2));
106 }
107
108
109 void HUD::Item::draw_text(float x, float y, const char *msg, int align, int digit)
110 {
111     _hud->_text_list.add(x, y, msg, align, digit);
112 }
113
114
115 void HUD::Item::draw_circle(float xoffs, float yoffs, float r) const
116 {
117     glBegin(GL_LINE_LOOP);
118     float step = SG_PI / r;
119     for (float alpha = 0; alpha < SG_PI * 2.0; alpha += step) {
120         float x = r * cos(alpha);
121         float y = r * sin(alpha);
122         glVertex2f(x + xoffs, y + yoffs);
123     }
124     glEnd();
125 }
126
127 void HUD::Item::draw_arc(float xoffs, float yoffs, float t0, float t1, float r) const
128 {
129     glBegin(GL_LINE_STRIP);
130     float step = SG_PI / r;
131     t0 = t0 * SG_DEGREES_TO_RADIANS;
132     t1 = t1 * SG_DEGREES_TO_RADIANS;
133
134     for (float alpha = t0; alpha < t1; alpha += step) {
135         float x = r * cos(alpha);
136         float y = r * sin(alpha);
137         glVertex2f(x + xoffs, y + yoffs);
138     }
139     glEnd();
140 }
141
142 void HUD::Item::draw_bullet(float x, float y, float size)
143 {
144     glEnable(GL_POINT_SMOOTH);
145     glPointSize(size);
146
147     glBegin(GL_POINTS);
148     glVertex2f(x, y);
149     glEnd();
150
151     glPointSize(1.0);
152     glDisable(GL_POINT_SMOOTH);
153 }
154
155
156 // make sure the format matches '[ -+#]?\d*(\.\d*)?(l?[df]|s)'
157 //
158 HUD::Item::Format HUD::Item::check_format(const char *f) const
159 {
160     bool l = false;
161     Format fmt = STRING;
162
163     for (; *f; f++) {
164         if (*f == '%') {
165             if (f[1] == '%')
166                 f++;
167             else
168                 break;
169         }
170     }
171     if (*f++ != '%')
172         return NONE;
173     if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
174         f++;
175     while (*f && isdigit(*f))
176         f++;
177     if (*f == '.') {
178         f++;
179         while (*f && isdigit(*f))
180             f++;
181     }
182     if (*f == 'l')
183         l = true, f++;
184
185     if (*f == 'd')
186         fmt = l ? LONG : INT;
187     else if (*f == 'f')
188         fmt = l ? DOUBLE : FLOAT;
189     else if (*f == 's') {
190         if (l)
191             return INVALID;
192         fmt = STRING;
193     } else
194         return INVALID;
195
196     for (++f; *f; f++) {
197         if (*f == '%') {
198             if (f[1] == '%')
199                 f++;
200             else
201                 return INVALID;
202         }
203     }
204     return fmt;
205 }
206
207