Category: C

Array vs pointer in C

Array vs pointer in C

Grid array
Image by Anja🤗#helpinghands #solidarity#stays healthy🙏 from Pixabay

A common pattern (I use the word loosely) in my C programs is to have an array of structs to hold things like asteroids and bullets in the game. There are two ways to process an array:

  1. As an array e.g. asteroids[index].
  2. As a pointer to an individual array element. Asteroid * pAsteroid = &(asteroids[index]); then refer to pAsteroid ->

One of the tents of software design though not that often said is that the easier the code is to read, the easier it is to understand. Programmers spend a lot of time reading code. Anything that lightens the cognitive load is good. I suspect it might also be faster, but not by a great deal.

Of course pointers make some programmers nervous. To me though they simplify the code. There is however another way to simplify the code. Use #define so you might have something like this:

#define table asteroids[index]

So everywhere you have a asteroids[index]., you put in table instead.
This for example from Chapter 36 DrawAsteroids()

	for (int i = 0; i<MAXASTEROIDS; i++) {
		if (asteroids[i].active) {
			numAsteroids++;                    // keep track of how many onscreen
			int sizeIndex = asteroids[i].size; // 0-3
			int asize = sizes[sizeIndex];      // asteroid size 280,140, 70,35
			target.h = asize;
			target.w = asize;
			asteroidRect.h = asize;
			asteroidRect.w = asize;
			asteroidRect.x = asize * asteroids[i].rotdir;
			target.x = (int)asteroids[i].x;
			target.y = (int)asteroids[i].y;

Would become

	for (int i = 0; i<MAXASTEROIDS; i++) {
		if (table.active) {
			numAsteroids++;                    // keep track of how many onscreen
			int sizeIndex = table.size; // 0-3
			int asize = sizes[sizeIndex];      // asteroid size 280,140, 70,35
			target.h = asize;
			target.w = asize;
			asteroidRect.h = asize;
			asteroidRect.w = asize;
			asteroidRect.x = asize * table.rotdir;
			target.x = (int)table.x;
			target.y = (int)table.y;

What do you think?

My encryption code is now live on GitHub

My encryption code is now live on GitHub

Crptography Word list
Image by tumbledore from Pixabay

I developed Pivot initially on Windows, (a Linux version will follow) though the differences are fairly small. I used the Windows _sopen_s for reading and writing files.  There shouldn’t be too much differen otherwise, though I guess I’ll find out when I compile it on Ubuntu or Raspberry Pi.

The program itself is around 450 lines of C in just one file. It can encrypt around 6 MB/s on my five year old i7 5930K PC and decrypt at around 10 MB/s.

If anyone could try this, I’d be very happy. It has one minor issue that I will resolve. Because it processes files in blocks of 64 bytes, it tends to round the output file when decrypting and adds a few 0s on the end. I will get it sorted

I’ve given it a very liberal MIT license, you can do what you want with it. Instructions on using it are provided on that link to GitHub.

This BTW is the encryption code at the heart of it.

        int bit = 128;
        for (int bi = 0; bi < 8; bi++) {
            for (int b = 0; b < NUMSTREAMS; b++) {
                dataout[b] = (dataout[b] >> 1) | (data[b] & bit);
                data[b] <<= 1;
            }
        }
             
        // Now alter the order of bytes according to the key
        for (int i = 0; i < NUMSTREAMS; i++) {
           data[i] = dataout[_key[i]];
        }

The first double for loop slices 64 bytes into 64 bit streams. It’s pivoting the bits if you like, hence the name. The second for loop is what does the donkey work of encrypting it. It uses a 64 byte key (made up of 64 numbers 0-63- shuffled). As there are 1.2688693e+89 different ways of arranging these 64 numbers, if you lose the key it might take you a while to brute force it!

So I believe that it is an original encryption algorithm, but I am not an expert in cryptography so I might be making a fool of myself! Whether there are any possible attacks against it, I don’t know, but it will be interesting to see!

A fast random number generator in C

A fast random number generator in C

Random numbersIf you are using RNGs (Random Number Generators) for cryptography then you need one that has been validated for sufficient randomness. For example the libsodium library.

But if you want a fast one for general purpose use, then xoshiro256++ is a fast one.  It’s actually that short that I can list it here. Just call next() and mod it (%) with the highest value+1. E.G. for a dice roll,

int diceroll= (next() %6) +1;

This algorithm is very fast, typically on the order of nano-seconds 10-9 seconds.

#include <stdint.h>
uint64_t rngstate[4];

static inline uint64_t rotl(const uint64_t x, int k) {
    return (x << k) | (x >> (64 - k));
}

// Returns a Uint64 random number
uint64_t next(void) {
    const uint64_t result = rotl(rngstate[0] + rngstate[3], 23) + rngstate[0];
    const uint64_t t = rngstate[1] << 17;
    rngstate[2] ^= rngstate[0];
    rngstate[3] ^= rngstate[1];
    rngstate[1] ^= rngstate[2];
    rngstate[0] ^= rngstate[3];
    rngstate[2] ^= t;
    rngstate[3] = rotl(rngstate[3], 45);
    return result;
}
A remarkable piece of C code

A remarkable piece of C code

What do you think this outputs?

unsigned char c = 241;
long bits = (c * 01001001001ULL & 042104210421ULL) % 017;
printf("Bits = %lu\n",bits);

Remarkably it calculates the number of bits in c and should output “Bits = 5”.

If you don’t believe me, try this program to show all 256 values and the count. If you use c in the for loop instead of i, it never finishes. Well not with Visual C++ 2019!

#include <stdio.h>

int main()
{
    for (int i = 0; i < 256; i++){
        unsigned char c = i % 256;
        long bits = (c * 01001001001ULL & 042104210421ULL) % 017;
        printf("c %d #Bits = %lu\n",c, bits);
    }
    return 0;
}

You can try this out online on one of the various online C compilers.
Count bitsHere’s it on repl.it.

Build Android apps in C

Build Android apps in C

Android phone image
Image by mohamed Hassan from Pixabay

Now this isn’t something I’m going to do but I thought it worth the mention. Android development is done in Java mostly but increasingly in Kotlin. But someone has figured out how to do it in C and published it on GitHub.

You still need to install the free Android Studio to get this to work and I’m not really sure I’d want to write a complete mobile app in C, but it would probably outperform many Java/Kotlin apps.

Using printf type variable parameters in your function

Using printf type variable parameters in your function

The C programming languagI needed this in a bit of debug code. I wanted it to work like printf where there’s a format string containing one or more % format specifications and then write this into a buffer and dump it where ever.

C has a library stdarg which lets you do this. It’s not the most intuitive but it’s definitely worth understanding.

What I’m wanting to do is a function that does something like this (assume s1,s2 and s3 are char *).

sprintf(buffer,"Some string values %s %s %s",s1,s2,s3);
doSomething(buffer);

But in my own function and with the ability to have 0,1,2 or how ever many parameters without having to write a separate function for each. Kind of what printf does.

Here’s the code:

 

#include <stdarg.h>
void op(char* s, ...) {
	char buffer[50];
	va_list argptr;
	va_start(argptr, s);
	vsprintf_s(buffer,sizeof(buffer),s,argptr);
	OutputDebugStringA(buffer);
	va_end(argptr);
}

The … represent the variable number of parameters. it’s called the variadic operator. To access the actual parameters needs the various va_ macros and types. For instance va_list is a type that manages the list of parameters. The va_start macro takes the list and the parameter before the list. vsprintf_s is the Microsoft secure version of vsprintf. Both are the variable parameter equivalent of sprintf/sprintf_s.

OutputDebugString is the Windows debug string function. Finally the va_end tidies up everything.

So you use this just like printf, except the output goes to the Debug channel and can be picked up in Visual Studio (if debugging) or by running the SysInternals free DebugView utility.

Note, the original version of this used OutputDebugString but I found it was outputting gibberish. I correctly guessed that it was linking to OutputDebugStringW ; the MBCS version and changing it to OutputDebugStringA (the ASCII version) fixed it. Something to watch out for on Windows. 

Success with gamepad mappings

Success with gamepad mappings

SNES Gamepad
Image by Marco Sberveglieri from Pixabay

My ploy with running gamepad-tool on the Linux laptop worked and I was able to get the correct mappings to use in my game. Though weirdly it seems to have X and Y buttons mixed up as well as A and B.

In the end I hard-coded the mapping string and set it up with this code:

	if (SDL_GameControllerAddMapping("030000001008000001e5000010010000,NEXT SNES Controller2,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0")==-1){
		LogError("Unable to load gamepad mappings from gamepad.txt");
	}

Then in my ProcessEvents() function which handles I/O events, I added this code:

			case SDL_CONTROLLERBUTTONDOWN:
			if (event.cbutton.state== SDL_PRESSED){
				switch(event.cbutton.button){
					case SDL_CONTROLLER_BUTTON_A:
					    fireFlag =1;
					    break;
					case SDL_CONTROLLER_BUTTON_B:						
					    jumpFlag =1;
					    break;
					case SDL_CONTROLLER_BUTTON_X:
					    shieldFlag =1;
					    break;
					case SDL_CONTROLLER_BUTTON_Y:						
					    thrustFlag =1;
					    break;						
					case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
					    rotateFlag = 1;
					    break;
					case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
					    rotateFlag= 2;				
					    break;
					}
				}

There’s similar code for the SDL_CONTROLLERBUTTONUP except it checks for the state = SDL_RELEASED and in the switch statement it sets each flag to 0. So inspite of the code, it’s the Y button that does shields and the X button does thrust, B button fires and A button does the hyper space jump.

C is top programming language in Tiobe?

C is top programming language in Tiobe?

Technology
Image by ar130405 from Pixabay

The Tiobe index is a popular and much quoted and updated monthly list of programming languages sorted by popularity. And in May 2020, it lists C as the top language.

Now call me cynical; I do like C (kind of obvious- duh!) but I do have my misgivings about this index. For one, other programming language popularity measures usually disagree with it but are more consistent. Here are some. Most other articles seem to quote from these particularly the StackOverflow developer survey.

RedMonk – C is ninth.

Reddit’s programming language sub-reddits. C is ninth on here.

PyPl – how often language tutorials are searched on Google.  C does not appear at all!

StackOverflow developer survey 2019. C is eleventh in their listed technologies.

Github Octoverse. You have to scroll down to Top languages. C is ninth.

Codingame 2020 Survey. You have to scroll down. C is 6th in most loved and most known (5th in most dreaded!)

Now each of these measures different things so they are never going to be that consistent but coming ninth in three different surveys is pretty telling, with one eleventh and one sixth.  So when you see things like Tiobe, please take this with a pinch of salt.

The missing SGN function

The missing SGN function

Both C and C++ lack a sgn (short for signum apparently!) function (unless C++ has added it in recent changes. It’s also available in Boost but this blog is not about C++ so who cares!

Sgn() for those who don’t know is a function that returns -1 if the passed in int value is negative, 1 if the value was positive or 0 otherwise. Even BASIC includes it but not C.

However it’s easy to add. Something like

int sgn(in x) {
  if (x=0) return 0;
    else
  if (x>0) return 1;
  else 
    return -1;
}

Of course if you are using longints or floats or doubles, you have to write those as well. However an alternative is to make it into a macro.

#define sgn(x) (x < 0) ? -1 : (x > 0)
int a = sgn(10);

The only downside if you make lots of calls to sgn() is that it will slightly bulk up your code compared to calling it as a function but it will run fractionally faster!