This commit is contained in:
deve 2016-10-26 13:51:40 +02:00
commit bc7f89d49a
34 changed files with 556 additions and 163 deletions

View File

@ -18,9 +18,10 @@
#include "font/bold_face.hpp"
#include "font/face_ttf.hpp"
// ----------------------------------------------------------------------------
/** Constructor of BoldFace.
* \param ttf \ref FaceTTF for BoldFace to use.
*/
BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf)
{
} // BoldFace
@ -53,3 +54,12 @@ void BoldFace::reset()
insertCharacters(preload_chars.c_str());
updateCharactersList();
} // reset
// ----------------------------------------------------------------------------
/** Embolden the glyph to make bold font using FT_Outline_Embolden.
* \return A FT_Error value.
*/
int BoldFace::shapeOutline(FT_Outline* outline) const
{
return FT_Outline_Embolden(outline, getDPI() * 2);
} // shapeOutline

View File

@ -23,24 +23,28 @@
class FaceTTF;
/** A font which uses regular TTFs to render title or important message in STK
* with a bold outline, it shares the same \ref FaceTTF with \ref RegularFace.
* \ingroup font
*/
class BoldFace : public FontWithFace
{
private:
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 1024; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.2f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 120; }
// ------------------------------------------------------------------------
virtual bool isBold() const { return true; }
// ------------------------------------------------------------------------
virtual int shapeOutline(FT_Outline* outline) const OVERRIDE;
public:
LEAK_CHECK()
// ------------------------------------------------------------------------
BoldFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~BoldFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -18,9 +18,10 @@
#include "font/digit_face.hpp"
#include "font/face_ttf.hpp"
// ----------------------------------------------------------------------------
/** Constructor of DigitFace.
* \param ttf \ref FaceTTF for DigitFace to use.
*/
DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf)
{
} // DigitFace

View File

