Tag Archives: Programmer’s Ranch

Morse Code Converter Using Dictionaries

This elementary article was originally posted as “C# Basics: Morse Code Converter Using Dictionaries” at Programmer’s Ranch, and was based on Visual Studio 2010. This updated version uses Visual Studio 2017; all screenshots as well as the intro and conclusion have been changed. The source code is now available at the Gigi Labs BitBucket repository.

Today, we’re going to write a little program that converts regular English characters and words into Morse Code, so each character will be represented by a series of dots and/or dashes. This article is mainly targeted at beginners and the goal is to show how dictionaries work.

We’ll start off by creating a console application. After going File -> New Project… in Visual Studio, select the Console App (.NET Framework) project type, and select a name and location for it. In Visual Studio 2017, you’ll find other options for console applications, such as Console App (.NET Core). While this simple tutorial should still work, we’re going to stick to the more traditional and familiar project type to avoid confusion.

In C#, we can use a dictionary to map keys (e.g. 'L') to values (e.g. ".-.."). In other programming languages, dictionaries are sometimes called hash tables or maps or associative arrays. The following is an example of a dictionary mapping the first two letters of the alphabet to their Morse equivalents:

            Dictionary<char, String> morse = new Dictionary<char, string>();
            morse.Add('A', ".-");
            morse.Add('B', "-...");

            Console.WriteLine(morse['A']);
            Console.WriteLine(morse['B']);

            Console.WriteLine("Press any key...");
            Console.ReadKey(false);

