Files
kaizen/docs/README-migration.md
SimoZ64 28d94e8b86 Squashed 'external/SDL/' changes from 8ec576dda..90fd2a3cb
90fd2a3cb Sync SDL3 wiki -> header
edd08771a wayland: Add xdg_toplevel v7 edge constraint support
113475acb wayland: Add multi-seat support
4093e4a19 Fixed process I/O redirection to NUL on Windows
c025fdbb7 Add the CREATE_NO_WINDOW flag for background processes
8a57c83ff Updated to GameInput v1.1
f35a2736b Don't reset the render target when invalidating GPU renderer cache state
47e52ab37 Sync SDL3 wiki -> header
6a3dbe34d Sync SDL3 wiki -> header
d84c000ac Sync SDL3 wiki -> header
98e76d283 Fixed conflict when linking both SDL and hidapi statically
f6db5ba4c Add Turtle Beach VelocityOne
a1016bd06 Allow 01-joystick-polling example to be resizable
60fb1b554 Fix IMU orientations for 8bitdo wireless 2 controller in bluetooth mode
b0860fb0c Disable EGL in Emscripten builds
f303ccca6 Updated the report size for Ultimate 2 Wireless firmware v1.02
0add03780 [Windows]: dialog: Add `OFN_OVERWRITEPROMPT` to save dialogs (#12782)
a390f5716 docs: improve man page generation
93ac1e689 Fixed non-XBox controllers being detected as Series X controllers
d29bb902f Don't treat the Keychron K1 Pro System Control keyboard as a joystick
ab57ef9d7 update sdlgenblit.pl after PR/12769
b0a0d236d fix sdlgenblit.pl so that it actually matches the generated source
0fdfa925f rename local pointer vars 'pixel' to 'pixels'
46c314cc3 Revert "bool is 4 bytes in Apple MacOS X 32 bit PPC ABI"
2abfb92c5 Sync SDL3 wiki -> header
97eddacd7 Use the actual value of EGL_PLATFORM_DEVICE_EXT if it's not defined
4c1a3ccd4 rename local vars 'pixel' to 'pixelvalue'
433704e77 rename 'pixel' params of SDL_GetRGB, SDL_GetRGBA and SDL_LookupRGBAColor
83b261ae8 Remove unused message box includes
cccad933a Updated version documentation to match SDL 3.x practice
adad7dcae x11/wayland: Ignore redundant restore and fullscreen leave requests when showing the window
d7d6d8e28 Sync SDL3 wiki -> header
f7b718883 Add SDL_CreateGPURenderer
5a59b5f32 bool is 4 bytes in Apple MacOS X 32 bit PPC ABI
3b9101768 pulseaudio: cleanup TLS every time we finish a threaded-mainloop callback.
646f1f243 x11: Only enable _NET_WM_SYNC_REQUEST for OpenGL windows
33f90f2e4 GPU Vulkan: Clean up in Submit in headless mode (#12744)
93b06cffd Sync SDL3 wiki -> header
c2c3a930b Add STRING suffix to SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_* string properties
44710a248 gpu: alpha-to-coverage support
d6d2c958a Move global event handlers to SDL_VideoInit
05939909d SDL_gpu.h: SDL_GetGPUDeviceProperties() is thread-safe.
1687bc746 Sync SDL3 wiki -> header
accd952c4 SDL_gpu.h: Another attempt to clean up SDL_GetGPUDeviceProperties() docs.
c5f369f55 Sync SDL3 wiki -> header
0c9eccd0e Sync SDL3 wiki -> header
906c6c751 GPU: Add missing error code to VkErrorMessages()
205c34c62 GPU: The D3D12 blit shaders are DXIL
300013cea GPU: Don't pass null properties to SDL_CopyProperties()
8ad64aba1 GPU: Remove subheadings from SDL_GetGPUDeviceProperties() docs
94ab2b76a Sync SDL3 wiki -> header
85281be78 Re-added text removed by the wiki bridge
b53e7b447 GPU Vulkan: Fix recursive Submit calls causing defrag to fail (#12718)
b1919783c Sync SDL3 wiki -> header
39a3b14df Renamed SDL_GetGPUDeviceDebugProperties() to SDL_GetGPUDeviceProperties()
ca613b9d8 x11: Send a restored event before entering fullscreen
667b706a9 x11: Don't set the hidden flag when minimizing windows
6430aed3d Removed SDL_XInputVersion, which isn't used
40e08ee7a Assume new XBox controllers have a share button
6bb16296b Added special handling for SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY
ebb52973e cmake: make SDL_CPU_xxx variable visible when using CMAKE_OSX_ARCHITECTURES
b4af01cd0 only build static library in some feature tests
756b455d3 Fixed building for Xbox One
25232c077 Sync SDL3 wiki -> header
f78aa4d8e GPU: Expose debug information from devices
008690d01 Sync SDL3 wiki -> header
df3282740 Note that you might get a different size window than you expect
ab34ea5a2 Fixed documentation for SDL_GL_*_SIZE
87d6beb89 Rename cmake/sdltargets.cmake -> cmake/sdlcommands.cmake
208ec1829 Update README-documentation-rules.md
5709466dd Sync SDL3 wiki -> header
b52140086 Note that the Emscripten window properties are strings
82b245d13 Added support for the HORI Taiko No Tatsujin Drum Controller
12ef57ede Sync SDL3 wiki -> header
735b68581 Fixed wiki reformatting
cc8ec6cf1 Handle global mouse state for Emscripten (#12669)
53d053279 Sync SDL3 wiki -> header
cbc26fe2c Add Emscripten window data to window properties
4aefde015 Only send sensor data if sensors are enabled for 8BitDo controllers
6d7827344 Return early in stead of goto
c3ce216c4 Fixed crash at shutdown on Windows
e87a00c07 tests: port failing SDL_Renderer test from pysdl2 to testautomation
10819273b tests: port failing SDL_Renderer test from pysdl2 to testautomation
ffbd434a1 tests: port failing window  test from pysdl2 to testautomation
2775e7a78 tests: port failing SDL_Rect tests from pysdl2 to testautomation
39eed1d23 tests: port failing SDL_Hint tests from pysdl2 to testautomation
366a5281b Fixed comment
79a41ca7f Implemented DEBUG_8BITDO_PROTOCOL
5922e2cb7 Corrected comment with 8BitDo controller report sizes
0d9ff082f 8BitDo HIDAPI driver cleanup
e236a48e1 8BitDo
4de396734 More clarification for high DPI support
36fc1c2c9 Fixed texture colorspace when creating a texture from a surface
512485869 fix vulkan vertex buffer indexing
2e494fda3 Clarify high DPI support and best practices
44faac292 Fixed A/B/X/Y buttons on Nintendo 3DS
38c2081ae Temporarily default SDL_HINT_JOYSTICK_HIDAPI_8BITDO off
bcacc37e3 Sync SDL3 wiki -> header
e18c6bd2e 8BitDo (#12661)
6b1d6bfbe wayland: Commit the confinement region upon creation
266ee41c8 wayland: Defer creating cursor confinement regions until the surface is mapped
cb1d79db3 Sync SDL3 wiki -> header
088ad66f7 Update include/SDL3/SDL_power.h
032d69602 Add performance disclaimer in `SDL_GetPowerInfo` documentation
0d04e9ea6 Fixed build
7bb95bde4 Set the alpha opaque when blending to an RGB format
8eb57c5a4 diskaudio: Use SDL_GetAudioFormatName instead of recreating it from scratch.
f05bb7aae diskaudio: Log the raw PCM's format during "device" open.
210b317d8 x11: Popup positions after constraining are in the window-relative space, not global
daa7a5ad7 Updated Visual Studio example projects
f7a89d19c fix missing AVFoundation in CMakeLists.txt
a23f97483 Temporarily disable DwmFlush()
536a1a236 coreaudio: Added some NULL pointer checks.
712c76fdc gamepad: Fix inability to disable SDL_EVENT_GAMEPAD_UPDATE_COMPLETE events
418acf629 Sync SDL3 wiki -> header
633b9f6fb Added SDL_SetRenderTextureAddressMode() and SDL_GetRenderTextureAddressMode()
eb918af3d video: fix surface leak when duplicating mjpeg
567dfd2eb examples/renderer/19-affine-textures: add metadata for examples.libsdl.org.
5ab1aef36 examples/renderer/19-affine-textures: blue background so you can see the cube.
87e6d2250 examples, affine-textures: fix RISC-OS build.
254f34808 examples/renderer/19-affine-textures: Flip coords so SDL logo is right-side up.
391545105 examples/renderer/19-affine-textures: Whole source file was indented one space.
2ebcee203 examples: added examples/renderer/19-affine-textures to CMakeLists.txt.
2207f6bc9 examples/renderer/affine-textures: Fixed compiler warnings.
83eea00d6 Create affine-textures.c
401aaf3d2 video: Revert unnecessary member assignment
eed94cb03 Updated link to PSP Hello World
be2f7f206 Sync SDL3 wiki -> header
0f27c3aab Added SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING
289f5cfdb touch: Don't call ResetTouch() if SDL_GetTouch() can't find a virtual device.
b00b08f83 touch: Keep state correct when removing virtual touch devices during quit.
09fff161e cocoa: Clear pending state on fullscreen switch failures
05d23cae7 cocoa: Re-add sync timeout
2e61b4165 Don't send relative motion while in a modal loop
4c035a1fd audio: Allow PipeWire and PulseAudio streams to migrate to other sinks.
f3d4e6fe5 Sync SDL3 wiki -> header
8e6eaf12a wayland: Expose wl_output objects on video displays
1f917d523 Sync SDL3 wiki -> header
00f316737 Progress bar comment changes
e28974124 Added mappings for the NSO N64/SEGA/SNES controllers
b88200b79 Fixed face buttons for the NSO SNES controller under the HIDAPI driver
f355c7f21 Allow the progress API to be used on all platforms
b45ed98ae Fix spelling mistake in documentation
716e33f10 x11: Send the _XWAYLAND_MAY_GRAB_KEYBOARD message when grabbing the keyboard
a5633ad0f Sync SDL3 wiki -> header
6cc00a31b WindowProgressState API getters and fixes (#12629)
b520cde18 cocoa: Properly set the pending fullscreen spaces state when in a transition
dd9b9d451 Check if GL_OES_EGL_image_external is supported before trying to use it
7ec13a2ea Document SDL_malloc alignment guarantees
ae17b04c0 alsa: Don't start the hardware until the device thread is ready to do work.
41636959d audio: Feed output devices immediately, instead of waiting upfront.
48d4104ec pulseaudio: Fixed typo in commented-out debug logging.
8cb303126 wayland: Fix global mouse position retrieval
d6f137b2b Added a note to tag the wiki when doing feature releases
7f927de1f x11: remove 'args' and 'ret' from SDL_X11_SYM macro
b6ca03611 Fixed mixed trigger and body rumble for Xbox controllers on Windows
c3a3a11db keyboard: Don't check text input on a null window
035d9179a WIN_SetWindowProgressState(): Unsupported parameter error message
c217663fb SDL_SetWindowProgressState(): Add parameter validation check for `state`
3fa1bd81f Fixed previous commit renaming {add,remove}AudioDevice to native{Add,Remove}AudioDevice
b8381b3a2 Sync SDL3 wiki -> header
fa0a86409 Additions to progress bar comments
721476033 SDL_SetWindowProgressValue(): Move value clamp from `WIN_SetWindowProgressValue()` to `SDL_SetWindowProgressValue()`
69ad66b01 Fixed error messages in GetTaskbarList()
a3be7a137 WIN_SetWindowProgressValue(): Fix value clamp
017783835 Native functions renamed: {add,remove}AudioDevice to native{Add,Remove}AudioDevice
6e875397f Proguard: remove onNativePen
027df89ed wayland: Scale accelerated relative pointer coordinates with emulated resolutions
f52f982b1 chore: rename integer mode field names
8407a1625 Sync SDL3 wiki -> header
7a10fcdcc Add progress bar support for Windows (#12530)
6b13d6910 Improve move/resize visual smoothness on Windows
4fcef9074 audio: hold floating point exceptions when using neon
b493e29a8 x11: Fix backwards _NET_WM_SYNC_REQUEST init check
2fbb58329 SDL_ClaimWindowForGPUDevice() should fail for transparent windows
bde49abdb GPU: Support swapchain buffer transparency in Vulkan
79081a178 cocoa: Fix zoom check when leaving fullscreen
03cdd297e video: Fix boolean logic for getting the pending window position
fbdb63797 Fixed build when virtual joysticks are disabled
758eb256b Fixed DebugLogRenderCommands() output
4ceb02434 We need to rebind D3D12 resources after updating them
3538abfb8 Revert "Don't update a texture twice in the same batch on D3D12"
0681d0881 Don't update a texture twice in the same batch on D3D12
ac5b2b610 Don't send text event while ctrl/alt is held on X11/Wayland
365b7837c add private definitions to SDL_build_config.h.cmake
817260c73 Updates SDL_SetEventFilter code snippet to SDL3
3fd61b053 Updated for SDL style
581b61429 Emscripten: Support Custom Message Boxes (#12583)
54f5b7333 emscripten: Don't use legacy JS library functions for assertions
03a53ce0d Always show the on-screen keyboard on Steam Deck
8caeaaacd A Steam Controller might be generating keyboard input
cbb83be89 Show the on-screen keyboard if we don't have active keyboard input
67b4c3a15 Sync SDL3 wiki -> header
10072bb07 asyncio: SDL_LoadFileAsync was not null-terminating the file data.
85435d5a1 SDL_audio.h: Fixed typos in docs.
3ed61f203 Fixed applications that integrate Qt with SDL joystick support
de60a5f39 Revert "Make native functions be public otherwise it fails at run-time."
fe024b8fe Fixed typo in build.gradle
10fae8c34 Fixed Android build warnings
bf7b9b020 Fixed gradle deprecation warnings
ac2870250 Use the android-21 SDK as documented in README-android.md
476e7e54c Don't create surfaces with invalid pixel formats
6f456da63 GPU: Request sampleRateShading feature on Vulkan
4fd4d89b6 Make native functions be public otherwise it fails at run-time. (they are public such as the one in SDLActivity)
f2ed5c7a1 Fix illegal calls to DwmGetWindowAttribute()
96bf12444 Windows allows windows to be resized to zero height.
47b0c7547 Make sure we're getting called for the correct window
3415bc920 Fixed crash if a window couldn't be created on Windows
07e4dea69 The posix4 library has been merged into the libc library
9820f655d android: reduce visiblity as much as possible
c696e9318 GPU Vulkan: Fix render pass race (#12587)
7b93a744c time: Fix compilation on Solaris
14deef997 emscripten: Fix undefined behavior in opengles2 renderer
5283f7374 storage: Declare a private bootstrap for NDA user storage
8b924df48 Use an autoreleasepool in Cocoa_GetDisplayUsableBounds()
82335fd0e Fixed building with SDL_LEAN_AND_MEAN
a551c2a6d Fix Vulkan error check
5985f0a32 Fixed infinite recursion in SDL_IsGamepad()
6d0fb0a2e gpu: Fix MTLLibrary dispatch data destructor
3e5664a5b Fix return type in SDL_CreateGPURenderState
4fc9509ab Fixed raw input device GUIDs changing randomly between runs
0bd70684b GPU: Fix Vulkan backend never checking deallocations (#12567)
715301cef Fixed crash if info->path is NULL
f5eea7efa remove status message for SDL_STATIC_PIC PIC is controlled through CMAKE_POSITION_INDEPENDENT_CODE and not by an SDL option
35c03774f [SDL3] Adding input and FFB support for Logitech G29(PS3) on hidapi (#11598)
d66483dfc video: Send pending coordinates for moved, hidden windows
b9504f247 opengl: pixelart fragment shader uses GLSL version 1.30
05531c5f4 release: use NDK r21e for building Android release artifact
18185e30e Remove breaks under return
80ff0f45f Move default
3b58ad9d4 Add breaks and defaults to switch statements
8b6e9936e Missed a bracket
36ec4cd39 Align spacing
3b90ce499 Fix spacing; tabs to 4 spaces
60857935c Add preliminary joystick support for snake example
aad1e3516 mouse: Allow use of integer coordinates with fractional wheel events
501e71f25 Added unaligned version of SDL_ConvertPixels_SwapNV_std()
ad9f9af4e Removed accidentally enabled debug code
efe122be4 Removed width/height parameters from LoadTexture()
dcb97a5f4 Set a default shader entry point
1a2fccc56 hints: The auto mode switching hint is for 3.4.0
285fa671a Sync SDL3 wiki -> header
0bfe0497f video: Add a hint to disable auto mode switching if an exclusive fullscreen window moves between displays
58f6e9c27 Fix trailing doc comments
f15832c68 Sync SDL3 wiki -> header
17b84dbcf emscripten: add window properties for canvas ID and keyboard element (#12509)
ffe69fc35 Fixed SDL_GPUTextureSupportsSampleCount() documentation
e671bc265 Sync SDL3 wiki -> header
02faa8f75 Rename SDL_SetGPURenderStateFragmentUniformData() to SDL_SetGPURenderStateFragmentUniforms()
96194347b Added an example of fullscreen shader effects with the GPU renderer
2aee105b4 Added support for custom shaders with the GPU renderer
eb56c8af8 Sync SDL3 wiki -> header
1ae4ef65e Fixed incorrect assert
3e9e22f17 Added SDL_SCALEMODE_PIXELART
853375da6 Removed texture_size from the GPU renderer vertex shader
28ec461eb Organize the GPU renderer draw code
af0420d89 Switched GPU renderer shaders to shadercross and HLSL
c318b1f92 SDL_mutex.h: Fixed code example.
0e29c6295 gpu: Clean up unused code in Vulkan and D3D12 drivers
71c4de190 Sync SDL3 wiki -> header
512d97eab cocoa: Set the internal window data before calling methods that may result in referencing the internal data
5e951a230 windows: Fix WIN_SetWindowAlwaysOnTop causing owner window z-order changes when child windows are created or change top-level status
50a397bb4 Removed help for obsolete (and removed) command line option
3235a4eb4 Initialize the padding of aligned allocations to zero
efaafd766 VITA: Remove unused/duplicate headers
7746a9656 Fixup the mingw readme cmakelists
2ce3dfdf1 Fixed Nintendo controller face button layout under Steam
be6ed6e9c Fixed sscanf("026", "%1x%1x%1x", &r, &g, &b)
24339524c Use sized types when fixing undefined behavior
f1d16e9b4 avoid UB (left shift of negative number) in SDL_windowsevents.c
9fcca8351 gpu: Validate that CopyGPUTextureToTexture formats match
f2866418d wayland: Fix enum/boolean comparison and assignment
597bfe6b2 mouse: Add internal integer mouse mode hint for sdl2-compat
65cd2256c emscripten: Fix handling of special HTML targets
5d804a39d Implement SDL_GetSystemRAM and SDL_GetNumLogicalCPUCores for the 3ds (#12494)
99336ea37 Fixed memory leak in memory leak tracking
0306b5a86 Fix n3ds/SDL_syssem.c:SDL_SignalSemaphore (libsdl-org/SDL#12411)
3353b92a9 Fixed pen events on iOS after reinitializing SDL
ad2584813 cocoa: Ignore both clicks and motion on tooltip windows
fe245c6e0 x11: Always synthesize size events for external windows
84d047cc1 wayland: Rollback the round trip when reading data offers
fc3510785 Sync SDL3 wiki -> header
d631a3add Add a link to docs/INTRO-mingw.md
04b4577b5 Added MinGW Intro readme, touched up CMake and Visual Studio readmes. (#12485)
b99ff00a9 Removed logic forcing vsync on if setting it off fails
55695d372 Sync SDL3 wiki -> header
9c7c11f25 wayland: Roundtrip when receiving data offers
c4be7f77a wayland: Add additional MIME types for text drag & drop
e20e27e1f Added SIMD blitters for 8888 -> 8888 format conversion
4c82b5843 Added support for SDL_PIXELFORMAT_MJPG to SDL_DuplicateSurface()
cb099ebd4 Make texture scale mode a part of the 2D renderer draw state
6e2d3c9b5 x11: Enable legacy synchronization for external window resize and move events
bdde07468 Sync SDL3 wiki -> header
49af57694 Disable XTest by default
794ff283e Added support for using XTest to warp the mouse
fae324dac Update XSync code to match SDL3 conventions
f01bcaeb1 Sync SDL3 wiki -> header
fe9bdcf50 Added SDL_HINT_VIDEO_X11_EXTERNAL_WINDOW_INPUT
9f557941f Sync SDL3 wiki -> header
8f40dad46 Document the thread safety of SDL surface functions
aef240b2e Fixed continuous logging if returning to desktop mode fails on X11
e9632c83c Handle XWayland not sending display disconnected events
ca9bc6b16 Revert "Ignore BadRROutput errors from XRRGetOutputInfo()"
0c8ddc1f0 Ignore BadRROutput errors from XRRGetOutputInfo()
80ae3a751 Fixed crash when restoring the desktop mode on macOS
5f07347e4 Fixed crash unplugging a HIDAPI controller
82552e5b7 Make SDL_RegisterEvents() thread-safe
9f9a44282 video: Synthesize fullscreen related moves if the driver does not.
e7abbf158 x11: Synthesize fullscreen size events on Openbox
5d20bbf34 Presenting while drawing to a render target should fail.
debbe1cf7 Fix for Message Box failing to init on X11 (#12455)
4bb46e93c Fixed clip rect when logical presentation is enabled
7df0ffd43 Sync SDL3 wiki -> header
7c29c8b26 Added fullscreen_active to better track fullscreen state
3b9f0dff1 Use _this pointer to reference the video device
0ccf272ee Check the display device before dereferencing
6c347cbf3 video: Handle Cocoa desktop mode switch inhibition in the video layer
24ec2ed78 Don't save temporary mode changes to the desktop mode
d57aa6f7a pipewire: Don't require pw_check_library_version() with Pipewire < 0.3.75
113eb6f01 gpu: Add BC2_RGBA_UNORM_SRGB to GetBlockWidth/Height functions
2c7c3d4d7 Only use VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR on Android
ca3c5fd40 fix build:  s/SDL_DetectSandbox/SDL_GetSandbox/
eac63b473 Add the definition for DBUS_TYPE_UNIX_FD to SDL_dbus.h
16f12c0d5 Implement the XDP Camera portal
c3b415641 Sync SDL3 wiki -> header
2a0223487 Sync SDL3 wiki -> header
1a7c20698 Save and restore error messages when rolling back after failed init
2c46c3d5b Updated dynamic API for new functions
5373271a1 forbid transform change while relative mode active
428f0dcd6 add SDL_SetRelativeMouseTransform
67127afe3 Fix from #12118
e25ee2246 Added tiled 9-grid texture rendering function
954675b32 Sync SDL3 wiki -> header
44bca81fd Change default texture scale mode per renderer
b0d2a4f35 gpu: Fix Z offset for D3D12 realigned 3D texture uploads
b69201dae cocoa: Don't overwrite the desktop mode when changing the fullscreen mode
078d737a2 cocoa: Run pending events to completion
b0df1cbbe Updated to version 3.3.0 for development
65864190c Added testpen to the Xcode test project
292e43174 Updated to version 3.2.6 for release
f0cb78e08 Handle XCreateIC() failing when composition UI is enabled
55484ef02 Moved WIN_UpdateMouseCapture() to be with the other mouse functions
020664bd1 Update mouse button state when re-entering a window
b836ad4d4 Fix a root signature mismatch for the D3D12 renderer
a88105784 camera: Delete some failure code that should have been removed before.
f868408a3 Ceil the audio resampling rate to avoid over-estimating output samples.
cbdc93b17 cmake: make sure a SDL3 library is present when not using COMPONENTs
8a7beca12 camera: clear the spec when closing, so re-opening can probe again
ee5f5c917 Sync SDL3 wiki -> header
6e4193b74 Note that the file names are UTF-8 encoded
60c65f9fa SDL_camera.c: fix failure-return in SDL_PrepareCameraSurfaces().
b8c2bc143 Added build dependencies for Arch Linux
7ab1412e2 Sync SDL3 wiki -> header
725af6ad1 camera: Fixed surface formats, etc, for Emscripten backend.
ef23ebfb5 Fixed the cursor clip rect when toggling window borders on macOS
c68259944 GPU_d3d12: Switched the default swapchain scaling mode to none.
ea513fd47 Fixed vulkan gpu backend android orientation behaviour to just work like on iOS.
87b1c9736 Fix pen generated mouse events not having SDL_PEN_MOUSEID  (#12392)
a44107540 sysjoystick: don't leak fd on error
9a802797d SDL_pen: fix eraser check
54c7aa9c9 Sync SDL3 wiki -> header
35e8cf8ee render: allow render targets to use logical presentation.
281f0fae1 Include the VID/PID of generic keyboard/mouse devices on Windows
d09bf5681 clipboard: Cleanup coding style
edaf44767 tests: Add showing/setting the primary selection text to testclipboard
7b9036bea wayland: Don't overwrite clipboard data with the primary selection text
f7cadcba8 examples: Use SDL_GetAudioStreamQueued, not SDL_GetAudioStreamAvailable.
b3336c5a7 Match style
2b784b5bf Fix SDL_GlobDirectory
eb89d0c8c Don't put wired Switch Pro controllers into simple report mode
1ea99bc90 Early out if setting a duplicate window title
56e2955b6 Sync SDL3 wiki -> header
cc984c973 Added a mapping for the 8BitDo SN30 Pro+ controller on macOS
ba88b6aa0 Fixed reliability of initializing Switch controllers on macOS
66ecdc69a Don't update the report mode until the related hint is set
fab52b578 wayland: Ensure that color descriptions are always retrieved
9464aaa8a Change D3D12 GPU backend to respect has_depth_stencil_target
cf819ca81 Don't allow further operations on properties while we're destroying them
e01257376 Don't fixup mappings for Joy-Con controllers
34c373495 Fixed opening one Joy-Con when the other is visible but disconnected
049a7a04d Wake the main thread for main function dispatch
f0f593f04 Embed a description about Wayland clipboard instead of a link
bb748ef2d Don't cleanup clipboard in SDL_SendClipboardUpdate on Wayland
38a73a178 Sync SDL3 wiki -> header
85a302550 Set an error message if the rect passed to SDL_RenderReadPixels() is entirely outside the viewport
29df99ee3 Clarified SDL_RenderReadPixels() documentation
2f77558ba fix comment
44f1ec35c GPU: Make Vulkan transfer buffers dedicated allocs
1c2189c7c strings.h isn't available in Windows environments
ffdca343f Sync SDL3 wiki -> header
ac5fca4ae Clarify the expected usage of SDL_StorageReady()
fc365e945 Sync SDL3 wiki -> header
ad840e879 Better document that main functionality is in SDL_main.h
bb8dcf08e Sync SDL3 wiki -> header
698032531 Added support for the "%n" sscanf format specifier
e6a24fcbb fix stbi__parse_png_file() reading too much bytes (thanks @miniupnp!)
db4e6c193 Cocoa metal layers need their size updated before renderer updates
0a592b78c Sync SDL3 wiki -> header
58388e8db Add SDL_HINT_JOYSTICK_HAPTIC_AXES
db817a37f gpu: Fix forward declaration and inclusion of PrivateGPUDriver
a7bc6c5e0 gpu: initialize VkDebugUtilsLabelEXT::color
60b7faa98 gpu: Validate that reserved struct members are unset
2990d142c Map additonal Linux keycodes to SDL scancodes
a0086a5cc Add missing scancode names
35544df83 Changed PULSEAUDIO_FlushRecording() to only flush audio present when called.
deadfe0c9 Sync SDL3 wiki -> header
0815637cf vulkan build fix
ea77472d7 Document/ignore GPU features without universal support
ad11c6988 src/io/SDL_asyncio.c:SDL_AsyncIOFromFile(): Fix null-dereference warning
8bfde6755 Remove unnecessary fcitx's devel package dependency in linux doc
52af81ea1 wayland: Fix mapping borderless windows under libdecor
1a0a94b50 x11: Accommodate the borders when setting the initial window position
52e64f816 Use SDL C runtime functions in OpenVR driver
7224b4040 Fix errors when building stb_image with -DSDL_LIBC=OFF
945da099a pipewire: Fix possible deadlock when opening a device
70f657e52 ci: farewell, clang32 on msys2
e50db698e Disable all camera drivers if SDL_CAMERA_DISABLED is defined
1ddba3ad5 Replace "8BitDo Tech Ltd" with "8BitDo" in the manufacturer string
fdf72d1e4 Use the keyboard/mouse vendor if available
a811e0ef0 Added support for the 8BitDo Micro gamepad
bc85c5535 testcontroller: create window with high pixel density
75bbcbf87 Added support for Motion JPEG pipewire camera capture
5c214e5e9 testcamera: SDL_AppQuit destroys state and SDL
03e00cd34 v4l2: map SDL_PIXELFORMAT_MJPG to V4L2_PIX_FMT_MJPEG
fcd41c1d2 Check desired window area when checking zoom state
b5297de56 Add 'const' to pointer parameters
911e53dec Retain mouse focus as long as we're getting mouse events
3b8cb6228 Make it easier to enable IME debug logs
9a607e886 make start&length represent utf32 indices
9d06145d6 ci: fix type + names of intel compiler artifacts
fa380a400 Update include/SDL3/SDL_assert.h
2a1b617fb Update include/SDL3/SDL_assert.h
69e03094b fallback to defining SDL_TriggerBreakpoint as __builtin_trap in older linux arm64 environments that do not have a __has_builtin facility
c70f54e28 Remove redundant casts
2e346d716 Added 32-bit texture formats to Texture_GetBlockWidth() and Texture_GetBlockHeight()
5d776c070 Refactored SDL_CreateJoystickName() into a general SDL_CreateDeviceName()
3293eb1a1 use hidapi to get mouse/keyboard string
785584230 ci: disable precompiled headers for classic intel compiler
71d1de5d9 ci: add cppflags to CMAKE_(C|CXX)_FLAGS
28f086794 SPA_FALLTHROUGH expands to nothing when using the Intel compiler
8d3db06ff ci: GitHub is retiring Ubuntu 20.04 support
c153f83df ci: enable ccache
52ee0c105 Sync SDL3 wiki -> header
9267930fe Added a fast path for converting the same format and pitch
f24f9d3be Revert "testcamera: added support for Motion JPEG camera frames"
2e89c53eb Added support for decoding MJPG into NV12 textures
06602f4e8 Document that the pitch is the length of the image data for SDL_PIXELFORMAT_MJPG
a792434a3 Added initial MJPG support using stb_image
baf69edfc Revert "cmake: build SDL_uclibc with -fPIC"
fdf8e5a70 ci: build static loongarch libraries with -fPIC
9784414dd cmake: build SDL_uclibc with -fPIC
b48de48ef wayland: Add support for high-DPI icons
6e0264d38 x11: Use the current or last-requested window position when setting the size hint
1a38960ee Call SDL_DiscardAllCommands() for the software renderer as well
8f4c5e15f Finish any drawing when destroying a software renderer
1a853973a thread/windows: fix stack overflow in exception naming
a40b2de94 Fix SDL_emscriptenaudio.c under wasm64
523e6530a SDL_test: fix "'function': different 'const' qualifiers" warning in SDL_test_harness
9e4c657ed wayland: Fix color manager protocol string check
7500a758b Remove usages of `restrict` keyword in SDL_render.c
a7f01cd73 x11: Set the pending window position immediately after mapping
1fd626939 Renamed DreamPort to DreamPicoPort
31f9cb480 Unchecked Return Value in WIN_SuspendScreenSaver (#12316)
057c3602e Removing Double-free Issue
5c79f4cae Incorrect bfOffBits Calculation in WIN_ConvertDIBtoBMP
70d23b234 README-migration: Remove errant reference to SDL_FALSE_
6aef6ae9a AddPulseAudioDevice(): Fix use-after-free
3b4cfc11f wayland: Update copyright dates in added color manager source files
fadb261b6 wayland: Add color manager protocol support
6ef687c86 Simplified and fixed media foundation buffer handling
de12cb92d Fixed crash at shutdown with new hashtable code
a51316890 Fixed Memory/Resource Leaks (#12304)
045a4492f test/testaudio.c: Fix use-after-free warning
da2460f9e test/testautomation_audio.c: Free variables before returning
7ea0ffb74 update
06eb10c51 haiku: check if the returned _SDL_GLView is null or not
dea99e54f Sync SDL3 wiki -> header
175494359 Fixed camera frame acquisition on Windows 7
e3d9f1172 Remove the reference to the thread when it is detached
831fc7092 test/testautomation_intrinsics.c: Free variables before returning
c6a3b5b6e src/test/SDL_test_harness.c: Free variables before returning
84a236c92 hashtable: Redesign the hashtable API.
4a9b57919 joystick: remove dead udev code
ba4525694 Sync SDL3 wiki -> header
fd4e6d294 Don't render 0 sized texture rectangles
6f3b14a6d audio/video: Fix uninitialized field warnings
5b98c4a52 Fixed motion events with TOOL_TYPE_UNKNOWN
8a648dfd9 emscripten: Fixed unregistering of key event handlers
c16b7bcb7 SDL_Get*Driver() functions: Set error message on failure
ed0a03e9b Fixed Cursor Icon State for SYSTEM_CURSOR_PROGRESS
5dce8c748 SDL_GetRelativeMouseState(): Get relative mouse position also when relative mouse mode is disabled
cedf53bbc Sync SDL3 wiki -> header
3de975884 Document the "trace" log priority
b9d018f2a Fixed wayland cursor use-after-free at shutdown
041894a52 Sync SDL3 wiki -> header
3be67ced6 Fix GTK tray icon without menu + lifetime
1354affd2 haiku: Fixed keyboard input.
d2b7a8465 Fixed SDL_GetNumGamepadTouchpads() returning 1 for a NULL gamepad
ca29304ce Fixed continually resetting keyboard and mouse readings
f67c64464 Fixed reporting hat positions for GameInput controllers
1b35ca9c3 Refactored GameInput initialization
706de78a9 audio/video: Skip preferred drivers when loading a driver on demand
715c18739 Added an internal hint "SDL_VIDEO_X11_XINPUT2" for sdl2-compat
ce69e9898 Copy SDL2_SYSWMEVENT data into temporary memory for the event
55fd205ba Add missing integer texture formats to SDL_GPUTextureFormatTexelBlockSize (#12151)
e6029401d Check for non-NULL icon for trays on Unix
b03332b68 updated bytepusher demo to be C++ compatible
5dd249264 updated the snake demo to be C++ compatible
78f816d74 x11: Apply the modifier state from key events
99cf16287 Fixed the name of SDL_SYSWMEVENT
6c3797152 Removed the mapping for the Sanwa Supply JY-P76USV
9b18e8438 [GPU] D3D12 backend debug markers were being cut
0bce19cf1 The 10-bit texture formats have alpha on Direct3D
3cfa476d3 Added support for SDL_PIXELFORMAT_ABGR8888 textures
5ccee7719 testcamera: added support for Motion JPEG camera frames
cf41ccc6c Removed stb_image.h from SDL
9308404e9 Removed functions not used by SDL
5e31bbf05 Remove functions not used when STBI_NO_PNG and STBI_NO_HDR are defined
84b0c13c4 Added support for Motion JPEG camera capture
3bc53b9ad wayland: Don't set libdecor frame visibility before the first commit
c03258626 wayland: Scale-to-display mode requires both viewports and xdg-output for proper functionality
b63d3afc1 Sync SDL3 wiki -> header
0bc1f8712 Added SDL_PROP_SURFACE_HOTSPOT_X_NUMBER and SDL_PROP_SURFACE_HOTSPOT_Y_NUMBER
da464e9e5 win32: Keep the window on the last maximized display when leaving fullscreen
bf01cc8ce Renamed "Dreamcast Controller Usb" to "DreamPort"
ecd089bb6 Don't return short waits from SDL_IOReady()
4fd0b2a85 Fix #12142 - the problem was if the size of the vertex buffer was exceeded, the currentVertexBuffer would be reset to zero and thus we'd leave it pointing to an in-use VB that would get overwritten on the next present before the vkQueueSubmit occurred.
f6126e9ea Centered joystick axis values should be 0
d35bef64e pipewire: Ensure that the correct struct is used for enumeration APIs
9bd6d3647 Added SDL_DEPS_SHARED option to control default dynamic loading of shared libraries (#12215)
78721d720 joystick: Fix PS5 player LED hint change callback name
7aba6c4c7 Proper Resource Cleanup in WIN_UpdateWindowShape
e29ebb9f1 Update geometry renderer example
ca9a044b3 Memory Leak in WIN_CreateHCursor When CreateColorBitmap Fails
69d28027a Fix for 500ms hang after user clicks on the title bar, but before moving (#12217)
a0b6c0fd8 x11: Don't wait for events when the connection errored out (#8392)
864bb65ce Removed crc
006605c3b Corrected alphabetical order
dc035c5ca Added mapping for Dreamcast Controller USB
5d1bbd9b2 Fix SSE 4.2 test
7c12c63f6 Add generic SDL_syscond to N3DS threads source list
2ced6b09f Delete src/thread/n3ds/SDL_syscond.c
7af17f874 Sync SDL3 wiki -> header
982094c85 Updated to version 3.2.5 for development
b5c3eab6b Updated to version 3.2.4 for release
48c00bfe6 Fixed creating a window with both software and hardware renderer attached
3c6e6645f Sync SDL3 wiki -> header
ad8429f1b Let the renderer always see window events
c59ac249d Revert "wayland: Don't send size events while the window is hidden"
6cb3d37a2 Sync SDL3 wiki -> header
80653a42c Remove non-ASCII character from public header SDL_hints.h
a646dc89e Note that SDL_GUIDToString() and SDL_StringToGUID() are thread-safe.
8730f6a56 dynapi: Don't use SDL_getenv; it might malloc before the app sets an allocator.
c9341489c Fix #12197: Force set /utf-8 for msvc compilers (#12198)
8397e1fcc Fix up SDL2 style mappings for HIDAPI controllers
7691cabe4 Removed incorrect HIDAPI gamepad mapping
86691d325 GPU: Remove stencil bit from sampler aspect mask on Vulkan (#12196)
6782cfe2c Don't use the HIDAPI driver for Thrustmaster wheels
1c0e2b7f9 SDL_OpenHapticFromJoystick() returns a valid haptic object
c4550d906 testcontroller: show the gamepad device type
5ad033768 Sync SDL3 wiki -> header
68dabd48c SDL_GetTrayEntries(): Rename parameter `size` to `count`
b99e19c0a Fixed potential double-free
8ba8cca69 Fixed memory leak looking up pen tool names
2cd2834df Fixed memory leak in the pen cleanup
c4c185283 dbus: fix spurious leak reports with SDL_SHUTDOWN_DBUS_ON_QUIT=0
691a6133d Remove #undef __3DS__
33c0654d5 Allow OpenGL initialization on XB1 and XSX.
eb5ab2203 Check nullptr before calling the windows message hook for WM_ENTERSIZEMOVE and WM_ENTERMENULOOP
e7f326a84 bmp: Removed debug printf call.
61b1c25ee x11: SDL_SetWindowPosition on an unmapped window will do the actual move later.
f1b3523c6 Remove redundant parenthesis in SDL_MUSTLOCK macro
8527d042b Remove const from parameter of inline function SDL_RectsEqualEpsilon()
07c22da46 Fixed decoding 4-bit RLE encoded BMP files
8ccf85c59 Formatting spaces around pointer symbol.
94409d350 Added Switch Input-only controller entries for Zuiki MasCon controller for Nintendo Switch.
a8a2874ef Added distinct VID/PIDs for the PS4 vs Xbox eSwap Pro controllers
84bc2abda Corrected the entry for the PXN V900 racing wheel
eac07bda0 Sort the controller lists by VID/PID
6243a0653 Call the windows message hook for WM_ENTERSIZEMOVE and WM_ENTERMENULOOP
ec959a434 Sync SDL3 wiki -> header
8e51b2468 Renamed SDL_SoftStretch() to SDL_StretchSurface()
f40ef62a2 Sync SDL3 wiki -> header
614ae843a Sync SDL3 wiki -> header
8848f8656 Corrected the version where SDL_SoftStretch() was added
a98a4b8a6 Re-added SDL_SoftStretch() to the API
842f85da0 Sync SDL3 wiki -> header
c06172dc1 Track mouse button state by real mouse ID
73a814358 timer, windows: allow building high resolution code with old SDKs.
be991239d Updated to version 3.2.3 for development
2fa1e7258 Updated to version 3.2.2 for release
c92276279 proposed fix: set curr_src.h is to bottom_height before drawing bottom edges / corners in SDL_RenderTexture9Grid, to avoid issue where inadvertently using top height if the npatch existed on a larger texture than the drawn edge would cause too many pixels to be included in the bottom part of the render.
235022fe2 Fixed error C2059: syntax error: '}'
dc13a6ae9 SDL_SaveBMP_IO: Write bitmap header v5 values
fe6bd8e9b Sync SDL3 wiki -> header
bc3264130 Fixed mouse motion events while the mouse is grabbed
69d361dee Ignore SDL_HINT_RENDER_DRIVER set to software when creating a window surface
70a239210 GPU: Describe "readonly storage" images as sampled images on Vulkan backend (#12149)
4c6d949e6 wayland: make sure the desktop mode is in the fullscreen mode list
ab5cb707a Fixed enabling call logging
16f8122a0 Keep the simplest mapping of scancode + modifer for a given keycode
6beda3421 do not build camera drivers if camera support is disabled
0825d07a4 wayland: Don't send size events while the window is hidden
8e766c925 GPU: Resource binding state shadowing (#12138)
43924ec87 Sync SDL3 wiki -> header
8c2682a21 Sync SDL3 wiki -> header
e4fcc7b6e gpu/vulkan/SDL_gpu_vulkan.c: fix type redefinition error
14edb21ae check for backslashes as well as the forward slash
50b8c6cdf Sync SDL3 wiki -> header
943c4abcb pipewire: Report correct device default formats instead of hardcoding Float32.
943579a54 Fix inverted pen Y tilt on macOS and add tilt display to example - Negate tilt.y in Cocoa pen handling to correct inverted Y tilt axis - Update drawing example to display X/Y tilt values for visualization - see 0f128fd7c5/src/plugins/platforms/cocoa/qnsview_tablet.mm (L63) - see https://source.chromium.org/chromium/chromium/src/+/main:components/input/web_input_event_builders_mac.mm;drc=0af5ffa1e4cc4cc4f818725f8fee93ec57855e4b;l=421
31364477f Rename parameter of type SDL_CameraID from devid to instance_id
36758d70c Rename parameters of type SDL_AudioDeviceID from dev to devid
2abc7735a Free XIDeviceInfo in X11_MaybeAddPenByDeviceID
8298d60e4 Dynamically load CreateWaitableTimerExW and SetWaitableTimerEx
409f3ade8 Removed SDF test program
4176e188b Enable testgles2 on all platforms
cf249b0cb fix -Wformat problem in 32 bit builds
11dbff246 Sync SDL3 wiki -> header
ccd5fcef1 audio: Fix potential NULL dereference in AudioStream gain adjustment.
48f555065 wayland: Don't send keyboard and mouse added events during initialization
2a946e91b android: updated release build SDK to match documented requirements
44edbf713 Use templates for the package support files
1c008d8ed Change DBUS introspection timer from INFINITE -> DEFAULT when introspecting available dialog services
c21bc48a7 Fix undefined behavior in SDL_windowsmouse.c
1c7cc6028 Skip IsRegularFileOrPipe() check on Emscripten
8f958953f audio: Fix audio stream gain going wrong in certain scenarios.
3b3af7105 audio: Fix a minor code style thing.
725ee7665 Documentation: fixed typos around floats precision
6f098a920 Avoid a crash when a tray without a menu is clicked on Windows.
09f900f66 audio: Remove resampling limits.
5f8e0ebf5 Fixed memory leak at shutdown
913e0a5e5 SDL_migration.cocci: handle more renamed event fields
628130ec8 SDL_migration.cocci: fix incorrect SDL3 API name
fa8c0f055 Sync SDL3 wiki -> header
17c4bdd75 Sync SDL3 wiki -> header
ad8a09000 Sync SDL3 wiki -> header
8df17c97d GPU: Add notes about shader resource requirements to documentation
303fd5ed5 release: rename resources/cmake -> resources/CMake in dmg
fdf33f904 xcode+cmake: Use SDL3.framework/SDL3 as IMPORTED_LOCATION
cb3d6dc46 .wikiheaders-options: Removed wikipreamble setting.
84c4ff2f1 Sync SDL3 wiki -> header
2e381a717 Fix possible integer overflow of size + 1
129ebc77b Sync SDL3 wiki -> header
a336b62d8 Remove newlines from error messages
d0ae09368 x11: Don't force position windows with an undefined position
72a3eae0d Fix buffer overrun in ConvertAudio with different src/dst channel count
983cfe8b1 Remove even more newlines from log messages
718034f5f Remove newlines from log messages
17625e20d Removed redundant step in Visual Studio instructions
c806c271c Tweaked emscripten introduction
74536243d Emscripten works well using the normal CMake workflow
98c447802 ci: bump to NetBSD 10.1
a437dbc7e Improve log documentation
1c21a72bd Sync SDL3 wiki -> header
73fc2b03a Copy pen handling code from `SDLSurface` to `SDLControllerManager`
6f3d0b3cd Fixed build when using an older Xcode SDK
cb3cc2880 emscripten: pass --no-sandbox to the chrome web driver
df3cfbc79 Sync SDL3 wiki -> header
799093799 GPU: Note buffer alignment requirements
5bf077f1f Sync SDL3 wiki -> header
5d6a78045 Sync SDL3 wiki -> header
77b520e93 Updated to version 3.2.1 for development
bb3c5b4f3 Fix multiple occurences of typo "an simple" to "a simple"
efa6e7aec android: add style to test apk's
535d80bad Include the README and related files in the SDL framework
ed2920afe All SDL 3.0 release symbols are at version 3.2.0
7a5604cf0 Sync SDL3 wiki -> headers.
7e130e27b fnsince.pl: Remove prerelease version tapdancing.
b775135b4 Removed temporary debug code
a52fc209b Updated to version 3.2.0 for release
f16c67115 Sync SDL3 wiki -> header
90bda6548 video: Don't let SDL_CreateWindowTexture use the software renderer.
c45c4a5e5 render: SDL_HINT_RENDER_DRIVER now accepts a comma-separated list.
670a7d812 Sync SDL3 wiki -> header
8a67896d9 docs: Note the preferred function for getting the content scale of a window
852686856 dialog: cleaned up D-Bus portal implementation
071bebf23 coreaudio: Add a note about why this uses 3 buffers instead of 2.
c0a9d220b vulkan: Fixes for swapchain resize crash on X11.
ea9880b76 Sync SDL3 wiki -> header
bcf7ead6e documentation typo: SFLOAT -> FLOAT
6d5815db5 vulkan: Deal with VK_ERROR_OUT_OF_DATE_KHR returns from vkAcquireNextImageKHR.
6b7dad7d8 vulkan: move temporary pointer to its own field to prevent a bad dereference.
3e530c6db cmake: remove superfluous cmake_minimum_required
7bff36e4b ci: add ubuntu arm job
37140aa9f cmake: expand libunwind
abe6d9db9 Automatically detect SDL_main_private.h
10c9fbf41 Use proper polar direction when creating FF_RUMBLE effect
c6c746970 Translate conditional effect direction instead of hardcoding it to 0
b476695e6 Call the windows message hook while inside a modal message loop
b6d0bc043 coreaudio: Use three buffers for the audioqueue, not two.
aa10e51c7 audio: Added some minor missing comments in struct SDL_AudioDevice.
10a5b388d win32: Retain the WS_MAXIMIZEDBOX style while in fullscreen
6449339ae win32: Restore the base size of a window when leaving fullscreen
075c0337c Removed debug print statement
a036aeda3 The Vulkan renderer doesn't actually support RGB texture formats
9b454a762 Revert "testautomation: don't validate alpha values on XRGB formats"
dcadd23ba render: Prevent division by zero if logical presentation is 0 pixels.
adb91fd3d process: Don't use vfork() on Apple platforms.
819628c6b testautomation: Remove Win32 borderless resizable hint
759e01bd6 testautomation: don't validate alpha values on XRGB formats
c698c61f0 renderer: initialize the surface colorspace correctly
c975f77b0 Update joysticks and so forth during live resize
362f96a6c testcontroller: use SDL_MAIN_USE_CALLBACKS so updates happen during live resizing
f8040b2e0 Use UIKeyboardTypeDecimalPad for number fields on iOS
90b2e2527 include: Added a tiny bit to SDL_sensor.h's category documentation.
2be749b23 include: More category documentation.
642262e30 cocoa: Fix mousegrab when going fullscreen.
d5766bc4b include: More category documentation.
b809da52f assert: Try using __builtin_trap() for SDL_TriggerBreakpoint().
c4c0bfdfb Sync SDL3 wiki -> header
7133969e3 Feature add hint to remap option as alt key (#12021)
53a535029 Sync SDL3 wiki -> header
5f2dd5f04 tray: fixed multi-threading issues with GTk implementation
dfdc12026 tray: document thread-safety
d4cda5105 tray: renamed SDL_HasNoActiveTrays() to SDL_HasActiveTrays()
a974888aa tray: fixed icon colors on Windows
7570ab106 tray: improved error checking
b716eeefe testtray: minor cleanup
3afd1e7ea windows: use WIN_UTF8ToStringW() for dialog titles
78023500f Sync SDL3 wiki -> header
34c12d0db include: Add category documentation to SDL_timer.h.
b088e8919 Sync SDL3 wiki -> header
0851322fb include: Add category documentation to SDL_power.h.
43b54b3d7 Fix Windows dialog folder titles
32965b4bf pen: Send virtual mouse motion without a button press when a pen is hovering.
5da9d4ecc cocoa: Slightly better display hotplugging detection.
19f42094b Fix Windows fie dialog args freeing
721fc7de0 Correct spacing of pointers ('a* b;' -> 'a *b;')
cd269730e Fix Windows dialog memory management
049a8f0e5 Use SDL_calloc() instead of SDL_malloc()
354d2c390 Initialize invalid parent_{tray,entry} to NULL
b79ada6aa Windows trays: Fix ParentEntry & Enabling
ba95c54f9 macOS: get the correct display name on macOS 10.15+
42e0fb10f wayland: Set the mouse state before calling the hit test callback
cd0db8d35 Added Linux evdev mappings for the Wireless HORIPAD For Steam
1d7a681e4 Revert "emscripten: resizable windows take whole page, resize with browser window."
e054f3c08 Sync SDL3 wiki -> header
75317dae5 include: Added category docs for SDL_mouse.h
c7d1fd90e Added support for the 8BitDo Ultimate 2C Wireless in Bluetooth mode
dbe3baeb0 release: document using the xcframework with CMake
ad3c7b92f xcode+cmake: use SDL3.framework folder as IMPORTED_LOCATION
0401b07ee Fixed typo
08e74d29b Fixed typo
923123a52 emscripten: Let SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT accept "#none"
c603a9c94 Moved flag documentation
90b7174a7 Respect the SDL_BORDERLESS_RESIZABLE_STYLE hint, but default it to true.
6a72d32d4 emscripten: Let SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT accept "".
f3a39074b windows: use WS_THICKFRAME style on borderless windows.
842f6dc40 Fixed wrong type of `phase` (#12014)
b95989d14 Fixed sine wave distortion over time.
010f27dc7 storage: enumerate and glob on storage can accept a NULL path.
a6a8598b9 storage: deal with paths with Windows '\\' path separators appended.
7c6adc1ca gpu renderer: removed unused sampler slots
feeea6a77 Sync SDL3 wiki -> headers.
e9f7f11f1 fnsince.pl: Fix script once bump to 3.1.10 exposed a bug.
d2fc394a2 Sync SDL3 wiki -> header
d317fc9c0 emscripten: resizable windows take whole page, resize with browser window.
ee469c6af Sync SDL3 wiki -> header
d4d22dd8d GPU: Add remarks about point topology
59ea078ee x11: check to see if displays moved when connected/disconnected
1848ce680 win32: Use the window coordinates to get the monitor when de-minimizing a maximized window
656c519cc Fixed warning C6313: Incorrect operator. Use an equality test to check for zero-valued flags.
9ed96f392 Sync SDL3 wiki -> header
ae8df1dcb Note that the primary monitor isn't always at 0,0
4b429b9fa Updated README-platforms.md
616ae9906 Removed README-git.md
c2dac95f5 Revert "Add CategoryAPICategory to the complete API index"
dd4f5df82 release: support android-X-ext-Y directories
cdc5483cf Vita: Fix off-by-one error for synthetic mouse events
07a5c144c Sync SDL3 wiki -> header
eb168e410 Updated to version 3.1.11 for development
b96bb152c wayland: Don't redundantly set the border state when showing a window
5a564a718 wayland: Add a dummy function for the libdecor dismiss popup callback
9f6eeb109 wayland: Set the border state before the initial configure
274bc95df Sync SDL3 wiki -> header
07f7c4046 Sync SDL3 wiki -> header
22d8e7353 include: filled in category documentation for SDL_messagebox.h.
21a42d2b0 Add CategoryAPICategory to the complete API index
1006236aa ci: add summary to release.yml
326ce9bb8 gpu: D3D12 buildfix for Xbox
c95b842b3 video: Xbox does not use CreateIconFromSurface
d8e1ad0eb release: skip extended Android SDK versions
7ee2ab383 wayland: Fix return value check from int-to-bool conversion
1dd8fadca Updated to version 3.1.10 for the release candidate
9225a421b Sync SDL3 wiki -> header
3ffb1a8cb storage: generic title storage allows override paths without '/' appended.
874c07f8d storage: Don't allow "." and ".." paths, enforce '/' dir separators.
67664a042 testfilesystem: test some Storage APIs, too.
eb793dede filesystem: SDL_GetCurrentDirectory() should add a path separator at the end.
87e1b0eb8 filesystem: SDL_EnumerateDirectory() gives dirs with path seperators appended.
e98ee9bb0 Adjust testgl.c to test gl_release_behavior
3424ec948 video: SDL_GL_GetAttribute gets correct SDL_GL_CONTEXT_RELEASE_BEHAVIOR value.
05877f2ce cmake: Add the IoRing async i/o code to the Windows build.
4d63a2b88 io: Renamed src/file to src/io
ea642fe9f cocoa: clear mouse focus based on NSEventTypeMouseExited events (#11991)
5f4696ce6 Updating documentation for the 3.2.0 release
2c7b7d1d3 Keep the lifecycle observer active while there are windows active
355f69ebf GPU: Ensure thread safety of Vulkan resource creation
c9d602307 cocoa: Only process hit tests on left clicks
dd0bdc256 win32: Pass through non-left mouse button presses when over draggable areas
84d35587e filesystem: SDL_SYS_EnumerateDirectory inexplicably takes the same arg twice.
fc9b2478d windows: don't set focus click pending if SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH is set
18d21b36f windows: use the initial rect to anchor fixed aspect ratio resizing
199547192 cocoa: fixed resizing windows with fixed aspect ratio
67382e9c8 Fixed detection of function keys on Emscripten
23410debf SDL_GetKeyboardNameForID(): Set an error message for invalid keyboard IDs
8ce176b59 SDL_GetMouseNameForID(): Set an error message for invalid mouse IDs.
51fa076fd Don't send normal keyboard events if no application window has focus
a446381ea Tooltips and unfocusable windows can't become main windows
ebb24eedc mouse: Clean up virtual touch devices as appropriate.
dabc93a63 pen: Send virtual mouse and touch events for pen input.
169c8d514 Fix incorrect hotspot calculation for cursor positioning
8e9c44bc3 Fixed accidental removal of optional delegate interface check
4dd585fb6 coreaudio: convert MPEG channel layout to WAVE channel layout
81e57147f Child windows shouldn't take focus if the parent window is in relative mouse mode
3bea84531 Sync SDL3 wiki -> header
9ed23a4b7 Updated SDL_SetEventFilter() documentation
e19a56f4d Don't send fake key events while processing real ones on Android
1ab61635a Use SDL_Log() for keyboard debugging.
29c684c62 Removed debug logging
0eaa6197c Removed unnecessary __builtin_available check
ffe194c52 Fixed build when SDL_JOYSTICK_MFI isn't enabled
a4547fe77 Updated weak framework dependencies for new deployment targets
49dd24e19 Fixed potentially overlapping memcpy() to use memmove()
191a6417d events: use SDL_memmove instead of SDL_memcpy for overlapping memory
bf793bf43 Sync SDL3 wiki -> header
9e60a8994 audio: Allow streams to change the device-side channels maps.
b2793a2ce Removed obsolete Raspberry Pi documentation
04e3b6770 Removed outdated Visual Studio instructions
a41f93bd1 Added https://github.com/Ravbug/sdl3-sample as a more complete Android example
5ca735b40 Only use WAVE surround sound channel layouts on macOS 10.15+
cdde6dd7b Bumped deployment requirements for Apple platforms
8f8af918b Removed CMakeLists.txt example that says you shouldn't use it
8feb21a1d Updated README-cmake.md with build instructions for several platforms
4294c0683 GPU: Check texture format support in pipeline creation
31dd4fe81 Sync SDL3 wiki -> header
417ed7f35 Fix references in docs
0aa319e4f Added support for custom tray icon on Windows via SDL hints.
581537220 minor update to mingw-w64 build instructions.
5d079c9a2 GPU: Remove bogus property from header docs
d590e1f12 GPU: Align D3D12 clear properties to naming convention
7098e525d Sync SDL3 wiki -> header
fb6df9338 GPU: Add name properties to resources (#11946)
a2b0ddcca Sync SDL3 wiki -> header
d28e95322 Added thread safety documentation for SDL_iostream.h
f731741ea Sync SDL3 wiki -> header
0eaa8c6d8 Added INTRO-emscripten.md
21b433536 Scale up the text for large displays
6bc7e88ca Added INTRO-androidstudio.md
e4e76ac72 Added INTRO-xcode.md
1b30a01b4 Added INTRO-visualstudio.md
191b9d502 Added INTRO-cmake.md
7d2a1c5f8 Mention the tests in INSTALL.md
b6b939044 Simplified INSTALL.md
55e094f7a Updated INSTALL.md with simple intro breadcrumbs
584c1d579 Tweaking the README
995a6a033 Minor readability improvement for README-contributing.md
86b46c678 Removed README-git.md
96414fa56 Removed obsolete Raspberry Pi documentation
670db4d24 Made the README links in INSTALL.md markdown links
b08d04581 Added a Discord link to BUGS.txt
2ad0f1e1f Updated the credits for SDL 3.0
41d48db4a Removed the runtime README
922b73195 Simplified the README
5e4a2974a Removed obsolete warnings about MIT licensed SIMD code
3766a3940 emscripten: double the audio buffer size.
e10e42c81 Sync SDL3 wiki -> header
2b8fb0bdd wikiheaders: Maybe fix perl warning.
efaf3739c Sync SDL3 wiki -> header
4bddf521d emscripten: Override emscripten's fullscreen button with SDL's implementation.
569de8490 better numerical precision for playback example
e5a4f0936 Call SDL_UDEV_Quit() if we don't end up using it
7d7a76c07 Sync SDL3 wiki -> header
66408308b Added documentation for mouse handling in relative mode
438075a83 Sync SDL3 wiki -> header
b4562c024 cocoa: Add a hint to control menu visibility in fullscreen spaces windows
611f132fd Don't use a hint callback for SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY
03a3c19c2 examples: use doubles to generate sine waves and avoid distortion
307e6f2ca emscripten: simulate mouse autocapture.
f79083d9b release: don't add test directory to mingw release archives
4ba4f0a10 release: add Android aar to devel zip archive
c4f2f7b35 Removed redundant information in example pages
949ec0c50 Sync SDL3 wiki -> header
839227b4b Sync SDL3 wiki -> header
c04b739df GPU: Note that resource naming functions are not thread safe.
3df0767e3 gpu: Initialize Metal stencil format even if stencil test is disabled
307dac97a testcontroller.c: fix build errors due to -Wformat after commit b524af1
21cc1878f Reset enhanced mode state when closing a controller
b524af1b4 testcontroller: log the ID of gamepads as they are added and removed
9a83fa026 apply multiplier scale after system scale
ea859fba3 Sync SDL3 wiki -> header
551510c0e SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE can be combined with SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE
95c158438 README-migration: note SDL2 brightness/gamma ramp APIs that have been removed.
f0af6c348 emscripten: Add SDL_EVENT_DISPLAY_ORIENTATION support.
3ad9c38a4 emscripten: Don't set OpenGL swap intervals until first PumpEvents.
d42b4ed96 Leave SDL_TriggerBreakpoint undefined on unknown platforms
9a7cfbc2d Add onNativePen to proguard-rules.pro
82125ec1d x11: Be more aggressive about finding _any_ usable messagebox font.
423184879 Revert "Separate android initialization from Activity (#11891)"
61f13b94d add a fallback SDL_TriggerBreakpoint() for MSVC after commit ebaa30d3.
d14c93c4b Separate android initialization from Activity (#11891)
c64197be1 Sync SDL3 wiki -> header
042898995 Added SDL_ClickTrayEntry()
fb0f6a119 cocoa: Display mode changes set Desktop display mode, not current.
38176bfe9 cocoa: Implemented display hotplugging support.
0e2ca934b events: Remove unused function declaration
715897aea Added support for displaying XIM composition strings
a8a65b6fc Use XIM for IME input on X11
1f3b40797 Sync SDL3 wiki -> header
fb94a79f8 stdinc: define SDL_NOLONGLONG for old Visual Studios, document the symbol.
bda90c3cb cmake: rename SDL_DISABLE_* CMake options to SDL_xxx
90aff306c gpu: Show a debug error when pipelines are not given the right shader stages
00b23a012 Sync SDL3 wiki -> header
6b776a998 keyboard: Add some SDL keycodes for common Xkb keys
e5966bbdb x11: Add support for Mod3 and more esoteric Xkb configurations
73ee99978 wayland: Add support for Mod3 and more esoteric Xkb configurations
ebaa30d33 __debugbreak was introduced in Microsoft Visual Studio 2003
c8f3f1b46 _BitScanReverse was introduced in Microsoft Visual Studio 2005
a78104a47 Disable long long support in the headers with SDL_NOLONGLONG
6cdde10ed gpu: Metal depth write should behave like Vulkan/D3D12
dd0dc64d5 Sync SDL3 wiki -> header
c688853a8 Sync SDL3 wiki -> header
507593f48 wikiheaders: Allow symbols to be filtered from manpage generation by regex.
7acf78ba9 storage: Trim the title storage root from enumerated paths
037cd25a2 win32: Use the pending size during NCCALCSIZE
e8916b260 pipewire: Use byte order pixel format aliases
d2090d1c8 Sync SDL3 wiki -> header
3f7f632e1 audio: Added SDL_AudioDeviceStreamPaused.
f61860fa9 testautomation: fixed incorrect test.
4bb3c2a1c render: Some cleanups.
61bdbacda render: SDL_RenderTextureTiled shouldn't try to drop draw calls, either.
f044a3d6c Revert "render: GetRenderViewportSize shouldn't use scale, just logical presentation."
fa7a52991 render: GetRenderViewportSize shouldn't scale viewport dimensions.
163600951 Sync SDL3 wiki -> header
bf8532094 render: Don't try to drop draws outside of the viewport.
f2f04e825 tests: Fix get/set window size test being skipped
cbdbd66e1 Sync SDL3 wiki -> header
ef1fdf11b tray: Create tray icons for libappindicator securely
e6bb50a71 Updated to version 3.1.9 for development
6b34c9fe7 Sync SDL3 wiki -> header
22422f774 Fixed ABI compatibility with 3.1.6
d7b10d05b Updated to version 3.1.8 for the preview release
4290fc8bd tray: Load GTK and libappindicator by versioned names, except on OpenBSD
6b38d250a tray: Don't try to use GTK 2 versions of libappindicator
bba066c44 tray: Don't call g_object_unref(NULL)
0bc370dfb Android doc cleanup
6934c910b opengl: use GL_UNSIGNED_BYTE instead of GL_UNSIGNED_INT_8_8_8_8_REV.
0176a19ae Fixed platform define condition for Windows phone
0180ca541 windows: Catch WM_POINTERCAPTURECHANGED events.

git-subtree-dir: external/SDL
git-subtree-split: 90fd2a3cbee5b7ead1f0517d7cc0eba1f3059207
2025-04-15 09:23:03 +02:00

115 KiB
Raw Blame History

Migrating to SDL 3.0

This guide provides useful information for migrating applications from SDL 2.0 to SDL 3.0.

Details on API changes are organized by SDL 2.0 header below.

The file with your main() function should include <SDL3/SDL_main.h>, as that is no longer included in SDL.h.

Functions that previously returned a negative error code now return bool.

Code that used to look like this:

    if (SDL_Function() < 0 || SDL_Function() == -1) {
        /* Failure... */
    }

or

    if (SDL_Function() == 0) {
        /* Success... */
    }

or

    if (!SDL_Function()) {
        /* Success... */
    }

should be changed to:

    if (SDL_Function()) {
        /* Success... */
    } else {
        /* Failure... */
    }

This only applies to camel case functions, e.g. SDL_[A-Z]*. Lower case functions like SDL_strcmp() and SDL_memcmp() are unchanged, matching their C runtime counterpart.

Many functions and symbols have been renamed. We have provided a handy Python script rename_symbols.py to rename SDL2 functions to their SDL3 counterparts:

rename_symbols.py --all-symbols source_code_path

It's also possible to apply a semantic patch to migrate more easily to SDL3: SDL_migration.cocci

SDL headers should now be included as #include <SDL3/SDL.h>. Typically that's the only SDL header you'll need in your application unless you are using OpenGL or Vulkan functionality. SDL_image, SDL_mixer, SDL_net, SDL_ttf and SDL_rtf have also their preferred include path changed: for SDL_image, it becomes #include <SDL3_image/SDL_image.h>. We have provided a handy Python script rename_headers.py to rename SDL2 headers to their SDL3 counterparts:

rename_headers.py source_code_path

Some macros are renamed and/or removed in SDL3. We have provided a handy Python script rename_macros.py to replace these, and also add fixme comments on how to further improve the code:

rename_macros.py source_code_path

CMake users should use this snippet to include SDL support in their project:

find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
target_link_libraries(mygame PRIVATE SDL3::SDL3)

Autotools users should use this snippet to include SDL support in their project:

PKG_CHECK_MODULES([SDL3], [sdl3])

and then add $SDL3_CFLAGS to their project CFLAGS and $SDL3_LIBS to their project LDFLAGS.

Makefile users can use this snippet to include SDL support in their project:

CFLAGS += $(shell pkg-config sdl3 --cflags)
LDFLAGS += $(shell pkg-config sdl3 --libs)

The SDL3test library has been renamed SDL3_test.

The SDLmain library has been removed, it's been entirely replaced by SDL_main.h.

The vi format comments have been removed from source code. Vim users can use the editorconfig plugin to automatically set tab spacing for the SDL coding style.

Installed SDL CMake configuration files no longer define SDL3_PREFIX, SDL3_EXEC_PREFIX, SDL3_INCLUDE_DIR, SDL3_INCLUDE_DIRS, SDL3_BINDIR or SDL3_LIBDIR. Users are expected to use CMake generator expressions with SDL3::SDL3, SDL3::SDL3-shared, SDL3::SDL3-static or SDL3::Headers. By no longer defining these CMake variables, using a system SDL3 or using a vendoring SDL3 behave in the same way.

SDL_atomic.h

The following structures have been renamed:

  • SDL_atomic_t => SDL_AtomicInt

The following functions have been renamed:

  • SDL_AtomicAdd() => SDL_AddAtomicInt()
  • SDL_AtomicCAS() => SDL_CompareAndSwapAtomicInt()
  • SDL_AtomicCASPtr() => SDL_CompareAndSwapAtomicPointer()
  • SDL_AtomicGet() => SDL_GetAtomicInt()
  • SDL_AtomicGetPtr() => SDL_GetAtomicPointer()
  • SDL_AtomicLock() => SDL_LockSpinlock()
  • SDL_AtomicSet() => SDL_SetAtomicInt()
  • SDL_AtomicSetPtr() => SDL_SetAtomicPointer()
  • SDL_AtomicTryLock() => SDL_TryLockSpinlock()
  • SDL_AtomicUnlock() => SDL_UnlockSpinlock()

SDL_audio.h

The audio subsystem in SDL3 is dramatically different than SDL2. The primary way to play audio is no longer an audio callback; instead you bind SDL_AudioStreams to devices; however, there is still a callback method available if needed.

The SDL 1.2 audio compatibility API has also been removed, as it was a simplified version of the audio callback interface.

SDL3 will not implicitly initialize the audio subsystem on your behalf if you open a device without doing so. Please explicitly call SDL_Init(SDL_INIT_AUDIO) at some point.

SDL2 referred to audio devices that record sound as "capture" devices, and ones that play sound to speakers as "output" devices. In SDL3, we've changed this terminology to be "recording" devices and "playback" devices, which we hope is more clear.

SDL3's audio subsystem offers an enormous amount of power over SDL2, but if you just want a simple migration of your existing code, you can ignore most of it. The simplest migration path from SDL2 looks something like this:

In SDL2, you might have done something like this to play audio...

    void SDLCALL MyAudioCallback(void *userdata, Uint8 * stream, int len)
    {
        /* Calculate a little more audio here, maybe using `userdata`, write it to `stream` */
    }

    /* ...somewhere near startup... */
    SDL_AudioSpec my_desired_audio_format;
    SDL_zero(my_desired_audio_format);
    my_desired_audio_format.format = AUDIO_S16;
    my_desired_audio_format.channels = 2;
    my_desired_audio_format.freq = 44100;
    my_desired_audio_format.samples = 1024;
    my_desired_audio_format.callback = MyAudioCallback;
    my_desired_audio_format.userdata = &my_audio_callback_user_data;
    SDL_AudioDeviceID my_audio_device = SDL_OpenAudioDevice(NULL, 0, &my_desired_audio_format, NULL, 0);
    SDL_PauseAudioDevice(my_audio_device, 0);

...in SDL3, you can do this...

    void SDLCALL MyNewAudioCallback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount)
    {
        /* Calculate a little more audio here, maybe using `userdata`, write it to `stream`
         *
         * If you want to use the original callback, you could do something like this:
         */
        if (additional_amount > 0) {
            Uint8 *data = SDL_stack_alloc(Uint8, additional_amount);
            if (data) {
                MyAudioCallback(userdata, data, additional_amount);
                SDL_PutAudioStreamData(stream, data, additional_amount);
                SDL_stack_free(data);
            }
        }
    }

    /* ...somewhere near startup... */
    const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 };
    SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, MyNewAudioCallback, &my_audio_callback_user_data);
    SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));

If you used SDL_QueueAudio instead of a callback in SDL2, this is also straightforward.

    /* ...somewhere near startup... */
    const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 };
    SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
    SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));

    /* ...in your main loop... */
    /* calculate a little more audio into `buf`, add it to `stream` */
    SDL_PutAudioStreamData(stream, buf, buflen);

...these same migration examples apply to audio recording, just using SDL_GetAudioStreamData instead of SDL_PutAudioStreamData.

SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint.

The SDL_AUDIO_ALLOW_* symbols have been removed; now one may request the format they desire from the audio device, but ultimately SDL_AudioStream will manage the difference. One can use SDL_GetAudioDeviceFormat() to see what the final format is, if any "allowed" changes should be accomodated by the app.

SDL_AudioDeviceID now represents both an open audio device's handle (a "logical" device) and the instance ID that the hardware owns as long as it exists on the system (a "physical" device). The separation between device instances and device indexes is gone, and logical and physical devices are almost entirely interchangeable at the API level.

Devices are opened by physical device instance ID, and a new logical instance ID is generated by the open operation; This allows any device to be opened multiple times, possibly by unrelated pieces of code. SDL will manage the logical devices to provide a single stream of audio to the physical device behind the scenes.

Devices are not opened by an arbitrary string name anymore, but by device instance ID (or magic numbers to request a reasonable default, like a NULL string would do in SDL2). In SDL2, the string was used to open both a standard list of system devices, but also allowed for arbitrary devices, such as hostnames of network sound servers. In SDL3, many of the backends that supported arbitrary device names are obsolete and have been removed; of those that remain, arbitrary devices will be opened with a default device ID and an SDL_hint, so specific end-users can set an environment variable to fit their needs and apps don't have to concern themselves with it.

Many functions that would accept a device index and an iscapture parameter now just take an SDL_AudioDeviceID, as they are unique across all devices, instead of separate indices into playback and recording device lists.

Rather than iterating over audio devices using a device index, there are new functions, SDL_GetAudioPlaybackDevices() and SDL_GetAudioRecordingDevices(), to get the current list of devices, and new functions to get information about devices from their instance ID:

{
    if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
        int i, num_devices;
        SDL_AudioDeviceID *devices = SDL_GetAudioPlaybackDevices(&num_devices);
        if (devices) {
            for (i = 0; i < num_devices; ++i) {
                SDL_AudioDeviceID instance_id = devices[i];
                SDL_Log("AudioDevice %" SDL_PRIu32 ": %s", instance_id, SDL_GetAudioDeviceName(instance_id));
            }
            SDL_free(devices);
        }
        SDL_QuitSubSystem(SDL_INIT_AUDIO);
    }
}

SDL_LockAudioDevice() and SDL_UnlockAudioDevice() have been removed, since there is no callback in another thread to protect. SDL's audio subsystem and SDL_AudioStream maintain their own locks internally, so audio streams are safe to use from any thread. If the app assigns a callback to a specific stream, it can use the stream's lock through SDL_LockAudioStream() if necessary.

SDL_PauseAudioDevice() no longer takes a second argument; it always pauses the device. To unpause, use SDL_ResumeAudioDevice().

Audio devices, opened by SDL_OpenAudioDevice(), no longer start in a paused state, as they don't begin processing audio until a stream is bound.

SDL_GetAudioDeviceStatus() has been removed; there is now SDL_AudioDevicePaused().

SDL_QueueAudio(), SDL_DequeueAudio, and SDL_ClearQueuedAudio and SDL_GetQueuedAudioSize() have been removed; an SDL_AudioStream bound to a device provides the exact same functionality.

APIs that use channel counts used to use a Uint8 for the channel; now they use int.

SDL_AudioSpec has been reduced; now it only holds format, channel, and sample rate. SDL_GetSilenceValueForFormat() can provide the information from the SDL_AudioSpec's removed silence field. SDL3 now manages the removed samples field; apps that want more control over device latency and throughput can force a newly-opened device's sample count with the SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES hint, but most apps should not risk messing with the defaults. The other SDL2 SDL_AudioSpec fields aren't relevant anymore.

SDL_GetAudioDeviceSpec() is removed; use SDL_GetAudioDeviceFormat() instead.

SDL_GetDefaultAudioInfo() is removed; SDL_GetAudioDeviceFormat() with SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or SDL_AUDIO_DEVICE_DEFAULT_RECORDING. There is no replacement for querying the default device name; the string is no longer used to open devices, and SDL3 will migrate between physical devices on the fly if the system default changes, so if you must show this to the user, a generic name like "System default" is recommended.

SDL_MixAudioFormat() and SDL_MIX_MAXVOLUME have been removed in favour of SDL_MixAudio(), which now takes the audio format, and a float volume between 0.0 and 1.0.

SDL_FreeWAV has been removed and calls can be replaced with SDL_free.

SDL_LoadWAV() is a proper function now and no longer a macro (but offers the same functionality otherwise).

SDL_LoadWAV_IO() and SDL_LoadWAV() return an bool now, like most of SDL. They no longer return a pointer to an SDL_AudioSpec.

SDL_AudioCVT interface has been removed, the SDL_AudioStream interface (for audio supplied in pieces) or the new SDL_ConvertAudioSamples() function (for converting a complete audio buffer in one call) can be used instead.

Code that used to look like this:

    SDL_AudioCVT cvt;
    SDL_BuildAudioCVT(&cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate);
    cvt.len = src_len;
    cvt.buf = (Uint8 *) SDL_malloc(src_len * cvt.len_mult);
    SDL_memcpy(cvt.buf, src_data, src_len);
    SDL_ConvertAudio(&cvt);
    do_something(cvt.buf, cvt.len_cvt);

should be changed to:

    Uint8 *dst_data = NULL;
    int dst_len = 0;
    const SDL_AudioSpec src_spec = { src_format, src_channels, src_rate };
    const SDL_AudioSpec dst_spec = { dst_format, dst_channels, dst_rate };
    if (!SDL_ConvertAudioSamples(&src_spec, src_data, src_len, &dst_spec, &dst_data, &dst_len)) {
        /* error */
    }
    do_something(dst_data, dst_len);
    SDL_free(dst_data);

AUDIO_U16, AUDIO_U16LSB, AUDIO_U16MSB, and AUDIO_U16SYS have been removed. They were not heavily used, and one could not memset a buffer in this format to silence with a single byte value. Use a different audio format.

If you need to convert U16 audio data to a still-supported format at runtime, the fastest, lossless conversion is to SDL_AUDIO_S16:

    /* this converts the buffer in-place. The buffer size does not change. */
    Sint16 *audio_ui16_to_si16(Uint16 *buffer, const size_t num_samples)
    {
        size_t i;
        const Uint16 *src = buffer;
        Sint16 *dst = (Sint16 *) buffer;

        for (i = 0; i < num_samples; i++) {
            dst[i] = (Sint16) (src[i] ^ 0x8000);
        }

        return dst;
    }

All remaining AUDIO_* symbols have been renamed to SDL_AUDIO_* for API consistency, but othewise are identical in value and usage.

In SDL2, SDL_AudioStream would convert/resample audio data during input (via SDL_AudioStreamPut). In SDL3, it does this work when requesting audio (via SDL_GetAudioStreamData, which would have been SDL_AudioStreamGet in SDL2). The way you use an AudioStream is roughly the same, just be aware that the workload moved to a different phase.

In SDL2, SDL_AudioStreamAvailable() returns 0 if passed a NULL stream. In SDL3, the equivalent SDL_GetAudioStreamAvailable() call returns -1 and sets an error string, which matches other audiostream APIs' behavior.

In SDL2, SDL_AUDIODEVICEREMOVED events would fire for open devices with the which field set to the SDL_AudioDeviceID of the lost device, and in later SDL2 releases, would also fire this event with a which field of zero for unopened devices, to signify that the app might want to refresh the available device list. In SDL3, this event works the same, except it won't ever fire with a zero; in this case it'll return the physical device's SDL_AudioDeviceID. Any still-open SDL_AudioDeviceIDs generated from this device with SDL_OpenAudioDevice() will also fire a separate event.

The following functions have been renamed:

  • SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable()
  • SDL_AudioStreamClear() => SDL_ClearAudioStream(), returns bool
  • SDL_AudioStreamFlush() => SDL_FlushAudioStream(), returns bool
  • SDL_AudioStreamGet() => SDL_GetAudioStreamData()
  • SDL_AudioStreamPut() => SDL_PutAudioStreamData(), returns bool
  • SDL_FreeAudioStream() => SDL_DestroyAudioStream()
  • SDL_LoadWAV_RW() => SDL_LoadWAV_IO(), returns bool
  • SDL_MixAudioFormat() => SDL_MixAudio(), returns bool
  • SDL_NewAudioStream() => SDL_CreateAudioStream()

The following functions have been removed:

  • SDL_GetNumAudioDevices()
  • SDL_GetAudioDeviceSpec()
  • SDL_ConvertAudio()
  • SDL_BuildAudioCVT()
  • SDL_OpenAudio()
  • SDL_CloseAudio()
  • SDL_PauseAudio()
  • SDL_GetAudioStatus()
  • SDL_GetAudioDeviceStatus()
  • SDL_GetDefaultAudioInfo()
  • SDL_LockAudio()
  • SDL_LockAudioDevice()
  • SDL_UnlockAudio()
  • SDL_UnlockAudioDevice()
  • SDL_MixAudio()
  • SDL_QueueAudio()
  • SDL_DequeueAudio()
  • SDL_ClearAudioQueue()
  • SDL_GetQueuedAudioSize()

The following symbols have been renamed:

  • AUDIO_F32 => SDL_AUDIO_F32LE
  • AUDIO_F32LSB => SDL_AUDIO_F32LE
  • AUDIO_F32MSB => SDL_AUDIO_F32BE
  • AUDIO_F32SYS => SDL_AUDIO_F32
  • AUDIO_S16 => SDL_AUDIO_S16LE
  • AUDIO_S16LSB => SDL_AUDIO_S16LE
  • AUDIO_S16MSB => SDL_AUDIO_S16BE
  • AUDIO_S16SYS => SDL_AUDIO_S16
  • AUDIO_S32 => SDL_AUDIO_S32LE
  • AUDIO_S32LSB => SDL_AUDIO_S32LE
  • AUDIO_S32MSB => SDL_AUDIO_S32BE
  • AUDIO_S32SYS => SDL_AUDIO_S32
  • AUDIO_S8 => SDL_AUDIO_S8
  • AUDIO_U8 => SDL_AUDIO_U8

The following symbols have been removed:

  • SDL_MIX_MAXVOLUME - mixer volume is now a float between 0.0 and 1.0

SDL_cpuinfo.h

The intrinsics headers (mmintrin.h, etc.) have been moved to <SDL3/SDL_intrin.h> and are no longer automatically included in SDL.h.

SDL_Has3DNow() has been removed; there is no replacement.

SDL_HasRDTSC() has been removed; there is no replacement. Don't use the RDTSC opcode in modern times, use SDL_GetPerformanceCounter and SDL_GetPerformanceFrequency instead.

SDL_SIMDAlloc(), SDL_SIMDRealloc(), and SDL_SIMDFree() have been removed. You can use SDL_aligned_alloc() and SDL_aligned_free() with SDL_GetSIMDAlignment() to get the same functionality.

The following functions have been renamed:

  • SDL_GetCPUCount() => SDL_GetNumLogicalCPUCores()
  • SDL_SIMDGetAlignment() => SDL_GetSIMDAlignment()

SDL_endian.h

The following functions have been renamed:

  • SDL_SwapBE16() => SDL_Swap16BE()
  • SDL_SwapBE32() => SDL_Swap32BE()
  • SDL_SwapBE64() => SDL_Swap64BE()
  • SDL_SwapLE16() => SDL_Swap16LE()
  • SDL_SwapLE32() => SDL_Swap32LE()
  • SDL_SwapLE64() => SDL_Swap64LE()

SDL_error.h

The following functions have been removed:

  • SDL_GetErrorMsg() - Can be implemented as SDL_strlcpy(errstr, SDL_GetError(), maxlen);

SDL_events.h

SDL_PRESSED and SDL_RELEASED have been removed. For the most part you can replace uses of these with true and false respectively. Events which had a field state to represent these values have had those fields changed to bool down, e.g. event.key.state is now event.key.down.

The timestamp member of the SDL_Event structure now represents nanoseconds, and is populated with SDL_GetTicksNS()

The timestamp_us member of the sensor events has been renamed sensor_timestamp and now represents nanoseconds. This value is filled in from the hardware, if available, and may not be synchronized with values returned from SDL_GetTicksNS().

You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().

Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed.

Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.

The SDL_DISPLAYEVENT_* events have been moved to top level events, and SDL_DISPLAYEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_DISPLAYEVENT and then checking for display events. You can compare the event >= SDL_EVENT_DISPLAY_FIRST and <= SDL_EVENT_DISPLAY_LAST if you need to see whether it's a display event.

The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event.

The SDL_EVENT_WINDOW_RESIZED event is always sent, even in response to SDL_SetWindowSize().

The SDL_EVENT_WINDOW_SIZE_CHANGED event has been removed, and you can use SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED to detect window backbuffer size changes.

The keysym field of key events has been removed to remove one level of indirection, and sym has been renamed key.

Code that used to look like this:

    SDL_Event event;
    SDL_Keycode key = event.key.keysym.sym;
    SDL_Keymod mod = event.key.keysym.mod;

should be changed to:

    SDL_Event event;
    SDL_Keycode key = event.key.key;
    SDL_Keymod mod = event.key.mod;

The gamepad event structures caxis, cbutton, cdevice, ctouchpad, and csensor have been renamed gaxis, gbutton, gdevice, gtouchpad, and gsensor.

The mouseX and mouseY fields of SDL_MouseWheelEvent have been renamed mouse_x and mouse_y.

The touchId and fingerId fields of SDL_TouchFingerEvent have been renamed touchID and fingerID.

The level field of SDL_JoyBatteryEvent has been split into state and percent.

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 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.

SDL_EventFilter functions now return bool.

The following symbols have been renamed:

  • SDL_APP_DIDENTERBACKGROUND => SDL_EVENT_DID_ENTER_BACKGROUND
  • SDL_APP_DIDENTERFOREGROUND => SDL_EVENT_DID_ENTER_FOREGROUND
  • SDL_APP_LOWMEMORY => SDL_EVENT_LOW_MEMORY
  • SDL_APP_TERMINATING => SDL_EVENT_TERMINATING
  • SDL_APP_WILLENTERBACKGROUND => SDL_EVENT_WILL_ENTER_BACKGROUND
  • SDL_APP_WILLENTERFOREGROUND => SDL_EVENT_WILL_ENTER_FOREGROUND
  • SDL_AUDIODEVICEADDED => SDL_EVENT_AUDIO_DEVICE_ADDED
  • SDL_AUDIODEVICEREMOVED => SDL_EVENT_AUDIO_DEVICE_REMOVED
  • SDL_CLIPBOARDUPDATE => SDL_EVENT_CLIPBOARD_UPDATE
  • SDL_CONTROLLERAXISMOTION => SDL_EVENT_GAMEPAD_AXIS_MOTION
  • SDL_CONTROLLERBUTTONDOWN => SDL_EVENT_GAMEPAD_BUTTON_DOWN
  • SDL_CONTROLLERBUTTONUP => SDL_EVENT_GAMEPAD_BUTTON_UP
  • SDL_CONTROLLERDEVICEADDED => SDL_EVENT_GAMEPAD_ADDED
  • SDL_CONTROLLERDEVICEREMAPPED => SDL_EVENT_GAMEPAD_REMAPPED
  • SDL_CONTROLLERDEVICEREMOVED => SDL_EVENT_GAMEPAD_REMOVED
  • SDL_CONTROLLERSENSORUPDATE => SDL_EVENT_GAMEPAD_SENSOR_UPDATE
  • SDL_CONTROLLERSTEAMHANDLEUPDATED => SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED
  • SDL_CONTROLLERTOUCHPADDOWN => SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN
  • SDL_CONTROLLERTOUCHPADMOTION => SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION
  • SDL_CONTROLLERTOUCHPADUP => SDL_EVENT_GAMEPAD_TOUCHPAD_UP
  • SDL_DROPBEGIN => SDL_EVENT_DROP_BEGIN
  • SDL_DROPCOMPLETE => SDL_EVENT_DROP_COMPLETE
  • SDL_DROPFILE => SDL_EVENT_DROP_FILE
  • SDL_DROPTEXT => SDL_EVENT_DROP_TEXT
  • SDL_FINGERDOWN => SDL_EVENT_FINGER_DOWN
  • SDL_FINGERMOTION => SDL_EVENT_FINGER_MOTION
  • SDL_FINGERUP => SDL_EVENT_FINGER_UP
  • SDL_FIRSTEVENT => SDL_EVENT_FIRST
  • SDL_JOYAXISMOTION => SDL_EVENT_JOYSTICK_AXIS_MOTION
  • SDL_JOYBALLMOTION => SDL_EVENT_JOYSTICK_BALL_MOTION
  • SDL_JOYBATTERYUPDATED => SDL_EVENT_JOYSTICK_BATTERY_UPDATED
  • SDL_JOYBUTTONDOWN => SDL_EVENT_JOYSTICK_BUTTON_DOWN
  • SDL_JOYBUTTONUP => SDL_EVENT_JOYSTICK_BUTTON_UP
  • SDL_JOYDEVICEADDED => SDL_EVENT_JOYSTICK_ADDED
  • SDL_JOYDEVICEREMOVED => SDL_EVENT_JOYSTICK_REMOVED
  • SDL_JOYHATMOTION => SDL_EVENT_JOYSTICK_HAT_MOTION
  • SDL_KEYDOWN => SDL_EVENT_KEY_DOWN
  • SDL_KEYMAPCHANGED => SDL_EVENT_KEYMAP_CHANGED
  • SDL_KEYUP => SDL_EVENT_KEY_UP
  • SDL_LASTEVENT => SDL_EVENT_LAST
  • SDL_LOCALECHANGED => SDL_EVENT_LOCALE_CHANGED
  • SDL_MOUSEBUTTONDOWN => SDL_EVENT_MOUSE_BUTTON_DOWN
  • SDL_MOUSEBUTTONUP => SDL_EVENT_MOUSE_BUTTON_UP
  • SDL_MOUSEMOTION => SDL_EVENT_MOUSE_MOTION
  • SDL_MOUSEWHEEL => SDL_EVENT_MOUSE_WHEEL
  • SDL_POLLSENTINEL => SDL_EVENT_POLL_SENTINEL
  • SDL_QUIT => SDL_EVENT_QUIT
  • SDL_RENDER_DEVICE_RESET => SDL_EVENT_RENDER_DEVICE_RESET
  • SDL_RENDER_TARGETS_RESET => SDL_EVENT_RENDER_TARGETS_RESET
  • SDL_SENSORUPDATE => SDL_EVENT_SENSOR_UPDATE
  • SDL_TEXTEDITING => SDL_EVENT_TEXT_EDITING
  • SDL_TEXTEDITING_EXT => SDL_EVENT_TEXT_EDITING_EXT
  • SDL_TEXTINPUT => SDL_EVENT_TEXT_INPUT
  • SDL_USEREVENT => SDL_EVENT_USER

The following symbols have been removed:

  • SDL_DROPEVENT_DATA_SIZE - drop event data is dynamically allocated
  • SDL_SYSWMEVENT - you can use SDL_SetWindowsMessageHook() and SDL_SetX11EventHook() to watch and modify system events before SDL sees them.
  • SDL_TEXTEDITINGEVENT_TEXT_SIZE - text editing event data is dynamically allocated

The following structures have been renamed:

  • SDL_ControllerAxisEvent => SDL_GamepadAxisEvent
  • SDL_ControllerButtonEvent => SDL_GamepadButtonEvent
  • SDL_ControllerDeviceEvent => SDL_GamepadDeviceEvent
  • SDL_ControllerSensorEvent => SDL_GamepadSensorEvent
  • SDL_ControllerTouchpadEvent => SDL_GamepadTouchpadEvent

The following functions have been removed:

  • SDL_EventState() - replaced with SDL_SetEventEnabled()
  • SDL_GetEventState() - replaced with SDL_EventEnabled()

The following enums have been renamed:

  • SDL_eventaction => SDL_EventAction

The following functions have been renamed:

  • SDL_DelEventWatch() => SDL_RemoveEventWatch()

SDL_gamecontroller.h

SDL_gamecontroller.h has been renamed SDL_gamepad.h, and all APIs have been renamed to match.

The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the which member of the cdevice event structure.

The functions SDL_GetGamepads(), SDL_GetGamepadNameForID(), SDL_GetGamepadPathForID(), SDL_GetGamepadPlayerIndexForID(), SDL_GetGamepadGUIDForID(), SDL_GetGamepadVendorForID(), SDL_GetGamepadProductForID(), SDL_GetGamepadProductVersionForID(), and SDL_GetGamepadTypeForID() have been added to directly query the list of available gamepads.

The gamepad face buttons have been renamed from A/B/X/Y to North/South/East/West to indicate that they are positional rather than hardware-specific. You can use SDL_GetGamepadButtonLabel() to get the labels for the face buttons, e.g. A/B/X/Y or Cross/Circle/Square/Triangle. The hint SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS is ignored, and mappings that use this hint are translated correctly into positional buttons. Applications should provide a way for users to swap between South/East as their accept/cancel buttons, as this varies based on region and muscle memory. You can use an approach similar to the following to handle this:

#define CONFIRM_BUTTON SDL_GAMEPAD_BUTTON_SOUTH
#define CANCEL_BUTTON SDL_GAMEPAD_BUTTON_EAST

bool flipped_buttons;

void InitMappedButtons(SDL_Gamepad *gamepad)
{
    if (!GetFlippedButtonSetting(&flipped_buttons)) {
        if (SDL_GetGamepadButtonLabel(gamepad, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B) {
            flipped_buttons = true;
        } else {
            flipped_buttons = false;
        }
    }
}

SDL_GamepadButton GetMappedButton(SDL_GamepadButton button)
{
    if (flipped_buttons) {
        switch (button) {
        case SDL_GAMEPAD_BUTTON_SOUTH:
            return SDL_GAMEPAD_BUTTON_EAST;
        case SDL_GAMEPAD_BUTTON_EAST:
            return SDL_GAMEPAD_BUTTON_SOUTH;
        case SDL_GAMEPAD_BUTTON_WEST:
            return SDL_GAMEPAD_BUTTON_NORTH;
        case SDL_GAMEPAD_BUTTON_NORTH:
            return SDL_GAMEPAD_BUTTON_WEST;
        default:
            break;
        }
    }
    return button;
}

SDL_GamepadButtonLabel GetConfirmActionLabel(SDL_Gamepad *gamepad)
{
    return SDL_GetGamepadButtonLabel(gamepad, GetMappedButton(CONFIRM_BUTTON));
}

SDL_GamepadButtonLabel GetCancelActionLabel(SDL_Gamepad *gamepad)
{
    return SDL_GetGamepadButtonLabel(gamepad, GetMappedButton(CANCEL_BUTTON));
}

void HandleGamepadEvent(SDL_Event *event)
{
    if (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
        switch (GetMappedButton(event->gbutton.button)) {
        case CONFIRM_BUTTON:
            /* Handle confirm action */
            break;
        case CANCEL_BUTTON:
            /* Handle cancel action */
            break;
        default:
            /* ... */
            break;
        }
    }
}

SDL_GameControllerGetSensorDataWithTimestamp() has been removed. If you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_GAMEPAD_SENSOR_UPDATE events.

SDL_CONTROLLER_TYPE_VIRTUAL has been removed, so virtual controllers can emulate other gamepad types. If you need to know whether a controller is virtual, you can use SDL_IsJoystickVirtual().

SDL_CONTROLLER_TYPE_AMAZON_LUNA has been removed, and can be replaced with this code:

bool SDL_IsJoystickAmazonLunaController(Uint16 vendor_id, Uint16 product_id)
{
    return ((vendor_id == 0x1949 && product_id == 0x0419) ||
            (vendor_id == 0x0171 && product_id == 0x0419));
}

SDL_CONTROLLER_TYPE_GOOGLE_STADIA has been removed, and can be replaced with this code:

bool SDL_IsJoystickGoogleStadiaController(Uint16 vendor_id, Uint16 product_id)
{
    return (vendor_id == 0x18d1 && product_id == 0x9400);
}

SDL_CONTROLLER_TYPE_NVIDIA_SHIELD has been removed, and can be replaced with this code:

bool SDL_IsJoystickNVIDIASHIELDController(Uint16 vendor_id, Uint16 product_id)
{
    return (vendor_id == 0x0955 && (product_id == 0x7210 || product_id == 0x7214));
}

The inputType and outputType fields of SDL_GamepadBinding have been renamed input_type and output_type.

SDL_GetGamepadTouchpadFinger() takes a pointer to bool for the finger state instead of a pointer to Uint8.

The following enums have been renamed:

  • SDL_GameControllerAxis => SDL_GamepadAxis
  • SDL_GameControllerBindType => SDL_GamepadBindingType
  • SDL_GameControllerButton => SDL_GamepadButton
  • SDL_GameControllerType => SDL_GamepadType

The following structures have been renamed:

  • SDL_GameController => SDL_Gamepad

The following functions have been renamed:

  • SDL_GameControllerAddMapping() => SDL_AddGamepadMapping()
  • SDL_GameControllerAddMappingsFromFile() => SDL_AddGamepadMappingsFromFile()
  • SDL_GameControllerAddMappingsFromRW() => SDL_AddGamepadMappingsFromIO()
  • SDL_GameControllerClose() => SDL_CloseGamepad()
  • SDL_GameControllerFromInstanceID() => SDL_GetGamepadFromID()
  • SDL_GameControllerFromPlayerIndex() => SDL_GetGamepadFromPlayerIndex()
  • SDL_GameControllerGetAppleSFSymbolsNameForAxis() => SDL_GetGamepadAppleSFSymbolsNameForAxis()
  • SDL_GameControllerGetAppleSFSymbolsNameForButton() => SDL_GetGamepadAppleSFSymbolsNameForButton()
  • SDL_GameControllerGetAttached() => SDL_GamepadConnected()
  • SDL_GameControllerGetAxis() => SDL_GetGamepadAxis()
  • SDL_GameControllerGetAxisFromString() => SDL_GetGamepadAxisFromString()
  • SDL_GameControllerGetButton() => SDL_GetGamepadButton()
  • SDL_GameControllerGetButtonFromString() => SDL_GetGamepadButtonFromString()
  • SDL_GameControllerGetFirmwareVersion() => SDL_GetGamepadFirmwareVersion()
  • SDL_GameControllerGetJoystick() => SDL_GetGamepadJoystick()
  • SDL_GameControllerGetNumTouchpadFingers() => SDL_GetNumGamepadTouchpadFingers()
  • SDL_GameControllerGetNumTouchpads() => SDL_GetNumGamepadTouchpads()
  • SDL_GameControllerGetPlayerIndex() => SDL_GetGamepadPlayerIndex()
  • SDL_GameControllerGetProduct() => SDL_GetGamepadProduct()
  • SDL_GameControllerGetProductVersion() => SDL_GetGamepadProductVersion()
  • SDL_GameControllerGetSensorData() => SDL_GetGamepadSensorData(), returns bool
  • SDL_GameControllerGetSensorDataRate() => SDL_GetGamepadSensorDataRate()
  • SDL_GameControllerGetSerial() => SDL_GetGamepadSerial()
  • SDL_GameControllerGetSteamHandle() => SDL_GetGamepadSteamHandle()
  • SDL_GameControllerGetStringForAxis() => SDL_GetGamepadStringForAxis()
  • SDL_GameControllerGetStringForButton() => SDL_GetGamepadStringForButton()
  • SDL_GameControllerGetTouchpadFinger() => SDL_GetGamepadTouchpadFinger(), returns bool
  • SDL_GameControllerGetType() => SDL_GetGamepadType()
  • SDL_GameControllerGetVendor() => SDL_GetGamepadVendor()
  • SDL_GameControllerHasAxis() => SDL_GamepadHasAxis()
  • SDL_GameControllerHasButton() => SDL_GamepadHasButton()
  • SDL_GameControllerHasSensor() => SDL_GamepadHasSensor()
  • SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled()
  • SDL_GameControllerMapping() => SDL_GetGamepadMapping()
  • SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID()
  • SDL_GameControllerName() => SDL_GetGamepadName()
  • SDL_GameControllerOpen() => SDL_OpenGamepad()
  • SDL_GameControllerPath() => SDL_GetGamepadPath()
  • SDL_GameControllerRumble() => SDL_RumbleGamepad(), returns bool
  • SDL_GameControllerRumbleTriggers() => SDL_RumbleGamepadTriggers(), returns bool
  • SDL_GameControllerSendEffect() => SDL_SendGamepadEffect(), returns bool
  • SDL_GameControllerSetLED() => SDL_SetGamepadLED(), returns bool
  • SDL_GameControllerSetPlayerIndex() => SDL_SetGamepadPlayerIndex(), returns bool
  • SDL_GameControllerSetSensorEnabled() => SDL_SetGamepadSensorEnabled(), returns bool
  • SDL_GameControllerUpdate() => SDL_UpdateGamepads()
  • SDL_IsGameController() => SDL_IsGamepad()

The following functions have been removed:

  • SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled()
  • SDL_GameControllerGetBindForAxis() - replaced with SDL_GetGamepadBindings()
  • SDL_GameControllerGetBindForButton() - replaced with SDL_GetGamepadBindings()
  • SDL_GameControllerHasLED() - replaced with SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN
  • SDL_GameControllerHasRumble() - replaced with SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN
  • SDL_GameControllerHasRumbleTriggers() - replaced with SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN
  • SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadMappingForID()
  • SDL_GameControllerMappingForIndex() - replaced with SDL_GetGamepadMappings()
  • SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadNameForID()
  • SDL_GameControllerNumMappings() - replaced with SDL_GetGamepadMappings()
  • SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadPathForID()
  • SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadTypeForID()

The following symbols have been renamed:

  • SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID
  • SDL_CONTROLLER_AXIS_LEFTX => SDL_GAMEPAD_AXIS_LEFTX
  • SDL_CONTROLLER_AXIS_LEFTY => SDL_GAMEPAD_AXIS_LEFTY
  • SDL_CONTROLLER_AXIS_MAX => SDL_GAMEPAD_AXIS_COUNT
  • SDL_CONTROLLER_AXIS_RIGHTX => SDL_GAMEPAD_AXIS_RIGHTX
  • SDL_CONTROLLER_AXIS_RIGHTY => SDL_GAMEPAD_AXIS_RIGHTY
  • SDL_CONTROLLER_AXIS_TRIGGERLEFT => SDL_GAMEPAD_AXIS_LEFT_TRIGGER
  • SDL_CONTROLLER_AXIS_TRIGGERRIGHT => SDL_GAMEPAD_AXIS_RIGHT_TRIGGER
  • SDL_CONTROLLER_BINDTYPE_AXIS => SDL_GAMEPAD_BINDTYPE_AXIS
  • SDL_CONTROLLER_BINDTYPE_BUTTON => SDL_GAMEPAD_BINDTYPE_BUTTON
  • SDL_CONTROLLER_BINDTYPE_HAT => SDL_GAMEPAD_BINDTYPE_HAT
  • SDL_CONTROLLER_BINDTYPE_NONE => SDL_GAMEPAD_BINDTYPE_NONE
  • SDL_CONTROLLER_BUTTON_A => SDL_GAMEPAD_BUTTON_SOUTH
  • SDL_CONTROLLER_BUTTON_B => SDL_GAMEPAD_BUTTON_EAST
  • SDL_CONTROLLER_BUTTON_BACK => SDL_GAMEPAD_BUTTON_BACK
  • SDL_CONTROLLER_BUTTON_DPAD_DOWN => SDL_GAMEPAD_BUTTON_DPAD_DOWN
  • SDL_CONTROLLER_BUTTON_DPAD_LEFT => SDL_GAMEPAD_BUTTON_DPAD_LEFT
  • SDL_CONTROLLER_BUTTON_DPAD_RIGHT => SDL_GAMEPAD_BUTTON_DPAD_RIGHT
  • SDL_CONTROLLER_BUTTON_DPAD_UP => SDL_GAMEPAD_BUTTON_DPAD_UP
  • SDL_CONTROLLER_BUTTON_GUIDE => SDL_GAMEPAD_BUTTON_GUIDE
  • SDL_CONTROLLER_BUTTON_INVALID => SDL_GAMEPAD_BUTTON_INVALID
  • SDL_CONTROLLER_BUTTON_LEFTSHOULDER => SDL_GAMEPAD_BUTTON_LEFT_SHOULDER
  • SDL_CONTROLLER_BUTTON_LEFTSTICK => SDL_GAMEPAD_BUTTON_LEFT_STICK
  • SDL_CONTROLLER_BUTTON_MAX => SDL_GAMEPAD_BUTTON_COUNT
  • SDL_CONTROLLER_BUTTON_MISC1 => SDL_GAMEPAD_BUTTON_MISC1
  • SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1
  • SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE1
  • SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2
  • SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE2
  • SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER
  • SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK
  • SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START
  • SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD
  • SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_WEST
  • SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_NORTH
  • SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT
  • SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
  • SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT
  • SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO
  • SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3
  • SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4
  • SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5
  • SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_STANDARD
  • SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL
  • SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360
  • SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE

SDL_gesture.h

The gesture API has been removed. There is no replacement planned in SDL3. However, the SDL2 code has been moved to a single-header library that can be dropped into an SDL3 or SDL2 program, to continue to provide this functionality to your app and aid migration. That is located in the SDL_gesture GitHub repository.

SDL_guid.h

SDL_GUIDToString() returns a const pointer to the string representation of a GUID.

The following functions have been renamed:

  • SDL_GUIDFromString() => SDL_StringToGUID()

SDL_haptic.h

Gamepads with simple rumble capability no longer show up in the SDL haptics interface, instead you should use SDL_RumbleGamepad().

Rather than iterating over haptic devices using device index, there is a new function SDL_GetHaptics() to get the current list of haptic devices, and new functions to get information about haptic devices from their instance ID:

{
    if (SDL_InitSubSystem(SDL_INIT_HAPTIC)) {
        int i, num_haptics;
        SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics);
        if (haptics) {
            for (i = 0; i < num_haptics; ++i) {
                SDL_HapticID instance_id = haptics[i];
                SDL_Log("Haptic %" SDL_PRIu32 ": %s", instance_id, SDL_GetHapticNameForID(instance_id));
            }
            SDL_free(haptics);
        }
        SDL_QuitSubSystem(SDL_INIT_HAPTIC);
    }
}

SDL_GetHapticEffectStatus() now returns bool instead of an int result. You should call SDL_GetHapticFeatures() to make sure effect status is supported before calling this function.

The following functions have been renamed:

  • SDL_HapticClose() => SDL_CloseHaptic()
  • SDL_HapticDestroyEffect() => SDL_DestroyHapticEffect()
  • SDL_HapticGetEffectStatus() => SDL_GetHapticEffectStatus(), returns bool
  • SDL_HapticNewEffect() => SDL_CreateHapticEffect()
  • SDL_HapticNumAxes() => SDL_GetNumHapticAxes()
  • SDL_HapticNumEffects() => SDL_GetMaxHapticEffects()
  • SDL_HapticNumEffectsPlaying() => SDL_GetMaxHapticEffectsPlaying()
  • SDL_HapticOpen() => SDL_OpenHaptic()
  • SDL_HapticOpenFromJoystick() => SDL_OpenHapticFromJoystick()
  • SDL_HapticOpenFromMouse() => SDL_OpenHapticFromMouse()
  • SDL_HapticPause() => SDL_PauseHaptic(), returns bool
  • SDL_HapticQuery() => SDL_GetHapticFeatures()
  • SDL_HapticRumbleInit() => SDL_InitHapticRumble(), returns bool
  • SDL_HapticRumblePlay() => SDL_PlayHapticRumble(), returns bool
  • SDL_HapticRumbleStop() => SDL_StopHapticRumble(), returns bool
  • SDL_HapticRunEffect() => SDL_RunHapticEffect(), returns bool
  • SDL_HapticSetAutocenter() => SDL_SetHapticAutocenter(), returns bool
  • SDL_HapticSetGain() => SDL_SetHapticGain(), returns bool
  • SDL_HapticStopAll() => SDL_StopHapticEffects(), returns bool
  • SDL_HapticStopEffect() => SDL_StopHapticEffect(), returns bool
  • SDL_HapticUnpause() => SDL_ResumeHaptic(), returns bool
  • SDL_HapticUpdateEffect() => SDL_UpdateHapticEffect(), returns bool
  • SDL_JoystickIsHaptic() => SDL_IsJoystickHaptic()
  • SDL_MouseIsHaptic() => SDL_IsMouseHaptic()

The following functions have been removed:

  • SDL_HapticIndex() - replaced with SDL_GetHapticID()
  • SDL_HapticName() - replaced with SDL_GetHapticNameForID()
  • SDL_HapticOpened() - replaced with SDL_GetHapticFromID()
  • SDL_NumHaptics() - replaced with SDL_GetHaptics()

SDL_hints.h

Calling SDL_GetHint() with the name of the hint being changed from within a hint callback will now return the new value rather than the old value. The old value is still passed as a parameter to the hint callback.

The environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER have been renamed to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER, but the old names are still supported as a fallback.

The environment variables SDL_VIDEO_X11_WMCLASS and SDL_VIDEO_WAYLAND_WMCLASS have been removed and replaced by either using the appindentifier param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_IDENTIFIER_STRING with SDL_SetAppMetadataProperty()

The environment variable AUDIODEV is used exclusively to specify the audio device for the OSS and NetBSD audio drivers. Its use in the ALSA driver has been replaced with the hint SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE and in the sndio driver with the environment variable AUDIODEVICE.

The following hints have been renamed:

  • SDL_HINT_ALLOW_TOPMOST => SDL_HINT_WINDOW_ALLOW_TOPMOST
  • SDL_HINT_AUDIODRIVER => SDL_HINT_AUDIO_DRIVER
  • SDL_HINT_DIRECTINPUT_ENABLED => SDL_HINT_JOYSTICK_DIRECTINPUT
  • SDL_HINT_GDK_TEXTINPUT_DEFAULT => SDL_HINT_GDK_TEXTINPUT_DEFAULT_TEXT
  • SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE => SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE
  • SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE => SDL_HINT_JOYSTICK_ENHANCED_REPORTS
  • SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE => SDL_HINT_JOYSTICK_ENHANCED_REPORTS
  • SDL_HINT_LINUX_DIGITAL_HATS => SDL_HINT_JOYSTICK_LINUX_DIGITAL_HATS
  • SDL_HINT_LINUX_HAT_DEADZONES => SDL_HINT_JOYSTICK_LINUX_HAT_DEADZONES
  • SDL_HINT_LINUX_JOYSTICK_CLASSIC => SDL_HINT_JOYSTICK_LINUX_CLASSIC
  • SDL_HINT_LINUX_JOYSTICK_DEADZONES => SDL_HINT_JOYSTICK_LINUX_DEADZONES
  • SDL_HINT_VIDEODRIVER => SDL_HINT_VIDEO_DRIVER
  • SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP => SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE

The following hints have been removed:

  • SDL_HINT_ACCELEROMETER_AS_JOYSTICK
  • SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO - the audio will be paused when the application is paused, and SDL_HINT_ANDROID_BLOCK_ON_PAUSE can be used to control that
  • SDL_HINT_AUDIO_DEVICE_APP_NAME - replaced by either using the appname param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_NAME_STRING with SDL_SetAppMetadataProperty()
  • SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS - gamepad buttons are always positional
  • SDL_HINT_GRAB_KEYBOARD - use SDL_SetWindowKeyboardGrab() instead
  • SDL_HINT_IDLE_TIMER_DISABLED - use SDL_DisableScreenSaver() instead
  • SDL_HINT_IME_INTERNAL_EDITING - replaced with SDL_HINT_IME_IMPLEMENTED_UI
  • SDL_HINT_IME_SHOW_UI - replaced with SDL_HINT_IME_IMPLEMENTED_UI
  • SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has extended text
  • SDL_HINT_MOUSE_RELATIVE_MODE_WARP - relative mode is always implemented at the hardware level or reported as unavailable
  • SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer
  • SDL_HINT_PS2_DYNAMIC_VSYNC - use SDL_SetRenderVSync(renderer, -1) instead
  • SDL_HINT_RENDER_BATCHING - Render batching is always enabled, apps should call SDL_FlushRenderer() before calling into a lower-level graphics API.
  • SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation()
  • SDL_HINT_RENDER_OPENGL_SHADERS - shaders are always used if they are available
  • SDL_HINT_RENDER_SCALE_QUALITY - textures now default to linear filtering, use SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST) if you want nearest pixel mode instead
  • SDL_HINT_THREAD_STACK_SIZE - the stack size can be specified using SDL_CreateThreadWithProperties()
  • SDL_HINT_VIDEO_EXTERNAL_CONTEXT - replaced with SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN in SDL_CreateWindowWithProperties()
  • SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL - replaced with SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN in SDL_CreateWindowWithProperties()
  • SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN - replaced with SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN in SDL_CreateWindowWithProperties()
  • SDL_HINT_VIDEO_HIGHDPI_DISABLED - high DPI support is always enabled
  • SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT - replaced with SDL_PROP_WINDOW_CREATE_WIN32_PIXEL_FORMAT_HWND_POINTER in SDL_CreateWindowWithProperties()
  • SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead
  • SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
  • SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
  • SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING - SDL now properly handles the 0x406D1388 Exception if no debugger intercepts it, preventing its propagation.
  • SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS - Slim Reader/Writer Locks are always used if available
  • SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 - replaced with SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4, defaulting to true
  • SDL_HINT_WINRT_HANDLE_BACK_BUTTON - WinRT support was removed in SDL3.
  • SDL_HINT_WINRT_PRIVACY_POLICY_LABEL - WinRT support was removed in SDL3.
  • SDL_HINT_WINRT_PRIVACY_POLICY_URL - WinRT support was removed in SDL3.
  • SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING

The following environment variables have been renamed:

  • SDL_AUDIODRIVER => SDL_AUDIO_DRIVER
  • SDL_PATH_DSP => AUDIODEV
  • SDL_VIDEODRIVER => SDL_VIDEO_DRIVER

The following environment variables have been removed:

  • SDL_AUDIO_ALSA_DEBUG - replaced by setting the hint SDL_HINT_LOGGING to "audio=debug"
  • SDL_DISKAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DISK_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay.
  • SDL_DISKAUDIOFILE - replaced with the hint SDL_HINT_AUDIO_DISK_OUTPUT_FILE
  • SDL_DISKAUDIOFILEIN - replaced with the hint SDL_HINT_AUDIO_DISK_INPUT_FILE
  • SDL_DUMMYAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DUMMY_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay.
  • SDL_HAPTIC_GAIN_MAX
  • SDL_HIDAPI_DISABLE_LIBUSB - replaced with the hint SDL_HINT_HIDAPI_LIBUSB
  • SDL_HIDAPI_JOYSTICK_DISABLE_UDEV - replaced with the hint SDL_HINT_HIDAPI_UDEV
  • SDL_INPUT_FREEBSD_KEEP_KBD - replaced with the hint SDL_HINT_MUTE_CONSOLE_KEYBOARD
  • SDL_INPUT_LINUX_KEEP_KBD - replaced with the hint SDL_HINT_MUTE_CONSOLE_KEYBOARD
  • VITA_DISABLE_TOUCH_BACK - replaced with the hint SDL_HINT_VITA_ENABLE_BACK_TOUCH
  • VITA_DISABLE_TOUCH_FRONT - replaced with the hint SDL_HINT_VITA_ENABLE_FRONT_TOUCH
  • VITA_MODULE_PATH - replaced with the hint SDL_HINT_VITA_MODULE_PATH
  • VITA_PVR_OGL - replaced with the hint SDL_HINT_VITA_PVR_OPENGL
  • VITA_PVR_SKIP_INIT - replaced with the hint SDL_HINT_VITA_PVR_INIT
  • VITA_RESOLUTION - replaced with the hint SDL_HINT_VITA_RESOLUTION

The following functions have been removed:

  • SDL_ClearHints() - replaced with SDL_ResetHints()

The following functions have been renamed:

  • SDL_DelHintCallback() => SDL_RemoveHintCallback()

SDL_init.h

On Haiku OS, SDL no longer sets the current working directory to the executable's path during SDL_Init(). If you need this functionality, the fastest solution is to add this code directly after the call to SDL_Init:

{
    const char *path = SDL_GetBasePath();
    if (path) {
        chdir(path);
    }
}

The following symbols have been renamed:

  • SDL_INIT_GAMECONTROLLER => SDL_INIT_GAMEPAD

The following symbols have been removed:

  • SDL_INIT_NOPARACHUTE
  • SDL_INIT_EVERYTHING - you should only initialize the subsystems you are using
  • SDL_INIT_TIMER - no longer needed before calling SDL_AddTimer()

SDL_joystick.h

SDL_JoystickID has changed from Sint32 to Uint32, with an invalid ID being 0.

Rather than iterating over joysticks using device index, there is a new function SDL_GetJoysticks() to get the current list of joysticks, and new functions to get information about joysticks from their instance ID:

{
    if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
        int i, num_joysticks;
        SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks);
        if (joysticks) {
            for (i = 0; i < num_joysticks; ++i) {
                SDL_JoystickID instance_id = joysticks[i];
                const char *name = SDL_GetJoystickNameForID(instance_id);
                const char *path = SDL_GetJoystickPathForID(instance_id);

                SDL_Log("Joystick %" SDL_PRIu32 ": %s%s%s VID 0x%.4x, PID 0x%.4x",
                        instance_id, name ? name : "Unknown", path ? ", " : "", path ? path : "", SDL_GetJoystickVendorForID(instance_id), SDL_GetJoystickProductForID(instance_id));
            }
            SDL_free(joysticks);
        }
        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
    }
}

The SDL_EVENT_JOYSTICK_ADDED event now provides the joystick instance ID in the which member of the jdevice event structure.

The functions SDL_GetJoysticks(), SDL_GetJoystickNameForID(), SDL_GetJoystickPathForID(), SDL_GetJoystickPlayerIndexForID(), SDL_GetJoystickGUIDForID(), SDL_GetJoystickVendorForID(), SDL_GetJoystickProductForID(), SDL_GetJoystickProductVersionForID(), and SDL_GetJoystickTypeForID() have been added to directly query the list of available joysticks.

SDL_AttachVirtualJoystick() now returns the joystick instance ID instead of a device index, and returns 0 if there was an error.

SDL_VirtualJoystickDesc version should not be set to SDL_VIRTUAL_JOYSTICK_DESC_VERSION, instead the structure should be initialized using SDL_INIT_INTERFACE().

The following functions have been renamed:

  • SDL_JoystickAttachVirtualEx() => SDL_AttachVirtualJoystick()
  • SDL_JoystickClose() => SDL_CloseJoystick()
  • SDL_JoystickDetachVirtual() => SDL_DetachVirtualJoystick(), returns bool
  • SDL_JoystickFromInstanceID() => SDL_GetJoystickFromID()
  • SDL_JoystickFromPlayerIndex() => SDL_GetJoystickFromPlayerIndex()
  • SDL_JoystickGetAttached() => SDL_JoystickConnected()
  • SDL_JoystickGetAxis() => SDL_GetJoystickAxis()
  • SDL_JoystickGetAxisInitialState() => SDL_GetJoystickAxisInitialState()
  • SDL_JoystickGetBall() => SDL_GetJoystickBall(), returns bool
  • SDL_JoystickGetButton() => SDL_GetJoystickButton()
  • SDL_JoystickGetFirmwareVersion() => SDL_GetJoystickFirmwareVersion()
  • SDL_JoystickGetGUID() => SDL_GetJoystickGUID()
  • SDL_JoystickGetGUIDFromString() => SDL_StringToGUID()
  • SDL_JoystickGetHat() => SDL_GetJoystickHat()
  • SDL_JoystickGetPlayerIndex() => SDL_GetJoystickPlayerIndex()
  • SDL_JoystickGetProduct() => SDL_GetJoystickProduct()
  • SDL_JoystickGetProductVersion() => SDL_GetJoystickProductVersion()
  • SDL_JoystickGetSerial() => SDL_GetJoystickSerial()
  • SDL_JoystickGetType() => SDL_GetJoystickType()
  • SDL_JoystickGetVendor() => SDL_GetJoystickVendor()
  • SDL_JoystickInstanceID() => SDL_GetJoystickID()
  • SDL_JoystickIsVirtual() => SDL_IsJoystickVirtual()
  • SDL_JoystickName() => SDL_GetJoystickName()
  • SDL_JoystickNumAxes() => SDL_GetNumJoystickAxes()
  • SDL_JoystickNumBalls() => SDL_GetNumJoystickBalls()
  • SDL_JoystickNumButtons() => SDL_GetNumJoystickButtons()
  • SDL_JoystickNumHats() => SDL_GetNumJoystickHats()
  • SDL_JoystickOpen() => SDL_OpenJoystick()
  • SDL_JoystickPath() => SDL_GetJoystickPath()
  • SDL_JoystickRumble() => SDL_RumbleJoystick(), returns bool
  • SDL_JoystickRumbleTriggers() => SDL_RumbleJoystickTriggers(), returns bool
  • SDL_JoystickSendEffect() => SDL_SendJoystickEffect(), returns bool
  • SDL_JoystickSetLED() => SDL_SetJoystickLED(), returns bool
  • SDL_JoystickSetPlayerIndex() => SDL_SetJoystickPlayerIndex(), returns bool
  • SDL_JoystickSetVirtualAxis() => SDL_SetJoystickVirtualAxis(), returns bool
  • SDL_JoystickSetVirtualButton() => SDL_SetJoystickVirtualButton(), returns bool
  • SDL_JoystickSetVirtualHat() => SDL_SetJoystickVirtualHat(), returns bool
  • SDL_JoystickUpdate() => SDL_UpdateJoysticks()

The following symbols have been renamed:

  • SDL_JOYSTICK_TYPE_GAMECONTROLLER => SDL_JOYSTICK_TYPE_GAMEPAD

The following functions have been removed:

  • SDL_JoystickAttachVirtual() - replaced with SDL_AttachVirtualJoystick()
  • SDL_JoystickCurrentPowerLevel() - replaced with SDL_GetJoystickConnectionState() and SDL_GetJoystickPowerInfo()
  • SDL_JoystickEventState() - replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled()
  • SDL_JoystickGetDeviceGUID() - replaced with SDL_GetJoystickGUIDForID()
  • SDL_JoystickGetDeviceInstanceID()
  • SDL_JoystickGetDevicePlayerIndex() - replaced with SDL_GetJoystickPlayerIndexForID()
  • SDL_JoystickGetDeviceProduct() - replaced with SDL_GetJoystickProductForID()
  • SDL_JoystickGetDeviceProductVersion() - replaced with SDL_GetJoystickProductVersionForID()
  • SDL_JoystickGetDeviceType() - replaced with SDL_GetJoystickTypeForID()
  • SDL_JoystickGetDeviceVendor() - replaced with SDL_GetJoystickVendorForID()
  • SDL_JoystickGetGUIDString() - replaced with SDL_GUIDToString()
  • SDL_JoystickHasLED() - replaced with SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN
  • SDL_JoystickHasRumble() - replaced with SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN
  • SDL_JoystickHasRumbleTriggers() - replaced with SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN
  • SDL_JoystickNameForIndex() - replaced with SDL_GetJoystickNameForID()
  • SDL_JoystickPathForIndex() - replaced with SDL_GetJoystickPathForID()
  • SDL_NumJoysticks() - replaced with SDL_GetJoysticks()
  • SDL_VIRTUAL_JOYSTICK_DESC_VERSION - no longer needed

The following symbols have been removed:

  • SDL_IPHONE_MAX_GFORCE
  • SDL_JOYBALLMOTION

The following structures have been renamed:

  • SDL_JoystickGUID => SDL_GUID

SDL_keyboard.h

Text input is no longer automatically enabled when initializing video, you should call SDL_StartTextInput() when you want to receive text input and call SDL_StopTextInput() when you are done. Starting text input may shown an input method editor (IME) and cause key up/down events to be skipped, so should only be enabled when the application wants text input.

The text input state hase been changed to be window-specific. SDL_StartTextInput(), SDL_StopTextInput(), SDL_TextInputActive(), and SDL_ClearComposition() all now take a window parameter.

SDL_GetDefaultKeyFromScancode(), SDL_GetKeyFromScancode(), and SDL_GetScancodeFromKey() take an SDL_Keymod parameter and use that to provide the correct result based on keyboard modifier state.

SDL_GetKeyboardState() returns a pointer to bool instead of Uint8.

The following functions have been renamed:

  • SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown()
  • SDL_IsTextInputActive() => SDL_TextInputActive()

The following functions have been removed:

  • SDL_IsTextInputShown()
  • SDL_SetTextInputRect() - replaced with SDL_SetTextInputArea()

The following structures have been removed:

  • SDL_Keysym

SDL_keycode.h

SDL_Keycode is now Uint32 and the SDLK_* constants are now defines instead of an enum, to more clearly reflect that they are a subset of the possible values of an SDL_Keycode.

In addition to the SDLK_SCANCODE_MASK bit found on key codes that directly map to scancodes, there is now the SDLK_EXTENDED_MASK bit used to denote key codes that don't have a corresponding scancode, and aren't a unicode value.

The following symbols have been removed:

  • KMOD_RESERVED - No replacement. A bit named "RESERVED" probably shouldn't be used in an app, but if you need it, this was equivalent to KMOD_SCROLL (0x8000) in SDL2.
  • SDLK_WWW
  • SDLK_MAIL
  • SDLK_CALCULATOR
  • SDLK_COMPUTER
  • SDLK_BRIGHTNESSDOWN
  • SDLK_BRIGHTNESSUP
  • SDLK_DISPLAYSWITCH
  • SDLK_KBDILLUMTOGGLE
  • SDLK_KBDILLUMDOWN
  • SDLK_KBDILLUMUP
  • SDLK_APP1
  • SDLK_APP2

The following symbols have been renamed:

  • KMOD_ALT => SDL_KMOD_ALT
  • KMOD_CAPS => SDL_KMOD_CAPS
  • KMOD_CTRL => SDL_KMOD_CTRL
  • KMOD_GUI => SDL_KMOD_GUI
  • KMOD_LALT => SDL_KMOD_LALT
  • KMOD_LCTRL => SDL_KMOD_LCTRL
  • KMOD_LGUI => SDL_KMOD_LGUI
  • KMOD_LSHIFT => SDL_KMOD_LSHIFT
  • KMOD_MODE => SDL_KMOD_MODE
  • KMOD_NONE => SDL_KMOD_NONE
  • KMOD_NUM => SDL_KMOD_NUM
  • KMOD_RALT => SDL_KMOD_RALT
  • KMOD_RCTRL => SDL_KMOD_RCTRL
  • KMOD_RGUI => SDL_KMOD_RGUI
  • KMOD_RSHIFT => SDL_KMOD_RSHIFT
  • KMOD_SCROLL => SDL_KMOD_SCROLL
  • KMOD_SHIFT => SDL_KMOD_SHIFT
  • SDLK_AUDIOFASTFORWARD => SDLK_MEDIA_FAST_FORWARD
  • SDLK_AUDIOMUTE => SDLK_MUTE
  • SDLK_AUDIONEXT => SDLK_MEDIA_NEXT_TRACK
  • SDLK_AUDIOPLAY => SDLK_MEDIA_PLAY
  • SDLK_AUDIOPREV => SDLK_MEDIA_PREVIOUS_TRACK
  • SDLK_AUDIOREWIND => SDLK_MEDIA_REWIND
  • SDLK_AUDIOSTOP => SDLK_MEDIA_STOP
  • SDLK_BACKQUOTE => SDLK_GRAVE
  • SDLK_EJECT => SDLK_MEDIA_EJECT
  • SDLK_MEDIASELECT => SDLK_MEDIA_SELECT
  • SDLK_QUOTE => SDLK_APOSTROPHE
  • SDLK_QUOTEDBL => SDLK_DBLAPOSTROPHE
  • SDLK_a => SDLK_A
  • SDLK_b => SDLK_B
  • SDLK_c => SDLK_C
  • SDLK_d => SDLK_D
  • SDLK_e => SDLK_E
  • SDLK_f => SDLK_F
  • SDLK_g => SDLK_G
  • SDLK_h => SDLK_H
  • SDLK_i => SDLK_I
  • SDLK_j => SDLK_J
  • SDLK_k => SDLK_K
  • SDLK_l => SDLK_L
  • SDLK_m => SDLK_M
  • SDLK_n => SDLK_N
  • SDLK_o => SDLK_O
  • SDLK_p => SDLK_P
  • SDLK_q => SDLK_Q
  • SDLK_r => SDLK_R
  • SDLK_s => SDLK_S
  • SDLK_t => SDLK_T
  • SDLK_u => SDLK_U
  • SDLK_v => SDLK_V
  • SDLK_w => SDLK_W
  • SDLK_x => SDLK_X
  • SDLK_y => SDLK_Y
  • SDLK_z => SDLK_Z

SDL_loadso.h

Shared object handles are now SDL_SharedObject *, an opaque type, instead of void *. This is just for type-safety and there is no functional difference.

SDL_LoadFunction() now returns SDL_FunctionPointer instead of void *, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.

SDL_log.h

SDL_Log() no longer prints a log prefix by default for SDL_LOG_PRIORITY_INFO and below. The log prefixes can be customized with SDL_SetLogPriorityPrefix().

The following macros have been removed:

  • SDL_MAX_LOG_MESSAGE - there's no message length limit anymore. If you need an artificial limit, this used to be 4096 in SDL versions before 2.0.24.

The following functions have been renamed:

  • SDL_LogGetOutputFunction() => SDL_GetLogOutputFunction()
  • SDL_LogGetPriority() => SDL_GetLogPriority()
  • SDL_LogResetPriorities() => SDL_ResetLogPriorities()
  • SDL_LogSetAllPriority() => SDL_SetLogPriorities()
  • SDL_LogSetOutputFunction() => SDL_SetLogOutputFunction()
  • SDL_LogSetPriority() => SDL_SetLogPriority()

The following symbols have been renamed:

  • SDL_NUM_LOG_PRIORITIES => SDL_LOG_PRIORITY_COUNT

SDL_main.h

SDL3 doesn't have a static libSDLmain to link against anymore. Instead SDL_main.h is now a header-only library and not included by SDL.h anymore.

Using it is really simple: Just #include <SDL3/SDL_main.h> in the source file with your standard int main(int argc, char* argv[]) function. See docs/README-main-functions.md for details.

Several platform-specific entry point functions have been removed as unnecessary. If for some reason you explicitly need them, here are easy replacements:

#define SDL_UIKitRunApp(ARGC, ARGV, MAIN_FUNC)  SDL_RunApp(ARGC, ARGV, MAIN_FUNC, NULL)
#define SDL_GDKRunApp(MAIN_FUNC, RESERVED)  SDL_RunApp(0, NULL, MAIN_FUNC, RESERVED)

The following functions have been removed:

  • SDL_WinRTRunApp() - WinRT support was removed in SDL3.

SDL_messagebox.h

The buttonid field of SDL_MessageBoxButtonData has been renamed buttonID.

The following symbols have been renamed:

  • SDL_MESSAGEBOX_COLOR_MAX => SDL_MESSAGEBOX_COLOR_COUNT

SDL_metal.h

SDL_Metal_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place.

SDL_mouse.h

SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()

SDL_GetMouseState(), SDL_GetGlobalMouseState(), SDL_GetRelativeMouseState(), SDL_WarpMouseInWindow(), and SDL_WarpMouseGlobal() all use floating point mouse positions, to provide sub-pixel precision on platforms that support it.

SDL_SystemCursor's items from SDL2 have been renamed to match CSS cursor names.

The following functions have been renamed:

  • SDL_FreeCursor() => SDL_DestroyCursor()

The following functions have been removed:

  • SDL_SetRelativeMouseMode() - replaced with SDL_SetWindowRelativeMouseMode()
  • SDL_GetRelativeMouseMode() - replaced with SDL_GetWindowRelativeMouseMode()

The following symbols have been renamed:

  • SDL_BUTTON => SDL_BUTTON_MASK
  • SDL_NUM_SYSTEM_CURSORS => SDL_SYSTEM_CURSOR_COUNT
  • SDL_SYSTEM_CURSOR_ARROW => SDL_SYSTEM_CURSOR_DEFAULT
  • SDL_SYSTEM_CURSOR_HAND => SDL_SYSTEM_CURSOR_POINTER
  • SDL_SYSTEM_CURSOR_IBEAM => SDL_SYSTEM_CURSOR_TEXT
  • SDL_SYSTEM_CURSOR_NO => SDL_SYSTEM_CURSOR_NOT_ALLOWED
  • SDL_SYSTEM_CURSOR_SIZEALL => SDL_SYSTEM_CURSOR_MOVE
  • SDL_SYSTEM_CURSOR_SIZENESW => SDL_SYSTEM_CURSOR_NESW_RESIZE
  • SDL_SYSTEM_CURSOR_SIZENS => SDL_SYSTEM_CURSOR_NS_RESIZE
  • SDL_SYSTEM_CURSOR_SIZENWSE => SDL_SYSTEM_CURSOR_NWSE_RESIZE
  • SDL_SYSTEM_CURSOR_SIZEWE => SDL_SYSTEM_CURSOR_EW_RESIZE
  • SDL_SYSTEM_CURSOR_WAITARROW => SDL_SYSTEM_CURSOR_PROGRESS

SDL_mutex.h

SDL_MUTEX_MAXWAIT has been removed; it suggested there was a maximum timeout one could outlive, instead of an infinite wait. Instead, pass a -1 to functions that accepted this symbol.

SDL_MUTEX_TIMEDOUT has been removed, the wait functions return true if the operation succeeded or false if they timed out.

SDL_LockMutex(), SDL_UnlockMutex(), SDL_WaitSemaphore(), SDL_SignalSemaphore(), SDL_WaitCondition(), SDL_SignalCondition(), and SDL_BroadcastCondition() now return void; if the object is valid (including being a NULL pointer, which returns immediately), these functions never fail. If the object is invalid or the caller does something illegal, like unlock another thread's mutex, this is considered undefined behavior.

SDL_TryWaitSemaphore(), SDL_WaitSemaphoreTimeout(), and SDL_WaitConditionTimeout() now return true if the operation succeeded or false if they timed out.

The following functions have been renamed:

  • SDL_CondBroadcast() => SDL_BroadcastCondition()
  • SDL_CondSignal() => SDL_SignalCondition()
  • SDL_CondWait() => SDL_WaitCondition()
  • SDL_CondWaitTimeout() => SDL_WaitConditionTimeout(), returns bool
  • SDL_CreateCond() => SDL_CreateCondition()
  • SDL_DestroyCond() => SDL_DestroyCondition()
  • SDL_SemPost() => SDL_SignalSemaphore()
  • SDL_SemTryWait() => SDL_TryWaitSemaphore(), returns bool
  • SDL_SemValue() => SDL_GetSemaphoreValue()
  • SDL_SemWait() => SDL_WaitSemaphore()
  • SDL_SemWaitTimeout() => SDL_WaitSemaphoreTimeout(), returns bool

The following symbols have been renamed:

  • SDL_cond => SDL_Condition
  • SDL_mutex => SDL_Mutex
  • SDL_sem => SDL_Semaphore

SDL_pixels.h

SDL_PixelFormat has been renamed SDL_PixelFormatDetails and just describes the pixel format, it does not include a palette for indexed pixel types.

SDL_PixelFormatEnum has been renamed SDL_PixelFormat and is used instead of Uint32 for API functions that refer to pixel format by enumerated value.

SDL_MapRGB(), SDL_MapRGBA(), SDL_GetRGB(), and SDL_GetRGBA() take an optional palette parameter for indexed color lookups.

Code that used to look like this:

    SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);

should be changed to:

    SDL_GetRGBA(pixel, SDL_GetPixelFormatDetails(surface->format), SDL_GetSurfacePalette(surface), &r, &g, &b, &a);

Code that used to look like this:

    pixel = SDL_MapRGBA(surface->format, r, g, b, a);

should be changed to:

    pixel = SDL_MapSurfaceRGBA(surface, r, g, b, a);

SDL_CalculateGammaRamp has been removed, because SDL_SetWindowGammaRamp has been removed as well due to poor support in modern operating systems (see SDL_video.h).

The following functions have been renamed:

  • SDL_AllocFormat() => SDL_GetPixelFormatDetails()
  • SDL_AllocPalette() => SDL_CreatePalette()
  • SDL_FreePalette() => SDL_DestroyPalette()
  • SDL_MasksToPixelFormatEnum() => SDL_GetPixelFormatForMasks()
  • SDL_PixelFormatEnumToMasks() => SDL_GetMasksForPixelFormat(), returns bool

The following symbols have been renamed:

  • SDL_PIXELFORMAT_BGR444 => SDL_PIXELFORMAT_XBGR4444
  • SDL_PIXELFORMAT_BGR555 => SDL_PIXELFORMAT_XBGR1555
  • SDL_PIXELFORMAT_BGR888 => SDL_PIXELFORMAT_XBGR8888
  • SDL_PIXELFORMAT_RGB444 => SDL_PIXELFORMAT_XRGB4444
  • SDL_PIXELFORMAT_RGB555 => SDL_PIXELFORMAT_XRGB1555
  • SDL_PIXELFORMAT_RGB888 => SDL_PIXELFORMAT_XRGB8888

The following functions have been removed:

  • SDL_FreeFormat()
  • SDL_SetPixelFormatPalette()
  • SDL_CalculateGammaRamp()

The following macros have been removed:

  • SDL_Colour - use SDL_Color instead

The following structures have been renamed:

  • SDL_PixelFormat => SDL_PixelFormatDetails

SDL_platform.h

The following platform preprocessor macros have been renamed:

SDL2 SDL3
__3DS__ SDL_PLATFORM_3DS
__AIX__ SDL_PLATFORM_AIX
__ANDROID__ SDL_PLATFORM_ANDROID
__APPLE__ SDL_PLATFORM_APPLE
__BSDI__ SDL_PLATFORM_BSDI
__CYGWIN_ SDL_PLATFORM_CYGWIN
__EMSCRIPTEN__ SDL_PLATFORM_EMSCRIPTEN
__FREEBSD__ SDL_PLATFORM_FREEBSD
__GDK__ SDL_PLATFORM_GDK
__HAIKU__ SDL_PLATFORM_HAIKU
__HPUX__ SDL_PLATFORM_HPUX
__IPHONEOS__ SDL_PLATFORM_IOS
__IRIX__ SDL_PLATFORM_IRIX
__LINUX__ SDL_PLATFORM_LINUX
__MACOSX__ SDL_PLATFORM_MACOS
__NETBSD__ SDL_PLATFORM_NETBSD
__OPENBSD__ SDL_PLATFORM_OPENBSD
__OS2__ SDL_PLATFORM_OS2
__OSF__ SDL_PLATFORM_OSF
__PS2__ SDL_PLATFORM_PS2
__PSP__ SDL_PLATFORM_PSP
__QNXNTO__ SDL_PLATFORM_QNXNTO
__RISCOS__ SDL_PLATFORM_RISCOS
__SOLARIS__ SDL_PLATFORM_SOLARIS
__TVOS__ SDL_PLATFORM_TVOS
__unix__ SDL_PLATFORM_UNI
__VITA__ SDL_PLATFORM_VITA
__WIN32__ SDL_PLATFORM_WIN32
__WINGDK__ SDL_PLATFORM_WINGDK
__XBOXONE__ SDL_PLATFORM_XBOXONE
__XBOXSERIES__ SDL_PLATFORM_XBOXSERIES

You can use the Python script rename_macros.py to automatically rename these in your source code.

A new macro SDL_PLATFORM_WINDOWS has been added that is true for all Windows platforms, including Xbox, GDK, etc.

The following platform preprocessor macros have been removed:

  • __DREAMCAST__
  • __NACL__
  • __PNACL__
  • __WINDOWS__
  • __WINRT__

SDL_quit.h

SDL_quit.h has been completely removed. It only had one symbol in it--SDL_QuitRequested--and if you want it, you can just add this to your app...

#define SDL_QuitRequested() (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_EVENT_QUIT,SDL_EVENT_QUIT) > 0))

...but this macro is sort of messy, calling two functions in sequence in an expression.

The following macros have been removed:

  • SDL_QuitRequested - call SDL_PumpEvents() then SDL_PeepEvents() directly, instead.

SDL_rect.h

The following functions have been renamed:

  • SDL_EncloseFPoints() => SDL_GetRectEnclosingPointsFloat()
  • SDL_EnclosePoints() => SDL_GetRectEnclosingPoints()
  • SDL_FRectEmpty() => SDL_RectEmptyFloat()
  • SDL_FRectEquals() => SDL_RectsEqualFloat()
  • SDL_FRectEqualsEpsilon() => SDL_RectsEqualEpsilon()
  • SDL_HasIntersection() => SDL_HasRectIntersection()
  • SDL_HasIntersectionF() => SDL_HasRectIntersectionFloat()
  • SDL_IntersectFRect() => SDL_GetRectIntersectionFloat()
  • SDL_IntersectFRectAndLine() => SDL_GetRectAndLineIntersectionFloat()
  • SDL_IntersectRect() => SDL_GetRectIntersection()
  • SDL_IntersectRectAndLine() => SDL_GetRectAndLineIntersection()
  • SDL_PointInFRect() => SDL_PointInRectFloat()
  • SDL_RectEquals() => SDL_RectsEqual()
  • SDL_UnionFRect() => SDL_GetRectUnionFloat(), returns bool
  • SDL_UnionRect() => SDL_GetRectUnion(), returns bool

SDL_render.h

The 2D renderer API always uses batching in SDL3. There is no magic to turn it on and off; it doesn't matter if you select a specific renderer or try to use any hint. This means that all apps that use SDL3's 2D renderer and also want to call directly into the platform's lower-layer graphics API must call SDL_FlushRenderer() before doing so. This will make sure any pending rendering work from SDL is done before the app starts directly drawing.

SDL_GetRenderDriverInfo() has been removed, since most of the information it reported were estimates and could not be accurate before creating a renderer. Often times this function was used to figure out the index of a driver, so one would call it in a for-loop, looking for the driver named "opengl" or whatnot. SDL_GetRenderDriver() has been added for this functionality, which returns only the name of the driver.

SDL_CreateRenderer()'s second argument is no longer an integer index, but a const char * representing a renderer's name; if you were just using a for-loop to find which index is the "opengl" or whatnot driver, you can just pass that string directly here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL to decide for you.

SDL_CreateRenderer()'s flags parameter has been removed. See specific flags below for how to achieve the same functionality in SDL 3.0.

SDL_CreateWindowAndRenderer() now takes the window title as the first parameter.

SDL_GetRendererInfo() has been removed. The name of a renderer can be retrieved using SDL_GetRendererName(), and the other information is available as properties on the renderer.

Textures are created with SDL_SCALEMODE_LINEAR by default, and use SDL_BLENDMODE_BLEND by default if they are created with a format that has an alpha channel.

SDL_QueryTexture() has been removed. The properties of the texture can be queried using SDL_PROP_TEXTURE_FORMAT_NUMBER, SDL_PROP_TEXTURE_ACCESS_NUMBER, SDL_PROP_TEXTURE_WIDTH_NUMBER, and SDL_PROP_TEXTURE_HEIGHT_NUMBER. A function SDL_GetTextureSize() has been added to get the size of the texture as floating point values.

Mouse and touch events are no longer filtered to change their coordinates, instead you can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into the rendering viewport.

SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions.

The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active.

SDL_Vertex has been changed to use floating point colors, in the range of [0..1] for SDR content.

SDL_RenderReadPixels() returns a surface instead of filling in preallocated memory.

SDL_RenderSetLogicalSize() (now called SDL_SetRenderLogicalPresentation()) in SDL2 would modify the scaling and viewport state. In SDL3, logical presentation maintains its state separately, so the app can use its own viewport and scaling while also setting a logical size.

The following functions have been renamed:

  • SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize(), returns bool
  • SDL_RenderCopy() => SDL_RenderTexture(), returns bool
  • SDL_RenderCopyEx() => SDL_RenderTextureRotated(), returns bool
  • SDL_RenderCopyExF() => SDL_RenderTextureRotated(), returns bool
  • SDL_RenderCopyF() => SDL_RenderTexture(), returns bool
  • SDL_RenderDrawLine() => SDL_RenderLine(), returns bool
  • SDL_RenderDrawLineF() => SDL_RenderLine(), returns bool
  • SDL_RenderDrawLines() => SDL_RenderLines(), returns bool
  • SDL_RenderDrawLinesF() => SDL_RenderLines(), returns bool
  • SDL_RenderDrawPoint() => SDL_RenderPoint(), returns bool
  • SDL_RenderDrawPointF() => SDL_RenderPoint(), returns bool
  • SDL_RenderDrawPoints() => SDL_RenderPoints(), returns bool
  • SDL_RenderDrawPointsF() => SDL_RenderPoints(), returns bool
  • SDL_RenderDrawRect() => SDL_RenderRect(), returns bool
  • SDL_RenderDrawRectF() => SDL_RenderRect(), returns bool
  • SDL_RenderDrawRects() => SDL_RenderRects(), returns bool
  • SDL_RenderDrawRectsF() => SDL_RenderRects(), returns bool
  • SDL_RenderFillRectF() => SDL_RenderFillRect(), returns bool
  • SDL_RenderFillRectsF() => SDL_RenderFillRects(), returns bool
  • SDL_RenderFlush() => SDL_FlushRenderer(), returns bool
  • SDL_RenderGetClipRect() => SDL_GetRenderClipRect(), returns bool
  • SDL_RenderGetIntegerScale() => SDL_GetRenderIntegerScale()
  • SDL_RenderGetLogicalSize() => SDL_GetRenderLogicalPresentation(), returns bool
  • SDL_RenderGetMetalCommandEncoder() => SDL_GetRenderMetalCommandEncoder()
  • SDL_RenderGetMetalLayer() => SDL_GetRenderMetalLayer()
  • SDL_RenderGetScale() => SDL_GetRenderScale(), returns bool
  • SDL_RenderGetViewport() => SDL_GetRenderViewport(), returns bool
  • SDL_RenderGetWindow() => SDL_GetRenderWindow()
  • SDL_RenderIsClipEnabled() => SDL_RenderClipEnabled()
  • SDL_RenderLogicalToWindow() => SDL_RenderCoordinatesToWindow(), returns bool
  • SDL_RenderSetClipRect() => SDL_SetRenderClipRect(), returns bool
  • SDL_RenderSetLogicalSize() => SDL_SetRenderLogicalPresentation(), returns bool
  • SDL_RenderSetScale() => SDL_SetRenderScale(), returns bool
  • SDL_RenderSetVSync() => SDL_SetRenderVSync(), returns bool
  • SDL_RenderSetViewport() => SDL_SetRenderViewport(), returns bool
  • SDL_RenderWindowToLogical() => SDL_RenderCoordinatesFromWindow(), returns bool

The following functions have been removed:

  • SDL_GL_BindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and bind the texture directly
  • SDL_GL_UnbindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and unbind the texture directly
  • SDL_GetTextureUserData() - use SDL_GetTextureProperties() instead
  • SDL_RenderGetIntegerScale()
  • SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE
  • SDL_RenderTargetSupported() - render targets are always supported
  • SDL_SetTextureUserData() - use SDL_GetTextureProperties() instead

The following enums have been renamed:

  • SDL_RendererFlip => SDL_FlipMode - moved to SDL_surface.h

The following symbols have been renamed:

  • SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR
  • SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST

The following symbols have been removed:

  • SDL_RENDERER_ACCELERATED - all renderers except SDL_SOFTWARE_RENDERER are accelerated
  • SDL_RENDERER_PRESENTVSYNC - replaced with SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER during renderer creation and SDL_PROP_RENDERER_VSYNC_NUMBER after renderer creation
  • SDL_RENDERER_SOFTWARE - you can check whether the name of the renderer is SDL_SOFTWARE_RENDERER
  • SDL_RENDERER_TARGETTEXTURE - all renderers support target texture functionality
  • SDL_ScaleModeBest - use SDL_SCALEMODE_LINEAR instead

SDL_rwops.h

The following symbols have been renamed:

  • RW_SEEK_CUR => SDL_IO_SEEK_CUR
  • RW_SEEK_END => SDL_IO_SEEK_END
  • RW_SEEK_SET => SDL_IO_SEEK_SET

SDL_rwops.h is now named SDL_iostream.h

SDL_RWops is now an opaque structure, and has been renamed to SDL_IOStream. The SDL3 APIs to create an SDL_IOStream (SDL_IOFromFile, etc) are renamed but otherwise still function as they did in SDL2. However, to make a custom SDL_IOStream with app-provided function pointers, call SDL_OpenIO and provide the function pointers through there. To call into an SDL_IOStream's functionality, use the standard APIs (SDL_ReadIO, etc), as the function pointers are internal.

SDL_IOStream is not to be confused with the unrelated standard C++ iostream class!

The RWops function pointers are now in a separate structure called SDL_IOStreamInterface, which is provided to SDL_OpenIO when creating a custom SDL_IOStream implementation. All the functions now take a void * userdata argument for their first parameter instead of an SDL_IOStream, since that's now an opaque structure.

SDL_RWread and SDL_RWwrite (and the read and write function pointers) have a different function signature in SDL3, in addition to being renamed.

Previously they looked more like stdio:

size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum);
size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum);

But now they look more like POSIX:

size_t SDL_ReadIO(SDL_IOStream *context, void *ptr, size_t size);
size_t SDL_WriteIO(SDL_IOStream *context, const void *ptr, size_t size);

Code that used to look like this:

size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
{
    return SDL_RWread(stream, ptr, size, nitems);
}

should be changed to:

size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_IOStream *stream)
{
    if (size > 0 && nitems > 0) {
        return SDL_ReadIO(stream, ptr, size * nitems) / size;
    }
    return 0;
}

SDL_RWops::type was removed; it wasn't meaningful for app-provided implementations at all, and wasn't much use for SDL's internal implementations, either. If you have to identify the type, you can examine the SDL_IOStream's properties to detect built-in implementations.

SDL_IOStreamInterface::close implementations should clean up their own userdata, but not call SDL_CloseIO on themselves; now the contract is always that SDL_CloseIO is called, which calls ->close before freeing the opaque object.

SDL_AllocRW(), SDL_FreeRW(), SDL_RWclose() and direct access to the ->close function pointer have been removed from the API, so there's only one path to manage RWops lifetimes now: SDL_OpenIO() and SDL_CloseIO().

SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application.

You can implement this in your own code easily:

#include <stdio.h>

typedef struct IOStreamStdioFPData
{
    FILE *fp;
    bool autoclose;
} IOStreamStdioFPData;

static Sint64 SDLCALL stdio_seek(void *userdata, Sint64 offset, int whence)
{
    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    int stdiowhence;

    switch (whence) {
    case SDL_IO_SEEK_SET:
        stdiowhence = SEEK_SET;
        break;
    case SDL_IO_SEEK_CUR:
        stdiowhence = SEEK_CUR;
        break;
    case SDL_IO_SEEK_END:
        stdiowhence = SEEK_END;
        break;
    default:
        SDL_SetError("Unknown value for 'whence'");
        return -1;
    }

    if (fseek(fp, (fseek_off_t)offset, stdiowhence) == 0) {
        const Sint64 pos = ftell(fp);
        if (pos < 0) {
            SDL_SetError("Couldn't get stream offset");
            return -1;
        }
        return pos;
    }
    SDL_SetError("Couldn't seek in stream");
    return -1;
}

static size_t SDLCALL stdio_read(void *userdata, void *ptr, size_t size, SDL_IOStatus *status)
{
    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    const size_t bytes = fread(ptr, 1, size, fp);
    if (bytes == 0 && ferror(fp)) {
        SDL_SetError("Couldn't read stream");
    }
    return bytes;
}

static size_t SDLCALL stdio_write(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status)
{
    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    const size_t bytes = fwrite(ptr, 1, size, fp);
    if (bytes == 0 && ferror(fp)) {
        SDL_SetError("Couldn't write stream");
    }
    return bytes;
}

static bool SDLCALL stdio_close(void *userdata)
{
    IOStreamStdioData *rwopsdata = (IOStreamStdioData *) userdata;
    bool status = true;
    if (rwopsdata->autoclose) {
        if (fclose(rwopsdata->fp) != 0) {
            SDL_SetError("Couldn't close stream");
            status = false;
        }
    }
    return status;
}

SDL_IOStream *SDL_RWFromFP(FILE *fp, bool autoclose)
{
    SDL_IOStreamInterface iface;
    IOStreamStdioFPData *rwopsdata;
    SDL_IOStream *rwops;

    rwopsdata = (IOStreamStdioFPData *) SDL_malloc(sizeof (*rwopsdata));
    if (!rwopsdata) {
        return NULL;
    }

    SDL_INIT_INTERFACE(&iface);
    /* There's no stdio_size because SDL_GetIOSize emulates it the same way we'd do it for stdio anyhow. */
    iface.seek = stdio_seek;
    iface.read = stdio_read;
    iface.write = stdio_write;
    iface.close = stdio_close;

    rwopsdata->fp = fp;
    rwopsdata->autoclose = autoclose;

    rwops = SDL_OpenIO(&iface, rwopsdata);
    if (!rwops) {
        iface.close(rwopsdata);
    }
    return rwops;
}

The internal FILE * is available through a standard SDL_IOStream property, for streams made through SDL_IOFromFile() that use stdio behind the scenes; apps use this pointer at their own risk and should make sure that SDL and the app are using the same C runtime.

On Apple platforms, SDL_RWFromFile (now called SDL_IOFromFile) no longer tries to read from inside the app bundle's resource directory, instead now using the specified path unchanged. One can use SDL_GetBasePath() to find the resource directory on these platforms.

The functions SDL_ReadU8(), SDL_ReadU16LE(), SDL_ReadU16BE(), SDL_ReadU32LE(), SDL_ReadU32BE(), SDL_ReadU64LE(), and SDL_ReadU64BE() now return true if the read succeeded and false if it didn't, and store the data in a pointer passed in as a parameter.

The following functions have been renamed:

  • SDL_RWFromConstMem() => SDL_IOFromConstMem()
  • SDL_RWFromFile() => SDL_IOFromFile()
  • SDL_RWFromMem() => SDL_IOFromMem()
  • SDL_RWclose() => SDL_CloseIO(), returns bool
  • SDL_RWread() => SDL_ReadIO()
  • SDL_RWseek() => SDL_SeekIO()
  • SDL_RWsize() => SDL_GetIOSize()
  • SDL_RWtell() => SDL_TellIO()
  • SDL_RWwrite() => SDL_WriteIO()
  • SDL_ReadBE16() => SDL_ReadU16BE()
  • SDL_ReadBE32() => SDL_ReadU32BE()
  • SDL_ReadBE64() => SDL_ReadU64BE()
  • SDL_ReadLE16() => SDL_ReadU16LE()
  • SDL_ReadLE32() => SDL_ReadU32LE()
  • SDL_ReadLE64() => SDL_ReadU64LE()
  • SDL_WriteBE16() => SDL_WriteU16BE()
  • SDL_WriteBE32() => SDL_WriteU32BE()
  • SDL_WriteBE64() => SDL_WriteU64BE()
  • SDL_WriteLE16() => SDL_WriteU16LE()
  • SDL_WriteLE32() => SDL_WriteU32LE()
  • SDL_WriteLE64() => SDL_WriteU64LE()

The following structures have been renamed:

  • SDL_RWops => SDL_IOStream

SDL_scancode.h

The following symbols have been removed:

  • SDL_SCANCODE_WWW
  • SDL_SCANCODE_MAIL
  • SDL_SCANCODE_CALCULATOR
  • SDL_SCANCODE_COMPUTER
  • SDL_SCANCODE_BRIGHTNESSDOWN
  • SDL_SCANCODE_BRIGHTNESSUP
  • SDL_SCANCODE_DISPLAYSWITCH
  • SDL_SCANCODE_KBDILLUMTOGGLE
  • SDL_SCANCODE_KBDILLUMDOWN
  • SDL_SCANCODE_KBDILLUMUP
  • SDL_SCANCODE_APP1
  • SDL_SCANCODE_APP2

The following symbols have been renamed:

  • SDL_NUM_SCANCODES => SDL_SCANCODE_COUNT
  • SDL_SCANCODE_AUDIOFASTFORWARD => SDL_SCANCODE_MEDIA_FAST_FORWARD
  • SDL_SCANCODE_AUDIOMUTE => SDL_SCANCODE_MUTE
  • SDL_SCANCODE_AUDIONEXT => SDL_SCANCODE_MEDIA_NEXT_TRACK
  • SDL_SCANCODE_AUDIOPLAY => SDL_SCANCODE_MEDIA_PLAY
  • SDL_SCANCODE_AUDIOPREV => SDL_SCANCODE_MEDIA_PREVIOUS_TRACK
  • SDL_SCANCODE_AUDIOREWIND => SDL_SCANCODE_MEDIA_REWIND
  • SDL_SCANCODE_AUDIOSTOP => SDL_SCANCODE_MEDIA_STOP
  • SDL_SCANCODE_EJECT => SDL_SCANCODE_MEDIA_EJECT
  • SDL_SCANCODE_MEDIASELECT => SDL_SCANCODE_MEDIA_SELECT

SDL_sensor.h

SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0.

Rather than iterating over sensors using device index, there is a new function SDL_GetSensors() to get the current list of sensors, and new functions to get information about sensors from their instance ID:

{
    if (SDL_InitSubSystem(SDL_INIT_SENSOR)) {
        int i, num_sensors;
        SDL_SensorID *sensors = SDL_GetSensors(&num_sensors);
        if (sensors) {
            for (i = 0; i < num_sensors; ++i) {
                SDL_Log("Sensor %" SDL_PRIu32 ": %s, type %d, platform type %d",
                        sensors[i],
                        SDL_GetSensorNameForID(sensors[i]),
                        SDL_GetSensorTypeForID(sensors[i]),
                        SDL_GetSensorNonPortableTypeForID(sensors[i]));
            }
            SDL_free(sensors);
        }
        SDL_QuitSubSystem(SDL_INIT_SENSOR);
    }
}

Removed SDL_SensorGetDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_SENSOR_UPDATE events.

The following functions have been renamed:

  • SDL_SensorClose() => SDL_CloseSensor()
  • SDL_SensorFromInstanceID() => SDL_GetSensorFromID()
  • SDL_SensorGetData() => SDL_GetSensorData(), returns bool
  • SDL_SensorGetInstanceID() => SDL_GetSensorID()
  • SDL_SensorGetName() => SDL_GetSensorName()
  • SDL_SensorGetNonPortableType() => SDL_GetSensorNonPortableType()
  • SDL_SensorGetType() => SDL_GetSensorType()
  • SDL_SensorOpen() => SDL_OpenSensor()
  • SDL_SensorUpdate() => SDL_UpdateSensors()

The following functions have been removed:

  • SDL_LockSensors()
  • SDL_NumSensors() - replaced with SDL_GetSensors()
  • SDL_SensorGetDeviceInstanceID()
  • SDL_SensorGetDeviceName() - replaced with SDL_GetSensorNameForID()
  • SDL_SensorGetDeviceNonPortableType() - replaced with SDL_GetSensorNonPortableTypeForID()
  • SDL_SensorGetDeviceType() - replaced with SDL_GetSensorTypeForID()
  • SDL_UnlockSensors()

SDL_shape.h

This header has been removed and a simplified version of this API has been added as SDL_SetWindowShape() in SDL_video.h. See test/testshape.c for an example.

SDL_stdinc.h

The standard C headers like stdio.h and stdlib.h are no longer included, you should include them directly in your project if you use non-SDL C runtime functions. M_PI is no longer defined in SDL_stdinc.h, you can use the new symbols SDL_PI_D (double) and SDL_PI_F (float) instead.

bool is now defined as bool, and is 1 byte instead of the size of an int.

SDL3 attempts to apply consistency to case-insensitive string functions. In SDL2, things like SDL_strcasecmp() would usually only work on English letters, and depending on the user's locale, possibly not even those. In SDL3, consistency is applied:

  • Many things that don't care about case-insensitivity, like SDL_strcmp(), continue to work with any null-terminated string of bytes, even if it happens to be malformed UTF-8.
  • SDL_strcasecmp() expects valid UTF-8 strings, and will attempt to support most Unicode characters with a technique known as "case-folding," which is to say it can match 'A' and 'a', and also 'Η' and 'η', but ALSO 'ß' and "ss". This is probably how most apps assumed it worked in SDL2 and won't need any changes.
  • SDL_strncasecmp() works the same, but the third parameter takes bytes, as before, so SDL_strlen() can continue to be used with it. If a string hits the limit in the middle of a codepoint, the half-processed bytes of the codepoint will be treated as a collection of U+0xFFFD (REPLACEMENT CHARACTER) codepoints, which you probably don't want.
  • SDL_wcscasecmp() and SDL_wcsncasecmp() work the same way but operate on UTF-16 or UTF-32 encoded strings, depending on what the platform considers "wchar_t" to be. SDL_wcsncasecmp's third parameter is number of wchar_t values, not bytes, but UTF-16 has the same concerns as UTF-8 for variable-length codepoints.
  • SDL_strcasestr() expects valid UTF-8 strings, and will compare codepoints using case-folding.
  • SDL_tolower() and SDL_toupper() continue to only work on single bytes (even though the parameter is an int) and only converts low-ASCII English A through Z.
  • SDL_strlwr() and SDL_strupr() operates on individual bytes (not UTF-8 codepoints) and only change low-ASCII English 'A' through 'Z'. These functions do not check the string for valid UTF-8 encoding.
  • The ctype.h replacement SDL_is*() functions (SDL_isalpha, SDL_isdigit, etc) only work on low-ASCII characters and ignore user locale, assuming English. This makes these functions consistent in SDL3, but applications need to be careful to understand their limits.

Please note that the case-folding technique used by SDL3 will not produce correct results for the "Turkish 'I'"; this one letter is a surprisingly hard problem in the Unicode world, and since these functions do not specify the human language in use, we have chosen to ignore this problem.

SDL_strtoll(), SDL_strtoull(), SDL_lltoa(), and SDL_ulltoa() use long long values instead of 64-bit values, to match their C runtime counterparts.

SDL_setenv() is not thread-safe and has been renamed SDL_setenv_unsafe().

The following macros have been removed:

  • SDL_TABLESIZE() - use SDL_arraysize() instead

The following functions have been renamed:

  • SDL_size_add_overflow() => SDL_size_add_check_overflow(), returns bool
  • SDL_size_mul_overflow() => SDL_size_mul_check_overflow(), returns bool
  • SDL_strtokr() => SDL_strtok_r()

The following functions have been removed:

  • SDL_memcpy4()

The following symbols have been renamed:

  • SDL_FALSE => false
  • SDL_TRUE => true
  • SDL_bool => bool

SDL_surface.h

SDL_Surface has been simplified and internal details are no longer in the public structure.

The format member of SDL_Surface is now an enumerated pixel format value. You can get the full details of the pixel format by calling SDL_GetPixelFormatDetails(surface->format). You can get the palette associated with the surface by calling SDL_GetSurfacePalette(). You can get the clip rectangle by calling SDL_GetSurfaceClipRect().

The userdata member of SDL_Surface has been replaced with a more general properties interface, which can be queried with SDL_GetSurfaceProperties()

Indexed format surfaces no longer have a palette by default. Surfaces without a palette will copy the pixels untranslated between surfaces.

Code that used to look like this:

    SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 8, SDL_PIXELFORMAT_INDEX8);
    SDL_Palette *palette = surface->format->palette;
    ...

should be changed to:

    SDL_Surface *surface = SDL_CreateSurface(32, 32, SDL_PIXELFORMAT_INDEX8);
    SDL_Palette *palette = SDL_CreateSurfacePalette(surface);
    ...

Removed the unused 'flags' parameter from SDL_ConvertSurface.

SDL_CreateRGBSurface() and SDL_CreateRGBSurfaceWithFormat() have been combined into a new function SDL_CreateSurface(). SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() have been combined into a new function SDL_CreateSurfaceFrom(), and the parameter order has changed for consistency with SDL_CreateSurface().

You can implement the old functions in your own code easily:

SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    return SDL_CreateSurface(width, height,
            SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask));
}

SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
{
    return SDL_CreateSurface(width, height, format);
}

SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    return SDL_CreateSurfaceFrom(width, height,
                                 SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask),
                                 pixels, pitch);
}

SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
{
    return SDL_CreateSurfaceFrom(width, height, format, pixels, pitch);
}

But if you're migrating your code which uses masks, you probably have a format in mind, possibly one of these:

// Various mask (R, G, B, A) and their corresponding format:
0xFF000000 0x00FF0000 0x0000FF00 0x000000FF => SDL_PIXELFORMAT_RGBA8888
0x00FF0000 0x0000FF00 0x000000FF 0xFF000000 => SDL_PIXELFORMAT_ARGB8888
0x0000FF00 0x00FF0000 0xFF000000 0x000000FF => SDL_PIXELFORMAT_BGRA8888
0x000000FF 0x0000FF00 0x00FF0000 0xFF000000 => SDL_PIXELFORMAT_ABGR8888
0x0000F800 0x000007E0 0x0000001F 0x00000000 => SDL_PIXELFORMAT_RGB565

SDL_BlitSurface() and SDL_BlitSurfaceScaled() now have a const dstrect parameter and do not fill it in with the final destination rectangle.

SDL_BlitSurfaceScaled() and SDL_BlitSurfaceUncheckedScaled() now take a scale parameter.

SDL_PixelFormat is used instead of Uint32 for API functions that refer to pixel format by enumerated value.

SDL_SetSurfaceColorKey() takes an bool to enable and disable colorkey. RLE acceleration isn't controlled by the parameter, you should use SDL_SetSurfaceRLE() to change that separately.

SDL_SetSurfaceRLE() takes an bool to enable and disable RLE acceleration.

The following functions have been renamed:

  • SDL_BlitScaled() => SDL_BlitSurfaceScaled(), returns bool
  • SDL_ConvertSurfaceFormat() => SDL_ConvertSurface()
  • SDL_FillRect() => SDL_FillSurfaceRect(), returns bool
  • SDL_FillRects() => SDL_FillSurfaceRects(), returns bool
  • SDL_FreeSurface() => SDL_DestroySurface()
  • SDL_GetClipRect() => SDL_GetSurfaceClipRect(), returns bool
  • SDL_GetColorKey() => SDL_GetSurfaceColorKey(), returns bool
  • SDL_HasColorKey() => SDL_SurfaceHasColorKey()
  • SDL_HasSurfaceRLE() => SDL_SurfaceHasRLE()
  • SDL_LoadBMP_RW() => SDL_LoadBMP_IO()
  • SDL_LowerBlit() => SDL_BlitSurfaceUnchecked(), returns bool
  • SDL_LowerBlitScaled() => SDL_BlitSurfaceUncheckedScaled(), returns bool
  • SDL_SaveBMP_RW() => SDL_SaveBMP_IO(), returns bool
  • SDL_SetClipRect() => SDL_SetSurfaceClipRect()
  • SDL_SetColorKey() => SDL_SetSurfaceColorKey(), returns bool
  • SDL_UpperBlit() => SDL_BlitSurface(), returns bool
  • SDL_UpperBlitScaled() => SDL_BlitSurfaceScaled(), returns bool

The following symbols have been removed:

  • SDL_SWSURFACE

The following functions have been removed:

  • SDL_FreeFormat()
  • SDL_GetYUVConversionMode()
  • SDL_GetYUVConversionModeForResolution()
  • SDL_SetYUVConversionMode() - use SDL_SetSurfaceColorspace() to set the surface colorspace and SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER with SDL_CreateTextureWithProperties() to set the texture colorspace. The default colorspace for YUV pixel formats is SDL_COLORSPACE_JPEG.
  • SDL_SoftStretch() - use SDL_StretchSurface() with SDL_SCALEMODE_NEAREST
  • SDL_SoftStretchLinear() - use SDL_StretchSurface() with SDL_SCALEMODE_LINEAR

The following symbols have been renamed:

  • SDL_PREALLOC => SDL_SURFACE_PREALLOCATED
  • SDL_SIMD_ALIGNED => SDL_SURFACE_SIMD_ALIGNED

SDL_system.h

SDL_WindowsMessageHook has changed signatures so the message may be modified and it can block further message processing.

SDL_RequestAndroidPermission is no longer a blocking call; the caller now provides a callback function that fires when a response is available.

SDL_iPhoneSetAnimationCallback() and SDL_iPhoneSetEventPump() have been renamed to SDL_SetiOSAnimationCallback() and SDL_SetiOSEventPump(), respectively. SDL2 has had macros to provide this new name with the old symbol since the introduction of the iPad, but now the correctly-named symbol is the only option.

SDL_IsAndroidTV() has been renamed SDL_IsTV() and is no longer Android-specific; an app running on an Apple TV device will also return true, for example.

The following functions have been removed:

  • SDL_GetWinRTFSPathUNICODE() - WinRT support was removed in SDL3.
  • SDL_GetWinRTFSPathUTF8() - WinRT support was removed in SDL3.
  • SDL_RenderGetD3D11Device() - replaced with the "SDL.renderer.d3d11.device" property
  • SDL_RenderGetD3D12Device() - replaced with the "SDL.renderer.d3d12.device" property
  • SDL_RenderGetD3D9Device() - replaced with the "SDL.renderer.d3d9.device" property
  • SDL_WinRTGetDeviceFamily() - WinRT support was removed in SDL3.

The following functions have been renamed:

  • SDL_AndroidBackButton() => SDL_SendAndroidBackButton()
  • SDL_AndroidGetActivity() => SDL_GetAndroidActivity()
  • SDL_AndroidGetExternalStoragePath() => SDL_GetAndroidExternalStoragePath()
  • SDL_AndroidGetExternalStorageState() => SDL_GetAndroidExternalStorageState()
  • SDL_AndroidGetInternalStoragePath() => SDL_GetAndroidInternalStoragePath()
  • SDL_AndroidGetJNIEnv() => SDL_GetAndroidJNIEnv()
  • SDL_AndroidRequestPermission() => SDL_RequestAndroidPermission(), returns bool
  • SDL_AndroidRequestPermissionCallback() => SDL_RequestAndroidPermissionCallback()
  • SDL_AndroidSendMessage() => SDL_SendAndroidMessage(), returns bool
  • SDL_AndroidShowToast() => SDL_ShowAndroidToast(), returns bool
  • SDL_DXGIGetOutputInfo() => SDL_GetDXGIOutputInfo(), returns bool
  • SDL_Direct3D9GetAdapterIndex() => SDL_GetDirect3D9AdapterIndex()
  • SDL_GDKGetDefaultUser() => SDL_GetGDKDefaultUser(), returns bool
  • SDL_GDKGetTaskQueue() => SDL_GetGDKTaskQueue(), returns bool
  • SDL_IsAndroidTV() => SDL_IsTV()
  • SDL_LinuxSetThreadPriority() => SDL_SetLinuxThreadPriority(), returns bool
  • SDL_LinuxSetThreadPriorityAndPolicy() => SDL_SetLinuxThreadPriorityAndPolicy(), returns bool
  • SDL_OnApplicationDidBecomeActive() => SDL_OnApplicationDidEnterForeground()
  • SDL_OnApplicationWillResignActive() => SDL_OnApplicationWillEnterBackground()
  • SDL_iOSSetAnimationCallback() => SDL_SetiOSAnimationCallback(), returns bool
  • SDL_iOSSetEventPump() => SDL_SetiOSEventPump()
  • SDL_iPhoneSetAnimationCallback() => SDL_SetiOSAnimationCallback(), returns bool
  • SDL_iPhoneSetEventPump() => SDL_SetiOSEventPump()

SDL_syswm.h

This header has been removed.

The Windows and X11 events are now available via callbacks which you can set with SDL_SetWindowsMessageHook() and SDL_SetX11EventHook().

The information previously available in SDL_GetWindowWMInfo() is now available as window properties, e.g.

    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);

#if defined(__WIN32__)
    HWND hwnd = NULL;
    if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_WINDOWS) {
        hwnd = info.info.win.window;
    }
    if (hwnd) {
        ...
    }
#elif defined(__MACOSX__)
    NSWindow *nswindow = NULL;
    if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_COCOA) {
        nswindow = (__bridge NSWindow *)info.info.cocoa.window;
    }
    if (nswindow) {
        ...
    }
#elif defined(__LINUX__)
    if (SDL_GetWindowWMInfo(window, &info)) {
        if (info.subsystem == SDL_SYSWM_X11) {
            Display *xdisplay = info.info.x11.display;
            Window xwindow = info.info.x11.window;
            if (xdisplay && xwindow) {
                ...
            }
        } else if (info.subsystem == SDL_SYSWM_WAYLAND) {
            struct wl_display *display = info.info.wl.display;
            struct wl_surface *surface = info.info.wl.surface;
            if (display && surface) {
                ...
            }
        }
    }
#elif defined(__IPHONEOS__)
    UIWindow *uiwindow = NULL;
    if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_UIKIT) {
        uiwindow = (__bridge UIWindow *)info.info.uikit.window;
    }
    if (uiwindow) {
        GLuint framebuffer = info.info.uikit.framebuffer;
        GLuint colorbuffer = info.info.uikit.colorbuffer;
        GLuint resolveFramebuffer = info.info.uikit.resolveFramebuffer;
        ...
    }
#endif

becomes:

#if defined(SDL_PLATFORM_WIN32)
    HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
    if (hwnd) {
        ...
    }
#elif defined(SDL_PLATFORM_MACOS)
    NSWindow *nswindow = (__bridge NSWindow *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
    if (nswindow) {
        ...
    }
#elif defined(SDL_PLATFORM_LINUX)
    if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
        Display *xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
        Window xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
        if (xdisplay && xwindow) {
            ...
        }
    } else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
        struct wl_display *display = (struct wl_display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
        struct wl_surface *surface = (struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);
        if (display && surface) {
            ...
        }
    }
#elif defined(SDL_PLATFORM_IOS)
    SDL_PropertiesID props = SDL_GetWindowProperties(window);
    UIWindow *uiwindow = (__bridge UIWindow *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL);
    if (uiwindow) {
        GLuint framebuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_FRAMEBUFFER_NUMBER, 0);
        GLuint colorbuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RENDERBUFFER_NUMBER, 0);
        GLuint resolveFramebuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RESOLVE_FRAMEBUFFER_NUMBER, 0);
        ...
    }
#endif

SDL_thread.h

SDL_CreateThreadWithStackSize has been replaced with SDL_CreateThreadWithProperties.

SDL_CreateThread and SDL_CreateThreadWithProperties now take beginthread/endthread function pointers on all platforms (ignoring them on most), and have been replaced with macros that hide this detail on all platforms. This works the same as before at the source code level, but the actual function signature that is called in SDL has changed. The library's exported symbol is SDL_CreateThreadRuntime, and looking for "SDL_CreateThread" in the DLL/Shared Library/Dylib will fail. You should not call this directly, but instead always use the macro!

SDL_GetTLS() and SDL_SetTLS() take a pointer to a TLS ID, and will automatically initialize it in a thread-safe way as needed.

The following functions have been renamed:

  • SDL_SetThreadPriority() => SDL_SetCurrentThreadPriority()
  • SDL_TLSCleanup() => SDL_CleanupTLS()
  • SDL_TLSGet() => SDL_GetTLS()
  • SDL_TLSSet() => SDL_SetTLS(), returns bool
  • SDL_ThreadID() => SDL_GetCurrentThreadID()

The following functions have been removed:

  • SDL_TLSCreate() - TLS IDs are automatically allocated as needed.

The following symbols have been renamed:

  • SDL_threadID => SDL_ThreadID

SDL_timer.h

SDL_GetTicks() now returns a 64-bit value. Instead of using the SDL_TICKS_PASSED macro, you can directly compare tick values, e.g.

Uint32 deadline = SDL_GetTicks() + 1000;
...
if (SDL_TICKS_PASSED(SDL_GetTicks(), deadline)) {
    ...
}

becomes:

Uint64 deadline = SDL_GetTicks() + 1000
...
if (SDL_GetTicks() >= deadline) {
    ...
}

If you were using this macro for other things besides SDL ticks values, you can define it in your own code as:

#define SDL_TICKS_PASSED(A, B)  ((Sint32)((B) - (A)) <= 0)

The callback passed to SDL_AddTimer() has changed parameters to:

Uint32 SDLCALL TimerCallback(void *userdata, SDL_TimerID timerID, Uint32 interval);

SDL_touch.h

SDL_GetTouchName is replaced with SDL_GetTouchDeviceName(), which takes an SDL_TouchID instead of an index.

SDL_TouchID and SDL_FingerID are now Uint64 with 0 being an invalid value.

Rather than iterating over touch devices using an index, there is a new function SDL_GetTouchDevices() to get the available devices.

Rather than iterating over touch fingers using an index, there is a new function SDL_GetTouchFingers() to get the current set of active fingers.

The following functions have been removed:

  • SDL_GetNumTouchDevices() - replaced with SDL_GetTouchDevices()
  • SDL_GetNumTouchFingers() - replaced with SDL_GetTouchFingers()
  • SDL_GetTouchDevice() - replaced with SDL_GetTouchDevices()
  • SDL_GetTouchFinger() - replaced with SDL_GetTouchFingers()

SDL_version.h

SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0.

SDL_GetVersion() returns the version number, which can be directly compared with another version wrapped with SDL_VERSIONNUM().

The following structures have been removed:

  • SDL_version

The following symbols have been renamed:

  • SDL_COMPILEDVERSION => SDL_VERSION
  • SDL_PATCHLEVEL => SDL_MICRO_VERSION

SDL_video.h

Several video backends have had their names lower-cased ("kmsdrm", "rpi", "android", "psp", "ps2", "vita"). SDL already does a case-insensitive compare for SDL_HINT_VIDEO_DRIVER tests, but if your app is calling SDL_GetVideoDriver() or SDL_GetCurrentVideoDriver() and doing case-sensitive compares on those strings, please update your code.

SDL_VideoInit() and SDL_VideoQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_VIDEO, which will properly refcount the subsystems. You can choose a specific video driver using SDL_HINT_VIDEO_DRIVER.

Rather than iterating over displays using display index, there is a new function SDL_GetDisplays() to get the current list of displays, and functions which used to take a display index now take SDL_DisplayID, with an invalid ID being 0.

{
    if (SDL_InitSubSystem(SDL_INIT_VIDEO)) {
        int i, num_displays = 0;
        SDL_DisplayID *displays = SDL_GetDisplays(&num_displays);
        if (displays) {
            for (i = 0; i < num_displays; ++i) {
                SDL_DisplayID instance_id = displays[i];
                const char *name = SDL_GetDisplayName(instance_id);

                SDL_Log("Display %" SDL_PRIu32 ": %s", instance_id, name ? name : "Unknown");
            }
            SDL_free(displays);
        }
        SDL_QuitSubSystem(SDL_INIT_VIDEO);
    }
}

SDL_CreateWindow() has been simplified and no longer takes a window position. You can use SDL_CreateWindowWithProperties() if you need to set the window position when creating it, e.g.

    SDL_PropertiesID props = SDL_CreateProperties();
    SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
    // For window flags you should use separate window creation properties,
    // but for easier migration from SDL2 you can use the following:
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags);
    pWindow = SDL_CreateWindowWithProperties(props);
    SDL_DestroyProperties(props);
    if (window) {
        ...
    }

The SDL_WINDOWPOS_UNDEFINED_DISPLAY() and SDL_WINDOWPOS_CENTERED_DISPLAY() macros take a display ID instead of display index. The display ID 0 has a special meaning in this case, and is used to indicate the primary display.

The SDL_WINDOW_SHOWN flag has been removed. Windows are shown by default and can be created hidden by using the SDL_WINDOW_HIDDEN flag.

The SDL_WINDOW_SKIP_TASKBAR flag has been replaced by the SDL_WINDOW_UTILITY flag, which has the same functionality.

SDL_DisplayMode now includes the pixel density which can be greater than 1.0 for display modes that have a higher pixel size than the mode size. You should use SDL_GetWindowSizeInPixels() to get the actual pixel size of the window back buffer.

The refresh rate in SDL_DisplayMode is now a float, as well as being represented as a precise fraction with numerator and denominator.

Rather than iterating over display modes using an index, there is a new function SDL_GetFullscreenDisplayModes() to get the list of available fullscreen modes on a display.

{
    SDL_DisplayID display = SDL_GetPrimaryDisplay();
    int num_modes = 0;
    SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes);
    if (modes) {
        for (i = 0; i < num_modes; ++i) {
            SDL_DisplayMode *mode = modes[i];
            SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gx %gHz",
                    display, i, mode->w, mode->h, mode->pixel_density, mode->refresh_rate);
        }
        SDL_free(modes);
    }
}

SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory.

Windows now have an explicit fullscreen mode that is set, using SDL_SetWindowFullscreenMode(). The fullscreen mode for a window can be queried with SDL_GetWindowFullscreenMode(), which returns a pointer to the mode, or NULL if the window will be fullscreen desktop. SDL_SetWindowFullscreen() just takes a boolean value, setting the correct fullscreen state based on the selected mode.

SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, and you can call SDL_GetWindowFullscreenMode() to see whether an exclusive fullscreen mode will be used or the borderless fullscreen desktop mode will be used when the window is fullscreen.

SDL_SetWindowBrightness(), SDL_GetWindowBrightness, SDL_SetWindowGammaRamp(), and SDL_GetWindowGammaRamp have been removed from the API, because they interact poorly with modern operating systems and aren't able to limit their effects to the SDL window.

Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect.

Removed SDL_GL_CONTEXT_EGL from OpenGL configuration attributes. You can instead use SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);

SDL_GL_GetProcAddress() and SDL_EGL_GetProcAddress() now return SDL_FunctionPointer instead of void *, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.

SDL_GL_DeleteContext() has been renamed to SDL_GL_DestroyContext to match SDL naming conventions (and glX/EGL!).

SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns true if the function succeeds or false if there was an error.

SDL_GL_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place.

The SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP_MENU window flags are now supported on Windows, Mac (Cocoa), X11, and Wayland. Creating windows with these flags must happen via the SDL_CreatePopupWindow() function. This function requires passing in the handle to a valid parent window for the popup, and the popup window is positioned relative to the parent.

SDL_WindowFlags is used instead of Uint32 for API functions that refer to window flags, and has been extended to 64 bits.

SDL_GetWindowOpacity() directly returns the opacity instead of using an out parameter.

The following functions have been renamed:

  • SDL_GL_DeleteContext() => SDL_GL_DestroyContext(), returns bool
  • SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode(), returns bool
  • SDL_GetDisplayOrientation() => SDL_GetCurrentDisplayOrientation()
  • SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint()
  • SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect()
  • SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow()
  • SDL_GetWindowDisplayMode() => SDL_GetWindowFullscreenMode()
  • SDL_HasWindowSurface() => SDL_WindowHasSurface()
  • SDL_IsScreenSaverEnabled() => SDL_ScreenSaverEnabled()
  • SDL_SetWindowDisplayMode() => SDL_SetWindowFullscreenMode(), returns bool

The following functions have been removed:

  • SDL_GetDisplayDPI() - not reliable across platforms, approximately replaced by multiplying SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms.
  • SDL_GetDisplayMode()
  • SDL_GetNumDisplayModes() - replaced with SDL_GetFullscreenDisplayModes()
  • SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays()
  • SDL_SetWindowGrab() - use SDL_SetWindowMouseGrab() instead, along with SDL_SetWindowKeyboardGrab() if you also set SDL_HINT_GRAB_KEYBOARD.
  • SDL_GetWindowGrab() - use SDL_GetWindowMouseGrab() instead, along with SDL_GetWindowKeyboardGrab() if you also set SDL_HINT_GRAB_KEYBOARD.
  • SDL_GetWindowData() - use SDL_GetPointerProperty() instead, along with SDL_GetWindowProperties()
  • SDL_SetWindowData() - use SDL_SetPointerProperty() instead, along with SDL_GetWindowProperties()
  • SDL_CreateWindowFrom() - use SDL_CreateWindowWithProperties() with the properties that allow you to wrap an existing window
  • SDL_SetWindowInputFocus() - use SDL_RaiseWindow() instead
  • SDL_SetWindowModalFor() - use SDL_SetWindowParent() with SDL_SetWindowModal() instead
  • SDL_SetWindowBrightness() - use a shader or other in-game effect.
  • SDL_GetWindowBrightness() - use a shader or other in-game effect.
  • SDL_SetWindowGammaRamp() - use a shader or other in-game effect.
  • SDL_GetWindowGammaRamp() - use a shader or other in-game effect.

