Month: March 2020

SSSnakes – a game for the next Ebook

SSSnakes – a game for the next Ebook

Screenshot of snake gameI’ve done a snake game in the past for About. That’s the picture and today I’ve uploaded it complete with source to Github. The thing with snake is, everyone knows it, its old hat and not particularly exciting.

Back in the early 80s the same was true about Breakout games. It was a common trope for game programming, bouncing a ball off a bat to break through a wall.

But then in 1987 along came the Arkanoid game which could be best described as Breakout re-imagined.  More balls, special bricks when when hit gave different features. It made Breakout games cool again for a few years.

So Ssnakes, is my name for a re-imagined snake game.  We’ll throw away losing your life when the snake hits a wall or itself. Only if your snake runs out of space is it dead, or if it is killed by an enemy. And as it travels around it picks up food which gives it energy. You can burn this energy is making it longer, moving faster or .. spawn off a new snake! Also you can attack enemy snakes – spitting venom directly ahead or sinking fangs into an enemy body if  your snake’s head is next to it.

Having 2, 3 or 4 snakes on the go will make it a bit more stressful to control. You only lose a life when you only have one snake left in play and you lose it.

Plus instead of a plain empty arena there will be a few static objects in it.

 

Using rsyslog to log

Using rsyslog to log

logging
Image by OpenClipart-Vectors from Pixabay

I’m a great fan of logging; it helps you find out what’s happening in a program even if you can’t debug it. Linux, well Ubuntu has a service (sorry Daemon!)  called rsyslog that logs messages from all sorts of processes and it’s quite easy to use in our programs as well.

If we don’t do the next steps all the log messages will go into a file called syslog in /var/log and as this gets a lot of stuff it can grow reasonably quickly. But if you do the following steps, all logged output will instead go into

/var/log/asteroids.log.

From a terminal type the following command:

sudo gedit /etc/rsyslog.d/30-debugging.conf

Type this in and then save it (click the Save button) and close gedit.

if $programname == 'asteroids' then /var/log/asteroids.log
& ~

Now run this command:

sudo service rsyslog restart

It should return immediately and means that any logging to syslog from a program called asteroids will from now on be redirected to /var/log/asteroids.log.

Using rsyslog in a C program

Here’s a short C Program that puts a message in the asteroids file.

#include <syslog.h>
#include <stdio.h>

int main() {
    openlog("asteroids",LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);    
    syslog(LOG_INFO,"Test Message %d",1);
    closelog();
}

In a typical program you’d put the openlog statement in main() near the start and the closelog() near the end of main, and uses as many syslog() calls throughout your program as you need.

Now what I suggest you do is open another terminal and run this command before you run your main program. This will just sit there printing out each message line as it appears in asteroids.log. You can stop tail by hitting ctrl-c.

tail -f /var/log/asteroids.log

H/T to this StackExchange answer from almost 8 years ago and answer by giuspen.

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.

 

Linux E-book Progress

Linux E-book Progress

Screenshot of the chapter 28 executableMy Linux rewrite continues with progress as far as chapter 38.

This is the first Linux version of asteroids on the left and is a demo of the text writing routines and also loading images from files.

It;s drawing all digits from 0 to 99 at random locations on the screen every frame.

The number at the top is how long it takes to output the text. That value if you can’t read it is 0.000622, which means it takes 622 microseconds to output 100 numbers or 6.22 micro-seconds each.

This is the routine that does that.

void RenderEveryThing() {
	int atX, atY;

	renderTexture(textures[PLBACKDROP], 0, 0);
	startTimer(&s);
	for (int i=0;i<100;i++) {
		atX = Random(WIDTH-50) + 1;
		atY = Random(HEIGHT) + 20;
		TextAt(atX, atY, SDL_ltoa(i,buffer,10));
	}	
	stopTimer(&s);
	SDL_RenderPresent(renderer);
	frameCount++;
	UpdateCaption();
}

The most recent uploaded code version (chapter 37) lets you move the player’s ship around (press q, w or ctrl) , fire bullets (space bar), press a to see random asteroids rotating and moving round (and off) the screen. Press the b key to blow up a few asteroids with explosions and sounds. Enjoy!

Zipped up source code, graphics etc from the forthcoming Linux book can be downloaded from Github.

A tale of two diffs

A tale of two diffs

Screenshot of devart code compareI’ve used diff and merge tools since the year dot. They let you compare two files and see on what lines they differ. You can also copy individual or blocks of lines from one to the other; that’s the merge. My all-time favourite was the commercial Araxis Merge which did a three way comparison and could be controlled by COM. I did this to compare two code bases.

Ten years earlier code for Base Metals (commodities trading) had been forked from Oil Trading software. There were ten years of changes to both sets of code and my job was to merge them back into one code base. I wrote a program to walk Araxis Merge through all folders of both code sets and out-put the differences, Then I could start merging where they differed. It still took about two months but I couldn’t have done it as quick without Araxis.