First, we are declaring a dictionary. A dictionary is a generic type, so we need to tell in the <> part which data types we are storing. In this case, we have a char key and a string value. We can then add various items, supplying the key and value to the Add() method. Finally, we get values just like we would access an array: using the [] syntax. Just that dictionaries aren’t restricted to using integers as keys; you can use any data type you like. Note: you’ll know from the earlier article, “The ASCII Table (C#)“, that a character can be directly converted to an integer. Dictionaries work just as well if you use other data types, such as strings.

Here is the output:

If you try to access a key that doesn’t exist, such as morse['C'], you’ll get a KeyNotFoundException. You can check whether a key exists using ContainsKey():

            if (morse.ContainsKey('C'))
                Console.WriteLine(morse['C']);

OK. Before we build our Morse converter, you should know that there are several ways of populating a dictionary. One is the Add() method we have seen above. Another is to assign values directly:

            morse['A'] = ".-";
            morse['B'] = "-...";

You can also use collection initialiser syntax to set several values at once:

            Dictionary<char, String> morse = new Dictionary<char, String>()
            {
                {'A' , ".-"},
                {'B' , "-..."}
            };

Since we only need to set the Morse mapping once, I’m going to use this method. Don’t forget the semicolon at the end! Replace your current code with the following:

            Dictionary<char, String> morse = new Dictionary<char, String>()
            {
                {'A' , ".-"},
                {'B' , "-..."},
                {'C' , "-.-."},
                {'D' , "-.."},
                {'E' , "."},
                {'F' , "..-."},
                {'G' , "--."},
                {'H' , "...."},
                {'I' , ".."},
                {'J' , ".---"},
                {'K' , "-.-"},
                {'L' , ".-.."},
                {'M' , "--"},
                {'N' , "-."},
                {'O' , "---"},
                {'P' , ".--."},
                {'Q' , "--.-"},
                {'R' , ".-."},
                {'S' , "..."},
                {'T' , "-"},
                {'U' , "..-"},
                {'V' , "...-"},
                {'W' , ".--"},
                {'X' , "-..-"},
                {'Y' , "-.--"},
                {'Z' , "--.."},
                {'0' , "-----"},
                {'1' , ".----"},
                {'2' , "..---"},
                {'3' , "...--"},
                {'4' , "....-"},
                {'5' , "....."},
                {'6' , "-...."},
                {'7' , "--..."},
                {'8' , "---.."},
                {'9' , "----."},
            };

           

            Console.WriteLine("Press any key...");
            Console.ReadKey(false);

In the empty space between the dictionary and the Console.WriteLine(), we can now accept user input and convert it to Morse:

            Console.WriteLine("Write something:");
            String input = Console.ReadLine();
            input = input.ToUpper();

            for (int i = 0; i < input.Length; i++)
            {
                if (i > 0)
                    Console.Write('/');

                char c = input[i];
                if (morse.ContainsKey(c))
                    Console.Write(morse);
            }

            Console.WriteLine();

Here, the user writes something and it is stored in the input variable. We then convert this to uppercase because the keys in our dictionary are uppercase. Then we loop over each character in the input string, and write its Morse equivalent if it exists. We separate different characters in the Morse output by a forward slash (/). Here’s the output:

Awesome! 🙂 In this article we used Visual Studio to create a program that converts alphanumeric text into the Morse-encoded equivalent, while learning to use dictionaries in the process.

Securing Passwords by Salting and Hashing

This article was originally posted as “C# Security: Securing Passwords by Salting and Hashing” on 11th November 2013 at Programmer’s Ranch. This republished version is slightly edited. Although using silly passwords and the MD5 hash function is not recommended, they are used in this article to illustrate the point more easily.

Password security is often quite challenging to understand for those who are new to it (I’ve been there too, as you can see from my question about salting on StackOverflow). In this article, I am hoping to make this fascinating topic a little easier to understand. We’ll be covering two important techniques called hashing and salting. Although passwords are typically stored in a database, we’ll be using a C# dictionary to keep it simple.

Clear Text Passwords

To get started, create a new Console Application. Add the following near the top, so that we can use dictionaries:

using System.Collections.Generic;

Just inside your class Program, before your Main() method, add the following dictionary to store our users and their corresponding passwords (see “Morse Code Converter Using Dictionaries” if this seems in any way new to you):

        public static Dictionary<string, string> users = new Dictionary<string, string>()
        {
            { "johnny", "password" },
            { "mary", "flowers" },
            { "chuck", "roundhousekick" },
            { "larry", "password123" }
        };

It is now pretty simple to add a method that can check whether a given username and password result in a successful login:

        public static bool Login(string username, string password)
        {
            if (users.ContainsKey(username) && users[username] == password)
                return true;
            else
                return false;
        }

This code first checks that the username actually exists in the dictionary, and then checks whether the corresponding password matches.

We can now test this code by replacing the contents of Main() with the following code:

        public static void Main(string[] args)
        {
            Console.Write("Username: ");
            string username = Console.ReadLine();
          
            Console.Write("Password: ");
            Console.ForegroundColor = ConsoleColor.Black;
            string password = Console.ReadLine();
            Console.ResetColor();
          
            bool loggedIn = Login(username, password);
            if (loggedIn)
                Console.WriteLine("You have successfully logged in!");
            else
                Console.WriteLine("Bugger off!");
          
            Console.ReadLine();
        }

Notice that when requesting the password, we’re setting the console’s text colour to black. The console’s background colour is also black, so the password won’t show as you type, fending off people trying to spy it while looking over your shoulder.

Press F5 to try it out:

cspwsec-naive-output

Awesome – we have just written a very simple login system.

The problem with this system is that the passwords are stored as clear text. If we imagine for a moment that our usernames and passwords were stored in a database, then the actual passwords can easily be obtained by a hacker gaining illegal access to the database, or any administrator with access to the database. We can see this by writing a simple method that shows the users’ data, simulating what a hacker would see if he managed to breach the database:

        public static void Hack()
        {
            foreach (string username in users.Keys)
                Console.WriteLine("{0}: {1}", username, users[username]);
        }

We can then add the following code just before the final Console.ReadLine() in Main() to test it out:

Console.WriteLine();
Hack();

This gives us all the details, as we are expecting:

cspwsec-breach-cleartext

This isn’t a nice thing to have – anyone who can somehow gain access to the database can see the passwords. How can we make this better?

Hashing

One way is to hash the passwords. A hash function is something that takes a piece of text and transforms it into another piece of text:

cspwsec-hashfunc-1

A hash function is one-way in the sense that you can use it to transform “Hello” to “8b1a9953c4611296a827abf8c47804d7”, but not the other way around. So if someone gets his hands on the hash of a password, it doesn’t mean that he has the password.

Another property of hash functions is that their output changes considerably even with a very small change in the input. Take a look at the following, for instance:

cspwsec-hashfunc-2

You can see how “8b1a9953c4611296a827abf8c47804d7” is very different from “5d41402abc4b2a76b9719d911017c592”. The hashes bear no relationship with each other, even though the passwords are almost identical. This means that a hacker won’t be able to notice patterns in the hashes that might allow him to guess one password based on another.

One popular hashing algorithm (though not the most secure) is MD5, which was used to produce the examples above. You can find online tools (such as this one) that allow you to compute an MD5 hash for any string you want.

In order to use MD5 in our code, we’ll need to add the following statement near the top of our program code:

using System.Security.Cryptography;

At the beginning of the Program class, we can now create an instance of the MD5 class to use whenever we need:

private static MD5 hashFunction = MD5.Create();

If you look at the intellisense for MD5, you’ll see that it has a ComputeHash() method, which returns an byte array, rather than a string:

cspwsec-md5-computehash

We’re going to do some string work, so add the following near the top:

using System.Text;

Let’s write a little helper method to hash our passwords, using strings for both input and output:

        public static string Hash(String input)
        {
            // code goes here
        }

In this method, the first thing we need to do is convert the input string to a byte array, so that ComputeHash() can work with it. This is done using the System.Text.Encoding class, which provides several useful members for converting between strings and bytes. In our case we can work with the ASCII encoding as follows:

byte[] inputBytes = Encoding.ASCII.GetBytes(input);

We can then compute the hash itself:

byte[] hashBytes = hashFunction.ComputeHash(inputBytes);

Since we don’t like working with raw bytes, we then convert it to a hexadecimal string:

StringBuilder sb = new StringBuilder();
foreach(byte b in hashBytes)
sb.Append(b.ToString("x2").ToLower());

The “x2” bit converts each byte into two hexadecimal characters. If you think about it for a moment, hexadecimal digits are from 0 to f (representing 0-15 in decimal), which fit into four bits. But each byte is eight bits, so each byte is made up of two hex digits.

Anyway, after that, all we need to do is return the string, so here’s the entire code for the method:

        public static String Hash(String input)
        {
            byte[] inputBytes = Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = hashFunction.ComputeHash(inputBytes);
          
            StringBuilder sb = new StringBuilder();
            foreach(byte b in hashBytes)
                sb.Append(b.ToString("x2").ToLower());
          
            return sb.ToString();
        }

We can now change our database to use hashed passwords:

        public static Dictionary<string, string> users = new Dictionary<string, string>()
        {
            { "johnny", Hash("password") },
            { "mary", Hash("flowers") },
            { "chuck", Hash("roundhousekick") },
            { "larry", Hash("password123") }
        };

In this way, we aren’t storing the passwords themselves, but their hashes. For example, we’re storing “5f4dcc3b5aa765d61d8327deb882cf99” instead of “password”. That means we don’t store the password itself any more (if you ever signed up to an internet forum or something, and it told you that your password can be reset but not recovered, you now know why). However, we can hash any input password and compare the hashes.

In our Login() method, we now change the line that checks username and password as follows:

if (users.ContainsKey(username) && users[username] == Hash(password))

Let’s try this out (F5):

cspwsec-hash-output

When the user types “johnny” as the username and “password” as the password, the password is hashed, giving us “5f4dcc3b5aa765d61d8327deb882cf99”. Since the passwords were also stored as hashes in our database, it matches. In reality our login is doing the same thing as it was doing before – just that we added a hash step (a) when storing our passwords and (b) when receiving a password as input. Ultimately the password in our database and that entered by the user both end up being hashes, and will match if the actual password was the same.

How does this help us? As you can see from the hack output (last four lines in the screenshot above), someone who manages to breach the database cannot see the passwords; he can only get to the hashes. He can’t login using a hash, since that will in turn be hashed, producing a completely different value that won’t match the hash in the database.

Although hashing won’t make the system 100% secure, it’s sure to give any potential hacker a hard time.

Salting

You may have noticed that in the example I used, I had some pretty dumb passwords, such as “password” and “password123”. Using a dictionary word such as “flowers” is also not a very good idea. Someone may be able to gain access to one of the accounts by attempting several common passwords such as “password”. These attempts can be automated by simple programs, allowing hackers to attempt entire dictionaries of words as passwords in a relatively short period of time.

Likewise, if you know the hash for common passwords (e.g. “5f4dcc3b5aa765d61d8327deb882cf99” is the hash for “password”), it becomes easy to recognise such passwords when you see the expected hash. Hackers can generate dictionaries of hashes for common passwords, known as rainbow tables, and find hashes for common words used as passwords.

We can combat such attacks by a process known as salting. When we compute our hashes, we add some string that we invent. This means changing the first line of our Hash() function as follows:

byte[] inputBytes = Encoding.ASCII.GetBytes("chuck" + input);

Both the database password and the one entered by the user will be a hash of “chuck” concatenated with the password itself. When the user tries to login, it will still work, but look at what happens now:

cspwsec-salt-output

The login worked, but the hashes have changed because of the salt! This means that even for a password as common as “password”, a hacker cannot identify it from the hash, making rainbow tables much less effective.

Summary

This article described how to store passwords securely. It started off by doing the easiest and worst thing you can do: store them as clear text. A hash function was subsequently introduced, to transform the passwords into text from which the password cannot be retrieved. When a user logs in, the hash of the password he enters is compared with the password hash stored in the database.

Finally, the hashes were salted, by adding an arbitrary piece of text to them, in order to transform the hashes into different values that can’t be used to identify common passwords.

Additional Notes

It is interesting to note that with hashes, it does not matter how long your password is. The hash is typically fixed-length (depending on the hash function you use). So if you create an account on some airline’s website and it tells you that your password is too long because they have some maximum limit… well, they don’t know what they are doing.

Hashing and salting make password storage a lot more secure. The next level is using a slow hash algorithm with a work function. You can read about this in my followup article, “Secure Authentication with BCrypt“.

Computing File Hashes in C#

This article was originally posted at Programmer’s Ranch as “C# Security: Computing File Hashes” on 2nd May 2014, which was the blog’s first anniversary. In this version of the article, I’ve removed anniversary references and made other slight edits where they were needed.

In this article, we’re going to learn a little about hashing: what it does, and how to use it to verify the integrity of a downloaded file (which is just one application where it is useful).

We’ve already seen seen in “C# Security: Securing Passwords by Salting and Hashing” that a hash function transforms an input string into a totally different piece of data (a hash):

cspwsec-hashfunc-1

If you make even a slight change to the input, such as changing the first character from uppercase to lowercase, you get a totally different output:

cspwsec-hashfunc-2

Also, if you use a decent hash function (i.e. not MD5), it is normally not possible to get the input string from the hash.

In today’s article, we’re going to use hashes for something much simpler than securing passwords. We’re going to hash the content of files, and then use that hash to check whether the file changed. Since I haven’t been very impressed with SharpDevelop 5 Beta, I’m going to ditch it and use Visual Studio 2013 instead. You can use whatever you like – SharpDevelop, Visual Studio Express for Desktop, or maybe even MonoDevelop.

Create a new Console Application, and add the following at the top:

using System.Security.Cryptography;

This will allow you to use a variety of hash functions, which all derive from the HashAlgorithm class.

We’ll also need a little helper function to convert our hashes from a byte array to a string, so that they may be displayed in hex in the command line. We’ll use the following, which is a modified version of the Hash() method from “C# Security: Securing Passwords by Salting and Hashing“:

        public static string ToHexString(byte[] bytes)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in bytes)
            sb.Append(b.ToString("x2").ToLower());

            return sb.ToString();
        }

