Update SDL3 from 3.2.4 to 3.2.20

This commit is contained in:
Sven Balzer
2025-08-27 21:24:05 +02:00
parent 6283160467
commit ad651462df
332 changed files with 20334 additions and 4852 deletions
+16 -9
View File
@@ -5,7 +5,12 @@ The easiest way to use SDL is to include it as a subproject in your project.
We'll start by creating a simple project to build and run [hello.c](hello.c)
Create the file CMakeLists.txt
# Get a copy of the SDL source:
```sh
git clone https://github.com/libsdl-org/SDL.git vendored/SDL
```
# Create the file CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 3.16)
project(hello)
@@ -25,24 +30,26 @@ add_executable(hello WIN32 hello.c)
target_link_libraries(hello PRIVATE SDL3::SDL3)
```
Build:
# Configure and Build:
```sh
cmake -S . -B build
cmake --build build
```
Run:
- On Windows the executable is in the build Debug directory:
```sh
cd build/Debug
./hello
```
- On other platforms the executable is in the build directory:
# Run:
The executable should be in the `build` directory:
```sh
cd build
./hello
```
If there wasn't an executable there despite the above Build section running successfully, it's likely because you're following this guide using the Visual Studio toolchain, it should instead be in the `build/Debug` directory:
```sh
cd build/Debug
./hello
```
A more complete example is available at:
https://github.com/Ravbug/sdl3-sample
+95
View File
@@ -0,0 +1,95 @@
# Introduction to SDL with MinGW
Without getting deep into the history, MinGW is a long running project that aims to bring gcc to Windows. That said, there's many distributions, versions, and forks floating around. We recommend installing [MSYS2](https://www.msys2.org/), as it's the easiest way to get a modern toolchain with a package manager to help with dependency management. This would allow you to follow the MSYS2 section below.
Otherwise you'll want to follow the "Other Distributions" section below.
We'll start by creating a simple project to build and run [hello.c](hello.c).
# MSYS2
Open the `MSYS2 UCRT64` prompt and then ensure you've installed the following packages. This will get you working toolchain, CMake, Ninja, and of course SDL3.
```sh
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-sdl3
```
## Create the file CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 3.26)
project(hello C CXX)
find_package(SDL3 REQUIRED)
add_executable(hello)
target_sources(hello
PRIVATE
hello.c
)
target_link_libraries(hello SDL3::SDL3)
```
## Configure and Build:
```sh
cmake -S . -B build
cmake --build build
```
## Run:
The executable is in the `build` directory:
```sh
cd build
./hello
```
# Other Distributions
Things can get quite complicated with other distributions of MinGW. If you can't follow [the cmake intro](INTRO-cmake.md), perhaps due to issues getting cmake to understand your toolchain, this section should work.
## Acquire SDL
Download the `SDL3-devel-<version>-mingw.zip` asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest) Then extract it inside your project folder such that the output of `ls SDL3-<version>` looks like `INSTALL.md LICENSE.txt Makefile README.md cmake i686-w64-mingw32 x86_64-w64-mingw32`.
## Know your Target Architecture
It is not uncommon for folks to not realize their distribution is targeting 32bit Windows despite things like the name of the toolchain, or the fact that they're running on a 64bit system. We'll ensure we know up front what we need:
Create a file named `arch.c` with the following contents:
```c
#include <stddef.h>
#include <stdio.h>
int main() {
#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
size_t ptr_size = sizeof(int*);
if (4 == ptr_size) puts("i686-w64-mingw32");
else if (8 == ptr_size) puts("x86_64-w64-mingw32");
else puts("Unknown Architecture");
#else
puts("Unknown Architecture");
#endif
return 0;
}
```
Then run
```sh
gcc arch.c
./a.exe
```
This should print out which library directory we'll need to use when compiling, keep this value in mind, you'll need to use it when compiling in the next section as `<arch>`. If you get "Unknown Architecture" please [report a bug](https://github.com/libsdl-org/SDL/issues).
## Build and Run
Now we should have everything needed to compile and run our program. You'll need to ensure to replace `<version>` with the version of the release of SDL3 you downloaded, as well as use the `<arch>` we learned in the previous section.
```sh
gcc hello.c -o hello.exe -I SDL3-<version>/<arch>/include -L SDL3-<version>/<arch>/lib -lSDL3 -mwindows
cp SDL3-<version>/<arch>/bin/SDL3.dll SDL3.dll
./hello.exe
```
+5 -3
View File
@@ -5,10 +5,12 @@ The easiest way to use SDL is to include it as a subproject in your project.
We'll start by creating a simple project to build and run [hello.c](hello.c)
- Get a copy of the SDL source, you can clone the repo, or download the "Source Code" asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest)
- If you've downloaded a release, make sure to extract the contents somewhere you can find it.
- Create a new project in Visual Studio, using the C++ Empty Project template
- Add hello.c to the Source Files
- Right click the solution, select add an existing project, navigate to VisualC/SDL and add SDL.vcxproj
- Select your main project and go to Project -> Add Reference and select SDL3
- Select your main project and go to Project -> Properties, set the filter at the top to "All Configurations" and "All Platforms", select VC++ Directories and add the SDL include directory to "Include Directories"
- Right click the solution, select add an existing project, navigate to `VisualC/SDL` from within the source you cloned or downloaded above and add SDL.vcxproj
- Select your main project and go to Project -> Add -> Reference and select SDL3
- Select your main project and go to Project -> Properties, set the filter at the top to "All Configurations" and "All Platforms", select C/C++ -> General and add the SDL include directory to "Additional Include Directories"
- Build and run!
+8 -8
View File
@@ -242,7 +242,7 @@ not give you any processing time after the events are delivered.
e.g.
int HandleAppEvents(void *userdata, SDL_Event *event)
bool HandleAppEvents(void *userdata, SDL_Event *event)
{
switch (event->type)
{
@@ -250,12 +250,12 @@ e.g.
/* Terminate the app.
Shut everything down before returning from this function.
*/
return 0;
return false;
case SDL_EVENT_LOW_MEMORY:
/* You will get this when your app is paused and iOS wants more memory.
Release as much memory as possible.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_BACKGROUND:
/* Prepare your app to go into the background. Stop loops, etc.
This gets called when the user hits the home button, or gets a call.
@@ -264,15 +264,15 @@ e.g.
in addition, you should set the render target to NULL, if you're using
it, e.g. call SDL_SetRenderTarget(renderer, NULL).
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_BACKGROUND:
/* Your app is NOT active at this point. */
return 0;
return false;
case SDL_EVENT_WILL_ENTER_FOREGROUND:
/* This call happens when your app is coming back to the foreground.
Restore all your state here.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_FOREGROUND:
/* Restart your loops here.
Your app is interactive and getting CPU again.
@@ -283,10 +283,10 @@ e.g.
event SDL_EVENT_RENDER_DEVICE_RESET and recreate your OpenGL context and
restore your textures when you get it, or quit the app.
*/
return 0;
return false;
default:
/* No special processing, add it to the event queue */
return 1;
return true;
}
}
+30 -26
View File
@@ -1,32 +1,6 @@
SDL 3.0 has new support for high DPI displays. Interfaces provided by SDL uses the platform's native coordinates unless otherwise specified.
To reconcile platform differences in their approach to high-density scaling, SDL provides the following interfaces:
- `SDL_GetWindowSize()` retrieves the window dimensions in native coordinates.
- `SDL_GetWindowSizeInPixels()` retrieves the window dimensions in pixels-addressable.
- `SDL_GetDisplayContentScale()` retrieves the suggested amplification factor when drawing in native coordinates.
- `SDL_GetWindowDisplayScale()` retrieves the suggested amplification factor when drawing in pixels-addressable.
- `SDL_GetWindowPixelDensity()` retrieves how many addressable pixels correspond to one unit of native coordinates.
- `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` is emitted when the value retrievable from `SDL_GetWindowSizeInPixels()` changes.
- `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` is emitted when the value retrievable from `SDL_GetWindowDisplayScale()` changes.
- Windows created with `SDL_WINDOW_HIGH_PIXEL_DENSITY` will ask the platform to display addressable pixels at their natural scale.
## Numeric example
Given a fullscreen window spanning a 3840x2160 monitor set to 2x display or 200% scaling, the following tabulates the effect of creating a window with or without `SDL_WINDOW_HIGH_PIXEL_DENSITY` on MacOS and Win32:
| Value | MacOS (Default) | MacOS (HD) | Win32 (Default & HD) |
|--------------------------------|-----------------|------------|----------------------|
| `SDL_GetWindowSize()` | 1920x1080 | 1920x1080 | 3840x2160 |
| `SDL_GetWindowSizeInPixels()` | 1920x1080 | 3840x2160 | 3840x2160 |
| `SDL_GetDisplayContentScale()` | 1.0 | 1.0 | 2.0 |
| `SDL_GetWindowDisplayScale()` | 1.0 | 2.0 | 2.0 |
| `SDL_GetWindowPixelDensity()` | 1.0 | 2.0 | 1.0 |
Observe the philosophical difference between the approaches taken by MacOS and Win32:
- Win32 coordinate system always deals in physical device pixels, high DPI support is achieved by providing an advisory hint for the developer to enlarge drawn objects. Ignoring the advisory scale factor results in graphics appearing tiny.
- MacOS coordinate system always deals in physical content sizes, high DPI support is achieved by providing an optional flag for the developer to request finer granularity. Omitting the granularity request results in graphics appearing coarse.
## Explanation
Displays now have a content display scale, which is the expected scale for content based on the DPI settings of the display. For example, a 4K display might have a 2.0 (200%) display scale, which means that the user expects UI elements to be twice as big on this display, to aid in readability. You can query the display content scale using `SDL_GetDisplayContentScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event.
@@ -34,3 +8,33 @@ Displays now have a content display scale, which is the expected scale for conte
The window size is now distinct from the window pixel size, and the ratio between the two is the window pixel density. If the window is created with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, SDL will try to match the native pixel density for the display, otherwise it will try to have the pixel size match the window size. You can query the window pixel density using `SDL_GetWindowPixelDensity()`. You can query the window pixel size using `SDL_GetWindowSizeInPixels()`, and when this changes you get an `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event. You are guaranteed to get a `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event when a window is created and resized, and you can use this event to create and resize your graphics context for the window.
The window has a display scale, which is the scale from the pixel resolution to the desired content size, e.g. the combination of the pixel density and the content scale. For example, a 3840x2160 window displayed at 200% on Windows, and a 1920x1080 window with the high density flag on a 2x display on macOS will both have a pixel size of 3840x2160 and a display scale of 2.0. You can query the window display scale using `SDL_GetWindowDisplayScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event.
## Numeric example
Given a window spanning a 3840x2160 monitor set to 2x display or 200% scaling, the following tabulates the effect of creating a window with or without `SDL_WINDOW_HIGH_PIXEL_DENSITY` on macOS and Windows:
| Value | macOS (Default) | macOS (HD) | Windows (Default & HD) |
|--------------------------------|-----------------|------------|------------------------|
| `SDL_GetWindowSize()` | 1920x1080 | 1920x1080 | 3840x2160 |
| `SDL_GetWindowSizeInPixels()` | 1920x1080 | 3840x2160 | 3840x2160 |
| `SDL_GetDisplayContentScale()` | 1.0 | 1.0 | 2.0 |
| `SDL_GetWindowDisplayScale()` | 1.0 | 2.0 | 2.0 |
| `SDL_GetWindowPixelDensity()` | 1.0 | 2.0 | 1.0 |
Observe the difference between the approaches taken by macOS and Windows:
- The Windows and Android coordinate system always deals in physical device pixels, high DPI support is achieved by providing a content scale that tells the developer to draw objects larger. Ignoring this scale factor results in graphics appearing tiny.
- The macOS and iOS coordinate system always deals in window coordinates, high DPI support is achieved by providing an optional flag for the developer to request more pixels. Omitting this flag results in graphics having low detail.
- On Linux, X11 uses a similar approach to Windows and Wayland uses a similar approach to macOS.
## Solution
Proper high DPI support takes into account both the content scale and the pixel density.
First, you'd create your window with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, assuming you want the highest detail possible. Then you'd get the window display scale to see how much your UI elements should be enlarged to be readable.
If you're using the SDL 2D renderer, SDL provides the function `SDL_ConvertEventToRenderCoordinates()` to convert mouse coordinates between window coordinates and rendering coordinates, and the more general functions `SDL_RenderCoordinatesFromWindow()` and `SDL_RenderCoordinatesToWindow()` to do other conversion between them.
If you're not using the 2D renderer, you can implement this yourself using `SDL_GetWindowPixelDensity()` as scale factor to convert from window coordinates to pixels.
Finally you'll want to test on both Windows and macOS if possible to make sure your high DPI support works in all environments.
+8 -8
View File
@@ -65,7 +65,7 @@ not give you any processing time after the events are delivered.
e.g.
int HandleAppEvents(void *userdata, SDL_Event *event)
bool HandleAppEvents(void *userdata, SDL_Event *event)
{
switch (event->type)
{
@@ -73,37 +73,37 @@ e.g.
/* Terminate the app.
Shut everything down before returning from this function.
*/
return 0;
return false;
case SDL_EVENT_LOW_MEMORY:
/* You will get this when your app is paused and iOS wants more memory.
Release as much memory as possible.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_BACKGROUND:
/* Prepare your app to go into the background. Stop loops, etc.
This gets called when the user hits the home button, or gets a call.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_BACKGROUND:
/* This will get called if the user accepted whatever sent your app to the background.
If the user got a phone call and canceled it, you'll instead get an SDL_EVENT_DID_ENTER_FOREGROUND event and restart your loops.
When you get this, you have 5 seconds to save all your state or the app will be terminated.
Your app is NOT active at this point.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_FOREGROUND:
/* This call happens when your app is coming back to the foreground.
Restore all your state here.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_FOREGROUND:
/* Restart your loops here.
Your app is interactive and getting CPU again.
*/
return 0;
return false;
default:
/* No special processing, add it to the event queue */
return 1;
return true;
}
}
+6 -2
View File
@@ -19,7 +19,7 @@ Ubuntu 18.04, all available features enabled:
libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \
libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev
Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev` to that command line.
@@ -28,7 +28,7 @@ Fedora 35, all available features enabled:
sudo yum install gcc git-core make cmake \
alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \
libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \
libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \
libXi-devel libXScrnSaver-devel dbus-devel ibus-devel \
systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \
mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \
libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \
@@ -45,6 +45,10 @@ openSUSE Tumbleweed:
sudo zypper in libunwind-devel libusb-1_0-devel Mesa-libGL-devel libxkbcommon-devel libdrm-devel \
libgbm-devel pipewire-devel libpulse-devel sndio-devel Mesa-libEGL-devel
Arch:
sudo pacman -S alsa-lib cmake hidapi ibus jack libdecor libgl libpulse libusb libx11 libxcursor libxext libxinerama libxkbcommon libxrandr libxrender libxss mesa ninja pipewire sndio vulkan-driver vulkan-headers wayland wayland-protocols
Joystick does not work
--------------------------------------------------------------------------------
+2 -2
View File
@@ -49,7 +49,7 @@ NSApplicationDelegate implementation:
```objc
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
if (SDL_GetEventState(SDL_EVENT_QUIT) == SDL_ENABLE) {
if (SDL_EventEnabled(SDL_EVENT_QUIT)) {
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_QUIT;
@@ -61,7 +61,7 @@ NSApplicationDelegate implementation:
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if (SDL_GetEventState(SDL_EVENT_DROP_FILE) == SDL_ENABLE) {
if (SDL_EventEnabled(SDL_EVENT_DROP_FILE)) {
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_DROP_FILE;
+1 -1
View File
@@ -411,7 +411,7 @@ The iscapture field of SDL_AudioDeviceEvent has been renamed recording.
SDL_QUERY, SDL_IGNORE, SDL_ENABLE, and SDL_DISABLE have been removed. You can use the functions SDL_SetEventEnabled() and SDL_EventEnabled() to set and query event processing state.
SDL_AddEventWatch() now returns SDL_FALSE_ if it fails because it ran out of memory and couldn't add the event watch callback.
SDL_AddEventWatch() now returns false if it fails because it ran out of memory and couldn't add the event watch callback.
SDL_RegisterEvents() now returns 0 if it couldn't allocate any user events.
+1 -1
View File
@@ -11,7 +11,7 @@
- [macOS](README-macos.md)
- [NetBSD](README-bsd.md)
- [Nintendo Switch](README-switch.md)
- [Nintendo 3DS](README-3ds.md)
- [Nintendo 3DS](README-n3ds.md)
- [OpenBSD](README-bsd.md)
- [PlayStation 2](README-ps2.md)
- [PlayStation 4](README-ps4.md)
+1 -1
View File
@@ -29,7 +29,7 @@ cmake --install build
## Compiling a HelloWorld
[PSP Hello World](https://psp-dev.org/doku.php?id=tutorial:hello_world)
[PSP Hello World](https://pspdev.github.io/basic_programs.html#hello-world)
## To Do
- PSP Screen Keyboard
+28 -40
View File
@@ -1,60 +1,48 @@
# Versioning
## Since 2.23.0
## Since 3.2.0
SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak
and older versions of the Linux kernel:
* The major version (first part) increases when backwards compatibility
is broken, which will happen infrequently.
* If the minor version (second part) is divisible by 2
(for example 2.24.x, 2.26.x), this indicates a version of SDL that
is believed to be stable and suitable for production use.
* If the minor version (second part) and the patch version (third part) is
divisible by 2 (for example 3.2.6, 3.4.0), this indicates a version of
SDL that is believed to be stable and suitable for production use.
* In stable releases, the patchlevel or micro version (third part)
indicates bugfix releases. Bugfix releases should not add or
remove ABI, so the ".0" release (for example 2.24.0) should be
forwards-compatible with all the bugfix releases from the
same cycle (for example 2.24.1).
indicates bugfix releases. Bugfix releases may add small changes
to the ABI, so newer patch versions are backwards-compatible but
not fully forwards-compatible. For example, programs built against
SDL 3.2.0 should work fine with SDL 3.2.8, but programs built against
SDL 3.2.8 may not work with 3.2.0.
* The minor version increases when new API or ABI is added, or when
other significant changes are made. Newer minor versions are
backwards-compatible, but not fully forwards-compatible.
For example, programs built against SDL 2.24.x should work fine
with SDL 2.26.x, but programs built against SDL 2.26.x will not
necessarily work with 2.24.x.
* The minor version increases when significant changes are made that
require longer development or testing time, e.g. major new functionality,
or revamping support for a platform. Newer minor versions are
backwards-compatible, but not fully forwards-compatible. For example,
programs built against SDL 3.2.x should work fine with SDL 3.4.x,
but programs built against SDL 3.4.x may not work with 3.2.x.
* If the minor version (second part) is not divisible by 2
(for example 2.23.x, 2.25.x), this indicates a development prerelease
of SDL that is not suitable for stable software distributions.
* If the minor version (second part) or patch version (third part) is not
divisible by 2 (for example 3.2.9, 3.3.x), this indicates a development
prerelease of SDL that is not suitable for stable software distributions.
Use with caution.
* The patchlevel or micro version (third part) increases with
each prerelease.
* Each prerelease might add new API and/or ABI.
* The patchlevel or micro version (third part) increases with each prerelease.
* Prereleases are backwards-compatible with older stable branches.
For example, 2.25.x will be backwards-compatible with 2.24.x.
For example, programs built against SDL 3.2.x should work fine with
SDL 3.3.x, but programs built against SDL 3.3.x may not work with 3.2.x.
* Prereleases are not guaranteed to be backwards-compatible with
each other. For example, new API or ABI added in 2.25.1
might be removed or changed in 2.25.2.
If this would be a problem for you, please do not use prereleases.
* Prereleases are not guaranteed to be backwards-compatible with each other.
For example, new API or ABI added in 3.3.0 might be removed or changed in
3.3.1. If this would be a problem for you, please do not use prereleases.
* Only upgrade to a prerelease if you can guarantee that you will
promptly upgrade to the stable release that follows it.
For example, do not upgrade to 2.23.x unless you will be able to
upgrade to 2.24.0 when it becomes available.
* Only use a prerelease if you can guarantee that you will promptly upgrade
to the stable release that follows it. For example, do not use 3.3.x
unless you will be able to upgrade to 3.4.0 when it becomes available.
* Software distributions that have a freeze policy (in particular Linux
distributions with a release cycle, such as Debian and Fedora)
should usually only package stable releases, and not prereleases.
should only package stable releases, and not prereleases.
## Before 2.23.0
Older versions of SDL followed a similar policy, but instead of the
odd/even rule applying to the minor version, it applied to the patchlevel
(micro version, third part). For example, 2.0.22 was a stable release
and 2.0.21 was a prerelease.
+4
View File
@@ -59,6 +59,10 @@ encounter limitations or behavior that is different from other windowing systems
`SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your
application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`.
### Keyboard grabs don't work when running under XWayland
- On GNOME based desktops, the dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled.
## Using custom Wayland windowing protocols with SDL windows
Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window.