[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:
		
							parent
							
								
									44bc01682e
								
							
						
					
					
						commit
						2a8d0f156e
					
				| @ -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 | ||||
|  | ||||
| @ -1,5 +0,0 @@ | ||||
| #pragma once | ||||
| #include <string> | ||||
| 
 | ||||
| std::string date_format(double time); | ||||
| 
 | ||||
| @ -4,6 +4,7 @@ | ||||
| #include <stdio.h> | ||||
| #include <assert.h> | ||||
| #include <map> | ||||
| #include <string> | ||||
| #include <ft2build.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) { | ||||
|   if(0 != FT_Init_FreeType(&library)) { | ||||
|     printf("Couldn't init freetype library.\n"); | ||||
|  | ||||
| @ -26,5 +26,32 @@ private: | ||||
|   }; | ||||
|   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); | ||||
| 
 | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
| 
 | ||||
| namespace Gui { | ||||
|   namespace RawEvents { | ||||
|     extern sigc::signal<void, SDL_MouseMotionEvent*>  onMouseMotion; | ||||
|     extern sigc::signal<void, SDL_MouseButtonEvent*>  onMouseDown; | ||||
|     extern sigc::signal<void, SDL_MouseButtonEvent*>  onMouseUp; | ||||
|     extern sigc::signal<void, SDL_KeyboardEvent*>     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" | ||||
|  | ||||
| @ -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]) { | ||||
|  | ||||
| @ -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<Widget*> Screen::kbshortcut_widgets; | ||||
| float Screen::font_xsize; | ||||
| float Screen::font_ysize; | ||||
| std::vector<Screen::LabelPos> 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); | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| #include <list> | ||||
| #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<Widget*> kbshortcut_widgets; | ||||
|     static std::list<Widget*> mouseHoveredWidgets; | ||||
|     static FontFace* font; | ||||
|     static float font_xsize; | ||||
|     static float font_ysize; | ||||
|     static TextureFontFace* font; | ||||
|     static float fontScale; | ||||
|     static Gui::Fixed* baseContainer; | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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 = { | ||||
|  | ||||
| @ -11,6 +11,6 @@ public: | ||||
|   virtual void Draw3D(void); | ||||
|   virtual void OnSwitchTo(void) { } | ||||
| private: | ||||
|   Gui::Label* info1; | ||||
|   Gui::Label* info1, *info2; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,8 @@ | ||||
| #include <float.h> | ||||
| #include <limits> | ||||
| #include <time.h> | ||||
| #include <stdarg.h> | ||||
| #include <alloca.h> | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| @ -21,7 +23,7 @@ | ||||
| #include "matrix4x4.h" | ||||
| #include "mtrand.h" | ||||
| 
 | ||||
| #include "date.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| #define DEBUG | ||||
| 
 | ||||
|  | ||||
| @ -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]; | ||||
|  | ||||
| @ -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(); | ||||
|   } | ||||
| 
 | ||||
|   { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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(); | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #include "date.h" | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| #include "libs.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| /* Urgh... */ | ||||
| static const char *i_am_a_little_teapot[365] = | ||||
							
								
								
									
										21
									
								
								src/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/utils.h
									
									
									
									
									
										Normal 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); | ||||
| } | ||||
| 
 | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rtch90
						Rtch90