Now, let’s create a text file in the same folder as our .sln file and name it “test.txt”, and put the following lyrics from the Eagles’ “Hotel California” in it:

So I called up the Captain,
"Please bring me my wine"
He said, "We haven't had that spirit here since nineteen sixty nine"
And still those voices are calling from far away,
Wake you up in the middle of the night
Just to hear them say...

Let’s read that file into memory. First, we need to add the following

using System.IO;

We can now read the contents of the file into a string:

string fileContents = File.ReadAllText(@"../../../test.txt");

…and quite easily compute the hash of those contents:

            using (HashAlgorithm hashAlgorithm = SHA256.Create())
            {
                byte[] plainText = Encoding.UTF8.GetBytes(fileContents);
                byte[] hash = hashAlgorithm.ComputeHash(plainText);
                Console.WriteLine(ToHexString(hash));
            }

            Console.ReadLine();

Note that I’m using SHA256 as the hash function this time – it’s a lot more robust than MD5. If you check the documentation for the HashAlgorithm class, you can find a bunch of different hash algorithms you can use. As it is, we get the following output:

cshashfile-output-1

Now, let’s see what happens if your little toddler manages to climb onto your keyboard and modify the file. Let’s remove the first character in the file (the initial “S”) – that might be within a toddler’s ability – and save the file. When we rerun the program, the output is quite different:

