}
+
+
+
+
+
+
+// HUDText -- text container for TextList vector
+
+
+HUDText::HUDText(fntRenderer *fnt, float x, float y, const char *s, int align, int d) :
+ _fnt(fnt),
+ _x(x),
+ _y(y),
+ _digits(d)
+{
+ strncpy(_msg, s, BUFSIZE);
+ if (!align || !s[0])
+ return;
+
+ fntFont *f = _fnt->getFont();
+ float gap = f->getGap();
+ float left, right, bot, top;
+ f->getBBox(s, _fnt->getPointSize(), _fnt->getSlant(), &left, &right, &bot, &top);
+
+ if (align & HCENTER)
+ _x = x - left + gap - (right - left - gap) / 2.0;
+ else if (align & RIGHT)
+ _x = x - right;
+ else if (align & LEFT)
+ _x = x - left;
+
+ if (align & VCENTER)
+ _y = y - bot - (top - bot) / 2.0;
+ else if (align & TOP)
+ _y = y - top;
+ else if (align & BOTTOM)
+ _y = y - bot;
+}
+
+
+void HUDText::draw()
+{
+ if (!_digits) { // show all digits in same size
+ _fnt->start2f(_x, _y);
+ _fnt->puts(_msg);
+ return;
+ }
+
+ // FIXME
+ // this code is changed to display Numbers with big/small digits
+ // according to MIL Standards for example Altitude above 10000 ft
+ // is shown as 10ooo.
+
+ int c = 0, i = 0;
+ char *t = _msg;
+ int p = 4;
+
+ if (t[0] == '-') {
+ //if negative value then increase the c and p values
+ //for '-' sign.
+ c++; // was moved to the comment. Unintentionally? TODO
+ p++;
+ }
+ char *tmp = _msg;
+ while (tmp[i] != '\0') {
+ if ((tmp[i] >= '0') && (tmp[i] <= '9'))
+ c++;
+ i++;
+ }
+
+ float orig_size = _fnt->getPointSize();
+ if (c > p) {
+ _fnt->setPointSize(orig_size * 0.8);
+ int p1 = c - 3;
+ char *tmp1 = _msg + p1;
+ int p2 = p1 * 8;
+
+ _fnt->start2f(_x + p2, _y);
+ _fnt->puts(tmp1);
+
+ _fnt->setPointSize(orig_size * 1.2);
+ char tmp2[BUFSIZE];
+ strncpy(tmp2, _msg, p1);
+ tmp2[p1] = '\0';
+
+ _fnt->start2f(_x, _y);
+ _fnt->puts(tmp2);
+ } else {
+ _fnt->setPointSize(orig_size * 1.2);
+ _fnt->start2f(_x, _y);
+ _fnt->puts(tmp);
+ }
+ _fnt->setPointSize(orig_size);
+}
+
+
class HUDText {
public:
- HUDText(float x, float y, char *s, int d = 0) : _x(x), _y(y), _digits(d) {
- strncpy(_msg, s, BUFSIZE);
- }
-
- // this code is changed to display Numbers with big/small digits
- // according to MIL Standards for example Altitude above 10000 ft
- // is shown as 10ooo.
-
- void draw(fntRenderer *fnt) {
- if (!_digits) { // show all digits in same size
- fnt->start2f(_x, _y);
- fnt->puts(_msg);
- return;
- }
-
- int c = 0, i = 0;
- char *t = _msg;
- int p = 4;
-
- if (t[0] == '-') {
- //if negative value then increase the c and p values
- //for '-' sign.
- c++; // was moved to the comment. Unintentionally? TODO
- p++;
- }
- char *tmp = _msg;
- while (tmp[i] != '\0') {
- if ((tmp[i] >= '0') && (tmp[i] <= '9'))
- c++;
- i++;
- }
-
- float orig_size = fnt->getPointSize();
- if (c > p) {
- fnt->setPointSize(orig_size * 0.8);
- int p1 = c - 3;
- char *tmp1 = _msg + p1;
- int p2 = p1 * 8;
-
- fnt->start2f(_x + p2, _y);
- fnt->puts(tmp1);
-
- fnt->setPointSize(orig_size * 1.2);
- char tmp2[BUFSIZE];
- strncpy(tmp2, _msg, p1);
- tmp2[p1] = '\0';
-
- fnt->start2f(_x, _y);
- fnt->puts(tmp2);
- } else {
- fnt->setPointSize(orig_size * 1.2);
- fnt->start2f(_x, _y);
- fnt->puts(tmp);
- }
- fnt->setPointSize(orig_size);
- }
+ HUDText(fntRenderer *f, float x, float y, const char *s, int align = 0, int digits = 0);
+ void draw();
+ enum {
+ LEFT = 0x0001,
+ RIGHT = 0x0002,
+ TOP = 0x0004,
+ BOTTOM = 0x0008,
+ HCENTER = 0x0010,
+ VCENTER = 0x0020,
+ CENTER = (HCENTER|VCENTER),
+ };
private:
+ fntRenderer *_fnt;
float _x, _y;
int _digits;
static const int BUFSIZE = 64;
TextList() { _font = 0; }
void setFont(fntRenderer *Renderer) { _font = Renderer; }
- void add(const HUDText& String) { _list.push_back(String); }
+ void add(float x, float y, const char *s, int align = 0, int digit = 0) {
+ _list.push_back(HUDText(_font, x, y, s, align, digit));
+ }
void erase() { _list.erase(_list.begin(), _list.end()); }
void draw() {
assert(_font);
_font->begin();
vector<HUDText>::iterator it, end = _list.end();
for (it = _list.begin(); it != end; ++it)
- it->draw(_font);
+ it->draw();
_font->end();
glDisable(GL_TEXTURE_2D);
BOTTOM = 0x0004,
LEFT = 0x0008,
RIGHT = 0x0010,
- HCENTER = 0x0020,
- VCENTER = 0x0040,
- NOTICKS = 0x0080,
- NOTEXT = 0x0100,
+ NOTICKS = 0x0020,
+ NOTEXT = 0x0040,
BOTH = (LEFT|RIGHT),
- CENTER = (HCENTER|VCENTER),
- };
-
- enum Adjust {
- LEFT_ALIGN,
- CENTER_ALIGN,
- RIGHT_ALIGN
};
protected:
inline bool option_top() const { return (_options & TOP) == TOP; }
inline bool option_bottom() const { return (_options & BOTTOM) == BOTTOM; }
- void draw_line( float x1, float y1, float x2, float y2);
- void draw_stipple_line( float x1, float y1, float x2, float y2);
- void draw_text( float x, float y, char *msg, int digit);
+ void draw_line(float x1, float y1, float x2, float y2);
+ void draw_stipple_line(float x1, float y1, float x2, float y2);
+ void draw_text(float x, float y, char *msg, int align = 0, int digit = 0);
float text_width(char *str) const;
void draw_circle(float x1, float y1, float r) const;
void draw_bullet(float, float, float);
Input _input;
Format _mode;
string _format;
- Adjust _halign;
+ int _halign; // HUDText alignment
int _blink;
bool _box;
float _text_y;
void draw_zenith(float, float);
void draw_nadir(float, float);
- void draw_text(float x, float y, char *s) {
- _locTextList.add(HUDText(x, y, s));
+ void draw_text(float x, float y, char *s, int align = 0) {
+ _locTextList.add(x, y, s, align, 0);
}
void draw_line(float x1, float y1, float x2, float y2) {
}
-void HUD::Item::draw_text(float x, float y, char *msg, int digit)
+void HUD::Item::draw_text(float x, float y, char *msg, int align, int digit)
{
- _hud->_text_list.add(HUDText(x, y, msg, digit));
+ _hud->_text_list.add(x, y, msg, align, digit);
}
const char *halign = n->getStringValue("halign", "center");
if (!strcmp(halign, "left"))
- _halign = LEFT_ALIGN;
+ _halign = HUDText::LEFT;
else if (!strcmp(halign, "right"))
- _halign = RIGHT_ALIGN;
+ _halign = HUDText::RIGHT;
else
- _halign = CENTER_ALIGN;
+ _halign = HUDText::HCENTER;
+
+ _halign |= HUDText::VCENTER;
const char *pre = n->getStringValue("prefix", 0);
const char *post = n->getStringValue("postfix", 0);
_mode = NONE;
}
- float top, bot;
- _hud->_font->getBBox("0", _hud->_font_size, 0.0, 0, 0, &bot, &top);
- _text_y = _y + (_h - top + bot) / 2.0 - bot;
blink();
}
else if (_mode == DOUBLE) // not really supported yet
snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
- float posincr;
- float L, R, B, T;
- _hud->_font->getBBox(buf, _hud->_font_size, 0.0, &L, &R, &B, &T);
- float lenstr = R - L;
-
- if (_halign == RIGHT_ALIGN)
- posincr = _w - lenstr;
- else if (_halign == CENTER_ALIGN)
- posincr = (_w - lenstr) / 2.0;
- else // LEFT_ALIGN
- posincr = 0;
-
- posincr += _hud->_font->getGap() / 2.0 - L;
- draw_text(_x + posincr, _text_y, buf, get_digits());
+ if (_halign & HUDText::HCENTER)
+ draw_text(_center_x, _center_y, buf, _halign, get_digits());
+ else if (_halign & HUDText::LEFT)
+ draw_text(_x, _center_y, buf, _halign, get_digits());
+ else // if (_halign & HUDText::RIGHT)
+ draw_text(_x + _w, _center_y, buf, _halign, get_digits());
}
sgdVec3 p; sgdSetVec3(p, vel_x, vel_y, 0.0);
sgdVec3 p0; sgdSetVec3(p0, 0.0, 0.0, 0.0);
sgdVec3 d; sgdSetVec3(d, cos(roll_value), sin(roll_value), 0.0);
- sgdClosestPointToLine( p1, p, p0, d );
+ sgdClosestPointToLine(p1, p, p0, d);
glTranslatef(p1[0], p1[1], 0);
}
} else {
if (_div_units) {
const int BUFSIZE = 8;
char buf[BUFSIZE];
- float label_length;
- float label_height;
- float left;
- float right;
- float bot;
- float top;
- float text_offset = 4.0f;
- float zero_offset = 0.0;
-
- // horizon line is wider by this much (hard coded ??)
- zero_offset = 50.0f;
-
- fntFont *font = _hud->_font_renderer->getFont(); // FIXME
- float pointsize = _hud->_font_renderer->getPointSize();
- float italic = _hud->_font_renderer->getSlant();
+ const float zero_offset = 50.0f; // horizon line is wider by this much
_locTextList.setFont(_hud->_font_renderer);
_locTextList.erase();
if (!(i % _div_units)) { // At integral multiple of div
snprintf(buf, BUFSIZE, "%d", i);
- font->getBBox(buf, pointsize, italic, &left, &right, &bot, &top);
- label_length = right + left;
- label_height = (top + bot) / 2.0f;
-
x_ini = -half_span;
- if (i >= 0) {
+ if (i == 0) {
// Make zero point wider on left
- if (i == 0)
- x_ini -= zero_offset;
+ x_ini -= zero_offset;
+ x_end += zero_offset;
+
+ draw_line(x_ini, y, x_end, y);
+ } else if (i > 0) {
// Zero or above draw solid lines
draw_line(x_ini, y, x_end, y);
draw_nadir(0.0, y);
}
- // Calculate the position of the left text and write it.
- draw_text(x_ini - text_offset - label_length + 2.5/*hack*/, y - label_height, buf);
- draw_text(x_end + text_offset, y - label_height, buf);
+ draw_text(x_ini - 4, y, buf, HUDText::VCENTER|HUDText::LEFT);
+ draw_text(x_end + 4, y, buf, HUDText::VCENTER|HUDText::RIGHT);
}
}
for (; i < last; i++) {
if (_type == PITCH) {
y = float(i - pitch_value) * _compression + .5;
- } else {
- // _type == CLIMB_DIVE
+ } else { // _type == CLIMB_DIVE
y = float(i - actslope) * _compression + .5;
}
- if ( i < 0 )
- y_end = y +
- sin(0.5 * i * SG_DEGREES_TO_RADIANS * 3/*hack*/) *
- _compression;
- else
- y_end = y;
if (!(i % _div_units)) { // At integral multiple of div
snprintf(buf, BUFSIZE, "%d", i);
- font->getBBox(buf, pointsize, italic, &left, &right, &bot, &top);
- label_length = right + left;
- label_height = (top + bot) / 2.0f;
- //printf("%s -- l %f r %f b %f t %f\n", buf, left, right, bot, top);
// Start by calculating the points and drawing the
// left side lines.
x_ini = -half_span;
x_end2 = half_span;
+ y_end = y;
- if (i >= 0) {
+ if (i == 0) {
// Make zero point wider on left
- if (i == 0) {
- x_ini -= zero_offset;
- x_end2 += zero_offset;
- } else {
- //draw climb bar vertical lines
- draw_line(x_end, y - 5.0, x_end, y);
- draw_line(x_ini2, y - 5.0, x_ini2, y);
- }
+ x_ini -= zero_offset;
+ x_end2 += zero_offset;
+
+ draw_line(x_ini, y, x_end, y);
+ draw_line(x_ini2, y, x_end2, y);
+
+ draw_text(x_ini - 3, y, buf, HUDText::VCENTER|HUDText::RIGHT);
+ draw_text(x_end2 + 3, y, buf, HUDText::VCENTER|HUDText::LEFT);
+
+ } else if (i > 0) {
+ //draw climb bar vertical lines
+ draw_line(x_ini, y - 5.0, x_ini, y);
+ draw_line(x_end2, y - 5.0, x_end2, y);
+
// draw pitch / climb bar
draw_line(x_ini, y, x_end, y);
draw_line(x_ini2, y, x_end2, y);
+ draw_text(x_ini + 0.5, y - 0.5, buf, HUDText::TOP|HUDText::LEFT);
+ draw_text(x_end2 - 0.5, y - 0.5, buf, HUDText::TOP|HUDText::RIGHT);
+
if (i == 90 && _zenith)
draw_zenith(0.0, y);
} else { // i < 0
+ y_end = y + sin(0.5 * i * SG_DEGREES_TO_RADIANS * 3/*hack*/) *
+ _compression;
+
// draw dive bar vertical lines
draw_line(x_end, y + 5.0, x_end, y);
draw_line(x_ini2, y + 5.0, x_ini2, y);
draw_stipple_line(x_ini, y_end, x_end, y);
draw_stipple_line(x_ini2, y, x_end2, y_end);
+ float yoffs = 1.0 + (y - y_end) / 4.0; // too hackish?
+ draw_text(x_ini + 2.0, y_end + yoffs, buf, HUDText::BOTTOM|HUDText::HCENTER);
+ draw_text(x_end2 - 2.0, y_end + yoffs, buf, HUDText::BOTTOM|HUDText::HCENTER);
+
if (i == -90 && _nadir)
draw_nadir(0.0, y);
}
-
- // Now calculate the location of the left side label using
- draw_text(x_ini - text_offset - label_length + 2.5/*hack*/, y_end - label_height, buf);
- draw_text(x_end2 + text_offset, y_end - label_height, buf);
}
}