The SDL_Window id type is named SDL_WindowID

The following environment variables have been removed:

  • SDL_VIDEO_GL_DRIVER - replaced with the hint SDL_HINT_OPENGL_LIBRARY
  • SDL_VIDEO_EGL_DRIVER - replaced with the hint SDL_HINT_EGL_LIBRARY

The following symbols have been renamed:

  • SDL_DISPLAYEVENT_DISCONNECTED => SDL_EVENT_DISPLAY_REMOVED
  • SDL_DISPLAYEVENT_MOVED => SDL_EVENT_DISPLAY_MOVED
  • SDL_DISPLAYEVENT_ORIENTATION => SDL_EVENT_DISPLAY_ORIENTATION
  • SDL_GLattr => SDL_GLAttr
  • SDL_GLcontextFlag => SDL_GLContextFlag
  • SDL_GLcontextReleaseFlag => SDL_GLContextReleaseFlag
  • SDL_GLprofile => SDL_GLProfile
  • SDL_WINDOWEVENT_CLOSE => SDL_EVENT_WINDOW_CLOSE_REQUESTED
  • SDL_WINDOWEVENT_DISPLAY_CHANGED => SDL_EVENT_WINDOW_DISPLAY_CHANGED
  • SDL_WINDOWEVENT_ENTER => SDL_EVENT_WINDOW_MOUSE_ENTER
  • SDL_WINDOWEVENT_EXPOSED => SDL_EVENT_WINDOW_EXPOSED
  • SDL_WINDOWEVENT_FOCUS_GAINED => SDL_EVENT_WINDOW_FOCUS_GAINED
  • SDL_WINDOWEVENT_FOCUS_LOST => SDL_EVENT_WINDOW_FOCUS_LOST
  • SDL_WINDOWEVENT_HIDDEN => SDL_EVENT_WINDOW_HIDDEN
  • SDL_WINDOWEVENT_HIT_TEST => SDL_EVENT_WINDOW_HIT_TEST
  • SDL_WINDOWEVENT_ICCPROF_CHANGED => SDL_EVENT_WINDOW_ICCPROF_CHANGED
  • SDL_WINDOWEVENT_LEAVE => SDL_EVENT_WINDOW_MOUSE_LEAVE
  • SDL_WINDOWEVENT_MAXIMIZED => SDL_EVENT_WINDOW_MAXIMIZED
  • SDL_WINDOWEVENT_MINIMIZED => SDL_EVENT_WINDOW_MINIMIZED
  • SDL_WINDOWEVENT_MOVED => SDL_EVENT_WINDOW_MOVED
  • SDL_WINDOWEVENT_RESIZED => SDL_EVENT_WINDOW_RESIZED
  • SDL_WINDOWEVENT_RESTORED => SDL_EVENT_WINDOW_RESTORED
  • SDL_WINDOWEVENT_SHOWN => SDL_EVENT_WINDOW_SHOWN
  • SDL_WINDOW_ALLOW_HIGHDPI => SDL_WINDOW_HIGH_PIXEL_DENSITY
  • SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED

