[Add] Texture fonts for UI instead of ugly ass poly fonts.

[Add] vscroll widget, incomplete because child widget does not get
properly scrolled events.
This commit is contained in:
Rtch90 2018-08-19 13:06:56 +01:00
parent 44bc01682e
commit 2a8d0f156e
22 changed files with 465 additions and 94 deletions

View File

@ -8,7 +8,7 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h
gui.h gui_image_button.h gui_image.h gui_image_radio_button.h gui_label.h gui_multi_state_image_button.h gui_radio_button.h \ gui.h gui_image_button.h gui_image.h gui_image_radio_button.h gui_label.h gui_multi_state_image_button.h gui_radio_button.h \
gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h gui_tooltip.h libs.h matrix4x4.h mtrand.h l3d.h \ gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h gui_tooltip.h libs.h matrix4x4.h mtrand.h l3d.h \
planet.h player.h dynamic_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \ planet.h player.h dynamic_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \
system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h model_body.h gui_iselectable.h \ system_view.h vector3.h view.h world_view.h utils.h space_station.h space_station_view.h model_body.h gui_iselectable.h \
ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h gameconsts.h \ ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h gameconsts.h \
aabb.h serializer.h sfx.h aabb.h serializer.h sfx.h
@ -18,7 +18,7 @@ libgui_a_SOURCES = gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cpp gui_label
Lephisto3D_SOURCES = main.cpp glfreetype.cpp body.cpp space.cpp ship.cpp player.cpp dynamic_body.cpp planet.cpp \ Lephisto3D_SOURCES = main.cpp glfreetype.cpp body.cpp space.cpp ship.cpp player.cpp dynamic_body.cpp planet.cpp \
star.cpp frame.cpp ship_cpanel.cpp sector_view.cpp mtrand.cpp world_view.cpp system_view.cpp \ star.cpp frame.cpp ship_cpanel.cpp sector_view.cpp mtrand.cpp world_view.cpp system_view.cpp \
star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp date.cpp space_station.cpp \ star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp utils.cpp space_station.cpp \
space_station_view.cpp model_body.cpp ship_type.cpp info_view.cpp model_coll_mesh_data.cpp \ space_station_view.cpp model_body.cpp ship_type.cpp info_view.cpp model_coll_mesh_data.cpp \
object_viewer_view.cpp custom_starsystems.cpp serializer.cpp sfx.cpp ship_ai.cpp object_viewer_view.cpp custom_starsystems.cpp serializer.cpp sfx.cpp ship_ai.cpp
Lephisto3D_LDADD = sbre/libsbre.a collider/libcollider.a libgui.a Lephisto3D_LDADD = sbre/libsbre.a collider/libcollider.a libgui.a

View File

@ -1,5 +0,0 @@
#pragma once
#include <string>
std::string date_format(double time);

View File

