Category: SDL

How to install SDL2 in Visual Studio

How to install SDL2 in Visual Studio

Visual Studio IDEThis is the first of a number of longer-piece game related tutorials. You’ll see I’ve added a tutorials link to the top menu. That page will grow as I add tutorials, as each is added to it .

You’ll see I use the terms SDL and SDL2 mostly interchangeably. SDL is the name of the library but we don’t want the older SDL1 instead we want SDL2 which seems more or less permanently at version 2.0.12.

I’ve left the Visual Studio version off as the process is mostly the same whether it’s Visual Studio 2017, 2019 or future versions. Screenshots are from Visual Studio 2019.

You don’t have to do this on Linux as it takes three or four sudo apt installs to add the various SDL2 dev modules in, but with Windows you need to configure Visual Studio and it can be a somewhat confusing process if you are new to Visual Studio.

Also you need to download and fetch the various files. This is made slightly more complicated because there are 32-bit and 64-bit versions and you want to keep them both so you can switch between the two.

Here are the various steps we have to go through.

  1. Download the various files and unzip them
  2. Setup include and lib paths in Visual Studio
  3. Add the lib files into Visual Studio.
  4. Copy the dlls into the folder where the game will run.
  5. Compile and run it.

What you are downloading are basically three types of files.

  1. Header files., This is files like sdl.h.  Your program will #include these.
  2. Lib files. This is the bulk of the SDL code.
  3. Dll files (Dynamic Link Liobraries). Needed for runtime.

Download the various files and unzip them