cshashfile-output-2

And here we have already seen how hashing gives us the means to verify a file’s integrity, or in other words, check whether it has been tampered with. In fact, popular Linux distributions such as Ubuntu distribute MD5 hashes for the files they release, so that the people who can download them can check that they are really downloading the file they wanted, and not some weird video of goats yelling like humans:

cshashfile-ubuntu-hashes

So let’s actually see this in action. After downloading an Ubuntu distribution, let’s change the filename to that of the Ubuntu file we downloaded, and the hash algorithm to MD5:

            string fileContents = File.ReadAllText(@"../../../../ubuntu-14.04-desktop-amd64.iso");

            using (HashAlgorithm hashAlgorithm = MD5.Create())

Now, let’s try to compute a hash of the Ubuntu file:

cshashfile-out-of-memory

Oops! We tried to read a ~1GB file into memory, and that’s a pretty stupid thing to do. Unless you’ve got a pretty awesome computer, you’ll see the memory usage spike until you get an OutOfMemoryException, as above. And even if you do have a pretty awesome computer, you shouldn’t load an entire massive file just to perform an operation on its contents.

In one of my first articles at Programmer’s Ranch, “C#: Working with Streams“, I explained how you could read a file bit by bit (e.g. line by line) and work on those parts without having to have the entire file in memory at any one time. And quite conveniently, the hash algorithms have a variant of the ComputeHash() method that takes a stream as a parameter.

