I’ve done 70 odd blog posts so far since I started this in March 2020 and there’s a fair number of gems and nuggets in there. Finding them though is probably a bit of hassle, so to let you see them easily, I’ve created a page of tips, accessible from Tips in the menu above.
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.
Unfortunately there’s no gamepad-tool for the PI, but there is a program called jstest and in particular a visual one called jstest-gtk. That’s it on the left. You install it on any Linux system, including Raspbian on the Pi with the command
sudo apt install jstest-gtk
Then run it with a jstest-gtk command from a terminal.
It then detects your game pad and responds to button presses and joystick movements.
The weird thing is although my gamepad identifies it as a NEXT SNES but so far attempts to load that have not been successful in the Asteroids game. It loads but doesn’t seem to work and its not recognising the right shoulder button and has A and B buttons muddled up. Yet in jstest, it is clearly able to identify them.
Time I think to create a mapping under Linux with gamepadtool. Unfortunately it doesn’t work on the Hyper-V Ubuntu so it’s time to fetch my Linux laptop and try it on that.
I’ve never dealt with a game pad (joypad etc.) before. It seems that there is no absolute mapping, it’s more like TV remote controls. There’s lots of them and they’re all different. So although SDL2 has a set of enum values for the buttons, I found that my game pad wasn’t responding to what I thought were the game keys.
But SDL2 to the rescue. The SDL_GameController has a flexible scheme where the game pad can be setup by a text string. There’s a database of schemes available on Github. That includes a couple of tools for discerning what the setup for your game pad is. That’s one of them shown. That program from General Arcade is free and cross-platform. I downloaded and ran it on Windows with my game pad attached.
So, my controller is a NEXT SNES Controller (no surprises there) and the setup string for it is 030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Windows.
There’s a database of these on Github and it currently has 780 odd strings. You can view it here though it’s not that great a read!
So I think the idea is, you can include that file in your application and any game that uses game pads can get the GUID from the game pad via one of the SDL calls- see this list of SDL GameController functions and load the file into memory et voila, your application can now use the game pad.
Back in November 2018, I was in Nottingham and passed a stand at the Winter Fayre. It was offering a console with 18,000 games on it for about £70. I bought one and what I got was an Orange PI with a 16 GB SD Card (all but full) and two USB joypads.
The game software used the Retro-Pie software, but the games were a massively illegal collection of games (for about ten different consoles including CBM-64, SNES, ZX Spectrum) put together by the company that supplied these “consoles”. Amazingly I found four games on there that I had written back in the 80s in this collection.
It was a bit of an odd PI. Instead of powering up through the power slot, it came with a USB to 5V connector. Looking about on the web I found it is this model in a nice acrylic case. Anyway, after three months it stopped working and it was pushed in to a drawer where it remained until today. I tried it today and it came back to life, I suspect the mains-to-USB adaptor is broken but as I’ve a drawer full of them it’s not a problem.
The reason for mentioning this is not the Orange Pi, nor the games but the joypads. I had a look on the libSDL website and I hadn’t realised that there was quite extensive support built in to SDL. So my next task is to add game controller support for the asteroids game.
When programmers have to explain why it took longer to get something working,you don’t often here reasons like this. A simple syntax error error took me an hour to find and fix. Yet it does happen and it happened to me today.
Oh sure you feel silly afterwards and it was only a 131 lines of C code. The very last of the 1566 compile errors was unexpected end-of-file found on line 132. That was a red herring of sorts. The error actually occurred right at the start of the program.
Here’s the first 10 lines. It should be quite easy to spot but when you are looking through 130 lines with a hint that it’s messed up the end of the file, it’s not so obvious.
// tictactoe.c
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
int playerIsX, computerFirst, x, y, danger, turn;
char board[3][3]; // holds X, O and space
char playerPiece, computerPiece;
In case you haven’t spotted it, it’s the missing .h; it should be string.h not string in that 3rd #include. An obvious-in-hindsight clue is the error listing. The files that are mentioned don’t have .h on them. (cctype, cstdint etc. Those are C++ files and string is a C++ header file. Also mention of namespace in the error message is also a big hint.
Still I think that sets a record for the most errors generated in a C compile! The compiler btw was Visual Studio 2019’s C/C++ compiler.
Yes it is possible, as the screenshot shows. You can download a copy of Raspbian from Raspberry-pi. You can either download the .iso directly or save them a bit of bandwidth and do it via a file Torrent. It then takes about 15 minutes or so to install it. When you first run it, it will do an update.
It looks exactly like Raspbian on a PI but there are one or two little things to bear in mind. It’s 32-bit, the clipboard doesn’t seem to work and SSH by default is disabled. It’s real easy to enable it, just find Raspberry Pi Configuration. Click the Raspberry in a circle menu button at the top, then click Preferences and there it is on the menu that pops up. In the Interfaces tab, tick the Enabled checkbox for SSH.
I use the excellent WinSCP to connect to it. Conveniently the Pi will show you its ip address (or from a terminal run ifconfig and it will show you the ip address of eth0) and just put that in with username pi and your pi’s password which you should have changed when you set up Raspbian.
Finally you have to install Visual Studio Code and as usual, it’s not quite so easy. Most Linux distros these days are 64-bit and the official VS Code is only available for Debian in 64-bit and Raspbian is of course 32-bit. But there are community builds and it’s the same place that I got the ARM version from.
And here’s the result. A slightly sluggish (well it is under Hyper-V). I had to comment out the code that initialises the audio. Line 580 ish.
/* int success=Mix_OpenAudio(22050, AUDIO_S16LSB, 2, 8192);
if (success==-1 ) {
LogError("InitSetup failed to init audio");
}
LoadSoundFiles();
*/
The publisher Springer has made a whole raft of their books available as free downloads and this should last until the end of July. This includes a Guide to Scientific Programming in C++ and Systems Programming in Unix/Linux.
There’s also books on networking, cryptography and more.
Alternatively, if you fancy learning x86-64 Assembly Language Programming with Ubuntu then knock yourself out. I used to write a lot of assembler (6502 and z80) a very long time ago. It’s a lot easier these days with debuggers.
In my ebook I talked about professional games using a resource manager. Games like Quake 2 use a .pak file which stores all images, levels etc. The first stage towards writing a resource manager is to have some way of compressing files. Most graphic file formats such as jpg, gif and png are already compressed. But other files like level files aren’t, typically text and so will compress well.
So a resource manager if it understands the type of resources it is handling can compress or not according to the file type. It will bundle everything into one archive file, and maintain a simple directory indicating where in the archive file each resource file starts, length and type.
However there is the issue of security. The idea of the resource manager is to protect your assets. I have two old games from the Dos days (bought recently on gog.com and playable in Windows) and a quick glance in the games folder shows some interesting files! That’s one of them shown above. It’s parts of a castle. There are hundreds of graphic files just lying there in the open. They are in an older graphic format (.pcx) but SDL2_image can read those quite happily.
So not only should a resource manager protect your files, it should obscure them so anyone inspecting them with a binary file editor can’t easily spot them.
That brings me to the 2nd point about security. Your program has to be able to use the resources directly from the resource manager rather than say unpack them into a folder on disk. According to this stackexchange answer, SDL2 can do that, so something for me to experiment with.
So I’m starting on a simple and easy to use resource manager. It’ll be implemented as a simple library that provides access to images, text files etc. all loaded from a resource file. And there will be a standalone utility to add, delete and list files in that resource file.
Playdate sounds a tad dodgy but is actually a small handheld game console with a 2.7-inch, 400 × 240 screen (173 ppi) and costing $149. It’s due out sometime this year.
The reason I mention it is it runs games written in C (or Lua). It also comes with 12 games. No mention of what’s inside it (RAM, CPU) though that’s described as ‘beefy’ but it has Wi-Fi, Bluetooth, USB-C, and a headphone jack.
That thing sticking out of the right is a hand crank. No, not for charging the battery but as a game input device. If you create a side-scroller game you can have it scroll one way by cranking in one direction and reverse it by cranking in the other way. Well that’s certainly original!
There will be a development kit available for it and you will be able to write programs for it though at the moment that looks as if its only on a Mac which is a bit of a shame. Oh I have a Mac but I much prefer my Windows PC or Ubuntu.
Compared to the massive screen sizes available on PCs, 400 x 240 sounds a bit small screen size. If you remember the CBM-64 from the 80s, it is exactly the same size as that screen and there were some great games out for it.
I’m excited about this because I believe it could be a renaissance for C Game programming.