Category: Source code

Quake II – still a favourite

Quake II – still a favourite

Quake II screenshotOh I do play much newer games such as Far Cry 5 which I’ve completed recently but Quake II was a favourite of mine back in 1997 when I bought it. I’m more of a Quake than a Doom person. Unfortunately for me, my then PC couldn’t run it. It was only two years old as well.  But I got a new PC in 1998 and that played it just fine. I’m not saying I’m a saddo but I can play it through on the hardest level without losing a life.

The reason I mention it because of an article I came across that described the different ID Tech Game engines and the games made with each engine. All have been open sourced (Up to ID Tech 4). Quake II was written using the ID Tech 2 engine itself written in C and assembler.

For some reason the link to Quake II source code is wrong in that article but you can find it on GitHub. In one of 18 of ID Tech’s 18 repositories there.

If you are interested in downloading and trying to understand the Quake II source code, I strongly recommend you read Fabien Sangard’s walkthough of the code.

Interesting C Program- What do you think it does?

Interesting C Program- What do you think it does?

Question mark
Image by Gordon Johnson from Pixabay

This is a past IOCCC winner. It needs a #include <stdio.h> to compile.

#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_
            _-_-_-_
}

When I compiled and ran it in Visual Studio it output 0.25 which is not the value it’s intended to output. That said it also messed up the formatting.

I can’t recommend this formatting BTW but then that’s the idea, to obfuscate i.e. disguise its purpose! So have you figured it out yet? I put the image on the right so as not to break up the program listing…

How to calculate how effective a Riffle is

How to calculate how effective a Riffle is

deck of cards
Image by Hebi B. from Pixabay

In my previous post I mentioned about writing a program to determine how effective a riffle shuffle was. So here’s the code.

How it works

I’m using an array of 52 chars to hold the deck. I’m only interested in the card’s position in the deck so each card is initialised with a value in the range 0-51. I’m using three other similar sized arrays.

  • tempCards are used purely for doing the riffle.
  • distances are used to calculate the maximum distance the card moved
  • startPos tracks the cards starting position 0-51 before doing lots of rounds of riffles.

The program starts by picking up ( as a parameter) how many rounds you want it to run. It defaults to 10 if no value is input.

It then clears distances and inits cards. In each round, it starts by storing card positions in startPos. It then does seven riffles and works out how far a card has moved. If it has moved more than before (in distances) it stores it in distances.

DoRiffle works by indexing through the two 1/2 deck piles taking a card from each and a 50:50 random chance determines which of the two cards goes into the shuffled deck first and then second.

Here’s the listing.

// riffle.c by D. Bolton (C) 2020 Learncgames.com - TYou are free to redistribute but please keep this line in

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// #defines
#define MAXROUNDS 10
#define NUMRIFFLES 7
#define NUMCARDS 52

// variables
int NumRounds;
char cards[NUMCARDS],tempCards[NUMCARDS],startPos[NUMCARDS];
int distances[NUMCARDS];
time_t t;

// functions

// Convert string to int calling strtol
int GetIntArg(char* str) {
	char* ptr;
	return strtol(str, &ptr, 10);
}

// Merges two cards a and b. 50:50 chance that a above b or other way
void DoRiffle() {
	// Copy cards into tempCards
	memcpy(tempCards, cards, sizeof(cards));
	// Merge each pair of cards tempCards[i] and TempCards[i+26]
	int cardIndex = 0;
	for (int i = 0; i < NUMCARDS / 2; i++) {
		if (rand() % 2) {
			cards[cardIndex++] = tempCards[i];
			cards[cardIndex++] = tempCards[i + 26];

		}
		else {
			cards[cardIndex++] = tempCards[i + 26];
			cards[cardIndex++] = tempCards[i];
		}
	}
}

// Works out how far cards have moved, added to distances
void CalculateDistances() {
	for (int i = 0; i < NUMCARDS; i++) {
		int moved = abs(cards[i] - startPos[i]);
		if (moved > distances[i])
			distances[i] = moved;
	}
}

void DoShuffles() {
	// Clear distances and init cards
	for (char i = 0; i < NUMCARDS; i++) {
		distances[i] = 0;		
		cards[i] = i;
	}
    // do Numrounds  rounds
	for (int round =0;round<NumRounds;round++){
		// Mark where the card starts
		for (char i = 0; i < NUMCARDS; i++) {
			startPos[i] = cards[i];
		}
		// Do seven riffles
		for (int i = 0; i < NUMRIFFLES; i++) {
			DoRiffle();
		}		
		CalculateDistances();
	}
	int furthest = 0;
	for (int i = 0; i < NUMCARDS; i++) {
		printf("Distance[%d]=%d\n", i, distances[i]);
		if (distances[i]> furthest) {
			furthest = distances[i];
		}
	}
	printf("furthest moved is %d\n", furthest);
}