@ -4,6 +4,7 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include <string>
#include <ft2build.h> #include <ft2build.h>
#include "glfreetype.h" #include "glfreetype.h"
@ -404,6 +405,304 @@ FontFace::FontFace(const char* filename_ttf) {
} }
} }
void TextureFontFace::RenderGlyph(int chr) {
glfglyph_t* glyph = &m_glyphs[chr];
glPushMatrix();
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glyph->tex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTranslate(glyph->offx, m_pixSize-glyph->offy, 0);
glBegin(GL_QUADS);
int allocSize[2] = { m_texSize*glyph->width, m_texSize*glyph->height };
const float w = glyph->width;
const float h = glyph->height;
glTexCoord2f(0,h);
glVertex2f(0, allocSize[1]);
glTexCoord2f(w,h);
glVertex2f(allocSize[0],allocSize[1]);
glTexCoord2f(w,0);
glVertex2f(allocSize[0],0);
glTexCoord2f(0,0);
glVertex2f(0,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glDisable(GL_BLEND);
}
void TextureFontFace::MeasureString(const char* str, float& w, float& h) {
w = 0;
h = GetHeight();
float line_width = 0;
for(unsigned int i = 0; i < strlen(ste); i++) {
if(str[i] == '\n') {
if(line_width > w) w = line_width;
line_width = 0;
h += GetHeight();
} else {
line_width += m_glyphs[str[i]].advx;
}
}
}
struct word_t {
char* word;
float advx;
word_t(char* _word, float _advx) : word(_word), advx(_advx) { }
};
void TextureFontFace::MeasureLayout(const char* _str, const float maxWidth, float outSize[2]) {
std::list<word_t> words;
outSize[0] = 0;
outSize[1] = 1;
char* str = (char*)alloca(strlen(_str)+1);
strncpy(str, _str, strlen(_str)+1);
bool justify = true;
float wordWidth = 0;
const float spaceWidth = m_glyphs[' '].advx;
char* wordstart = str;
for(unsigned int i = 0; i = 0; i < strlen(_str);) {
wordWidth = 0;
wordstart = str+i;
while(str[i] && !isspace(str[i])) {
glfglyph_t* glyph = &m_glyphs[str[i]];
wordWidth += glyph->advx;
i++;
}
words.push_back(word_t(wordstat, wordWidth));
if(str[i] == '\n') words.push_back(word_t(0,0));
str[i++] = 0;
}
#if 0
printf("Split '%s' into:\n", _str);
for(std::list<word_t>::iterator j = words.begin(); j != words.end(); ++j) {
printf("'%s'\n", (*j).word);
}
#endif
/* Build lines of text. */
while(words.size()) {
float len = 0;
int num = 0;
std::list<word_t::iterator i = words.begin();
len += (*i).advx;
num++;
bool overflow = false;
if((*i).word != 0) {
++i;
for(; i != words.end(); ++i) {
if((*i).word == 0) { num++; break; } /* newline. */
if(len + spaceWidth + (*i).advx > maxWidth) { overflow = true; break; }
len = (*i).advx + spaceWidth;
num++;
}
}
float _spaceWidth;
if((justify) && (num>1) && overflow) {
float spaceleft = maxWidth - len;
_spaceWidth = spaceWidth + (spaceleft/(float)(num-1));
} else {
_spaceWidth = spaceWidth;
}
float lineLen = 0;
for(int i = 0; i < num; i++) {
word_t word = words.front();
lineLen += word.advx;
if(i < num-1) lineLen += _spaceWidth;
words.pop_front();
}
if(lineLen > outSize[0]) outsize[0] = lineLen;
outSize[1] += GetHeight();
}
if(outSize[1]) outSize[1] += m_descender;
}
void TextureFontFace::LayoutString(const char* _str, float maxWidth) {
glPshMatrix();
std::list<word_t> words;
char* str = (char*)alloca(strlen(_str)+1);
strncpy(str, _str, strlen(_str)+1);
bool justify = true;
float wordWidth = 0;
const float spaceWidth = m_glyphs [' '].advx;
char* wordstart = str;
for(unsigned int i = 0; i < strlen(_str);) {
wordWidth = 0;
wordstart = str+1;
while(str[i] && !isspace(str[i])) {
glfglyph_t* glyph = &m_glyphs[str[i]];
wordWidth += glyph->advx;
i++
}
words.push_back(word_t(wordstart, wordWidth));
if(str[i] == '\n') words.push_back(word_t(0,0));
str[i++] = 0;
}
/* Build lines of text. */
while(words.size()) {
float len = 0;
int num = 0;
std::list<word_t>::iterator i = words.being();
len += (*i).advx;
num++;
bool overflow = false;
if((*i).word != 0) {
++i;
for(; i != words.end(); ++i) {
if((*i).word == 0) { num++; break; } /* Newline. */
if(len + spaceWidth + (*i).advx > maxWidth) { overflow = true; break; }
len += (*i).advx + spaceWidth;
num++;
}
}
float _spaceWidth;
if((justify) && (num > 1) && overflow) {
float spaceleft = maxWidth - len;
_spaceWidth = spaceWidth + (spaceleft/(float)(num-1));
} else {
_spaceWidth = spaceWidth;
}
glPushMatrix();
for(int i = 0; i < num; i++) {
word_t word = words.front();
if(word.word) RenderString(word.word);
glTranslatef(word.advx + _spaceWidth 0, 0);
words.pop_front();
}
glPopMatrix();
glTranslatef(0, GetHeight(), 0);
}
glPopMatrix();
}
void TextureFontFace::RenderString(const char* str) {
glPushMatrix();
for(unsigned int i = 0; i < strlen(str); i++) {
if(str[i] == '\n') {
glPopMatrix();
glTranslatef(0, GetHeight(), 0);
glPushMatrix();
} else {
glfglyph_t* glyph = &m_glyphs[str[i]];
if(glyph->tex) RenderGlyph(str[i]);
glTranslatef(glyph->advx, 0, 0);
}
}
glPopMatrix();
}
void TextureFontFace::RenderMarkup(const char* str) {
glPushMatrix();
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i] == '#') {
int hexcol;
if(sscanf(str+i, "#%3x", &hexcol)==1) {
Uint8 col[3];
col[0] = (hexcol&0xf00)>>4;
col[1] = (hexcol&0xf0);
col[2] = (hexcol&0xf)<<4;
glColor3ubv(col);
i+=3;
continue;
}
}
if(str[i] == '\n') {
glPopMatrx();
glTranslatef(0, GetHeight(), 0);
glPushMatrix();
} else {
glfglyph_t* glyph = &m_glyphs[str[i]];
if(glyph->tex) RenderGlyph(str[i]);
glTranslatef(glyph->advx, 0, 0);
}
}
glPopMatrix();
}
TextureFontFace::TextureFontFace(const char* filename_ttf, int a_width, int a_height) {
FT_Face face;
int err;
m_pixSize = a_height;
if(0 != (err = FT_New_Face(library, filename_ttf, 0, &face))) {
fprintf(stderr, "Terrible Error!! Couldn't load '%s'; error %d.\n", filename_ttf, err);
} else {
FT_Set_Pixel_Sizes(face, a_width, a_height);
int nbit = 0;
int sz = a_height;
while(sz) { sz >>= 1; nbit++; }
sz = (64 > (<<nbit) ? 64 : (1<<nbit));
m_texSize = sz;
printf("Using size %d\n", sz);
unsigned char* pixBuf = new unsigned char[2*sz*sz];
for(int chr = 32; chr < 127; chr++) {
memset(pixBuf, 0, 2*sz*sz);
if(0 != FT_Load_Cha(face, chr, FT_LOAD_RENDER)) {
printf("Couldn't load glyph\n");
continue;
}
/*
* Copy to square buffer GL can handle.
*/
const int pitch = face->glyph->pitch;
const int xs = face->glyph->bitmap_left;
const int ys = face->glyph->bitmap_top;
for(int row = 0; row < face->glyph>bitmap.rows; row++) {
for(int col = 0; col < face->glyph->bitmap.width; col++) {
pixBuf[2*sz*row + 2*col] = face->glyph->bitmap.buffer[pitch*row + col];
pixBuf[2*sz*row + 2*col+1] = face->glyph->bitmap.buffer[pitch*row + col];
}
}
glfglyph_t _face;
glEnable(GL_TEXTURE_2D);
glGenTexures(1, &_face.tex);
glBindTexture(GL_TEXTURE_2D, _face_tex);
glTeximage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, sz, sz, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixBuf);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
GLTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glDisable(GL_TEXTURE_2D);
_face.width = face->glyph->bitmap.width / (float)sz;
_face.height = face->glyph->bitmap.rows / (float)sz;
_face.offx = face->glyph->bitmap_left;
_face.offy = face->glyph->bitmap_top;
_face.advx = face->glyph->advance.x >> 6;
_face.advy = face->glyph->advance.y >> 6;
m_glyphes[chr] = _face;
}
delete pixBuf;
m_height = a_height;
m_width = a_width;
m_descender = -(face->descnder >> 6);
}
}
void GLFTInit(void) { void GLFTInit(void) {
if(0 != FT_Init_FreeType(&library)) { if(0 != FT_Init_FreeType(&library)) {
printf("Couldn't init freetype library.\n"); printf("Couldn't init freetype library.\n");

View File

@ -26,5 +26,32 @@ private:
}; };
std::map<int, glfglyph_t> m_glyphs; std::map<int, glfglyph_t> m_glyphs;
}; };
class TextureFontFace {
public:
TextureFontFace(const char* filename_ttf, int width, int height);
void RenderGlyph(int chr);
void LayoutString(const char* _str, float maxWidth);
void MeasureLayout(const char* str, const float maxWidth, float outSize[2]);
void RenderString(const char* str);
void RenderMarkup(const char* str);
void MeasureString(const char*str, float& w, float& h);
/* Of Ms. */
float GetHeight(void) { return m_height; }
float GetWidth(void) { return m_width; }
private:
float m_height;
float m_width;
float m_descender;
int m_texSize, m_pixSize;
struct glfglyph_t {
unsigned int tex;
float advx, advy;
float width, height;
int offx, offy;
};
std::map<int, glfglyph_t> m_glyphs;
};
void GLFTInit(void); void GLFTInit(void);