So let’s change our code as follows:

        static void Main(string[] args)
        {
            using (FileStream fs = File.OpenRead(@"../../../../ubuntu-14.04-desktop-amd64.iso"))
            using (HashAlgorithm hashAlgorithm = MD5.Create())
            {
                byte[] hash = hashAlgorithm.ComputeHash(fs);
                Console.WriteLine(ToHexString(hash));
            }

            Console.ReadLine();
        }

And let’s run it:

cshashfile-streamed-hash

There are a few things to note from the output:

  • It computes pretty quickly, despite the fact that it’s going through a ~1GB file.
  • Memory levels remain at a pretty decent level (in fact the memory used by the program is negligible).
  • The output matches the first hash in the list of hashes on the Ubuntu webpage (in the background of the above screenshot).

In this article, we revisited the concept of hashing, and learned the following:

  • There are several different hash algorithms provided by .NET that you can use, including MD5, SHA256, and others.
  • A hash gives you a way to verify whether a file has been tampered with.
  • Streaming provides the ability to process large files quickly and with very little memory overhead.

Animations with Sprite Sheets in SDL2

This is an updated version of “SDL2: Animations with Sprite Sheets“, originally posted on 30th March 2014 at Programmer’s Ranch. The source code is available at the Gigi Labs BitBucket repository.

Many of the previous SDL2 tutorials have involved working with images. In this article, we’re going to take this to the next level, using a very simple technique to animate our images and make them feel more alive.

Our project setup for this article is just the same as in “Loading Images in SDL2 with SDL_image“, and in fact our starting code is adapted from that article:

#include <SDL.h>
#include <SDL_image.h>

int main(int argc, char ** argv)
{
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);
    IMG_Init(IMG_INIT_PNG);

    SDL_Window * window = SDL_CreateWindow("SDL2 Sprite Sheets",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Surface * image = IMG_Load("spritesheet.png");
    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);

    while (!quit)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
        }

        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    IMG_Quit();
    SDL_Quit();

    return 0;
}

sdl2-spritesheet-borders

This image is 128 pixels wide and 64 pixels high. It consists of 4 sub-images (called sprites or frames), each 32 pixels wide. If we can rapidly render each image in quick succession, just like a cartoon, then we have an animation! 😀
Now, those ugly borders in the image above are just for demonstration purposes. Here’s the same image, without borders and with transparency:

sdl2-spritesheet-actual

If we now try to draw the above on the default black background, we’re not going to see anything, are we? Fortunately, it’s easy to change the background colour, and we’ve done it before in “Handling Keyboard and Mouse Events in SDL2“. Just add the following two lines before the while loop:

    SDL_SetRenderDrawColor(renderer, 168, 230, 255, 255);
    SDL_RenderClear(renderer);