The SDL website is libsdl.org and if you click the SDL Releases in the bottom right it will take you to the SDL downloads page. WE don’t need the source code (you are welcome to download it and take a look but it’s not needed to use SDL2.

We do however need the development libraries. These include the runtime binaries so we don’t need to download those. as well. Just the one file SDL2-devel-2.0.12-VC.zip

I suggest you create a folder SDL or SDL2 on your drive. My C: drive is for Windows so I use d: \SDL2

If you unzip the files into there you’ll end up with three folders and five .txt files. Just under 7 MB in total. Other than docs there are include and lib.  The lib folder is further split into x64 (64-bit) and x86 (32-bit) . It also includes the runtime dlls. These will have to be in the path for your program but we’ll leave that until later.

Sounds, Images and Truetype fonts

As well as these, you are probably going to want image file support, sounds and possibly truetype font support in your program. These are separate files in the SDL projects folder.

  1. Image file support. Download the development library file from the sdl_image page. As before you want development library file. SDL2_image-devel-2.0.5-VC.zip.
  2. Sounds file support. Download the development library from the sdl mixer page. It’s SDL2_mixer-devel-2.0.4-VC.zip.
  3. ttf file support. Once again a development library downloaded from the SDL_ttf project page. It’s SDL2_ttf-devel-2.0.15-VC.zip.

All three files have similar structure to the SDL2 dev library.  Unzip the include files into the SDL include folder and the lib files into the relevant X86 and X64 lib sub-folders. So all your SDL files that you need are in the same include and lib sub-folders.

I suggest you extract the file folders one by one, do the three include files first then the x64 files and then the x86. Do not get x86 and x64 mixed up. The only way to tell them apart is by size and it’s not always an accurate way.  Don’t worry if it complains about overwriting zlib1.dll. There’s a copy in both the images and sounds zip files.

Setup include and lib paths in Visual Studio

This can be a bit complicated, just follow these instructions exactly.

To configure a C/C++ project in Visual Studio, you have to specify where the compiler gets its include files, where it finds its lib files and which lib files you want to link to.

Solution ExplorerI’ve created a blank C++ project called sdltest in VS 2019.  Now I actually want it to be a C project so just rename the main file sdltest.cpp to sdltest.c. You need to delete all of the C++ code in that file as well.  After renaming the Solution Explorer should look something like this. We will have a sdltest program to run later so just save this for now. You can get the file from GitHub and overwrite sdltest.c.

Now click Project on the top menu then sdltest properties at the foot of the menu.  You should see this form (below).  This is how you specify properties for your project in Visual Studio.

You’ll see I have selected VC++ Directories on the left. This is where you specify some of the directories (folders and directories mean the same thing BTW) .

But the Platforms pull down probably shows Win32 on yours. Change it to All Platforms. Visual Studio lets you specify configurations for all things or for x86 or x64 separately. We’ll use the same include folders for both x86 and x64 but we’ll specify the paths to the lib files individually as the x64 lib files are in the x64 sub-folder and the x86 files in the x86 folder.

Property Pages
To specify the path click on Include Directories, you’ll see a down arrow appear on the right.  Click it and you’ll see <Edit…> appear, click it and a form like this below will popup.
Visual studio folder editClick on the blue area in the form and you’ll be able to paste or type in the path or click the … button to get a file browser appear. Type in, paste or select the folder then press Ok.  You should now see your path in the folders.

Here I typed in d:\SDL\Include. Be careful that you don’t get rid of $(VC_includePath);$(WindowsSDK_IncludePath); in the include path as I did as your program won’t compile!

folder paths

We now have to do the same for the lib paths.  But first we must change the Platform to specify x86 or x64.

If you change it, a popup will appear asking if you want to save your changes. Click the Yes button.

Confusingly the platform choices on mine are Win32 and x64, but Win32 is the same as x86.

You’ll see that the include path you added shows up in the x86/Win32 platforms because we changed it for all platforms.

Now add the path for Library Directories. Click the down arrow then <edit…> and put in the full path to the folder that matches the Platform. x86 for Win32 platform, x64 for x64 platform. After you’ve entered it will show up in the directories.

Visual studio all paths

If you want both x64 and x86 then change the platform and re-enter it. Don’t forget to save!

Add the lib files into Visual Studio

The last configuration to do is specify the lib files that are needed. We’ve specified the paths for include and lib files but the compiler linker doesn’t know what lib files to link.

As linking depends on 32-bit or 64-bit we have to specify this twice as we did for the lib paths. It’s in a different place in the property pages. Click Linker then Input.

Visual Studio Linker Configuration It’s the top line (Additional Dependencies) that we need to work with. Click into it to get the down arrow then click that and the <edit…> as before.

You’ll have noticed that it comes pre-populated with all the various library .lib files.  We’ll be adding some more. The ones we need are

SDl2.lib SDL2_mixer.lib SDL2_ttf.lib SDL2_image.lib and SDL2main.lib

Add these into the edit box one by one and press return after each one.

After you’ve added them and pressed Ok, you’ll see them in a list. Something like this though I’ve not added SDL2_ttf.lib in to it yet.

As before repeat for both x86 and x64.

 

We’re now ready to compile. Only we need a program to do that. I’m not going to list the whole sdltest as it’s 135 lines but you can download the VS project in the file sdltest.zip from GitHub. It should compile with no errors. If you get errors, please recheck the include folders and lib folders and make sure you have configured them correctly.

So it compiles, but it won’t run. If you look in the Debug folder under the x64 (or Win32 if you built that) , you’ll see a whole lot of files. but only sdltest.exe is important. You can delete the rest. Leave sdltest.pdb if you wish to debug.

We have to

Copy the dlls into the folder where the game will run

That folder is this the \sdltest\x64\Debug folder. We need several .dll files from the same lib folder that holds the x64 libs. (Again if you are on Win32 you need dlls from the x86 lib folder).

What files do we need?

Just SDL2.dll. If we were using images we’d also need sdl2_image.dll and zlib1.dll. We don’t currently need the SDL2_mixer.dll or the SDL2_ttf.dll but if you ever use sounds or Truetype then you’ll need those. For sounds you’ll also need some of the lib*.dll files such as libogg-0.dll or libvorbis-0.dll. For image we might need in the future libjpeg-9.dll (if we ever use jpg files).

So you’ve compiled it and should see something like this when you run sdltest.exe. It doesn’t do much except draw coloured rectangles. Press the esc key to close it. On my POC it draws 100,000 coloured rectangles each 120 x 120 pixels in about a second. That’s pretty fast!

The heart of the program is this function:

void DrawRandomRectangle() {
	char buff[20];
	SDL_Rect rect;
	SDL_SetRenderDrawColor(renderer, Random(256) - 1, Random(256) - 1, Random(256) - 1, 255);
	rect.h = 120;// Random(100) + 20;
	rect.w = 120;// Random(100) + 20;
	rect.y = Random(HEIGHT - rect.h - 1);
	rect.x = Random(WIDTH - rect.w - 1);
	SDL_RenderFillRect(renderer, &rect);

	rectCount++;
	if (rectCount % 100000 == 0) {
		SDL_RenderPresent(renderer);
		stopTimer(&s);
		sprintf_s(buff, sizeof(buff), "%10.6f", getElapsedTime(&s));
		SetCaption(buff);
		startTimer(&s);
	}
}

Uncomment the two lines with 120; // Random(100) + 20; to have it draw random sized rectangles. The figure in the caption is how long it takes to draw 100,000 rectangles.

Using small delays in C with SDL ticks

Using small delays in C with SDL ticks

Asteroids game - player ship rotationRunning a game at 60 frames per second means that handling things like key presses can be interesting. In the game, I call various SDL functions and via a giant switch statement set flags. Then later in the game loop, those flags are used to determine actions

So if you press Q to rotate the player ship anti-clockwise (counter-clockwise to yanks!) without some limiting thing, it would whizz round through 900 degrees each second. (There are 24 rotation angles for the ship, each 15 degrees. 60 x 15 = 900) .

I use a very simple technique to limit it. SDL has a function called SDL_GetTicks that returns the number of ticks since SDL was initialized in the game, i.e. when it started running. A tick is 1/1000th of a second, i.e. a millisecond. By calling this function twice, you can measure a time period. It’s not as precise as the nanosecond CPU clock that I use but for the kind of delays I’m talking about it is more than sufficient.

This is the code that is called each frame in the game loop.

void RotatePlayerShip() {
	if (rotateFlag && (SDL_GetTicks() - rotTimer > 40)) {
		rotTimer = SDL_GetTicks();
		if (rotateFlag == 1) // CounterClockwise 
		{
			Player.dir += 23;
			Player.dir %= 24;
		}
		else
			if (rotateFlag == 2) // Clockwise
			{
				Player.dir++;
				Player.dir %= 24;
			}
	}
}

Because the game loop syncs to the vertical fly-back, the time between two successive calls of this would be about 16.666 milliseconds. (=1000/60), but the check to see if 40 ticks have passed slows it down to 25 x 15 = 375 degrees rotation per second, i.e. just over one complete revolution which is more manageable than 900/360 = 2.5 full rotations. Plus if you wish rotation speed to be faster just change the 40 to a lower value.

This measured time delay is used quite a few times in the game. You could use it as a means to make the game get harder by having shorter delays on say aliens moving or firing.

How to Draw a circle in C

How to Draw a circle in C

Asteroids-with shield-round-player-shipIn the asteroids game, when you press the s button to put up a shield, it draws a circle.  I must confess, I didn’t know how to draw a cuircle so looked it up and found an example on StackOverflow. You can use code from StackOverflow, licensed under a MIT license.  I include the link to StackOverflow in the game code (in the chapter 48 zip file) in a comment.

Here’s the code in the game.

void DrawCircle(SDL_Renderer *Renderer, int _x, int _y, int radius)
{
	int x = radius - 1;
	int y = 0;
	int tx = 1;
	int ty = 1;
	int err = tx - (radius << 1); // shifting bits left by 1 effectively
								  // doubles the value. == tx - diameter
	while (x >= y)
	{
		//  Each of the following renders an octant (1/8th) of the circle
		SDL_RenderDrawPoint(Renderer, _x + x, _y - y);
		SDL_RenderDrawPoint(Renderer, _x + x, _y + y);
		SDL_RenderDrawPoint(Renderer, _x - x, _y - y);
		SDL_RenderDrawPoint(Renderer, _x - x, _y + y);
		SDL_RenderDrawPoint(Renderer, _x + y, _y - x);
		SDL_RenderDrawPoint(Renderer, _x + y, _y + x);
		SDL_RenderDrawPoint(Renderer, _x - y, _y - x);
		SDL_RenderDrawPoint(Renderer, _x - y, _y + x);

		if (err <= 0)
		{
			y++;
			err += ty;
			ty += 2;
		}
		else 
		{
			x--;
			tx += 2;
			err += tx - (radius << 1);
		}
	}
}

it’s as simple as that! To make it more interesting, it is called each frame with the shield throbbing  by increasing  the radius from 38 to 46 pixels by 2 then restarting at 38 again. Here’s the code for that. Note that when the shield energy is below 10, it no longer works.

void DisplayShield(SDL_Rect * target) {
	if (shieldFlag && shieldStrength >10) {
		SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
		DrawCircle(renderer, target->x + (SHIPWIDTH/2), target->y + (SHIPHEIGHT/2), shieldRadius);
		shieldRadius += 2;
		if (shieldRadius == 46) {
			shieldRadius = 38;
		}
	}
	if (shieldStrength < 100) {
		TextAt(target->x + 10, target->y + 58, sltoa(shieldStrength), 0.67f);
	}
}

The number under the player ship is the shield energy which drains while the shield is being displayed and recharges back up to 100 when you take your finger off the shield button. The number is only shown when the value is less than 100.

How to find files in Ubuntu

How to find files in Ubuntu

In this I’m looking for the SDL2 header files. These are installed when you install libsdl2-dev as we saw yesterday.

While you can do it from a terminal with the find command, I find it easier to do it from the GUI. We need the Files utility which you get by clicking on this icon on the left toolbar. files-icon Now click Other Locations on the left and you should see something like this.

On This computer
Click Computer. This will let you search through the entire Linux file tree.

Click on the magnifying glass icon and in the text box that appears type in sdl2 and press enter. It will spend a few seconds or minutes searching and then find a number of files/folders.

The first result was SDL2 and the usr/include is a big clue. Double-click on this and it will open on a folder full of header files!That’s what we want.SDL2 Folder

 

When you are configuring gcc/clang and want to add paths for include files like SDL2, it’s important to know where those files are located.

Publishing excerpts from my 2nd ebook

Publishing excerpts from my 2nd ebook

learn C Games Book coverI’m changing horses in midstream so this won’t appear as it’s been done so far. Rather than let it go to waste, I’ll be publishing it in parts here. My next book will be Learn C Games Programming on the Raspberry Pi.

Installing SDL2 on Ubuntu/Debian

The SDL2 library is an open source library available from the libsdl.org website. However in Ubuntu it’s fairly easy to install. We do need not just the binary files but the headers so we can include them.
On Ubuntu (and Debian system) the apt tool maintains a cache of files. You can search these from a terminal with this command.
apt-cache search libsdl2
On my PC this output.
libsdl2-2.0-0 – Simple DirectMedia Layer
libsdl2-dev – Simple DirectMedia Layer development files
libsdl2-doc – Reference manual for libsdl2
libsdl2-gfx-1.0-0 – drawing and graphical effects extension for SDL2
libsdl2-gfx-dev – development files for SDL2_gfx
libsdl2-gfx-doc – documentation files for SDL2_gfx
libsdl2-image-2.0-0 – Image loading library for Simple DirectMedia Layer 2, libraries
libsdl2-image-dev – Image loading library for Simple DirectMedia Layer 2, development files
libsdl2-mixer-2.0-0 – Mixer library for Simple DirectMedia Layer 2, libraries
libsdl2-mixer-dev – Mixer library for Simple DirectMedia Layer 2, development files
libsdl2-net-2.0-0 – Network library for Simple DirectMedia Layer 2, libraries
libsdl2-net-dev – Network library for Simple DirectMedia Layer 2, development files
libsdl2-ttf-2.0-0 – TrueType Font library for Simple DirectMedia Layer 2, libraries
libsdl2-ttf-dev – TrueType Font library for Simple DirectMedia Layer 2, development files

We’ll eventually need libsdl2, libsdl2-image for graphics support and libsdl2-mixer for sounds. We’ll also need libsdl2-dev so let’s start with that. Run this command . It will probably ask for your password.

sudo apt-get install libsdl2-dev

That downloaded and installed 73 MB of files.   More to follow

Working with SDL_ttf

Working with SDL_ttf

Font set
Image by Gordon Johnson from Pixabay

I’ve decided that I should use SDL_ttf in my games. I had previously incorrectly thought that using it would lead to a performance hit and wrote my own printch and TextAt functions which with a fixed-with (monospaced) font saved as a bitmap worked ok.

However after reading up on this, I see that the main routine for outputting text returns a SDL_Surface. This is an in-ram structure.

SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, const char *text, SDL_Color fg)

