Category: C

Learning C and SDL

Learning C and SDL

Learning
Image by Gerd Altmann from Pixabay

I frequent the Reddit C subreddit and Quora.com and quite often see people asking what they should learn first. So I’ve updated the C tutorials page (link at top) with details of future tutorials as well as a new one on functions. This includes the entire course (though some are not yet written).  It has more details about each lesson and shows the whole course,

There’s considerable overlap with material in my first EBook though that was for Windows only and this is for Windows, Linux and Raspberry Pi. The Pi of course is Linux with some hardware specific stuff and I’ll include links back to previous blog entries which have explained how to get and display the Pi’s temperature in a C program or use game pads.

Unlike other C courses it will include SDL2 code and how to use it. I think C + SDL2 is a great way to make 2D games, and is probably the easiest and simplest to learn.

 

A first-person-shooter in 32KB

A first-person-shooter in 32KB

Anarch FPSDon’t expect this to be Call of Duty standard but then those games typically have a 50GB or higher footprint on disk. Anarch comes with 10 levels, 6 weapons, 7 enemy types and 3 ammo types and runs in 200 KB of disk space and runs in 32KB RAM. It’s 100% C but doesn’t use any FPU, GPU or file I/O. It’s old skool 90s style.

If you’ve played original Doom you’ll have an idea what it’s like.

Interestingly, the creator has put everything, source code, graphics etc into the public domain which is a very philanthropic gesture. So if you want to understand how to write a FPS (first-person-shooter) in C, take a look. You can even play it in a browser.

I’ve added this to the C Code links page (on the top menu).

 

How to move a SDL project from Windows to Linux

How to move a SDL project from Windows to Linux

SDL Logo
The SDL Logo is from libsdl.org

It’s not actually that hard to do, there’s just a few things that are different between C and Linux, specifically between MSVC and GCC /Clang.. I did this when I wrote the Asteroids game in the book.

Originally I developed it on Windows then moved it to Linux (Ubuntu) and then I added the bits to have it work on a Raspberry Pi. It worked on the Pi more or less as is on Ubuntu but I added support for game pad, detecting that it was on a Pi and displaying the temperature.

Here’s what I’ve found is different between MSVC and GCC/Clang.

  1. The safe string functions. MSVC has the _s functions so instead of strcpy, there’s strcpy_s on MSVC. This doesn’t exists in GCC/Clang but there are similar functions with an n in the middle e.g. strncpy. In future I’ll create a macro for each function that uses the appropriate type so the compiler will pick the correct type.   However it seems even strncpy may not be all that safe. If there is no \0 in the n characters then the copied string won’t have a terminating \0 and thus could still blow up.  This article says that in order of safety it goes like this with strcpy least safe and strlcpy the most.
    strcpy < strncpy < snprintf < strlcpy

    so maybe I should be using strlcpy instead.

  2. The include path for SDL in GCC/Clang is “SDL\SDL.h” not “SDL.h” as it is in MSVC. Again this could be fixed with a macro prefix for the SDL path so all #include works correctly on either system.

3.  I found that the file type was wrong. This wasn’t just a matter of CR/LF versus LF which you get between Windows and Linux (CR = Carriage return, LF = Line feed). Somehow the Windows file had a different UTF encoding type to what GCC/Clang expected and the compiler did not like it. However Visual Studio Code shows you what encoding it is (on the bottom of the edit window) and lets you change it, so no harm done. You may need to do this once on each file you’ve moved from Windows to Linux.

4. I found that the time header file in Linux needed a bit of work to make it compile. The standard for this dictates that differences aren’t done to the header file but by adding in additional headers.

So I’ll look into strlcpy.

 

 

 

Loads of C Algorithms

Loads of C Algorithms

C algorithms
From C Algorithms

While it’s fun writing your own code when it comes to things like sort or graph algorithms, common algorithms, you can save a lot of time, grief, debugging by using code that someone else has created.