Now we get an early peek at what the output is going to look like. Press Ctrl+Shift+B to build the project, and then copy SDL2.dll, all the SDL_image DLLs, and the spritesheet into the Debug folder where the executable is generated.

Once that is done, hit F5:

sdl2-spritesheet-early

So at this point, there are two issues we want to address. First, we don’t want our image to take up the whole window, as it’s doing above. Secondly, we only want to draw one sprite at a time. Both of these are pretty easy to solve if you remember SDL_RenderCopy()‘s last two parameters: a source rectangle (to draw only a portion of the image) and a destination rectangle (to draw the image only to a portion of the screen).

So let’s add the following at the beginning of the while loop:

        SDL_Rect srcrect = { 0, 0, 32, 64 };
        SDL_Rect dstrect = { 10, 10, 32, 64 };

…and then update our SDL_RenderCopy() call as follows:

        SDL_RenderCopy(renderer, texture, &srcrect, &dstrect);

Note that the syntax we’re using to initialise our SDL_Rects is just shorthand to set all of the x, y, w (width) and h (height) members all at once.

Let’s run the program again and see what it looks like:

sdl2-spritesheet-clipped

Okay, so like this we are just rendering the first sprite to a part of the window. Now, let’s work on actually animating this. At the beginning of the while loop, add the following:

        Uint32 ticks = SDL_GetTicks();

SDL_GetTicks() gives us the number of milliseconds that passed since the program started. Thanks to this, we can use the current time when calculating which sprite to use. We can then simply divide by 1000 to convert milliseconds to seconds:

        Uint32 seconds = ticks / 1000;

We then divide the seconds by the number of sprites in our spritesheet, in this case 4. Using the modulus operator ensures that the sprite number wraps around, so it is never greater than 3 (remember that counting is always zero-based, so our sprites are numbered 0 to 3).

        Uint32 sprite = seconds % 4;

Finally, we replace our srcrect declaration by the following:

        SDL_Rect srcrect = { sprite * 32, 0, 32, 64 };

Instead of using an x value of zero, as we did before, we’re passing in the sprite value (between 0 and 3, based on the current time) multiplied by 32 (the width of a single sprite). So with each second that passes, the sprite will be extracted from the image at x=0, then x=32, then x=64, then x=96, back to x=0, and so on.

Let’s run this again:

sdl2-spritesheet-irregular

You’ll notice two problems at this stage. First, the animation is very irregular, in fact it doesn’t animate at all unless you move the mouse or something. Second, the sprites seem to be dumped onto one another, as shown by the messy image above.

Fortunately, both of these problems can be solved with code we’ve already used in “Handling Keyboard and Mouse Events in SDL2“. The first issue is because we’re using SDL_WaitEvent(), so the program doesn’t do anything unless some event occurs. Thus, we need to replace our call to SDL_WaitEvent() with a call to SDL_PollEvent():

        while (SDL_PollEvent(&event) != NULL)
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    quit = true;
                    break;
            }
        }

The second problem is because we are drawing sprites without clearing the ones we drew before. All we need to do is add a call to SDL_RenderClear() before we call SDL_RenderCopy():

        SDL_RenderClear(renderer);

Great! You can now admire our little character shuffling at one frame per second:

sdl2-spritesheet-goodslow

It’s good, but it’s a bit slow. We can make it faster by replacing the animation code before the srcrect declaration with the following (10 frames per second):

        Uint32 ticks = SDL_GetTicks();
        Uint32 sprite = (ticks / 100) % 4;

Woohoo! 😀 Look at that little guy dance! (The image below is animated, but this seems only to work in Firefox.)

sdl2-spritesheet-animated

So in this article, we learned how to animate simple characters using sprite sheets, which are really just a digital version of a cartoon. We used SDL_RenderCopy()‘s srcrect parameter to draw just a single sprite from the sheet at a time, and selected that sprite using the current time based on SDL_GetTicks().

Displaying Text in SDL2 with SDL_ttf

This is an updated version of the article originally posted on 29th March 2014 at Programmer’s Ranch. The source code for this article is available at the Gigi Labs BitBucket repository.