The significance of this is that you pre-render all text strings as much as possible then convert them to SDL_Textures which moves the structures into VRAM. That means those strings can be blitted as fast as my string method. It’s less flexible says when printing numbers, so it might make sense to output a monospaced font of digits in the desired colour and font size  (I call it a digitset) and prepare all the digit sets that you need. I’ll create a test program…

PS. This is my 100th blog entry! Here’s to the next 100….

Progress on the Match Three game

Progress on the Match Three game

Match Three game Having a week off work has let me work on this game a bit more. I’ve put in about eight hours and it is now correctly dropping.

I’d never programmed one of these before so my first version used a board of pieces plus a secondary array for holding “transitions”. A transition was a struct that held information about two pieces being swapped and the current coordinates of each piece.  It seemed to be quite messy code and was quite buggy with pieces on top of other pieces.

So I then switched to a system where each board cell had a pointer to a struct for a piece (held in an array).  If the piece wasn’t moving the program calculated its pixel coordinates from the board coordinates and drew it there. If it was moving, it would no longer have board coordinates and would use the pixel coordinates to draw it.

That was better but then I thought why not just have the board just be a 2D array of structs with one struct for each piece.

This is the struct for each piece.

 

struct Cell {
	int piece;
	int moving;
	int scEndX, scEndY;
	float scCurrentX, scCurrentY;
	float velY, velX;
	int bdEndX;
	int bdEndY;
	int angle;
	int lock;  //1 = locked. Display padlock
	int size; // used when killing to diminish size
};