Today I came across an algorithms website with algorithm source code for 14 programming languages including C, C++, Java, Python and go.

The C site alone has over 150 algorithms, mind you the Python and C++ have over 600!. Each of the ones I’ve looked at links to a YouTube video (not always about a C implementation but about the topic) and has a source code listing.

Overall its a very useful resource, has a memorable url (algorithm examples) and I’;ve added a permanent link on the C Code utilities page.

How slow is SDL_TTF 2.0?

How slow is SDL_TTF 2.0?

FWhen  I created the Asteroids game, I deliberately didn’t use SDL_TTF instead I took a Monospaced font and saved it out as a PNG file which was loaded into a SDL Texture. I then created my own character printing routines by figuring out which character I wanted and then blitting it. The image shows the font I used zoomed in.

You probably can’t get much faster than that, although I wasn’t really doing that much output. Every frame, the score is output and if an asteroid is hit, the value of the hit scrolls upward for a few frames.

Also when you lost a life, it would print using a scaled up version of the font. The only problem with that is scaling up a bit map font just shows off the deficiencies of the font scaling as a bitmap, as the image shows. Not exactly smooth is it?

So I’ve decided to write a small program that uses SDL_TTF 2.0 and does high resolution timing to determine exactly how long it takes to draw text using a TTF font. The big advantage of doing that in a game is you can draw different sizes, weight (bold etc) and colour compared to a bitmap font.

But TTF is an interesting format, there’s a lot going on. Letters are drawn using mathematical equations so it is bound to be a bit slower than pure blitting and I’m interested in knowing just how long it takes. It’s all relative, if you view a page of text in MS Word (or just in Windows generally), Windows renders it pretty fast.  But its still important to know just how fast. For what I used text for in Asteroids, it probably could have used TTF text but in another game with more text it might be too slow for 60 frames per second.

If it was too slow then perhaps a hybrid approach might work. Figure out what text you’ll need, prerender it into bitmaps (when the program starts up) then use those bitmaps.

So I’ll publish the speed test program once written. Watch this space.

 

New C tutorial on implementing linked lists with pointers

New C tutorial on implementing linked lists with pointers

Links
Image by Денис Марчук from Pixabay

Once you leave the relative safety of arrays and structs, the linked list using pointers is probably the next thing to consider.  Technically it’s a liked list of structs containing pointers. It’s like an array of structs only instead of allocating contiguous memory for an array, you allocate memory for each struct as you need it.

Linked lists are easy to program. You have a head pointer (a pointer to the head of the list). It starts as null as the list is empty. There’s two types of linked lists (single and double). A single list has a pointer to the next node (or is 0 at the end of the list) and can only be processed from head to end. A node is just a fancy name for the struct in the linked list.

A double list has two pointers. One to the previous node and one to the next. As well as a head pointer you need a tail pointer and you can process the list from head to tail or tail to head (i.e. backwards).

Now the first operation you can do on a linked list is add a node to it.

To do this you

  1. Allocate memory for the node using malloc.
  2.  Copy the head pointer to the node’s next pointer.
  3. Stitch the node in by pointing the head pointer to this node.

So when you are building a list you add each node to the head, in a sense pushing it in front of the others.

Double linked lists have to do an additional operation which is set the next node’s previous pointer to point to the newly added pointer. And when you add the first node to a double linked list, you have to set the tail pointer to point to this first node. After that it never changes unless you have an Append node at the end.

Uses of Linked Lists

Anything that needs dynamic memory for example a text editor might use a double linked list to store all the text. Each line could be a different length. So each node would not only have a pointer to the next and previous nodes, it would have a pointer to the text in memory. When you insert a new line, you are just inserting a new node in the list at the current node that the cursor is on.

Or you might store a directed graph (a bit like in the picture) where each node has multiple pointers to other nodes.  Anyway I’ve published tutorial eight which looks at pointers and linked lists.

 

A blog post worth reading

A blog post worth reading

