diff --git a/Bin/VC10/VC10.vcxproj b/Bin/VC10/VC10.vcxproj index 4075b76..e81bbd1 100644 --- a/Bin/VC10/VC10.vcxproj +++ b/Bin/VC10/VC10.vcxproj @@ -59,7 +59,7 @@ Windows true ..\..\Libs\Win32\SDL\lib - SDL.lib;SDL_image.lib;SDL_mixer.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + SDL.lib;SDL_image.lib;SDL_mixer.lib;SDL_ttf.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) @@ -79,7 +79,7 @@ true true ..\..\Libs\Win32\SDL\lib - SDL.lib;SDL_image.lib;SDL_mixer.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + SDL.lib;SDL_image.lib;SDL_mixer.lib;SDL_ttf.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) @@ -87,6 +87,7 @@ + @@ -129,6 +130,7 @@ + diff --git a/Bin/VC10/VC10.vcxproj.filters b/Bin/VC10/VC10.vcxproj.filters index 7599343..aaab8eb 100644 --- a/Bin/VC10/VC10.vcxproj.filters +++ b/Bin/VC10/VC10.vcxproj.filters @@ -40,6 +40,9 @@ {28fe54ce-152c-4d7d-8a14-3b9d0155d089} + + {be4a8635-8a7a-45ba-8c95-06e95cdfb8e3} + @@ -162,6 +165,9 @@ Actor + + Font + @@ -260,5 +266,8 @@ Actor + + Font + \ No newline at end of file diff --git a/Data/Font/Fairydust.ttf b/Data/Font/Fairydust.ttf new file mode 100644 index 0000000..c5aa0fc Binary files /dev/null and b/Data/Font/Fairydust.ttf differ diff --git a/LibDQt/LibDQt.pro b/LibDQt/LibDQt.pro index acdf8a4..a798c85 100644 --- a/LibDQt/LibDQt.pro +++ b/LibDQt/LibDQt.pro @@ -6,7 +6,8 @@ LIBS += -lGL \ -lGLU \ -lz \ -ltinyxml \ - -lSDL_mixer + -lSDL_mixer \ + -lSDL_ttf win32: { LIBS -= -lGL \ -lGLU diff --git a/Libs/Win32/SDL/include/SDL/SDL_ttf.h b/Libs/Win32/SDL/include/SDL/SDL_ttf.h new file mode 100644 index 0000000..5ae5bea --- /dev/null +++ b/Libs/Win32/SDL/include/SDL/SDL_ttf.h @@ -0,0 +1,249 @@ +/* + SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts + Copyright (C) 2001-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* This library is a wrapper around the excellent FreeType 2.0 library, + available at: + http://www.freetype.org/ +*/ + +#ifndef _SDL_TTF_H +#define _SDL_TTF_H + +#include "SDL.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_TTF_MAJOR_VERSION 2 +#define SDL_TTF_MINOR_VERSION 0 +#define SDL_TTF_PATCHLEVEL 11 + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL_ttf library. + */ +#define SDL_TTF_VERSION(X) \ +{ \ + (X)->major = SDL_TTF_MAJOR_VERSION; \ + (X)->minor = SDL_TTF_MINOR_VERSION; \ + (X)->patch = SDL_TTF_PATCHLEVEL; \ +} + +/* Backwards compatibility */ +#define TTF_MAJOR_VERSION SDL_TTF_MAJOR_VERSION +#define TTF_MINOR_VERSION SDL_TTF_MINOR_VERSION +#define TTF_PATCHLEVEL SDL_TTF_PATCHLEVEL +#define TTF_VERSION(X) SDL_TTF_VERSION(X) + +/* This function gets the version of the dynamically linked SDL_ttf library. + it should NOT be used to fill a version structure, instead you should + use the SDL_TTF_VERSION() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL TTF_Linked_Version(void); + +/* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */ +#define UNICODE_BOM_NATIVE 0xFEFF +#define UNICODE_BOM_SWAPPED 0xFFFE + +/* This function tells the library whether UNICODE text is generally + byteswapped. A UNICODE BOM character in a string will override + this setting for the remainder of that string. +*/ +extern DECLSPEC void SDLCALL TTF_ByteSwappedUNICODE(int swapped); + +/* The internal structure containing font information */ +typedef struct _TTF_Font TTF_Font; + +/* Initialize the TTF engine - returns 0 if successful, -1 on error */ +extern DECLSPEC int SDLCALL TTF_Init(void); + +/* Open a font file and create a font of the specified point size. + * Some .fon fonts will have several sizes embedded in the file, so the + * point size becomes the index of choosing which size. If the value + * is too high, the last indexed size will be the default. */ +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndex(const char *file, int ptsize, long index); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize); +extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index); + +/* Set and retrieve the font style */ +#define TTF_STYLE_NORMAL 0x00 +#define TTF_STYLE_BOLD 0x01 +#define TTF_STYLE_ITALIC 0x02 +#define TTF_STYLE_UNDERLINE 0x04 +#define TTF_STYLE_STRIKETHROUGH 0x08 +extern DECLSPEC int SDLCALL TTF_GetFontStyle(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontStyle(TTF_Font *font, int style); +extern DECLSPEC int SDLCALL TTF_GetFontOutline(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontOutline(TTF_Font *font, int outline); + +/* Set and retrieve FreeType hinter settings */ +#define TTF_HINTING_NORMAL 0 +#define TTF_HINTING_LIGHT 1 +#define TTF_HINTING_MONO 2 +#define TTF_HINTING_NONE 3 +extern DECLSPEC int SDLCALL TTF_GetFontHinting(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontHinting(TTF_Font *font, int hinting); + +/* Get the total height of the font - usually equal to point size */ +extern DECLSPEC int SDLCALL TTF_FontHeight(const TTF_Font *font); + +/* Get the offset from the baseline to the top of the font + This is a positive value, relative to the baseline. + */ +extern DECLSPEC int SDLCALL TTF_FontAscent(const TTF_Font *font); + +/* Get the offset from the baseline to the bottom of the font + This is a negative value, relative to the baseline. + */ +extern DECLSPEC int SDLCALL TTF_FontDescent(const TTF_Font *font); + +/* Get the recommended spacing between lines of text for this font */ +extern DECLSPEC int SDLCALL TTF_FontLineSkip(const TTF_Font *font); + +/* Get/Set whether or not kerning is allowed for this font */ +extern DECLSPEC int SDLCALL TTF_GetFontKerning(const TTF_Font *font); +extern DECLSPEC void SDLCALL TTF_SetFontKerning(TTF_Font *font, int allowed); + +/* Get the number of faces of the font */ +extern DECLSPEC long SDLCALL TTF_FontFaces(const TTF_Font *font); + +/* Get the font face attributes, if any */ +extern DECLSPEC int SDLCALL TTF_FontFaceIsFixedWidth(const TTF_Font *font); +extern DECLSPEC char * SDLCALL TTF_FontFaceFamilyName(const TTF_Font *font); +extern DECLSPEC char * SDLCALL TTF_FontFaceStyleName(const TTF_Font *font); + +/* Check wether a glyph is provided by the font or not */ +extern DECLSPEC int SDLCALL TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch); + +/* Get the metrics (dimensions) of a glyph + To understand what these metrics mean, here is a useful link: + http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html + */ +extern DECLSPEC int SDLCALL TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, + int *minx, int *maxx, + int *miny, int *maxy, int *advance); + +/* Get the dimensions of a rendered string of text */ +extern DECLSPEC int SDLCALL TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int SDLCALL TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int SDLCALL TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h); + +/* Create an 8-bit palettized surface and render the given text at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Solid(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given glyph at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. The glyph is rendered without any padding or + centering in the X direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Solid(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given text at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Shaded(TTF_Font *font, + const Uint16 *text, SDL_Color fg, SDL_Color bg); + +/* Create an 8-bit palettized surface and render the given glyph at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, + Uint16 ch, SDL_Color fg, SDL_Color bg); + +/* Create a 32-bit ARGB surface and render the given text at high quality, + using alpha blending to dither the font with the given color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create a 32-bit ARGB surface and render the given glyph at high quality, + using alpha blending to dither the font with the given color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* For compatibility with previous versions, here are the old functions */ +#define TTF_RenderText(font, text, fg, bg) \ + TTF_RenderText_Shaded(font, text, fg, bg) +#define TTF_RenderUTF8(font, text, fg, bg) \ + TTF_RenderUTF8_Shaded(font, text, fg, bg) +#define TTF_RenderUNICODE(font, text, fg, bg) \ + TTF_RenderUNICODE_Shaded(font, text, fg, bg) + +/* Close an opened font file */ +extern DECLSPEC void SDLCALL TTF_CloseFont(TTF_Font *font); + +/* De-initialize the TTF engine */ +extern DECLSPEC void SDLCALL TTF_Quit(void); + +/* Check if the TTF engine is initialized */ +extern DECLSPEC int SDLCALL TTF_WasInit(void); + +/* Get the kerning size of two glyphs */ +extern DECLSPEC int TTF_GetFontKerningSize(TTF_Font *font, int prev_index, int index); + +/* We'll use SDL for reporting errors */ +#define TTF_SetError SDL_SetError +#define TTF_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_TTF_H */ diff --git a/Libs/Win32/SDL/lib/SDL_ttf.dll b/Libs/Win32/SDL/lib/SDL_ttf.dll new file mode 100644 index 0000000..a8f1bcc Binary files /dev/null and b/Libs/Win32/SDL/lib/SDL_ttf.dll differ diff --git a/Libs/Win32/SDL/lib/SDL_ttf.lib b/Libs/Win32/SDL/lib/SDL_ttf.lib new file mode 100644 index 0000000..a44d887 Binary files /dev/null and b/Libs/Win32/SDL/lib/SDL_ttf.lib differ diff --git a/Libs/Win32/SDL/lib/libfreetype-6.dll b/Libs/Win32/SDL/lib/libfreetype-6.dll new file mode 100644 index 0000000..3b2e69d Binary files /dev/null and b/Libs/Win32/SDL/lib/libfreetype-6.dll differ diff --git a/Libs/Win32/SDL/lib/zlib1.dll b/Libs/Win32/SDL/lib/zlib1.dll index 0eeaa29..53f3376 100644 Binary files a/Libs/Win32/SDL/lib/zlib1.dll and b/Libs/Win32/SDL/lib/zlib1.dll differ diff --git a/src/Font/Font.cpp b/src/Font/Font.cpp new file mode 100644 index 0000000..f06b2f6 --- /dev/null +++ b/src/Font/Font.cpp @@ -0,0 +1,161 @@ +#include +#include "../Texture/Texture.h" +#include "../System/Debug.h" +#include "Font.h" + +Font::Font(void) { + _texture = 0; + _spaceWidth = 0; + _tabWidth = 0; + _lineSkip = 0; + memset(_characters, 0, sizeof(_characters)); + SetColor(1.0f, 1.0f, 1.0f, 1.0f); +} + +Font::~Font(void) { + if(_texture) { + glDeleteTextures(1, &_texture); + _texture = 0; + } +} + +bool Font::Load(const std::string& filename) { + TTF_Font* font = TTF_OpenFont(filename.c_str(), 16); + if(!font) { + Debug::logger->message("Error loading %s: %s", filename.c_str(), TTF_GetError()); + return false; + } + + glGenTextures(1, &_texture); + BindTexture(_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Font::TEXTURE_WIDTH, Font::TEXTURE_HEIGHT, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + SDL_Color white = { 0xFF, 0xFF, 0xFF }; + + const int ascent = TTF_FontAscent(font); + + int x = 0; + int y = 0; + int lineHeight = 0; + + for(int i = 0; i < Font::MAX_CHARS; i++) { + FontChar& character = _characters[i]; + + int minx; + int maxy; + TTF_GlyphMetrics(font, i, &minx, NULL, NULL, &maxy, &character.advance); + + character.xOffset += minx; + character.yOffset -= maxy; + character.yOffset += ascent; + + SDL_Surface* glyphSurf = TTF_RenderGlyph_Blended(font, i, white); + + if((x + glyphSurf->w) > 255) { + x = 0; + y += lineHeight; + lineHeight = 0; + } + + if(glyphSurf->w == 0 || glyphSurf->h == 0) { + SDL_FreeSurface(glyphSurf); + continue; + } + + character.uvX = (float)x / (float)Font::TEXTURE_WIDTH; + character.uvY = (float)y / (float)Font::TEXTURE_HEIGHT; + character.uvW = (float)glyphSurf->w / (float)Font::TEXTURE_WIDTH; + character.uvH = (float)glyphSurf->h / (float)Font::TEXTURE_HEIGHT; + character.width = glyphSurf->w; + character.height = glyphSurf->h; + + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, character.width, character.height, + GL_RGBA, GL_UNSIGNED_BYTE, glyphSurf->pixels); + + SDL_FreeSurface(glyphSurf); + + if(character.height > lineHeight) { + lineHeight = character.height; + } + + x += character.width; + } + + TTF_SizeText(font, " ", &_spaceWidth, NULL); + TTF_SizeText(font, "\t", &_tabWidth, NULL); + + _lineSkip = TTF_FontLineSkip(font); + + TTF_CloseFont(font); + + return true; +} + +void Font::DrawText(int xOffset, int yOffset, const char* text) { + glEnable(GL_TEXTURE_2D); + BindTexture(_texture); + + glColor4fv(_color); + + glBegin(GL_QUADS); + + const int textLength = strlen(text); + + int x = 0; + int y = 0; + + for(int i = 0; i < textLength; i++) { + char c = text[i]; + + if(c == ' ') { + x += _spaceWidth; + continue; + } else if(c == '\t') { + x += _tabWidth; + continue; + } else if(c == '\n') { + x = 0; + y += _lineSkip; + continue; + } + + FontChar& charInfo = _characters[int(c)]; + + glTexCoord2f( + charInfo.uvX, + charInfo.uvY); + glVertex2i( + charInfo.xOffset + x + xOffset, + charInfo.yOffset + y + yOffset); + + glTexCoord2f( + charInfo.uvX + charInfo.uvW, + charInfo.uvY); + glVertex2i( + charInfo.xOffset + x + charInfo.width + xOffset, + charInfo.yOffset + y + yOffset); + + glTexCoord2f( + charInfo.uvX + charInfo.uvW, + charInfo.uvY + charInfo.uvH); + glVertex2i( + charInfo.xOffset + x + charInfo.width + xOffset, + charInfo.yOffset + y + charInfo.height + yOffset); + + glTexCoord2f( + charInfo.uvX, + charInfo.uvY + charInfo.uvH); + glVertex2i( + charInfo.xOffset + x + xOffset, + charInfo.yOffset + y + charInfo.height + yOffset); + + x += charInfo.advance; + } + + glEnd(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +} diff --git a/src/Font/Font.h b/src/Font/Font.h new file mode 100644 index 0000000..28356f6 --- /dev/null +++ b/src/Font/Font.h @@ -0,0 +1,53 @@ +#pragma once + +#include "../System/ResourceManager.h" + +class Texture; + +struct FontChar { + float uvX; + float uvY; + float uvW; + float uvH; + int width; + int height; + int xOffset; + int yOffset; + int advance; +}; + +class Font : public Resource { + template friend class ResourceManager; + +public: + Font(void); + ~Font(void); + + bool Load(const std::string& filename); + + void DrawText(int xOffset, int yOffset, const char* text); + + int GetLineSkip() const { return _lineSkip; } + float* GetColor() { return _color; } + + void SetColor(float r, float g, float b, float a) { + _color[0] = r; + _color[1] = g; + _color[2] = b; + _color[3] = a; + } + +private: + unsigned int _texture; + int _spaceWidth; + int _tabWidth; + int _lineSkip; + + float _color[4]; + + static const int MAX_CHARS = 128; + static const int TEXTURE_WIDTH = 256; + static const int TEXTURE_HEIGHT = 256; + + FontChar _characters[MAX_CHARS]; +}; diff --git a/src/Main/Game.cpp b/src/Main/Game.cpp index e36625f..df2b1a0 100644 --- a/src/Main/Game.cpp +++ b/src/Main/Game.cpp @@ -20,6 +20,8 @@ Game::Game(void) { //_NPC = new NPC(); _level = new Level(); //_rotationAngle = 0.0f; + _testFont = new Font(); + _testFont->Load("../Data/Font/Fairydust.ttf"); } Game::~Game(void) { @@ -71,11 +73,17 @@ void Game::Render(void) { // Render our shit.. _level->Draw(xOffset, yOffset); _player->Render(); + _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f); + _testFont->DrawText( + _player->GetX() - 5, + _player->GetY() - _testFont->GetLineSkip() - 2, + "Miss D"); //_NPC->Render(); } void Game::Shutdown(void) { Debug::logger->message("\n ----- Cleaning Engine -----"); + delete _testFont; delete _player; delete _level; } diff --git a/src/Main/Game.h b/src/Main/Game.h index d9d6e99..d80066b 100644 --- a/src/Main/Game.h +++ b/src/Main/Game.h @@ -2,6 +2,7 @@ #include "../IO/Input.h" #include "../Actor/NPC.h" #include "../Actor/Player.h" +#include "../Font/Font.h" class Sprite; class Level; @@ -21,6 +22,7 @@ public: void OnResize(int width, int height); private: + Font* _testFont; Player* _player; NPC* _NPC; Level* _level; diff --git a/src/Main/main.cpp b/src/Main/main.cpp index d5b42c8..a263ae4 100644 --- a/src/Main/main.cpp +++ b/src/Main/main.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "Game.h" @@ -20,6 +21,7 @@ #include "../System/Debug.h" void Destroy(void) { + TTF_Quit(); Mix_CloseAudio(); DestroyInput(); SDL_FreeSurface(screen); @@ -65,6 +67,10 @@ int main(int argc, char** argv) { Debug::logger->message("Audio opened.."); } + if(TTF_Init()) { + Debug::logger->message("SDL_ttf initialized.\n"); + } + info = SDL_GetVideoInfo(); if(!info) { // This should never accur. @@ -107,9 +113,9 @@ int main(int argc, char** argv) { game.Render(); SDL_GL_SwapBuffers(); - Uint32 timeEnd = SDL_GetTicks(); - dt = (float)(timeEnd - timeStart) / 1000.0f; - timeStart = timeEnd; + Uint32 timeEnd = SDL_GetTicks(); + dt = (float)(timeEnd - timeStart) / 1000.0f; + timeStart = timeEnd; } game.Shutdown();