int main(int argc, char* argv[]) {
	srand((unsigned)time(&t));
	if (argc ==1 || argc== 2) {
		NumRounds = MAXROUNDS;
		if (argc == 2) {
			NumRounds = GetIntArg(argv[1]);
			printf("Numrounds = %d\n", NumRounds);
		}
		DoShuffles();
	}
	else {
		printf("Please supply 0 or 1 arguments e.g. riffle 60\n");
	}
}

Even with ten rounds I’ve seen cards move 51 positions. With 5,000 rounds all cards but one moved by 51 and one by 50.

MonoGame – How to make a clickable button

MonoGame – How to make a clickable button

Clear Button with one card clickedI’m using this in Android games but the principle applies to any MonoGame game. Here clickable and touchable mean the same.

You need three things to make something clickable.

  1. The area. For simplicity sake this will always be rectangular.
  2. The Action. When you touch (or click it), you want it to run code.
  3. An id of sorts. If you have multiple buttons etc, you meed to distinguish them.

We’ll use an int for 3. Use const ints to give it a name rather than being a magic number.

 

When you click whatever, the Event should include the ide so let’s define the event Type first.

public class ButtonClickedEventArgs : EventArgs
{
    public int Id { get; set; }
}

Not rocket science is it!

Now lets define a ClickButton class.

public class ClickButton
{
    public int Id { get; set; }
    public Rectangle TouchArea { get; set; }
    public Action<object, ButtonClickedEventArgs> AnAction { get; set; } = null;

    public ClickButton(int id)
    {
        Id = id;
        TouchArea = new Rectangle(0, 0, 0, 0);
    }
}

Again nothing too complicated. There’s an int Id which which is set in the Constructor, a Rectangle TouchArea and an Action which is defined to include our ButtonClickedEventArgs.

Here;’s some example code. I’ve defined a graphic for a Clear button in my game and this is loaded as usual in the LoadContent().  I’ve also defined the button in Class declaration.

ClickButton ClearButton;

In LoadControl(), this is also initialised. Here’s it’s two line. It could be done in one, by altering the constuctor.

ClearButton = new ClickButton(1);  // 1 is the id
ClearButton.AnAction += ClearCards;

ClearCards is a method that does something when the button is cleared. This matches our Event handler as it has the usal two parameters for an Event except the args is our ButtonClickedEventArgs.

private void ClearCards(object sender, ButtonClickedEventArgs args)  {
   // all the code here, not shown
}

Where is the TouchArea defined?

So are we all setup ready to rock’n’roll? Well not quite. We haven’t said exactly where the TouchArea is. That of course depends on where we draw the button. In my game, the ClearButton moves across. It’s absent when all six cards are present but as soon as one has been touched and a back card touched to move it, the Clear Card appears. In the top image you can see it to the right of the five top cards. I had clicked the seven of clubs when it was in the top row then the first back on the top row of the three rows.

For my next move I clicked the ten of diamonds and the second back on that first row where the ten of diamonds no wit. It now looks like this and the Clear Button has moved over.  If I click the Clear button it will move the seven clubs and ten diamonds back to the top row and replace them in the first row with backs.

Second clickTo set the TouchArea of the ClearButton, I do it in the Draw method. It’s as simple as this:

if (hand.Count < 6) // Draw ClearButton on end
  {
    spriteBatch.Draw(clearButton, new Rectangle(x, y, cardWidth, cardHeight), 
        new Rectangle(0, 0, cardWidth, cardHeight), Color.White);
    ClearButton.TouchArea = new Rectangle(x, y, cardWidth, cardHeight);
  }

There’s actually a small bug visible. When you click a top row card, the game highlights it by reducing its opacity to 0.5. If you look at the ten of diamonds, you can see it still has that reduced opacity; it should have been restored to 1.0 when it was moved to the first row. The same is true in the top picture for the seven clubs! Easily overlooked but just a one-line fix.

Some Touchy Code

The very last bit is to fire touch detection and this is done in the Update() method. When you touch the screen, calling Touchpanel.GetState() returns a collection of touches. This is my code. It cycles through the touches collection, gets the X, Y position of each touch and adjusts it to match the virtual screen coordinates. (Drawing to a virtual screen means this looks the same on every Android irrespective of its physical screen sizes and resolution).