Letter C
Image by Clker-Free-Vector-Images from Pixabay

A developer called Jakub “Jorengarenar” Łukasiewicz has posted a blog entry Best aspects of C language and I’m more than happy to link to it. It says much of what I think about C but expressed very nicely and its well worth the read.

In his post he refers to a document Rationale for International Standard Programming Languages C (PDF).  This is a 2003 document (C doesn’t change very often)  and not exactly a light read at a trifle over 200 pages long. It’s an insight and commentary into what C99 is about and also lists these five principles:

  • Trust the programmer.
  • Don’t prevent the programmer from doing what needs to be done.
  • Keep the language small and simple.
  • Provide only one way to do an operation.
  • Make it fast, even if it is not guaranteed to be portable.

If you are learning C this will provide you with explanations of why some things in C99 are what thy are. Like myself you will discover things that you didn’t know. For instance I didn’t know about long double. Or that in K & R C(Kernighan and Ritchie) that all floating point arithmetic was done at double precision but that was relaxed in C89.

 

A Minecraft clone in C

A Minecraft clone in C

Open source Minecraft clone in CI’ve never really been a great fan of Minecraft, though it is a great and wildly successful game. My reason for mentioning it is that there’s a C open source version of it and it’s cross-platform as well on Windows, Mac and Linux.

It was developed seven years ago and has had the odd update since with the most recent earlier this year.

The developer (Michael Fogleman) has also provided an online server for it and has some Python in it to make that possible but 80% of the code is C. It uses OpenGl to draw the graphics; so if you want to write your own Minecraft clone, this is a good program to study. As usual I’ve added a link into the C Code Links page.

 

Quicksort in C

Quicksort in C

Sorting
Image by Clker-Free-Vector-Images from Pixabay

Normally I wouldn’t mention a sorting algorithm, but by a lucky coincidence, when I had my interview before going to university (Queen’s University Belfast), the bloke who interviewed me back in 1977 was the inventor of Quicksort. Tony Hoare. He left very shortly after so I never got him as a lecturer,

As algorithms go, Quicksort is one of the faster. it works by splitting the list in two and then recursively sorting the two halves. The simplest sorting method Bubble sort uses a double loop and for very small numbers of items to sort is generally more efficient than Quicksort, but it doesn’t take long for Quicksort to catch up.

I was reminded of Quicksort by seeing this article and thought it would be interesting to do a series of test of sorting 5-50 items a few thousand times each in Quicksort and Bubblesort and see where the crossover point is. How many items is the minimum for Quicksort to become faster than Bubble sort?

If you take the Swap functions and BubbleSort from here and partition and quickSort functions from here and use my high precision timing code and add the code below then you can run the comparison. I did it twice, once in Debug and once in Release and the difference is much larger in release. I’ve zipped up the source code including the Visual C++ project code (It is C source code not C++ btw) and high performance timing code and put it on GitHub.

#define NUMLOOPS 5000

int main()
{
    int startarr[]= { 86,91,50,5,79,64,2,57,26,63,12,61,12,92,40,38,11,
                 94,90,38,24,25,54,75,67,56,7,9,32,26,54,48,51,28,
                90,50,37,53,8,75,30,25,59,57,92,42,25,33,84,46 };
    int arr[50];
    stopWatch stw;
    double bTime, qTime;

    bTime = 0.0;
    qTime = 0.0;
    for (int i = 3; i < 50; i++) {
        printf("Bubble sort for %d = ", i);
        for (int j = 1; j < NUMLOOPS; j++) {
            memset(arr, 0, sizeof(arr));                     // Clear arr
            memcpy(arr, startarr, sizeof(int) * i); // copy in i elements
            startTimer(&stw);
            bubbleSort(arr, i);
            stopTimer(&stw);
            bTime += getElapsedTime(&stw);
        }
        bTime /= NUMLOOPS;
        printf("%12.10f.  ", bTime);
        printf("Quicksort sort for %d = ", i);
        for (int j = 1; j < NUMLOOPS; j++) {
            memcpy(arr, startarr, sizeof(int) * i); // copy in i elements
            startTimer(&stw);
            quickSort(arr, 0, i - 1);
            stopTimer(&stw);
            qTime += getElapsedTime(&stw);
        }
        qTime /= NUMLOOPS;
        printf("%12.10f\n", qTime);
    }
    return 0;
}