The following symbols have been removed:

  • SDL_WINDOWEVENT_SIZE_CHANGED - handle the SDL_EVENT_WINDOW_RESIZED and SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED events instead
  • SDL_WINDOWEVENT_TAKE_FOCUS

The following window operations are now considered to be asynchronous requests and should not be assumed to succeed unless a corresponding event has been received:

  • SDL_SetWindowSize() (SDL_EVENT_WINDOW_RESIZED)
  • SDL_SetWindowPosition() (SDL_EVENT_WINDOW_MOVED)
  • SDL_MinimizeWindow() (SDL_EVENT_WINDOW_MINIMIZED)
  • SDL_MaximizeWindow() (SDL_EVENT_WINDOW_MAXIMIZED)
  • SDL_RestoreWindow() (SDL_EVENT_WINDOW_RESTORED)
  • SDL_SetWindowFullscreen() (SDL_EVENT_WINDOW_ENTER_FULLSCREEN / SDL_EVENT_WINDOW_LEAVE_FULLSCREEN)

If it is required that operations be applied immediately after one of the preceding calls, the SDL_SyncWindow() function will attempt to wait until all pending window operations have completed. The SDL_HINT_VIDEO_SYNC_WINDOW_OPERATIONS hint can also be set to automatically synchronize after all calls to an asynchronous window operation, mimicking the behavior of SDL 2. Be aware that synchronizing can potentially block for long periods of time, as it may have to wait for window animations to complete. Also note that windowing systems can deny or not precisely obey these requests (e.g. windows may not be allowed to be larger than the usable desktop space or placed offscreen), so a corresponding event may never arrive or not contain the expected values.

SDL_vulkan.h

SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter, and no longer makes the app allocate query/allocate space for the result, instead returning a static const internal string.

SDL_Vulkan_GetVkGetInstanceProcAddr() now returns SDL_FunctionPointer instead of void *, and should be cast to PFN_vkGetInstanceProcAddr.

SDL_Vulkan_CreateSurface() now takes a VkAllocationCallbacks pointer as its third parameter. If you don't have an allocator to supply, pass a NULL here to use the system default allocator (SDL2 always used the system default allocator here).

SDL_Vulkan_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place.

SDL_vulkanInstance and SDL_vulkanSurface have been removed. They were for compatibility with Tizen, who had built their own Vulkan interface into SDL2, but these apps will need changes for the SDL3 API if they are upgraded anyhow.