1. Technology

An SDL GUI for Empire Tutorial Three

Using True Type Fonts with SDL_ttf

By

Screenshot of Empire Map with TTF text

This is another tutorial about developing the Empire game. If you've found this article first, please see part one. Here's more information about the Empire Game.

In the previous SDL Gui tutorial I created a GUI and implemented one of the controls and this time I'm using the SDL_ttf True Type Fonts in the Empire game.

  • Download Source Code File (Zip).
  • Download binaries (All Exe + SDL dlls + graphic files etc) zipped up. Just unzip everything into one folder. It should run. YOu shouldn't need SDL installed unless you are developing it.

So far all of the SDL games like Asteroids, Snake and Empire have used a mono width single-sized bitmap font. For Snake and Asteroids it was sufficient and just remember that all games on the 80s Personal Computers, like the Timex Spectrum and CBM-64 all used the same type of fonts. As did all of the games on PCs before Windows came along. You needed a separate bitmap for each type and size of font.

But with Windows and Mac computers having lovely proportional scalable fonts (i.e. True Type fonts), it was not long before people thought about including them in games. SDL does not support them natively but an extension library SDL_ttf does. So this tutorial is about setting up SDL_ttf and making use of it. Then I can start using it in the SDL Gui and making it look pretty compared to the first version.

Setting Up SDL_TTF

The libraries page or projects directory lists several projects including SDL_ttf. Click the page and download the appropriate files.

As this tutorial is Windows you need the SDL_ttf-2.*.zip and SDL_ttf-devel-2.*.zip (whatever version), currently it's SDL_ttf-2.0.11-win32.zip and SDL_ttf-devel-2.0.11-VC.zip. The first file contains three dlls and you need them all in the location where your game exe will be.

The second file includes debug versions of these dlls as well as the header file SDL_ttf.h in the include folder and SDL_ttf.lib in the lib folder (a 32 bit version in x86 and 64 bit in x64). One of these is what the Visual C++ linker needs. I'm using the x86 32 bit set.

You need to set up the header and lib files in the same way as the main SDL files were setup. See Setting Up Visual Studio/Visual C++ 2010 for SDL.

The short version is like this: On my PC I have a c:\sdl folder with lib and include sub folders. Put SDL_ttf.h in the include sub folder (and make it read only so you don't risk accidentally editing it like I did once and breaking SDL!) and the SDL_ttf.lib in the lib folder and copy the three dlls to where your exe is (or both debug and release folders).

If you've already setup SDL in Visual Studio then you just have to go to the project properties, look for Linker under Configuration Properties then click Input and on the right panel click the Additional Dependencies. You'll see a pull down arrow appear, click it and then click <edit>. and add SDL_TTF.lib to the end of the list which should already contain SDL.lib, SDL_main.lib and SDL_image.lib. Click Ok, and Apply to accept and that's it. Your project now supports SDL_ttf. If you are building a release version you need to repeat for that.

Note: For further detailed information on using SDL_ttf.h, download the 4.1 MB SDL_TTF source file. You don't need to build the sources but this includes showfont.c which has lots of calls. Also I found this very useful SDL_ttf documentation on the web.

Using SDL_ttf

Add #include "SDL_ttf.h" to the start of sdlgui.h. I added it just after include "SDL_image.h". Because there are multiple files (.h and .c) involved, it's very easy to get link errors like _font defined already. I've wrapped the headers inside #ifndef for SDLTTF, STDLIB etc. The main SDL includes are defined in sdlgui.h which is included from both sdlgui.c and empire.c so by using #IFNDEF and defining a named symbol SDLTTF etc, this stops the same include file being included multiple times.

I downloaded the free TTF font bobcaygeon.zip from 1001freefonts.com and copied one of the two .ttf files there into the debug and release folders, along with the SDL_ttf set of dlls.

Before using the TTF library you have to initialize it so there's a call to TTF_Init in InitSetup() and a corresponding TTF_Quit() call at the end in FinishOff(). Plus for each font used (just one for now), I've added a call to TTF_OpenFont() in initsdlguilib plus a call to TTF_CloseFont() in freesdlguilib().

Each TTF_OpenFont() allocates memory for a given font size, loaded from a .ttf file. So load these all up at the start then free the memory at the end and finally close down the TTF system with TTF_Quit().

Displaying Text

Rendering text is slightly slower than just blitting bitmaps so you might prefer to pre-render it in to surfaces then blit those surfaces. You'd tend to use that for always displayed text like Score etc. For one off messages, it's less important.

There are three rendering modes to use. From fast to slow (anti aliased) to very slow (includes alpha transparency) which is the nicest. The JonAtkins documentation I liked to earlier goes into this in quite some depth. I'll use the fast mode TTF_RenderText_Solid for my debug info at the bottom drawn with print().

As I hate to throw away working code, I've left the the older bitmap print routine in (just in case) and created ttf_print() with the same parameters as print(). This is ttf_print():

void ttf_print(int x,int y,char * text) {
   SDL_Rect target;
   SDL_Surface *text_surface;
   int w,h;
   int ok= TTF_SizeText(font, text, &w, &h);
   target.h = h;
   target.w= w;
   target.x = (Sint16)x;
   target.y = (Sint16)y;
   text_surface=TTF_RenderText_Solid(font,text,red);
   SDL_BlitSurface(text_surface,NULL,screen,&target);
   SDL_FreeSurface(text_surface);
}

The call to TTF_RenderText_Solid() allocates an SDL surface so after using it, you must throw it away with SDL_FreeSurface. The TTF_SizeText call returns the size of the string as a rendered rectangle of size w and h. These are plugged into the target SDL_RECT so that it can blitted to the exact place. Note the red color is defined elsewhere.

So that's TTF text used successfully and I can continue in the next tutorial adding the other controls and making the button control a bit nicer looking. Also I'm going to start timing all the calls to get a feel for what takes longest and how long.

The game is starting to get large enough that I should consider building some kind of resource manager library to manage fonts, bitmaps, surfaces etc. Though initially it makes the program a little bit more complex, it simplifies things eventually and with a utility program to combine then into one file, wil start to make the game look a bit more professionally organized.

PS

I solved the crash problem with the release version. Although it worked in the Debug version I hadn't moved all of the variables into sdlgui.c and extern'd them to access them from empire.c. Once I did that the release version compiled and ran without issue. That's the version that's in the binaries file so it should run better than previous versions.

  1. About.com
  2. Technology
  3. C / C++ / C#
  4. Programming Games
  5. An SDL GUI for Empire Tutorial Three

©2014 About.com. All rights reserved.