SDL2 does rotation very nicely; you don’t need to pre-render shapes just call SDL_RenderCopyEx instead of SDL_RenderCopy and specify the angle and one or two other parameters. When a piece is removed, it animates for about a half-second, rotating and shrinking in place. That’s the purpose of the angle and size fields.

If the lock value is 1 then the piece stays in place and won’t drop. You have to remove the lock by forming a line that includes the locked piece. When the line is removed, all locked pieces in the line remain but without the lock.

So far the game is currently about 800 lines of code. There’s no game level structure, high-score table, sounds, bonus pieces or even a basic piece matching algorithm. I’ve been testing by just randomly removing three vertical or horizontal pieces and then having unlocked pieces above fall down.

This 3rd version does not suffer from the Mexican-wave problem that the first and second version had. Sometimes when a column of pieces moved down, instead of all pieces moving together they moved one-by-one. New pieces get added in when the top row piece finishes dropping away.

So now on with the book and the next part of the game.

Code::Blocks revisited

Code::Blocks revisited

Code::Blocks SDL2 demoSo after yesterday’s post I also installed Code::Blocks on Ubuntu 20.04 LTS, the recent six monthly Ubuntu release. Guess what, it’s a much newer version of Code::Blocks that looks slightly different and does include SDL2. Although the demo program it creates is C++ not C (That coloured bar picture is the demo).  I haven’t used it enough to see what’s different between this and version 16.01.

