Category: SDL

Setting up SDL3 on Linux

Setting up SDL3 on Linux

SDL3 program running on Raspberry Pi.

I knew it wasn’t going to be easy, but it turned out to be quite a bit more difficult than I thought.

The problem is, unlike SDL2, there are no dev versions of SDL3 etc. yet, so you have to build it from scratch.

I’ll be honest, I’m not sure I could have done it without this GitHub repository. User Ravbug who is very busy person (752 contributions on GitHub in the last year- I tip my hat to him or her!) who provided that repository.

It sets up SDL3, SDL_image, sdl_mixer and SDL_ttf.

Follow his link to the Wiki page Scroll down to the bottom for the Linux instructions. I can confirm that it works on Raspberry Pi as well.  You’ll need to install cmake first with

sudo apt install cmake

Then run his cmake to build everything and go for a coffee.
Now go into the build folder under sdl3-sample and do

make

That only takes a second or so.

After you’ve done that you’ll end up with a load of files including an executable sdl-min that you can run. That’s what generated the Tiger’s head – it plays The Sting film’s theme (The Entertainer) music as well demonstrating that it’s using SDL_mixer as well as SDL3 and SDL_ttf (I’m guessing) and of course SDL_image.

But that is just the start

To use SDL3 etc in your C program, you need a bit more configuration than with SDL2. I’m in uncharted waters here but used an AI- Claude 4 to help me get through and it did.

The problem is you have to tell VS Code where the header files are located, the .so files and also the executable needs to know at runtime.

I set up Ravbug’s sdl3_sample in my home folder so all paths start /home/david/sdl3-sample. 

