Category: SDL

Problems debugging SDL2 with Visual Studio Code

Problems debugging SDL2 with Visual Studio Code

500 numbers blitted to screen by SDL2So my demo program runs fine when I run it from the terminal. It creates a SDL Window and blits lots of numbers, but if I try to start it in the debugger, it gets to this function and fails in the SDL_CreateWindowAndRenderer.

void InitSetup() {
	srand((int)time(NULL));
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, SDL_WINDOW_SHOWN, &screen, &renderer);
	if (!screen) {
		LogError("InitSetup failed to create window");
	}
	SetCaption("Example Two");
	LoadTextures();
}

And in the Debug Console I can see two of these:

@”error: XDG_RUNTIME_DIR not set in the environment.\r\n”

followed by my error message InitSetup failed to create window.

I’ve looked online and there’s one or two mentions. Now possibly it might be because I’m running Ubuntu 18.04 LTS under Hyper-V Manager.  I’ll try this on a laptop where I’ve installed the same version of Ubuntu on and see if the same thing happens.

 

The mighty Blit

The mighty Blit

Showing an asteroid being targetted by the player's shipWhat makes possible all of the fast graphics in SDL2 is really one instruction.

SDL_RenderCopy – The link goes to the SDL Wiki.

This copies part of a texture into video RAM (aka VRAM). You must specify which texture is to be copied, a rectangle into the source and a rectangle into the destination VRAM.

So what is a Texture? In SDL2, it’s a structure that manages an area of VRAM. At the start of the game, image files are uploaded into Textures, the file bits are copied from disk and stored in an area in VRAM.

Every frame, a background image (another texture) is copied to the screen area. Then all moving objects are rendered into this area by calling SDL_RenderCopy for each object. The entire object (be it player ship, bullet or asteroid) is then rendered onto the screen area at the correct point. This is sometimes called blitting or more accurately bit blitting; blit is shorthand for bit block transfer.

A rectangle is just a struct holding four ints. The first two ints are the x and y positions and last two are width and height.  The player’s ship consists of a graphic 64 pixels high by 16 x 24 (=1,536) pixels wide. That’s 24 images, each rotated by 15 degrees from the previous one. So the source rectangle is always x = rotation (0-23) x 64, y = 0 and both height and width are 64. Remember, the source x,y is relative to the source texture which is 1536 wide by 64 high.

The ship rotations start with 0 facing up, so the ship on screen is at rotation 18 (Facing Left) , so  x = 1152.

To make sure rendering is a smooth process and there is no tearing of the images, the screen VRAM is always off-screen when the objects are rendered into it. Then after all objects have been rendered (a posh word meaning copy!), the display is toggled so that the bank of VRAM that was off-screen is now on-screen i.e. visible and the other bank is now off-screen.

Objects are always rendered into off-screen VRAM and the flipping is done by a call to this SDL routine.

SDL_RenderPresent

When you create the renderer, you can specify whether SDL_RenderPresent is synced to the video card vertical refresh signal. If it is, then the display will only render 60 frames per second. If you don’t sync then you can have frame rates up to several thousand times per second. I once achieved 5,000 fps, because there was very little processing going on.  However your video card probably doesn’t refresh any faster than 60 fps so it’s a bit pointless!

Other ways to time code

Other ways to time code

Stop Watch photo from Pixabay
Image by Free-Photos from Pixabay

As well as the hr_time code that I used in discussion of sdldemo SDL itself provides some other ways to time. If you are happy with millisecond level accuracy of timing, just call this function which returns an unsigned 32-bit (i.e. 0- 4 billion) giving the number of milliseconds since the SDL library was initialised.

SDL_GetTicks()

The link goes to the Wiki page on libsdl.org  for SDL_GetTicks().

As always, call it twice, once to get the start value and once to get the stop then subtract start from stop to get the elapsed time in milliseconds..

For some operations this can be easier to use. A frame is 16.666666 milliseconds so if your code runs in less than 16 milliseconds, it’s not going to cause problems. In my original Windows code, it ran is a fraction of a millisecond. Compiled C code really is fast and helped because the GPU is doing most of the donkey work!

There’s also a higher accuracy timer. This I guess is just a wrapper round the system call I call in hr_time.

Uint64 SDL_GetPerformanceCounter(void)
Which I haven’t used yet but which I guess returns a processor clock count. To measure time you need to call it twice (start and stop values as before) then divide by the frequency value returned from a call to

Uint64 SDL_GetPerformanceFrequency(void)

My computer returns a clock frequency of 3,500,000,000 clocks per second but the actual value is irrelevant just divide ((stop – start)/ frequency) to get the elapsed time in seconds.

Added Empire 9 to the C Games repository

Added Empire 9 to the C Games repository

Splash screen from the Empire gameBack in 2012/2013 I was writing the C/C++/C# column for About.com and I was doing games tutorials with SDL. This is an Empire type game, much like the Z80 game I mentioned in yesterday’s post except coded in C and with hexagons instead of squares.

