From 410b40c34636fa255ac43960943489b0e88aeafc Mon Sep 17 00:00:00 2001 From: Rtch90 Date: Sun, 19 Aug 2018 13:06:56 +0100 Subject: [PATCH] [Add] Texture fonts for UI instead of ugly ass poly fonts. [Add] vscroll widget, incomplete because child widget does not get properly scrolled events. --- src/Makefile.am | 4 +- src/date.h | 5 - src/glfreetype.cpp | 299 ++++++++++++++++++++++++++++++++++++ src/glfreetype.h | 27 ++++ src/gui.h | 4 + src/gui_label.cpp | 11 ++ src/gui_screen.cpp | 47 +++--- src/gui_screen.h | 8 +- src/gui_tooltip.cpp | 3 +- src/info_view.cpp | 33 ++-- src/info_view.h | 2 +- src/libs.h | 4 +- src/matrix4x4.h | 2 +- src/player.cpp | 4 + src/ship_cpanel.cpp | 2 +- src/space_station_view.cpp | 18 +-- src/system_info_view.cpp | 57 ++++--- src/system_info_view.h | 2 +- src/{date.cpp => utils.cpp} | 2 +- src/utils.h | 21 +++ src/view.h | 2 +- src/world_view.cpp | 2 +- 22 files changed, 465 insertions(+), 94 deletions(-) delete mode 100644 src/date.h rename src/{date.cpp => utils.cpp} (99%) create mode 100644 src/utils.h diff --git a/src/Makefile.am b/src/Makefile.am index c8f0344..19a4873 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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_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 \ - 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 \ 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 \ 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 \ object_viewer_view.cpp custom_starsystems.cpp serializer.cpp sfx.cpp ship_ai.cpp Lephisto3D_LDADD = sbre/libsbre.a collider/libcollider.a libgui.a diff --git a/src/date.h b/src/date.h deleted file mode 100644 index 6d89cc3..0000000 --- a/src/date.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include - -std::string date_format(double time); - diff --git a/src/glfreetype.cpp b/src/glfreetype.cpp index 09aacdb..b7b8a61 100644 --- a/src/glfreetype.cpp +++ b/src/glfreetype.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #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 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::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 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 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::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 > (<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) { if(0 != FT_Init_FreeType(&library)) { printf("Couldn't init freetype library.\n"); diff --git a/src/glfreetype.h b/src/glfreetype.h index 3da23f1..6cab2fb 100644 --- a/src/glfreetype.h +++ b/src/glfreetype.h @@ -26,5 +26,32 @@ private: }; std::map 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 m_glyphs; +}; void GLFTInit(void); diff --git a/src/gui.h b/src/gui.h index c7e3e27..86a6551 100644 --- a/src/gui.h +++ b/src/gui.h @@ -18,6 +18,7 @@ namespace Gui { namespace RawEvents { + extern sigc::signal onMouseMotion; extern sigc::signal onMouseDown; extern sigc::signal onMouseUp; extern sigc::signal onKeyDown; @@ -26,6 +27,7 @@ namespace Gui { } #include "gui_widget.h" +#include "GuiAdjustment.h" #include "gui_image.h" #include "gui_button.h" #include "gui_toggle_button.h" @@ -36,6 +38,8 @@ namespace Gui { #include "gui_image_radio_button.h" #include "gui_radio_group.h" #include "gui_fixed.h" +#include "gui_vscroll_portal.h" +#include "gui_vscroll_bar.h" #include "gui_label.h" #include "gui_tooltip.h" #include "gui_screen.h" diff --git a/src/gui_label.cpp b/src/gui_label.cpp index afa97e6..951a274 100644 --- a/src/gui_label.cpp +++ b/src/gui_label.cpp @@ -29,8 +29,19 @@ void Label::SetText(std::string& text) { } 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); Screen::RenderMarkup(m_text); + //Screen::LayoutString(m_text, 400); } void Label::GetSizeRequested(float size[2]) { diff --git a/src/gui_screen.cpp b/src/gui_screen.cpp index 41e792b..2baa6cf 100644 --- a/src/gui_screen.cpp +++ b/src/gui_screen.cpp @@ -3,7 +3,7 @@ namespace Gui { -FontFace* Screen::font; +TextureFontFace* Screen::font; bool Screen::init = false; int Screen::width; int Screen::height; @@ -11,9 +11,8 @@ int Screen::realWidth; int Screen::realHeight; float Screen::invRealWidth; float Screen::invRealHeight; +float Screen::fontScale; std::list Screen::kbshortcut_widgets; -float Screen::font_xsize; -float Screen::font_ysize; std::vector Screen::labelPositions; 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::invRealHeight = 1.0f/real_height; Screen::init = true; - Screen::font = new FontFace("font.ttf"); - Screen::font_xsize = 16*0.8; - Screen::font_ysize = 16; + const float fontscale = real_height / (float)ui_height; + Screen::font = new TextureFontFace("guifont.ttf", 15*fontscale, 15*fontscale); + /* + * 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->SetPosition(0,0); } @@ -127,36 +131,26 @@ void Screen::OnKeyDown(const SDL_keysym* sym) { } 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) { font->MeasureString(s.c_str(), w, h); - w *= Screen::font_xsize; - h *= Screen::font_ysize; + w *= fontScale; + h *= fontScale; } void Screen::RenderString(const std::string& s) { glPushMatrix(); - { - glTranslatef(0, Screen::font_ysize*Screen::font->GetHeight(),0); - glScalef(Screen::font_xsize, -Screen::font_ysize,1); - glDisable(GL_CULL_FACE); - } + glScalef(Screen::fontScale, Screen::fontScale, 1); font->RenderString(s.c_str()); - glEnable(GL_CULL_FACE); glPopMatrix(); } void Screen::RenderMarkup(const std::string& s) { glPushMatrix(); - { - glTranslatef(0, Screen::font_ysize*Screen::font->GetHeight(), 0); - glScalef(Screen::font_xsize, -Screen::font_ysize, 1); - glDisable(GL_CULL_FACE); - } + glScalef(Screen::fontScale, Screen::fontScale, 1); font->RenderMarkup(s.c_str()); - glEnable(GL_CULL_FACE); glPopMatrix(); } @@ -171,14 +165,12 @@ bool Screen::CanPutLabel(float x, float y) { void Screen::RenderLabel(const std::string& s, float x, float y) { if(CanPutLabel(x, y)) { labelPositions.push_back(LabelPos(x, y)); - glDisable(GL_CULL_FACE); glPushMatrix(); glTranslatef(x, y, 0); - glScalef(Screen::font_xsize, -Screen::font_ysize, 1); - glTranslatef(0.5*font->GetWidth(), -0.4*font->GetHeight(), 0); + glScalef(Screen::fontScale, Screen::fontScale, 1); + glTranslatef(0.5*font->GetWidth(), -0.5*font->GetHeight(), 0); font->RenderString(s.c_str()); 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); p.onClick.connect(slot); labelPositions.push_back(p); - glDisable(GL_CULL_FACE); glPushMatrix(); glTranslatef(x, y, 0); - glScalef(Screen::font_xsize, -Screen::font_ysize, 1); - glTranslatef(0.5*font->GetWidth(), -0.4*font->GetHeight(), 0); + glScalef(Screen::fontScale, Screen::fontScale, 1); + glTranslatef(0.5*font->GetWidth(), -0.5*font->GetHeight(), 0); font->RenderString(s.c_str()); glPopMatrix(); glEnable(GL_CULL_FACE); diff --git a/src/gui_screen.h b/src/gui_screen.h index 5a4e0c3..f0a2b24 100644 --- a/src/gui_screen.h +++ b/src/gui_screen.h @@ -2,7 +2,7 @@ #include #include "gui.h" -class FontFace; +class TextureFontFace; namespace Gui { class Screen { @@ -14,6 +14,7 @@ namespace Gui { static void OnMouseMotion(SDL_MouseMotionEvent* e); static void OnClick(SDL_MouseButtonEvent* e); 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 MeasureString(const std::string& s, float& w, float& h); static void RenderMarkup(const std::string& s); @@ -48,9 +49,8 @@ namespace Gui { static float invRealWidth, invRealHeight; static std::list kbshortcut_widgets; static std::list mouseHoveredWidgets; - static FontFace* font; - static float font_xsize; - static float font_ysize; + static TextureFontFace* font; + static float fontScale; static Gui::Fixed* baseContainer; }; } diff --git a/src/gui_tooltip.cpp b/src/gui_tooltip.cpp index da91acd..43f5dba 100644 --- a/src/gui_tooltip.cpp +++ b/src/gui_tooltip.cpp @@ -14,7 +14,6 @@ void ToolTip::CalcSize(void) { float w, h; Screen::MeasureString(m_text, w, h); w += 2*TOOLTIP_PADDING; - h += 2*TOOLTIP_PADDING; SetSize(w, h); } @@ -54,7 +53,7 @@ void ToolTip::Draw(void) { glVertex2f(0, 0); glEnd(); glPushMatrix(); - glTranslatef(TOOLTIP_PADDING, TOOLTIP_PADDING, 0); + glTranslatef(TOOLTIP_PADDING, 0, 0); glColor4f(1, 1, 1, alpha); Screen::RenderMarkup(m_text); glPopMatrix(); diff --git a/src/info_view.cpp b/src/info_view.cpp index 781eabe..454c105 100644 --- a/src/info_view.cpp +++ b/src/info_view.cpp @@ -7,8 +7,10 @@ InfoView::InfoView(void) : View() { SetTransparency(true); - info1 = new Gui::Label("Some star stuff."); + info1 = new Gui::Label(""); + info2 = new Gui::Label(""); Add(info1, 40, 40); + Add(info2, 300, 40); } void InfoView::UpdateInfo(void) { @@ -16,29 +18,36 @@ void InfoView::UpdateInfo(void) { std::string nfo; const ShipType& stype = L3D::player->GetShipType(); 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); - nfo += std::string("\n\nDrive system: ")+EquipType::types[e].name; + nfo += std::string(EquipType::types[e].name); const shipstats_t* stats; stats = L3D::player->CalcStats(); - snprintf(buf, sizeof(buf), "n\nCapacity: %dt\n" - "Free: %dt\n" - "Used: %dt\n" - "All-up weight: %dt", stats->max_capacity, - stats->free_capacity, stats->used_capacity, - stats->total_mass); + snprintf(buf, sizeof(buf), "\n\n%dt\n" + "%dt\n" + "%dt\n" + "%dt", stats->max_capacity; nfo += std::string(buf); 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); - 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); - info1->SetText(nfo); + info2->SetText(nfo); } static ObjParams params = { diff --git a/src/info_view.h b/src/info_view.h index f3c0431..6882478 100644 --- a/src/info_view.h +++ b/src/info_view.h @@ -11,6 +11,6 @@ public: virtual void Draw3D(void); virtual void OnSwitchTo(void) { } private: - Gui::Label* info1; + Gui::Label* info1, *info2; }; diff --git a/src/libs.h b/src/libs.h index 3891cf3..63f83e7 100644 --- a/src/libs.h +++ b/src/libs.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #ifdef _WIN32 #include @@ -21,7 +23,7 @@ #include "matrix4x4.h" #include "mtrand.h" -#include "date.h" +#include "utils.h" #define DEBUG diff --git a/src/matrix4x4.h b/src/matrix4x4.h index abc7b5f..6aa028c 100644 --- a/src/matrix4x4.h +++ b/src/matrix4x4.h @@ -194,7 +194,7 @@ public: } 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[ 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]; diff --git a/src/player.cpp b/src/player.cpp index cf0efa9..f93b8c6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -295,7 +295,11 @@ void Player::DrawHUD(const Frame* cam_frame) { pos.x, pos.y, pos.z, abs_pos.x, abs_pos.y, abs_pos.z, abs_pos.Length()/AU, rel_to, pos.Length()/1000); + + glPushMatrix(); + glTranslatef(2, Gui::Screen::GetFontHeight(), 0); Gui::Screen::RenderString(buf); + glPopMatrix(); } { diff --git a/src/ship_cpanel.cpp b/src/ship_cpanel.cpp index f9b9094..cc427af 100644 --- a/src/ship_cpanel.cpp +++ b/src/ship_cpanel.cpp @@ -84,7 +84,7 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(Gui::Screen::GetWidth(), 64) { m_clock = new Gui::Label(""); m_clock->SetColor(1, 0.7, 0); - Add(m_clock, 2, 3); + Add(m_clock, 2, 1); tempMsg = new Gui::Label(""); Add(tempMsg, 170, 44); diff --git a/src/space_station_view.cpp b/src/space_station_view.cpp index 17e44b9..b4c8ffa 100644 --- a/src/space_station_view.cpp +++ b/src/space_station_view.cpp @@ -31,14 +31,14 @@ private: StationFrontView::StationFrontView(SpaceStationView* parent): StationSubView(parent) { SetTransparency(false); - Gui::Label* l = new Gui::Label("Hello friend! Thankyou for docking with this space station!\n" - "You may have noticed that the docking procedure was not entirely\n" - "physically correct. this is a result of unimplemented physics in this\n" - "region of the galaxy. We hope to have things back to normal within a\n" - "few weeks, and in the mean time would like to offer our apologies for\n" - "any loss of earnings, immersion or lunch.\n\n" - "Currently the usual space station services are not available, but we\n" - "can offer you this promotional message from one of the station's sponsors:\n\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 " + "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 " + "few weeks, and in the mean time would like to offer our apologies for " + "any loss of earnings, immersion or lunch. " + "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" " ADOPT A CAT: THEY CHEW IMPORTANT CABLES!"); Add(l, 40, 100); @@ -78,7 +78,7 @@ SpaceStationView::SpaceStationView(void): View() { Gui::Label* l = new Gui::Label("Comms Link"); l->SetColor(1, .7, 0); - m_rightRegion2->Add(l, 10, 3); + m_rightRegion2->Add(l, 10, 0); } void SpaceStationView::SwitchView(StationSubView* v) { diff --git a/src/system_info_view.cpp b/src/system_info_view.cpp index be85448..d7cb30b 100644 --- a/src/system_info_view.cpp +++ b/src/system_info_view.cpp @@ -12,17 +12,19 @@ SystemInfoView::SystemInfoView(void) : GenericSystemView() { void SystemInfoView::OnBodySelected(StarSystem::SBody* b) { m_bodySelected = b; - std::string desc; + std::string desc, data; + char buf[1024]; - snprintf(buf, sizeof(buf), "%s: %s\n" - "Mass %.2f %s masses\n", - b->name.c_str(), b->GetAstroDescription(), b->mass.ToDouble(), - (b->GetSuperType() == StarSystem::SUPERTYPE_STAR ? "Solar" : "Earth")); - desc += buf; + desc += string(256, "%s: %s\n", b->name.c_str(), b->GetAstroDescription()); + data += "\n"; - snprintf(buf, sizeof(buf), "Surface temperature %d C\n", b->averageTemp-273); - desc += buf; + desc += "Mass\n"; + 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. @@ -34,22 +36,23 @@ void SystemInfoView::OnBodySelected(StarSystem::SBody* b) { if(b->parent) { float days = b->orbit.period / (60*60*24); + desc += "Orbital period\n"; if(days > 1000) { - snprintf(buf, sizeof(buf), "Orbital period %.1f years\n", days / 365); + data += string(64, "%.1f years\n", days/365); } 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; - snprintf(buf, sizeof(buf), "Perihelion distance %.2f AU\n", b->orbMin.ToDouble()); - desc += buf; - snprintf(buf, sizeof(buf), "Aphelion distance %.2f AU\n", b->orbMax.ToDouble()); - desc += buf; - snprintf(buf, sizeof(buf), "Eccentricity %.2f\n", b->orbit.eccentricity); - desc += buf; + desc += "Perihelion distance\n"; + data += stringf(64, "%.2f AU\n", b->orbMin.ToDouble()); + desc += "Aphelion distance\n" + data += stringf(64, "%.2.f AU\n", b->orbMax.ToDouble()); + desc += "Eccentricity\n"; + data += stringf(64, "%.2f AU\n", b->orbit.eccentricity); + const float dayLen = b->GetRotationPeriod(); if(dayLen) { - snprintf(buf, sizeof(buf), "Day length %.1f earth days\n", dayLen/(60*60*24)); - desc += buf; + desc += "Day length\n"; + data += stringf(64, "%.1f earth days\n", dayLen/(60*60*24)); } int numSurfaceStarports = 0; std::string nameList; @@ -60,10 +63,12 @@ void SystemInfoView::OnBodySelected(StarSystem::SBody* b) { } } 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], @@ -106,9 +111,13 @@ void SystemInfoView::SystemChanged(StarSystem* s) { char buf[512]; snprintf(buf, sizeof(buf), "Stable system with %d major bodies", majorBodies); - m_infoText = new Gui::Label(buf); - m_infoText->SetColor(1, 1, 0); - Add(m_infoText, 50, 400); + m_infoLabel = new Gui::Label(buf); + m_infoLabel->SetColor(1, 1, 0); + Add(m_infoLabel, 50, 350); + + m_infData = new Gui::Label(""); + m_infoData->SetColor(1. 1, 0); + Add(m_infoData, 300, 350); ShowAll(); } diff --git a/src/system_info_view.h b/src/system_info_view.h index c302c2d..172b67f 100644 --- a/src/system_info_view.h +++ b/src/system_info_view.h @@ -16,6 +16,6 @@ private: void OnBodySelected(StarSystem::SBody* b); void PutBodies(StarSystem::SBody* body, int dir, float pos[2], int& majorBodies, float prevSize); StarSystem::SBody* m_bodySelected; - Gui::Label* m_infoText; + Gui::Label* m_infoLabel, *m_infoData; }; diff --git a/src/date.cpp b/src/utils.cpp similarity index 99% rename from src/date.cpp rename to src/utils.cpp index 56707ad..3b82045 100644 --- a/src/date.cpp +++ b/src/utils.cpp @@ -1,7 +1,7 @@ -#include "date.h" #include #include #include "libs.h" +#include "utils.h" /* Urgh... */ static const char *i_am_a_little_teapot[365] = diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..9b7427f --- /dev/null +++ b/src/utils.h @@ -0,0 +1,21 @@ +#pragma once +#include + +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); +} + diff --git a/src/view.h b/src/view.h index 514b148..d9f56a3 100644 --- a/src/view.h +++ b/src/view.h @@ -20,7 +20,7 @@ m_rightRegion2 = new Gui::Fixed(122, 17); 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 void ShowAll(void) { diff --git a/src/world_view.cpp b/src/world_view.cpp index 08735f5..0597472 100644 --- a/src/world_view.cpp +++ b/src/world_view.cpp @@ -61,7 +61,7 @@ WorldView::WorldView(void): View() { m_flightStatus = new Gui::Label(""); m_flightStatus->SetColor(1, .7, 0); - m_rightRegion2->Add(m_flightStatus, 10, 3); + m_rightRegion2->Add(m_flightStatus, 10, 0); m_bgstarsDlist = glGenLists(1);