This is my tasks.json

 

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "clang-14.0 build active file",
            "command": "/usr/bin/clang-14",
            "args": [
                "-I/home/david/sdl3-sample/SDL/include",
                "-I/home/david/sdl3-sample/SDL_image/include", 
                "-I/home/david/sdl3-sample/SDL_mixer/include",
                "-I/home/david/sdl3-sample/SDL_ttf/include",
                "-g",
                "${file}","${workspaceFolder}/hr_time.c",
                "-L/home/david/sdl3-sample/build",	
                "-Wl,-rpath,/home/david/sdl3-sample/build",				
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                "-lSDL3",
                "-lSDL3_image", 
                "-lSDL3_ttf"   

            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

The lines that are SDL3 specific include the -I’s to provide the include path. -L the path to the .so files and the -rpath line is the path to the runtime files which gets linked into the executable.

If you add these three lines into c_cpp_properties.json then you’ll also avoid the dreaded red squiggles.

            "includePath": [
                "${workspaceFolder}/**",
                "/home/david/sdl3-sample/SDL/include",
                "/home/david/sdl3-sample/SDL_image/include",
                "/home/david/sdl3-sample/SDL_ttf/include"
            ],

And your C’s #includes need the files prefixed like this :

#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_ttf/SDL_ttf.h>

And here it is running on my Pi.

Missile Command running on a Raspberry Pi 5 with SDL3

Converting from SDL2 to SDL3 on Windows

Converting from SDL2 to SDL3 on Windows

Missile Command running with SDL3

These notes were made when converting an existing C game that used SDL2 to SDL3 on Windows. The game was originally developed for Linux Format and I had got it running on Windows with SDL2.

Windows include paths have been made consistent with Linux. The include files path for SDL3 need to be SDL3\… when setting them up. For SDL2, I had them in a folder c:\SDL2\include but noted that in SDL2.h include files were like this:

#include "SDL_main.h"
#include "SDL_stdinc.h"

While in SDL3’s SDL.h they are

#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_assert.h>

So I put them c:\SDL3\SDL3

When you include them in your software they are like this:

#include <SDL3/SDL.h>
#include <SDL3/SDL_image.h>

Which is how they are in Linux.

The rest of these notes are taken from the differences between the SDL2 and SDL3 versions of the game. They are not complete but intended to give you an idea of some of the changes you may need to do.

SDL_TTF

TTF_RenderUTF8_Blended( is now TTF_RenderText_Blended with an extra text length parameter.

SDL_Rects are mostly replaced by SDL_FRect

This is a big change. Everywhere I was passing in an SDL_Rect became an SDL_Frect which is four floats rather than four ints.

SDL_RenderCopy is now SDL_RenderTexture and the last two params are now SDL_FRects.

To fix this I used a load of (float) casts.

SDL_RenderDrawLine becomes SDL_RenderLine and has an SDL_FRect parameter instaed of SDL_Rect.

Same for SDL_RenderDrawPoint which becomes SDL_RenderPoint.

SDL_GetMouseState keeps the same name but returns float * for both parameters now.

Setup changes slightly

There’s no SDL_SetMainReady() and SDL2main.lib is gone.

Also gone is SDL_INIT_EVERYTHING in SDL_Init()– you have to or the specific subunits. E.g. SDL_INIT_VIDEO | SDL_INIT_EVENTS

Also there’s no SDL_RENDERER_PRESENTVSYNC for SDL_CreateRenderer. Vsync is disabled by default as I found when my game ran about 30x faster and finished in a few seconds! Instead you need to call SDL_SetRenderVSync(renderer, 1) where 1 is syncing with each retrace, or 2 with every 2nd retrace.

Several of the events have been renamed, so SDL_KEYDOWN becomes SDL_EVENT_KEY_DOWN, SDL_MOUSEBUTTONDOWN becomes  SDL_EVENT_MOUSE_BUTTON_DOWN and similar for other events.  Also event.key.keysym.sym becomes event.key.key.

Finally SDL_FreeSurface( becomes SDL_DestroySurface.

I’m sure there are more but changing these was sufficent to get my game compiling and running correctly with SDL3.

Rust on Windows – problem with sdl2.lib

Rust on Windows – problem with sdl2.lib

I’m currently unable to compile Rust programs that use SDL2 on Windows. No problems on Ubuntu or Raspberry Pi OS, just Windows 11.
Compiling an SDL2 app (in Rust) on WindowsAlthough it says cannot open input file SDL2.lib, I think the problem is a parameter passed into Link.exe.

The text from the image above is listed below- I’ve broken it to make it readable as it’s displayed preformatted and unmodified it is all on a single very wide line!

 = note: "C:\\Program Files\\Microsoft Visual Studio\22\\Community\\VC\\Tools\\MSVC\.43.34808\\bin\\HostX64\\x64\\link.exe" 
"/NOLOGO" "C:\\Users\\dhbol\\AppData\\Local\\Temp\\rustcA1PhoK\\symbols.o" "<70 object files omitted>" 
"D:\\development\\rustapps\\choice\\target\\debug\\deps/{libsdl2-f8d94d30d19bed49.rlib,libsdl2_sys-325e30d8e9547ff4.rlib,
libbitflags-d15393d08e2f31fc.rlib,liblazy_static-c28c0e13093a4168.rlib,liblibc-851e0bf801239f69.rlib}.rlib" 
"<sysroot>\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib/{libstd-*,libpanic_unwind-*,libwindows_targets-*,
librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libunwind-*,libcfg_if-*,liballoc-*,
librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "SDL2.lib" "SDL2_image.lib" "SDL2_ttf.lib" 
"legacy_stdio_definitions.lib" "kernel32.lib" "kernel32.lib" "advapi32.lib" "ntdll.lib" "userenv.lib" "ws2_32.lib" 
"dbghelp.lib" "/defaultlib:msvcrt" "/NXCOMPAT" "/OUT:D:\\development\\rustapps\\choice\\target\\debug\\deps\\choice.exe" 
"/OPT:REF,NOICF" "/DEBUG" "/PDBALTPATH:%_PDB%" "/NATVIS:<sysroot>\\lib\\rustlib\\etc\\intrinsic.natvis" 
"/NATVIS:<sysroot>\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:<sysroot>\\lib\\rustlib\\etc\\libcore.natvis" 
"/NATVIS:<sysroot>\\lib\\rustlib\\etc\\libstd.natvis"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: LINK : fatal error LNK1181: cannot open input file 'SDL2.lib'␍

But if you try running part of it like the first line
“C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\link.exe”
“/NOLOGO” “C:\\Users\\dhbol\\AppData\\Local\\Temp\\rustcA1PhoK\\symbols.o”

Well the path to link..exe is correct, but there’s no  rustcA1PhoK\symbols.o in that temp folder. Any suggestions welcomed…

I just solved it.

I’ve left this in, in case anyone else has this problem.

You need to add an environment variable LIB with the address of the SDL .lib files including ttf, image and mixer. Make sure they’re all in this folder:

C:\Users\dhbol\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib

The bold part of the path will be different on you PC.

In File Explorer, right-click on This PC then click Properties on the popup menu.

File Explorer - This PC,.

 

 

 

It’ll open Settings – About, and you need to click Advanced system settings.

settings_about

This opens System Properties and on that you click Environment variables.

System properties on Windows

Environment variables popup on Windows

 

 

 

 

 

 

 

 

Now just click New and add Lib and that path It should look something like mine. Now reopen Visual Studio and your SDL2 Rust app should now build and run.

Interesting bug with controllermap

Interesting bug with controllermap

Running a Rust program to show gamepad controls

So I’ve been playing with a Rust program that uses the config string generated by controllermap. It shows all the keys and the text of a particular button turns green when you press it and it shows PRESSED/RELEASED.

But it got A and B buttons mixed up and also X and Y. I’d press A, it highlighted B etc.

I checked my code, it wasn’t there. I ran controllermap again and it generated a similar config string.

I then went back to the Pi version of Asteroids, put it on a Pi, started debugging it, pressed the fire button and it hit the line of code for the A button. D’oh.

The only conclusion I can come up with is that controllermap gets it wrong for my gamepad. I had somehow missed it when I added gamepad control for the Asteroid Pi.

It’s quite easy to fix.  This is what the full text in gamepad.txt look like.

030000001008000001e5000010010000,usb gamepad,platform:Linux,crc:417e,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,

but we’re only interesed in the button mappings for a,b, x and y which are in bold.

a:b2,b:b1,x:b3,y:b0,

Just swap the a b mappings and the x and y so it looks like

a:b1,b:b2,x:b0,y,b3

Then save the file and it now works correctly.

 

So I found the fix

So I found the fix

It's fixed text on a technology backgroundWell actually I asked Microsoft’s CoPilot AI and it sorted it!

This is what you need in the dependencies section in cargo.toml

[dependencies]
sdl2-sys = "*"
sdl2 = { version = "0.37", features = ["image","ttf"] }

It compiled with no problems after saving that.

A slight problem with SDL2 and Rust

A slight problem with SDL2 and Rust

VS Code Rust SDL Copikle problemThis is on Ubuntu 24.04 LTS. I’ve installed the dev versions of SDL2, including images and TTF.  You can read how to install them in this tutorial.

Once that’s done you add them to the rust project with commands like this

cargo add sdl2

You can see these instruction in the relevant crates pages. For instance SDL2 crate, SDL2 Image and SDL2 TTF.

So far so good. The cargo add added the crates into cargo.toml as expected but when I compiled it. Not a compile error as such but a version of dll hell.

The text in that image says:

Updating crates.io index
error: failed to select a version for `sdl2-sys`.
... required by package `sdl2_image v0.25.0`
... which satisfies dependency `sdl2_image = "^0.25.0"` of package `sdl1 v0.1.0 (/home/david/rust/sdl1)`
versions that meet the requirements `^0.25.0` are: 0.25.0

the package `sdl2-sys` links to the native library `SDL2`, but it conflicts with a previous package which links to `SDL2` as well:
package `sdl2-sys v0.37.0`
... which satisfies dependency `sdl2-sys = "^0.37.0"` of package `sdl1 v0.1.0 (/home/david/rust/sdl1)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "SDL2"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

failed to select a version for `sdl2-sys` which could resolve this conflict

The problem appears to be a clash between sdl-sys and sdl2-ttf or sdl2-image. If anyone knows a fix…

 

Compiling C with Visual C++ 2022

Compiling C with Visual C++ 2022

monitor displaying programming languageIt’s been a few years since I compiled the code for the first eBook and I needed to create an SDL application on Windows. I copied a project, as it was the fastest way to setup the include and lib paths, and the lib files needed to compile.

Compared to clang/gcc on Linux, setting up visual studio projects on Windows can be a bit of a pita. You’ve got to be careful not to mix up the x64 and x86 files, add everything twice (once for Win 32 and once for x64).

So I copied .sln and .vcxproj files, started compiling and kept getting this error:

Error LNK2019 unresolved external symbol main referenced in function “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) maze D:\development\LinuxFormat\maze\MSVCRTD.lib(exe_main.obj) 

I messed around with settings, still no joy. did a bit of searching around and found that some people fixed it by setting the Link System Subsystem but that didn’t fix it. Also one person had forgotten to add SDL2_main.lib to the list of lib files to be linked in.

Then I noticed the project was defaulting to 64-bit. I checked my includes and it was only setup for 32-bit. D’oh. So copying the settings from 32-bit to 64-bit fixed it.

Update to the Windows eBook

Update to the Windows eBook

Visual Studio configurationA reader asked me how to setup SDL2 for Windows given recent changes in SDL2. Specifically the files and libsdl projects have been moved from the libsdl.org website to GitHub. You can easily find SDL2 Image, Mixer, TTF etc.

However it can still be quite daunting setting up Visual Studio for SDL2. You have to download the specific files, then configure the project properties to specify the include paths for header files and then the lib files, both the path to them and identify the ones you want to use.

As I’m on my new PC, I bit the bullet and went through the process of setting it up. It took just over an hour to configure it.  I’ve put it into a PDF that’s a couple of pages long.

So the game works but only after I disabled the sound code; it was failing in the call to Mix_OpenAudio(). I think recent work on the SDL Mixer needs some work on my part. I need to sit down and look at the SDL Mixer page and figure out what’s failing. Once that’s done, I’ll update the files.

 

New Tutorial on getting started with SDL

New Tutorial on getting started with SDL

SDL REctanglesI had this tutorial pencilled in to do and it’s now done. It’s the old SDL rectangles program that was part of the eBook. I’ve modernised it a bit so the same file will now compile under either MSVC on Windows or VS Code/Clang on Linux without changes.

I used the _WIN32 predefined macro so it compiles the call to Windows cod on Windows. Here’s an example:

#ifdef _WIN32
		sprintf_s(buff, sizeof(buff), "%10.6f", getElapsedTime(&s));
#else
		snprintf(buff, sizeof(buff),"%10.6f",diff(&s));
#endif

I do a similar thing with the path to SDL which is “SDL.h” on Windows but “SDL2/SDL.h” on Ubuntu. Writing code this way makes it  lot less of a hassle.

The game of 2048 in C in your browser

The game of 2048 in C in your browser

2048 game playing in a browserBack in 2014, an Italian developer called Gabriele Cirulli devised a puzzle game called 2048. It has been implemented on many platforms (I have it on my iPhone) and here is a link to a C version of it (in 300 lines) by developer Nishchith Shetty that plays it in a browser using WebAssembly.

The idea behind the puzzle is that you combine the numbered pieces by moving pieces intro same numbered pieces. 2 into 3, 4 into 4 and so on.

WebAssembly is the technology that lets you run programs in many languages (including C and C++) in your browser at speeds up to 50% of native code.  It’s also used in Blazor where you can write C# programs that run in the browser.

To convert the C code to WebAssembly, you have to install a transpiler (a program that converts one programming language to another) called Emscripten, then it’s a single command line instruction to build the WebAssembly from the C sources and SDL2. Or you can just play it online here.

I’ve been meaning to do a WebAssembly version of my asteroids game using Emscripten. it’s just been sheer laziness that I haven’t got round to it.