However most of us don’t have access to Enterprise tools, so here are two alternatives. The first is Devart’s Code Compare (that’s the image above) and the second is a free Extension for Visual Studio Code called Diff & Merge. I’ve added both to the Links to C utilities page.

Some useful tips for Visual Studio Code

Some useful tips for Visual Studio Code

The more I use Visual Studio Code, the more I like it and it is definitely one of the slickest pieces of software running on Linux. But I’ve found a few minor problem that are easily fixed so before I forget the fixes, here they are:

UTF-16 Instead of UTF-8

You copy a file in from somewhere but when you try to compile it you get: fatal error: UTF-16 (LE) byte order mark detected in ‘/home/david/Projects/Asteroids/asteroids.c’, but encoding is not supported.

Fixing this is quite easy; you just need to change the file type from UTF-16 to UTF-8. Visual Studio Code shows the file details at the bottom:

File details for Visual Studio code

Here you can see it’s UTF-16 LE. Click on UTF-16 and you’ll get a popup menu. Click Save with Encoding and you’ll get a list of Encodings. Just pick UTF-8 and the problem is solved.

Changing the type of a Visual Studio Code file

You want to save or copy the C/C++ JSON files

But you can only do it by copying and pasting when its in the editor. The problem is they are in a hidden folder under the main folder. Visual Studio Code’s C/C++ extension uses these to hold build, debug etc. configuration details. It’s handy saving them out with source files but a bit slow doing it individually via the editor.

Visual Studio Code uses the main folder (I call mine Projects) and the four JSON files are in ~/Projects/.vscode

On Linux any folder that starts with a . is hidden.

If you use File Explorer, you can tell it to show hidden folders and files by clicking the top button (highlighted) then ticking the Show Hidden Files box. The three folders that were hidden including .vscode are now visible and you can browse, view, copy files etc.

Showing the hidden Files setting

New page added to Website

New page added to Website

Word Cloud
Made with WordArt

I thought it about time to add a list of curated C utilities such as compilers, IDES etc. So you’ll see that bar under the title now includes Links To C Utilities.

One of the included links is to Cheerp which is a C/C++ compiler that can output WebAssembly. One of my goals is to add a WebAssembly chapter to my first EBook, after the 2nd one on Linux is done.  I want to play my asteroids game in the browser.

I have used EmScriptem to do this but I’d like to see what other tools are available.

My next Book – Match three

My next Book – Match three

I’ve been thinking about doing a 3rd book – something like ‘More C Games, design and programming’ which would have three games, each with a design and then implemented with explanations and bits of source code and all on Github.  The first game is possibly going to be a Match Three game.

Match tree gameMatch Three games have been around for the best part of a decade and have a basic mechanic of swapping two adjacent pieces to make a line up of three, four or five pieces which get removed.

What makes it more challenging and interesting is the almost limitless number of mechanisms you can build on. For instance when you clear four or five you get special items that when swapped with another special item do something interesting. Or could be you have to get a set of special items and so on.

Or you might have special levels where you have to clear all of one particular shape within a time or Boss levels where the baddy is continually adding hard to remove pieces that clog up the game, or you might have a rotate button that flips the board 90 degrees so you can get rid of hard to remove pieces by having them drop into special buckets beneath the board.

Now I just have to come up with two more games. Suggestions welcomed!

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!

More on function pointers

More on function pointers

A function pointer is a pointer to a function, i.e. it’s a variable (a pointer) but instead of pointing to some data, it is assigned to a function. Most importantly, the compiler checks that the function you are assigning is compatible to that pointer. This is so, as I discussed earlier that when the function is executed, it correctly retrieves any parameters.

Here’s how you create a function pointer. Let’s start with a function that adds 1 to the input value.

int getValue(int x) {
    return n + 1;
};

This passes in x and returns an int. Let’s create a pointer to this function and this is the full program.


#include <stdio.h>

int getValue(int n) {
    return n + 1;
}

typedef int (*getValueFn)(int);

int main()
{
    getValueFn f = &getValue;
    printf( "Value of getValue = %d\n",f(1));
}

It’s as simple as that. The complicated bit is turning the function signature into the typedef. Start with the function name. Put it in brackets and add a * at the start, and make the name different to the function you are assigning. It’s a new type. So getValue becomes (*getValueFn).

Now add on the return type at the start int and the parameters at the end (int n), but throw away the name n, we only need the type and you get int (*getValueFn)(int);

Finally add typedef, cook for 30 microseconds and you’re done! In the line getValueFn f = &getValue;
I’ve declared an instance of the type f and assigned to it the address of getValue. That gets called with a value f(1) and in this case returns 2.

It’s also good practice to check that the instance variable is not null before you call it.