Category: Source code

Comparing MSVC vs Clang

Comparing MSVC vs Clang

Listing of some C codeI originally created Asteroids for Windows using Visual Studio 2017 Community Edition. Since then I’ve started the Clang version on Ubuntu and there haven’t been too many differences but there are just a few so in this post I’ll list what I’ve found so far.

Include Paths

On Windows, I was able to get away with #include <SDL.h> but on Linux, I’ve had to include the path so it’s #include <SDL2/SDL.h>. This was probably because I included the full path in the MSVC configuration.

Link Failures

The asteroids.c code in chapter 29 uses sin and cos for the first time and the linker was unhappy with that. So in tasks.json, I’ve explicitly had to add it into args, along with SDL2 and SDL2_image,

            "args": [
                "-g",
                "${file}","${workspaceFolder}/Asteroids/hr_time.c",
                "-o",
                "${fileDirname}/asteroids",                
                "-lSDL2",
                "-lSDL2_image",
                "-lm"
            ],

That “-lm” does that for maths.

Safe functions

Microsoft has its own set of safe functions many with an _s and extra length parameter.

On Linux, there don’t seem to be so many.

So sprintf_s on Windows becomes snprintf.

fopen_s just becomes standard fopen

linux/time.h

As well as time.h in the includes, I needed to add linux/time.h as well.

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.

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.

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…

About that Empire Map Generator

About that Empire Map Generator

The Circle data used in the Empire map generatorThis post refers to the c sources in the AboutEmpire.zip file in the Github C Games repository.

I first developed the algorithm in 1986 and wrote it in Z80 assembler. It was then rewritten in Turbo Pascal and used in both the Warlord and Quest postal games that are still run by kjcgames.com. It has been rewritten in C in the Empire game. So how does it work?

The idea is to generate continents. Typically between 2 and 3 continents between 1500 and 1800 squares in total on an 80 x 50 map. The map is made up of land squares and sea squares but starts out blank.

First I throw down 30 land points and 50 sea points. I.e. the program randomly picks points.

void AddPoints(enum loctype lt,int numpoints) {
  int i,x,y;

for (i=0;i<numpoints;i++) {
  do {
    x=Random(MAPWIDTH-40)+20;
    y=Random(MAPHEIGHT-40)+20;
    }
  while (map[x][y].locis != lctnull);
  map[x][y].locis = lt;
  genpointsx[pointindex]=x;
  genpointsy[pointindex++]=y;
  }
}

Some of the constants and the loctype enum are defined in common.h. The map itself is built up by adding extra points to each land point and sea point. I’ve defined an array of points in data.h that has 35 rings of points.  Well they’re more squares than rings.  That text file shown in the image is what these rings are derived from. I’ve translated all the points into 35 sets of X,Y offsets in data.h.

These points get added in layers. Starting with the first layer which has 8 points in it around the centre – that’s the A’s in the image, the next layer has 12 B’s and 4 C’s in it and so on.

But I only add a land or sea point if the spot its going into is empty; once it is defined as sea or land it can never change. So sea points and land points bump up against each other as these ‘circles’ expand and you get coasts and all sorts of interesting shapes. After that I fill in all empty spaces as sea, and the count up the connected land and sea squares.

If there are any tiny seas, i.e. less than 5 squares area they get filled in as land and any land point that isn’t surrounded by at least 3 other land point gets sunk. Then so long as there are the right number of continents and the total land squares is between 1500 and 1800, the map is accepted. If not a new one is generated. Adjusting the number of initial land and sea points helps to generate more acceptable maps.

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.

Update on the sdldemo

Update on the sdldemo

I’ve redone the hr_time,h and c files and am much happier with them now and also updated the code on github.  Apparently the reason for having <linux/time.h> as well as <time.h> and including both is because the <time.h> is set in stone and any additions have to be done as an extra include file. This is what hr_time.h looks like now.

#ifndef _timeh
#define _timeh 1
#include <linux/time.h>
#include 

struct _times {
  struct timespec start;
  struct timespec stop;
};

typedef struct _times stopWatch;

void startTimer(stopWatch *timer);
void stopTimer(stopWatch *timer);
double diff(stopWatch *timer);

#endif

 

That Clang C compilation

That Clang C compilation

I spent about five hours trying to get the timing code to compile before I got it compiling and working. Now I’m used to the concept of include guards in C. Those are the #ifndef that you see like this:

#ifndef _timeh
  #include <linux/time.h>
  #define _timeh 1
#endif

But in the hr_time.c file these include guards are on steroids. Not only did I need to include <time.h>, I also had to include <linux/time.h> but with a couple of extra #defines in there. It doesn’t seem right and wasn’t needed with the Windows version.  I’d welcome any comments on this.

#ifndef _timeh
  #include <linux/time.h>
  #define __timespec_defined 1 
  #define __itimerspec_defined 1
  #include <time.h>
  #define _timeh 1
#endif

The sdldemo program with timing whown in the window caption.Without these, I’d get compile errors like __timespec redefined errors.

I’ve uploaded the source files and Visual Studio Code JSON files for this in the file asteroids_ch25.zip in the new repository for the Learn C on Linux Ebook

So feel free to try it. The only difference between this and the version shown in an earlier post is the time (in the window caption) to draw all 100,000 rectangles,  You’ll need to install SDL2 if you want to compile and run the program.