These are the first 15 and last 5 output lines in Release. The Bubble sort time for 7 is a bit of an oddity just for the actual numbers sorted. But its clear that by 11 values that Bubble sort is slower than QuickSort and the difference just gets worse up to 50. So up to 10 elements, Bubble Sort wins.

Bubble sort for 3 = 0.0000000358.  Quicksort sort for 3 = 0.0000000412
Bubble sort for 4 = 0.0000000407.  Quicksort sort for 4 = 0.0000000445
Bubble sort for 5 = 0.0000000474.  Quicksort sort for 5 = 0.0000000485
Bubble sort for 6 = 0.0000000677.  Quicksort sort for 6 = 0.0000000448
Bubble sort for 7 = 0.0000000191.  Quicksort sort for 7 = 0.0000000097
Bubble sort for 8 = 0.0000000405.  Quicksort sort for 8 = 0.0000000601
Bubble sort for 9 = 0.0000000510.  Quicksort sort for 9 = 0.0000000434
Bubble sort for 10 = 0.0000000568.  Quicksort sort for 10 = 0.0000000653
Bubble sort for 11 = 0.0000000633.  Quicksort sort for 11 = 0.0000000566
Bubble sort for 12 = 0.0000000702.  Quicksort sort for 12 = 0.0000000606
Bubble sort for 13 = 0.0000000845.  Quicksort sort for 13 = 0.0000000743
Bubble sort for 14 = 0.0000000931.  Quicksort sort for 14 = 0.0000001145
Bubble sort for 15 = 0.0000001040.  Quicksort sort for 15 = 0.0000000827
Bubble sort for 16 = 0.0000001142.  Quicksort sort for 16 = 0.0000000892
Bubble sort for 17 = 0.0000001448.  Quicksort sort for 17 = 0.0000000974
...
Bubble sort for 45 = 0.0000008478.  Quicksort sort for 45 = 0.0000002737
Bubble sort for 46 = 0.0000008561.  Quicksort sort for 46 = 0.0000002524
Bubble sort for 47 = 0.0000008948.  Quicksort sort for 47 = 0.0000002643
Bubble sort for 48 = 0.0000009421.  Quicksort sort for 48 = 0.0000003147
Bubble sort for 49 = 0.0000010042.  Quicksort sort for 49 = 0.0000002804

 

 

Tutorial seven on pointers and C strings published

Tutorial seven on pointers and C strings published

A different kind of sea string
Image by Steve Norris from Pixabay

The tutorials from About.com continue with the 7th one (of about 30) published. This is about C strings which are really just pointers to an array of characters.  Once you understand pointers strings are easy enough to understand.

C is not a great programming language for string handling. To do a lot of manipulation is tedious and error prone. You’ll find safe versions of many of the standard functions for things like string copying and appending. The difference between the safe functions and the non-safe functions is that the safe functions include a maximum length.

For example strcpy() is used to copy a string. It’s definition is this:

char *strcpy(char *dest, const char *src)

That is, it copies a string pointed to by src to a string pointed by dest and confusing also returns a pointer to dest.  What a waste of a function. It could have returned an int saying how many characters were copied instead. Because it relies on src pointing to a string (char *) that terminates with a null (or 0). If the null is missing it can copy a lot more characters and that’s how buffer overflow bugs happen. So you have strncpy which is defined as this:

char *strncpy(char *dest, const char *src, size_t n)

The extra parameter is how many characters are to be copied. That way if it goes wrong, it is limited to n.

The picture? That’s a different kind of sea string…<groan>