Get Started Now

Intro to C++ Programming

Starting from the fundamentals, become a C++ software engineer, step by step.

LATEST UPDATES

Screenshot from Cyberpunk 2077
Module One

Intro to C++ Programming

Starting from the basics, become a C++ software engineer, step by step

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
Screenshot from Cyberpunk 2077
Capstone Project

Building Minesweeper with C++ and SDL2

Apply what we learned to build an interactive, portfolio-ready capstone project using C++ and the SDL2 library

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
Screenshot from Cyberpunk 2077
Module Two

Professional C++

Learn C++ and SDL development by recreating classic retro games

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
MOST POPULAR

Writing Data to Files

Learn to write and append data to files using SDL2's I/O functions.
Abstract art representing computer programming
Ryan McCombe
Updated
Published

In this lesson, we’ll introduce how to write data from our program to external sources. We’ll focus on writing to files for now, but the techniques we cover lay the foundations for working with other data streams, such as network traffic.

As we might expect, SDL’s mechanism for writing data shares much in common with their API for reading data. We’ll rely on SDL_RWops objects, and the functions we use will be familiar to what we learned in the previous lesson.

Like before, we’ll start with a basic main function that initializes SDL, and calls Write() and Read() functions within an included File namespace.

// main.cpp
#include <SDL.h>
#include "File.h"

int main(int argc, char** argv) {
  SDL_Init(0);
  File::Write("output.txt");
  File::Read("output.txt");
  return 0;
}

Our Read() function logs out the file’s contents, using techniques we covered in the previous lesson. In this lesson, we’ll work on the Write() function, which is currently empty:

// File.h
#pragma once
#include <iostream>
#include <SDL.h>

namespace File {
  void Read(const std::string& Path) {
    char* Content{static_cast<char*>(
      SDL_LoadFile(Path.c_str(), nullptr)
    )};
    
    if (Content) {
      std::cout << "Content: " << Content;
    } else {
      std::cout << "Error loading file: "
        << SDL_GetError();
    }
    
    SDL_free(Content);
  }
  
  void Write(const std::string& Path) {
    // ...
  }

}

Running our program, we should see an error output from our Read() function, as it’s trying to read a file that we haven’t created yet:

Error loading file: Parameter 'src' is invalid

Customising Mouse Cursors

Learn how to control cursor visibility, switch between default system cursors, and create custom cursors
Abstract art representing computer programming
Ryan McCombe
Published

When we’re working on a mouse-based game, creating an engaging user interface typically requires us to change the visual appearance of the cursor.

For example, we might customize the cursor to fit the theme of our game. We may also want to apply further modifications to the cursor based on what the user is pointing at, like changing the cursor to a sword if the pointer is hovering over an enemy. This helps players quickly understand what effect clicking will have.

This lesson will guide you through the various cursor customization options available in SDL2. We’ll cover:

  • Simple visibility toggles to show and hide the cursor
  • Switching between a range of default cursor options provided by the platform
  • Implementing custom cursors from image files
  • Completely replacing the cursor implementation to take full control on how mouse interaction is implemented

Parsing Data using std::string

Learn how to read, parse, and use config files in your game using std::string and SDL_RWops
Abstract art representing computer programming
Ryan McCombe
Published

When we’re loading text files into our program, we need the ability to programmatically understand that text data. This process is commonly called parsing the data.

In this lesson, we’ll imagine the configuration of our program is provided in a serialized form - perhaps a file or network response - that looks like this:

WINDOW_TITLE: Example Window
WINDOW_WIDTH: 800
WINDOW_HEIGHT: 600
LEVELS: 1, 2, 3, 4

We want to deserialize this payload into C++ content, defined by a struct that looks like this:

struct Config {
  std::string WindowTitle;
  int WindowWidth;
  int WindowHeight;
  std::vector<int> Levels;
};

We’ll cover the most important techniques to achieve results like this, using the standard library’s std::string type.

Numeric and Binary Data

Learn how C++ represents numbers and data in memory using binary, decimal, and hexadecimal systems.
Abstract art representing computer programming
Ryan McCombe
Published

So far, we’ve been converting the data we want to serialize into a string-based form. For example, when we’ve serialized a number like 42, we’ve converted it into a std::string. Then, when we deserialize that data back into memory, we convert it back to its original int form.

This is a useful technique and is applicable to many scenarios, but these conversions incur a performance cost. In situations where performance matters, we’d prefer to avoid this cost and use binary serialization instead.

Binary serialization creates data that represents our objects in the exact same way that type is represented in memory. To fully understand this, we first need to familiarise ourselves with some important concepts that affect how data is stored in memory.

Read/Write Offsets and Seeking

Learn how to manipulate the read/write offset of an SDL_RWops object to control stream interactions.
Abstract art representing computer programming
Ryan McCombe
Published