In this article, we’re going to learn how we can write text in our window. To do this, we’ll use the SDL_ttf library. Setting it up is almost identical to how we set up SDL_image in “Loading Images in SDL2 with SDL_image“. You need to download the Visual C++ development libraries from the SDL_ttf homepage:

sdl2ttf-download

Then, extract the lib and include folders over the ones you have in your sdl2 folder. You should end up with an SDL_ttf.h in your include folder, and you should get SDL2_ttf.lib and a few DLLs including SDL_ttf.dll in your lib\x86 and lib\x64 folders.

In your Linker -> Input, you’ll then need to add SDL2_ttf.lib:

sdl2ttf-linker-input

Good. Now, let’s start with the following code which is a modified version of the code from about halfway through “Displaying an Image in an SDL2 Window“:

#include <SDL.h>

int main(int argc, char ** argv)
{
    bool quit = false;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window * window = SDL_CreateWindow("SDL_ttf in SDL2",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640,
        480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

    while (!quit)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
        }
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

The first thing we need to do in order to use SDL_ttf is include the relevant header file:

#include <SDL_ttf.h>

Then, we initialise the SDL_ttf library right after we call SDL_Init():

TTF_Init();

…and we clean it up just before we call SDL_Quit():

TTF_Quit();

Right after we initialise our renderer, we can now load a font into memory:

 TTF_Font * font = TTF_OpenFont("arial.ttf", 25);

TTF_OpenFont() takes two parameters. The first is the path to the TrueType Font (TTF) that it needs to load. The second is the font size (in points, not pixels). In this case we’re loading Arial with a size of 25.

A font is a resource like any other, so we need to free the resources it uses near the end:

TTF_CloseFont(font);

We can now render some text to an SDL_Surface using TTF_RenderText_Solid(). which takes the font we just created, a string to render, and an SDL_Color which we are passing in as white in this case:

 SDL_Color color = { 255, 255, 255 };
 SDL_Surface * surface = TTF_RenderText_Solid(font,
  "Welcome to Gigi Labs", color);

We can then create a texture from this surface as we did in “Displaying an Image in an SDL2 Window“:

    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);

And yet again, we should not forget to release the resources we just allocated near the end, so let’s do that right away:

 SDL_DestroyTexture(texture);
 SDL_FreeSurface(surface);

Now all we need is to actually render the texture. We’ve done this before; just add the following just before the end of your while loop:

  SDL_RenderCopy(renderer, texture, NULL, NULL);
  SDL_RenderPresent(renderer);

Okay, now before we actually run this program, we need to put our Arial TTF font somewhere where our program can find it. Go to C:\Windows\Fonts, and from there copy the Arial font into the Debug folder where your executable is compiled. This will result in several TTF files, although we’re only going to use arial.ttf. We will also need the usual SDL2.dll, along with the SDL_ttf DLLs (libfreetype-6.dll, zlib1.dll and SDL2_ttf.dll):

sdl2ttf-fonts

Great, now let’s admire the fruit of our work:

sdl2ttf-blocky2

Nooooooooooooooo! This isn’t quite what we were expecting, right? This is happening because the texture is being stretched to fill the contents of the window. The solution is to supply the dimensions occupied by the text in the dstrect parameter of SDL_RenderCopy() (as we did in “Displaying an Image in an SDL2 Window“). But how can we know these dimensions?

If you check out Will Usher’s SDL_ttf tutorial, you’ll realise that a function called SDL_QueryTexture() can give you exactly this information (and more). So before our while loop, let’s add the following code:

    int texW = 0;
    int texH = 0;
    SDL_QueryTexture(texture, NULL, NULL, &texW, &texH);
    SDL_Rect dstrect = { 0, 0, texW, texH };

Finally, we can pass dstrect in our call to SDL_RenderCopy():

SDL_RenderCopy(renderer, texture, NULL, &dstrect);

Let’s run the program now:

sdl2ttf-text2

Much better! 🙂

In this article, we learned how to use the SDL_ttf to render text using TTF fonts in SDL2. Using the SDL_ttf library in a project was just the same as with SDL_image. To actually use fonts, we first rendered text to a surface, then passed it to a texture, and finally to the GPU. We used SDL_QueryTexture() to obtain the dimensions of the texture, so that we could render the text in exactly as much space as it needed. We also learned how we can set up our project to use the same path regardless of whether we’re running from Visual Studio or directly from the executable.