View File

@ -18,6 +18,7 @@
namespace Gui { namespace Gui {
namespace RawEvents { namespace RawEvents {
extern sigc::signal<void, SDL_MouseMotionEvent*> onMouseMotion;
extern sigc::signal<void, SDL_MouseButtonEvent*> onMouseDown; extern sigc::signal<void, SDL_MouseButtonEvent*> onMouseDown;
extern sigc::signal<void, SDL_MouseButtonEvent*> onMouseUp; extern sigc::signal<void, SDL_MouseButtonEvent*> onMouseUp;
extern sigc::signal<void, SDL_KeyboardEvent*> onKeyDown; extern sigc::signal<void, SDL_KeyboardEvent*> onKeyDown;
@ -26,6 +27,7 @@ namespace Gui {
} }
#include "gui_widget.h" #include "gui_widget.h"
#include "GuiAdjustment.h"
#include "gui_image.h" #include "gui_image.h"
#include "gui_button.h" #include "gui_button.h"
#include "gui_toggle_button.h" #include "gui_toggle_button.h"
@ -36,6 +38,8 @@ namespace Gui {
#include "gui_image_radio_button.h" #include "gui_image_radio_button.h"
#include "gui_radio_group.h" #include "gui_radio_group.h"
#include "gui_fixed.h" #include "gui_fixed.h"
#include "gui_vscroll_portal.h"
#include "gui_vscroll_bar.h"
#include "gui_label.h" #include "gui_label.h"
#include "gui_tooltip.h" #include "gui_tooltip.h"
#include "gui_screen.h" #include "gui_screen.h"

View File

@ -29,8 +29,19 @@ void Label::SetText(std::string& text) {
} }
void Label::Draw(void) { void Label::Draw(void) {
#if 0
float size[2]; GetSize(size);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex2f(0, size[1]);
glVertex2f(size[0]), size[1]);
glVertex2f(size[0], 0);
glVertex2f(0, 0);
glEnd();
#endif /* 0 */
glColor3fv(m_color); glColor3fv(m_color);
Screen::RenderMarkup(m_text); Screen::RenderMarkup(m_text);
//Screen::LayoutString(m_text, 400);
} }
void Label::GetSizeRequested(float size[2]) { void Label::GetSizeRequested(float size[2]) {

View File

@ -3,7 +3,7 @@
namespace Gui { namespace Gui {
FontFace* Screen::font; TextureFontFace* Screen::font;
bool Screen::init = false; bool Screen::init = false;
int Screen::width; int Screen::width;
int Screen::height; int Screen::height;
@ -11,9 +11,8 @@ int Screen::realWidth;
int Screen::realHeight; int Screen::realHeight;
float Screen::invRealWidth; float Screen::invRealWidth;
float Screen::invRealHeight; float Screen::invRealHeight;
float Screen::fontScale;
std::list<Widget*> Screen::kbshortcut_widgets; std::list<Widget*> Screen::kbshortcut_widgets;
float Screen::font_xsize;
float Screen::font_ysize;
std::vector<Screen::LabelPos> Screen::labelPositions; std::vector<Screen::LabelPos> Screen::labelPositions;
Gui::Fixed* Screen::baseContainer; Gui::Fixed* Screen::baseContainer;
@ -25,9 +24,14 @@ void Screen::Init(int real_width, int real_height, int ui_width, int ui_height)
Screen::invRealWidth = 1.0f/real_width; Screen::invRealWidth = 1.0f/real_width;
Screen::invRealHeight = 1.0f/real_height; Screen::invRealHeight = 1.0f/real_height;
Screen::init = true; Screen::init = true;
Screen::font = new FontFace("font.ttf"); const float fontscale = real_height / (float)ui_height;
Screen::font_xsize = 16*0.8; Screen::font = new TextureFontFace("guifont.ttf", 15*fontscale, 15*fontscale);
Screen::font_ysize = 16; /*
* Why? Because although our font textures get bigger with screen resolution,
* out GUI Ortho projections is still 800x600 so vertex
* coords must be scaled.
*/
Screen::fontScale = 1.0/fontscale;
Screen::baseContainer = new Gui::Fixed(Screen::width, Screen::height); Screen::baseContainer = new Gui::Fixed(Screen::width, Screen::height);
Screen::baseContainer->SetPosition(0,0); Screen::baseContainer->SetPosition(0,0);
} }
@ -127,36 +131,26 @@ void Screen::OnKeyDown(const SDL_keysym* sym) {
} }
float Screen::GetFontHeight(void) { float Screen::GetFontHeight(void) {
return font->GetHeight()*Screen::font_ysize; return font->GetHeight()*fontScale;
} }
void Screen::MeasureString(const std::string& s, float& w, float& h) { void Screen::MeasureString(const std::string& s, float& w, float& h) {
font->MeasureString(s.c_str(), w, h); font->MeasureString(s.c_str(), w, h);
w *= Screen::font_xsize; w *= fontScale;
h *= Screen::font_ysize; h *= fontScale;
} }
void Screen::RenderString(const std::string& s) { void Screen::RenderString(const std::string& s) {
glPushMatrix(); glPushMatrix();
{ glScalef(Screen::fontScale, Screen::fontScale, 1);
glTranslatef(0, Screen::font_ysize*Screen::font->GetHeight(),0);
glScalef(Screen::font_xsize, -Screen::font_ysize,1);
glDisable(GL_CULL_FACE);
}
font->RenderString(s.c_str()); font->RenderString(s.c_str());
glEnable(GL_CULL_FACE);
glPopMatrix(); glPopMatrix();
} }
void Screen::RenderMarkup(const std::string& s) { void Screen::RenderMarkup(const std::string& s) {
glPushMatrix(); glPushMatrix();
{ glScalef(Screen::fontScale, Screen::fontScale, 1);
glTranslatef(0, Screen::font_ysize*Screen::font->GetHeight(), 0);
glScalef(Screen::font_xsize, -Screen::font_ysize, 1);
glDisable(GL_CULL_FACE);
}
font->RenderMarkup(s.c_str()); font->RenderMarkup(s.c_str());
glEnable(GL_CULL_FACE);
glPopMatrix(); glPopMatrix();
} }
@ -171,14 +165,12 @@ bool Screen::CanPutLabel(float x, float y) {
void Screen::RenderLabel(const std::string& s, float x, float y) { void Screen::RenderLabel(const std::string& s, float x, float y) {
if(CanPutLabel(x, y)) { if(CanPutLabel(x, y)) {
labelPositions.push_back(LabelPos(x, y)); labelPositions.push_back(LabelPos(x, y));
glDisable(GL_CULL_FACE);
glPushMatrix(); glPushMatrix();
glTranslatef(x, y, 0); glTranslatef(x, y, 0);
glScalef(Screen::font_xsize, -Screen::font_ysize, 1); glScalef(Screen::fontScale, Screen::fontScale, 1);
glTranslatef(0.5*font->GetWidth(), -0.4*font->GetHeight(), 0); glTranslatef(0.5*font->GetWidth(), -0.5*font->GetHeight(), 0);
font->RenderString(s.c_str()); font->RenderString(s.c_str());
glPopMatrix(); glPopMatrix();
glEnable(GL_CULL_FACE);
} }
} }
@ -189,11 +181,10 @@ void Screen::PutClickableLabel(const std::string& s, float x, float y,
LabelPos p = LabelPos(x, y); LabelPos p = LabelPos(x, y);
p.onClick.connect(slot); p.onClick.connect(slot);
labelPositions.push_back(p); labelPositions.push_back(p);
glDisable(GL_CULL_FACE);
glPushMatrix(); glPushMatrix();
glTranslatef(x, y, 0); glTranslatef(x, y, 0);
glScalef(Screen::font_xsize, -Screen::font_ysize, 1); glScalef(Screen::fontScale, Screen::fontScale, 1);
glTranslatef(0.5*font->GetWidth(), -0.4*font->GetHeight(), 0); glTranslatef(0.5*font->GetWidth(), -0.5*font->GetHeight(), 0);
font->RenderString(s.c_str()); font->RenderString(s.c_str());
glPopMatrix(); glPopMatrix();
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);

View File

@ -2,7 +2,7 @@
#include <list> #include <list>
#include "gui.h" #include "gui.h"
class FontFace; class TextureFontFace;
namespace Gui { namespace Gui {
class Screen { class Screen {
@ -14,6 +14,7 @@ namespace Gui {
static void OnMouseMotion(SDL_MouseMotionEvent* e); static void OnMouseMotion(SDL_MouseMotionEvent* e);
static void OnClick(SDL_MouseButtonEvent* e); static void OnClick(SDL_MouseButtonEvent* e);
static void OnKeyDown(const SDL_keysym* sym); static void OnKeyDown(const SDL_keysym* sym);
static void LayoutString(const std::string& s, float width);
static void RenderString(const std::string& s); static void RenderString(const std::string& s);
static void MeasureString(const std::string& s, float& w, float& h); static void MeasureString(const std::string& s, float& w, float& h);
static void RenderMarkup(const std::string& s); static void RenderMarkup(const std::string& s);
@ -48,9 +49,8 @@ namespace Gui {
static float invRealWidth, invRealHeight; static float invRealWidth, invRealHeight;
static std::list<Widget*> kbshortcut_widgets; static std::list<Widget*> kbshortcut_widgets;
static std::list<Widget*> mouseHoveredWidgets; static std::list<Widget*> mouseHoveredWidgets;
static FontFace* font; static TextureFontFace* font;
static float font_xsize; static float fontScale;
static float font_ysize;
static Gui::Fixed* baseContainer; static Gui::Fixed* baseContainer;
}; };
} }

View File

@ -14,7 +14,6 @@ void ToolTip::CalcSize(void) {
float w, h; float w, h;
Screen::MeasureString(m_text, w, h); Screen::MeasureString(m_text, w, h);
w += 2*TOOLTIP_PADDING; w += 2*TOOLTIP_PADDING;
h += 2*TOOLTIP_PADDING;
SetSize(w, h); SetSize(w, h);
} }
@ -54,7 +53,7 @@ void ToolTip::Draw(void) {
glVertex2f(0, 0); glVertex2f(0, 0);
glEnd(); glEnd();
glPushMatrix(); glPushMatrix();
glTranslatef(TOOLTIP_PADDING, TOOLTIP_PADDING, 0); glTranslatef(TOOLTIP_PADDING, 0, 0);
glColor4f(1, 1, 1, alpha); glColor4f(1, 1, 1, alpha);
Screen::RenderMarkup(m_text); Screen::RenderMarkup(m_text);
glPopMatrix(); glPopMatrix();

View File

@ -7,8 +7,10 @@
InfoView::InfoView(void) : View() { InfoView::InfoView(void) : View() {
SetTransparency(true); SetTransparency(true);
info1 = new Gui::Label("Some star stuff."); info1 = new Gui::Label("");
info2 = new Gui::Label("");
Add(info1, 40, 40); Add(info1, 40, 40);
Add(info2, 300, 40);
} }
void InfoView::UpdateInfo(void) { void InfoView::UpdateInfo(void) {
@ -16,29 +18,36 @@ void InfoView::UpdateInfo(void) {
std::string nfo; std::string nfo;
const ShipType& stype = L3D::player->GetShipType(); const ShipType& stype = L3D::player->GetShipType();
nfo = "SHIP INFORMATION: "+std::string(stype.name); nfo = "SHIP INFORMATION: "+std::string(stype.name);
nfo += "\n\nDrive System:"
"\n\nCapacity:"
"\n\nFree:"
"\n\nUsed:"
"\n\nAll=up weight:"
"\n\nFront weapon:"
"\n\nRear weapon:"
"\n\nHyperspace range:";
info1->SetText(info);
Equip::Type e = L3D::player->m_equipment.Get(Equip::SLOT_ENGINE); Equip::Type e = L3D::player->m_equipment.Get(Equip::SLOT_ENGINE);
nfo += std::string("\n\nDrive system: ")+EquipType::types[e].name; nfo += std::string(EquipType::types[e].name);
const shipstats_t* stats; const shipstats_t* stats;
stats = L3D::player->CalcStats(); stats = L3D::player->CalcStats();
snprintf(buf, sizeof(buf), "n\nCapacity: %dt\n" snprintf(buf, sizeof(buf), "\n\n%dt\n"
"Free: %dt\n" "%dt\n"
"Used: %dt\n" "%dt\n"
"All-up weight: %dt", stats->max_capacity, "%dt", stats->max_capacity;
stats->free_capacity, stats->used_capacity,
stats->total_mass);
nfo += std::string(buf); nfo += std::string(buf);
e = L3D::player->m_equipment.Get(Equip::SLOT_LASER, 0); e = L3D::player->m_equipment.Get(Equip::SLOT_LASER, 0);
nfo += std::string("\n\nFront weapon: ")+EquipType::types[e].name; nfo += std::string"\n\n")+EquipType::types[e], name;
e = L3D::player->m_equipment.Get(Equip::SLOT_LASER, 1); e = L3D::player->m_equipment.Get(Equip::SLOT_LASER, 1);
nfo += std::string("\nRear weapon: ")+EquipType::types[e].name; nfo += std::string("\n")+EquipType::types[e].name;
snprintf(buf, sizeof(buf), "\n\nHyperspace range: %.2f light years.", stats->hyperspace_range); snprintf(buf,sizeof(buf), "\n\n%.1f lioght years", stats->hyperspace_range);
nfo += std::string(buf); nfo += std::string(buf);
info1->SetText(nfo); info2->SetText(nfo);
} }
static ObjParams params = { static ObjParams params = {

View File

@ -11,6 +11,6 @@ public:
virtual void Draw3D(void); virtual void Draw3D(void);
virtual void OnSwitchTo(void) { } virtual void OnSwitchTo(void) { }
private: private:
Gui::Label* info1; Gui::Label* info1, *info2;
}; };

View File

@ -8,6 +8,8 @@
#include <float.h> #include <float.h>
#include <limits> #include <limits>
#include <time.h> #include <time.h>
#include <stdarg.h>
#include <alloca.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -21,7 +23,7 @@
#include "matrix4x4.h" #include "matrix4x4.h"
#include "mtrand.h" #include "mtrand.h"
#include "date.h" #include "utils.h"
#define DEBUG #define DEBUG

View File

@ -194,7 +194,7 @@ public:
} }
friend matrix4x4 operator*(const matrix4x4& a, const matrix4x4& b) { friend matrix4x4 operator*(const matrix4x4& a, const matrix4x4& b) {
matrix4x4 m; matrix4xt:q: m;
m.cell[ 0] = a.cell[0]*b.cell[ 0]+a.cell[4]*b.cell[ 1]+a.cell[ 8]*b.cell[ 2]+a.cell[12]*b.cell[ 3]; m.cell[ 0] = a.cell[0]*b.cell[ 0]+a.cell[4]*b.cell[ 1]+a.cell[ 8]*b.cell[ 2]+a.cell[12]*b.cell[ 3];
m.cell[ 1] = a.cell[1]*b.cell[ 0]+a.cell[5]*b.cell[ 1]+a.cell[ 9]*b.cell[ 2]+a.cell[13]*b.cell[ 3]; m.cell[ 1] = a.cell[1]*b.cell[ 0]+a.cell[5]*b.cell[ 1]+a.cell[ 9]*b.cell[ 2]+a.cell[13]*b.cell[ 3];
m.cell[ 2] = a.cell[2]*b.cell[ 0]+a.cell[6]*b.cell[ 1]+a.cell[10]*b.cell[ 2]+a.cell[14]*b.cell[ 3]; m.cell[ 2] = a.cell[2]*b.cell[ 0]+a.cell[6]*b.cell[ 1]+a.cell[10]*b.cell[ 2]+a.cell[14]*b.cell[ 3];

View File

@ -295,7 +295,11 @@ void Player::DrawHUD(const Frame* cam_frame) {
pos.x, pos.y, pos.z, pos.x, pos.y, pos.z,
abs_pos.x, abs_pos.y, abs_pos.z, abs_pos.Length()/AU, abs_pos.x, abs_pos.y, abs_pos.z, abs_pos.Length()/AU,
rel_to, pos.Length()/1000); rel_to, pos.Length()/1000);
glPushMatrix();
glTranslatef(2, Gui::Screen::GetFontHeight(), 0);
Gui::Screen::RenderString(buf); Gui::Screen::RenderString(buf);
glPopMatrix();
} }
{ {

View File

@ -84,7 +84,7 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(Gui::Screen::GetWidth(), 64) {
m_clock = new Gui::Label(""); m_clock = new Gui::Label("");
m_clock->SetColor(1, 0.7, 0); m_clock->SetColor(1, 0.7, 0);
Add(m_clock, 2, 3); Add(m_clock, 2, 1);
tempMsg = new Gui::Label(""); tempMsg = new Gui::Label("");
Add(tempMsg, 170, 44); Add(tempMsg, 170, 44);

View File

@ -31,14 +31,14 @@ private:
StationFrontView::StationFrontView(SpaceStationView* parent): StationSubView(parent) { StationFrontView::StationFrontView(SpaceStationView* parent): StationSubView(parent) {
SetTransparency(false); SetTransparency(false);
Gui::Label* l = new Gui::Label("Hello friend! Thankyou for docking with this space station!\n" Gui::Label* l = new Gui::Label("Hello friend! Thankyou for docking with this space station! "
"You may have noticed that the docking procedure was not entirely\n" "You may have noticed that the docking procedure was not entirely "
"physically correct. this is a result of unimplemented physics in this\n" "physically correct. this is a result of unimplemented physics in this "
"region of the galaxy. We hope to have things back to normal within a\n" "region of the galaxy. We hope to have things back to normal within a "
"few weeks, and in the mean time would like to offer our apologies for\n" "few weeks, and in the mean time would like to offer our apologies for "
"any loss of earnings, immersion or lunch.\n\n" "any loss of earnings, immersion or lunch. "
"Currently the usual space station services are not available, but we\n" "Currently the usual space station services are not available, but we "
"can offer you this promotional message from one of the station's sponsors:\n\n" "can offer you this promotional message from one of the station's sponsors: \n"
" ADOPT A CAT: THEY CHEW IMPORTANT CABLES!"); " ADOPT A CAT: THEY CHEW IMPORTANT CABLES!");
Add(l, 40, 100); Add(l, 40, 100);
@ -78,7 +78,7 @@ SpaceStationView::SpaceStationView(void): View() {
Gui::Label* l = new Gui::Label("Comms Link"); Gui::Label* l = new Gui::Label("Comms Link");
l->SetColor(1, .7, 0); l->SetColor(1, .7, 0);
m_rightRegion2->Add(l, 10, 3); m_rightRegion2->Add(l, 10, 0);
} }
void SpaceStationView::SwitchView(StationSubView* v) { void SpaceStationView::SwitchView(StationSubView* v) {

View File

@ -12,17 +12,19 @@ SystemInfoView::SystemInfoView(void) : GenericSystemView() {
void SystemInfoView::OnBodySelected(StarSystem::SBody* b) { void SystemInfoView::OnBodySelected(StarSystem::SBody* b) {
m_bodySelected = b; m_bodySelected = b;
std::string desc; std::string desc, data;
char buf[1024]; char buf[1024];
snprintf(buf, sizeof(buf), "%s: %s\n" desc += string(256, "%s: %s\n", b->name.c_str(), b->GetAstroDescription());
"Mass %.2f %s masses\n", data += "\n";
b->name.c_str(), b->GetAstroDescription(), b->mass.ToDouble(),
(b->GetSuperType() == StarSystem::SUPERTYPE_STAR ? "Solar" : "Earth"));
desc += buf;
snprintf(buf, sizeof(buf), "Surface temperature %d C\n", b->averageTemp-273); desc += "Mass\n";
desc += buf; data += string(64, "%.2f %s masses\n", b->mass.TodDouble(),
(b->GetSuperType() == StarSystem::SUPERTYPE_STAR ? "Solar" : "Earth"));
desc += "Surface temperature\n";
data += stringf(64, "%d C\n", b->averageTemp-273);
/* /*
* Surface temperature. * Surface temperature.
@ -34,22 +36,23 @@ void SystemInfoView::OnBodySelected(StarSystem::SBody* b) {
if(b->parent) { if(b->parent) {
float days = b->orbit.period / (60*60*24); float days = b->orbit.period / (60*60*24);
desc += "Orbital period\n";
if(days > 1000) { if(days > 1000) {
snprintf(buf, sizeof(buf), "Orbital period %.1f years\n", days / 365); data += string(64, "%.1f years\n", days/365);
} else { } else {
snprintf(buf, sizeof(buf), "Orbital period %.1f days\n", b->orbit.period/(60*60*24)); data += stringf(64, "%.1f days\n", b->orbit.period / (60*60*24));
} }
desc += buf; desc += "Perihelion distance\n";
snprintf(buf, sizeof(buf), "Perihelion distance %.2f AU\n", b->orbMin.ToDouble()); data += stringf(64, "%.2f AU\n", b->orbMin.ToDouble());
desc += buf; desc += "Aphelion distance\n"
snprintf(buf, sizeof(buf), "Aphelion distance %.2f AU\n", b->orbMax.ToDouble()); data += stringf(64, "%.2.f AU\n", b->orbMax.ToDouble());
desc += buf; desc += "Eccentricity\n";
snprintf(buf, sizeof(buf), "Eccentricity %.2f\n", b->orbit.eccentricity); data += stringf(64, "%.2f AU\n", b->orbit.eccentricity);
desc += buf;
const float dayLen = b->GetRotationPeriod(); const float dayLen = b->GetRotationPeriod();
if(dayLen) { if(dayLen) {
snprintf(buf, sizeof(buf), "Day length %.1f earth days\n", dayLen/(60*60*24)); desc += "Day length\n";
desc += buf; data += stringf(64, "%.1f earth days\n", dayLen/(60*60*24));
} }
int numSurfaceStarports = 0; int numSurfaceStarports = 0;
std::string nameList; std::string nameList;
@ -60,10 +63,12 @@ void SystemInfoView::OnBodySelected(StarSystem::SBody* b) {
} }
} }
if(numSurfaceStarports) { if(numSurfaceStarports) {
desc += "Starports "+nameList+"\n"; desc += "Starports\n";
data += nameList+"\n";
} }
} }
m_infoText->SetText(desc); m_infoLabel->SetText(desc);
m_infoData->SetText(data);
} }
void SystemInfoView::PutBodies(StarSystem::SBody* body, int dir, float pos[2], void SystemInfoView::PutBodies(StarSystem::SBody* body, int dir, float pos[2],
@ -106,9 +111,13 @@ void SystemInfoView::SystemChanged(StarSystem* s) {
char buf[512]; char buf[512];
snprintf(buf, sizeof(buf), "Stable system with %d major bodies", majorBodies); snprintf(buf, sizeof(buf), "Stable system with %d major bodies", majorBodies);
m_infoText = new Gui::Label(buf); m_infoLabel = new Gui::Label(buf);
m_infoText->SetColor(1, 1, 0); m_infoLabel->SetColor(1, 1, 0);
Add(m_infoText, 50, 400); Add(m_infoLabel, 50, 350);
m_infData = new Gui::Label("");
m_infoData->SetColor(1. 1, 0);
Add(m_infoData, 300, 350);
ShowAll(); ShowAll();
} }

View File

@ -16,6 +16,6 @@ private:
void OnBodySelected(StarSystem::SBody* b); void OnBodySelected(StarSystem::SBody* b);
void PutBodies(StarSystem::SBody* body, int dir, float pos[2], int& majorBodies, float prevSize); void PutBodies(StarSystem::SBody* body, int dir, float pos[2], int& majorBodies, float prevSize);
StarSystem::SBody* m_bodySelected; StarSystem::SBody* m_bodySelected;
Gui::Label* m_infoText; Gui::Label* m_infoLabel, *m_infoData;
}; };

View File

@ -1,7 +1,7 @@
#include "date.h"
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "libs.h" #include "libs.h"
#include "utils.h"
/* Urgh... */ /* Urgh... */
static const char *i_am_a_little_teapot[365] = static const char *i_am_a_little_teapot[365] =

21
src/utils.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <string>
std::string date_format(double time);
#ifndef __GNUC__
#define __attribute(x)
#endif
static inline std::string stringf(int maxlen, const char* ofrmat, ...)
__attribute((format(printf, 2, 3)));
static inline std::string(int maxlen, const char* format, ...) {
char* buf = (char*)alloca(maxlen);
va_list argptr;
va start(argptr format);
vsnprintf(buf, maxlen, format, argptr);
va_end(argptr);
return std::string(buf);
}

View File

@ -20,7 +20,7 @@
m_rightRegion2 = new Gui::Fixed(122, 17); m_rightRegion2 = new Gui::Fixed(122, 17);
m_rightRegion2->SetTransparency(true); m_rightRegion2->SetTransparency(true);
Gui::Screen::AddBaseWidget(m_rightRegion2, Gui::Screen::GetWidth()-123, Gui::Screen::GetHeight()-44); Gui::Screen::AddBaseWidget(m_rightRegion2, Gui::Screen::GetWidth()-123, Gui::Screen::GetHeight()-43);
} }
virtual ~View(void) { delete m_rightButtonBar; delete m_rightRegion2; } virtual ~View(void) { delete m_rightButtonBar; delete m_rightRegion2; }
virtual void ShowAll(void) { virtual void ShowAll(void) {

View File

@ -61,7 +61,7 @@ WorldView::WorldView(void): View() {
m_flightStatus = new Gui::Label(""); m_flightStatus = new Gui::Label("");
m_flightStatus->SetColor(1, .7, 0); m_flightStatus->SetColor(1, .7, 0);
m_rightRegion2->Add(m_flightStatus, 10, 3); m_rightRegion2->Add(m_flightStatus, 10, 0);
m_bgstarsDlist = glGenLists(1); m_bgstarsDlist = glGenLists(1);