This lesson focuses on two essential functions for working with SDL_RWops: SDL_RWtell() and SDL_RWseek().

  • SDL_RWtell() provides the current read/write offset
  • SDL_RWseek() lets you modify it

This gives us fine-grained control over stream interactions. We'll examine how these functions work together and apply them to a practical example of managing a game's high score.

Mouse Capture and Global Mouse State

Learn how to track mouse movements and button states across your entire application, even when the mouse leaves your window.
Abstract art representing computer programming
Ryan McCombe
Updated
Published

In our earlier lessons where we covered mouse events and mouse tracking, we were primarily concerned with what the mouse is doing whilst it is hovering over our windows. That is, when one of our windows has mouse focus.

However, in certain scenarios, we may need to understand what’s going on with the mouse even when we don’t have mouse focus. This lesson covers the techniques we can use to accomplish this, and some of the scenarios where we may need to.

Working with Data

Learn techniques for managing game data, including save systems, configuration, and networked multiplayer.
Abstract art representing computer programming
Ryan McCombe
Published

As we’ve seen, when we create variables and instantiate classes in C++, the data in these objects are stored in a block of memory, which our program can freely read and update. To build more advanced features, we need the ability to convert those memory representations into other forms. This process is typically called serialization.

The output of this serialization can be used in many ways - we might store it on our player’s hard drive to use later, send it to some other program, or send it to some other computer over the internet. When a program later uses that serialized data, it will need to convert back into an understandable form in memory. This process is called deserialization.

In this lesson, we’ll give a brief introduction to why serialization and deserialization are important, and the types of capabilities that they unlock. Through the rest of the chapter, we’ll walk through how to implement these techniques with C++ and SDL, and the things we need to consider when doing so.

We’ll then use these principles to create a basic save and reload system from scratch. Finally, we’ll introduce a free, open-source library that applies these concepts to provide a feature-complete solution, allowing us to quickly add these capabilities to much more complex projects.

Byte Order and Endianness

Learn how to handle byte order in using SDL's endianness functions
Abstract art representing computer programming
Ryan McCombe
Published

Previously, we’ve focused on serializing single bytes of data at a time - usually the 8-bit char type. However, when we start to serialize multi-byte objects, such as int and float values, things can get slightly more complex.

We need to pay careful attention to the order of those bytes, especially when working across different systems.

In this lesson, we'll explore how computers store multi-byte values, understand the challenges of different byte orderings, and learn practical techniques for handling these differences using SDL's binary manipulation functions.

Padding and Alignment

Learn how memory alignment affects data serialization and how to handle it safely
Abstract art representing computer programming
Ryan McCombe
Published

When we write code, we often think about memory as a simple sequence of bytes. However, modern processors work with memory in larger chunks for efficiency. Two key concepts drive this behavior: cache lines and memory pages.

Cache lines, typically 64 bytes, are the smallest unit of data that can be transferred between the CPU cache and main memory. Similarly, memory pages are the smallest unit managed by the operating system's virtual memory system.

For optimal performance, we typically want our data to be aligned to minimise the frequency with which a single value crosses one of these boundaries. An example of a boundary cross might be a 4-byte integer where it’s first two bytes are at the end of one cache line, and the last two bytes are at the start of the next.

The boundary between our two cache lines might look like the following, where X represents the integer we’re interested in, and A and B represent other arbitrary variables:

Line 1  | Line 2
A A X X | X X B B

Our systems can typically handle this - it can perform multiple reads to grab both blocks of memory, then take the appropriate bytes from each and combine them to to reconstruct our integer X. However, this comes at a performance cost. Instead, we want to align our data to maximise the chances that it is stored entirely within the same cache line or page, eliminating the need for this additional processing.

Fullscreen Windows

Learn how to create and manage fullscreen windows in SDL, including desktop and exclusive fullscreen modes.
Abstract art representing computer programming
Ryan McCombe
Published

In this lesson, we'll explore SDL's window management features, learning how to implement both desktop and exclusive fullscreen modes. We’ll cover:

  • Creating borderless fullscreen windows that cover the entire screen using SDL_WINDOW_FULLSCREEN_DESKTOP
  • Using exclusive fullscreen mode, which changes display settings for optimal performance using SDL_WINDOW_FULLSCREEN
  • Using SDL_SetWindowFullscreen() lets you change modes at runtime
  • Best practices and error handling
Module One
3D art showing a progammer setting up a development environment

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 60 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Capstone Project
3D art representing computer programming

Building Minesweeper with C++ and SDL2

Apply what we learned to build an interactive, portfolio-ready capstone project using C++ and the SDL2 library

Free, unlimited access

This course includes:

  • 37 Lessons
  • 100+ Code Samples
  • 92% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Module Two
A computer programmer

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Get Started Now

Intro to C++ Programming

Starting from the fundamentals, become a C++ software engineer, step by step.

Contact|Privacy Policy|Terms of Use
Copyright © 2025 - All Rights Reserved