It is not complete but includes a working map generator and a simple GUI that I devised based on a very crude OOP type of coding using function pointers and macros.

I’ve put it on the C Games repository and In the empire9src.zip (in the aboutempire.zip)  file you’ll see sdlgui.h and c. These implement it and (years ahead of Flutter and Dart!) it redraws the GUI at 60 fps.  The controls are built in a linked list of sdlcontrols.  This is a sdlbase which is the base for all controls.

#define sdlbase enum controltype ctype;\
int x,y,width,height,color,clickable;\
SDL_Color textcolor;\
void (*pRender)(struct sdlcontrol * self);\
void (*pFree)(struct sdlcontrol * self);\
void (*pClick)(struct sdlcontrol * self);\
void (*pPreClick)(struct sdlcontrol * self);\
struct sdlcontrol * nextcontrol

The four void (*..) are the function pointers. The pRender function draws the controls, pFree frees it up.. pClick handles clicks and PreClick provides extra functionality.

struct sdlcontrol { sdlbase; };
typedef struct sdlcontrol * psdlcontrol;
typedef char * pchar;

struct sdlbutton {
  sdlbase;
  pchar labeltext;
  int isDown;
  int countDown;
};

struct sdllabel {
  sdlbase;
  pchar labeltext;
};

Those are the definitions for sdlbutton and sdllabel and all controls have sdlbase (Everything in the big macro) and additional info.

This is the code that rendered a label.

void RenderLabel(psdlcontrol self) {
  int result,x,y;
  char buff[60];
  struct sdllabel * label= (struct sdllabel *)self;
  SDL_Rect rect = {(Sint16)self->x,(Sint16)self->y,(Uint16)self->width,(Uint16)self->height};
  x= self->x;
  y=self->y;

result=SDL_FillRect( screen, &rect, self->color );
  sprintf(buff,"%s",label->labeltext);
  ttf_print(x+2,y+2,buff,self->textcolor);
}

So every frame, the program would render all controls to the off-screen buffer by walking the linked list of controls and calling the pRender pointer for each. For buttons this would include a simple animation to show the button being clicked down and then released etc.

If you’ve ever wondered how a GUI is implemented take a look at the code. The sdlgui.c is less than 600 lines but manages to do panels, buttons, labels, checkbox, listbox and images.

Why I like C for creating games

Why I like C for creating games

Dark Empire ZX Spectrum gamePart of the reason is SDL which is a wonderful library and whose potential I have barely touched. I used to be an 8-bit games developer back in the 1980s, writing games for CBM-64, ZX Spectrum, MSX and Amstrad CPC-464.

I wrote those games in Z80 and 6502 assembly language. Thee were no libraries, no frameworks, no debuggers (lots of print statements) and when I first started, I wrote the games on the machines themselves.  If you got a crash, the computer would hang or reset and everything had to be reloaded from tape usually.

True story, I started by learning 6502 and when I came to learn Z80 I did it by writing a 6502 cross-assembler in Z80.  6502 is a very simple CPU with just 69 instructions. I was given the Z80 source for a text editor (Zen) and built the 6502 assembler into it.

Things gradually improved, we got development machines so we just needed a small loader on the target machine that downloaded the machine code from the development machine. That speeded up development enormously.

C is a very simple language and SDL can shift pixels very rapidly. I wouldn’t necessarily choose C for 3D games but for 2D arcade games, I think C is nearly perfect. With SDL, once you learn how to initialise it, load graphics (from disk to GPU), blit shapes and flip the screen you are 90% of the way there.

That image was one of the games I wrote in 1987, an Empire “Conquer the shrouded world” game where you are playing against a computer player. There’s six minutes of gameplay on youtube.

SDL on Linux

SDL on Linux

In my forthcoming ebook, which is the Linux equivalent of the first one I use Visual Studio Code (VSC) as the IDE to develop along with the Microsoft C/C++ extension. I’m using the SDL2 library for fast graphics and Clang as the compiler.

Thankfully Microsoft have documented most of the process of using Clang with VSC, albeit on a Mac. I’m using Ubuntu but it’s mostly the same.

Before I could configure SDL I had to add it and I never realised about apt-cache on Ubuntu (and Debian). The command

apt- cache search libsdl2

Outputs this, showing what's available.
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

So a quick

sudo apt-get install libsdl2-dev

Installed 73 MB of files including all the header files. I used the files app to search for SDL files and it found a folder SDL2 in /usr/include.

And all I needed in my program was

[perl]

#include <SDL2/SDL.h>

[/perl]

And I had to add “/usr/include/SDL2/” into the includePath section of c_cpp_properties.json and “-lSDL2” into the args section of tasks.json. These two JSON files are included in C/C++ projects in VSC.

At that point I could compile and run my first SDL program on Ubuntu. It throws 10,000 random sized coloured rectangles onto the screen

The first SDL demo program