@ -23,6 +23,9 @@
class FaceTTF;
/** A font which uses a more cartonish style TTF to render big numbers in STK.
* \ingroup font
*/
class DigitFace : public FontWithFace
{
private:
@ -39,8 +42,6 @@ public:
// ------------------------------------------------------------------------
DigitFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~DigitFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -18,22 +18,29 @@
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "io/file_manager.hpp"
// ----------------------------------------------------------------------------
/** Constructor. Load all TTFs from a list.
* \param ttf_list List of TTFs to be loaded.
*/
FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
{
for (const std::string& font : ttf_list)
{
FT_Face face = NULL;
const std::string loc = file_manager
->getAssetChecked(FileManager::TTF, font.c_str(), true);
font_manager->checkFTError(FT_New_Face(font_manager->getFTLibrary(),
(file_manager->getAssetChecked(FileManager::TTF,
font.c_str(), true)).c_str(), 0, &face), "loading fonts");
loc.c_str(), 0, &face), loc + " is loaded");
m_faces.push_back(face);
}
} // FaceTTF
// ----------------------------------------------------------------------------
/** Destructor. Clears all TTFs.
*/
FaceTTF::~FaceTTF()
{
for (unsigned int i = 0; i < m_faces.size(); i++)
@ -42,6 +49,9 @@ FaceTTF::~FaceTTF()
}
} // ~FaceTTF
// ----------------------------------------------------------------------------
/** Return a TTF in \ref m_faces.
* \param i index of TTF file in \ref m_faces.
*/
FT_Face FaceTTF::getFace(unsigned int i) const
{
assert(i < m_faces.size());

View File

@ -19,15 +19,30 @@
#ifndef HEADER_FACE_TTF_HPP
#define HEADER_FACE_TTF_HPP
#include "font/font_manager.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <string>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
/** This class will load a list of TTF files from \ref STKConfig, and save
* them inside \ref m_faces for \ref FontWithFace to load glyph.
* Each FaceTTF can be used more than once in each instantiation of \ref
* FontWithFace, so it can render characters differently using the same TTF
* file to save memory, for example different outline size.
* \ingroup font
*/
class FaceTTF : public NoCopy
{
private:
/** Contains all TTF files loaded. */
std::vector<FT_Face> m_faces;
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FaceTTF(const std::vector<std::string>& ttf_list);
// ------------------------------------------------------------------------
@ -35,6 +50,7 @@ public:
// ------------------------------------------------------------------------
FT_Face getFace(unsigned int i) const;
// ------------------------------------------------------------------------
/** Return the total TTF files loaded. */
unsigned int getTotalFaces() const { return m_faces.size(); }
}; // FaceTTF

View File

@ -28,15 +28,22 @@
FontManager *font_manager = NULL;
// ----------------------------------------------------------------------------
/** Constructor. It will initialize the \ref m_ft_library.
*/
FontManager::FontManager()
{
checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library");
} // FontManager
// ----------------------------------------------------------------------------
/** Destructor. Clears all fonts and related stuff.
*/
FontManager::~FontManager()
{
m_fonts.clearAndDeleteAll();
for (unsigned int i = 0; i < m_fonts.size(); i++)
delete m_fonts[i];
m_fonts.clear();
delete m_normal_ttf;
m_normal_ttf = NULL;
delete m_digit_ttf;
@ -47,6 +54,8 @@ FontManager::~FontManager()
} // ~FontManager
// ----------------------------------------------------------------------------
/** Initialize all \ref FaceTTF and \ref FontWithFace members.
*/
void FontManager::loadFonts()
{
// First load the TTF files required by each font
@ -72,15 +81,10 @@ void FontManager::loadFonts()
} // loadFonts
// ----------------------------------------------------------------------------
void FontManager::checkFTError(FT_Error err, const std::string& desc) const
{
if (err > 0)
{
Log::error("FontManager", "Something wrong when %s!", desc.c_str());
}
} // checkFTError
// ----------------------------------------------------------------------------
/** Unit testing that will try to load all translations in STK, and discover if
* there is any characters required by it are not supported in \ref
* m_normal_ttf.
*/
void FontManager::unitTesting()
{
std::vector<std::string> list = *(translations->getLanguageList());

View File

@ -19,14 +19,18 @@
#ifndef HEADER_FONT_MANAGER_HPP
#define HEADER_FONT_MANAGER_HPP
/** \defgroup font Font
* This module stores font files and tools used to draw characters in STK.
*/
#include "utils/leak_check.hpp"
#include "utils/log.hpp"
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
#include <string>
#include <typeindex>
#include <unordered_map>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
@ -34,17 +38,26 @@
class FaceTTF;
class FontWithFace;
/** This class stores all font files required in STK.
* \ingroup font
*/
class FontManager : public NoCopy
{
private:
PtrVector<FontWithFace> m_fonts;
/** Stores all \ref FontWithFace used in STK. */
std::vector<FontWithFace*> m_fonts;
/** A FreeType library, it holds the FT_Face internally inside freetype. */
FT_Library m_ft_library;
/** TTF files used in \ref BoldFace and \ref RegularFace. */
FaceTTF* m_normal_ttf;
/** TTF files used in \ref DigitFace. */
FaceTTF* m_digit_ttf;
/** Map type for each \ref FontWithFace with a index, save getting time in
* \ref getFont. */
std::unordered_map<std::type_index, int> m_font_type_map;
public:
@ -54,11 +67,12 @@ public:
// ------------------------------------------------------------------------
~FontManager();
// ------------------------------------------------------------------------
/** Return a specfic type of \ref FontWithFace found in \ref m_fonts. */
template <typename T> T* getFont()
{
T* out = NULL;
const unsigned int n = m_font_type_map[std::type_index(typeid(T))];
out = dynamic_cast<T*>(m_fonts.get(n));
out = dynamic_cast<T*>(m_fonts[n]);
if (out != NULL)
{
return out;
@ -68,16 +82,23 @@ public:
}
// ------------------------------------------------------------------------
/** Check for any error discovered in a freetype function that will return
* a FT_Error value.
* a FT_Error value, and log into the terminal.
* \param err The Freetype function.
* \param desc The description of what is the function doing.
*/
void checkFTError(FT_Error err, const std::string& desc) const;
* \param desc The description of what is the function doing. */
void checkFTError(FT_Error err, const std::string& desc) const
{
if (err > 0)
{
Log::error("FontManager", "Something wrong when %s! The error "
"code was %d.", desc.c_str(), err);
}
}
// ------------------------------------------------------------------------
void loadFonts();
// ------------------------------------------------------------------------
void unitTesting();
// ------------------------------------------------------------------------
/** Return the \ref m_ft_library. */
FT_Library getFTLibrary() const { return m_ft_library; }
}; // FontManager

View File

@ -25,21 +25,34 @@
using namespace irr;
/** This class stores settings when rendering fonts, used when instantiating
* \ref irr::gui::ScalableFont.
* \ingroup font
*/
class FontSettings
{
private:
/** True if black border will be drawn when rendering. */
bool m_black_border;
/** If true, characters will have right alignment when rendering, for RTL
* language. */
bool m_rtl;
/** Scaling when rendering. */
float m_scale;
/** True if shadow will be drawn when rendering. */
bool m_shadow;
/** Save the color of shadow when rendering. */
video::SColor m_shadow_color;
public:
LEAK_CHECK()
// ------------------------------------------------------------------------
/** Constructor. It will initialize all members with default values if no
* parameter is given. */
FontSettings(bool black_border = false, bool rtl = false,
float scale = 1.0f, bool shadow = false,
const video::SColor& color = video::SColor(0, 0, 0, 0))
@ -51,26 +64,39 @@ public:
m_shadow_color = color;
}
// ------------------------------------------------------------------------
~FontSettings() {}
// ------------------------------------------------------------------------
/** Set the scaling.
* \param scale Scaling to be set. */
void setScale(float scale) { m_scale = scale; }
// ------------------------------------------------------------------------
/** Return the scaling. */
float getScale() const { return m_scale; }
// ------------------------------------------------------------------------
/** Set the color of shadow.
* \param col The color of shadow to be set. */
void setShadowColor(const video::SColor &col) { m_shadow_color = col; }
// ------------------------------------------------------------------------
/** Return the color of shadow. */
const video::SColor& getShadowColor() const { return m_shadow_color; }
// ------------------------------------------------------------------------
/** Return if shadow is enabled. */
bool useShadow() const { return m_shadow; }
// ------------------------------------------------------------------------
/** Set whether shadow is enabled.
* \param shadow If it's enabled. */
void setShadow(bool shadow) { m_shadow = shadow; }
// ------------------------------------------------------------------------
/** Set whether black border is enabled.
* \param border If it's enabled. */
void setBlackBorder(bool border) { m_black_border = border; }
// ------------------------------------------------------------------------
/** Return if black border is enabled. */
bool useBlackBorder() const { return m_black_border; }
// ------------------------------------------------------------------------
/** Set right text alignment for RTL language.
* \param rtl If it's enabled. */
void setRTL(bool rtl) { m_rtl = rtl; }
// ------------------------------------------------------------------------
/** Return if right text alignment for RTL language is enabled. */
bool isRTL() const { return m_rtl; }
}; // FontSettings

View File

@ -18,17 +18,20 @@
#include "font/font_with_face.hpp"
#include "font/bold_face.hpp"
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/skin.hpp"
#include "utils/string_utils.hpp"
#include FT_OUTLINE_H
// ----------------------------------------------------------------------------
/** Constructor. It will initialize the \ref m_spritebank and TTF files to use.
* \param name The name of face, used by irrlicht to distinguish spritebank.
* \param ttf \ref FaceTTF for this face to use.
*/
FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
{
m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str());
@ -43,6 +46,8 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
} // FontWithFace
// ----------------------------------------------------------------------------
/** Destructor. Clears the glyph page and sprite bank.
*/
FontWithFace::~FontWithFace()
{
m_page->drop();
@ -56,6 +61,8 @@ FontWithFace::~FontWithFace()
} // ~FontWithFace
// ----------------------------------------------------------------------------
/** Initialize the font structure, but don't load glyph here.
*/
void FontWithFace::init()
{
setDPI();
@ -83,7 +90,11 @@ void FontWithFace::init()
reset();
} // init
// ----------------------------------------------------------------------------
/** Clear all the loaded characters, sub-class can do pre-loading of characters
* after this.
*/
void FontWithFace::reset()
{
m_new_char_holder.clear();
@ -94,6 +105,12 @@ void FontWithFace::reset()
} // reset
// ----------------------------------------------------------------------------
/** Convert a character to a glyph index in one of the font in \ref m_face_ttf,
* it will find the first TTF that supports this character, if the final
* glyph_index is 0, this means such character is not supported by all TTFs in
* \ref m_face_ttf.
* \param c The character to be loaded.
*/
void FontWithFace::loadGlyphInfo(wchar_t c)
{
unsigned int font_number = 0;
@ -108,11 +125,12 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
} // loadGlyphInfo
// ----------------------------------------------------------------------------
/** Create a new glyph page by filling it with transparent content.
*/
void FontWithFace::createNewGlyphPage()
{
// Clean the current glyph page by filling it with transparent content
m_page->fill(video::SColor(0, 255, 255, 255));
m_temp_height = 0;
m_current_height = 0;
m_used_width = 0;
m_used_height = 0;
@ -140,6 +158,10 @@ void FontWithFace::createNewGlyphPage()
} // createNewGlyphPage
// ----------------------------------------------------------------------------
/** Render a glyph for a character into bitmap and save it into the glyph page.
* \param c The character to be loaded.
* \param c \ref GlyphInfo for the character.
*/
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
{
assert(gi.glyph_index > 0);
@ -147,7 +169,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
FT_Face cur_face = m_face_ttf->getFace(gi.font_number);
FT_GlyphSlot slot = cur_face->glyph;
// Faces may be shared across regular and bold,
// Same face may be shared across the different FontWithFace,
// so reset dpi each time
font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()),
"setting DPI");
@ -155,15 +177,11 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index,
FT_LOAD_DEFAULT), "loading a glyph");
if (dynamic_cast<BoldFace*>(this) != NULL)
{
// Embolden the outline of the glyph
font_manager->checkFTError(FT_Outline_Embolden(&(slot->outline),
getDPI() * 2), "embolden a glyph");
}
font_manager->checkFTError(shapeOutline(&(slot->outline)),
"shaping outline");
font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL),
"render a glyph to bitmap");
"rendering a glyph to bitmap");
// Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap;
@ -176,7 +194,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
true, 0);
if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
m_used_height + m_temp_height + texture_size.Height >
m_used_height + m_current_height + texture_size.Height >
getGlyphPageSize()) ||
m_used_height + texture_size.Height > getGlyphPageSize())
{
@ -244,8 +262,8 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
if (m_used_width + texture_size.Width > getGlyphPageSize())
{
m_used_width = 0;
m_used_height += m_temp_height;
m_temp_height = 0;
m_used_height += m_current_height;
m_current_height = 0;
}
// Copy to the full glyph page
@ -283,11 +301,13 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
// Store used area
m_used_width += texture_size.Width;
if (m_temp_height < texture_size.Height)
m_temp_height = texture_size.Height;
if (m_current_height < texture_size.Height)
m_current_height = texture_size.Height;
} // insertGlyph
// ----------------------------------------------------------------------------
/** Update the supported characters for this font if required.
*/
void FontWithFace::updateCharactersList()
{
if (m_fallback_font != NULL)
@ -321,6 +341,10 @@ void FontWithFace::updateCharactersList()
} // updateCharactersList
// ----------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Mainly for debug use.
* \param name The file name.
*/
void FontWithFace::dumpGlyphPage(const std::string& name)
{
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
@ -341,20 +365,23 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
} // dumpGlyphPage
// ----------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Useful in gdb without parameter.
*/
void FontWithFace::dumpGlyphPage()
{
dumpGlyphPage("face");
} // dumpGlyphPage
// ----------------------------------------------------------------------------
/** Set the face dpi which is resolution-dependent.
* Normal text will range from 0.8, in 640x* resolutions (won't scale below
* that) to 1.0, in 1024x* resolutions, and linearly up.
* Bold text will range from 0.2, in 640x* resolutions (won't scale below
* that) to 0.4, in 1024x* resolutions, and linearly up.
*/
void FontWithFace::setDPI()
{
// Set face dpi:
// Font size is resolution-dependent.
// Normal text will range from 0.8, in 640x* resolutions (won't scale
// below that) to 1.0, in 1024x* resolutions, and linearly up
// Bold text will range from 0.2, in 640x* resolutions (won't scale
// below that) to 0.4, in 1024x* resolutions, and linearly up
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
float scale = std::max(0, screen_width - 640) / 564.0f;
@ -371,6 +398,10 @@ void FontWithFace::setDPI()
} // setDPI
// ----------------------------------------------------------------------------
/** Return the \ref FontArea about a character.
* \param c The character to get.
* \param[out] fallback_font Whether fallback font is used.
*/
const FontWithFace::FontArea&
FontWithFace::getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const
@ -397,6 +428,12 @@ const FontWithFace::FontArea&
} // getAreaFromCharacter
// ----------------------------------------------------------------------------
/** Get the dimension of text with support to different \ref FontSettings,
* it will also do checking for missing characters in font and lazy load them.
* \param text The text to be calculated.
* \param font_settings \ref FontSettings to use.
* \return The dimension of text
*/
core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
FontSettings* font_settings)
{
@ -441,6 +478,12 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
} // getDimension
// ----------------------------------------------------------------------------
/** Calculate the index of the character in the text on a specific position.
* \param text The text to be calculated.
* \param pixel_x The specific position.
* \param font_settings \ref FontSettings to use.
* \return The index of the character, -1 means no character in such position.
*/
int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
FontSettings* font_settings) const
{
@ -466,6 +509,17 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
} // getCharacterFromPos
// ----------------------------------------------------------------------------
/** Render text and clip it to the specified rectangle if wanted, it will also
* do checking for missing characters in font and lazy load them.
* \param text The text to be rendering.
* \param position The position to be rendering.
* \param color The color used when rendering.
* \param hcenter If rendered horizontally center.
* \param vcenter If rendered vertically center.
* \param clip If clipping is needed.
* \param font_settings \ref FontSettings to use.
* \param char_collector \ref FontCharCollector to render billboard text.
*/
void FontWithFace::render(const core::stringw& text,
const core::rect<s32>& position,
const video::SColor& color, bool hcenter,
@ -473,7 +527,6 @@ void FontWithFace::render(const core::stringw& text,
FontSettings* font_settings,
FontCharCollector* char_collector)
{
const bool is_bold_face = (dynamic_cast<BoldFace*>(this) != NULL);
const bool black_border = font_settings ?
font_settings->useBlackBorder() : false;
const bool rtl = font_settings ? font_settings->isRTL() : false;
@ -621,7 +674,7 @@ void FontWithFace::render(const core::stringw& text,
const int sprite_amount = sprites.size();
if ((black_border || is_bold_face) && char_collector == NULL)
if ((black_border || isBold()) && char_collector == NULL)
{
// Draw black border first, to make it behind the real character
// which make script language display better
@ -693,7 +746,7 @@ void FontWithFace::render(const core::stringw& text,
m_fallback_font->m_spritebank->getTexture(tex_id) :
m_spritebank->getTexture(tex_id));
if (fallback[n] || is_bold_face)
if (fallback[n] || isBold())
{
video::SColor top = GUIEngine::getSkin()->getColor("font::top");
video::SColor bottom = GUIEngine::getSkin()

View File

@ -19,47 +19,84 @@
#ifndef HEADER_FONT_WITH_FACE_HPP
#define HEADER_FONT_WITH_FACE_HPP
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "utils/cpp2011.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <algorithm>
#include <cassert>
#include <map>
#include <set>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include <irrlicht.h>
using namespace irr;
const int BEARING = 64;
class FaceTTF;
class FontSettings;
/** An abstract class which contains functions which convert vector fonts into
* bitmap and render them in STK. To make STK draw characters with different
* render option (like scaling, shadow) using a same FontWithFace, you need
* to wrap this with \ref irr::gui::ScalableFont and configure the
* \ref FontSettings for it.
* \ingroup font
*/
class FontWithFace : public NoCopy
{
public:
/** A class for \ref STKTextBillboard to get font info to render billboard
* text. */
class FontCharCollector
{
public:
/** Collect the character info for billboard text.
* \param texture The texture of the character.
* \param destRect The destination rectangle
* \param sourceRect The source rectangle in the glyph page
* \param colors The color to render it. */
virtual void collectChar(video::ITexture* texture,
const core::rect<float>& destRect,
const core::rect<s32>& sourceRect,
const video::SColor* const colors) = 0;
};
/** Glyph metrics for each glyph loaded. */
struct FontArea
{
FontArea() : advance_x(0), bearing_x(0) ,offset_y(0), offset_y_bt(0),
spriteno(0) {}
/** Advance width for horizontal layout. */
int advance_x;
/** Left side bearing for horizontal layout. */
int bearing_x;
/** Top side bearing for horizontal layout. */
int offset_y;
/** Top side bearing for horizontal layout used in billboard text. */
int offset_y_bt;
/** Index number in sprite bank. */
int spriteno;
};
protected:
int m_font_max_height;
/** Used in vertical dimension calculation. */
int m_font_max_height;
int m_glyph_max_height;
/** Used in top side bearing calculation. */
int m_glyph_max_height;
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
@ -88,44 +125,69 @@ protected:
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
/** Set the fallback font for this font, so if some character is missing in
* this font, it will use that fallback font to try rendering it.
* \param face A \ref FontWithFace font. */
void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
// ------------------------------------------------------------------------
/** Set the scaling of fallback font.
* \param scale The scaling to set. */
void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
private:
/** Mapping of glyph index to a TTF in \ref FaceTTF. */
struct GlyphInfo
{
GlyphInfo(unsigned int font_num = 0, unsigned int glyph_idx = 0) :
font_number(font_num), glyph_index(glyph_idx) {}
/** Index to a TTF in \ref FaceTTF. */
unsigned int font_number;
/** Glyph index in the TTF, 0 means no such glyph. */
unsigned int glyph_index;
GlyphInfo(unsigned int first = 0, unsigned int second = 0)
{
font_number = first;
glyph_index = second;
}
};
/** \ref FaceTTF to load glyph from. */
FaceTTF* m_face_ttf;
/** Fallback font to use if some character isn't supported by this font. */
FontWithFace* m_fallback_font;
/** Scaling for fallback font. */
float m_fallback_font_scale;
/** A temporary holder stored new char to be inserted. */
/** A temporary holder to store new characters to be inserted. */
std::set<wchar_t> m_new_char_holder;
/** Sprite bank to store each glyph. */
gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font. */
video::IImage* m_page;
unsigned int m_temp_height;
/** The current max height at current drawing line in glyph page. */
unsigned int m_current_height;
/** The used width in glyph page. */
unsigned int m_used_width;
/** The used height in glyph page. */
unsigned int m_used_height;
/** The dpi of this font. */
unsigned int m_face_dpi;
/** Store a list of supported character to a \ref FontArea. */
std::map<wchar_t, FontArea> m_character_area_map;
/** Store a list of loaded and tested character to a \ref GlyphInfo. */
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
// ------------------------------------------------------------------------
/** Return a character width.
* \param area \ref FontArea to get glyph metrics.
* \param fallback If fallback font is used.
* \param scale The scaling of the character.
* \return The calculated width with suitable scaling. */
float getCharWidth(const FontArea& area, bool fallback, float scale) const
{
if (fallback)
@ -134,6 +196,9 @@ private:
return area.advance_x * scale;
}
// ------------------------------------------------------------------------
/** Test if a character has already been tried to be loaded.
* \param c Character to test.
* \return True if tested. */
bool loadedChar(wchar_t c) const
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -143,6 +208,10 @@ private:
return false;
}
// ------------------------------------------------------------------------
/** Get the \ref GlyphInfo from \ref m_character_glyph_info_map about a
* character.
* \param c Character to get.
* \return \ref GlyphInfo of this character. */
const GlyphInfo& getGlyphInfo(wchar_t c) const
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -152,6 +221,10 @@ private:
return n->second;
}
// ------------------------------------------------------------------------
/** Tells whether a character is supported by all TTFs in \ref m_face_ttf
* which is determined by \ref GlyphInfo of this character.
* \param c Character to test.
* \return True if it's supported. */
bool supportChar(wchar_t c)
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -167,22 +240,36 @@ private:
// ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
/** Add a character into \ref m_new_char_holder for lazy loading later. */
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------
void insertGlyph(wchar_t c, const GlyphInfo& gi);
// ------------------------------------------------------------------------
void setDPI();
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const = 0;
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Defined by sub-class about the texture size of glyph page, it should be
* a power of two. */
virtual unsigned int getGlyphPageSize() const = 0;
// ------------------------------------------------------------------------
/** Defined by sub-class about the scaling factor 1. */
virtual float getScalingFactorOne() const = 0;
// ------------------------------------------------------------------------
/** Defined by sub-class about the scaling factor 2. */
virtual unsigned int getScalingFactorTwo() const = 0;
// ------------------------------------------------------------------------
/** Override it if sub-class has bold outline. */
virtual bool isBold() const { return false; }
// ------------------------------------------------------------------------
/** Override it if any outline shaping is needed to be done before
* rendering the glyph into bitmap.
* \return A FT_Error value if needed. */
virtual int shapeOutline(FT_Outline* outline) const { return 0; }
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FontWithFace(const std::string& name, FaceTTF* ttf);
// ------------------------------------------------------------------------
@ -204,22 +291,17 @@ public:
FontSettings* font_settings,
FontCharCollector* char_collector = NULL);
// ------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Mainly for debug use.
* \param name The file name.
*/
void dumpGlyphPage(const std::string& name);
// ------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Useful in gdb without parameter.
*/
void dumpGlyphPage();
// ------------------------------------------------------------------------
/** Return the sprite bank. */
gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
// ------------------------------------------------------------------------
const FontArea& getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const;
// ------------------------------------------------------------------------
/** Return the dpi of this face. */
unsigned int getDPI() const { return m_face_dpi; }
}; // FontWithFace

View File

@ -16,11 +16,12 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "font/face_ttf.hpp"
#include "font/regular_face.hpp"
// ----------------------------------------------------------------------------
/** Constructor of RegularFace.
* \param ttf \ref FaceTTF for RegularFace to use.
*/
RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf)
{
} // RegularFace

View File

@ -23,11 +23,12 @@
class FaceTTF;
/** A font which uses regular TTFs to render most text in STK.
* \ingroup font
*/
class RegularFace : public FontWithFace
{
private:
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 512; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
@ -39,8 +40,6 @@ public:
// ------------------------------------------------------------------------
RegularFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~RegularFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -50,14 +50,28 @@ STKTextBillboard::STKTextBillboard(core::stringw text, FontWithFace* font,
void STKTextBillboard::updateAbsolutePosition()
{
// Make billboard always face the camera
scene::ICameraSceneNode* curr_cam =
irr_driver->getSceneManager()->getActiveCamera();
if (!curr_cam) return;
core::quaternion q(curr_cam->getViewMatrix());
q.W = -q.W;
if (Parent)
{
// Override to not use the parent's rotation
AbsoluteTransformation = getRelativeTransformation();
AbsoluteTransformation.setTranslation(AbsoluteTransformation.getTranslation() + Parent->getAbsolutePosition());
core::vector3df wc = RelativeTranslation;
Parent->getAbsoluteTransformation().transformVect(wc);
AbsoluteTransformation.setTranslation(wc);
q.getMatrix(AbsoluteTransformation, wc);
}
else
AbsoluteTransformation = getRelativeTransformation();
{
q.getMatrix(AbsoluteTransformation, RelativeTranslation);
}
core::matrix4 m;
m.setScale(RelativeScale);
AbsoluteTransformation *= m;
}
scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, FontWithFace* font)
@ -171,18 +185,6 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, FontWithFace* fo
return Mesh;
}
void STKTextBillboard::updateNoGL()
{
scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera();
core::vector3df cam_pos = curr_cam->getPosition();
core::vector3df text_pos = this->getAbsolutePosition();
float angle = atan2(text_pos.X - cam_pos.X, text_pos.Z - cam_pos.Z);
this->setRotation(core::vector3df(0.0f, angle * 180.0f / M_PI, 0.0f));
updateAbsolutePosition();
STKMeshSceneNode::updateNoGL();
}
void STKTextBillboard::collectChar(video::ITexture* texture,
const core::rect<float>& destRect,
const core::rect<s32>& sourceRect,

View File

@ -74,8 +74,6 @@ public:
const irr::core::vector3df& position,
const irr::core::vector3df& size);
virtual void updateNoGL() OVERRIDE;
virtual scene::ESCENE_NODE_TYPE getType() const OVERRIDE
{
return scene::ESNT_TEXT;

View File

@ -659,6 +659,8 @@ namespace GUIEngine
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "font/regular_face.hpp"
#include "input/input_manager.hpp"
#include "io/file_manager.hpp"

View File

@ -18,6 +18,7 @@
#include "guiengine/scalable_font.hpp"
#include "font/font_settings.hpp"
#include "font/font_with_face.hpp"
#include "utils/translation.hpp"

View File

@ -15,6 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"

View File

@ -26,6 +26,7 @@
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/font_manager.hpp"
#include "graphics/camera.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/explosion.hpp"

View File

@ -31,26 +31,54 @@
* Here is an overview of the high-level interactions between modules :
\dot
digraph interaction {
race -> modes
# race -> modes
race -> tracks
race -> karts
modes -> tracks
modes -> karts
# modes -> tracks
# modes -> karts
tracks -> graphics
karts -> graphics
tracks -> items
graphics -> irrlicht
guiengine -> irrlicht
states_screens -> guiengine
states_screens -> input
guiengine -> input
karts->physics
tracks->physics
karts -> controller
input->controller
items -> graphics
animations -> graphics
graphics -> "Antarctica/irrlicht"
# guiengine -> irrlicht
# states_screens -> guiengine
# input -> states_screens
input -> guiengine
guiengine -> font_system
karts -> physics
physics -> karts
tracks -> physics
ai -> controller
controller -> karts
input -> controller
tracks -> animations
physics -> animations
}
animations -> physics
karts -> audio
physics -> audio
"translations\n(too many connections\nto draw)"
"configuration\n(too many connections\nto draw)"
# addons -> tracks
# addons -> karts
guiengine -> addons
guiengine -> race
addons -> online_manager
challenges -> race
# challenges -> modes
guiengine -> challenges
online_manager -> addons
online_manager -> "STK Server"
"STK Server" -> online_manager
karts -> replay
replay
# force karts and tracks on the same level, looks better this way
subgraph {
rank = same; karts; tracks;
}
}
\enddot
Note that this graph is only an approximation because the real one would be
@ -73,6 +101,8 @@
This module handles the user configuration, the supertuxkart configuration
file (which contains options usually not edited by the player) and the input
configuration file.
\li \ref font :
This module stores font files and tools used to draw characters in STK.
\li \ref graphics :
This module contains the core graphics engine, that is mostly a thin layer
on top of irrlicht providing some additional features we need for STK
@ -182,6 +212,7 @@
#include "network/rewind_manager.hpp"
#include "network/servers_manager.hpp"
#include "network/stk_host.hpp"
#include "network/protocols/get_public_address.hpp"
#include "online/profile_manager.hpp"
#include "online/request_manager.hpp"
#include "race/grand_prix_manager.hpp"
@ -546,6 +577,7 @@ void cmdLineHelp()
" --login=s Automatically log in (set the login).\n"
" --password=s Automatically log in (set the password).\n"
" --port=n Port number to use.\n"
" --my-address=1.1.1.1:1 Own IP address (can replace stun protocol)\n"
" --max-players=n Maximum number of clients (server only).\n"
" --no-console Does not write messages in the console but to\n"
" stdout.log.\n"
@ -981,6 +1013,9 @@ int handleCmdLine()
if(CommandLine::has("--password", &s))
password = s.c_str();
if (CommandLine::has("--my-address", &s))
GetPublicAddress::setMyIPAddress(s);
// Race parameters
if(CommandLine::has("--kartsize-debug"))
{

View File

@ -30,17 +30,19 @@ NetworkConfig *NetworkConfig::m_network_config = NULL;
* instance.
*/
// ============================================================================
/** Constructor for a client
/** Constructor.
*/
NetworkConfig::NetworkConfig()
{
m_network_type = NETWORK_NONE;
m_is_server = false;
m_max_players = 4;
m_is_registered = false;
m_server_name = "";
m_password = "";
m_private_port = 0;
m_network_type = NETWORK_NONE;
m_is_server = false;
m_max_players = 4;
m_is_registered = false;
m_server_name = "";
m_password = "";
m_server_discovery_port = 2757;
m_server_port = 2758;
m_client_port = 2759;
m_my_address.lock();
m_my_address.getData().clear();
m_my_address.unlock();
@ -56,3 +58,11 @@ void NetworkConfig::setMyAddress(const TransportAddress& addr)
m_my_address.unlock();
} // setPublicAddress
// --------------------------------------------------------------------
/** Sets if this instance is a server or client. It also assigns the
* private port depending if this is a server or client.
*/
void NetworkConfig::setIsServer(bool b)
{
m_is_server = b;
} // setIsServer

View File

@ -50,10 +50,14 @@ private:
* be updated from a separate thread. */
Synchronised<TransportAddress> m_my_address;
/** Even if this is a WAN server, we also store the private (LAN)
* port number, to allow direct connection to clients on the same
* LAN. */
uint16_t m_private_port;
/** The port number to which the server listens to detect LAN requests. */
uint16_t m_server_discovery_port;
/** The port on which the server listens for connection requests from LAN. */
uint16_t m_server_port;
/** The LAN port on which a client is waiting for a server connection. */
uint16_t m_client_port;
/** Maximum number of players on the server. */
int m_max_players;
@ -85,7 +89,28 @@ public:
// ------------------------------------------------------------------------
void setMyAddress(const TransportAddress& addr);
void setIsServer(bool b);
// ------------------------------------------------------------------------
/** Sets the port for server discovery. */
void setServerDiscoveryPort(uint16_t port)
{
m_server_discovery_port = port;
} // setServerDiscoveryPort
// ------------------------------------------------------------------------
/** Sets the port on which this server listens. */
void setServerPort(uint16_t port) { m_server_port = port; }
// ------------------------------------------------------------------------
/** Sets the port on which a client listens for server connection. */
void setClientPort(uint16_t port) { m_client_port = port; }
// ------------------------------------------------------------------------
/** Returns the port on which this server listenes. */
uint16_t getServerPort() const { return m_server_port; }
// ------------------------------------------------------------------------
/** Returns the port for LAN server discovery. */
uint16_t getServerDiscoveryPort() const { return m_server_discovery_port; }
// ------------------------------------------------------------------------
/** Returns the port on which a client listens for server connections. */
uint16_t getClientPort() const { return m_client_port; }
// ------------------------------------------------------------------------
/** Sets the password for a server. */
void setPassword(const std::string &password) { m_password = password; }
@ -118,9 +143,6 @@ public:
/** Returns the maximum number of players for this server. */
int getMaxPlayers() const { return m_max_players; }
// --------------------------------------------------------------------
/** Sets if this instance is a server or client. */
void setIsServer(bool b) { m_is_server = b; }
// --------------------------------------------------------------------
/** Returns if this instance is a server. */
bool isServer() const { return m_is_server; }
// --------------------------------------------------------------------
@ -158,6 +180,7 @@ public:
/** Returns the IP address of this host. We need to return a copy
* to make sure the address is thread safe (otherwise it could happen
* that e.g. data is taken when the IP address was written, but not
return a;
* yet the port). */
const TransportAddress getMyAddress() const
{
@ -167,12 +190,6 @@ public:
m_my_address.unlock();
return a;
} // getMyAddress
// ------------------------------------------------------------------------
/** Sets the private (LAN) port for this instance. */
void setPrivatePort(uint16_t port) { m_private_port = port; }
// ------------------------------------------------------------------------
/** Returns the private (LAN) port. */
uint16_t getPrivatePort() const { return m_private_port; }
}; // class NetworkConfig

View File

@ -71,6 +71,8 @@ ConnectToPeer::~ConnectToPeer()
void ConnectToPeer::setup()
{
m_broadcast_count = 0;
m_time_last_broadcast = 0;
} // setup
// ----------------------------------------------------------------------------
@ -125,14 +127,40 @@ void ConnectToPeer::asynchronousUpdate()
// the server itself accepts connections from anywhere.
if (!m_is_lan &&
m_peer_address.getIP() != NetworkConfig::get()
->getMyAddress().getIP())
->getMyAddress().getIP())
{
m_current_protocol = new PingProtocol(m_peer_address,
/*time-between-ping*/2.0);
ProtocolManager::getInstance()->requestStart(m_current_protocol);
m_state = CONNECTING;
}
else
{
m_broadcast_count = 0;
// Make sure we trigger the broadcast operation next
m_time_last_broadcast = float(StkTime::getRealTime()-100.0f);
m_state = WAIT_FOR_LAN;
}
break;
}
case WAIT_FOR_LAN:
{
// Broadcast once per second
if (StkTime::getRealTime() < m_time_last_broadcast + 1.0f)
{
break;
}
m_time_last_broadcast = float(StkTime::getRealTime());
m_broadcast_count++;
if (m_broadcast_count > 100)
{
// Not much we can do about if we don't receive the client
// connection - it could have stopped, lost network, ...
// Terminate this protocol.
Log::error("ConnectToPeer", "Time out trying to connect to %s",
m_peer_address.toString().c_str());
requestTerminate();
}
// Otherwise we are in the same LAN (same public ip address).
// Just send a broadcast packet with the string aloha_stk inside,
@ -146,6 +174,9 @@ void ConnectToPeer::asynchronousUpdate()
else
broadcast_address.copy(m_peer_address);
broadcast_address.copy(m_peer_address);
BareNetworkString aloha(std::string("aloha_stk"));
STKHost::get()->sendRawPacket(aloha, broadcast_address);
Log::info("ConnectToPeer", "Broadcast aloha sent.");
@ -155,10 +186,12 @@ void ConnectToPeer::asynchronousUpdate()
broadcast_address.setPort(m_peer_address.getPort());
STKHost::get()->sendRawPacket(aloha, broadcast_address);
Log::info("ConnectToPeer", "Broadcast aloha to self.");
m_state = CONNECTING;
break;
}
case CONNECTING: // waiting for the peer to connect
// If we receive a 'connected' event from enet, our
// notifyEventAsynchronous is called, which will move
// the FSM to the next state CONNECTED
break;
case CONNECTED:
{

View File

@ -39,10 +39,17 @@ protected:
/** True if this is a LAN connection. */
bool m_is_lan;
/** We might need to broadcast several times (in case the client is not
* ready in time). This keep track of broadcastst. */
float m_time_last_broadcast;
int m_broadcast_count;
enum STATE
{
NONE,
RECEIVED_PEER_ADDRESS,
WAIT_FOR_LAN,
CONNECTING,
CONNECTED,
DONE,

View File

@ -132,14 +132,7 @@ void ConnectToServer::asynchronousUpdate()
}
else
{
// No quick connect, so we have a server to connect to.
// Find its address
m_current_protocol = new GetPeerAddress(m_host_id, this);
m_current_protocol->requestStart();
m_state = GOT_SERVER_ADDRESS;
// Pause this protocol till GetPeerAddress finishes.
// The callback then will unpause this protocol/
requestPause();
}
}
break;
@ -270,11 +263,6 @@ void ConnectToServer::callback(Protocol *protocol)
// STKHost, so we only need to unpause this protocol
requestUnpause();
break;
case GOT_SERVER_ADDRESS:
// Get the server address from the protocol.
m_server_address.copy(((GetPeerAddress*)protocol)->getAddress());
requestUnpause();
break;
default:
Log::error("ConnectToServer",
"Received unexpected callback while in state %d.",
@ -296,7 +284,7 @@ void ConnectToServer::registerWithSTKServer()
request->addParameter("address", addr.getIP());
request->addParameter("port", addr.getPort());
request->addParameter("private_port",
NetworkConfig::get()->getPrivatePort());
NetworkConfig::get()->getClientPort());
Log::info("ConnectToServer", "Registering addr %s",
addr.toString().c_str());