touchState = TouchPanel.GetState();
foreach (var touch in touchState)
{
   if (touch.State == TouchLocationState.Pressed)
    {
         var x = touch.Position.X / xRatio; // adjust for virtual screen
         var y = touch.Position.Y / yRatio;
         CheckClickedTop(x, y, hand);
         if (pickedCard == null) return; // no point checking further...
         for (var i = 0; i < 3; i++)
            CheckClickedBottom(x, y, commonCards[i], true);
            if (hand.Count == 6) continue; // All top cards so no ClearButton visible
            // Check if Clear button
            if (ClearButton.TouchArea.Contains(x, y))
              {
                  ClearButton.AnAction(ClearButton, new ButtonClickedEventArgs() { Id = ClearButton.Id }); 
              }
      }
}

The top cards are held in a class called hand and the bottom three rows are held in CommonCards[3] each of which is a hand. The CheckClicked.. methods cycle through the cards in the hand comparing coordinates to see which card if at all has been clicked. If it has it calls the AnAction Event for the one clicked. The very last if shows how this works to check if the ClearButton was clicked. I’ll simplify this code by moving it into a ClickButton method.

Using heap memory with malloc

Using heap memory with malloc

For some reason malloc seems to confuse new programmers but it’s very straightforward.  I didn’t use it or even talk about it in the ebook. Memory allocation is not something you want to be doing in a game loop, running 60 times a second. All the memory that was ever used in the asteroids game was for text strings, variables and arrays and you don’t have to explicitly allocate any memory for those.

When you have a program that needs to allocate and free memory, like say a compiler or text editor then you grab a block of RAM using malloc.  You have to specify how much RAM you need and you must type cast it, because malloc return a void *.

Here’s an example. The image shows the output in the Visual Studio debugger.


#include <stdio.h>
#include <stdlib.h>

char* ptr[10];
int main() {
	for (int i = 0; i < 10; i++) {
		ptr[i] = (char *)malloc(1000);			
		char* aptr = ptr[i];
		for (int j = 0; j < 1000; j++) {
			aptr[j] = i + 64;
		}
        }
	for (int i = 0; i < 10; i++) {
		free(ptr[i]);
	}
}

DEbugger showing array valuesThis is what the Visual Studio debugger shows just before the final loop that calls free.

It has allocated 1000 bytes of memory for each of the ten char * in ptr[] and then fills it with 1000 each of the ASCII values 64..73 @

Finally, it frees up the memory using free. For every malloc, there should be a corresponding free or else your program will develop a memory leak.

 

 

Do you use assert in your code?

Do you use assert in your code?

assertIt’s a macro that checks an expression, and if that expression isn’t true (.e. non-zero) it outputs a message and halts the program.

Here’s an example.

#include 
#include 

int main() {
	int x = 0;
	assert(x != 0);
	printf("It is the end");
}

Because x is 0, it triggers the assert and the program never reaches the printf statement. It’s a bit of a crude tool. In other programming languages like C++ or Delphi it raises an exception which can be handles but C of course does not have exceptions.

My own preference is to check the value for example making sure a pointer is not null and nthen displaying an error but other programmers prefer to use assert and have it kill the program if things go wrong.

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.

Goto is considered bad programming in C but

Goto is considered bad programming in C but

goto exit signThere is one case for using goto when you have nested loops and you’d like to jump all the way out. The goto statement was very popular in BASIC but often resulted in programs being like spaghetti with gotos all over the place.

Here’s a contrived example where I have used a goto.

#include <stdio.h> 

int array[10][10][10];
int main() {
    // Populate array
    for (int y=0;y<10;y++)
      for (int x=0;x<10;x++) 
        for (int z=0;z<10;z++) {
          if (array[x][y][z]==0)
            goto exit;
    }
exit:;
}

In my C programs, for-loops are the most popular followed by while-loops, do-while loops and gotos are hardly ever used at all.

My trial by Windows Defender is over

My trial by Windows Defender is over

EXpression opf irritation!
Image by prettysleepy1 from Pixabay

There’s nothing wrong with this short C program, which is in my ebook and which I was compiling to test it.

#include <stdio.h>

int main() {

	int a = 10;
	for (int i = 0; i < 5; i++) {
		a--;
		printf("i = %d\n", i);
		if (a == 8) break;
	}
}

Nothing wrong, except Windows Defender went ape-shit every time I compiled it! Talk about annoying. This was in Visual Studio. I’m fairly scrupulous about keeping nasties off my PC but if you believed Defender I had some weird Trojan.

I did a search and found an unanswered question on StackOverflow from someone with the same reported trojan. So I answered it!

Thankfully there was an update from Windows Defender last night and they have quashed this false positive. If the worst came to the worst, I’d hop on to Hyper-V and compile it in Ubuntu or Raspberry Pi OS with clang. But still a bit irritating!