The version of Code::Blocks on the 18.04LTS Ubuntu  was 16.01 and on Ubuntu 20.04 LTS it’s Code::Blocks 20.03. I keep my Ubuntus up to date but the 18.04 LTS hasn’t switched to the newer Code::Blocks which surprised me. I’m guessing that the maintainers of the 18.04 LTS Ubuntu repositories just haven’t updated their copy of Code::Blocks.

One thing I hadn’t explored in Code::Blocks is the debugging and this seems a lot more powerful than what you get in Visual Studio Code.   This screenshot below from version 20 shows it is more akin to Visual Studio debugging rather than Visual Studio Code debugging what with CPU registers, stack, memory dump and threads.

Code::Blocks Debugging Menu

 

A new mini game console

A new mini game console

playdatePlaydate sounds a tad dodgy but is actually a small handheld game console with a 2.7-inch, 400 × 240 screen (173 ppi) and costing $149. It’s due out sometime this year.

The reason I mention it is it runs games written in C (or Lua).  It also comes with 12 games. No mention of what’s inside it (RAM, CPU) though that’s described as ‘beefy’ but it has Wi-Fi, Bluetooth, USB-C, and a headphone jack.

That thing sticking out of the right is a hand crank. No, not for charging the battery but as a game input device. If you create a side-scroller game you can have it scroll one way by cranking in one direction and reverse it by cranking in the other way. Well that’s certainly original!

There will be a development kit available for it and you will be able to write programs for it though at the moment that looks as if its only on a Mac which is a bit of a shame. Oh I have a Mac but I much prefer my Windows PC or Ubuntu.

Compared to the massive screen sizes available on PCs, 400 x 240 sounds a bit small screen size. If you remember the CBM-64 from the 80s, it is exactly the same size as that screen and there were some great games out for it.

I’m excited about this because I believe it could be a renaissance for C Game programming.

SDL. Surfaces or textures?

SDL. Surfaces or textures?

Screenshot from DominionsWhen I first started on the asteroids game, I did it as a set of tutorials on About.com. That was around 2011/2012 and back then I used SDL 1 which was all about surfaces not textures. When I picked up SDL coding again in 2018, it had progressed to SDL2 which uses textures.

As I understand it, a surface is a structure in RAM while a texture is a structure in VRAM ( the memory in the GPU(. That makes it much faster copying pixels from VRAM to VRAM than from RAM to VRAM.

But I found it much easier to read pixels from a surface than from a texture. Chapter 38 in my e-book has a mask utility. It loads the images from disk into a surface then reads the pixels and creates the masks from that. Masks are used in collision detection. I had previously thought you couldn’t read from a texture.

However after reading this article, which writes directly to the pixels in a texture, it makes me think that reading from them should be possible. I will give it a go just because I’ve not seen it done anywhere.

Picture is from the game Dominions, created with SDL.