Author: David

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.

Function pointers in C

Function pointers in C

The one thing worse for beginners than pointers is … function pointers. A normal pointer holds the address of another variable whereas a function pointer holds the address of some code.

But before I delve into the complexities of function pointers, you have to understand a little bit about functions. A function is defined, not just by what it does but the values you pass in and get back from it. Here are a couple of examples.

int add(int b,int c) {
  return a + b;
}

void DoSomething(int value) {
  //
}

The code generated by the compiler has to pass in the parameters and usually does it by pushing values on the stack or in registers. In the code for the function, the first thing it does it fetch the parameters. So when you use a function pointer, according to the definition of that function pointer, the compiler will generate code in the function to extract parameters.

I’ll look at the syntax of function pointers tomorrow; it’s always the complicated bit, probably the most complicated bit but it dos give your program a bit more flexibility.

I’m now using the Prismatic plugin. Much nicer listing with indentations!

Using recursive fill to count maps

Using recursive fill to count maps

Terrain hexagonsIn the Empire game (yes, just one last mention!) during the map generation the program counts up the size of individual islands and sea areas. This is don by recursion and quite useful. Otherwise, the usual place you see recursion mentioned is in calculating factorials and Fibonacci sequences.

The map struct holds not only the terrain type and other information but a continent number. This is set initially to 0.  After the land and seas have been generated, the program picks a random land point on the map (just keep picking a random location until it has land with a continent number of 0).

It then counts by calling itself 8 times. It calls itself recursively at location y,x with directions (y-1,x-1) that’s NorthWest, (y-1,x)  and so on round to West (y,x-1).  But it only does it as long as each of those locations is land type with a continent number of 0. And as it does it, it sets the continent numbers in each location to 1 for the first continent and so on.

This recursive algorithm means that every contiguous land location gets reached. A similar thing is done with seas and lakes but you have to be careful that the stack is large enough.

void FillIn(int x,int y,int locis) {
  if onMap(x,y) {
    if (locis==map[x][y].locis && map[x] 
 [y].continent==UNALLOCATED) { 
      map[x][y].continent=numconts;
      allconts[numconts].count++;
      FillIn(x-1,y,locis);
      FillIn(x+1,y,locis);
      FillIn(x,y-1,locis);
      FillIn(x,y+1,locis);
      FillIn(x-1,y-1,locis);
      FillIn(x+1,y-1,locis);
      FillIn(x+1,y+1,locis);
      FillIn(x-1,y+1,locis);
    }
  }
}

This is used for both land and sea, so locis can be either. It’s an efficient algorithm and quite quick.

Those graphics? They were the initial hexagon graphics…