Category: utility

A mini-project- SDL toolkit

A mini-project- SDL toolkit

Coloured Rectangles
Image by Gerd Altmann from Pixabay

I’ve thought about doing this for a while. Build a small toolkit (a library) of helper routines for any program that uses the SDL2 library. That means it will have functions to do the following:

  1. Draw horizontal and vertical lines in a specified colour.
  2. Draw coloured rectangles both filled in and empty.
  3. Draw Circles of specified radius and colour.
  4. Draw hexagons in either orientation and of a specified size, hollow or filled.

Plus any other things that occur to me. I’ll start on this shortly.

SDL-TTF now on Raspberry Pi

SDL-TTF now on Raspberry Pi

Raspberry Pi screenshotI eventually got the Windows SDL vs TTF comparison program converted to run on Raspberry-pi, after wrestling with VS Code’s Folder. Get it wrong and you can waste hours trying to get it to compile and link. I originally set the Folder (VS Code’s way of managing projects) to the pi/Projects folder (which contained both asteroids and sdlttf folders) but eventually I sussed it and set sdlttf as my Folder.  The login user is pi and so the pi folder is my home folder. I created the Projects folder under it.

This time the home brewed print routine (print) took 28x as long as the SDL_ttf compared to 14x on Windows. I used the same text.png and font.ttf files. The times are in the Window caption and read (for those with poor contrast) sdl: 35538.574 ttf: 1235.630. These times are the microsecond times to draw the strings 100x.

Changes were fairly minimal. I changed the fopen_s to fopen (used for error logging and changed the paths to the two font files. The other change was in the timing which used the Linux versions of hr_time.h/.c and called the diff() function instead of GetElapsedTime().

I’ve zipped up the source file (sdlttf.c) plus timing files and JSON config files for VS Code in the sdlttf_pi.zip file and put it in the LearnConLinux repository on GitHub.

Note I created a projects folder then sdlttf under that. The paths in tasks.json reflect this. To build this you’ll need libsdl2-dev,libsdl2_image_dev and libsdl2-ttf-dev installed. I used clang version 7 (the default installed on pi when you do sudo apt install clang) but I imagine gcc should also build it without any problems.

This matches my conclusions from running the virtually identical Windows version. The sdlttf way is way faster for prerendered strings than my print routine which just blits the characters out of the font bitmap one by one.

 

How to create an Alphabet bitmap in CSharp

How to create an Alphabet bitmap in CSharp

Letters generated by the programHere’s another short utility. I have been looking for a decent alphabet to look in my next game (called HogWash) . As before, I want to create a sprite sheet with letters. But every alphabet set that I found had issues with kerning. I kid you not, usually but not always with M, W, or even Q.

Even when I put together a sprite sheet manually, the editor didn’t quite get it right and letters didn’t quite fit the grid. So to simplify it, here;’s a 50 line C# program that takes the letters you supply in a string, combined with a font (Liberation Mono- from Red Hat) and a brush (black solid). It does a double loop that I exit with a goto (shock horror!) when it reaches the a terminating * in the string I supplied.

That is the graphic file above that the program below generated. As you can see the letters are far enough apart so no overlapping. Just put in your path where I have for the source and dest consts. You can use this technique for building sprite sheet.

// Author D. Bolton Learncgames.com You are free to use and copy this program as you wish but please leave this line in.
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace buildfont
{
    class Program
    {
        const int LetterWidth = 100;
        const int LetterHeight = 120;
        const string source = "Your path"
        const string dest = @"YourPath\letters.png";

        static Bitmap allLetters = new Bitmap(LetterWidth * 8,LetterHeight * 5);

        static void Main(string[] args)
        {
            BuildOneImage();
        }

        private static void BuildOneImage()
        {
            var font = new Font("Liberation Mono",95);
            var brush = new SolidBrush(Color.Black);
            var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
            Console.WriteLine("Creating letters.png");
            var aty = 0.0f;
            using (Graphics g = Graphics.FromImage(allLetters))
            {
                var strindex = 0;
                for (var y = 0; y < 5; y++)
                {
                    var atx = 0.0f;
                    for (int x = 0; x < 6; x++)
                    {
                        string aLetter = str[strindex++].ToString();
                        if (aLetter == "*") goto Done;
                        g.DrawString(aLetter, font, brush, atx, aty);
                        atx += LetterWidth;
                    }
                    aty += LetterHeight;
                }
            }
            Done:
            allLetters.Save(dest, ImageFormat.Png);
        }
    }
}
How to create a big image from a number of smaller ones

How to create a big image from a number of smaller ones

Card DeckAfter the day before yesterday’s experiment showed that loading a single larger image on an Android phone is nearly three times faster than loading 52 smaller images, I decided to write a short utility program to read all the 52 individual card files and create one file with them laid out neatly in four rows of cards, one row per suite with each card running from Ace to King.

The individual card .png files were all in one folder with two letter filenames rank and suit in capitals like AS.png (Ace of spades), TH.png (Ten of Hearts and so on).

This 62 line C# program reads all 52 files into RAM in a two-dimension array cards (original name eh!) in the method LoadAllImages() then in BuildOneImage() it writes them out in the four rows into the bitmap allcards then saves them out as one .png format file.

C# makes doing this very easy. In C you would have to write your own file format handling code or use a library like libpng.

// Author D. Bolton Learncgames.com You are free to use and copy this program as you wish but please leave this line in.
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace mpics
{
    class Program
    {
        const int CardWidth = 100;
        const int CardHeight = 153;
        const string source = "your path here"; // Path to all 52 card files
        const string dest = "target file here"; // Path + filename for target .png file.
        const string suits = "HCDS";
        const string ranks = "A23456789TJQK";

        static Bitmap[,] cards = new Bitmap[13,4];
        static Bitmap allcards = new Bitmap(CardWidth * 13,CardHeight * 4);

        static void Main(string[] args)
        {
            LoadAllImages();
            BuildOneImage();
        }

        private static void BuildOneImage()
        {
            Console.WriteLine();
            var aty = 0.0f;
            using (Graphics g = Graphics.FromImage(allcards))
            {
                for (var y = 0; y < 4; y++)
                {
                    var atx = 0.0f;
                    for (int x = 0; x < 13; x++)
                    {
                        var r = new Rectangle((int)atx, (int)aty, CardWidth, CardHeight);
                        g.DrawImage(cards[x,y],r);
                        atx += CardWidth;
                    }
                    aty += CardHeight;
                }
            }
            allcards.Save(dest, ImageFormat.Png);
        }

        private static void LoadAllImages()
        {
            var i = 0;
            foreach (char c in suits)
            {
                var j = 0;
                foreach (char r in ranks)
                {
                    var s = source + r + c+".png";
                    cards[j++,i] = (Bitmap)Bitmap.FromFile(s);
                }
                i++;
            }
        }
    }
}

Don’t forget to set the source and dest path constants. This was compiled in Visual Studio 2019 and run on Windows 10. The only really important thing I found was using the Rectangle r in BuildOneImage(). If I used just atx and aty and didn’t specify the size of card then DrawImage() drew much smaller images into the bitmap. I’m not sure why as the card images when loaded from disk were 100 wide by 153 deep, the same as specified in the constants CardWidth and CardHeight.

The card images were originally downloaded from the American Contract Bridge League but were much bigger so I scaled them first to 100 x 153 pixels. There are many free playing card images on the web but these are one of the nicer sets.