View File

@ -24,6 +24,7 @@
#include "network/network_string.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include <assert.h>
#include <string>
@ -43,8 +44,35 @@
#include <sys/types.h>
// make the linker happy
const uint32_t GetPublicAddress::m_stun_magic_cookie = 0x2112A442;
const uint32_t GetPublicAddress::m_stun_magic_cookie = 0x2112A442;
TransportAddress GetPublicAddress::m_my_address(0, 0);
void GetPublicAddress::setMyIPAddress(const std::string &s)
{
std::vector<std::string> l = StringUtils::split(s, ':');
if (l.size() != 2)
{
Log::fatal("Invalid IP address '%s'.", s.c_str());
}
std::vector<std::string> ip = StringUtils::split(l[0], '.');
if (ip.size() != 4)
{
Log::fatal("Invalid IP address '%s'.", s.c_str());
}
uint32_t u = 0;
for (unsigned int i = 0; i < 4; i++)
{
int k;
StringUtils::fromString(ip[i], k);
u = (u << 8) + k;
}
m_my_address.setIP(u);
int p;
StringUtils::fromString(l[1], p);
m_my_address.setPort(p);
} // setMyIPAddress
// ============================================================================
GetPublicAddress::GetPublicAddress(CallbackObject *callback)
: Protocol(PROTOCOL_SILENT, callback)
{
@ -203,6 +231,22 @@ std::string GetPublicAddress::parseStunResponse()
* selected STUN server and then parsing and validating the response */
void GetPublicAddress::asynchronousUpdate()
{
// If the user has specified an address, use it instead of the stun protocol.
if (m_my_address.getIP() != 0 && m_my_address.getPort() != 0)
{
NetworkConfig::get()->setMyAddress(m_my_address);
m_state = EXITING;
requestTerminate();
}
//#define LAN_TEST
#ifdef LAN_TEST
TransportAddress address(0x7f000001, 4);
NetworkConfig::get()->setMyAddress(address);
m_state = EXITING;
requestTerminate();
return;
#endif
if (m_state == NOTHING_DONE)
{
createStunRequest();

View File

@ -20,6 +20,7 @@
#define GET_PUBLIC_ADDRESS_HPP
#include "network/protocol.hpp"
#include "network/transport_address.hpp"
#include "utils/cpp2011.hpp"
#include <string>
@ -36,6 +37,10 @@ private:
static const uint32_t m_stun_magic_cookie;
static const int m_stun_server_port = 3478;
/** The user can specify its own IP address to make the use of stun
* unnecessary (though that means that the user has to take care of
* opening the firewall). */
static TransportAddress m_my_address;
enum State
{
NOTHING_DONE,
@ -48,8 +53,9 @@ private:
Network* m_transaction_host;
public:
GetPublicAddress(CallbackObject *callback = NULL);
virtual ~GetPublicAddress() {}
static void setMyIPAddress(const std::string &s);
GetPublicAddress(CallbackObject *callback = NULL);
virtual ~GetPublicAddress() {}
virtual void asynchronousUpdate() OVERRIDE;
// ------------------------------------------------------------------------
@ -60,6 +66,7 @@ public:
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual void setup() { m_state = NOTHING_DONE; }
// ------------------------------------------------------------------------
}; // class GetPublicAddress

View File

@ -210,7 +210,7 @@ void ServerLobbyRoomProtocol::registerServer()
request->addParameter("address", addr.getIP() );
request->addParameter("port", addr.getPort() );
request->addParameter("private_port",
NetworkConfig::get()->getPrivatePort());
NetworkConfig::get()->getServerPort() );
request->addParameter("name", NetworkConfig::get()->getServerName() );
request->addParameter("max_players",
UserConfigParams::m_server_max_players );

View File

@ -49,7 +49,13 @@ Server::Server(const XMLNode & xml, bool is_lan)
xml.get("hostid", &m_host_id);
xml.get("max_players", &m_max_players);
xml.get("current_players", &m_current_players);
uint32_t ip;
xml.get("ip", &ip);
m_address.setIP(ip);
uint16_t port;
xml.get("port", &port);
m_address.setPort(port);
xml.get("private_port", &m_private_port);
} // Server(const XML&)
// ----------------------------------------------------------------------------

View File

@ -153,7 +153,8 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const
Network *broadcast = new Network(1, 1, 0, 0);
BareNetworkString s(std::string("stk-server"));
TransportAddress broadcast_address(-1, 2757);
TransportAddress broadcast_address(-1,
NetworkConfig::get()->getServerDiscoveryPort());
broadcast->sendRawPacket(s, broadcast_address);
Log::info("ServersManager", "Sent broadcast message.");

View File

@ -141,7 +141,7 @@ void STKHost::create()
*
* Server:
*
* The ServerLobbyRoomProtocol (SLR) will the detect the above client
* The ServerLobbyRoomProtocol (SLR) will then detect the above client
* requests, and start a ConnectToPeer protocol for each incoming client.
* The ConnectToPeer protocol uses:
* 1. GetPeerAddress to get the ip address and port of the client.
@ -231,9 +231,13 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id)
// server is made.
m_host_id = 0;
init();
TransportAddress a;
a.setIP(0);
a.setPort(NetworkConfig::get()->getClientPort());
ENetAddress ea = a.toEnetAddress();
m_network = new Network(/*peer_count*/1, /*channel_limit*/2,
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0);
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &ea);
if (!m_network)
{
Log::fatal ("STKHost", "An error occurred while trying to create "
@ -258,7 +262,7 @@ STKHost::STKHost(const irr::core::stringw &server_name)
ENetAddress addr;
addr.host = STKHost::HOST_ANY;
addr.port = 2758;
addr.port = NetworkConfig::get()->getServerPort();
m_network= new Network(NetworkConfig::get()->getMaxPlayers(),
/*channel_limit*/2,
@ -511,7 +515,7 @@ void* STKHost::mainLoop(void* self)
if(NetworkConfig::get()->isServer() &&
NetworkConfig::get()->isLAN() )
{
TransportAddress address(0, 2757);
TransportAddress address(0, NetworkConfig::get()->getServerDiscoveryPort());
ENetAddress eaddr = address.toEnetAddress();
myself->m_lan_network = new Network(1, 1, 0, 0, &eaddr);
}
@ -565,6 +569,10 @@ void* STKHost::mainLoop(void* self)
} // mainLoop
// ----------------------------------------------------------------------------
/** Handles LAN related messages. It checks for any LAN broadcast messages,
* and if a valid LAN server-request message is received, will answer
* with a message containing server details (and sender IP address and port).
*/
void STKHost::handleLANRequests()
{
const int LEN=2048;

View File

@ -20,6 +20,7 @@
#include "animations/three_d_animation.hpp"
#include "font/digit_face.hpp"
#include "font/font_manager.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/scalable_font.hpp"
@ -104,6 +105,7 @@ namespace Scripting
core::vector3df(1.5f, 1.5f, 1.5f));
World::getWorld()->getTrack()->addNode(tb);
tb->drop();
}
else
{

View File

@ -24,6 +24,7 @@
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"

View File

@ -21,6 +21,7 @@
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "graphics/camera_debug.hpp"
#include "graphics/camera_fps.hpp"