Skip to main content

C++

Posts about the C++ programming language

The cover of "SDL_GameController: Making gamepads just work"

SDL_GameController: Making gamepads just work

When implementing controller support in a game, it’s desirable for gamepads to just work without a lot of user configuration. Platform APIs are pretty useless for this, the solution is an API like SDL_GameController that allows you to target a large number of gamepads without much effort.

Each operating system has its own API for gamepad input. Windows has XInput, and Linux has the joystick and evdev APIs. When a gamepad button is pressed, applications will receive a button id. This is a number, there’s no OS way to know which button id corresponds with which button. The ids for a button are not the same on different gamepads and platforms, making it super hard to support more than a couple of devices.

if (SDL_JoystickGetButton(joystick, 8)) {
    std::cerr << "no idea what button 8 is" << std::endl;
}

One thing platforms do give you is the name, model, and manufacturer of the game controller. If you test with a large number of gamepads, you can create a database from gamepad name to layout. Luckily, SDL_GameController has already done this for you. Instead of a random number, you can use a named button that will work no matter the gamepad and platform:

if (SDL_GameControllerGetButton(controller, SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X)) {
    std::cerr << "X was pressed!" << std::endl;
}

Read more of "SDL_GameController: Making gamepads just work"

The cover of "Extending sol3's implicit type conversion"

Extending sol3's implicit type conversion

Many APIs in my game push Vector3s to and from Lua. It’s such a common operation, that most of my functions used to look like this:

sol::table add(sol::table tPos) {
    Vector3f pos = TableToPos(tPos);

    // do something
    return PosToTable(pos);
}

One of the benefits of sol is that it is able to bind Lua arguments to C++ function arguments, converting types implicitly. Having to convert from a table to a vector ourselves is quite annoying. It would be much nicer to have sol do it for us. Luckily, sol allows you to customise how types are retrieved and pushed to Lua using Customisation Points.

When trying to convert a type from Lua to C++, sol will call certain templated functions. We will be customisating sol’s behaviour using a technique called template specialization, which allows us to specialise a specific instance of the templated functions and structs. By the end of this article, we’ll be able to use Vector3 directly when using sol, allowing the above code to be turned into this:

Vector3f add(Vector3f pos) {
    // do something

    return pos;
}

Read more of "Extending sol3's implicit type conversion"

The cover of "A Comparison of SFML GUI Libraries: TGUI vs SFGUI vs ImGui"

A Comparison of SFML GUI Libraries: TGUI vs SFGUI vs ImGui

SFML is an excellent library that can be used to create 2D games and similar applications in C++. It’s an abstraction over OpenGL and various system APIs, presenting a consistent and easy-to-use interface.

Providing a Graphical User Interface (GUI / UI) API is out of scope for SFML. GUIs are complicated, and there’s no single good way to implement them. The S in SFML stands for Simple but GUI code rarely is.

There are many different options to choose from when making GUIs. This article is an in-depth comparison of the options for making GUIs in SFML, discussing their pros and cons.

Read more of "A Comparison of SFML GUI Libraries: TGUI vs SFGUI vs ImGui"

C++: Self-registering functions using macros for test libraries

Google’s C++ testing library has a nice syntax for registering tests, without needing to remember to add the tests to some central index. This article will show how to use macros to allow the creation of tests using only the following code:

Test(IntegerComparisonTest) {
    int a = 3;
    assert(a == 3);
}

Read more of "C++: Self-registering functions using macros for test libraries"

Rubix: My Simple Kernel written in C for arm

During the second year of university, I created a kernel for the ARMv7 instruction set. I went above and beyond what was required on this project, achieving a clean design and features such as a blocked process queue, piping, kill, and a simple filesystem. This was my favourite coursework so far. I found it very interesting to learn about and implement the things that we take for granted as programmers.

I tried to stick to POSIX as much as possible, and stuck to the Linux method of having everything as either a file or process. Because pipes and standard in/out were both “files”, I was able to implement both popen and piping of the output of a process to another process.

Read more of "Rubix: My Simple Kernel written in C for arm"

The cover of "RVWP: Multiplayer Topdown Sandbox Game in C++"

RVWP: Multiplayer Topdown Sandbox Game in C++

For the last two years, I have been working on a very ambitious game. The game is a top-down sandbox with multiplayer support. I’m aiming towards a city-based game, where players can wander around a procedurally generated city. One of the main reasons I started creating this game is to learn about multiplayer networking at a low level - client-side prediction, server-side reconcilliation, cheat preventation, and reducing the visual effect of latency.

Read more of "RVWP: Multiplayer Topdown Sandbox Game in C++"

Mingw-w64 and CMake: unrecognised option -rdynamic on Ubuntu

I had an issue where CMake was failing on a compiler test with the following error:

error: unrecognized option '-rdynamic'

The problem was that CMake caches settings such as compiler flags in CMakeCache.txt, so you need to clear the cache when changing the platform. Do this by deleting CMakeFiles and CMakeCache.txt

Read more of "Mingw-w64 and CMake: unrecognised option -rdynamic on Ubuntu"

How to emit a single particle using SFML's Thor Particle System

Usecase: shells dropping in sync with firing, fake bullets, etc

You must use a particle emitter to create particles, however this doesn’t mean it’s impossible to create single particles on command. You can create a particle emitter which simply adds particles from a queue to the system

Read more of "How to emit a single particle using SFML's Thor Particle System"