diff --git a/.vs/ShadoowCrest_Gameengine/v17/.suo b/.vs/ShadoowCrest_Gameengine/v17/.suo
deleted file mode 100644
index 5724ff4..0000000
Binary files a/.vs/ShadoowCrest_Gameengine/v17/.suo and /dev/null differ
diff --git a/.vs/ShadoowCrest_Gameengine/v17/DocumentLayout.json b/.vs/ShadoowCrest_Gameengine/v17/DocumentLayout.json
deleted file mode 100644
index fd29503..0000000
--- a/.vs/ShadoowCrest_Gameengine/v17/DocumentLayout.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "Version": 1,
- "WorkspaceRootPath": "C:\\Users\\steev\\Desktop\\shadowcrest\\ShadoowCrest_Gameengine\\",
- "Documents": [],
- "DocumentGroupContainers": [
- {
- "Orientation": 0,
- "VerticalTabListWidth": 256,
- "DocumentGroups": [
- {
- "DockedWidth": 200,
- "SelectedChildIndex": -1,
- "Children": [
- {
- "$type": "Bookmark",
- "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
- }
- ]
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/.vs/ShadowCrestGameEngine/FileContentIndex/8f1993df-0a8c-4bee-8881-b034a4ec9bbf.vsidx b/.vs/ShadowCrestGameEngine/FileContentIndex/8f1993df-0a8c-4bee-8881-b034a4ec9bbf.vsidx
new file mode 100644
index 0000000..b42a4af
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/FileContentIndex/8f1993df-0a8c-4bee-8881-b034a4ec9bbf.vsidx differ
diff --git a/.vs/ShadowCrestGameEngine/FileContentIndex/a0455f11-3666-495c-ac38-9570ee990249.vsidx b/.vs/ShadowCrestGameEngine/FileContentIndex/a0455f11-3666-495c-ac38-9570ee990249.vsidx
new file mode 100644
index 0000000..9385d72
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/FileContentIndex/a0455f11-3666-495c-ac38-9570ee990249.vsidx differ
diff --git a/.vs/ShadowCrestGameEngine/FileContentIndex/b9248b32-d6dc-45bd-9a29-1ad2b7d97843.vsidx b/.vs/ShadowCrestGameEngine/FileContentIndex/b9248b32-d6dc-45bd-9a29-1ad2b7d97843.vsidx
new file mode 100644
index 0000000..13d632c
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/FileContentIndex/b9248b32-d6dc-45bd-9a29-1ad2b7d97843.vsidx differ
diff --git a/.vs/ShadowCrestGameEngine/FileContentIndex/ca5343bc-50dd-4b0f-8297-0b947c3b4a15.vsidx b/.vs/ShadowCrestGameEngine/FileContentIndex/ca5343bc-50dd-4b0f-8297-0b947c3b4a15.vsidx
new file mode 100644
index 0000000..2e11bbe
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/FileContentIndex/ca5343bc-50dd-4b0f-8297-0b947c3b4a15.vsidx differ
diff --git a/.vs/ShadowCrestGameEngine/FileContentIndex/de5cd0eb-2142-4e94-912e-98a004a4d48f.vsidx b/.vs/ShadowCrestGameEngine/FileContentIndex/de5cd0eb-2142-4e94-912e-98a004a4d48f.vsidx
new file mode 100644
index 0000000..1fbf7f6
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/FileContentIndex/de5cd0eb-2142-4e94-912e-98a004a4d48f.vsidx differ
diff --git a/.vs/ShadowCrestGameEngine/v17/.suo b/.vs/ShadowCrestGameEngine/v17/.suo
new file mode 100644
index 0000000..7ecde54
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/v17/.suo differ
diff --git a/.vs/ShadowCrestGameEngine/v17/Browse.VC.db b/.vs/ShadowCrestGameEngine/v17/Browse.VC.db
new file mode 100644
index 0000000..f3a45c1
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/v17/Browse.VC.db differ
diff --git a/.vs/ShadowCrestGameEngine/v17/DocumentLayout.backup.json b/.vs/ShadowCrestGameEngine/v17/DocumentLayout.backup.json
new file mode 100644
index 0000000..2ecb35c
--- /dev/null
+++ b/.vs/ShadowCrestGameEngine/v17/DocumentLayout.backup.json
@@ -0,0 +1,102 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\Engine.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\Logger.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\WindowManager.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def||{8B382828-6202-11D1-8870-0000F87579D2}",
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:SDL3.def||{8B382828-6202-11D1-8870-0000F87579D2}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 200,
+ "SelectedChildIndex": 3,
+ "Children": [
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "SDL3.def",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def",
+ "RelativeDocumentMoniker": "SDL3.def",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def",
+ "RelativeToolTip": "SDL3.def",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAALwEAAALAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001913|",
+ "WhenOpened": "2025-07-12T23:40:30.165Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 2,
+ "Title": "Logger.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp",
+ "RelativeDocumentMoniker": "src\\core\\Logger.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp",
+ "RelativeToolTip": "src\\core\\Logger.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:31:49.016Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "WindowManager.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp",
+ "RelativeDocumentMoniker": "src\\core\\WindowManager.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp",
+ "RelativeToolTip": "src\\core\\WindowManager.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:31:48.358Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Engine.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp",
+ "RelativeDocumentMoniker": "src\\core\\Engine.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp",
+ "RelativeToolTip": "src\\core\\Engine.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAGAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:30:21.367Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "main.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp",
+ "RelativeDocumentMoniker": "src\\main.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp",
+ "RelativeToolTip": "src\\main.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:27:27.198Z",
+ "EditorCaption": ""
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vs/ShadowCrestGameEngine/v17/DocumentLayout.json b/.vs/ShadowCrestGameEngine/v17/DocumentLayout.json
new file mode 100644
index 0000000..d2dbf2d
--- /dev/null
+++ b/.vs/ShadowCrestGameEngine/v17/DocumentLayout.json
@@ -0,0 +1,138 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\Engine.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\WindowManager.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\WindowManager.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\Engine.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
+ "RelativeMoniker": "D:0:0:{5653811A-38D1-4D9D-9446-A417E8557584}|ShadowCrestGameEngine.vcxproj|solutionrelative:src\\core\\Logger.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def||{8B382828-6202-11D1-8870-0000F87579D2}",
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:SDL3.def||{8B382828-6202-11D1-8870-0000F87579D2}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 200,
+ "SelectedChildIndex": 5,
+ "Children": [
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "Engine.h",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.h",
+ "RelativeDocumentMoniker": "src\\core\\Engine.h",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.h",
+ "RelativeToolTip": "src\\core\\Engine.h",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
+ "WhenOpened": "2025-07-13T00:30:33.574Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "WindowManager.h",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.h",
+ "RelativeDocumentMoniker": "src\\core\\WindowManager.h",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.h",
+ "RelativeToolTip": "src\\core\\WindowManager.h",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAACAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
+ "WhenOpened": "2025-07-13T00:30:23.261Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "SDL3.def",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def",
+ "RelativeDocumentMoniker": "SDL3.def",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\SDL3.def",
+ "RelativeToolTip": "SDL3.def",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAALwEAAALAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001913|",
+ "WhenOpened": "2025-07-12T23:40:30.165Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
+ "Title": "Logger.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp",
+ "RelativeDocumentMoniker": "src\\core\\Logger.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Logger.cpp",
+ "RelativeToolTip": "src\\core\\Logger.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:31:49.016Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "WindowManager.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp",
+ "RelativeDocumentMoniker": "src\\core\\WindowManager.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\WindowManager.cpp",
+ "RelativeToolTip": "src\\core\\WindowManager.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAABDAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:31:48.358Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Engine.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp",
+ "RelativeDocumentMoniker": "src\\core\\Engine.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\core\\Engine.cpp",
+ "RelativeToolTip": "src\\core\\Engine.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAUAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:30:21.367Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 2,
+ "Title": "main.cpp",
+ "DocumentMoniker": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp",
+ "RelativeDocumentMoniker": "src\\main.cpp",
+ "ToolTip": "C:\\Users\\steev\\Desktop\\ShadowCrestGameEngine\\src\\main.cpp",
+ "RelativeToolTip": "src\\main.cpp",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
+ "WhenOpened": "2025-07-12T23:27:27.198Z",
+ "EditorCaption": ""
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vs/ShadoowCrest_Gameengine/v17/Browse.VC.db b/.vs/ShadowCrestGameEngine/v17/Solution.VC.db
similarity index 71%
rename from .vs/ShadoowCrest_Gameengine/v17/Browse.VC.db
rename to .vs/ShadowCrestGameEngine/v17/Solution.VC.db
index 9a7f769..6512273 100644
Binary files a/.vs/ShadoowCrest_Gameengine/v17/Browse.VC.db and b/.vs/ShadowCrestGameEngine/v17/Solution.VC.db differ
diff --git a/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/3c48dcde4ebc285f/ENGINE.ipch b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/3c48dcde4ebc285f/ENGINE.ipch
new file mode 100644
index 0000000..f782382
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/3c48dcde4ebc285f/ENGINE.ipch differ
diff --git a/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/b003513ded54e89a/WINDOWMANAGER.ipch b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/b003513ded54e89a/WINDOWMANAGER.ipch
new file mode 100644
index 0000000..d245a98
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/b003513ded54e89a/WINDOWMANAGER.ipch differ
diff --git a/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/c806b5d5c43bcb0b/MAIN.ipch b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/c806b5d5c43bcb0b/MAIN.ipch
new file mode 100644
index 0000000..c9bcdf4
Binary files /dev/null and b/.vs/ShadowCrestGameEngine/v17/ipch/AutoPCH/c806b5d5c43bcb0b/MAIN.ipch differ
diff --git a/ShadoowCrest_Gameengine.sln b/ShadoowCrest_Gameengine.sln
deleted file mode 100644
index 264b588..0000000
--- a/ShadoowCrest_Gameengine.sln
+++ /dev/null
@@ -1,31 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.14.36301.6 d17.14
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShadoowCrest_Gameengine", "ShadoowCrest_Gameengine.vcxproj", "{EDD323AC-3212-4BD6-877E-1A0155781415}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
- Release|x64 = Release|x64
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Debug|x64.ActiveCfg = Debug|x64
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Debug|x64.Build.0 = Debug|x64
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Debug|x86.ActiveCfg = Debug|Win32
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Debug|x86.Build.0 = Debug|Win32
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Release|x64.ActiveCfg = Release|x64
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Release|x64.Build.0 = Release|x64
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Release|x86.ActiveCfg = Release|Win32
- {EDD323AC-3212-4BD6-877E-1A0155781415}.Release|x86.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {E38B3869-3F4D-47BE-9C10-30182BCFAEA1}
- EndGlobalSection
-EndGlobal
diff --git a/ShadoowCrest_Gameengine.vcxproj.filters b/ShadoowCrest_Gameengine.vcxproj.filters
deleted file mode 100644
index 50aca57..0000000
--- a/ShadoowCrest_Gameengine.vcxproj.filters
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
\ No newline at end of file
diff --git a/ShadowCr.5653811a/x64/Debug/Engine.obj b/ShadowCr.5653811a/x64/Debug/Engine.obj
new file mode 100644
index 0000000..7bae0d2
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/Engine.obj differ
diff --git a/ShadowCr.5653811a/x64/Debug/Logger.obj b/ShadowCr.5653811a/x64/Debug/Logger.obj
new file mode 100644
index 0000000..8fa411e
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/Logger.obj differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.command.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.command.1.tlog
new file mode 100644
index 0000000..dfdeeab
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.command.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.read.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.read.1.tlog
new file mode 100644
index 0000000..22aaacf
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.read.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.write.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.write.1.tlog
new file mode 100644
index 0000000..2e24bec
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/CL.write.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/Cl.items.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/Cl.items.tlog
new file mode 100644
index 0000000..6503d99
--- /dev/null
+++ b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/Cl.items.tlog
@@ -0,0 +1,4 @@
+C:\Users\steev\Desktop\ShadowCrestGameEngine\src\core\Engine.cpp;C:\Users\steev\Desktop\ShadowCrestGameEngine\ShadowCr.5653811a\x64\Debug\Engine.obj
+C:\Users\steev\Desktop\ShadowCrestGameEngine\src\core\Logger.cpp;C:\Users\steev\Desktop\ShadowCrestGameEngine\ShadowCr.5653811a\x64\Debug\Logger.obj
+C:\Users\steev\Desktop\ShadowCrestGameEngine\src\core\WindowManager.cpp;C:\Users\steev\Desktop\ShadowCrestGameEngine\ShadowCr.5653811a\x64\Debug\WindowManager.obj
+C:\Users\steev\Desktop\ShadowCrestGameEngine\src\main.cpp;C:\Users\steev\Desktop\ShadowCrestGameEngine\ShadowCr.5653811a\x64\Debug\main.obj
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/ShadowCrestGameEngine.lastbuildstate b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/ShadowCrestGameEngine.lastbuildstate
new file mode 100644
index 0000000..37ad6e7
--- /dev/null
+++ b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/ShadowCrestGameEngine.lastbuildstate
@@ -0,0 +1,2 @@
+PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.44.35207:TargetPlatformVersion=10.0.26100.0:
+Debug|x64|C:\Users\steev\Desktop\ShadowCrestGameEngine\|
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.command.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.command.1.tlog
new file mode 100644
index 0000000..c3fc777
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.command.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.read.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.read.1.tlog
new file mode 100644
index 0000000..c879fdf
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.read.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.secondary.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.secondary.1.tlog
new file mode 100644
index 0000000..1ed42a8
--- /dev/null
+++ b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.secondary.1.tlog
@@ -0,0 +1,2 @@
+^C:\USERS\STEEV\DESKTOP\SHADOWCRESTGAMEENGINE\SHADOWCR.5653811A\X64\DEBUG\ENGINE.OBJ|C:\USERS\STEEV\DESKTOP\SHADOWCRESTGAMEENGINE\SHADOWCR.5653811A\X64\DEBUG\LOGGER.OBJ|C:\USERS\STEEV\DESKTOP\SHADOWCRESTGAMEENGINE\SHADOWCR.5653811A\X64\DEBUG\MAIN.OBJ|C:\USERS\STEEV\DESKTOP\SHADOWCRESTGAMEENGINE\SHADOWCR.5653811A\X64\DEBUG\WINDOWMANAGER.OBJ
+C:\Users\steev\Desktop\ShadowCrestGameEngine\ShadowCr.5653811a\x64\Debug\ShadowCrestGameEngine.ilk
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.write.1.tlog b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.write.1.tlog
new file mode 100644
index 0000000..f74279c
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCr.5653811a.tlog/link.write.1.tlog differ
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.exe.recipe b/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.exe.recipe
new file mode 100644
index 0000000..163265f
--- /dev/null
+++ b/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.exe.recipe
@@ -0,0 +1,11 @@
+
+
+
+
+ C:\Users\steev\Desktop\ShadowCrestGameEngine\x64\Debug\ShadowCrestGameEngine.exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.ilk b/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.ilk
new file mode 100644
index 0000000..f66d08a
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/ShadowCrestGameEngine.ilk differ
diff --git a/ShadowCr.5653811a/x64/Debug/WindowManager.obj b/ShadowCr.5653811a/x64/Debug/WindowManager.obj
new file mode 100644
index 0000000..35a9765
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/WindowManager.obj differ
diff --git a/ShadowCr.5653811a/x64/Debug/main.obj b/ShadowCr.5653811a/x64/Debug/main.obj
new file mode 100644
index 0000000..8b8f8ba
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/main.obj differ
diff --git a/ShadowCr.5653811a/x64/Debug/vc143.idb b/ShadowCr.5653811a/x64/Debug/vc143.idb
new file mode 100644
index 0000000..1daf9cd
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/vc143.idb differ
diff --git a/ShadowCr.5653811a/x64/Debug/vc143.pdb b/ShadowCr.5653811a/x64/Debug/vc143.pdb
new file mode 100644
index 0000000..5765c7c
Binary files /dev/null and b/ShadowCr.5653811a/x64/Debug/vc143.pdb differ
diff --git a/ShadowCrestGameEngine.sln b/ShadowCrestGameEngine.sln
new file mode 100644
index 0000000..e349201
--- /dev/null
+++ b/ShadowCrestGameEngine.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36301.6 d17.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShadowCrestGameEngine", "ShadowCrestGameEngine.vcxproj", "{5653811A-38D1-4D9D-9446-A417E8557584}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Debug|x64.ActiveCfg = Debug|x64
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Debug|x64.Build.0 = Debug|x64
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Debug|x86.ActiveCfg = Debug|Win32
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Debug|x86.Build.0 = Debug|Win32
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Release|x64.ActiveCfg = Release|x64
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Release|x64.Build.0 = Release|x64
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Release|x86.ActiveCfg = Release|Win32
+ {5653811A-38D1-4D9D-9446-A417E8557584}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {BCC6CFCC-6747-45A2-ABEE-0BC355C15801}
+ EndGlobalSection
+EndGlobal
diff --git a/ShadoowCrest_Gameengine.vcxproj b/ShadowCrestGameEngine.vcxproj
similarity index 65%
rename from ShadoowCrest_Gameengine.vcxproj
rename to ShadowCrestGameEngine.vcxproj
index 4935a93..441737e 100644
--- a/ShadoowCrest_Gameengine.vcxproj
+++ b/ShadowCrestGameEngine.vcxproj
@@ -17,13 +17,12 @@
Releasex64
-
17.0Win32Proj
- {edd323ac-3212-4bd6-877e-1a0155781415}
- ShadoowCrestGameengine
+ {5653811a-38d1-4d9d-9446-a417e8557584}
+ ShadowCrestGameEngine10.0
@@ -53,27 +52,27 @@
trueUnicode
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ $(IncludePath)
+ Level3
@@ -83,7 +82,7 @@
Console
- true
+ true
@@ -97,7 +96,7 @@
Console
- true
+ true
@@ -106,10 +105,13 @@
true_DEBUG;_CONSOLE;%(PreprocessorDefinitions)true
+ $(ProjectDir)/Vendored/SDL/include;$(ProjectDir)/libs;%(AdditionalIncludeDirectories)Console
- true
+ true
+ $(ProjectDir)/libs
+ $(ProjectDir)libs/SDL3.lib;%(AdditionalDependencies)
@@ -123,12 +125,21 @@
Console
- true
+ true
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/ShadowCrestGameEngine.vcxproj.filters b/ShadowCrestGameEngine.vcxproj.filters
new file mode 100644
index 0000000..f479f1f
--- /dev/null
+++ b/ShadowCrestGameEngine.vcxproj.filters
@@ -0,0 +1,48 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {c7e9328e-53fc-4a6c-b575-2a282171ee45}
+
+
+ {dab3d0c3-1768-433c-86d1-ac8cb6dbeb21}
+
+
+
+
+ Quelldateien
+
+
+ Quelldateien\core
+
+
+ Quelldateien\core
+
+
+ Quelldateien\core
+
+
+
+
+ Headerdateien\core
+
+
+ Headerdateien\core
+
+
+ Headerdateien\core
+
+
+
\ No newline at end of file
diff --git a/ShadoowCrest_Gameengine.vcxproj.user b/ShadowCrestGameEngine.vcxproj.user
similarity index 100%
rename from ShadoowCrest_Gameengine.vcxproj.user
rename to ShadowCrestGameEngine.vcxproj.user
diff --git a/libs/SDL3.dll b/libs/SDL3.dll
new file mode 100644
index 0000000..63f5b22
Binary files /dev/null and b/libs/SDL3.dll differ
diff --git a/libs/SDL3.lib b/libs/SDL3.lib
new file mode 100644
index 0000000..164aeb9
Binary files /dev/null and b/libs/SDL3.lib differ
diff --git a/libs/SDL3.pdb b/libs/SDL3.pdb
new file mode 100644
index 0000000..e2b078f
Binary files /dev/null and b/libs/SDL3.pdb differ
diff --git a/libs/SDL3_test.lib b/libs/SDL3_test.lib
new file mode 100644
index 0000000..79a1eef
Binary files /dev/null and b/libs/SDL3_test.lib differ
diff --git a/src/core/.gitkeep b/src/core/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp
new file mode 100644
index 0000000..c885f6f
--- /dev/null
+++ b/src/core/Engine.cpp
@@ -0,0 +1,41 @@
+#include "Engine.h"
+#include
+#include
+#include "WindowManager.h"
+
+bool running = true;
+WindowManager wm;
+
+bool Engine::Init() {
+ if (!SDL_Init(SDL_INIT_VIDEO)) {
+ std::cerr << "SDL_Init failed: " << SDL_GetError() << "\n";
+ return false;
+ }
+
+ wm = new WindowManager();
+
+ if (!wm.InitWindow("ShadowCrest", 800, 600)) {
+ std::cerr << "SDL_Init failed: " << SDL_GetError() << "\n";
+ return false;
+ }
+
+ return true;
+}
+
+void Engine::Run() {
+ SDL_Event event;
+ while (running) {
+ while (SDL_PollEvent(&event)) {
+ if (event.type == SDL_EVENT_QUIT) {
+ running = false;
+ }
+ }
+
+ SDL_Delay(16);
+ }
+}
+
+void Engine::Shutdown() {
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+}
\ No newline at end of file
diff --git a/src/core/Engine.h b/src/core/Engine.h
new file mode 100644
index 0000000..13f5ff6
--- /dev/null
+++ b/src/core/Engine.h
@@ -0,0 +1,8 @@
+#pragma once
+
+class Engine {
+public:
+ bool Init();
+ void Run();
+ void Shutdown();
+};
\ No newline at end of file
diff --git a/src/core/Logger.cpp b/src/core/Logger.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/src/core/Logger.h b/src/core/Logger.h
new file mode 100644
index 0000000..e69de29
diff --git a/src/core/WindowManager.cpp b/src/core/WindowManager.cpp
new file mode 100644
index 0000000..e456375
--- /dev/null
+++ b/src/core/WindowManager.cpp
@@ -0,0 +1,12 @@
+#include "WindowManager.h"
+#include
+#include
+#include
+
+SDL_Window* window = nullptr;
+
+bool WindowManager::InitWindow(char *name, int width, int height) {
+ // creates window
+ window = SDL_CreateWindow(name, width, height, SDL_WINDOW_RESIZABLE);
+ return window != nullptr;
+}
\ No newline at end of file
diff --git a/src/core/WindowManager.h b/src/core/WindowManager.h
new file mode 100644
index 0000000..a9916b5
--- /dev/null
+++ b/src/core/WindowManager.h
@@ -0,0 +1,10 @@
+#include
+using namespace std;
+
+#pragma once
+
+class WindowManager {
+public:
+ bool InitWindow(char *name, int width, int height);
+ void Draw();
+};
\ No newline at end of file
diff --git a/src/game/.gitkeep b/src/game/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..dd41483
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,15 @@
+#include "core/Engine.h"
+#include
+#include // Nur für SDL_GetError()
+
+int main() {
+ Engine engine;
+ if (!engine.Init()) {
+ std::cerr << "Engine failed to initialize. SDL Error: " << SDL_GetError() << "\n";
+ return 1;
+ }
+
+ engine.Run();
+ engine.Shutdown();
+ return 0;
+}
diff --git a/src/systems/.gitkeep b/src/systems/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/vendored/SDL/include/SDL3/SDL.h b/vendored/SDL/include/SDL3/SDL.h
new file mode 100644
index 0000000..ed1b324
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL.h
@@ -0,0 +1,90 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * Main include header for the SDL library, version 3.2.16
+ *
+ * It is almost always best to include just this one header instead of
+ * picking out individual headers included here. There are exceptions to
+ * this rule--SDL_main.h is special and not included here--but usually
+ * letting SDL.h include the kitchen sink for you is the correct approach.
+ */
+
+#ifndef SDL_h_
+#define SDL_h_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#endif /* SDL_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_assert.h b/vendored/SDL/include/SDL3/SDL_assert.h
new file mode 100644
index 0000000..6c90acc
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_assert.h
@@ -0,0 +1,662 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryAssert
+ *
+ * A helpful assertion macro!
+ *
+ * SDL assertions operate like your usual `assert` macro, but with some added
+ * features:
+ *
+ * - It uses a trick with the `sizeof` operator, so disabled assertions
+ * vaporize out of the compiled code, but variables only referenced in the
+ * assertion won't trigger compiler warnings about being unused.
+ * - It is safe to use with a dangling-else: `if (x) SDL_assert(y); else
+ * do_something();`
+ * - It works the same everywhere, instead of counting on various platforms'
+ * compiler and C runtime to behave.
+ * - It provides multiple levels of assertion (SDL_assert, SDL_assert_release,
+ * SDL_assert_paranoid) instead of a single all-or-nothing option.
+ * - It offers a variety of responses when an assertion fails (retry, trigger
+ * the debugger, abort the program, ignore the failure once, ignore it for
+ * the rest of the program's run).
+ * - It tries to show the user a dialog by default, if possible, but the app
+ * can provide a callback to handle assertion failures however they like.
+ * - It lets failed assertions be retried. Perhaps you had a network failure
+ * and just want to retry the test after plugging your network cable back
+ * in? You can.
+ * - It lets the user ignore an assertion failure, if there's a harmless
+ * problem that one can continue past.
+ * - It lets the user mark an assertion as ignored for the rest of the
+ * program's run; if there's a harmless problem that keeps popping up.
+ * - It provides statistics and data on all failed assertions to the app.
+ * - It allows the default assertion handler to be controlled with environment
+ * variables, in case an automated script needs to control it.
+ * - It can be used as an aid to Clang's static analysis; it will treat SDL
+ * assertions as universally true (under the assumption that you are serious
+ * about the asserted claims and that your debug builds will detect when
+ * these claims were wrong). This can help the analyzer avoid false
+ * positives.
+ *
+ * To use it: compile a debug build and just sprinkle around tests to check
+ * your code!
+ */
+
+#ifndef SDL_assert_h_
+#define SDL_assert_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * The level of assertion aggressiveness.
+ *
+ * This value changes depending on compiler options and other preprocessor
+ * defines.
+ *
+ * It is currently one of the following values, but future SDL releases might
+ * add more:
+ *
+ * - 0: All SDL assertion macros are disabled.
+ * - 1: Release settings: SDL_assert disabled, SDL_assert_release enabled.
+ * - 2: Debug settings: SDL_assert and SDL_assert_release enabled.
+ * - 3: Paranoid settings: All SDL assertion macros enabled, including
+ * SDL_assert_paranoid.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_ASSERT_LEVEL SomeNumberBasedOnVariousFactors
+
+#elif !defined(SDL_ASSERT_LEVEL)
+#ifdef SDL_DEFAULT_ASSERT_LEVEL
+#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL
+#elif defined(_DEBUG) || defined(DEBUG) || \
+ (defined(__GNUC__) && !defined(__OPTIMIZE__))
+#define SDL_ASSERT_LEVEL 2
+#else
+#define SDL_ASSERT_LEVEL 1
+#endif
+#endif
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * Attempt to tell an attached debugger to pause.
+ *
+ * This allows an app to programmatically halt ("break") the debugger as if it
+ * had hit a breakpoint, allowing the developer to examine program state, etc.
+ *
+ * This is a macro--not a function--so that the debugger breaks on the source
+ * code line that used SDL_TriggerBreakpoint and not in some random guts of
+ * SDL. SDL_assert uses this macro for the same reason.
+ *
+ * If the program is not running under a debugger, SDL_TriggerBreakpoint will
+ * likely terminate the app, possibly without warning. If the current platform
+ * isn't supported, this macro is left undefined.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
+
+#elif defined(_MSC_VER) && _MSC_VER >= 1310
+ /* Don't include intrin.h here because it contains C++ code */
+ extern void __cdecl __debugbreak(void);
+ #define SDL_TriggerBreakpoint() __debugbreak()
+#elif defined(_MSC_VER) && defined(_M_IX86)
+ #define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
+#elif defined(ANDROID)
+ #include
+ #define SDL_TriggerBreakpoint() assert(0)
+#elif SDL_HAS_BUILTIN(__builtin_debugtrap)
+ #define SDL_TriggerBreakpoint() __builtin_debugtrap()
+#elif SDL_HAS_BUILTIN(__builtin_trap)
+ #define SDL_TriggerBreakpoint() __builtin_trap()
+#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
+#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
+#elif ( defined(SDL_PLATFORM_APPLE) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" )
+#elif defined(SDL_PLATFORM_APPLE) && defined(__arm__)
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" )
+#elif defined(_WIN32) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) )
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #0xF000\n\t" )
+#elif defined(__GNUC__) || defined(__clang__)
+ #define SDL_TriggerBreakpoint() __builtin_trap() /* older gcc may not support SDL_HAS_BUILTIN(__builtin_trap) above */
+#elif defined(__386__) && defined(__WATCOMC__)
+ #define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
+#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__)
+ #include
+ #define SDL_TriggerBreakpoint() raise(SIGTRAP)
+#else
+ /* SDL_TriggerBreakpoint is intentionally left undefined on unknown platforms. */
+#endif
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro that reports the current function being compiled.
+ *
+ * If SDL can't figure how the compiler reports this, it will use "???".
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_FUNCTION __FUNCTION__
+
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
+# define SDL_FUNCTION __func__
+#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__))
+# define SDL_FUNCTION __FUNCTION__
+#else
+# define SDL_FUNCTION "???"
+#endif
+
+/**
+ * A macro that reports the current file being compiled.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_FILE __FILE__
+
+/**
+ * A macro that reports the current line number of the file being compiled.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_LINE __LINE__
+
+/*
+sizeof (x) makes the compiler still parse the expression even without
+assertions enabled, so the code is always checked at compile time, but
+doesn't actually generate code for it, so there are no side effects or
+expensive checks at run time, just the constant size of what x WOULD be,
+which presumably gets optimized out as unused.
+This also solves the problem of...
+
+ int somevalue = blah();
+ SDL_assert(somevalue == 1);
+
+...which would cause compiles to complain that somevalue is unused if we
+disable assertions.
+*/
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro for wrapping code in `do {} while (0);` without compiler warnings.
+ *
+ * Visual Studio with really aggressive warnings enabled needs this to avoid
+ * compiler complaints.
+ *
+ * the `do {} while (0);` trick is useful for wrapping code in a macro that
+ * may or may not be a single statement, to avoid various C language
+ * accidents.
+ *
+ * To use:
+ *
+ * ```c
+ * do { SomethingOnce(); } while (SDL_NULL_WHILE_LOOP_CONDITION (0));
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_NULL_WHILE_LOOP_CONDITION (0)
+
+#elif defined(_MSC_VER) /* Avoid /W4 warnings. */
+/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking
+ this condition isn't constant. And looks like an owl's face! */
+#define SDL_NULL_WHILE_LOOP_CONDITION (0,0)
+#else
+#define SDL_NULL_WHILE_LOOP_CONDITION (0)
+#endif
+
+/**
+ * The macro used when an assertion is disabled.
+ *
+ * This isn't for direct use by apps, but this is the code that is inserted
+ * when an SDL_assert is disabled (perhaps in a release build).
+ *
+ * The code does nothing, but wraps `condition` in a sizeof operator, which
+ * generates no code and has no side effects, but avoid compiler warnings
+ * about unused variables.
+ *
+ * \param condition the condition to assert (but not actually run here).
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_disabled_assert(condition) \
+ do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION)
+
+/**
+ * Possible outcomes from a triggered assertion.
+ *
+ * When an enabled assertion triggers, it may call the assertion handler
+ * (possibly one provided by the app via SDL_SetAssertionHandler), which will
+ * return one of these values, possibly after asking the user.
+ *
+ * Then SDL will respond based on this outcome (loop around to retry the
+ * condition, try to break in a debugger, kill the program, or ignore the
+ * problem).
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_AssertState
+{
+ SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */
+ SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */
+ SDL_ASSERTION_ABORT, /**< Terminate the program. */
+ SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
+ SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
+} SDL_AssertState;
+
+/**
+ * Information about an assertion failure.
+ *
+ * This structure is filled in with information about a triggered assertion,
+ * used by the assertion handler, then added to the assertion report. This is
+ * returned as a linked list from SDL_GetAssertionReport().
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_AssertData
+{
+ bool always_ignore; /**< true if app should always continue when assertion is triggered. */
+ unsigned int trigger_count; /**< Number of times this assertion has been triggered. */
+ const char *condition; /**< A string of this assert's test code. */
+ const char *filename; /**< The source file where this assert lives. */
+ int linenum; /**< The line in `filename` where this assert lives. */
+ const char *function; /**< The name of the function where this assert lives. */
+ const struct SDL_AssertData *next; /**< next item in the linked list. */
+} SDL_AssertData;
+
+/**
+ * Never call this directly.
+ *
+ * Use the SDL_assert macros instead.
+ *
+ * \param data assert data structure.
+ * \param func function name.
+ * \param file file name.
+ * \param line line number.
+ * \returns assert state.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data,
+ const char *func,
+ const char *file, int line) SDL_ANALYZER_NORETURN;
+
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * The macro used when an assertion triggers a breakpoint.
+ *
+ * This isn't for direct use by apps; use SDL_assert or SDL_TriggerBreakpoint
+ * instead.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
+
+#elif !defined(SDL_AssertBreakpoint)
+# if defined(ANDROID) && defined(assert)
+ /* Define this as empty in case assert() is defined as SDL_assert */
+# define SDL_AssertBreakpoint()
+# else
+# define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
+# endif
+#endif /* !SDL_AssertBreakpoint */
+
+/**
+ * The macro used when an assertion is enabled.
+ *
+ * This isn't for direct use by apps, but this is the code that is inserted
+ * when an SDL_assert is enabled.
+ *
+ * The `do {} while(0)` avoids dangling else problems:
+ *
+ * ```c
+ * if (x) SDL_assert(y); else blah();
+ * ```
+ *
+ * ... without the do/while, the "else" could attach to this macro's "if". We
+ * try to handle just the minimum we need here in a macro...the loop, the
+ * static vars, and break points. The heavy lifting is handled in
+ * SDL_ReportAssertion().
+ *
+ * \param condition the condition to assert.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_enabled_assert(condition) \
+ do { \
+ while ( !(condition) ) { \
+ static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \
+ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
+ if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
+ continue; /* go again. */ \
+ } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
+ SDL_AssertBreakpoint(); \
+ } \
+ break; /* not retrying. */ \
+ } \
+ } while (SDL_NULL_WHILE_LOOP_CONDITION)
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * An assertion test that is normally performed only in debug builds.
+ *
+ * This macro is enabled when the SDL_ASSERT_LEVEL is >= 2, otherwise it is
+ * disabled. This is meant to only do these tests in debug builds, so they can
+ * tend to be more expensive, and they are meant to bring everything to a halt
+ * when they fail, with the programmer there to assess the problem.
+ *
+ * In short: you can sprinkle these around liberally and assume they will
+ * evaporate out of the build when building for end-users.
+ *
+ * When assertions are disabled, this wraps `condition` in a `sizeof`
+ * operator, which means any function calls and side effects will not run, but
+ * the compiler will not complain about any otherwise-unused variables that
+ * are only referenced in the assertion.
+ *
+ * One can set the environment variable "SDL_ASSERT" to one of several strings
+ * ("abort", "break", "retry", "ignore", "always_ignore") to force a default
+ * behavior, which may be desirable for automation purposes. If your platform
+ * requires GUI interfaces to happen on the main thread but you're debugging
+ * an assertion in a background thread, it might be desirable to set this to
+ * "break" so that your debugger takes control as soon as assert is triggered,
+ * instead of risking a bad UI interaction (deadlock, etc) in the application.
+ *
+ * \param condition boolean value to test.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_assert(condition) if (assertion_enabled && (condition)) { trigger_assertion; }
+
+/**
+ * An assertion test that is performed even in release builds.
+ *
+ * This macro is enabled when the SDL_ASSERT_LEVEL is >= 1, otherwise it is
+ * disabled. This is meant to be for tests that are cheap to make and
+ * extremely unlikely to fail; generally it is frowned upon to have an
+ * assertion failure in a release build, so these assertions generally need to
+ * be of more than life-and-death importance if there's a chance they might
+ * trigger. You should almost always consider handling these cases more
+ * gracefully than an assert allows.
+ *
+ * When assertions are disabled, this wraps `condition` in a `sizeof`
+ * operator, which means any function calls and side effects will not run, but
+ * the compiler will not complain about any otherwise-unused variables that
+ * are only referenced in the assertion.
+ *
+ * One can set the environment variable "SDL_ASSERT" to one of several strings
+ * ("abort", "break", "retry", "ignore", "always_ignore") to force a default
+ * behavior, which may be desirable for automation purposes. If your platform
+ * requires GUI interfaces to happen on the main thread but you're debugging
+ * an assertion in a background thread, it might be desirable to set this to
+ * "break" so that your debugger takes control as soon as assert is triggered,
+ * instead of risking a bad UI interaction (deadlock, etc) in the application.
+ * *
+ *
+ * \param condition boolean value to test.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_assert_release(condition) SDL_disabled_assert(condition)
+
+/**
+ * An assertion test that is performed only when built with paranoid settings.
+ *
+ * This macro is enabled when the SDL_ASSERT_LEVEL is >= 3, otherwise it is
+ * disabled. This is a higher level than both release and debug, so these
+ * tests are meant to be expensive and only run when specifically looking for
+ * extremely unexpected failure cases in a special build.
+ *
+ * When assertions are disabled, this wraps `condition` in a `sizeof`
+ * operator, which means any function calls and side effects will not run, but
+ * the compiler will not complain about any otherwise-unused variables that
+ * are only referenced in the assertion.
+ *
+ * One can set the environment variable "SDL_ASSERT" to one of several strings
+ * ("abort", "break", "retry", "ignore", "always_ignore") to force a default
+ * behavior, which may be desirable for automation purposes. If your platform
+ * requires GUI interfaces to happen on the main thread but you're debugging
+ * an assertion in a background thread, it might be desirable to set this to
+ * "break" so that your debugger takes control as soon as assert is triggered,
+ * instead of risking a bad UI interaction (deadlock, etc) in the application.
+ *
+ * \param condition boolean value to test.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+
+/* Enable various levels of assertions. */
+#elif SDL_ASSERT_LEVEL == 0 /* assertions disabled */
+# define SDL_assert(condition) SDL_disabled_assert(condition)
+# define SDL_assert_release(condition) SDL_disabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 1 /* release settings. */
+# define SDL_assert(condition) SDL_disabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 2 /* debug settings. */
+# define SDL_assert(condition) SDL_enabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */
+# define SDL_assert(condition) SDL_enabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
+#else
+# error Unknown assertion level.
+#endif
+
+/**
+ * An assertion test that is always performed.
+ *
+ * This macro is always enabled no matter what SDL_ASSERT_LEVEL is set to. You
+ * almost never want to use this, as it could trigger on an end-user's system,
+ * crashing your program.
+ *
+ * One can set the environment variable "SDL_ASSERT" to one of several strings
+ * ("abort", "break", "retry", "ignore", "always_ignore") to force a default
+ * behavior, which may be desirable for automation purposes. If your platform
+ * requires GUI interfaces to happen on the main thread but you're debugging
+ * an assertion in a background thread, it might be desirable to set this to
+ * "break" so that your debugger takes control as soon as assert is triggered,
+ * instead of risking a bad UI interaction (deadlock, etc) in the application.
+ *
+ * \param condition boolean value to test.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_assert_always(condition) SDL_enabled_assert(condition)
+
+
+/**
+ * A callback that fires when an SDL assertion fails.
+ *
+ * \param data a pointer to the SDL_AssertData structure corresponding to the
+ * current assertion.
+ * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler().
+ * \returns an SDL_AssertState value indicating how to handle the failure.
+ *
+ * \threadsafety This callback may be called from any thread that triggers an
+ * assert at any time.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
+ const SDL_AssertData *data, void *userdata);
+
+/**
+ * Set an application-defined assertion handler.
+ *
+ * This function allows an application to show its own assertion UI and/or
+ * force the response to an assertion failure. If the application doesn't
+ * provide this, SDL will try to do the right thing, popping up a
+ * system-specific GUI dialog, and probably minimizing any fullscreen windows.
+ *
+ * This callback may fire from any thread, but it runs wrapped in a mutex, so
+ * it will only fire from one thread at a time.
+ *
+ * This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
+ *
+ * \param handler the SDL_AssertionHandler function to call when an assertion
+ * fails or NULL for the default handler.
+ * \param userdata a pointer that is passed to `handler`.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAssertionHandler
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetAssertionHandler(
+ SDL_AssertionHandler handler,
+ void *userdata);
+
+/**
+ * Get the default assertion handler.
+ *
+ * This returns the function pointer that is called by default when an
+ * assertion is triggered. This is an internal function provided by SDL, that
+ * is used for assertions when SDL_SetAssertionHandler() hasn't been used to
+ * provide a different function.
+ *
+ * \returns the default SDL_AssertionHandler that is called when an assert
+ * triggers.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAssertionHandler
+ */
+extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void);
+
+/**
+ * Get the current assertion handler.
+ *
+ * This returns the function pointer that is called when an assertion is
+ * triggered. This is either the value last passed to
+ * SDL_SetAssertionHandler(), or if no application-specified function is set,
+ * is equivalent to calling SDL_GetDefaultAssertionHandler().
+ *
+ * The parameter `puserdata` is a pointer to a void*, which will store the
+ * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value
+ * will always be NULL for the default handler. If you don't care about this
+ * data, it is safe to pass a NULL pointer to this function to ignore it.
+ *
+ * \param puserdata pointer which is filled with the "userdata" pointer that
+ * was passed to SDL_SetAssertionHandler().
+ * \returns the SDL_AssertionHandler that is called when an assert triggers.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAssertionHandler
+ */
+extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata);
+
+/**
+ * Get a list of all assertion failures.
+ *
+ * This function gets all assertions triggered since the last call to
+ * SDL_ResetAssertionReport(), or the start of the program.
+ *
+ * The proper way to examine this data looks something like this:
+ *
+ * ```c
+ * const SDL_AssertData *item = SDL_GetAssertionReport();
+ * while (item) {
+ * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n",
+ * item->condition, item->function, item->filename,
+ * item->linenum, item->trigger_count,
+ * item->always_ignore ? "yes" : "no");
+ * item = item->next;
+ * }
+ * ```
+ *
+ * \returns a list of all failed assertions or NULL if the list is empty. This
+ * memory should not be modified or freed by the application. This
+ * pointer remains valid until the next call to SDL_Quit() or
+ * SDL_ResetAssertionReport().
+ *
+ * \threadsafety This function is not thread safe. Other threads calling
+ * SDL_ResetAssertionReport() simultaneously, may render the
+ * returned pointer invalid.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ResetAssertionReport
+ */
+extern SDL_DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
+
+/**
+ * Clear the list of all assertion failures.
+ *
+ * This function will clear the list of all assertions triggered up to that
+ * point. Immediately following this call, SDL_GetAssertionReport will return
+ * no items. In addition, any previously-triggered assertions will be reset to
+ * a trigger_count of zero, and their always_ignore state will be false.
+ *
+ * \threadsafety This function is not thread safe. Other threads triggering an
+ * assertion, or simultaneously calling this function may cause
+ * memory leaks or crashes.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAssertionReport
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_assert_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_asyncio.h b/vendored/SDL/include/SDL3/SDL_asyncio.h
new file mode 100644
index 0000000..b36cb07
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_asyncio.h
@@ -0,0 +1,546 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: AsyncIO */
+
+/**
+ * # CategoryAsyncIO
+ *
+ * SDL offers a way to perform I/O asynchronously. This allows an app to read
+ * or write files without waiting for data to actually transfer; the functions
+ * that request I/O never block while the request is fulfilled.
+ *
+ * Instead, the data moves in the background and the app can check for results
+ * at their leisure.
+ *
+ * This is more complicated than just reading and writing files in a
+ * synchronous way, but it can allow for more efficiency, and never having
+ * framerate drops as the hard drive catches up, etc.
+ *
+ * The general usage pattern for async I/O is:
+ *
+ * - Create one or more SDL_AsyncIOQueue objects.
+ * - Open files with SDL_AsyncIOFromFile.
+ * - Start I/O tasks to the files with SDL_ReadAsyncIO or SDL_WriteAsyncIO,
+ * putting those tasks into one of the queues.
+ * - Later on, use SDL_GetAsyncIOResult on a queue to see if any task is
+ * finished without blocking. Tasks might finish in any order with success
+ * or failure.
+ * - When all your tasks are done, close the file with SDL_CloseAsyncIO. This
+ * also generates a task, since it might flush data to disk!
+ *
+ * This all works, without blocking, in a single thread, but one can also wait
+ * on a queue in a background thread, sleeping until new results have arrived:
+ *
+ * - Call SDL_WaitAsyncIOResult from one or more threads to efficiently block
+ * until new tasks complete.
+ * - When shutting down, call SDL_SignalAsyncIOQueue to unblock any sleeping
+ * threads despite there being no new tasks completed.
+ *
+ * And, of course, to match the synchronous SDL_LoadFile, we offer
+ * SDL_LoadFileAsync as a convenience function. This will handle allocating a
+ * buffer, slurping in the file data, and null-terminating it; you still check
+ * for results later.
+ *
+ * Behind the scenes, SDL will use newer, efficient APIs on platforms that
+ * support them: Linux's io_uring and Windows 11's IoRing, for example. If
+ * those technologies aren't available, SDL will offload the work to a thread
+ * pool that will manage otherwise-synchronous loads without blocking the app.
+ *
+ * ## Best Practices
+ *
+ * Simple non-blocking I/O--for an app that just wants to pick up data
+ * whenever it's ready without losing framerate waiting on disks to spin--can
+ * use whatever pattern works well for the program. In this case, simply call
+ * SDL_ReadAsyncIO, or maybe SDL_LoadFileAsync, as needed. Once a frame, call
+ * SDL_GetAsyncIOResult to check for any completed tasks and deal with the
+ * data as it arrives.
+ *
+ * If two separate pieces of the same program need their own I/O, it is legal
+ * for each to create their own queue. This will prevent either piece from
+ * accidentally consuming the other's completed tasks. Each queue does require
+ * some amount of resources, but it is not an overwhelming cost. Do not make a
+ * queue for each task, however. It is better to put many tasks into a single
+ * queue. They will be reported in order of completion, not in the order they
+ * were submitted, so it doesn't generally matter what order tasks are
+ * started.
+ *
+ * One async I/O queue can be shared by multiple threads, or one thread can
+ * have more than one queue, but the most efficient way--if ruthless
+ * efficiency is the goal--is to have one queue per thread, with multiple
+ * threads working in parallel, and attempt to keep each queue loaded with
+ * tasks that are both started by and consumed by the same thread. On modern
+ * platforms that can use newer interfaces, this can keep data flowing as
+ * efficiently as possible all the way from storage hardware to the app, with
+ * no contention between threads for access to the same queue.
+ *
+ * Written data is not guaranteed to make it to physical media by the time a
+ * closing task is completed, unless SDL_CloseAsyncIO is called with its
+ * `flush` parameter set to true, which is to say that a successful result
+ * here can still result in lost data during an unfortunately-timed power
+ * outage if not flushed. However, flushing will take longer and may be
+ * unnecessary, depending on the app's needs.
+ */
+
+#ifndef SDL_asyncio_h_
+#define SDL_asyncio_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The asynchronous I/O operation structure.
+ *
+ * This operates as an opaque handle. One can then request read or write
+ * operations on it.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_AsyncIOFromFile
+ */
+typedef struct SDL_AsyncIO SDL_AsyncIO;
+
+/**
+ * Types of asynchronous I/O tasks.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_AsyncIOTaskType
+{
+ SDL_ASYNCIO_TASK_READ, /**< A read operation. */
+ SDL_ASYNCIO_TASK_WRITE, /**< A write operation. */
+ SDL_ASYNCIO_TASK_CLOSE /**< A close operation. */
+} SDL_AsyncIOTaskType;
+
+/**
+ * Possible outcomes of an asynchronous I/O task.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_AsyncIOResult
+{
+ SDL_ASYNCIO_COMPLETE, /**< request was completed without error */
+ SDL_ASYNCIO_FAILURE, /**< request failed for some reason; check SDL_GetError()! */
+ SDL_ASYNCIO_CANCELED /**< request was canceled before completing. */
+} SDL_AsyncIOResult;
+
+/**
+ * Information about a completed asynchronous I/O request.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_AsyncIOOutcome
+{
+ SDL_AsyncIO *asyncio; /**< what generated this task. This pointer will be invalid if it was closed! */
+ SDL_AsyncIOTaskType type; /**< What sort of task was this? Read, write, etc? */
+ SDL_AsyncIOResult result; /**< the result of the work (success, failure, cancellation). */
+ void *buffer; /**< buffer where data was read/written. */
+ Uint64 offset; /**< offset in the SDL_AsyncIO where data was read/written. */
+ Uint64 bytes_requested; /**< number of bytes the task was to read/write. */
+ Uint64 bytes_transferred; /**< actual number of bytes that were read/written. */
+ void *userdata; /**< pointer provided by the app when starting the task */
+} SDL_AsyncIOOutcome;
+
+/**
+ * A queue of completed asynchronous I/O tasks.
+ *
+ * When starting an asynchronous operation, you specify a queue for the new
+ * task. A queue can be asked later if any tasks in it have completed,
+ * allowing an app to manage multiple pending tasks in one place, in whatever
+ * order they complete.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateAsyncIOQueue
+ * \sa SDL_ReadAsyncIO
+ * \sa SDL_WriteAsyncIO
+ * \sa SDL_GetAsyncIOResult
+ * \sa SDL_WaitAsyncIOResult
+ */
+typedef struct SDL_AsyncIOQueue SDL_AsyncIOQueue;
+
+/**
+ * Use this function to create a new SDL_AsyncIO object for reading from
+ * and/or writing to a named file.
+ *
+ * The `mode` string understands the following values:
+ *
+ * - "r": Open a file for reading only. It must exist.
+ * - "w": Open a file for writing only. It will create missing files or
+ * truncate existing ones.
+ * - "r+": Open a file for update both reading and writing. The file must
+ * exist.
+ * - "w+": Create an empty file for both reading and writing. If a file with
+ * the same name already exists its content is erased and the file is
+ * treated as a new empty file.
+ *
+ * There is no "b" mode, as there is only "binary" style I/O, and no "a" mode
+ * for appending, since you specify the position when starting a task.
+ *
+ * This function supports Unicode filenames, but they must be encoded in UTF-8
+ * format, regardless of the underlying operating system.
+ *
+ * This call is _not_ asynchronous; it will open the file before returning,
+ * under the assumption that doing so is generally a fast operation. Future
+ * reads and writes to the opened file will be async, however.
+ *
+ * \param file a UTF-8 string representing the filename to open.
+ * \param mode an ASCII string representing the mode to be used for opening
+ * the file.
+ * \returns a pointer to the SDL_AsyncIO structure that is created or NULL on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseAsyncIO
+ * \sa SDL_ReadAsyncIO
+ * \sa SDL_WriteAsyncIO
+ */
+extern SDL_DECLSPEC SDL_AsyncIO * SDLCALL SDL_AsyncIOFromFile(const char *file, const char *mode);
+
+/**
+ * Use this function to get the size of the data stream in an SDL_AsyncIO.
+ *
+ * This call is _not_ asynchronous; it assumes that obtaining this info is a
+ * non-blocking operation in most reasonable cases.
+ *
+ * \param asyncio the SDL_AsyncIO to get the size of the data stream from.
+ * \returns the size of the data stream in the SDL_IOStream on success or a
+ * negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC Sint64 SDLCALL SDL_GetAsyncIOSize(SDL_AsyncIO *asyncio);
+
+/**
+ * Start an async read.
+ *
+ * This function reads up to `size` bytes from `offset` position in the data
+ * source to the area pointed at by `ptr`. This function may read less bytes
+ * than requested.
+ *
+ * This function returns as quickly as possible; it does not wait for the read
+ * to complete. On a successful return, this work will continue in the
+ * background. If the work begins, even failure is asynchronous: a failing
+ * return value from this function only means the work couldn't start at all.
+ *
+ * `ptr` must remain available until the work is done, and may be accessed by
+ * the system at any time until then. Do not allocate it on the stack, as this
+ * might take longer than the life of the calling function to complete!
+ *
+ * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
+ * to it when it completes its work.
+ *
+ * \param asyncio a pointer to an SDL_AsyncIO structure.
+ * \param ptr a pointer to a buffer to read data into.
+ * \param offset the position to start reading in the data source.
+ * \param size the number of bytes to read from the data source.
+ * \param queue a queue to add the new SDL_AsyncIO to.
+ * \param userdata an app-defined pointer that will be provided with the task
+ * results.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WriteAsyncIO
+ * \sa SDL_CreateAsyncIOQueue
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ReadAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
+
+/**
+ * Start an async write.
+ *
+ * This function writes `size` bytes from `offset` position in the data source
+ * to the area pointed at by `ptr`.
+ *
+ * This function returns as quickly as possible; it does not wait for the
+ * write to complete. On a successful return, this work will continue in the
+ * background. If the work begins, even failure is asynchronous: a failing
+ * return value from this function only means the work couldn't start at all.
+ *
+ * `ptr` must remain available until the work is done, and may be accessed by
+ * the system at any time until then. Do not allocate it on the stack, as this
+ * might take longer than the life of the calling function to complete!
+ *
+ * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
+ * to it when it completes its work.
+ *
+ * \param asyncio a pointer to an SDL_AsyncIO structure.
+ * \param ptr a pointer to a buffer to write data from.
+ * \param offset the position to start writing to the data source.
+ * \param size the number of bytes to write to the data source.
+ * \param queue a queue to add the new SDL_AsyncIO to.
+ * \param userdata an app-defined pointer that will be provided with the task
+ * results.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ReadAsyncIO
+ * \sa SDL_CreateAsyncIOQueue
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WriteAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
+
+/**
+ * Close and free any allocated resources for an async I/O object.
+ *
+ * Closing a file is _also_ an asynchronous task! If a write failure were to
+ * happen during the closing process, for example, the task results will
+ * report it as usual.
+ *
+ * Closing a file that has been written to does not guarantee the data has
+ * made it to physical media; it may remain in the operating system's file
+ * cache, for later writing to disk. This means that a successfully-closed
+ * file can be lost if the system crashes or loses power in this small window.
+ * To prevent this, call this function with the `flush` parameter set to true.
+ * This will make the operation take longer, and perhaps increase system load
+ * in general, but a successful result guarantees that the data has made it to
+ * physical storage. Don't use this for temporary files, caches, and
+ * unimportant data, and definitely use it for crucial irreplaceable files,
+ * like game saves.
+ *
+ * This function guarantees that the close will happen after any other pending
+ * tasks to `asyncio`, so it's safe to open a file, start several operations,
+ * close the file immediately, then check for all results later. This function
+ * will not block until the tasks have completed.
+ *
+ * Once this function returns true, `asyncio` is no longer valid, regardless
+ * of any future outcomes. Any completed tasks might still contain this
+ * pointer in their SDL_AsyncIOOutcome data, in case the app was using this
+ * value to track information, but it should not be used again.
+ *
+ * If this function returns false, the close wasn't started at all, and it's
+ * safe to attempt to close again later.
+ *
+ * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
+ * to it when it completes its work.
+ *
+ * \param asyncio a pointer to an SDL_AsyncIO structure to close.
+ * \param flush true if data should sync to disk before the task completes.
+ * \param queue a queue to add the new SDL_AsyncIO to.
+ * \param userdata an app-defined pointer that will be provided with the task
+ * results.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, but two
+ * threads should not attempt to close the same object.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CloseAsyncIO(SDL_AsyncIO *asyncio, bool flush, SDL_AsyncIOQueue *queue, void *userdata);
+
+/**
+ * Create a task queue for tracking multiple I/O operations.
+ *
+ * Async I/O operations are assigned to a queue when started. The queue can be
+ * checked for completed tasks thereafter.
+ *
+ * \returns a new task queue object or NULL if there was an error; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_DestroyAsyncIOQueue
+ * \sa SDL_GetAsyncIOResult
+ * \sa SDL_WaitAsyncIOResult
+ */
+extern SDL_DECLSPEC SDL_AsyncIOQueue * SDLCALL SDL_CreateAsyncIOQueue(void);
+
+/**
+ * Destroy a previously-created async I/O task queue.
+ *
+ * If there are still tasks pending for this queue, this call will block until
+ * those tasks are finished. All those tasks will be deallocated. Their
+ * results will be lost to the app.
+ *
+ * Any pending reads from SDL_LoadFileAsync() that are still in this queue
+ * will have their buffers deallocated by this function, to prevent a memory
+ * leak.
+ *
+ * Once this function is called, the queue is no longer valid and should not
+ * be used, including by other threads that might access it while destruction
+ * is blocking on pending tasks.
+ *
+ * Do not destroy a queue that still has threads waiting on it through
+ * SDL_WaitAsyncIOResult(). You can call SDL_SignalAsyncIOQueue() first to
+ * unblock those threads, and take measures (such as SDL_WaitThread()) to make
+ * sure they have finished their wait and won't wait on the queue again.
+ *
+ * \param queue the task queue to destroy.
+ *
+ * \threadsafety It is safe to call this function from any thread, so long as
+ * no other thread is waiting on the queue with
+ * SDL_WaitAsyncIOResult.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DestroyAsyncIOQueue(SDL_AsyncIOQueue *queue);
+
+/**
+ * Query an async I/O task queue for completed tasks.
+ *
+ * If a task assigned to this queue has finished, this will return true and
+ * fill in `outcome` with the details of the task. If no task in the queue has
+ * finished, this function will return false. This function does not block.
+ *
+ * If a task has completed, this function will free its resources and the task
+ * pointer will no longer be valid. The task will be removed from the queue.
+ *
+ * It is safe for multiple threads to call this function on the same queue at
+ * once; a completed task will only go to one of the threads.
+ *
+ * \param queue the async I/O task queue to query.
+ * \param outcome details of a finished task will be written here. May not be
+ * NULL.
+ * \returns true if a task has completed, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WaitAsyncIOResult
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome);
+
+/**
+ * Block until an async I/O task queue has a completed task.
+ *
+ * This function puts the calling thread to sleep until there a task assigned
+ * to the queue that has finished.
+ *
+ * If a task assigned to the queue has finished, this will return true and
+ * fill in `outcome` with the details of the task. If no task in the queue has
+ * finished, this function will return false.
+ *
+ * If a task has completed, this function will free its resources and the task
+ * pointer will no longer be valid. The task will be removed from the queue.
+ *
+ * It is safe for multiple threads to call this function on the same queue at
+ * once; a completed task will only go to one of the threads.
+ *
+ * Note that by the nature of various platforms, more than one waiting thread
+ * may wake to handle a single task, but only one will obtain it, so
+ * `timeoutMS` is a _maximum_ wait time, and this function may return false
+ * sooner.
+ *
+ * This function may return false if there was a system error, the OS
+ * inadvertently awoke multiple threads, or if SDL_SignalAsyncIOQueue() was
+ * called to wake up all waiting threads without a finished task.
+ *
+ * A timeout can be used to specify a maximum wait time, but rather than
+ * polling, it is possible to have a timeout of -1 to wait forever, and use
+ * SDL_SignalAsyncIOQueue() to wake up the waiting threads later.
+ *
+ * \param queue the async I/O task queue to wait on.
+ * \param outcome details of a finished task will be written here. May not be
+ * NULL.
+ * \param timeoutMS the maximum time to wait, in milliseconds, or -1 to wait
+ * indefinitely.
+ * \returns true if task has completed, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SignalAsyncIOQueue
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome, Sint32 timeoutMS);
+
+/**
+ * Wake up any threads that are blocking in SDL_WaitAsyncIOResult().
+ *
+ * This will unblock any threads that are sleeping in a call to
+ * SDL_WaitAsyncIOResult for the specified queue, and cause them to return
+ * from that function.
+ *
+ * This can be useful when destroying a queue to make sure nothing is touching
+ * it indefinitely. In this case, once this call completes, the caller should
+ * take measures to make sure any previously-blocked threads have returned
+ * from their wait and will not touch the queue again (perhaps by setting a
+ * flag to tell the threads to terminate and then using SDL_WaitThread() to
+ * make sure they've done so).
+ *
+ * \param queue the async I/O task queue to signal.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WaitAsyncIOResult
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SignalAsyncIOQueue(SDL_AsyncIOQueue *queue);
+
+/**
+ * Load all the data from a file path, asynchronously.
+ *
+ * This function returns as quickly as possible; it does not wait for the read
+ * to complete. On a successful return, this work will continue in the
+ * background. If the work begins, even failure is asynchronous: a failing
+ * return value from this function only means the work couldn't start at all.
+ *
+ * The data is allocated with a zero byte at the end (null terminated) for
+ * convenience. This extra byte is not included in SDL_AsyncIOOutcome's
+ * bytes_transferred value.
+ *
+ * This function will allocate the buffer to contain the file. It must be
+ * deallocated by calling SDL_free() on SDL_AsyncIOOutcome's buffer field
+ * after completion.
+ *
+ * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
+ * to it when it completes its work.
+ *
+ * \param file the path to read all available data from.
+ * \param queue a queue to add the new SDL_AsyncIO to.
+ * \param userdata an app-defined pointer that will be provided with the task
+ * results.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_LoadFile_IO
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_LoadFileAsync(const char *file, SDL_AsyncIOQueue *queue, void *userdata);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_asyncio_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_atomic.h b/vendored/SDL/include/SDL3/SDL_atomic.h
new file mode 100644
index 0000000..78b5e0f
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_atomic.h
@@ -0,0 +1,664 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryAtomic
+ *
+ * Atomic operations.
+ *
+ * IMPORTANT: If you are not an expert in concurrent lockless programming, you
+ * should not be using any functions in this file. You should be protecting
+ * your data structures with full mutexes instead.
+ *
+ * ***Seriously, here be dragons!***
+ *
+ * You can find out a little more about lockless programming and the subtle
+ * issues that can arise here:
+ * https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
+ *
+ * There's also lots of good information here:
+ *
+ * - https://www.1024cores.net/home/lock-free-algorithms
+ * - https://preshing.com/
+ *
+ * These operations may or may not actually be implemented using processor
+ * specific atomic operations. When possible they are implemented as true
+ * processor specific atomic operations. When that is not possible the are
+ * implemented using locks that *do* use the available atomic operations.
+ *
+ * All of the atomic operations that modify memory are full memory barriers.
+ */
+
+#ifndef SDL_atomic_h_
+#define SDL_atomic_h_
+
+#include
+#include
+
+#include
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An atomic spinlock.
+ *
+ * The atomic locks are efficient spinlocks using CPU instructions, but are
+ * vulnerable to starvation and can spin forever if a thread holding a lock
+ * has been terminated. For this reason you should minimize the code executed
+ * inside an atomic lock and never do expensive things like API or system
+ * calls while holding them.
+ *
+ * They are also vulnerable to starvation if the thread holding the lock is
+ * lower priority than other threads and doesn't get scheduled. In general you
+ * should use mutexes instead, since they have better performance and
+ * contention behavior.
+ *
+ * The atomic locks are not safe to lock recursively.
+ *
+ * Porting Note: The spin lock functions and type are required and can not be
+ * emulated because they are used in the atomic emulation code.
+ */
+typedef int SDL_SpinLock;
+
+/**
+ * Try to lock a spin lock by setting it to a non-zero value.
+ *
+ * ***Please note that spinlocks are dangerous if you don't know what you're
+ * doing. Please be careful using any sort of spinlock!***
+ *
+ * \param lock a pointer to a lock variable.
+ * \returns true if the lock succeeded, false if the lock is already held.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_LockSpinlock
+ * \sa SDL_UnlockSpinlock
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_TryLockSpinlock(SDL_SpinLock *lock);
+
+/**
+ * Lock a spin lock by setting it to a non-zero value.
+ *
+ * ***Please note that spinlocks are dangerous if you don't know what you're
+ * doing. Please be careful using any sort of spinlock!***
+ *
+ * \param lock a pointer to a lock variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_TryLockSpinlock
+ * \sa SDL_UnlockSpinlock
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_LockSpinlock(SDL_SpinLock *lock);
+
+/**
+ * Unlock a spin lock by setting it to 0.
+ *
+ * Always returns immediately.
+ *
+ * ***Please note that spinlocks are dangerous if you don't know what you're
+ * doing. Please be careful using any sort of spinlock!***
+ *
+ * \param lock a pointer to a lock variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_LockSpinlock
+ * \sa SDL_TryLockSpinlock
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UnlockSpinlock(SDL_SpinLock *lock);
+
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * Mark a compiler barrier.
+ *
+ * A compiler barrier prevents the compiler from reordering reads and writes
+ * to globally visible variables across the call.
+ *
+ * This macro only prevents the compiler from reordering reads and writes, it
+ * does not prevent the CPU from reordering reads and writes. However, all of
+ * the atomic operations that modify memory are full memory barriers.
+ *
+ * \threadsafety Obviously this macro is safe to use from any thread at any
+ * time, but if you find yourself needing this, you are probably
+ * dealing with some very sensitive code; be careful!
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_CompilerBarrier() DoCompilerSpecificReadWriteBarrier()
+
+#elif defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__)
+void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#define SDL_CompilerBarrier() _ReadWriteBarrier()
+#elif (defined(__GNUC__) && !defined(SDL_PLATFORM_EMSCRIPTEN)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
+/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
+#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
+#elif defined(__WATCOMC__)
+extern __inline void SDL_CompilerBarrier(void);
+#pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
+#else
+#define SDL_CompilerBarrier() \
+{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }
+#endif
+
+/**
+ * Insert a memory release barrier (function version).
+ *
+ * Please refer to SDL_MemoryBarrierRelease for details. This is a function
+ * version, which might be useful if you need to use this functionality from a
+ * scripting language, etc. Also, some of the macro versions call this
+ * function behind the scenes, where more heavy lifting can happen inside of
+ * SDL. Generally, though, an app written in C/C++/etc should use the macro
+ * version, as it will be more efficient.
+ *
+ * \threadsafety Obviously this function is safe to use from any thread at any
+ * time, but if you find yourself needing this, you are probably
+ * dealing with some very sensitive code; be careful!
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_MemoryBarrierRelease
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void);
+
+/**
+ * Insert a memory acquire barrier (function version).
+ *
+ * Please refer to SDL_MemoryBarrierRelease for details. This is a function
+ * version, which might be useful if you need to use this functionality from a
+ * scripting language, etc. Also, some of the macro versions call this
+ * function behind the scenes, where more heavy lifting can happen inside of
+ * SDL. Generally, though, an app written in C/C++/etc should use the macro
+ * version, as it will be more efficient.
+ *
+ * \threadsafety Obviously this function is safe to use from any thread at any
+ * time, but if you find yourself needing this, you are probably
+ * dealing with some very sensitive code; be careful!
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_MemoryBarrierAcquire
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
+
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * Insert a memory release barrier (macro version).
+ *
+ * Memory barriers are designed to prevent reads and writes from being
+ * reordered by the compiler and being seen out of order on multi-core CPUs.
+ *
+ * A typical pattern would be for thread A to write some data and a flag, and
+ * for thread B to read the flag and get the data. In this case you would
+ * insert a release barrier between writing the data and the flag,
+ * guaranteeing that the data write completes no later than the flag is
+ * written, and you would insert an acquire barrier between reading the flag
+ * and reading the data, to ensure that all the reads associated with the flag
+ * have completed.
+ *
+ * In this pattern you should always see a release barrier paired with an
+ * acquire barrier and you should gate the data reads/writes with a single
+ * flag variable.
+ *
+ * For more information on these semantics, take a look at the blog post:
+ * http://preshing.com/20120913/acquire-and-release-semantics
+ *
+ * This is the macro version of this functionality; if possible, SDL will use
+ * compiler intrinsics or inline assembly, but some platforms might need to
+ * call the function version of this, SDL_MemoryBarrierReleaseFunction to do
+ * the heavy lifting. Apps that can use the macro should favor it over the
+ * function.
+ *
+ * \threadsafety Obviously this macro is safe to use from any thread at any
+ * time, but if you find yourself needing this, you are probably
+ * dealing with some very sensitive code; be careful!
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_MemoryBarrierAcquire
+ * \sa SDL_MemoryBarrierReleaseFunction
+ */
+#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
+
+/**
+ * Insert a memory acquire barrier (macro version).
+ *
+ * Please see SDL_MemoryBarrierRelease for the details on what memory barriers
+ * are and when to use them.
+ *
+ * This is the macro version of this functionality; if possible, SDL will use
+ * compiler intrinsics or inline assembly, but some platforms might need to
+ * call the function version of this, SDL_MemoryBarrierAcquireFunction, to do
+ * the heavy lifting. Apps that can use the macro should favor it over the
+ * function.
+ *
+ * \threadsafety Obviously this macro is safe to use from any thread at any
+ * time, but if you find yourself needing this, you are probably
+ * dealing with some very sensitive code; be careful!
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_MemoryBarrierRelease
+ * \sa SDL_MemoryBarrierAcquireFunction
+ */
+#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
+
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__aarch64__)
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#elif defined(__GNUC__) && defined(__arm__)
+#if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */
+/* Information from:
+ https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
+
+ The Linux kernel provides a helper function which provides the right code for a memory barrier,
+ hard-coded at address 0xffff0fa0
+*/
+typedef void (*SDL_KernelMemoryBarrierFunc)();
+#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
+#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
+#else
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__)
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
+#ifdef __thumb__
+/* The mcr instruction isn't available in thumb mode, use real functions */
+#define SDL_MEMORY_BARRIER_USES_FUNCTION
+#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
+#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
+#else
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#endif /* __thumb__ */
+#else
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
+#endif /* SDL_PLATFORM_LINUX || SDL_PLATFORM_ANDROID */
+#endif /* __GNUC__ && __arm__ */
+#else
+#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
+/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
+#include
+#define SDL_MemoryBarrierRelease() __machine_rel_barrier()
+#define SDL_MemoryBarrierAcquire() __machine_acq_barrier()
+#else
+/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
+#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
+#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
+#endif
+#endif
+
+/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro to insert a CPU-specific "pause" instruction into the program.
+ *
+ * This can be useful in busy-wait loops, as it serves as a hint to the CPU as
+ * to the program's intent; some CPUs can use this to do more efficient
+ * processing. On some platforms, this doesn't do anything, so using this
+ * macro might just be a harmless no-op.
+ *
+ * Note that if you are busy-waiting, there are often more-efficient
+ * approaches with other synchronization primitives: mutexes, semaphores,
+ * condition variables, etc.
+ *
+ * \threadsafety This macro is safe to use from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_CPUPauseInstruction() DoACPUPauseInACompilerAndArchitectureSpecificWay
+
+#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
+ #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
+#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__)
+ #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
+#elif (defined(__powerpc__) || defined(__powerpc64__))
+ #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
+#elif (defined(__riscv) && __riscv_xlen == 64)
+ #define SDL_CPUPauseInstruction() __asm__ __volatile__(".insn i 0x0F, 0, x0, x0, 0x010");
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+ #define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
+#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
+ #define SDL_CPUPauseInstruction() __yield()
+#elif defined(__WATCOMC__) && defined(__386__)
+ extern __inline void SDL_CPUPauseInstruction(void);
+ #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
+#else
+ #define SDL_CPUPauseInstruction()
+#endif
+
+
+/**
+ * A type representing an atomic integer value.
+ *
+ * This can be used to manage a value that is synchronized across multiple
+ * CPUs without a race condition; when an app sets a value with
+ * SDL_SetAtomicInt all other threads, regardless of the CPU it is running on,
+ * will see that value when retrieved with SDL_GetAtomicInt, regardless of CPU
+ * caches, etc.
+ *
+ * This is also useful for atomic compare-and-swap operations: a thread can
+ * change the value as long as its current value matches expectations. When
+ * done in a loop, one can guarantee data consistency across threads without a
+ * lock (but the usual warnings apply: if you don't know what you're doing, or
+ * you don't do it carefully, you can confidently cause any number of
+ * disasters with this, so in most cases, you _should_ use a mutex instead of
+ * this!).
+ *
+ * This is a struct so people don't accidentally use numeric operations on it
+ * directly. You have to use SDL atomic functions.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CompareAndSwapAtomicInt
+ * \sa SDL_GetAtomicInt
+ * \sa SDL_SetAtomicInt
+ * \sa SDL_AddAtomicInt
+ */
+typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt;
+
+/**
+ * Set an atomic variable to a new value if it is currently an old value.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt variable to be modified.
+ * \param oldval the old value.
+ * \param newval the new value.
+ * \returns true if the atomic variable was set, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAtomicInt
+ * \sa SDL_SetAtomicInt
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval);
+
+/**
+ * Set an atomic variable to a value.
+ *
+ * This function also acts as a full memory barrier.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt variable to be modified.
+ * \param v the desired value.
+ * \returns the previous value of the atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAtomicInt
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v);
+
+/**
+ * Get the value of an atomic variable.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt variable.
+ * \returns the current value of an atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAtomicInt
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a);
+
+/**
+ * Add to an atomic variable.
+ *
+ * This function also acts as a full memory barrier.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt variable to be modified.
+ * \param v the desired value to add.
+ * \returns the previous value of the atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AtomicDecRef
+ * \sa SDL_AtomicIncRef
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v);
+
+#ifndef SDL_AtomicIncRef
+
+/**
+ * Increment an atomic variable used as a reference count.
+ *
+ * ***Note: If you don't know what this macro is for, you shouldn't use it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt to increment.
+ * \returns the previous value of the atomic variable.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_AtomicDecRef
+ */
+#define SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1)
+#endif
+
+#ifndef SDL_AtomicDecRef
+
+/**
+ * Decrement an atomic variable used as a reference count.
+ *
+ * ***Note: If you don't know what this macro is for, you shouldn't use it!***
+ *
+ * \param a a pointer to an SDL_AtomicInt to decrement.
+ * \returns true if the variable reached zero after decrementing, false
+ * otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_AtomicIncRef
+ */
+#define SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1)
+#endif
+
+/**
+ * A type representing an atomic unsigned 32-bit value.
+ *
+ * This can be used to manage a value that is synchronized across multiple
+ * CPUs without a race condition; when an app sets a value with
+ * SDL_SetAtomicU32 all other threads, regardless of the CPU it is running on,
+ * will see that value when retrieved with SDL_GetAtomicU32, regardless of CPU
+ * caches, etc.
+ *
+ * This is also useful for atomic compare-and-swap operations: a thread can
+ * change the value as long as its current value matches expectations. When
+ * done in a loop, one can guarantee data consistency across threads without a
+ * lock (but the usual warnings apply: if you don't know what you're doing, or
+ * you don't do it carefully, you can confidently cause any number of
+ * disasters with this, so in most cases, you _should_ use a mutex instead of
+ * this!).
+ *
+ * This is a struct so people don't accidentally use numeric operations on it
+ * directly. You have to use SDL atomic functions.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CompareAndSwapAtomicU32
+ * \sa SDL_GetAtomicU32
+ * \sa SDL_SetAtomicU32
+ */
+typedef struct SDL_AtomicU32 { Uint32 value; } SDL_AtomicU32;
+
+/**
+ * Set an atomic variable to a new value if it is currently an old value.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicU32 variable to be modified.
+ * \param oldval the old value.
+ * \param newval the new value.
+ * \returns true if the atomic variable was set, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAtomicU32
+ * \sa SDL_SetAtomicU32
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval);
+
+/**
+ * Set an atomic variable to a value.
+ *
+ * This function also acts as a full memory barrier.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicU32 variable to be modified.
+ * \param v the desired value.
+ * \returns the previous value of the atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAtomicU32
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
+
+/**
+ * Get the value of an atomic variable.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicU32 variable.
+ * \returns the current value of an atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAtomicU32
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a);
+
+/**
+ * Set a pointer to a new value if it is currently an old value.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to a pointer.
+ * \param oldval the old pointer value.
+ * \param newval the new pointer value.
+ * \returns true if the pointer was set, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CompareAndSwapAtomicInt
+ * \sa SDL_GetAtomicPointer
+ * \sa SDL_SetAtomicPointer
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval);
+
+/**
+ * Set a pointer to a value atomically.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to a pointer.
+ * \param v the desired pointer value.
+ * \returns the previous value of the pointer.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CompareAndSwapAtomicPointer
+ * \sa SDL_GetAtomicPointer
+ */
+extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v);
+
+/**
+ * Get the value of a pointer atomically.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to a pointer.
+ * \returns the current value of a pointer.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CompareAndSwapAtomicPointer
+ * \sa SDL_SetAtomicPointer
+ */
+extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointer(void **a);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+
+#include
+
+#endif /* SDL_atomic_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_audio.h b/vendored/SDL/include/SDL3/SDL_audio.h
new file mode 100644
index 0000000..c6acf88
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_audio.h
@@ -0,0 +1,2200 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryAudio
+ *
+ * Audio functionality for the SDL library.
+ *
+ * All audio in SDL3 revolves around SDL_AudioStream. Whether you want to play
+ * or record audio, convert it, stream it, buffer it, or mix it, you're going
+ * to be passing it through an audio stream.
+ *
+ * Audio streams are quite flexible; they can accept any amount of data at a
+ * time, in any supported format, and output it as needed in any other format,
+ * even if the data format changes on either side halfway through.
+ *
+ * An app opens an audio device and binds any number of audio streams to it,
+ * feeding more data to the streams as available. When the device needs more
+ * data, it will pull it from all bound streams and mix them together for
+ * playback.
+ *
+ * Audio streams can also use an app-provided callback to supply data
+ * on-demand, which maps pretty closely to the SDL2 audio model.
+ *
+ * SDL also provides a simple .WAV loader in SDL_LoadWAV (and SDL_LoadWAV_IO
+ * if you aren't reading from a file) as a basic means to load sound data into
+ * your program.
+ *
+ * ## Logical audio devices
+ *
+ * In SDL3, opening a physical device (like a SoundBlaster 16 Pro) gives you a
+ * logical device ID that you can bind audio streams to. In almost all cases,
+ * logical devices can be used anywhere in the API that a physical device is
+ * normally used. However, since each device opening generates a new logical
+ * device, different parts of the program (say, a VoIP library, or
+ * text-to-speech framework, or maybe some other sort of mixer on top of SDL)
+ * can have their own device opens that do not interfere with each other; each
+ * logical device will mix its separate audio down to a single buffer, fed to
+ * the physical device, behind the scenes. As many logical devices as you like
+ * can come and go; SDL will only have to open the physical device at the OS
+ * level once, and will manage all the logical devices on top of it
+ * internally.
+ *
+ * One other benefit of logical devices: if you don't open a specific physical
+ * device, instead opting for the default, SDL can automatically migrate those
+ * logical devices to different hardware as circumstances change: a user
+ * plugged in headphones? The system default changed? SDL can transparently
+ * migrate the logical devices to the correct physical device seamlessly and
+ * keep playing; the app doesn't even have to know it happened if it doesn't
+ * want to.
+ *
+ * ## Simplified audio
+ *
+ * As a simplified model for when a single source of audio is all that's
+ * needed, an app can use SDL_OpenAudioDeviceStream, which is a single
+ * function to open an audio device, create an audio stream, bind that stream
+ * to the newly-opened device, and (optionally) provide a callback for
+ * obtaining audio data. When using this function, the primary interface is
+ * the SDL_AudioStream and the device handle is mostly hidden away; destroying
+ * a stream created through this function will also close the device, stream
+ * bindings cannot be changed, etc. One other quirk of this is that the device
+ * is started in a _paused_ state and must be explicitly resumed; this is
+ * partially to offer a clean migration for SDL2 apps and partially because
+ * the app might have to do more setup before playback begins; in the
+ * non-simplified form, nothing will play until a stream is bound to a device,
+ * so they start _unpaused_.
+ *
+ * ## Channel layouts
+ *
+ * Audio data passing through SDL is uncompressed PCM data, interleaved. One
+ * can provide their own decompression through an MP3, etc, decoder, but SDL
+ * does not provide this directly. Each interleaved channel of data is meant
+ * to be in a specific order.
+ *
+ * Abbreviations:
+ *
+ * - FRONT = single mono speaker
+ * - FL = front left speaker
+ * - FR = front right speaker
+ * - FC = front center speaker
+ * - BL = back left speaker
+ * - BR = back right speaker
+ * - SR = surround right speaker
+ * - SL = surround left speaker
+ * - BC = back center speaker
+ * - LFE = low-frequency speaker
+ *
+ * These are listed in the order they are laid out in memory, so "FL, FR"
+ * means "the front left speaker is laid out in memory first, then the front
+ * right, then it repeats for the next audio frame".
+ *
+ * - 1 channel (mono) layout: FRONT
+ * - 2 channels (stereo) layout: FL, FR
+ * - 3 channels (2.1) layout: FL, FR, LFE
+ * - 4 channels (quad) layout: FL, FR, BL, BR
+ * - 5 channels (4.1) layout: FL, FR, LFE, BL, BR
+ * - 6 channels (5.1) layout: FL, FR, FC, LFE, BL, BR (last two can also be
+ * SL, SR)
+ * - 7 channels (6.1) layout: FL, FR, FC, LFE, BC, SL, SR
+ * - 8 channels (7.1) layout: FL, FR, FC, LFE, BL, BR, SL, SR
+ *
+ * This is the same order as DirectSound expects, but applied to all
+ * platforms; SDL will swizzle the channels as necessary if a platform expects
+ * something different.
+ *
+ * SDL_AudioStream can also be provided channel maps to change this ordering
+ * to whatever is necessary, in other audio processing scenarios.
+ */
+
+#ifndef SDL_audio_h_
+#define SDL_audio_h_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Mask of bits in an SDL_AudioFormat that contains the format bit size.
+ *
+ * Generally one should use SDL_AUDIO_BITSIZE instead of this macro directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_MASK_BITSIZE (0xFFu)
+
+/**
+ * Mask of bits in an SDL_AudioFormat that contain the floating point flag.
+ *
+ * Generally one should use SDL_AUDIO_ISFLOAT instead of this macro directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_MASK_FLOAT (1u<<8)
+
+/**
+ * Mask of bits in an SDL_AudioFormat that contain the bigendian flag.
+ *
+ * Generally one should use SDL_AUDIO_ISBIGENDIAN or SDL_AUDIO_ISLITTLEENDIAN
+ * instead of this macro directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_MASK_BIG_ENDIAN (1u<<12)
+
+/**
+ * Mask of bits in an SDL_AudioFormat that contain the signed data flag.
+ *
+ * Generally one should use SDL_AUDIO_ISSIGNED instead of this macro directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_MASK_SIGNED (1u<<15)
+
+/**
+ * Define an SDL_AudioFormat value.
+ *
+ * SDL does not support custom audio formats, so this macro is not of much use
+ * externally, but it can be illustrative as to what the various bits of an
+ * SDL_AudioFormat mean.
+ *
+ * For example, SDL_AUDIO_S32LE looks like this:
+ *
+ * ```c
+ * SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 32)
+ * ```
+ *
+ * \param signed 1 for signed data, 0 for unsigned data.
+ * \param bigendian 1 for bigendian data, 0 for littleendian data.
+ * \param flt 1 for floating point data, 0 for integer data.
+ * \param size number of bits per sample.
+ * \returns a format value in the style of SDL_AudioFormat.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_DEFINE_AUDIO_FORMAT(signed, bigendian, flt, size) \
+ (((Uint16)(signed) << 15) | ((Uint16)(bigendian) << 12) | ((Uint16)(flt) << 8) | ((size) & SDL_AUDIO_MASK_BITSIZE))
+
+/**
+ * Audio format.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_AUDIO_BITSIZE
+ * \sa SDL_AUDIO_BYTESIZE
+ * \sa SDL_AUDIO_ISINT
+ * \sa SDL_AUDIO_ISFLOAT
+ * \sa SDL_AUDIO_ISBIGENDIAN
+ * \sa SDL_AUDIO_ISLITTLEENDIAN
+ * \sa SDL_AUDIO_ISSIGNED
+ * \sa SDL_AUDIO_ISUNSIGNED
+ */
+typedef enum SDL_AudioFormat
+{
+ SDL_AUDIO_UNKNOWN = 0x0000u, /**< Unspecified audio format */
+ SDL_AUDIO_U8 = 0x0008u, /**< Unsigned 8-bit samples */
+ /* SDL_DEFINE_AUDIO_FORMAT(0, 0, 0, 8), */
+ SDL_AUDIO_S8 = 0x8008u, /**< Signed 8-bit samples */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 8), */
+ SDL_AUDIO_S16LE = 0x8010u, /**< Signed 16-bit samples */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 16), */
+ SDL_AUDIO_S16BE = 0x9010u, /**< As above, but big-endian byte order */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 1, 0, 16), */
+ SDL_AUDIO_S32LE = 0x8020u, /**< 32-bit integer samples */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 32), */
+ SDL_AUDIO_S32BE = 0x9020u, /**< As above, but big-endian byte order */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 1, 0, 32), */
+ SDL_AUDIO_F32LE = 0x8120u, /**< 32-bit floating point samples */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 0, 1, 32), */
+ SDL_AUDIO_F32BE = 0x9120u, /**< As above, but big-endian byte order */
+ /* SDL_DEFINE_AUDIO_FORMAT(1, 1, 1, 32), */
+
+ /* These represent the current system's byteorder. */
+ #if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ SDL_AUDIO_S16 = SDL_AUDIO_S16LE,
+ SDL_AUDIO_S32 = SDL_AUDIO_S32LE,
+ SDL_AUDIO_F32 = SDL_AUDIO_F32LE
+ #else
+ SDL_AUDIO_S16 = SDL_AUDIO_S16BE,
+ SDL_AUDIO_S32 = SDL_AUDIO_S32BE,
+ SDL_AUDIO_F32 = SDL_AUDIO_F32BE
+ #endif
+} SDL_AudioFormat;
+
+
+/**
+ * Retrieve the size, in bits, from an SDL_AudioFormat.
+ *
+ * For example, `SDL_AUDIO_BITSIZE(SDL_AUDIO_S16)` returns 16.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns data size in bits.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_BITSIZE(x) ((x) & SDL_AUDIO_MASK_BITSIZE)
+
+/**
+ * Retrieve the size, in bytes, from an SDL_AudioFormat.
+ *
+ * For example, `SDL_AUDIO_BYTESIZE(SDL_AUDIO_S16)` returns 2.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns data size in bytes.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_BYTESIZE(x) (SDL_AUDIO_BITSIZE(x) / 8)
+
+/**
+ * Determine if an SDL_AudioFormat represents floating point data.
+ *
+ * For example, `SDL_AUDIO_ISFLOAT(SDL_AUDIO_S16)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is floating point, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISFLOAT(x) ((x) & SDL_AUDIO_MASK_FLOAT)
+
+/**
+ * Determine if an SDL_AudioFormat represents bigendian data.
+ *
+ * For example, `SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16LE)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is bigendian, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISBIGENDIAN(x) ((x) & SDL_AUDIO_MASK_BIG_ENDIAN)
+
+/**
+ * Determine if an SDL_AudioFormat represents littleendian data.
+ *
+ * For example, `SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16BE)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is littleendian, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x))
+
+/**
+ * Determine if an SDL_AudioFormat represents signed data.
+ *
+ * For example, `SDL_AUDIO_ISSIGNED(SDL_AUDIO_U8)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is signed, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISSIGNED(x) ((x) & SDL_AUDIO_MASK_SIGNED)
+
+/**
+ * Determine if an SDL_AudioFormat represents integer data.
+ *
+ * For example, `SDL_AUDIO_ISINT(SDL_AUDIO_F32)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is integer, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x))
+
+/**
+ * Determine if an SDL_AudioFormat represents unsigned data.
+ *
+ * For example, `SDL_AUDIO_ISUNSIGNED(SDL_AUDIO_S16)` returns 0.
+ *
+ * \param x an SDL_AudioFormat value.
+ * \returns non-zero if format is unsigned, zero otherwise.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x))
+
+
+/**
+ * SDL Audio Device instance IDs.
+ *
+ * Zero is used to signify an invalid/null device.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef Uint32 SDL_AudioDeviceID;
+
+/**
+ * A value used to request a default playback audio device.
+ *
+ * Several functions that require an SDL_AudioDeviceID will accept this value
+ * to signify the app just wants the system to choose a default device instead
+ * of the app providing a specific one.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK ((SDL_AudioDeviceID) 0xFFFFFFFFu)
+
+/**
+ * A value used to request a default recording audio device.
+ *
+ * Several functions that require an SDL_AudioDeviceID will accept this value
+ * to signify the app just wants the system to choose a default device instead
+ * of the app providing a specific one.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_DEVICE_DEFAULT_RECORDING ((SDL_AudioDeviceID) 0xFFFFFFFEu)
+
+/**
+ * Format specifier for audio data.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_AudioFormat
+ */
+typedef struct SDL_AudioSpec
+{
+ SDL_AudioFormat format; /**< Audio data format */
+ int channels; /**< Number of channels: 1 mono, 2 stereo, etc */
+ int freq; /**< sample rate: sample frames per second */
+} SDL_AudioSpec;
+
+/**
+ * Calculate the size of each audio frame (in bytes) from an SDL_AudioSpec.
+ *
+ * This reports on the size of an audio sample frame: stereo Sint16 data (2
+ * channels of 2 bytes each) would be 4 bytes per frame, for example.
+ *
+ * \param x an SDL_AudioSpec to query.
+ * \returns the number of bytes used per sample frame.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_AUDIO_FRAMESIZE(x) (SDL_AUDIO_BYTESIZE((x).format) * (x).channels)
+
+/**
+ * The opaque handle that represents an audio stream.
+ *
+ * SDL_AudioStream is an audio conversion interface.
+ *
+ * - It can handle resampling data in chunks without generating artifacts,
+ * when it doesn't have the complete buffer available.
+ * - It can handle incoming data in any variable size.
+ * - It can handle input/output format changes on the fly.
+ * - It can remap audio channels between inputs and outputs.
+ * - You push data as you have it, and pull it when you need it
+ * - It can also function as a basic audio data queue even if you just have
+ * sound that needs to pass from one place to another.
+ * - You can hook callbacks up to them when more data is added or requested,
+ * to manage data on-the-fly.
+ *
+ * Audio streams are the core of the SDL3 audio interface. You create one or
+ * more of them, bind them to an opened audio device, and feed data to them
+ * (or for recording, consume data from them).
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateAudioStream
+ */
+typedef struct SDL_AudioStream SDL_AudioStream;
+
+
+/* Function prototypes */
+
+/**
+ * Use this function to get the number of built-in audio drivers.
+ *
+ * This function returns a hardcoded number. This never returns a negative
+ * value; if there are no drivers compiled into this build of SDL, this
+ * function returns zero. The presence of a driver in this list does not mean
+ * it will function, it just means SDL is capable of interacting with that
+ * interface. For example, a build of SDL might have esound support, but if
+ * there's no esound server available, SDL's esound driver would fail if used.
+ *
+ * By default, SDL tries all drivers, in its preferred order, until one is
+ * found to be usable.
+ *
+ * \returns the number of built-in audio drivers.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioDriver
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
+
+/**
+ * Use this function to get the name of a built in audio driver.
+ *
+ * The list of audio drivers is given in the order that they are normally
+ * initialized by default; the drivers that seem more reasonable to choose
+ * first (as far as the SDL developers believe) are earlier in the list.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "alsa",
+ * "coreaudio" or "wasapi". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \param index the index of the audio driver; the value ranges from 0 to
+ * SDL_GetNumAudioDrivers() - 1.
+ * \returns the name of the audio driver at the requested index, or NULL if an
+ * invalid index was specified.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetNumAudioDrivers
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetAudioDriver(int index);
+
+/**
+ * Get the name of the current audio driver.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "alsa",
+ * "coreaudio" or "wasapi". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \returns the name of the current audio driver or NULL if no driver has been
+ * initialized.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentAudioDriver(void);
+
+/**
+ * Get a list of currently-connected audio playback devices.
+ *
+ * This returns of list of available devices that play sound, perhaps to
+ * speakers or headphones ("playback" devices). If you want devices that
+ * record audio, like a microphone ("recording" devices), use
+ * SDL_GetAudioRecordingDevices() instead.
+ *
+ * This only returns a list of physical devices; it will not have any device
+ * IDs returned by SDL_OpenAudioDevice().
+ *
+ * If this function returns NULL, to signify an error, `*count` will be set to
+ * zero.
+ *
+ * \param count a pointer filled in with the number of devices returned, may
+ * be NULL.
+ * \returns a 0 terminated array of device instance IDs or NULL on error; call
+ * SDL_GetError() for more information. This should be freed with
+ * SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenAudioDevice
+ * \sa SDL_GetAudioRecordingDevices
+ */
+extern SDL_DECLSPEC SDL_AudioDeviceID * SDLCALL SDL_GetAudioPlaybackDevices(int *count);
+
+/**
+ * Get a list of currently-connected audio recording devices.
+ *
+ * This returns of list of available devices that record audio, like a
+ * microphone ("recording" devices). If you want devices that play sound,
+ * perhaps to speakers or headphones ("playback" devices), use
+ * SDL_GetAudioPlaybackDevices() instead.
+ *
+ * This only returns a list of physical devices; it will not have any device
+ * IDs returned by SDL_OpenAudioDevice().
+ *
+ * If this function returns NULL, to signify an error, `*count` will be set to
+ * zero.
+ *
+ * \param count a pointer filled in with the number of devices returned, may
+ * be NULL.
+ * \returns a 0 terminated array of device instance IDs, or NULL on failure;
+ * call SDL_GetError() for more information. This should be freed
+ * with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenAudioDevice
+ * \sa SDL_GetAudioPlaybackDevices
+ */
+extern SDL_DECLSPEC SDL_AudioDeviceID * SDLCALL SDL_GetAudioRecordingDevices(int *count);
+
+/**
+ * Get the human-readable name of a specific audio device.
+ *
+ * \param devid the instance ID of the device to query.
+ * \returns the name of the audio device, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioPlaybackDevices
+ * \sa SDL_GetAudioRecordingDevices
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetAudioDeviceName(SDL_AudioDeviceID devid);
+
+/**
+ * Get the current audio format of a specific audio device.
+ *
+ * For an opened device, this will report the format the device is currently
+ * using. If the device isn't yet opened, this will report the device's
+ * preferred format (or a reasonable default if this can't be determined).
+ *
+ * You may also specify SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or
+ * SDL_AUDIO_DEVICE_DEFAULT_RECORDING here, which is useful for getting a
+ * reasonable recommendation before opening the system-recommended default
+ * device.
+ *
+ * You can also use this to request the current device buffer size. This is
+ * specified in sample frames and represents the amount of data SDL will feed
+ * to the physical hardware in each chunk. This can be converted to
+ * milliseconds of audio with the following equation:
+ *
+ * `ms = (int) ((((Sint64) frames) * 1000) / spec.freq);`
+ *
+ * Buffer size is only important if you need low-level control over the audio
+ * playback timing. Most apps do not need this.
+ *
+ * \param devid the instance ID of the device to query.
+ * \param spec on return, will be filled with device details.
+ * \param sample_frames pointer to store device buffer size, in sample frames.
+ * Can be NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames);
+
+/**
+ * Get the current channel map of an audio device.
+ *
+ * Channel maps are optional; most things do not need them, instead passing
+ * data in the [order that SDL expects](CategoryAudio#channel-layouts).
+ *
+ * Audio devices usually have no remapping applied. This is represented by
+ * returning NULL, and does not signify an error.
+ *
+ * \param devid the instance ID of the device to query.
+ * \param count On output, set to number of channels in the map. Can be NULL.
+ * \returns an array of the current channel mapping, with as many elements as
+ * the current output spec's channels, or NULL if default. This
+ * should be freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamInputChannelMap
+ */
+extern SDL_DECLSPEC int * SDLCALL SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count);
+
+/**
+ * Open a specific audio device.
+ *
+ * You can open both playback and recording devices through this function.
+ * Playback devices will take data from bound audio streams, mix it, and send
+ * it to the hardware. Recording devices will feed any bound audio streams
+ * with a copy of any incoming data.
+ *
+ * An opened audio device starts out with no audio streams bound. To start
+ * audio playing, bind a stream and supply audio data to it. Unlike SDL2,
+ * there is no audio callback; you only bind audio streams and make sure they
+ * have data flowing into them (however, you can simulate SDL2's semantics
+ * fairly closely by using SDL_OpenAudioDeviceStream instead of this
+ * function).
+ *
+ * If you don't care about opening a specific device, pass a `devid` of either
+ * `SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK` or
+ * `SDL_AUDIO_DEVICE_DEFAULT_RECORDING`. In this case, SDL will try to pick
+ * the most reasonable default, and may also switch between physical devices
+ * seamlessly later, if the most reasonable default changes during the
+ * lifetime of this opened device (user changed the default in the OS's system
+ * preferences, the default got unplugged so the system jumped to a new
+ * default, the user plugged in headphones on a mobile device, etc). Unless
+ * you have a good reason to choose a specific device, this is probably what
+ * you want.
+ *
+ * You may request a specific format for the audio device, but there is no
+ * promise the device will honor that request for several reasons. As such,
+ * it's only meant to be a hint as to what data your app will provide. Audio
+ * streams will accept data in whatever format you specify and manage
+ * conversion for you as appropriate. SDL_GetAudioDeviceFormat can tell you
+ * the preferred format for the device before opening and the actual format
+ * the device is using after opening.
+ *
+ * It's legal to open the same device ID more than once; each successful open
+ * will generate a new logical SDL_AudioDeviceID that is managed separately
+ * from others on the same physical device. This allows libraries to open a
+ * device separately from the main app and bind its own streams without
+ * conflicting.
+ *
+ * It is also legal to open a device ID returned by a previous call to this
+ * function; doing so just creates another logical device on the same physical
+ * device. This may be useful for making logical groupings of audio streams.
+ *
+ * This function returns the opened device ID on success. This is a new,
+ * unique SDL_AudioDeviceID that represents a logical device.
+ *
+ * Some backends might offer arbitrary devices (for example, a networked audio
+ * protocol that can connect to an arbitrary server). For these, as a change
+ * from SDL2, you should open a default device ID and use an SDL hint to
+ * specify the target if you care, or otherwise let the backend figure out a
+ * reasonable default. Most backends don't offer anything like this, and often
+ * this would be an end user setting an environment variable for their custom
+ * need, and not something an application should specifically manage.
+ *
+ * When done with an audio device, possibly at the end of the app's life, one
+ * should call SDL_CloseAudioDevice() on the returned device id.
+ *
+ * \param devid the device instance id to open, or
+ * SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or
+ * SDL_AUDIO_DEVICE_DEFAULT_RECORDING for the most reasonable
+ * default device.
+ * \param spec the requested device configuration. Can be NULL to use
+ * reasonable defaults.
+ * \returns the device ID on success or 0 on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseAudioDevice
+ * \sa SDL_GetAudioDeviceFormat
+ */
+extern SDL_DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec);
+
+/**
+ * Determine if an audio device is physical (instead of logical).
+ *
+ * An SDL_AudioDeviceID that represents physical hardware is a physical
+ * device; there is one for each piece of hardware that SDL can see. Logical
+ * devices are created by calling SDL_OpenAudioDevice or
+ * SDL_OpenAudioDeviceStream, and while each is associated with a physical
+ * device, there can be any number of logical devices on one physical device.
+ *
+ * For the most part, logical and physical IDs are interchangeable--if you try
+ * to open a logical device, SDL understands to assign that effort to the
+ * underlying physical device, etc. However, it might be useful to know if an
+ * arbitrary device ID is physical or logical. This function reports which.
+ *
+ * This function may return either true or false for invalid device IDs.
+ *
+ * \param devid the device ID to query.
+ * \returns true if devid is a physical device, false if it is logical.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsAudioDevicePhysical(SDL_AudioDeviceID devid);
+
+/**
+ * Determine if an audio device is a playback device (instead of recording).
+ *
+ * This function may return either true or false for invalid device IDs.
+ *
+ * \param devid the device ID to query.
+ * \returns true if devid is a playback device, false if it is recording.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsAudioDevicePlayback(SDL_AudioDeviceID devid);
+
+/**
+ * Use this function to pause audio playback on a specified device.
+ *
+ * This function pauses audio processing for a given device. Any bound audio
+ * streams will not progress, and no audio will be generated. Pausing one
+ * device does not prevent other unpaused devices from running.
+ *
+ * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app
+ * has to bind a stream before any audio will flow. Pausing a paused device is
+ * a legal no-op.
+ *
+ * Pausing a device can be useful to halt all audio without unbinding all the
+ * audio streams. This might be useful while a game is paused, or a level is
+ * loading, etc.
+ *
+ * Physical devices can not be paused or unpaused, only logical devices
+ * created through SDL_OpenAudioDevice() can be.
+ *
+ * \param devid a device opened by SDL_OpenAudioDevice().
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ResumeAudioDevice
+ * \sa SDL_AudioDevicePaused
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID devid);
+
+/**
+ * Use this function to unpause audio playback on a specified device.
+ *
+ * This function unpauses audio processing for a given device that has
+ * previously been paused with SDL_PauseAudioDevice(). Once unpaused, any
+ * bound audio streams will begin to progress again, and audio can be
+ * generated.
+ *
+ * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app
+ * has to bind a stream before any audio will flow. Unpausing an unpaused
+ * device is a legal no-op.
+ *
+ * Physical devices can not be paused or unpaused, only logical devices
+ * created through SDL_OpenAudioDevice() can be.
+ *
+ * \param devid a device opened by SDL_OpenAudioDevice().
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AudioDevicePaused
+ * \sa SDL_PauseAudioDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID devid);
+
+/**
+ * Use this function to query if an audio device is paused.
+ *
+ * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app
+ * has to bind a stream before any audio will flow.
+ *
+ * Physical devices can not be paused or unpaused, only logical devices
+ * created through SDL_OpenAudioDevice() can be. Physical and invalid device
+ * IDs will report themselves as unpaused here.
+ *
+ * \param devid a device opened by SDL_OpenAudioDevice().
+ * \returns true if device is valid and paused, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PauseAudioDevice
+ * \sa SDL_ResumeAudioDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_AudioDevicePaused(SDL_AudioDeviceID devid);
+
+/**
+ * Get the gain of an audio device.
+ *
+ * The gain of a device is its volume; a larger gain means a louder output,
+ * with a gain of zero being silence.
+ *
+ * Audio devices default to a gain of 1.0f (no change in output).
+ *
+ * Physical devices may not have their gain changed, only logical devices, and
+ * this function will always return -1.0f when used on physical devices.
+ *
+ * \param devid the audio device to query.
+ * \returns the gain of the device or -1.0f on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioDeviceGain
+ */
+extern SDL_DECLSPEC float SDLCALL SDL_GetAudioDeviceGain(SDL_AudioDeviceID devid);
+
+/**
+ * Change the gain of an audio device.
+ *
+ * The gain of a device is its volume; a larger gain means a louder output,
+ * with a gain of zero being silence.
+ *
+ * Audio devices default to a gain of 1.0f (no change in output).
+ *
+ * Physical devices may not have their gain changed, only logical devices, and
+ * this function will always return false when used on physical devices. While
+ * it might seem attractive to adjust several logical devices at once in this
+ * way, it would allow an app or library to interfere with another portion of
+ * the program's otherwise-isolated devices.
+ *
+ * This is applied, along with any per-audiostream gain, during playback to
+ * the hardware, and can be continuously changed to create various effects. On
+ * recording devices, this will adjust the gain before passing the data into
+ * an audiostream; that recording audiostream can then adjust its gain further
+ * when outputting the data elsewhere, if it likes, but that second gain is
+ * not applied until the data leaves the audiostream again.
+ *
+ * \param devid the audio device on which to change gain.
+ * \param gain the gain. 1.0f is no change, 0.0f is silence.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioDeviceGain
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioDeviceGain(SDL_AudioDeviceID devid, float gain);
+
+/**
+ * Close a previously-opened audio device.
+ *
+ * The application should close open audio devices once they are no longer
+ * needed.
+ *
+ * This function may block briefly while pending audio data is played by the
+ * hardware, so that applications don't drop the last buffer of data they
+ * supplied if terminating immediately afterwards.
+ *
+ * \param devid an audio device id previously returned by
+ * SDL_OpenAudioDevice().
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenAudioDevice
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
+
+/**
+ * Bind a list of audio streams to an audio device.
+ *
+ * Audio data will flow through any bound streams. For a playback device, data
+ * for all bound streams will be mixed together and fed to the device. For a
+ * recording device, a copy of recorded data will be provided to each bound
+ * stream.
+ *
+ * Audio streams can only be bound to an open device. This operation is
+ * atomic--all streams bound in the same call will start processing at the
+ * same time, so they can stay in sync. Also: either all streams will be bound
+ * or none of them will be.
+ *
+ * It is an error to bind an already-bound stream; it must be explicitly
+ * unbound first.
+ *
+ * Binding a stream to a device will set its output format for playback
+ * devices, and its input format for recording devices, so they match the
+ * device's settings. The caller is welcome to change the other end of the
+ * stream's format at any time with SDL_SetAudioStreamFormat().
+ *
+ * \param devid an audio device to bind a stream to.
+ * \param streams an array of audio streams to bind.
+ * \param num_streams number streams listed in the `streams` array.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindAudioStreams
+ * \sa SDL_UnbindAudioStream
+ * \sa SDL_GetAudioStreamDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *streams, int num_streams);
+
+/**
+ * Bind a single audio stream to an audio device.
+ *
+ * This is a convenience function, equivalent to calling
+ * `SDL_BindAudioStreams(devid, &stream, 1)`.
+ *
+ * \param devid an audio device to bind a stream to.
+ * \param stream an audio stream to bind to a device.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindAudioStreams
+ * \sa SDL_UnbindAudioStream
+ * \sa SDL_GetAudioStreamDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream);
+
+/**
+ * Unbind a list of audio streams from their audio devices.
+ *
+ * The streams being unbound do not all have to be on the same device. All
+ * streams on the same device will be unbound atomically (data will stop
+ * flowing through all unbound streams on the same device at the same time).
+ *
+ * Unbinding a stream that isn't bound to a device is a legal no-op.
+ *
+ * \param streams an array of audio streams to unbind. Can be NULL or contain
+ * NULL.
+ * \param num_streams number streams listed in the `streams` array.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindAudioStreams
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStreams(SDL_AudioStream * const *streams, int num_streams);
+
+/**
+ * Unbind a single audio stream from its audio device.
+ *
+ * This is a convenience function, equivalent to calling
+ * `SDL_UnbindAudioStreams(&stream, 1)`.
+ *
+ * \param stream an audio stream to unbind from a device. Can be NULL.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindAudioStream
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
+
+/**
+ * Query an audio stream for its currently-bound device.
+ *
+ * This reports the audio device that an audio stream is currently bound to.
+ *
+ * If not bound, or invalid, this returns zero, which is not a valid device
+ * ID.
+ *
+ * \param stream the audio stream to query.
+ * \returns the bound audio device, or 0 if not bound or invalid.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindAudioStream
+ * \sa SDL_BindAudioStreams
+ */
+extern SDL_DECLSPEC SDL_AudioDeviceID SDLCALL SDL_GetAudioStreamDevice(SDL_AudioStream *stream);
+
+/**
+ * Create a new audio stream.
+ *
+ * \param src_spec the format details of the input audio.
+ * \param dst_spec the format details of the output audio.
+ * \returns a new audio stream on success or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PutAudioStreamData
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_GetAudioStreamAvailable
+ * \sa SDL_FlushAudioStream
+ * \sa SDL_ClearAudioStream
+ * \sa SDL_SetAudioStreamFormat
+ * \sa SDL_DestroyAudioStream
+ */
+extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec);
+
+/**
+ * Get the properties associated with an audio stream.
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \returns a valid property ID on success or 0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetAudioStreamProperties(SDL_AudioStream *stream);
+
+/**
+ * Query the current format of an audio stream.
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \param src_spec where to store the input audio format; ignored if NULL.
+ * \param dst_spec where to store the output audio format; ignored if NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamFormat
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec, SDL_AudioSpec *dst_spec);
+
+/**
+ * Change the input and output formats of an audio stream.
+ *
+ * Future calls to and SDL_GetAudioStreamAvailable and SDL_GetAudioStreamData
+ * will reflect the new format, and future calls to SDL_PutAudioStreamData
+ * must provide data in the new input formats.
+ *
+ * Data that was previously queued in the stream will still be operated on in
+ * the format that was current when it was added, which is to say you can put
+ * the end of a sound file in one format to a stream, change formats for the
+ * next sound file, and start putting that new data while the previous sound
+ * file is still queued, and everything will still play back correctly.
+ *
+ * If a stream is bound to a device, then the format of the side of the stream
+ * bound to a device cannot be changed (src_spec for recording devices,
+ * dst_spec for playback devices). Attempts to make a change to this side will
+ * be ignored, but this will not report an error. The other side's format can
+ * be changed.
+ *
+ * \param stream the stream the format is being changed.
+ * \param src_spec the new format of the audio input; if NULL, it is not
+ * changed.
+ * \param dst_spec the new format of the audio output; if NULL, it is not
+ * changed.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamFormat
+ * \sa SDL_SetAudioStreamFrequencyRatio
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec);
+
+/**
+ * Get the frequency ratio of an audio stream.
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \returns the frequency ratio of the stream or 0.0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamFrequencyRatio
+ */
+extern SDL_DECLSPEC float SDLCALL SDL_GetAudioStreamFrequencyRatio(SDL_AudioStream *stream);
+
+/**
+ * Change the frequency ratio of an audio stream.
+ *
+ * The frequency ratio is used to adjust the rate at which input data is
+ * consumed. Changing this effectively modifies the speed and pitch of the
+ * audio. A value greater than 1.0 will play the audio faster, and at a higher
+ * pitch. A value less than 1.0 will play the audio slower, and at a lower
+ * pitch.
+ *
+ * This is applied during SDL_GetAudioStreamData, and can be continuously
+ * changed to create various effects.
+ *
+ * \param stream the stream the frequency ratio is being changed.
+ * \param ratio the frequency ratio. 1.0 is normal speed. Must be between 0.01
+ * and 100.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamFrequencyRatio
+ * \sa SDL_SetAudioStreamFormat
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream *stream, float ratio);
+
+/**
+ * Get the gain of an audio stream.
+ *
+ * The gain of a stream is its volume; a larger gain means a louder output,
+ * with a gain of zero being silence.
+ *
+ * Audio streams default to a gain of 1.0f (no change in output).
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \returns the gain of the stream or -1.0f on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamGain
+ */
+extern SDL_DECLSPEC float SDLCALL SDL_GetAudioStreamGain(SDL_AudioStream *stream);
+
+/**
+ * Change the gain of an audio stream.
+ *
+ * The gain of a stream is its volume; a larger gain means a louder output,
+ * with a gain of zero being silence.
+ *
+ * Audio streams default to a gain of 1.0f (no change in output).
+ *
+ * This is applied during SDL_GetAudioStreamData, and can be continuously
+ * changed to create various effects.
+ *
+ * \param stream the stream on which the gain is being changed.
+ * \param gain the gain. 1.0f is no change, 0.0f is silence.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamGain
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamGain(SDL_AudioStream *stream, float gain);
+
+/**
+ * Get the current input channel map of an audio stream.
+ *
+ * Channel maps are optional; most things do not need them, instead passing
+ * data in the [order that SDL expects](CategoryAudio#channel-layouts).
+ *
+ * Audio streams default to no remapping applied. This is represented by
+ * returning NULL, and does not signify an error.
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \param count On output, set to number of channels in the map. Can be NULL.
+ * \returns an array of the current channel mapping, with as many elements as
+ * the current output spec's channels, or NULL if default. This
+ * should be freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamInputChannelMap
+ */
+extern SDL_DECLSPEC int * SDLCALL SDL_GetAudioStreamInputChannelMap(SDL_AudioStream *stream, int *count);
+
+/**
+ * Get the current output channel map of an audio stream.
+ *
+ * Channel maps are optional; most things do not need them, instead passing
+ * data in the [order that SDL expects](CategoryAudio#channel-layouts).
+ *
+ * Audio streams default to no remapping applied. This is represented by
+ * returning NULL, and does not signify an error.
+ *
+ * \param stream the SDL_AudioStream to query.
+ * \param count On output, set to number of channels in the map. Can be NULL.
+ * \returns an array of the current channel mapping, with as many elements as
+ * the current output spec's channels, or NULL if default. This
+ * should be freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamInputChannelMap
+ */
+extern SDL_DECLSPEC int * SDLCALL SDL_GetAudioStreamOutputChannelMap(SDL_AudioStream *stream, int *count);
+
+/**
+ * Set the current input channel map of an audio stream.
+ *
+ * Channel maps are optional; most things do not need them, instead passing
+ * data in the [order that SDL expects](CategoryAudio#channel-layouts).
+ *
+ * The input channel map reorders data that is added to a stream via
+ * SDL_PutAudioStreamData. Future calls to SDL_PutAudioStreamData must provide
+ * data in the new channel order.
+ *
+ * Each item in the array represents an input channel, and its value is the
+ * channel that it should be remapped to. To reverse a stereo signal's left
+ * and right values, you'd have an array of `{ 1, 0 }`. It is legal to remap
+ * multiple channels to the same thing, so `{ 1, 1 }` would duplicate the
+ * right channel to both channels of a stereo signal. An element in the
+ * channel map set to -1 instead of a valid channel will mute that channel,
+ * setting it to a silence value.
+ *
+ * You cannot change the number of channels through a channel map, just
+ * reorder/mute them.
+ *
+ * Data that was previously queued in the stream will still be operated on in
+ * the order that was current when it was added, which is to say you can put
+ * the end of a sound file in one order to a stream, change orders for the
+ * next sound file, and start putting that new data while the previous sound
+ * file is still queued, and everything will still play back correctly.
+ *
+ * Audio streams default to no remapping applied. Passing a NULL channel map
+ * is legal, and turns off remapping.
+ *
+ * SDL will copy the channel map; the caller does not have to save this array
+ * after this call.
+ *
+ * If `count` is not equal to the current number of channels in the audio
+ * stream's format, this will fail. This is a safety measure to make sure a
+ * race condition hasn't changed the format while this call is setting the
+ * channel map.
+ *
+ * Unlike attempting to change the stream's format, the input channel map on a
+ * stream bound to a recording device is permitted to change at any time; any
+ * data added to the stream from the device after this call will have the new
+ * mapping, but previously-added data will still have the prior mapping.
+ *
+ * \param stream the SDL_AudioStream to change.
+ * \param chmap the new channel map, NULL to reset to default.
+ * \param count The number of channels in the map.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running. Don't change the
+ * stream's format to have a different number of channels from a
+ * a different thread at the same time, though!
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamInputChannelMap
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamInputChannelMap(SDL_AudioStream *stream, const int *chmap, int count);
+
+/**
+ * Set the current output channel map of an audio stream.
+ *
+ * Channel maps are optional; most things do not need them, instead passing
+ * data in the [order that SDL expects](CategoryAudio#channel-layouts).
+ *
+ * The output channel map reorders data that leaving a stream via
+ * SDL_GetAudioStreamData.
+ *
+ * Each item in the array represents an input channel, and its value is the
+ * channel that it should be remapped to. To reverse a stereo signal's left
+ * and right values, you'd have an array of `{ 1, 0 }`. It is legal to remap
+ * multiple channels to the same thing, so `{ 1, 1 }` would duplicate the
+ * right channel to both channels of a stereo signal. An element in the
+ * channel map set to -1 instead of a valid channel will mute that channel,
+ * setting it to a silence value.
+ *
+ * You cannot change the number of channels through a channel map, just
+ * reorder/mute them.
+ *
+ * The output channel map can be changed at any time, as output remapping is
+ * applied during SDL_GetAudioStreamData.
+ *
+ * Audio streams default to no remapping applied. Passing a NULL channel map
+ * is legal, and turns off remapping.
+ *
+ * SDL will copy the channel map; the caller does not have to save this array
+ * after this call.
+ *
+ * If `count` is not equal to the current number of channels in the audio
+ * stream's format, this will fail. This is a safety measure to make sure a
+ * race condition hasn't changed the format while this call is setting the
+ * channel map.
+ *
+ * Unlike attempting to change the stream's format, the output channel map on
+ * a stream bound to a recording device is permitted to change at any time;
+ * any data added to the stream after this call will have the new mapping, but
+ * previously-added data will still have the prior mapping. When the channel
+ * map doesn't match the hardware's channel layout, SDL will convert the data
+ * before feeding it to the device for playback.
+ *
+ * \param stream the SDL_AudioStream to change.
+ * \param chmap the new channel map, NULL to reset to default.
+ * \param count The number of channels in the map.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, as it holds
+ * a stream-specific mutex while running. Don't change the
+ * stream's format to have a different number of channels from a
+ * a different thread at the same time, though!
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamInputChannelMap
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamOutputChannelMap(SDL_AudioStream *stream, const int *chmap, int count);
+
+/**
+ * Add data to the stream.
+ *
+ * This data must match the format/channels/samplerate specified in the latest
+ * call to SDL_SetAudioStreamFormat, or the format specified when creating the
+ * stream if it hasn't been changed.
+ *
+ * Note that this call simply copies the unconverted data for later. This is
+ * different than SDL2, where data was converted during the Put call and the
+ * Get call would just dequeue the previously-converted data.
+ *
+ * \param stream the stream the audio data is being added to.
+ * \param buf a pointer to the audio data to add.
+ * \param len the number of bytes to write to the stream.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread, but if the
+ * stream has a callback set, the caller might need to manage
+ * extra locking.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearAudioStream
+ * \sa SDL_FlushAudioStream
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_GetAudioStreamQueued
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len);
+
+/**
+ * Get converted/resampled data from the stream.
+ *
+ * The input/output data format/channels/samplerate is specified when creating
+ * the stream, and can be changed after creation by calling
+ * SDL_SetAudioStreamFormat.
+ *
+ * Note that any conversion and resampling necessary is done during this call,
+ * and SDL_PutAudioStreamData simply queues unconverted data for later. This
+ * is different than SDL2, where that work was done while inputting new data
+ * to the stream and requesting the output just copied the converted data.
+ *
+ * \param stream the stream the audio is being requested from.
+ * \param buf a buffer to fill with audio data.
+ * \param len the maximum number of bytes to fill.
+ * \returns the number of bytes read from the stream or -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread, but if the
+ * stream has a callback set, the caller might need to manage
+ * extra locking.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearAudioStream
+ * \sa SDL_GetAudioStreamAvailable
+ * \sa SDL_PutAudioStreamData
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetAudioStreamData(SDL_AudioStream *stream, void *buf, int len);
+
+/**
+ * Get the number of converted/resampled bytes available.
+ *
+ * The stream may be buffering data behind the scenes until it has enough to
+ * resample correctly, so this number might be lower than what you expect, or
+ * even be zero. Add more data or flush the stream if you need the data now.
+ *
+ * If the stream has so much data that it would overflow an int, the return
+ * value is clamped to a maximum value, but no queued data is lost; if there
+ * are gigabytes of data queued, the app might need to read some of it with
+ * SDL_GetAudioStreamData before this function's return value is no longer
+ * clamped.
+ *
+ * \param stream the audio stream to query.
+ * \returns the number of converted/resampled bytes available or -1 on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_PutAudioStreamData
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetAudioStreamAvailable(SDL_AudioStream *stream);
+
+
+/**
+ * Get the number of bytes currently queued.
+ *
+ * This is the number of bytes put into a stream as input, not the number that
+ * can be retrieved as output. Because of several details, it's not possible
+ * to calculate one number directly from the other. If you need to know how
+ * much usable data can be retrieved right now, you should use
+ * SDL_GetAudioStreamAvailable() and not this function.
+ *
+ * Note that audio streams can change their input format at any time, even if
+ * there is still data queued in a different format, so the returned byte
+ * count will not necessarily match the number of _sample frames_ available.
+ * Users of this API should be aware of format changes they make when feeding
+ * a stream and plan accordingly.
+ *
+ * Queued data is not converted until it is consumed by
+ * SDL_GetAudioStreamData, so this value should be representative of the exact
+ * data that was put into the stream.
+ *
+ * If the stream has so much data that it would overflow an int, the return
+ * value is clamped to a maximum value, but no queued data is lost; if there
+ * are gigabytes of data queued, the app might need to read some of it with
+ * SDL_GetAudioStreamData before this function's return value is no longer
+ * clamped.
+ *
+ * \param stream the audio stream to query.
+ * \returns the number of bytes queued or -1 on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PutAudioStreamData
+ * \sa SDL_ClearAudioStream
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetAudioStreamQueued(SDL_AudioStream *stream);
+
+
+/**
+ * Tell the stream that you're done sending data, and anything being buffered
+ * should be converted/resampled and made available immediately.
+ *
+ * It is legal to add more data to a stream after flushing, but there may be
+ * audio gaps in the output. Generally this is intended to signal the end of
+ * input, so the complete output becomes available.
+ *
+ * \param stream the audio stream to flush.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PutAudioStreamData
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_FlushAudioStream(SDL_AudioStream *stream);
+
+/**
+ * Clear any pending data in the stream.
+ *
+ * This drops any queued data, so there will be nothing to read from the
+ * stream until more is added.
+ *
+ * \param stream the audio stream to clear.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamAvailable
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_GetAudioStreamQueued
+ * \sa SDL_PutAudioStreamData
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ClearAudioStream(SDL_AudioStream *stream);
+
+/**
+ * Use this function to pause audio playback on the audio device associated
+ * with an audio stream.
+ *
+ * This function pauses audio processing for a given device. Any bound audio
+ * streams will not progress, and no audio will be generated. Pausing one
+ * device does not prevent other unpaused devices from running.
+ *
+ * Pausing a device can be useful to halt all audio without unbinding all the
+ * audio streams. This might be useful while a game is paused, or a level is
+ * loading, etc.
+ *
+ * \param stream the audio stream associated with the audio device to pause.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ResumeAudioStreamDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PauseAudioStreamDevice(SDL_AudioStream *stream);
+
+/**
+ * Use this function to unpause audio playback on the audio device associated
+ * with an audio stream.
+ *
+ * This function unpauses audio processing for a given device that has
+ * previously been paused. Once unpaused, any bound audio streams will begin
+ * to progress again, and audio can be generated.
+ *
+ * Remember, SDL_OpenAudioDeviceStream opens device in a paused state, so this
+ * function call is required for audio playback to begin on such device.
+ *
+ * \param stream the audio stream associated with the audio device to resume.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PauseAudioStreamDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ResumeAudioStreamDevice(SDL_AudioStream *stream);
+
+/**
+ * Use this function to query if an audio device associated with a stream is
+ * paused.
+ *
+ * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app
+ * has to bind a stream before any audio will flow.
+ *
+ * \param stream the audio stream associated with the audio device to query.
+ * \returns true if device is valid and paused, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PauseAudioStreamDevice
+ * \sa SDL_ResumeAudioStreamDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_AudioStreamDevicePaused(SDL_AudioStream *stream);
+
+
+/**
+ * Lock an audio stream for serialized access.
+ *
+ * Each SDL_AudioStream has an internal mutex it uses to protect its data
+ * structures from threading conflicts. This function allows an app to lock
+ * that mutex, which could be useful if registering callbacks on this stream.
+ *
+ * One does not need to lock a stream to use in it most cases, as the stream
+ * manages this lock internally. However, this lock is held during callbacks,
+ * which may run from arbitrary threads at any time, so if an app needs to
+ * protect shared data during those callbacks, locking the stream guarantees
+ * that the callback is not running while the lock is held.
+ *
+ * As this is just a wrapper over SDL_LockMutex for an internal lock; it has
+ * all the same attributes (recursive locks are allowed, etc).
+ *
+ * \param stream the audio stream to lock.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_UnlockAudioStream
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_LockAudioStream(SDL_AudioStream *stream);
+
+
+/**
+ * Unlock an audio stream for serialized access.
+ *
+ * This unlocks an audio stream after a call to SDL_LockAudioStream.
+ *
+ * \param stream the audio stream to unlock.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety You should only call this from the same thread that
+ * previously called SDL_LockAudioStream.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_LockAudioStream
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_UnlockAudioStream(SDL_AudioStream *stream);
+
+/**
+ * A callback that fires when data passes through an SDL_AudioStream.
+ *
+ * Apps can (optionally) register a callback with an audio stream that is
+ * called when data is added with SDL_PutAudioStreamData, or requested with
+ * SDL_GetAudioStreamData.
+ *
+ * Two values are offered here: one is the amount of additional data needed to
+ * satisfy the immediate request (which might be zero if the stream already
+ * has enough data queued) and the other is the total amount being requested.
+ * In a Get call triggering a Put callback, these values can be different. In
+ * a Put call triggering a Get callback, these values are always the same.
+ *
+ * Byte counts might be slightly overestimated due to buffering or resampling,
+ * and may change from call to call.
+ *
+ * This callback is not required to do anything. Generally this is useful for
+ * adding/reading data on demand, and the app will often put/get data as
+ * appropriate, but the system goes on with the data currently available to it
+ * if this callback does nothing.
+ *
+ * \param stream the SDL audio stream associated with this callback.
+ * \param additional_amount the amount of data, in bytes, that is needed right
+ * now.
+ * \param total_amount the total amount of data requested, in bytes, that is
+ * requested or available.
+ * \param userdata an opaque pointer provided by the app for their personal
+ * use.
+ *
+ * \threadsafety This callbacks may run from any thread, so if you need to
+ * protect shared data, you should use SDL_LockAudioStream to
+ * serialize access; this lock will be held before your callback
+ * is called, so your callback does not need to manage the lock
+ * explicitly.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamGetCallback
+ * \sa SDL_SetAudioStreamPutCallback
+ */
+typedef void (SDLCALL *SDL_AudioStreamCallback)(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount);
+
+/**
+ * Set a callback that runs when data is requested from an audio stream.
+ *
+ * This callback is called _before_ data is obtained from the stream, giving
+ * the callback the chance to add more on-demand.
+ *
+ * The callback can (optionally) call SDL_PutAudioStreamData() to add more
+ * audio to the stream during this call; if needed, the request that triggered
+ * this callback will obtain the new data immediately.
+ *
+ * The callback's `additional_amount` argument is roughly how many bytes of
+ * _unconverted_ data (in the stream's input format) is needed by the caller,
+ * although this may overestimate a little for safety. This takes into account
+ * how much is already in the stream and only asks for any extra necessary to
+ * resolve the request, which means the callback may be asked for zero bytes,
+ * and a different amount on each call.
+ *
+ * The callback is not required to supply exact amounts; it is allowed to
+ * supply too much or too little or none at all. The caller will get what's
+ * available, up to the amount they requested, regardless of this callback's
+ * outcome.
+ *
+ * Clearing or flushing an audio stream does not call this callback.
+ *
+ * This function obtains the stream's lock, which means any existing callback
+ * (get or put) in progress will finish running before setting the new
+ * callback.
+ *
+ * Setting a NULL function turns off the callback.
+ *
+ * \param stream the audio stream to set the new callback on.
+ * \param callback the new callback function to call when data is requested
+ * from the stream.
+ * \param userdata an opaque pointer provided to the callback for its own
+ * personal use.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information. This only fails if `stream` is NULL.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamPutCallback
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata);
+
+/**
+ * Set a callback that runs when data is added to an audio stream.
+ *
+ * This callback is called _after_ the data is added to the stream, giving the
+ * callback the chance to obtain it immediately.
+ *
+ * The callback can (optionally) call SDL_GetAudioStreamData() to obtain audio
+ * from the stream during this call.
+ *
+ * The callback's `additional_amount` argument is how many bytes of
+ * _converted_ data (in the stream's output format) was provided by the
+ * caller, although this may underestimate a little for safety. This value
+ * might be less than what is currently available in the stream, if data was
+ * already there, and might be less than the caller provided if the stream
+ * needs to keep a buffer to aid in resampling. Which means the callback may
+ * be provided with zero bytes, and a different amount on each call.
+ *
+ * The callback may call SDL_GetAudioStreamAvailable to see the total amount
+ * currently available to read from the stream, instead of the total provided
+ * by the current call.
+ *
+ * The callback is not required to obtain all data. It is allowed to read less
+ * or none at all. Anything not read now simply remains in the stream for
+ * later access.
+ *
+ * Clearing or flushing an audio stream does not call this callback.
+ *
+ * This function obtains the stream's lock, which means any existing callback
+ * (get or put) in progress will finish running before setting the new
+ * callback.
+ *
+ * Setting a NULL function turns off the callback.
+ *
+ * \param stream the audio stream to set the new callback on.
+ * \param callback the new callback function to call when data is added to the
+ * stream.
+ * \param userdata an opaque pointer provided to the callback for its own
+ * personal use.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information. This only fails if `stream` is NULL.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamGetCallback
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata);
+
+
+/**
+ * Free an audio stream.
+ *
+ * This will release all allocated data, including any audio that is still
+ * queued. You do not need to manually clear the stream first.
+ *
+ * If this stream was bound to an audio device, it is unbound during this
+ * call. If this stream was created with SDL_OpenAudioDeviceStream, the audio
+ * device that was opened alongside this stream's creation will be closed,
+ * too.
+ *
+ * \param stream the audio stream to destroy.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateAudioStream
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream);
+
+
+/**
+ * Convenience function for straightforward audio init for the common case.
+ *
+ * If all your app intends to do is provide a single source of PCM audio, this
+ * function allows you to do all your audio setup in a single call.
+ *
+ * This is also intended to be a clean means to migrate apps from SDL2.
+ *
+ * This function will open an audio device, create a stream and bind it.
+ * Unlike other methods of setup, the audio device will be closed when this
+ * stream is destroyed, so the app can treat the returned SDL_AudioStream as
+ * the only object needed to manage audio playback.
+ *
+ * Also unlike other functions, the audio device begins paused. This is to map
+ * more closely to SDL2-style behavior, since there is no extra step here to
+ * bind a stream to begin audio flowing. The audio device should be resumed
+ * with `SDL_ResumeAudioStreamDevice(stream);`
+ *
+ * This function works with both playback and recording devices.
+ *
+ * The `spec` parameter represents the app's side of the audio stream. That
+ * is, for recording audio, this will be the output format, and for playing
+ * audio, this will be the input format. If spec is NULL, the system will
+ * choose the format, and the app can use SDL_GetAudioStreamFormat() to obtain
+ * this information later.
+ *
+ * If you don't care about opening a specific audio device, you can (and
+ * probably _should_), use SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK for playback and
+ * SDL_AUDIO_DEVICE_DEFAULT_RECORDING for recording.
+ *
+ * One can optionally provide a callback function; if NULL, the app is
+ * expected to queue audio data for playback (or unqueue audio data if
+ * capturing). Otherwise, the callback will begin to fire once the device is
+ * unpaused.
+ *
+ * Destroying the returned stream with SDL_DestroyAudioStream will also close
+ * the audio device associated with this stream.
+ *
+ * \param devid an audio device to open, or SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK
+ * or SDL_AUDIO_DEVICE_DEFAULT_RECORDING.
+ * \param spec the audio stream's data format. Can be NULL.
+ * \param callback a callback where the app will provide new data for
+ * playback, or receive new data for recording. Can be NULL,
+ * in which case the app will need to call
+ * SDL_PutAudioStreamData or SDL_GetAudioStreamData as
+ * necessary.
+ * \param userdata app-controlled pointer passed to callback. Can be NULL.
+ * Ignored if callback is NULL.
+ * \returns an audio stream on success, ready to use, or NULL on failure; call
+ * SDL_GetError() for more information. When done with this stream,
+ * call SDL_DestroyAudioStream to free resources and close the
+ * device.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAudioStreamDevice
+ * \sa SDL_ResumeAudioStreamDevice
+ */
+extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec, SDL_AudioStreamCallback callback, void *userdata);
+
+/**
+ * A callback that fires when data is about to be fed to an audio device.
+ *
+ * This is useful for accessing the final mix, perhaps for writing a
+ * visualizer or applying a final effect to the audio data before playback.
+ *
+ * This callback should run as quickly as possible and not block for any
+ * significant time, as this callback delays submission of data to the audio
+ * device, which can cause audio playback problems.
+ *
+ * The postmix callback _must_ be able to handle any audio data format
+ * specified in `spec`, which can change between callbacks if the audio device
+ * changed. However, this only covers frequency and channel count; data is
+ * always provided here in SDL_AUDIO_F32 format.
+ *
+ * The postmix callback runs _after_ logical device gain and audiostream gain
+ * have been applied, which is to say you can make the output data louder at
+ * this point than the gain settings would suggest.
+ *
+ * \param userdata a pointer provided by the app through
+ * SDL_SetAudioPostmixCallback, for its own use.
+ * \param spec the current format of audio that is to be submitted to the
+ * audio device.
+ * \param buffer the buffer of audio samples to be submitted. The callback can
+ * inspect and/or modify this data.
+ * \param buflen the size of `buffer` in bytes.
+ *
+ * \threadsafety This will run from a background thread owned by SDL. The
+ * application is responsible for locking resources the callback
+ * touches that need to be protected.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioPostmixCallback
+ */
+typedef void (SDLCALL *SDL_AudioPostmixCallback)(void *userdata, const SDL_AudioSpec *spec, float *buffer, int buflen);
+
+/**
+ * Set a callback that fires when data is about to be fed to an audio device.
+ *
+ * This is useful for accessing the final mix, perhaps for writing a
+ * visualizer or applying a final effect to the audio data before playback.
+ *
+ * The buffer is the final mix of all bound audio streams on an opened device;
+ * this callback will fire regularly for any device that is both opened and
+ * unpaused. If there is no new data to mix, either because no streams are
+ * bound to the device or all the streams are empty, this callback will still
+ * fire with the entire buffer set to silence.
+ *
+ * This callback is allowed to make changes to the data; the contents of the
+ * buffer after this call is what is ultimately passed along to the hardware.
+ *
+ * The callback is always provided the data in float format (values from -1.0f
+ * to 1.0f), but the number of channels or sample rate may be different than
+ * the format the app requested when opening the device; SDL might have had to
+ * manage a conversion behind the scenes, or the playback might have jumped to
+ * new physical hardware when a system default changed, etc. These details may
+ * change between calls. Accordingly, the size of the buffer might change
+ * between calls as well.
+ *
+ * This callback can run at any time, and from any thread; if you need to
+ * serialize access to your app's data, you should provide and use a mutex or
+ * other synchronization device.
+ *
+ * All of this to say: there are specific needs this callback can fulfill, but
+ * it is not the simplest interface. Apps should generally provide audio in
+ * their preferred format through an SDL_AudioStream and let SDL handle the
+ * difference.
+ *
+ * This function is extremely time-sensitive; the callback should do the least
+ * amount of work possible and return as quickly as it can. The longer the
+ * callback runs, the higher the risk of audio dropouts or other problems.
+ *
+ * This function will block until the audio device is in between iterations,
+ * so any existing callback that might be running will finish before this
+ * function sets the new callback and returns.
+ *
+ * Setting a NULL callback function disables any previously-set callback.
+ *
+ * \param devid the ID of an opened audio device.
+ * \param callback a callback function to be called. Can be NULL.
+ * \param userdata app-controlled pointer passed to callback. Can be NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, SDL_AudioPostmixCallback callback, void *userdata);
+
+
+/**
+ * Load the audio data of a WAVE file into memory.
+ *
+ * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to
+ * be valid pointers. The entire data portion of the file is then loaded into
+ * memory and decoded if necessary.
+ *
+ * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and
+ * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and
+ * A-law and mu-law (8 bits). Other formats are currently unsupported and
+ * cause an error.
+ *
+ * If this function succeeds, the return value is zero and the pointer to the
+ * audio data allocated by the function is written to `audio_buf` and its
+ * length in bytes to `audio_len`. The SDL_AudioSpec members `freq`,
+ * `channels`, and `format` are set to the values of the audio data in the
+ * buffer.
+ *
+ * It's necessary to use SDL_free() to free the audio data returned in
+ * `audio_buf` when it is no longer used.
+ *
+ * Because of the underspecification of the .WAV format, there are many
+ * problematic files in the wild that cause issues with strict decoders. To
+ * provide compatibility with these files, this decoder is lenient in regards
+ * to the truncation of the file, the fact chunk, and the size of the RIFF
+ * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`,
+ * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to
+ * tune the behavior of the loading process.
+ *
+ * Any file that is invalid (due to truncation, corruption, or wrong values in
+ * the headers), too big, or unsupported causes an error. Additionally, any
+ * critical I/O error from the data source will terminate the loading process
+ * with an error. The function returns NULL on error and in all cases (with
+ * the exception of `src` being NULL), an appropriate error message will be
+ * set.
+ *
+ * It is required that the data source supports seeking.
+ *
+ * Example:
+ *
+ * ```c
+ * SDL_LoadWAV_IO(SDL_IOFromFile("sample.wav", "rb"), true, &spec, &buf, &len);
+ * ```
+ *
+ * Note that the SDL_LoadWAV function does this same thing for you, but in a
+ * less messy way:
+ *
+ * ```c
+ * SDL_LoadWAV("sample.wav", &spec, &buf, &len);
+ * ```
+ *
+ * \param src the data source for the WAVE data.
+ * \param closeio if true, calls SDL_CloseIO() on `src` before returning, even
+ * in the case of an error.
+ * \param spec a pointer to an SDL_AudioSpec that will be set to the WAVE
+ * data's format details on successful return.
+ * \param audio_buf a pointer filled with the audio data, allocated by the
+ * function.
+ * \param audio_len a pointer filled with the length of the audio data buffer
+ * in bytes.
+ * \returns true on success. `audio_buf` will be filled with a pointer to an
+ * allocated buffer containing the audio data, and `audio_len` is
+ * filled with the length of that audio buffer in bytes.
+ *
+ * This function returns false if the .WAV file cannot be opened,
+ * uses an unknown data format, or is corrupt; call SDL_GetError()
+ * for more information.
+ *
+ * When the application is done with the data returned in
+ * `audio_buf`, it should call SDL_free() to dispose of it.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_free
+ * \sa SDL_LoadWAV
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
+
+/**
+ * Loads a WAV from a file path.
+ *
+ * This is a convenience function that is effectively the same as:
+ *
+ * ```c
+ * SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), true, spec, audio_buf, audio_len);
+ * ```
+ *
+ * \param path the file path of the WAV file to open.
+ * \param spec a pointer to an SDL_AudioSpec that will be set to the WAVE
+ * data's format details on successful return.
+ * \param audio_buf a pointer filled with the audio data, allocated by the
+ * function.
+ * \param audio_len a pointer filled with the length of the audio data buffer
+ * in bytes.
+ * \returns true on success. `audio_buf` will be filled with a pointer to an
+ * allocated buffer containing the audio data, and `audio_len` is
+ * filled with the length of that audio buffer in bytes.
+ *
+ * This function returns false if the .WAV file cannot be opened,
+ * uses an unknown data format, or is corrupt; call SDL_GetError()
+ * for more information.
+ *
+ * When the application is done with the data returned in
+ * `audio_buf`, it should call SDL_free() to dispose of it.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_free
+ * \sa SDL_LoadWAV_IO
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
+
+/**
+ * Mix audio data in a specified format.
+ *
+ * This takes an audio buffer `src` of `len` bytes of `format` data and mixes
+ * it into `dst`, performing addition, volume adjustment, and overflow
+ * clipping. The buffer pointed to by `dst` must also be `len` bytes of
+ * `format` data.
+ *
+ * This is provided for convenience -- you can mix your own audio data.
+ *
+ * Do not use this function for mixing together more than two streams of
+ * sample data. The output from repeated application of this function may be
+ * distorted by clipping, because there is no accumulator with greater range
+ * than the input (not to mention this being an inefficient way of doing it).
+ *
+ * It is a common misconception that this function is required to write audio
+ * data to an output stream in an audio callback. While you can do that,
+ * SDL_MixAudio() is really only needed when you're mixing a single audio
+ * stream with a volume adjustment.
+ *
+ * \param dst the destination for the mixed audio.
+ * \param src the source audio buffer to be mixed.
+ * \param format the SDL_AudioFormat structure representing the desired audio
+ * format.
+ * \param len the length of the audio buffer in bytes.
+ * \param volume ranges from 0.0 - 1.0, and should be set to 1.0 for full
+ * audio volume.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_MixAudio(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, float volume);
+
+/**
+ * Convert some audio data of one format to another format.
+ *
+ * Please note that this function is for convenience, but should not be used
+ * to resample audio in blocks, as it will introduce audio artifacts on the
+ * boundaries. You should only use this function if you are converting audio
+ * data in its entirety in one call. If you want to convert audio in smaller
+ * chunks, use an SDL_AudioStream, which is designed for this situation.
+ *
+ * Internally, this function creates and destroys an SDL_AudioStream on each
+ * use, so it's also less efficient than using one directly, if you need to
+ * convert multiple times.
+ *
+ * \param src_spec the format details of the input audio.
+ * \param src_data the audio data to be converted.
+ * \param src_len the len of src_data.
+ * \param dst_spec the format details of the output audio.
+ * \param dst_data will be filled with a pointer to converted audio data,
+ * which should be freed with SDL_free(). On error, it will be
+ * NULL.
+ * \param dst_len will be filled with the len of dst_data.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len);
+
+/**
+ * Get the human readable name of an audio format.
+ *
+ * \param format the audio format to query.
+ * \returns the human readable name of the specified audio format or
+ * "SDL_AUDIO_UNKNOWN" if the format isn't recognized.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetAudioFormatName(SDL_AudioFormat format);
+
+/**
+ * Get the appropriate memset value for silencing an audio format.
+ *
+ * The value returned by this function can be used as the second argument to
+ * memset (or SDL_memset) to set an audio buffer in a specific format to
+ * silence.
+ *
+ * \param format the audio data format to query.
+ * \returns a byte value that can be passed to memset.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetSilenceValueForFormat(SDL_AudioFormat format);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_audio_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_begin_code.h b/vendored/SDL/include/SDL3/SDL_begin_code.h
new file mode 100644
index 0000000..a6b47cf
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_begin_code.h
@@ -0,0 +1,486 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: BeginCode */
+
+/**
+ * # CategoryBeginCode
+ *
+ * `SDL_begin_code.h` sets things up for C dynamic library function
+ * definitions, static inlined functions, and structures aligned at 4-byte
+ * alignment. If you don't like ugly C preprocessor code, don't look at this
+ * file. :)
+ *
+ * SDL's headers use this; applications generally should not include this
+ * header directly.
+ */
+
+/* This shouldn't be nested -- included it around code only. */
+#ifdef SDL_begin_code_h
+#error Nested inclusion of SDL_begin_code.h
+#endif
+#define SDL_begin_code_h
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro to tag a symbol as deprecated.
+ *
+ * A function is marked deprecated by adding this macro to its declaration:
+ *
+ * ```c
+ * extern SDL_DEPRECATED int ThisFunctionWasABadIdea(void);
+ * ```
+ *
+ * Compilers with deprecation support can give a warning when a deprecated
+ * function is used. This symbol may be used in SDL's headers, but apps are
+ * welcome to use it for their own interfaces as well.
+ *
+ * SDL, on occasion, might deprecate a function for various reasons. However,
+ * SDL never removes symbols before major versions, so deprecated interfaces
+ * in SDL3 will remain available until SDL4, where it would be expected an app
+ * would have to take steps to migrate anyhow.
+ *
+ * On compilers without a deprecation mechanism, this is defined to nothing,
+ * and using a deprecated function will not generate a warning.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_DEPRECATED __attribute__((deprecated))
+
+/**
+ * A macro to tag a symbol as a public API.
+ *
+ * SDL uses this macro for all its public functions. On some targets, it is
+ * used to signal to the compiler that this function needs to be exported from
+ * a shared library, but it might have other side effects.
+ *
+ * This symbol is used in SDL's headers, but apps and other libraries are
+ * welcome to use it for their own interfaces as well.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_DECLSPEC __attribute__ ((visibility("default")))
+
+/**
+ * A macro to set a function's calling conventions.
+ *
+ * SDL uses this macro for all its public functions, and any callbacks it
+ * defines. This macro guarantees that calling conventions match between SDL
+ * and the app, even if the two were built with different compilers or
+ * optimization settings.
+ *
+ * When writing a callback function, it is very important for it to be
+ * correctly tagged with SDLCALL, as mismatched calling conventions can cause
+ * strange behaviors and can be difficult to diagnose. Plus, on many
+ * platforms, SDLCALL is defined to nothing, so compilers won't be able to
+ * warn that the tag is missing.
+ *
+ * This symbol is used in SDL's headers, but apps and other libraries are
+ * welcome to use it for their own interfaces as well.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDLCALL __cdecl
+
+/**
+ * A macro to request a function be inlined.
+ *
+ * This is a hint to the compiler to inline a function. The compiler is free
+ * to ignore this request. On compilers without inline support, this is
+ * defined to nothing.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_INLINE __inline
+
+/**
+ * A macro to demand a function be inlined.
+ *
+ * This is a command to the compiler to inline a function. SDL uses this macro
+ * in its public headers for a handful of simple functions. On compilers
+ * without forceinline support, this is defined to `static SDL_INLINE`, which
+ * is often good enough.
+ *
+ * This symbol is used in SDL's headers, but apps and other libraries are
+ * welcome to use it for their own interfaces as well.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_FORCE_INLINE __forceinline
+
+/**
+ * A macro to tag a function as never-returning.
+ *
+ * This is a hint to the compiler that a function does not return. An example
+ * of a function like this is the C runtime's exit() function.
+ *
+ * This hint can lead to code optimizations, and help analyzers understand
+ * code flow better. On compilers without noreturn support, this is defined to
+ * nothing.
+ *
+ * This symbol is used in SDL's headers, but apps and other libraries are
+ * welcome to use it for their own interfaces as well.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_NORETURN __attribute__((noreturn))
+
+/**
+ * A macro to tag a function as never-returning (for analysis purposes).
+ *
+ * This is almost identical to SDL_NORETURN, except functions marked with this
+ * _can_ actually return. The difference is that this isn't used for code
+ * generation, but rather static analyzers use this information to assume
+ * truths about program state and available code paths. Specifically, this tag
+ * is useful for writing an assertion mechanism. Indeed, SDL_assert uses this
+ * tag behind the scenes. Generally, apps that don't understand the specific
+ * use-case for this tag should avoid using it directly.
+ *
+ * On compilers without analyzer_noreturn support, this is defined to nothing.
+ *
+ * This symbol is used in SDL's headers, but apps and other libraries are
+ * welcome to use it for their own interfaces as well.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+
+
+/**
+ * A macro to signal that a case statement without a `break` is intentional.
+ *
+ * C compilers have gotten more aggressive about warning when a switch's
+ * `case` block does not end with a `break` or other flow control statement,
+ * flowing into the next case's code, as this is a common accident that leads
+ * to strange bugs. But sometimes falling through to the next case is the
+ * correct and desired behavior. This symbol lets an app communicate this
+ * intention to the compiler, so it doesn't generate a warning.
+ *
+ * It is used like this:
+ *
+ * ```c
+ * switch (x) {
+ * case 1:
+ * DoSomethingOnlyForOne();
+ * SDL_FALLTHROUGH; // tell the compiler this was intentional.
+ * case 2:
+ * DoSomethingForOneAndTwo();
+ * break;
+ * }
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_FALLTHROUGH [[fallthrough]]
+
+/**
+ * A macro to tag a function's return value as critical.
+ *
+ * This is a hint to the compiler that a function's return value should not be
+ * ignored.
+ *
+ * If an NODISCARD function's return value is thrown away (the function is
+ * called as if it returns `void`), the compiler will issue a warning.
+ *
+ * While it's generally good practice to check return values for errors, often
+ * times legitimate programs do not for good reasons. Be careful about what
+ * functions are tagged as NODISCARD. It operates best when used on a function
+ * that's failure is surprising and catastrophic; a good example would be a
+ * program that checks the return values of all its file write function calls
+ * but not the call to close the file, which it assumes incorrectly never
+ * fails.
+ *
+ * Function callers that want to throw away a NODISCARD return value can call
+ * the function with a `(void)` cast, which informs the compiler the act is
+ * intentional.
+ *
+ * On compilers without nodiscard support, this is defined to nothing.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_NODISCARD [[nodiscard]]
+
+/**
+ * A macro to tag a function as an allocator.
+ *
+ * This is a hint to the compiler that a function is an allocator, like
+ * malloc(), with certain rules. A description of how GCC treats this hint is
+ * here:
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
+ *
+ * On compilers without allocator tag support, this is defined to nothing.
+ *
+ * Most apps don't need to, and should not, use this directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
+
+/**
+ * A macro to tag a function as returning a certain allocation.
+ *
+ * This is a hint to the compiler that a function allocates and returns a
+ * specific amount of memory based on one of its arguments. For example, the C
+ * runtime's malloc() function could use this macro with an argument of 1
+ * (first argument to malloc is the size of the allocation).
+ *
+ * On compilers without alloc_size support, this is defined to nothing.
+ *
+ * Most apps don't need to, and should not, use this directly.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
+
+/**
+ * A macro to tag a pointer variable, to help with pointer aliasing.
+ *
+ * A good explanation of the restrict keyword is here:
+ *
+ * https://en.wikipedia.org/wiki/Restrict
+ *
+ * On compilers without restrict support, this is defined to nothing.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_RESTRICT __restrict__
+
+/**
+ * Check if the compiler supports a given builtin functionality.
+ *
+ * This allows preprocessor checks for things that otherwise might fail to
+ * compile.
+ *
+ * Supported by virtually all clang versions and more-recent GCCs. Use this
+ * instead of checking the clang version if possible.
+ *
+ * On compilers without has_builtin support, this is defined to 0 (always
+ * false).
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_HAS_BUILTIN(x) __has_builtin(x)
+
+/* end of wiki documentation section. */
+#endif
+
+#ifndef SDL_HAS_BUILTIN
+#ifdef __has_builtin
+#define SDL_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#define SDL_HAS_BUILTIN(x) 0
+#endif
+#endif
+
+#ifndef SDL_DEPRECATED
+# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
+# define SDL_DEPRECATED __attribute__((deprecated))
+# elif defined(_MSC_VER)
+# define SDL_DEPRECATED __declspec(deprecated)
+# else
+# define SDL_DEPRECATED
+# endif
+#endif
+
+#ifndef SDL_UNUSED
+# ifdef __GNUC__
+# define SDL_UNUSED __attribute__((unused))
+# else
+# define SDL_UNUSED
+# endif
+#endif
+
+/* Some compilers use a special export keyword */
+#ifndef SDL_DECLSPEC
+# if defined(SDL_PLATFORM_WINDOWS)
+# ifdef DLL_EXPORT
+# define SDL_DECLSPEC __declspec(dllexport)
+# else
+# define SDL_DECLSPEC
+# endif
+# else
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define SDL_DECLSPEC __attribute__ ((visibility("default")))
+# else
+# define SDL_DECLSPEC
+# endif
+# endif
+#endif
+
+/* By default SDL uses the C calling convention */
+#ifndef SDLCALL
+#if defined(SDL_PLATFORM_WINDOWS) && !defined(__GNUC__)
+#define SDLCALL __cdecl
+#else
+#define SDLCALL
+#endif
+#endif /* SDLCALL */
+
+/* Force structure packing at 4 byte alignment.
+ This is necessary if the header is included in code which has structure
+ packing set to an alternate value, say for loading structures from disk.
+ The packing is reset to the previous value in SDL_close_code.h
+ */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef _MSC_VER
+#pragma warning(disable: 4103)
+#endif
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wpragma-pack"
+#endif
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#ifdef _WIN64
+/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
+#pragma pack(push,8)
+#else
+#pragma pack(push,4)
+#endif
+#endif /* Compiler needs structure packing set */
+
+#ifndef SDL_INLINE
+#ifdef __GNUC__
+#define SDL_INLINE __inline__
+#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__DMC__) || defined(__SC__) || \
+ defined(__WATCOMC__) || defined(__LCC__) || \
+ defined(__DECC) || defined(__CC_ARM)
+#define SDL_INLINE __inline
+#ifndef __inline__
+#define __inline__ __inline
+#endif
+#else
+#define SDL_INLINE inline
+#ifndef __inline__
+#define __inline__ inline
+#endif
+#endif
+#endif /* SDL_INLINE not defined */
+
+#ifndef SDL_FORCE_INLINE
+#ifdef _MSC_VER
+#define SDL_FORCE_INLINE __forceinline
+#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
+#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
+#else
+#define SDL_FORCE_INLINE static SDL_INLINE
+#endif
+#endif /* SDL_FORCE_INLINE not defined */
+
+#ifndef SDL_NORETURN
+#ifdef __GNUC__
+#define SDL_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define SDL_NORETURN __declspec(noreturn)
+#else
+#define SDL_NORETURN
+#endif
+#endif /* SDL_NORETURN not defined */
+
+#ifdef __clang__
+#if __has_feature(attribute_analyzer_noreturn)
+#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+#endif
+#endif
+
+#ifndef SDL_ANALYZER_NORETURN
+#define SDL_ANALYZER_NORETURN
+#endif
+
+/* Apparently this is needed by several Windows compilers */
+#ifndef __MACH__
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif /* NULL */
+#endif /* ! macOS - breaks precompiled headers */
+
+#ifndef SDL_FALLTHROUGH
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
+ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
+#define SDL_FALLTHROUGH [[fallthrough]]
+#else
+#if defined(__has_attribute) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
+#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
+#else
+#define SDL_HAS_FALLTHROUGH 0
+#endif /* __has_attribute */
+#if SDL_HAS_FALLTHROUGH && \
+ ((defined(__GNUC__) && __GNUC__ >= 7) || \
+ (defined(__clang_major__) && __clang_major__ >= 10))
+#define SDL_FALLTHROUGH __attribute__((__fallthrough__))
+#else
+#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
+#endif /* SDL_HAS_FALLTHROUGH */
+#undef SDL_HAS_FALLTHROUGH
+#endif /* C++17 or C2x */
+#endif /* SDL_FALLTHROUGH not defined */
+
+#ifndef SDL_NODISCARD
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
+ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
+#define SDL_NODISCARD [[nodiscard]]
+#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
+#define SDL_NODISCARD __attribute__((warn_unused_result))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
+#define SDL_NODISCARD _Check_return_
+#else
+#define SDL_NODISCARD
+#endif /* C++17 or C23 */
+#endif /* SDL_NODISCARD not defined */
+
+#ifndef SDL_MALLOC
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define SDL_MALLOC __attribute__((malloc))
+/** FIXME
+#elif defined(_MSC_VER)
+#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
+**/
+#else
+#define SDL_MALLOC
+#endif
+#endif /* SDL_MALLOC not defined */
+
+#ifndef SDL_ALLOC_SIZE
+#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
+#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
+#elif defined(_MSC_VER)
+#define SDL_ALLOC_SIZE(p)
+#else
+#define SDL_ALLOC_SIZE(p)
+#endif
+#endif /* SDL_ALLOC_SIZE not defined */
+
+#ifndef SDL_ALLOC_SIZE2
+#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
+#define SDL_ALLOC_SIZE2(p1, p2) __attribute__((alloc_size(p1, p2)))
+#elif defined(_MSC_VER)
+#define SDL_ALLOC_SIZE2(p1, p2)
+#else
+#define SDL_ALLOC_SIZE2(p1, p2)
+#endif
+#endif /* SDL_ALLOC_SIZE2 not defined */
diff --git a/vendored/SDL/include/SDL3/SDL_bits.h b/vendored/SDL/include/SDL3/SDL_bits.h
new file mode 100644
index 0000000..7435ce6
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_bits.h
@@ -0,0 +1,147 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryBits
+ *
+ * Functions for fiddling with bits and bitmasks.
+ */
+
+#ifndef SDL_bits_h_
+#define SDL_bits_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__WATCOMC__) && defined(__386__)
+extern __inline int _SDL_bsr_watcom(Uint32);
+#pragma aux _SDL_bsr_watcom = \
+ "bsr eax, eax" \
+ parm [eax] nomemory \
+ value [eax] \
+ modify exact [eax] nomemory;
+#endif
+
+/**
+ * Get the index of the most significant (set) bit in a 32-bit number.
+ *
+ * Result is undefined when called with 0. This operation can also be stated
+ * as "count leading zeroes" and "log base 2".
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the 32-bit value to examine.
+ * \returns the index of the most significant bit, or -1 if the value is 0.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+ /* Count Leading Zeroes builtin in GCC.
+ * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
+ */
+ if (x == 0) {
+ return -1;
+ }
+ return 31 - __builtin_clz(x);
+#elif defined(__WATCOMC__) && defined(__386__)
+ if (x == 0) {
+ return -1;
+ }
+ return _SDL_bsr_watcom(x);
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+ unsigned long index;
+ if (_BitScanReverse(&index, x)) {
+ return (int)index;
+ }
+ return -1;
+#else
+ /* Based off of Bit Twiddling Hacks by Sean Eron Anderson
+ * , released in the public domain.
+ * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
+ */
+ const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
+ const int S[] = {1, 2, 4, 8, 16};
+
+ int msbIndex = 0;
+ int i;
+
+ if (x == 0) {
+ return -1;
+ }
+
+ for (i = 4; i >= 0; i--)
+ {
+ if (x & b[i])
+ {
+ x >>= S[i];
+ msbIndex |= S[i];
+ }
+ }
+
+ return msbIndex;
+#endif
+}
+
+/**
+ * Determine if a unsigned 32-bit value has exactly one bit set.
+ *
+ * If there are no bits set (`x` is zero), or more than one bit set, this
+ * returns false. If any one bit is exclusively set, this returns true.
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the 32-bit value to examine.
+ * \returns true if exactly one bit is set in `x`, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE bool SDL_HasExactlyOneBitSet32(Uint32 x)
+{
+ if (x && !(x & (x - 1))) {
+ return true;
+ }
+ return false;
+}
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_bits_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_blendmode.h b/vendored/SDL/include/SDL3/SDL_blendmode.h
new file mode 100644
index 0000000..8f00cbc
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_blendmode.h
@@ -0,0 +1,202 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryBlendmode
+ *
+ * Blend modes decide how two colors will mix together. There are both
+ * standard modes for basic needs and a means to create custom modes,
+ * dictating what sort of math to do on what color components.
+ */
+
+#ifndef SDL_blendmode_h_
+#define SDL_blendmode_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A set of blend modes used in drawing operations.
+ *
+ * These predefined blend modes are supported everywhere.
+ *
+ * Additional values may be obtained from SDL_ComposeCustomBlendMode.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_ComposeCustomBlendMode
+ */
+typedef Uint32 SDL_BlendMode;
+
+#define SDL_BLENDMODE_NONE 0x00000000u /**< no blending: dstRGBA = srcRGBA */
+#define SDL_BLENDMODE_BLEND 0x00000001u /**< alpha blending: dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)), dstA = srcA + (dstA * (1-srcA)) */
+#define SDL_BLENDMODE_BLEND_PREMULTIPLIED 0x00000010u /**< pre-multiplied alpha blending: dstRGBA = srcRGBA + (dstRGBA * (1-srcA)) */
+#define SDL_BLENDMODE_ADD 0x00000002u /**< additive blending: dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA */
+#define SDL_BLENDMODE_ADD_PREMULTIPLIED 0x00000020u /**< pre-multiplied additive blending: dstRGB = srcRGB + dstRGB, dstA = dstA */
+#define SDL_BLENDMODE_MOD 0x00000004u /**< color modulate: dstRGB = srcRGB * dstRGB, dstA = dstA */
+#define SDL_BLENDMODE_MUL 0x00000008u /**< color multiply: dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)), dstA = dstA */
+#define SDL_BLENDMODE_INVALID 0x7FFFFFFFu
+
+/**
+ * The blend operation used when combining source and destination pixel
+ * components.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_BlendOperation
+{
+ SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
+ SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< src - dst : supported by D3D, OpenGL, OpenGLES, and Vulkan */
+ SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< dst - src : supported by D3D, OpenGL, OpenGLES, and Vulkan */
+ SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
+ SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
+} SDL_BlendOperation;
+
+/**
+ * The normalized factor used to multiply pixel components.
+ *
+ * The blend factors are multiplied with the pixels from a drawing operation
+ * (src) and the pixels from the render target (dst) before the blend
+ * operation. The comma-separated factors listed above are always applied in
+ * the component order red, green, blue, and alpha.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_BlendFactor
+{
+ SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */
+ SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */
+ SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */
+ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */
+ SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */
+ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */
+ SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */
+ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
+ SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
+ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
+} SDL_BlendFactor;
+
+/**
+ * Compose a custom blend mode for renderers.
+ *
+ * The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept
+ * the SDL_BlendMode returned by this function if the renderer supports it.
+ *
+ * A blend mode controls how the pixels from a drawing operation (source) get
+ * combined with the pixels from the render target (destination). First, the
+ * components of the source and destination pixels get multiplied with their
+ * blend factors. Then, the blend operation takes the two products and
+ * calculates the result that will get stored in the render target.
+ *
+ * Expressed in pseudocode, it would look like this:
+ *
+ * ```c
+ * dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor);
+ * dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor);
+ * ```
+ *
+ * Where the functions `colorOperation(src, dst)` and `alphaOperation(src,
+ * dst)` can return one of the following:
+ *
+ * - `src + dst`
+ * - `src - dst`
+ * - `dst - src`
+ * - `min(src, dst)`
+ * - `max(src, dst)`
+ *
+ * The red, green, and blue components are always multiplied with the first,
+ * second, and third components of the SDL_BlendFactor, respectively. The
+ * fourth component is not used.
+ *
+ * The alpha component is always multiplied with the fourth component of the
+ * SDL_BlendFactor. The other components are not used in the alpha
+ * calculation.
+ *
+ * Support for these blend modes varies for each renderer. To check if a
+ * specific SDL_BlendMode is supported, create a renderer and pass it to
+ * either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will
+ * return with an error if the blend mode is not supported.
+ *
+ * This list describes the support of custom blend modes for each renderer.
+ * All renderers support the four blend modes listed in the SDL_BlendMode
+ * enumeration.
+ *
+ * - **direct3d**: Supports all operations with all factors. However, some
+ * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
+ * `SDL_BLENDOPERATION_MAXIMUM`.
+ * - **direct3d11**: Same as Direct3D 9.
+ * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
+ * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly here.
+ * - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`,
+ * `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT`
+ * operations with all factors.
+ * - **psp**: No custom blend mode support.
+ * - **software**: No custom blend mode support.
+ *
+ * Some renderers do not provide an alpha component for the default render
+ * target. The `SDL_BLENDFACTOR_DST_ALPHA` and
+ * `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this
+ * case.
+ *
+ * \param srcColorFactor the SDL_BlendFactor applied to the red, green, and
+ * blue components of the source pixels.
+ * \param dstColorFactor the SDL_BlendFactor applied to the red, green, and
+ * blue components of the destination pixels.
+ * \param colorOperation the SDL_BlendOperation used to combine the red,
+ * green, and blue components of the source and
+ * destination pixels.
+ * \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of
+ * the source pixels.
+ * \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of
+ * the destination pixels.
+ * \param alphaOperation the SDL_BlendOperation used to combine the alpha
+ * component of the source and destination pixels.
+ * \returns an SDL_BlendMode that represents the chosen factors and
+ * operations.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetRenderDrawBlendMode
+ * \sa SDL_GetRenderDrawBlendMode
+ * \sa SDL_SetTextureBlendMode
+ * \sa SDL_GetTextureBlendMode
+ */
+extern SDL_DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor,
+ SDL_BlendFactor dstColorFactor,
+ SDL_BlendOperation colorOperation,
+ SDL_BlendFactor srcAlphaFactor,
+ SDL_BlendFactor dstAlphaFactor,
+ SDL_BlendOperation alphaOperation);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_blendmode_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_camera.h b/vendored/SDL/include/SDL3/SDL_camera.h
new file mode 100644
index 0000000..5f3911f
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_camera.h
@@ -0,0 +1,519 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryCamera
+ *
+ * Video capture for the SDL library.
+ *
+ * This API lets apps read input from video sources, like webcams. Camera
+ * devices can be enumerated, queried, and opened. Once opened, it will
+ * provide SDL_Surface objects as new frames of video come in. These surfaces
+ * can be uploaded to an SDL_Texture or processed as pixels in memory.
+ *
+ * Several platforms will alert the user if an app tries to access a camera,
+ * and some will present a UI asking the user if your application should be
+ * allowed to obtain images at all, which they can deny. A successfully opened
+ * camera will not provide images until permission is granted. Applications,
+ * after opening a camera device, can see if they were granted access by
+ * either polling with the SDL_GetCameraPermissionState() function, or waiting
+ * for an SDL_EVENT_CAMERA_DEVICE_APPROVED or SDL_EVENT_CAMERA_DEVICE_DENIED
+ * event. Platforms that don't have any user approval process will report
+ * approval immediately.
+ *
+ * Note that SDL cameras only provide video as individual frames; they will
+ * not provide full-motion video encoded in a movie file format, although an
+ * app is free to encode the acquired frames into any format it likes. It also
+ * does not provide audio from the camera hardware through this API; not only
+ * do many webcams not have microphones at all, many people--from streamers to
+ * people on Zoom calls--will want to use a separate microphone regardless of
+ * the camera. In any case, recorded audio will be available through SDL's
+ * audio API no matter what hardware provides the microphone.
+ *
+ * ## Camera gotchas
+ *
+ * Consumer-level camera hardware tends to take a little while to warm up,
+ * once the device has been opened. Generally most camera apps have some sort
+ * of UI to take a picture (a button to snap a pic while a preview is showing,
+ * some sort of multi-second countdown for the user to pose, like a photo
+ * booth), which puts control in the users' hands, or they are intended to
+ * stay on for long times (Pokemon Go, etc).
+ *
+ * It's not uncommon that a newly-opened camera will provide a couple of
+ * completely black frames, maybe followed by some under-exposed images. If
+ * taking a single frame automatically, or recording video from a camera's
+ * input without the user initiating it from a preview, it could be wise to
+ * drop the first several frames (if not the first several _seconds_ worth of
+ * frames!) before using images from a camera.
+ */
+
+#ifndef SDL_camera_h_
+#define SDL_camera_h_
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is a unique ID for a camera device for the time it is connected to the
+ * system, and is never reused for the lifetime of the application.
+ *
+ * If the device is disconnected and reconnected, it will get a new ID.
+ *
+ * The value 0 is an invalid ID.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameras
+ */
+typedef Uint32 SDL_CameraID;
+
+/**
+ * The opaque structure used to identify an opened SDL camera.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_Camera SDL_Camera;
+
+/**
+ * The details of an output format for a camera device.
+ *
+ * Cameras often support multiple formats; each one will be encapsulated in
+ * this struct.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameraSupportedFormats
+ * \sa SDL_GetCameraFormat
+ */
+typedef struct SDL_CameraSpec
+{
+ SDL_PixelFormat format; /**< Frame format */
+ SDL_Colorspace colorspace; /**< Frame colorspace */
+ int width; /**< Frame width */
+ int height; /**< Frame height */
+ int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
+ int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */
+} SDL_CameraSpec;
+
+/**
+ * The position of camera in relation to system device.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameraPosition
+ */
+typedef enum SDL_CameraPosition
+{
+ SDL_CAMERA_POSITION_UNKNOWN,
+ SDL_CAMERA_POSITION_FRONT_FACING,
+ SDL_CAMERA_POSITION_BACK_FACING
+} SDL_CameraPosition;
+
+
+/**
+ * Use this function to get the number of built-in camera drivers.
+ *
+ * This function returns a hardcoded number. This never returns a negative
+ * value; if there are no drivers compiled into this build of SDL, this
+ * function returns zero. The presence of a driver in this list does not mean
+ * it will function, it just means SDL is capable of interacting with that
+ * interface. For example, a build of SDL might have v4l2 support, but if
+ * there's no kernel support available, SDL's v4l2 driver would fail if used.
+ *
+ * By default, SDL tries all drivers, in its preferred order, until one is
+ * found to be usable.
+ *
+ * \returns the number of built-in camera drivers.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameraDriver
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
+
+/**
+ * Use this function to get the name of a built in camera driver.
+ *
+ * The list of camera drivers is given in the order that they are normally
+ * initialized by default; the drivers that seem more reasonable to choose
+ * first (as far as the SDL developers believe) are earlier in the list.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
+ * "coremedia" or "android". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \param index the index of the camera driver; the value ranges from 0 to
+ * SDL_GetNumCameraDrivers() - 1.
+ * \returns the name of the camera driver at the requested index, or NULL if
+ * an invalid index was specified.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetNumCameraDrivers
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraDriver(int index);
+
+/**
+ * Get the name of the current camera driver.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
+ * "coremedia" or "android". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \returns the name of the current camera driver or NULL if no driver has
+ * been initialized.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentCameraDriver(void);
+
+/**
+ * Get a list of currently connected camera devices.
+ *
+ * \param count a pointer filled in with the number of cameras returned, may
+ * be NULL.
+ * \returns a 0 terminated array of camera instance IDs or NULL on failure;
+ * call SDL_GetError() for more information. This should be freed
+ * with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenCamera
+ */
+extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
+
+/**
+ * Get the list of native formats/sizes a camera supports.
+ *
+ * This returns a list of all formats and frame sizes that a specific camera
+ * can offer. This is useful if your app can accept a variety of image formats
+ * and sizes and so want to find the optimal spec that doesn't require
+ * conversion.
+ *
+ * This function isn't strictly required; if you call SDL_OpenCamera with a
+ * NULL spec, SDL will choose a native format for you, and if you instead
+ * specify a desired format, it will transparently convert to the requested
+ * format on your behalf.
+ *
+ * If `count` is not NULL, it will be filled with the number of elements in
+ * the returned array.
+ *
+ * Note that it's legal for a camera to supply an empty list. This is what
+ * will happen on Emscripten builds, since that platform won't tell _anything_
+ * about available cameras until you've opened one, and won't even tell if
+ * there _is_ a camera until the user has given you permission to check
+ * through a scary warning popup.
+ *
+ * \param instance_id the camera device instance ID.
+ * \param count a pointer filled in with the number of elements in the list,
+ * may be NULL.
+ * \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on
+ * failure; call SDL_GetError() for more information. This is a
+ * single allocation that should be freed with SDL_free() when it is
+ * no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameras
+ * \sa SDL_OpenCamera
+ */
+extern SDL_DECLSPEC SDL_CameraSpec ** SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count);
+
+/**
+ * Get the human-readable device name for a camera.
+ *
+ * \param instance_id the camera device instance ID.
+ * \returns a human-readable device name or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameras
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraName(SDL_CameraID instance_id);
+
+/**
+ * Get the position of the camera in relation to the system.
+ *
+ * Most platforms will report UNKNOWN, but mobile devices, like phones, can
+ * often make a distinction between cameras on the front of the device (that
+ * points towards the user, for taking "selfies") and cameras on the back (for
+ * filming in the direction the user is facing).
+ *
+ * \param instance_id the camera device instance ID.
+ * \returns the position of the camera on the system hardware.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameras
+ */
+extern SDL_DECLSPEC SDL_CameraPosition SDLCALL SDL_GetCameraPosition(SDL_CameraID instance_id);
+
+/**
+ * Open a video recording device (a "camera").
+ *
+ * You can open the device with any reasonable spec, and if the hardware can't
+ * directly support it, it will convert data seamlessly to the requested
+ * format. This might incur overhead, including scaling of image data.
+ *
+ * If you would rather accept whatever format the device offers, you can pass
+ * a NULL spec here and it will choose one for you (and you can use
+ * SDL_Surface's conversion/scaling functions directly if necessary).
+ *
+ * You can call SDL_GetCameraFormat() to get the actual data format if passing
+ * a NULL spec here. You can see the exact specs a device can support without
+ * conversion with SDL_GetCameraSupportedFormats().
+ *
+ * SDL will not attempt to emulate framerate; it will try to set the hardware
+ * to the rate closest to the requested speed, but it won't attempt to limit
+ * or duplicate frames artificially; call SDL_GetCameraFormat() to see the
+ * actual framerate of the opened the device, and check your timestamps if
+ * this is crucial to your app!
+ *
+ * Note that the camera is not usable until the user approves its use! On some
+ * platforms, the operating system will prompt the user to permit access to
+ * the camera, and they can choose Yes or No at that point. Until they do, the
+ * camera will not be usable. The app should either wait for an
+ * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
+ * or poll SDL_GetCameraPermissionState() occasionally until it returns
+ * non-zero. On platforms that don't require explicit user approval (and
+ * perhaps in places where the user previously permitted access), the approval
+ * event might come immediately, but it might come seconds, minutes, or hours
+ * later!
+ *
+ * \param instance_id the camera device instance ID.
+ * \param spec the desired format for data the device will provide. Can be
+ * NULL.
+ * \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetCameras
+ * \sa SDL_GetCameraFormat
+ */
+extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id, const SDL_CameraSpec *spec);
+
+/**
+ * Query if camera access has been approved by the user.
+ *
+ * Cameras will not function between when the device is opened by the app and
+ * when the user permits access to the hardware. On some platforms, this
+ * presents as a popup dialog where the user has to explicitly approve access;
+ * on others the approval might be implicit and not alert the user at all.
+ *
+ * This function can be used to check the status of that approval. It will
+ * return 0 if still waiting for user response, 1 if the camera is approved
+ * for use, and -1 if the user denied access.
+ *
+ * Instead of polling with this function, you can wait for a
+ * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event
+ * in the standard SDL event loop, which is guaranteed to be sent once when
+ * permission to use the camera is decided.
+ *
+ * If a camera is declined, there's nothing to be done but call
+ * SDL_CloseCamera() to dispose of it.
+ *
+ * \param camera the opened camera device to query.
+ * \returns -1 if user denied access to the camera, 1 if user approved access,
+ * 0 if no decision has been made yet.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenCamera
+ * \sa SDL_CloseCamera
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
+
+/**
+ * Get the instance ID of an opened camera.
+ *
+ * \param camera an SDL_Camera to query.
+ * \returns the instance ID of the specified camera on success or 0 on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenCamera
+ */
+extern SDL_DECLSPEC SDL_CameraID SDLCALL SDL_GetCameraID(SDL_Camera *camera);
+
+/**
+ * Get the properties associated with an opened camera.
+ *
+ * \param camera the SDL_Camera obtained from SDL_OpenCamera().
+ * \returns a valid property ID on success or 0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
+
+/**
+ * Get the spec that a camera is using when generating images.
+ *
+ * Note that this might not be the native format of the hardware, as SDL might
+ * be converting to this format behind the scenes.
+ *
+ * If the system is waiting for the user to approve access to the camera, as
+ * some platforms require, this will return false, but this isn't necessarily
+ * a fatal error; you should either wait for an
+ * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
+ * or poll SDL_GetCameraPermissionState() occasionally until it returns
+ * non-zero.
+ *
+ * \param camera opened camera device.
+ * \param spec the SDL_CameraSpec to be initialized by this function.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenCamera
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec);
+
+/**
+ * Acquire a frame.
+ *
+ * The frame is a memory pointer to the image data, whose size and format are
+ * given by the spec requested when opening the device.
+ *
+ * This is a non blocking API. If there is a frame available, a non-NULL
+ * surface is returned, and timestampNS will be filled with a non-zero value.
+ *
+ * Note that an error case can also return NULL, but a NULL by itself is
+ * normal and just signifies that a new frame is not yet available. Note that
+ * even if a camera device fails outright (a USB camera is unplugged while in
+ * use, etc), SDL will send an event separately to notify the app, but
+ * continue to provide blank frames at ongoing intervals until
+ * SDL_CloseCamera() is called, so real failure here is almost always an out
+ * of memory condition.
+ *
+ * After use, the frame should be released with SDL_ReleaseCameraFrame(). If
+ * you don't do this, the system may stop providing more video!
+ *
+ * Do not call SDL_DestroySurface() on the returned surface! It must be given
+ * back to the camera subsystem with SDL_ReleaseCameraFrame!
+ *
+ * If the system is waiting for the user to approve access to the camera, as
+ * some platforms require, this will return NULL (no frames available); you
+ * should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or
+ * SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll
+ * SDL_GetCameraPermissionState() occasionally until it returns non-zero.
+ *
+ * \param camera opened camera device.
+ * \param timestampNS a pointer filled in with the frame's timestamp, or 0 on
+ * error. Can be NULL.
+ * \returns a new frame of video on success, NULL if none is currently
+ * available.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ReleaseCameraFrame
+ */
+extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS);
+
+/**
+ * Release a frame of video acquired from a camera.
+ *
+ * Let the back-end re-use the internal buffer for camera.
+ *
+ * This function _must_ be called only on surface objects returned by
+ * SDL_AcquireCameraFrame(). This function should be called as quickly as
+ * possible after acquisition, as SDL keeps a small FIFO queue of surfaces for
+ * video frames; if surfaces aren't released in a timely manner, SDL may drop
+ * upcoming video frames from the camera.
+ *
+ * If the app needs to keep the surface for a significant time, they should
+ * make a copy of it and release the original.
+ *
+ * The app should not use the surface again after calling this function;
+ * assume the surface is freed and the pointer is invalid.
+ *
+ * \param camera opened camera device.
+ * \param frame the video frame surface to release.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AcquireCameraFrame
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame);
+
+/**
+ * Use this function to shut down camera processing and close the camera
+ * device.
+ *
+ * \param camera opened camera device.
+ *
+ * \threadsafety It is safe to call this function from any thread, but no
+ * thread may reference `device` once this function is called.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenCamera
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CloseCamera(SDL_Camera *camera);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_camera_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_clipboard.h b/vendored/SDL/include/SDL3/SDL_clipboard.h
new file mode 100644
index 0000000..0d3cbb4
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_clipboard.h
@@ -0,0 +1,331 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryClipboard
+ *
+ * SDL provides access to the system clipboard, both for reading information
+ * from other processes and publishing information of its own.
+ *
+ * This is not just text! SDL apps can access and publish data by mimetype.
+ *
+ * ## Basic use (text)
+ *
+ * Obtaining and publishing simple text to the system clipboard is as easy as
+ * calling SDL_GetClipboardText() and SDL_SetClipboardText(), respectively.
+ * These deal with C strings in UTF-8 encoding. Data transmission and encoding
+ * conversion is completely managed by SDL.
+ *
+ * ## Clipboard callbacks (data other than text)
+ *
+ * Things get more complicated when the clipboard contains something other
+ * than text. Not only can the system clipboard contain data of any type, in
+ * some cases it can contain the same data in different formats! For example,
+ * an image painting app might let the user copy a graphic to the clipboard,
+ * and offers it in .BMP, .JPG, or .PNG format for other apps to consume.
+ *
+ * Obtaining clipboard data ("pasting") like this is a matter of calling
+ * SDL_GetClipboardData() and telling it the mimetype of the data you want.
+ * But how does one know if that format is available? SDL_HasClipboardData()
+ * can report if a specific mimetype is offered, and
+ * SDL_GetClipboardMimeTypes() can provide the entire list of mimetypes
+ * available, so the app can decide what to do with the data and what formats
+ * it can support.
+ *
+ * Setting the clipboard ("copying") to arbitrary data is done with
+ * SDL_SetClipboardData. The app does not provide the data in this call, but
+ * rather the mimetypes it is willing to provide and a callback function.
+ * During the callback, the app will generate the data. This allows massive
+ * data sets to be provided to the clipboard, without any data being copied
+ * before it is explicitly requested. More specifically, it allows an app to
+ * offer data in multiple formats without providing a copy of all of them
+ * upfront. If the app has an image that it could provide in PNG or JPG
+ * format, it doesn't have to encode it to either of those unless and until
+ * something tries to paste it.
+ *
+ * ## Primary Selection
+ *
+ * The X11 and Wayland video targets have a concept of the "primary selection"
+ * in addition to the usual clipboard. This is generally highlighted (but not
+ * explicitly copied) text from various apps. SDL offers APIs for this through
+ * SDL_GetPrimarySelectionText() and SDL_SetPrimarySelectionText(). SDL offers
+ * these APIs on platforms without this concept, too, but only so far that it
+ * will keep a copy of a string that the app sets for later retrieval; the
+ * operating system will not ever attempt to change the string externally if
+ * it doesn't support a primary selection.
+ */
+
+#ifndef SDL_clipboard_h_
+#define SDL_clipboard_h_
+
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function prototypes */
+
+/**
+ * Put UTF-8 text into the clipboard.
+ *
+ * \param text the text to store in the clipboard.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetClipboardText
+ * \sa SDL_HasClipboardText
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
+
+/**
+ * Get UTF-8 text from the clipboard.
+ *
+ * This functions returns an empty string if there was not enough memory left
+ * for a copy of the clipboard's content.
+ *
+ * \returns the clipboard text on success or an empty string on failure; call
+ * SDL_GetError() for more information. This should be freed with
+ * SDL_free() when it is no longer needed.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasClipboardText
+ * \sa SDL_SetClipboardText
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetClipboardText(void);
+
+/**
+ * Query whether the clipboard exists and contains a non-empty text string.
+ *
+ * \returns true if the clipboard has text, or false if it does not.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetClipboardText
+ * \sa SDL_SetClipboardText
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardText(void);
+
+/**
+ * Put UTF-8 text into the primary selection.
+ *
+ * \param text the text to store in the primary selection.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetPrimarySelectionText
+ * \sa SDL_HasPrimarySelectionText
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
+
+/**
+ * Get UTF-8 text from the primary selection.
+ *
+ * This functions returns an empty string if there was not enough memory left
+ * for a copy of the primary selection's content.
+ *
+ * \returns the primary selection text on success or an empty string on
+ * failure; call SDL_GetError() for more information. This should be
+ * freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasPrimarySelectionText
+ * \sa SDL_SetPrimarySelectionText
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void);
+
+/**
+ * Query whether the primary selection exists and contains a non-empty text
+ * string.
+ *
+ * \returns true if the primary selection has text, or false if it does not.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetPrimarySelectionText
+ * \sa SDL_SetPrimarySelectionText
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
+
+/**
+ * Callback function that will be called when data for the specified mime-type
+ * is requested by the OS.
+ *
+ * The callback function is called with NULL as the mime_type when the
+ * clipboard is cleared or new data is set. The clipboard is automatically
+ * cleared in SDL_Quit().
+ *
+ * \param userdata a pointer to provided user data.
+ * \param mime_type the requested mime-type.
+ * \param size a pointer filled in with the length of the returned data.
+ * \returns a pointer to the data for the provided mime-type. Returning NULL
+ * or setting length to 0 will cause no data to be sent to the
+ * "receiver". It is up to the receiver to handle this. Essentially
+ * returning no data is more or less undefined behavior and may cause
+ * breakage in receiving applications. The returned data will not be
+ * freed so it needs to be retained and dealt with internally.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetClipboardData
+ */
+typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
+
+/**
+ * Callback function that will be called when the clipboard is cleared, or new
+ * data is set.
+ *
+ * \param userdata a pointer to provided user data.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetClipboardData
+ */
+typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
+
+/**
+ * Offer clipboard data to the OS.
+ *
+ * Tell the operating system that the application is offering clipboard data
+ * for each of the provided mime-types. Once another application requests the
+ * data the callback function will be called, allowing it to generate and
+ * respond with the data for the requested mime-type.
+ *
+ * The size of text data does not include any terminator, and the text does
+ * not need to be null terminated (e.g. you can directly copy a portion of a
+ * document).
+ *
+ * \param callback a function pointer to the function that provides the
+ * clipboard data.
+ * \param cleanup a function pointer to the function that cleans up the
+ * clipboard data.
+ * \param userdata an opaque pointer that will be forwarded to the callbacks.
+ * \param mime_types a list of mime-types that are being offered.
+ * \param num_mime_types the number of mime-types in the mime_types list.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearClipboardData
+ * \sa SDL_GetClipboardData
+ * \sa SDL_HasClipboardData
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types);
+
+/**
+ * Clear the clipboard data.
+ *
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetClipboardData
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
+
+/**
+ * Get the data from clipboard for a given mime type.
+ *
+ * The size of text data does not include the terminator, but the text is
+ * guaranteed to be null terminated.
+ *
+ * \param mime_type the mime type to read from the clipboard.
+ * \param size a pointer filled in with the length of the returned data.
+ * \returns the retrieved data buffer or NULL on failure; call SDL_GetError()
+ * for more information. This should be freed with SDL_free() when it
+ * is no longer needed.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasClipboardData
+ * \sa SDL_SetClipboardData
+ */
+extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, size_t *size);
+
+/**
+ * Query whether there is data in the clipboard for the provided mime type.
+ *
+ * \param mime_type the mime type to check for data for.
+ * \returns true if there exists data in clipboard for the provided mime type,
+ * false if it does not.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetClipboardData
+ * \sa SDL_GetClipboardData
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
+
+/**
+ * Retrieve the list of mime types available in the clipboard.
+ *
+ * \param num_mime_types a pointer filled with the number of mime types, may
+ * be NULL.
+ * \returns a null terminated array of strings with mime types, or NULL on
+ * failure; call SDL_GetError() for more information. This should be
+ * freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetClipboardData
+ */
+extern SDL_DECLSPEC char ** SDLCALL SDL_GetClipboardMimeTypes(size_t *num_mime_types);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_clipboard_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_close_code.h b/vendored/SDL/include/SDL3/SDL_close_code.h
new file mode 100644
index 0000000..da1dea7
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_close_code.h
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * This file reverses the effects of SDL_begin_code.h and should be included
+ * after you finish any function and structure declarations in your headers.
+ *
+ * SDL's headers use this; applications generally should not include this
+ * header directly.
+ */
+
+#ifndef SDL_begin_code_h
+#error SDL_close_code.h included without matching SDL_begin_code.h
+#endif
+#undef SDL_begin_code_h
+
+/* Reset structure packing at previous byte alignment */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#pragma pack(pop)
+#endif /* Compiler needs structure packing set */
diff --git a/vendored/SDL/include/SDL3/SDL_copying.h b/vendored/SDL/include/SDL3/SDL_copying.h
new file mode 100644
index 0000000..747bd35
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_copying.h
@@ -0,0 +1,22 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* Header file containing SDL's license. */
diff --git a/vendored/SDL/include/SDL3/SDL_cpuinfo.h b/vendored/SDL/include/SDL3/SDL_cpuinfo.h
new file mode 100644
index 0000000..1745bd9
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_cpuinfo.h
@@ -0,0 +1,353 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: CPUInfo */
+
+/**
+ * # CategoryCPUInfo
+ *
+ * CPU feature detection for SDL.
+ *
+ * These functions are largely concerned with reporting if the system has
+ * access to various SIMD instruction sets, but also has other important info
+ * to share, such as system RAM size and number of logical CPU cores.
+ *
+ * CPU instruction set checks, like SDL_HasSSE() and SDL_HasNEON(), are
+ * available on all platforms, even if they don't make sense (an ARM processor
+ * will never have SSE and an x86 processor will never have NEON, for example,
+ * but these functions still exist and will simply return false in these
+ * cases).
+ */
+
+#ifndef SDL_cpuinfo_h_
+#define SDL_cpuinfo_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A guess for the cacheline size used for padding.
+ *
+ * Most x86 processors have a 64 byte cache line. The 64-bit PowerPC
+ * processors have a 128 byte cache line. We use the larger value to be
+ * generally safe.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_CACHELINE_SIZE 128
+
+/**
+ * Get the number of logical CPU cores available.
+ *
+ * \returns the total number of logical CPU cores. On CPUs that include
+ * technologies such as hyperthreading, the number of logical cores
+ * may be more than the number of physical cores.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumLogicalCPUCores(void);
+
+/**
+ * Determine the L1 cache line size of the CPU.
+ *
+ * This is useful for determining multi-threaded structure padding or SIMD
+ * prefetch sizes.
+ *
+ * \returns the L1 cache line size of the CPU, in bytes.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void);
+
+/**
+ * Determine whether the CPU has AltiVec features.
+ *
+ * This always returns false on CPUs that aren't using PowerPC instruction
+ * sets.
+ *
+ * \returns true if the CPU has AltiVec features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasAltiVec(void);
+
+/**
+ * Determine whether the CPU has MMX features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has MMX features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasMMX(void);
+
+/**
+ * Determine whether the CPU has SSE features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has SSE features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasSSE2
+ * \sa SDL_HasSSE3
+ * \sa SDL_HasSSE41
+ * \sa SDL_HasSSE42
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE(void);
+
+/**
+ * Determine whether the CPU has SSE2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has SSE2 features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasSSE
+ * \sa SDL_HasSSE3
+ * \sa SDL_HasSSE41
+ * \sa SDL_HasSSE42
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE2(void);
+
+/**
+ * Determine whether the CPU has SSE3 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has SSE3 features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasSSE
+ * \sa SDL_HasSSE2
+ * \sa SDL_HasSSE41
+ * \sa SDL_HasSSE42
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE3(void);
+
+/**
+ * Determine whether the CPU has SSE4.1 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has SSE4.1 features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasSSE
+ * \sa SDL_HasSSE2
+ * \sa SDL_HasSSE3
+ * \sa SDL_HasSSE42
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE41(void);
+
+/**
+ * Determine whether the CPU has SSE4.2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has SSE4.2 features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasSSE
+ * \sa SDL_HasSSE2
+ * \sa SDL_HasSSE3
+ * \sa SDL_HasSSE41
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE42(void);
+
+/**
+ * Determine whether the CPU has AVX features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has AVX features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasAVX2
+ * \sa SDL_HasAVX512F
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX(void);
+
+/**
+ * Determine whether the CPU has AVX2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has AVX2 features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasAVX
+ * \sa SDL_HasAVX512F
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX2(void);
+
+/**
+ * Determine whether the CPU has AVX-512F (foundation) features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *
+ * \returns true if the CPU has AVX-512F features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasAVX
+ * \sa SDL_HasAVX2
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX512F(void);
+
+/**
+ * Determine whether the CPU has ARM SIMD (ARMv6) features.
+ *
+ * This is different from ARM NEON, which is a different instruction set.
+ *
+ * This always returns false on CPUs that aren't using ARM instruction sets.
+ *
+ * \returns true if the CPU has ARM SIMD features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasNEON
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasARMSIMD(void);
+
+/**
+ * Determine whether the CPU has NEON (ARM SIMD) features.
+ *
+ * This always returns false on CPUs that aren't using ARM instruction sets.
+ *
+ * \returns true if the CPU has ARM NEON features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasNEON(void);
+
+/**
+ * Determine whether the CPU has LSX (LOONGARCH SIMD) features.
+ *
+ * This always returns false on CPUs that aren't using LOONGARCH instruction
+ * sets.
+ *
+ * \returns true if the CPU has LOONGARCH LSX features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasLSX(void);
+
+/**
+ * Determine whether the CPU has LASX (LOONGARCH SIMD) features.
+ *
+ * This always returns false on CPUs that aren't using LOONGARCH instruction
+ * sets.
+ *
+ * \returns true if the CPU has LOONGARCH LASX features or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasLASX(void);
+
+/**
+ * Get the amount of RAM configured in the system.
+ *
+ * \returns the amount of RAM configured in the system in MiB.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
+
+/**
+ * Report the alignment this system needs for SIMD allocations.
+ *
+ * This will return the minimum number of bytes to which a pointer must be
+ * aligned to be compatible with SIMD instructions on the current machine. For
+ * example, if the machine supports SSE only, it will return 16, but if it
+ * supports AVX-512F, it'll return 64 (etc). This only reports values for
+ * instruction sets SDL knows about, so if your SDL build doesn't have
+ * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and
+ * not 64 for the AVX-512 instructions that exist but SDL doesn't know about.
+ * Plan accordingly.
+ *
+ * \returns the alignment in bytes needed for available, known SIMD
+ * instructions.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_aligned_alloc
+ * \sa SDL_aligned_free
+ */
+extern SDL_DECLSPEC size_t SDLCALL SDL_GetSIMDAlignment(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_cpuinfo_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_dialog.h b/vendored/SDL/include/SDL3/SDL_dialog.h
new file mode 100644
index 0000000..ddb9e24
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_dialog.h
@@ -0,0 +1,341 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryDialog
+ *
+ * File dialog support.
+ *
+ * SDL offers file dialogs, to let users select files with native GUI
+ * interfaces. There are "open" dialogs, "save" dialogs, and folder selection
+ * dialogs. The app can control some details, such as filtering to specific
+ * files, or whether multiple files can be selected by the user.
+ *
+ * Note that launching a file dialog is a non-blocking operation; control
+ * returns to the app immediately, and a callback is called later (possibly in
+ * another thread) when the user makes a choice.
+ */
+
+#ifndef SDL_dialog_h_
+#define SDL_dialog_h_
+
+#include
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An entry for filters for file dialogs.
+ *
+ * `name` is a user-readable label for the filter (for example, "Office
+ * document").
+ *
+ * `pattern` is a semicolon-separated list of file extensions (for example,
+ * "doc;docx"). File extensions may only contain alphanumeric characters,
+ * hyphens, underscores and periods. Alternatively, the whole string can be a
+ * single asterisk ("*"), which serves as an "All files" filter.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_DialogFileCallback
+ * \sa SDL_ShowOpenFileDialog
+ * \sa SDL_ShowSaveFileDialog
+ * \sa SDL_ShowOpenFolderDialog
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+typedef struct SDL_DialogFileFilter
+{
+ const char *name;
+ const char *pattern;
+} SDL_DialogFileFilter;
+
+/**
+ * Callback used by file dialog functions.
+ *
+ * The specific usage is described in each function.
+ *
+ * If `filelist` is:
+ *
+ * - NULL, an error occurred. Details can be obtained with SDL_GetError().
+ * - A pointer to NULL, the user either didn't choose any file or canceled the
+ * dialog.
+ * - A pointer to non-`NULL`, the user chose one or more files. The argument
+ * is a null-terminated array of pointers to UTF-8 encoded strings, each
+ * containing a path.
+ *
+ * The filelist argument should not be freed; it will automatically be freed
+ * when the callback returns.
+ *
+ * The filter argument is the index of the filter that was selected, or -1 if
+ * no filter was selected or if the platform or method doesn't support
+ * fetching the selected filter.
+ *
+ * In Android, the `filelist` are `content://` URIs. They should be opened
+ * using SDL_IOFromFile() with appropriate modes. This applies both to open
+ * and save file dialog.
+ *
+ * \param userdata an app-provided pointer, for the callback's use.
+ * \param filelist the file(s) chosen by the user.
+ * \param filter index of the selected filter.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_DialogFileFilter
+ * \sa SDL_ShowOpenFileDialog
+ * \sa SDL_ShowSaveFileDialog
+ * \sa SDL_ShowOpenFolderDialog
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+typedef void (SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const *filelist, int filter);
+
+/**
+ * Displays a dialog that lets the user select a file on their filesystem.
+ *
+ * This is an asynchronous function; it will return immediately, and the
+ * result will be passed to the callback.
+ *
+ * The callback will be invoked with a null-terminated list of files the user
+ * chose. The list will be empty if the user canceled the dialog, and it will
+ * be NULL if an error occurred.
+ *
+ * Note that the callback may be called from a different thread than the one
+ * the function was invoked on.
+ *
+ * Depending on the platform, the user may be allowed to input paths that
+ * don't yet exist.
+ *
+ * On Linux, dialogs may require XDG Portals, which requires DBus, which
+ * requires an event-handling loop. Apps that do not use SDL to handle events
+ * should add a call to SDL_PumpEvents in their main loop.
+ *
+ * \param callback a function pointer to be invoked when the user selects a
+ * file and accepts, or cancels the dialog, or an error
+ * occurs.
+ * \param userdata an optional pointer to pass extra data to the callback when
+ * it will be invoked.
+ * \param window the window that the dialog should be modal for, may be NULL.
+ * Not all platforms support this option.
+ * \param filters a list of filters, may be NULL. Not all platforms support
+ * this option, and platforms that do support it may allow the
+ * user to ignore the filters. If non-NULL, it must remain
+ * valid at least until the callback is invoked.
+ * \param nfilters the number of filters. Ignored if filters is NULL.
+ * \param default_location the default folder or file to start the dialog at,
+ * may be NULL. Not all platforms support this option.
+ * \param allow_many if non-zero, the user will be allowed to select multiple
+ * entries. Not all platforms support this option.
+ *
+ * \threadsafety This function should be called only from the main thread. The
+ * callback may be invoked from the same thread or from a
+ * different one, depending on the OS's constraints.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_DialogFileCallback
+ * \sa SDL_DialogFileFilter
+ * \sa SDL_ShowSaveFileDialog
+ * \sa SDL_ShowOpenFolderDialog
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, bool allow_many);
+
+/**
+ * Displays a dialog that lets the user choose a new or existing file on their
+ * filesystem.
+ *
+ * This is an asynchronous function; it will return immediately, and the
+ * result will be passed to the callback.
+ *
+ * The callback will be invoked with a null-terminated list of files the user
+ * chose. The list will be empty if the user canceled the dialog, and it will
+ * be NULL if an error occurred.
+ *
+ * Note that the callback may be called from a different thread than the one
+ * the function was invoked on.
+ *
+ * The chosen file may or may not already exist.
+ *
+ * On Linux, dialogs may require XDG Portals, which requires DBus, which
+ * requires an event-handling loop. Apps that do not use SDL to handle events
+ * should add a call to SDL_PumpEvents in their main loop.
+ *
+ * \param callback a function pointer to be invoked when the user selects a
+ * file and accepts, or cancels the dialog, or an error
+ * occurs.
+ * \param userdata an optional pointer to pass extra data to the callback when
+ * it will be invoked.
+ * \param window the window that the dialog should be modal for, may be NULL.
+ * Not all platforms support this option.
+ * \param filters a list of filters, may be NULL. Not all platforms support
+ * this option, and platforms that do support it may allow the
+ * user to ignore the filters. If non-NULL, it must remain
+ * valid at least until the callback is invoked.
+ * \param nfilters the number of filters. Ignored if filters is NULL.
+ * \param default_location the default folder or file to start the dialog at,
+ * may be NULL. Not all platforms support this option.
+ *
+ * \threadsafety This function should be called only from the main thread. The
+ * callback may be invoked from the same thread or from a
+ * different one, depending on the OS's constraints.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_DialogFileCallback
+ * \sa SDL_DialogFileFilter
+ * \sa SDL_ShowOpenFileDialog
+ * \sa SDL_ShowOpenFolderDialog
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location);
+
+/**
+ * Displays a dialog that lets the user select a folder on their filesystem.
+ *
+ * This is an asynchronous function; it will return immediately, and the
+ * result will be passed to the callback.
+ *
+ * The callback will be invoked with a null-terminated list of files the user
+ * chose. The list will be empty if the user canceled the dialog, and it will
+ * be NULL if an error occurred.
+ *
+ * Note that the callback may be called from a different thread than the one
+ * the function was invoked on.
+ *
+ * Depending on the platform, the user may be allowed to input paths that
+ * don't yet exist.
+ *
+ * On Linux, dialogs may require XDG Portals, which requires DBus, which
+ * requires an event-handling loop. Apps that do not use SDL to handle events
+ * should add a call to SDL_PumpEvents in their main loop.
+ *
+ * \param callback a function pointer to be invoked when the user selects a
+ * file and accepts, or cancels the dialog, or an error
+ * occurs.
+ * \param userdata an optional pointer to pass extra data to the callback when
+ * it will be invoked.
+ * \param window the window that the dialog should be modal for, may be NULL.
+ * Not all platforms support this option.
+ * \param default_location the default folder or file to start the dialog at,
+ * may be NULL. Not all platforms support this option.
+ * \param allow_many if non-zero, the user will be allowed to select multiple
+ * entries. Not all platforms support this option.
+ *
+ * \threadsafety This function should be called only from the main thread. The
+ * callback may be invoked from the same thread or from a
+ * different one, depending on the OS's constraints.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_DialogFileCallback
+ * \sa SDL_ShowOpenFileDialog
+ * \sa SDL_ShowSaveFileDialog
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char *default_location, bool allow_many);
+
+/**
+ * Various types of file dialogs.
+ *
+ * This is used by SDL_ShowFileDialogWithProperties() to decide what kind of
+ * dialog to present to the user.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_ShowFileDialogWithProperties
+ */
+typedef enum SDL_FileDialogType
+{
+ SDL_FILEDIALOG_OPENFILE,
+ SDL_FILEDIALOG_SAVEFILE,
+ SDL_FILEDIALOG_OPENFOLDER
+} SDL_FileDialogType;
+
+/**
+ * Create and launch a file dialog with the specified properties.
+ *
+ * These are the supported properties:
+ *
+ * - `SDL_PROP_FILE_DIALOG_FILTERS_POINTER`: a pointer to a list of
+ * SDL_DialogFileFilter structs, which will be used as filters for
+ * file-based selections. Ignored if the dialog is an "Open Folder" dialog.
+ * If non-NULL, the array of filters must remain valid at least until the
+ * callback is invoked.
+ * - `SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER`: the number of filters in the
+ * array of filters, if it exists.
+ * - `SDL_PROP_FILE_DIALOG_WINDOW_POINTER`: the window that the dialog should
+ * be modal for.
+ * - `SDL_PROP_FILE_DIALOG_LOCATION_STRING`: the default folder or file to
+ * start the dialog at.
+ * - `SDL_PROP_FILE_DIALOG_MANY_BOOLEAN`: true to allow the user to select
+ * more than one entry.
+ * - `SDL_PROP_FILE_DIALOG_TITLE_STRING`: the title for the dialog.
+ * - `SDL_PROP_FILE_DIALOG_ACCEPT_STRING`: the label that the accept button
+ * should have.
+ * - `SDL_PROP_FILE_DIALOG_CANCEL_STRING`: the label that the cancel button
+ * should have.
+ *
+ * Note that each platform may or may not support any of the properties.
+ *
+ * \param type the type of file dialog.
+ * \param callback a function pointer to be invoked when the user selects a
+ * file and accepts, or cancels the dialog, or an error
+ * occurs.
+ * \param userdata an optional pointer to pass extra data to the callback when
+ * it will be invoked.
+ * \param props the properties to use.
+ *
+ * \threadsafety This function should be called only from the main thread. The
+ * callback may be invoked from the same thread or from a
+ * different one, depending on the OS's constraints.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_FileDialogType
+ * \sa SDL_DialogFileCallback
+ * \sa SDL_DialogFileFilter
+ * \sa SDL_ShowOpenFileDialog
+ * \sa SDL_ShowSaveFileDialog
+ * \sa SDL_ShowOpenFolderDialog
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props);
+
+#define SDL_PROP_FILE_DIALOG_FILTERS_POINTER "SDL.filedialog.filters"
+#define SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER "SDL.filedialog.nfilters"
+#define SDL_PROP_FILE_DIALOG_WINDOW_POINTER "SDL.filedialog.window"
+#define SDL_PROP_FILE_DIALOG_LOCATION_STRING "SDL.filedialog.location"
+#define SDL_PROP_FILE_DIALOG_MANY_BOOLEAN "SDL.filedialog.many"
+#define SDL_PROP_FILE_DIALOG_TITLE_STRING "SDL.filedialog.title"
+#define SDL_PROP_FILE_DIALOG_ACCEPT_STRING "SDL.filedialog.accept"
+#define SDL_PROP_FILE_DIALOG_CANCEL_STRING "SDL.filedialog.cancel"
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_dialog_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_egl.h b/vendored/SDL/include/SDL3/SDL_egl.h
new file mode 100644
index 0000000..65d4e96
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_egl.h
@@ -0,0 +1,2355 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * This is a simple file to encapsulate the EGL API headers.
+ */
+
+#include
+
+#if !defined(_MSC_VER) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS)
+
+#if defined(SDL_PLATFORM_VITA)
+#include
+#include
+#include
+#endif
+
+#include
+#include
+
+#else /* _MSC_VER */
+
+/* EGL headers for Visual Studio */
+
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2018 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * The master copy of khrplatform.h is maintained in the Khronos EGL
+ * Registry repository at https://github.com/KhronosGroup/EGL-Registry
+ * The last semantic modification to khrplatform.h was at commit ID:
+ * 67a3e0864c2d75ea5287b9f3d2eb74a745936692
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by filing pull requests or issues on
+ * the EGL Registry repository linked above.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
+# define KHRONOS_STATIC 1
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(KHRONOS_STATIC)
+ /* If the preprocessor constant KHRONOS_STATIC is defined, make the
+ * header compatible with static linking. */
+# define KHRONOS_APICALL
+#elif defined(_WIN32)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#elif defined(__ANDROID__)
+# define KHRONOS_APICALL __attribute__((visibility("default")))
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+/*
+ * To support platform where unsigned long cannot be used interchangeably with
+ * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
+ * Ideally, we could just use (u)intptr_t everywhere, but this could result in
+ * ABI breakage if khronos_uintptr_t is changed from unsigned long to
+ * unsigned long long or similar (this results in different C++ name mangling).
+ * To avoid changes for existing platforms, we restrict usage of intptr_t to
+ * platforms where the size of a pointer is larger than the size of long.
+ */
+#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
+#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
+#define KHRONOS_USE_INTPTR_T
+#endif
+#endif
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef KHRONOS_USE_INTPTR_T
+typedef intptr_t khronos_intptr_t;
+typedef uintptr_t khronos_uintptr_t;
+#elif defined(_WIN64)
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+#endif
+
+#if defined(_WIN64)
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
+
+
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/*
+** Copyright 2007-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/* Platform-specific types and definitions for egl.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by filing an issue or pull request on the public Khronos EGL Registry, at
+ * https://www.github.com/KhronosGroup/EGL-Registry/
+ */
+
+/*#include */
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGL functions should be prototyped as:
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
+ */
+
+#ifndef EGLAPI
+#define EGLAPI KHRONOS_APICALL
+#endif
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY KHRONOS_APIENTRY
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ *
+ * Khronos STRONGLY RECOMMENDS that you use the default definitions
+ * provided below, since these changes affect both binary and source
+ * portability of applications using EGL running on different EGL
+ * implementations.
+ */
+
+#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES)
+
+typedef void *EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include
+
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+typedef HWND EGLNativeWindowType;
+
+#elif defined(SDL_PLATFORM_EMSCRIPTEN)
+
+typedef int EGLNativeDisplayType;
+typedef int EGLNativePixmapType;
+typedef int EGLNativeWindowType;
+
+#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(WL_EGL_PLATFORM)
+
+typedef struct wl_display *EGLNativeDisplayType;
+typedef struct wl_egl_pixmap *EGLNativePixmapType;
+typedef struct wl_egl_window *EGLNativeWindowType;
+
+#elif defined(__GBM__)
+
+typedef struct gbm_device *EGLNativeDisplayType;
+typedef struct gbm_bo *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+struct ANativeWindow;
+struct egl_native_pixmap_t;
+
+typedef void* EGLNativeDisplayType;
+typedef struct egl_native_pixmap_t* EGLNativePixmapType;
+typedef struct ANativeWindow* EGLNativeWindowType;
+
+#elif defined(USE_OZONE)
+
+typedef intptr_t EGLNativeDisplayType;
+typedef intptr_t EGLNativePixmapType;
+typedef intptr_t EGLNativeWindowType;
+
+#elif defined(USE_X11)
+
+/* X11 (tentative) */
+#include
+#include
+
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap EGLNativePixmapType;
+typedef Window EGLNativeWindowType;
+
+#elif defined(__unix__)
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#elif defined(__APPLE__)
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(__HAIKU__)
+
+#include
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#elif defined(__Fuchsia__)
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#else
+#error "Platform not recognized"
+#endif
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef EGLNativeDisplayType NativeDisplayType;
+typedef EGLNativePixmapType NativePixmapType;
+typedef EGLNativeWindowType NativeWindowType;
+
+
+/* Define EGLint. This must be a signed integral type large enough to contain
+ * all legal attribute names and values passed into and out of EGL, whether
+ * their type is boolean, bitmask, enumerant (symbolic constant), integer,
+ * handle, or other. While in general a 32-bit integer will suffice, if
+ * handles are 64 bit types, then EGLint should be defined as a signed 64-bit
+ * integer type.
+ */
+typedef khronos_int32_t EGLint;
+
+
+/* C++ / C typecast macros for special EGL handle values */
+#if defined(__cplusplus)
+#define EGL_CAST(type, value) (static_cast(value))
+#else
+#define EGL_CAST(type, value) ((type) (value))
+#endif
+
+#endif /* __eglplatform_h */
+
+
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+**
+** This header is generated from the Khronos EGL XML API Registry.
+** The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $
+*/
+
+/*#include */
+
+#ifndef EGL_EGL_PROTOTYPES
+#define EGL_EGL_PROTOTYPES 1
+#endif
+
+/* Generated on date 20220525 */
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
+typedef unsigned int EGLBoolean;
+typedef void *EGLDisplay;
+/*#include */
+/*#include */
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
+#define EGL_DRAW 0x3059
+#define EGL_EXTENSIONS 0x3055
+#define EGL_FALSE 0
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_HEIGHT 0x3056
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_NONE 0x3038
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
+#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
+#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_PIXMAP_BIT 0x0002
+#define EGL_READ 0x305A
+#define EGL_RED_SIZE 0x3024
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SLOW_CONFIG 0x3050
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_SUCCESS 0x3000
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_TRANSPARENT_RGB 0x3052
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRUE 1
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_WIDTH 0x3057
+#define EGL_WINDOW_BIT 0x0004
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id);
+typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void);
+typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif
+#endif /* EGL_VERSION_1_0 */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_CONTEXT_LOST 0x300E
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_2D 0x305F
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_TARGET 0x3081
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT 0x3088
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_ALPHA_FORMAT_PRE 0x308C
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_BUFFER_PRESERVED 0x3094
+#define EGL_BUFFER_DESTROYED 0x3095
+#define EGL_CLIENT_APIS 0x308D
+#define EGL_COLORSPACE 0x3087
+#define EGL_COLORSPACE_sRGB 0x3089
+#define EGL_COLORSPACE_LINEAR 0x308A
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define EGL_DISPLAY_SCALING 10000
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_LUMINANCE_BUFFER 0x308F
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_OPENGL_ES_BIT 0x0001
+#define EGL_OPENVG_BIT 0x0002
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_OPENVG_IMAGE 0x3096
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_RGB_BUFFER 0x308E
+#define EGL_SINGLE_BUFFER 0x3085
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
+#define EGL_VERTICAL_RESOLUTION 0x3091
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api);
+typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT 0x3042
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_COLORSPACE_sRGB 0x3089
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
+typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __egl_h_ */
+
+
+#ifndef __eglext_h_
+#define __eglext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+**
+** This header is generated from the Khronos EGL XML API Registry.
+** The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $
+*/
+
+/*#include */
+
+#define EGL_EGLEXT_VERSION 20220525
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: egl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+#endif /* EGL_KHR_cl_event */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#endif
+#endif /* EGL_KHR_cl_event2 */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#endif /* EGL_KHR_config_attribs */
+
+#ifndef EGL_KHR_context_flush_control
+#define EGL_KHR_context_flush_control 1
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
+#endif /* EGL_KHR_context_flush_control */
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif /* EGL_KHR_create_context */
+
+#ifndef EGL_KHR_create_context_no_error
+#define EGL_KHR_create_context_no_error 1
+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
+#endif /* EGL_KHR_create_context_no_error */
+
+#ifndef EGL_KHR_debug
+#define EGL_KHR_debug 1
+typedef void *EGLLabelKHR;
+typedef void *EGLObjectKHR;
+typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+#define EGL_OBJECT_THREAD_KHR 0x33B0
+#define EGL_OBJECT_DISPLAY_KHR 0x33B1
+#define EGL_OBJECT_CONTEXT_KHR 0x33B2
+#define EGL_OBJECT_SURFACE_KHR 0x33B3
+#define EGL_OBJECT_IMAGE_KHR 0x33B4
+#define EGL_OBJECT_SYNC_KHR 0x33B5
+#define EGL_OBJECT_STREAM_KHR 0x33B6
+#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9
+#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA
+#define EGL_DEBUG_MSG_WARN_KHR 0x33BB
+#define EGL_DEBUG_MSG_INFO_KHR 0x33BC
+#define EGL_DEBUG_CALLBACK_KHR 0x33B8
+typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value);
+typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value);
+EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#endif
+#endif /* EGL_KHR_debug */
+
+#ifndef EGL_KHR_display_reference
+#define EGL_KHR_display_reference 1
+#define EGL_TRACK_REFERENCES_KHR 0x3352
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#endif
+#endif /* EGL_KHR_display_reference */
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
+
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+#endif /* EGL_KHR_get_all_proc_addresses */
+
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+#define EGL_GL_COLORSPACE_KHR 0x309D
+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#endif /* EGL_KHR_gl_colorspace */
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9
+#endif /* EGL_KHR_gl_renderbuffer_image */
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+typedef void *EGLImageKHR;
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0)
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_KHR_image */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif /* EGL_KHR_image_base */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+#endif /* EGL_KHR_image_pixmap */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_KHR_lock_surface */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#endif /* EGL_KHR_lock_surface2 */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#endif
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifndef EGL_KHR_mutable_render_buffer
+#define EGL_KHR_mutable_render_buffer 1
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
+#endif /* EGL_KHR_mutable_render_buffer */
+
+#ifndef EGL_KHR_no_config_context
+#define EGL_KHR_no_config_context 1
+#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0)
+#endif /* EGL_KHR_no_config_context */
+
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+#define EGL_BUFFER_AGE_KHR 0x313D
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_partial_update */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR 0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_reusable_sync */
+
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream */
+
+#ifndef EGL_KHR_stream_attrib
+#define EGL_KHR_stream_attrib 1
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream_attrib */
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#ifdef EGL_KHR_stream
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#ifdef EGL_KHR_stream
+#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1)
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_fifo */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#ifdef EGL_KHR_stream
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+#endif /* EGL_KHR_surfaceless_context */
+
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
+#endif /* EGL_KHR_vg_parent_image */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+#endif /* EGL_KHR_wait_sync */
+
+#ifndef EGL_ANDROID_GLES_layers
+#define EGL_ANDROID_GLES_layers 1
+#endif /* EGL_ANDROID_GLES_layers */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifndef EGL_ANDROID_create_native_client_buffer
+#define EGL_ANDROID_create_native_client_buffer 1
+#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143
+#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001
+#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002
+#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list);
+#endif
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#endif /* EGL_ANDROID_framebuffer_target */
+
+#ifndef EGL_ANDROID_front_buffer_auto_refresh
+#define EGL_ANDROID_front_buffer_auto_refresh 1
+#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+
+#ifndef EGL_ANDROID_get_frame_timestamps
+#define EGL_ANDROID_get_frame_timestamps 1
+typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
+#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2)
+#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1)
+#define EGL_TIMESTAMPS_ANDROID 0x3430
+#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431
+#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432
+#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433
+#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434
+#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435
+#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436
+#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437
+#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438
+#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439
+#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A
+#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B
+#define EGL_READS_DONE_TIME_ANDROID 0x343C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+#endif
+#endif /* EGL_ANDROID_get_frame_timestamps */
+
+#ifndef EGL_ANDROID_get_native_client_buffer
+#define EGL_ANDROID_get_native_client_buffer 1
+struct AHardwareBuffer;
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
+#endif
+#endif /* EGL_ANDROID_get_native_client_buffer */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#endif /* EGL_ANDROID_image_native_buffer */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
+#endif
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifndef EGL_ANDROID_presentation_time
+#define EGL_ANDROID_presentation_time 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#endif
+#endif /* EGL_ANDROID_presentation_time */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID 0x3142
+#endif /* EGL_ANDROID_recordable */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+#define EGL_D3D9_DEVICE_ANGLE 0x33A0
+#define EGL_D3D11_DEVICE_ANGLE 0x33A1
+#endif /* EGL_ANGLE_device_d3d */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#endif
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+#ifndef EGL_ANGLE_sync_control_rate
+#define EGL_ANGLE_sync_control_rate 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
+#endif
+#endif /* EGL_ANGLE_sync_control_rate */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE 0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
+#ifndef EGL_ARM_image_format
+#define EGL_ARM_image_format 1
+#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287
+#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288
+#endif /* EGL_ARM_image_format */
+
+#ifndef EGL_ARM_implicit_external_sync
+#define EGL_ARM_implicit_external_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A
+#endif /* EGL_ARM_implicit_external_sync */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+#ifndef EGL_EXT_bind_to_front
+#define EGL_EXT_bind_to_front 1
+#define EGL_FRONT_BUFFER_EXT 0x3464
+#endif /* EGL_EXT_bind_to_front */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT 0x313D
+#endif /* EGL_EXT_buffer_age */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+#endif /* EGL_EXT_client_extensions */
+
+#ifndef EGL_EXT_client_sync
+#define EGL_EXT_client_sync 1
+#define EGL_SYNC_CLIENT_EXT 0x3364
+#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_EXT_client_sync */
+
+#ifndef EGL_EXT_compositor
+#define EGL_EXT_compositor 1
+#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460
+#define EGL_EXTERNAL_REF_ID_EXT 0x3461
+#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462
+#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy);
+#endif
+#endif /* EGL_EXT_compositor */
+
+#ifndef EGL_EXT_config_select_group
+#define EGL_EXT_config_select_group 1
+#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0
+#endif /* EGL_EXT_config_select_group */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#endif /* EGL_EXT_create_context_robustness */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0)
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_device_drm
+#define EGL_EXT_device_drm 1
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+#define EGL_DRM_MASTER_FD_EXT 0x333C
+#endif /* EGL_EXT_device_drm */
+
+#ifndef EGL_EXT_device_drm_render_node
+#define EGL_EXT_device_drm_render_node 1
+#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377
+#endif /* EGL_EXT_device_drm_render_node */
+
+#ifndef EGL_EXT_device_enumeration
+#define EGL_EXT_device_enumeration 1
+#endif /* EGL_EXT_device_enumeration */
+
+#ifndef EGL_EXT_device_openwf
+#define EGL_EXT_device_openwf 1
+#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
+#define EGL_OPENWF_DEVICE_EXT 0x333D
+#endif /* EGL_EXT_device_openwf */
+
+#ifndef EGL_EXT_device_persistent_id
+#define EGL_EXT_device_persistent_id 1
+#define EGL_DEVICE_UUID_EXT 0x335C
+#define EGL_DRIVER_UUID_EXT 0x335D
+#define EGL_DRIVER_NAME_EXT 0x335E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
+#endif
+#endif /* EGL_EXT_device_persistent_id */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+#endif /* EGL_EXT_device_query */
+
+#ifndef EGL_EXT_device_query_name
+#define EGL_EXT_device_query_name 1
+#define EGL_RENDERER_EXT 0x335F
+#endif /* EGL_EXT_device_query_name */
+
+#ifndef EGL_EXT_explicit_device
+#define EGL_EXT_explicit_device 1
+#endif /* EGL_EXT_explicit_device */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_linear
+#define EGL_EXT_gl_colorspace_bt2020_linear 1
+#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F
+#endif /* EGL_EXT_gl_colorspace_bt2020_linear */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_pq
+#define EGL_EXT_gl_colorspace_bt2020_pq 1
+#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340
+#endif /* EGL_EXT_gl_colorspace_bt2020_pq */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3
+#define EGL_EXT_gl_colorspace_display_p3 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363
+#endif /* EGL_EXT_gl_colorspace_display_p3 */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_linear
+#define EGL_EXT_gl_colorspace_display_p3_linear 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362
+#endif /* EGL_EXT_gl_colorspace_display_p3_linear */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough
+#define EGL_EXT_gl_colorspace_display_p3_passthrough 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490
+#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb
+#define EGL_EXT_gl_colorspace_scrgb 1
+#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351
+#endif /* EGL_EXT_gl_colorspace_scrgb */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb_linear
+#define EGL_EXT_gl_colorspace_scrgb_linear 1
+#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350
+#endif /* EGL_EXT_gl_colorspace_scrgb_linear */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#endif /* EGL_EXT_image_dma_buf_import */
+
+#ifndef EGL_EXT_image_dma_buf_import_modifiers
+#define EGL_EXT_image_dma_buf_import_modifiers 1
+#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
+#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
+#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
+#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
+#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
+#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
+#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
+#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
+#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
+#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#endif
+#endif /* EGL_EXT_image_dma_buf_import_modifiers */
+
+#ifndef EGL_EXT_image_gl_colorspace
+#define EGL_EXT_image_gl_colorspace 1
+#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D
+#endif /* EGL_EXT_image_gl_colorspace */
+
+#ifndef EGL_EXT_image_implicit_sync_control
+#define EGL_EXT_image_implicit_sync_control 1
+#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470
+#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471
+#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472
+#endif /* EGL_EXT_image_implicit_sync_control */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#endif /* EGL_EXT_multiview_window */
+
+#ifndef EGL_EXT_output_base
+#define EGL_EXT_output_base 1
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0)
+#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0)
+#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
+#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
+#define EGL_SWAP_INTERVAL_EXT 0x322F
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+#endif /* EGL_EXT_output_base */
+
+#ifndef EGL_EXT_output_drm
+#define EGL_EXT_output_drm 1
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#define EGL_DRM_CONNECTOR_EXT 0x3236
+#endif /* EGL_EXT_output_drm */
+
+#ifndef EGL_EXT_output_openwf
+#define EGL_EXT_output_openwf 1
+#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
+#define EGL_OPENWF_PORT_ID_EXT 0x3239
+#endif /* EGL_EXT_output_openwf */
+
+#ifndef EGL_EXT_pixel_format_float
+#define EGL_EXT_pixel_format_float 1
+#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339
+#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A
+#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B
+#endif /* EGL_EXT_pixel_format_float */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#endif
+#endif /* EGL_EXT_platform_base */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif /* EGL_EXT_platform_device */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
+#endif /* EGL_EXT_platform_wayland */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+#define EGL_PLATFORM_X11_EXT 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+#endif /* EGL_EXT_platform_x11 */
+
+#ifndef EGL_EXT_platform_xcb
+#define EGL_EXT_platform_xcb 1
+#define EGL_PLATFORM_XCB_EXT 0x31DC
+#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE
+#endif /* EGL_EXT_platform_xcb */
+
+#ifndef EGL_EXT_present_opaque
+#define EGL_EXT_present_opaque 1
+#define EGL_PRESENT_OPAQUE_EXT 0x31DF
+#endif /* EGL_EXT_present_opaque */
+
+#ifndef EGL_EXT_protected_content
+#define EGL_EXT_protected_content 1
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+#endif /* EGL_EXT_protected_content */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+#define EGL_EXT_stream_consumer_egloutput 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+#ifndef EGL_EXT_surface_CTA861_3_metadata
+#define EGL_EXT_surface_CTA861_3_metadata 1
+#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360
+#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361
+#endif /* EGL_EXT_surface_CTA861_3_metadata */
+
+#ifndef EGL_EXT_surface_SMPTE2086_metadata
+#define EGL_EXT_surface_SMPTE2086_metadata 1
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346
+#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347
+#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348
+#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349
+#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A
+#define EGL_METADATA_SCALING_EXT 50000
+#endif /* EGL_EXT_surface_SMPTE2086_metadata */
+
+#ifndef EGL_EXT_surface_compression
+#define EGL_EXT_surface_compression 1
+#define EGL_SURFACE_COMPRESSION_EXT 0x34B0
+#define EGL_SURFACE_COMPRESSION_PLANE1_EXT 0x328E
+#define EGL_SURFACE_COMPRESSION_PLANE2_EXT 0x328F
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x34B1
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x34B2
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x34B4
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x34B5
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x34B6
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x34B7
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x34B8
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x34B9
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x34BA
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x34BB
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x34BC
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x34BD
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x34BE
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x34BF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSUPPORTEDCOMPRESSIONRATESEXTPROC) (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySupportedCompressionRatesEXT (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates);
+#endif
+#endif /* EGL_EXT_surface_compression */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifndef EGL_EXT_sync_reuse
+#define EGL_EXT_sync_reuse 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_EXT_sync_reuse */
+
+#ifndef EGL_EXT_yuv_surface
+#define EGL_EXT_yuv_surface 1
+#define EGL_YUV_ORDER_EXT 0x3301
+#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
+#define EGL_YUV_SUBSAMPLE_EXT 0x3312
+#define EGL_YUV_DEPTH_RANGE_EXT 0x3317
+#define EGL_YUV_CSC_STANDARD_EXT 0x330A
+#define EGL_YUV_PLANE_BPP_EXT 0x331A
+#define EGL_YUV_BUFFER_EXT 0x3300
+#define EGL_YUV_ORDER_YUV_EXT 0x3302
+#define EGL_YUV_ORDER_YVU_EXT 0x3303
+#define EGL_YUV_ORDER_YUYV_EXT 0x3304
+#define EGL_YUV_ORDER_UYVY_EXT 0x3305
+#define EGL_YUV_ORDER_YVYU_EXT 0x3306
+#define EGL_YUV_ORDER_VYUY_EXT 0x3307
+#define EGL_YUV_ORDER_AYUV_EXT 0x3308
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319
+#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D
+#define EGL_YUV_PLANE_BPP_0_EXT 0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT 0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT 0x331D
+#endif /* EGL_EXT_yuv_surface */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+struct EGLClientPixmapHI {
+ void *pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#endif
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+#define EGL_COLOR_FORMAT_HI 0x8F70
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#endif /* EGL_IMG_context_priority */
+
+#ifndef EGL_IMG_image_plane_attribs
+#define EGL_IMG_image_plane_attribs 1
+#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105
+#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106
+#endif /* EGL_IMG_image_plane_attribs */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA 0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+#endif /* EGL_MESA_drm_image */
+
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#endif
+#endif /* EGL_MESA_image_dma_buf_export */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif /* EGL_MESA_platform_gbm */
+
+#ifndef EGL_MESA_platform_surfaceless
+#define EGL_MESA_platform_surfaceless 1
+#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD
+#endif /* EGL_MESA_platform_surfaceless */
+
+#ifndef EGL_MESA_query_driver
+#define EGL_MESA_query_driver 1
+typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy);
+typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy);
+EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy);
+#endif
+#endif /* EGL_MESA_query_driver */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK 0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV 0x3136
+#endif /* EGL_NV_3dvision_surface */
+
+#ifndef EGL_NV_context_priority_realtime
+#define EGL_NV_context_priority_realtime 1
+#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357
+#endif /* EGL_NV_context_priority_realtime */
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif /* EGL_NV_coverage_sample */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#endif /* EGL_NV_coverage_sample_resolve */
+
+#ifndef EGL_NV_cuda_event
+#define EGL_NV_cuda_event 1
+#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
+#define EGL_SYNC_CUDA_EVENT_NV 0x323C
+#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
+#endif /* EGL_NV_cuda_event */
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif /* EGL_NV_depth_nonlinear */
+
+#ifndef EGL_NV_device_cuda
+#define EGL_NV_device_cuda 1
+#define EGL_CUDA_DEVICE_NV 0x323A
+#endif /* EGL_NV_device_cuda */
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+#endif /* EGL_NV_native_query */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+#endif /* EGL_NV_post_convert_rounding */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifndef EGL_NV_quadruple_buffer
+#define EGL_NV_quadruple_buffer 1
+#define EGL_QUADRUPLE_BUFFER_NV 0x3231
+#endif /* EGL_NV_quadruple_buffer */
+
+#ifndef EGL_NV_robustness_video_memory_purge
+#define EGL_NV_robustness_video_memory_purge 1
+#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#endif /* EGL_NV_robustness_video_memory_purge */
+
+#ifndef EGL_NV_stream_consumer_eglimage
+#define EGL_NV_stream_consumer_eglimage 1
+#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373
+#define EGL_STREAM_IMAGE_ADD_NV 0x3374
+#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375
+#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list);
+typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list);
+EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
+#endif
+#endif /* EGL_NV_stream_consumer_eglimage */
+
+#ifndef EGL_NV_stream_consumer_gltexture_yuv
+#define EGL_NV_stream_consumer_gltexture_yuv 1
+#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C
+#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D
+#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifndef EGL_NV_stream_cross_display
+#define EGL_NV_stream_cross_display 1
+#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E
+#endif /* EGL_NV_stream_cross_display */
+
+#ifndef EGL_NV_stream_cross_object
+#define EGL_NV_stream_cross_object 1
+#define EGL_STREAM_CROSS_OBJECT_NV 0x334D
+#endif /* EGL_NV_stream_cross_object */
+
+#ifndef EGL_NV_stream_cross_partition
+#define EGL_NV_stream_cross_partition 1
+#define EGL_STREAM_CROSS_PARTITION_NV 0x323F
+#endif /* EGL_NV_stream_cross_partition */
+
+#ifndef EGL_NV_stream_cross_process
+#define EGL_NV_stream_cross_process 1
+#define EGL_STREAM_CROSS_PROCESS_NV 0x3245
+#endif /* EGL_NV_stream_cross_process */
+
+#ifndef EGL_NV_stream_cross_system
+#define EGL_NV_stream_cross_system 1
+#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F
+#endif /* EGL_NV_stream_cross_system */
+
+#ifndef EGL_NV_stream_dma
+#define EGL_NV_stream_dma 1
+#define EGL_STREAM_DMA_NV 0x3371
+#define EGL_STREAM_DMA_SERVER_NV 0x3372
+#endif /* EGL_NV_stream_dma */
+
+#ifndef EGL_NV_stream_fifo_next
+#define EGL_NV_stream_fifo_next 1
+#define EGL_PENDING_FRAME_NV 0x3329
+#define EGL_STREAM_TIME_PENDING_NV 0x332A
+#endif /* EGL_NV_stream_fifo_next */
+
+#ifndef EGL_NV_stream_fifo_synchronous
+#define EGL_NV_stream_fifo_synchronous 1
+#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336
+#endif /* EGL_NV_stream_fifo_synchronous */
+
+#ifndef EGL_NV_stream_flush
+#define EGL_NV_stream_flush 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_NV_stream_flush */
+
+#ifndef EGL_NV_stream_frame_limits
+#define EGL_NV_stream_frame_limits 1
+#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337
+#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338
+#endif /* EGL_NV_stream_frame_limits */
+
+#ifndef EGL_NV_stream_metadata
+#define EGL_NV_stream_metadata 1
+#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250
+#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251
+#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252
+#define EGL_PRODUCER_METADATA_NV 0x3253
+#define EGL_CONSUMER_METADATA_NV 0x3254
+#define EGL_PENDING_METADATA_NV 0x3328
+#define EGL_METADATA0_SIZE_NV 0x3255
+#define EGL_METADATA1_SIZE_NV 0x3256
+#define EGL_METADATA2_SIZE_NV 0x3257
+#define EGL_METADATA3_SIZE_NV 0x3258
+#define EGL_METADATA0_TYPE_NV 0x3259
+#define EGL_METADATA1_TYPE_NV 0x325A
+#define EGL_METADATA2_TYPE_NV 0x325B
+#define EGL_METADATA3_TYPE_NV 0x325C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#endif
+#endif /* EGL_NV_stream_metadata */
+
+#ifndef EGL_NV_stream_origin
+#define EGL_NV_stream_origin 1
+#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366
+#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367
+#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368
+#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369
+#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A
+#define EGL_LEFT_NV 0x336B
+#define EGL_RIGHT_NV 0x336C
+#define EGL_TOP_NV 0x336D
+#define EGL_BOTTOM_NV 0x336E
+#define EGL_X_AXIS_NV 0x336F
+#define EGL_Y_AXIS_NV 0x3370
+#endif /* EGL_NV_stream_origin */
+
+#ifndef EGL_NV_stream_remote
+#define EGL_NV_stream_remote 1
+#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240
+#define EGL_STREAM_TYPE_NV 0x3241
+#define EGL_STREAM_PROTOCOL_NV 0x3242
+#define EGL_STREAM_ENDPOINT_NV 0x3243
+#define EGL_STREAM_LOCAL_NV 0x3244
+#define EGL_STREAM_PRODUCER_NV 0x3247
+#define EGL_STREAM_CONSUMER_NV 0x3248
+#define EGL_STREAM_PROTOCOL_FD_NV 0x3246
+#endif /* EGL_NV_stream_remote */
+
+#ifndef EGL_NV_stream_reset
+#define EGL_NV_stream_reset 1
+#define EGL_SUPPORT_RESET_NV 0x3334
+#define EGL_SUPPORT_REUSE_NV 0x3335
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_NV_stream_reset */
+
+#ifndef EGL_NV_stream_socket
+#define EGL_NV_stream_socket 1
+#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B
+#define EGL_SOCKET_HANDLE_NV 0x324C
+#define EGL_SOCKET_TYPE_NV 0x324D
+#endif /* EGL_NV_stream_socket */
+
+#ifndef EGL_NV_stream_socket_inet
+#define EGL_NV_stream_socket_inet 1
+#define EGL_SOCKET_TYPE_INET_NV 0x324F
+#endif /* EGL_NV_stream_socket_inet */
+
+#ifndef EGL_NV_stream_socket_unix
+#define EGL_NV_stream_socket_unix 1
+#define EGL_SOCKET_TYPE_UNIX_NV 0x324E
+#endif /* EGL_NV_stream_socket_unix */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+#define EGL_SYNC_NEW_FRAME_NV 0x321F
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#endif
+#endif /* EGL_NV_stream_sync */
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+typedef void *EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0)
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_sync */
+
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_system_time */
+
+#ifndef EGL_NV_triple_buffer
+#define EGL_NV_triple_buffer 1
+#define EGL_TRIPLE_BUFFER_NV 0x3230
+#endif /* EGL_NV_triple_buffer */
+
+#ifndef EGL_TIZEN_image_native_buffer
+#define EGL_TIZEN_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
+#endif /* EGL_TIZEN_image_native_buffer */
+
+#ifndef EGL_TIZEN_image_native_surface
+#define EGL_TIZEN_image_native_surface 1
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif /* EGL_TIZEN_image_native_surface */
+
+#ifndef EGL_WL_bind_wayland_display
+#define EGL_WL_bind_wayland_display 1
+#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
+#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
+#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
+struct wl_display;
+struct wl_resource;
+#define EGL_WAYLAND_BUFFER_WL 0x31D5
+#define EGL_WAYLAND_PLANE_WL 0x31D6
+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
+#define EGL_TEXTURE_Y_UV_WL 0x31D8
+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
+#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
+#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+#endif
+#endif /* EGL_WL_bind_wayland_display */
+
+#ifndef EGL_WL_create_wayland_buffer_from_image
+#define EGL_WL_create_wayland_buffer_from_image 1
+#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
+struct wl_buffer;
+typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_WL_create_wayland_buffer_from_image */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __eglext_h_ */
+
+#endif /* _MSC_VER */
diff --git a/vendored/SDL/include/SDL3/SDL_endian.h b/vendored/SDL/include/SDL3/SDL_endian.h
new file mode 100644
index 0000000..a34e9d4
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_endian.h
@@ -0,0 +1,645 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryEndian
+ *
+ * Functions converting endian-specific values to different byte orders.
+ *
+ * These functions either unconditionally swap byte order (SDL_Swap16,
+ * SDL_Swap32, SDL_Swap64, SDL_SwapFloat), or they swap to/from the system's
+ * native byte order (SDL_Swap16LE, SDL_Swap16BE, SDL_Swap32LE, SDL_Swap32BE,
+ * SDL_Swap32LE, SDL_Swap32BE, SDL_SwapFloatLE, SDL_SwapFloatBE). In the
+ * latter case, the functionality is provided by macros that become no-ops if
+ * a swap isn't necessary: on an x86 (littleendian) processor, SDL_Swap32LE
+ * does nothing, but SDL_Swap32BE reverses the bytes of the data. On a PowerPC
+ * processor (bigendian), the macros behavior is reversed.
+ *
+ * The swap routines are inline functions, and attempt to use compiler
+ * intrinsics, inline assembly, and other magic to make byteswapping
+ * efficient.
+ */
+
+#ifndef SDL_endian_h_
+#define SDL_endian_h_
+
+#include
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
+ so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
+#ifdef __clang__
+#ifndef __PRFCHWINTRIN_H
+#define __PRFCHWINTRIN_H
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_prefetch(void *__P)
+{
+ __builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */);
+}
+#endif /* __PRFCHWINTRIN_H */
+#endif /* __clang__ */
+
+#include
+#endif
+
+/**
+ * \name The two types of endianness
+ */
+/* @{ */
+
+
+/**
+ * A value to represent littleendian byteorder.
+ *
+ * This is used with the preprocessor macro SDL_BYTEORDER, to determine a
+ * platform's byte ordering:
+ *
+ * ```c
+ * #if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ * SDL_Log("This system is littleendian.");
+ * #endif
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_BYTEORDER
+ * \sa SDL_BIG_ENDIAN
+ */
+#define SDL_LIL_ENDIAN 1234
+
+/**
+ * A value to represent bigendian byteorder.
+ *
+ * This is used with the preprocessor macro SDL_BYTEORDER, to determine a
+ * platform's byte ordering:
+ *
+ * ```c
+ * #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ * SDL_Log("This system is bigendian.");
+ * #endif
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_BYTEORDER
+ * \sa SDL_LIL_ENDIAN
+ */
+#define SDL_BIG_ENDIAN 4321
+
+/* @} */
+
+#ifndef SDL_BYTEORDER
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro that reports the target system's byte order.
+ *
+ * This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
+ * values in the future, if something else becomes popular). This can be
+ * tested with the preprocessor, so decisions can be made at compile time.
+ *
+ * ```c
+ * #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ * SDL_Log("This system is bigendian.");
+ * #endif
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_LIL_ENDIAN
+ * \sa SDL_BIG_ENDIAN
+ */
+#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
+#elif defined(SDL_PLATFORM_LINUX)
+#include
+#define SDL_BYTEORDER __BYTE_ORDER
+#elif defined(SDL_PLATFORM_SOLARIS)
+#include
+#if defined(_LITTLE_ENDIAN)
+#define SDL_BYTEORDER SDL_LIL_ENDIAN
+#elif defined(_BIG_ENDIAN)
+#define SDL_BYTEORDER SDL_BIG_ENDIAN
+#else
+#error Unsupported endianness
+#endif
+#elif defined(SDL_PLATFORM_OPENBSD) || defined(__DragonFly__)
+#include
+#define SDL_BYTEORDER BYTE_ORDER
+#elif defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_NETBSD)
+#include
+#define SDL_BYTEORDER BYTE_ORDER
+/* predefs from newer gcc and clang versions: */
+#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__)
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#define SDL_BYTEORDER SDL_LIL_ENDIAN
+#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define SDL_BYTEORDER SDL_BIG_ENDIAN
+#else
+#error Unsupported endianness
+#endif /**/
+#else
+#if defined(__hppa__) || \
+ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
+ (defined(__MIPS__) && defined(__MIPSEB__)) || \
+ defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \
+ defined(__sparc__) || defined(__sparc)
+#define SDL_BYTEORDER SDL_BIG_ENDIAN
+#else
+#define SDL_BYTEORDER SDL_LIL_ENDIAN
+#endif
+#endif /* SDL_PLATFORM_LINUX */
+#endif /* !SDL_BYTEORDER */
+
+#ifndef SDL_FLOATWORDORDER
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro that reports the target system's floating point word order.
+ *
+ * This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
+ * values in the future, if something else becomes popular). This can be
+ * tested with the preprocessor, so decisions can be made at compile time.
+ *
+ * ```c
+ * #if SDL_FLOATWORDORDER == SDL_BIG_ENDIAN
+ * SDL_Log("This system's floats are bigendian.");
+ * #endif
+ * ```
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_LIL_ENDIAN
+ * \sa SDL_BIG_ENDIAN
+ */
+#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
+/* predefs from newer gcc versions: */
+#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__)
+#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
+#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
+#else
+#error Unsupported endianness
+#endif /**/
+#elif defined(__MAVERICK__)
+/* For Maverick, float words are always little-endian. */
+#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
+#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__)
+/* For FPA, float words are always big-endian. */
+#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
+#else
+/* By default, assume that floats words follow the memory system mode. */
+#define SDL_FLOATWORDORDER SDL_BYTEORDER
+#endif /* __FLOAT_WORD_ORDER__ */
+#endif /* !SDL_FLOATWORDORDER */
+
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* various modern compilers may have builtin swap */
+#if defined(__GNUC__) || defined(__clang__)
+# define HAS_BUILTIN_BSWAP16 (SDL_HAS_BUILTIN(__builtin_bswap16)) || \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+# define HAS_BUILTIN_BSWAP32 (SDL_HAS_BUILTIN(__builtin_bswap32)) || \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+# define HAS_BUILTIN_BSWAP64 (SDL_HAS_BUILTIN(__builtin_bswap64)) || \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+
+ /* this one is broken */
+# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95)
+#else
+# define HAS_BUILTIN_BSWAP16 0
+# define HAS_BUILTIN_BSWAP32 0
+# define HAS_BUILTIN_BSWAP64 0
+# define HAS_BROKEN_BSWAP 0
+#endif
+
+/* Byte swap 16-bit integer. */
+#ifndef SDL_WIKI_DOCUMENTATION_SECTION
+#if HAS_BUILTIN_BSWAP16
+#define SDL_Swap16(x) __builtin_bswap16(x)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
+#pragma intrinsic(_byteswap_ushort)
+#define SDL_Swap16(x) _byteswap_ushort(x)
+#elif defined(__i386__) && !HAS_BROKEN_BSWAP
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
+{
+ __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
+ return x;
+}
+#elif defined(__x86_64__)
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
+{
+ __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
+ return x;
+}
+#elif (defined(__powerpc__) || defined(__ppc__))
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
+{
+ int result;
+
+ __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
+ return (Uint16)result;
+}
+#elif (defined(__m68k__) && !defined(__mcoldfire__))
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
+{
+ __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
+ return x;
+}
+#elif defined(__WATCOMC__) && defined(__386__)
+extern __inline Uint16 SDL_Swap16(Uint16);
+#pragma aux SDL_Swap16 = \
+ "xchg al, ah" \
+ parm [ax] \
+ modify [ax];
+#else
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
+{
+ return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
+}
+#endif
+#endif
+
+/* Byte swap 32-bit integer. */
+#ifndef SDL_WIKI_DOCUMENTATION_SECTION
+#if HAS_BUILTIN_BSWAP32
+#define SDL_Swap32(x) __builtin_bswap32(x)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
+#pragma intrinsic(_byteswap_ulong)
+#define SDL_Swap32(x) _byteswap_ulong(x)
+#elif defined(__i386__) && !HAS_BROKEN_BSWAP
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
+{
+ __asm__("bswap %0": "=r"(x):"0"(x));
+ return x;
+}
+#elif defined(__x86_64__)
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
+{
+ __asm__("bswapl %0": "=r"(x):"0"(x));
+ return x;
+}
+#elif (defined(__powerpc__) || defined(__ppc__))
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
+{
+ Uint32 result;
+
+ __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x));
+ __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x));
+ __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x));
+ return result;
+}
+#elif (defined(__m68k__) && !defined(__mcoldfire__))
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
+{
+ __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
+ return x;
+}
+#elif defined(__WATCOMC__) && defined(__386__)
+extern __inline Uint32 SDL_Swap32(Uint32);
+#pragma aux SDL_Swap32 = \
+ "bswap eax" \
+ parm [eax] \
+ modify [eax];
+#else
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
+{
+ return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
+ ((x >> 8) & 0x0000FF00) | (x >> 24)));
+}
+#endif
+#endif
+
+/* Byte swap 64-bit integer. */
+#ifndef SDL_WIKI_DOCUMENTATION_SECTION
+#if HAS_BUILTIN_BSWAP64
+#define SDL_Swap64(x) __builtin_bswap64(x)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
+#pragma intrinsic(_byteswap_uint64)
+#define SDL_Swap64(x) _byteswap_uint64(x)
+#elif defined(__i386__) && !HAS_BROKEN_BSWAP
+SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
+{
+ union {
+ struct {
+ Uint32 a, b;
+ } s;
+ Uint64 u;
+ } v;
+ v.u = x;
+ __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
+ : "=r"(v.s.a), "=r"(v.s.b)
+ : "0" (v.s.a), "1"(v.s.b));
+ return v.u;
+}
+#elif defined(__x86_64__)
+SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
+{
+ __asm__("bswapq %0": "=r"(x):"0"(x));
+ return x;
+}
+#elif defined(__WATCOMC__) && defined(__386__)
+extern __inline Uint64 SDL_Swap64(Uint64);
+#pragma aux SDL_Swap64 = \
+ "bswap eax" \
+ "bswap edx" \
+ "xchg eax,edx" \
+ parm [eax edx] \
+ modify [eax edx];
+#else
+SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
+{
+ Uint32 hi, lo;
+
+ /* Separate into high and low 32-bit values and swap them */
+ lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
+ x >>= 32;
+ hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
+ x = SDL_Swap32(lo);
+ x <<= 32;
+ x |= SDL_Swap32(hi);
+ return (x);
+}
+#endif
+#endif
+
+/**
+ * Byte-swap a floating point number.
+ *
+ * This will always byte-swap the value, whether it's currently in the native
+ * byteorder of the system or not. You should use SDL_SwapFloatLE or
+ * SDL_SwapFloatBE instead, in most cases.
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the value to byte-swap.
+ * \returns x, with its bytes in the opposite endian order.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE float SDL_SwapFloat(float x)
+{
+ union {
+ float f;
+ Uint32 ui32;
+ } swapper;
+ swapper.f = x;
+ swapper.ui32 = SDL_Swap32(swapper.ui32);
+ return swapper.f;
+}
+
+/* remove extra macros */
+#undef HAS_BROKEN_BSWAP
+#undef HAS_BUILTIN_BSWAP16
+#undef HAS_BUILTIN_BSWAP32
+#undef HAS_BUILTIN_BSWAP64
+
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * Byte-swap an unsigned 16-bit number.
+ *
+ * This will always byte-swap the value, whether it's currently in the native
+ * byteorder of the system or not. You should use SDL_Swap16LE or SDL_Swap16BE
+ * instead, in most cases.
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the value to byte-swap.
+ * \returns `x`, with its bytes in the opposite endian order.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { return x_but_byteswapped; }
+
+/**
+ * Byte-swap an unsigned 32-bit number.
+ *
+ * This will always byte-swap the value, whether it's currently in the native
+ * byteorder of the system or not. You should use SDL_Swap32LE or SDL_Swap32BE
+ * instead, in most cases.
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the value to byte-swap.
+ * \returns `x`, with its bytes in the opposite endian order.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
+
+/**
+ * Byte-swap an unsigned 64-bit number.
+ *
+ * This will always byte-swap the value, whether it's currently in the native
+ * byteorder of the system or not. You should use SDL_Swap64LE or SDL_Swap64BE
+ * instead, in most cases.
+ *
+ * Note that this is a forced-inline function in a header, and not a public
+ * API function available in the SDL library (which is to say, the code is
+ * embedded in the calling program and the linker and dynamic loader will not
+ * be able to find this function inside SDL itself).
+ *
+ * \param x the value to byte-swap.
+ * \returns `x`, with its bytes in the opposite endian order.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+SDL_FORCE_INLINE Uint32 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
+
+/**
+ * Swap a 16-bit value from littleendian to native byte order.
+ *
+ * If this is running on a littleendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in littleendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap16LE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a 32-bit value from littleendian to native byte order.
+ *
+ * If this is running on a littleendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in littleendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap32LE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a 64-bit value from littleendian to native byte order.
+ *
+ * If this is running on a littleendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in littleendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap64LE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a floating point value from littleendian to native byte order.
+ *
+ * If this is running on a littleendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in littleendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_SwapFloatLE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a 16-bit value from bigendian to native byte order.
+ *
+ * If this is running on a bigendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in bigendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap16BE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a 32-bit value from bigendian to native byte order.
+ *
+ * If this is running on a bigendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in bigendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap32BE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a 64-bit value from bigendian to native byte order.
+ *
+ * If this is running on a bigendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in bigendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Swap64BE(x) SwapOnlyIfNecessary(x)
+
+/**
+ * Swap a floating point value from bigendian to native byte order.
+ *
+ * If this is running on a bigendian system, `x` is returned unchanged.
+ *
+ * This macro never references `x` more than once, avoiding side effects.
+ *
+ * \param x the value to swap, in bigendian byte order.
+ * \returns `x` in native byte order.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_SwapFloatBE(x) SwapOnlyIfNecessary(x)
+
+#elif SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define SDL_Swap16LE(x) (x)
+#define SDL_Swap32LE(x) (x)
+#define SDL_Swap64LE(x) (x)
+#define SDL_SwapFloatLE(x) (x)
+#define SDL_Swap16BE(x) SDL_Swap16(x)
+#define SDL_Swap32BE(x) SDL_Swap32(x)
+#define SDL_Swap64BE(x) SDL_Swap64(x)
+#define SDL_SwapFloatBE(x) SDL_SwapFloat(x)
+#else
+#define SDL_Swap16LE(x) SDL_Swap16(x)
+#define SDL_Swap32LE(x) SDL_Swap32(x)
+#define SDL_Swap64LE(x) SDL_Swap64(x)
+#define SDL_SwapFloatLE(x) SDL_SwapFloat(x)
+#define SDL_Swap16BE(x) (x)
+#define SDL_Swap32BE(x) (x)
+#define SDL_Swap64BE(x) (x)
+#define SDL_SwapFloatBE(x) (x)
+#endif
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_endian_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_error.h b/vendored/SDL/include/SDL3/SDL_error.h
new file mode 100644
index 0000000..934967c
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_error.h
@@ -0,0 +1,226 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryError
+ *
+ * Simple error message routines for SDL.
+ *
+ * Most apps will interface with these APIs in exactly one function: when
+ * almost any SDL function call reports failure, you can get a human-readable
+ * string of the problem from SDL_GetError().
+ *
+ * These strings are maintained per-thread, and apps are welcome to set their
+ * own errors, which is popular when building libraries on top of SDL for
+ * other apps to consume. These strings are set by calling SDL_SetError().
+ *
+ * A common usage pattern is to have a function that returns true for success
+ * and false for failure, and do this when something fails:
+ *
+ * ```c
+ * if (something_went_wrong) {
+ * return SDL_SetError("The thing broke in this specific way: %d", errcode);
+ * }
+ * ```
+ *
+ * It's also common to just return `false` in this case if the failing thing
+ * is known to call SDL_SetError(), so errors simply propagate through.
+ */
+
+#ifndef SDL_error_h_
+#define SDL_error_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public functions */
+
+
+/**
+ * Set the SDL error message for the current thread.
+ *
+ * Calling this function will replace any previous error message that was set.
+ *
+ * This function always returns false, since SDL frequently uses false to
+ * signify a failing result, leading to this idiom:
+ *
+ * ```c
+ * if (error_code) {
+ * return SDL_SetError("This operation has failed: %d", error_code);
+ * }
+ * ```
+ *
+ * \param fmt a printf()-style message format string.
+ * \param ... additional parameters matching % tokens in the `fmt` string, if
+ * any.
+ * \returns false.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearError
+ * \sa SDL_GetError
+ * \sa SDL_SetErrorV
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
+
+/**
+ * Set the SDL error message for the current thread.
+ *
+ * Calling this function will replace any previous error message that was set.
+ *
+ * \param fmt a printf()-style message format string.
+ * \param ap a variable argument list.
+ * \returns false.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearError
+ * \sa SDL_GetError
+ * \sa SDL_SetError
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(1);
+
+/**
+ * Set an error indicating that memory allocation failed.
+ *
+ * This function does not do any memory allocation.
+ *
+ * \returns false.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_OutOfMemory(void);
+
+/**
+ * Retrieve a message about the last error that occurred on the current
+ * thread.
+ *
+ * It is possible for multiple errors to occur before calling SDL_GetError().
+ * Only the last error is returned.
+ *
+ * The message is only applicable when an SDL function has signaled an error.
+ * You must check the return values of SDL function calls to determine when to
+ * appropriately call SDL_GetError(). You should *not* use the results of
+ * SDL_GetError() to decide if an error has occurred! Sometimes SDL will set
+ * an error string even when reporting success.
+ *
+ * SDL will *not* clear the error string for successful API calls. You *must*
+ * check return values for failure cases before you can assume the error
+ * string applies.
+ *
+ * Error strings are set per-thread, so an error set in a different thread
+ * will not interfere with the current thread's operation.
+ *
+ * The returned value is a thread-local string which will remain valid until
+ * the current thread's error string is changed. The caller should make a copy
+ * if the value is needed after the next SDL API call.
+ *
+ * \returns a message with information about the specific error that occurred,
+ * or an empty string if there hasn't been an error message set since
+ * the last call to SDL_ClearError().
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClearError
+ * \sa SDL_SetError
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetError(void);
+
+/**
+ * Clear any previous error message for this thread.
+ *
+ * \returns true.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetError
+ * \sa SDL_SetError
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ClearError(void);
+
+/**
+ * \name Internal error functions
+ *
+ * \internal
+ * Private error reporting function - used internally.
+ */
+/* @{ */
+
+/**
+ * A macro to standardize error reporting on unsupported operations.
+ *
+ * This simply calls SDL_SetError() with a standardized error string, for
+ * convenience, consistency, and clarity.
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_Unsupported() SDL_SetError("That operation is not supported")
+
+/**
+ * A macro to standardize error reporting on unsupported operations.
+ *
+ * This simply calls SDL_SetError() with a standardized error string, for
+ * convenience, consistency, and clarity.
+ *
+ * A common usage pattern inside SDL is this:
+ *
+ * ```c
+ * bool MyFunction(const char *str) {
+ * if (!str) {
+ * return SDL_InvalidParamError("str"); // returns false.
+ * }
+ * DoSomething(str);
+ * return true;
+ * }
+ * ```
+ *
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param))
+
+/* @} *//* Internal error functions */
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_error_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_events.h b/vendored/SDL/include/SDL3/SDL_events.h
new file mode 100644
index 0000000..d267f05
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_events.h
@@ -0,0 +1,1576 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryEvents
+ *
+ * Event queue management.
+ *
+ * It's extremely common--often required--that an app deal with SDL's event
+ * queue. Almost all useful information about interactions with the real world
+ * flow through here: the user interacting with the computer and app, hardware
+ * coming and going, the system changing in some way, etc.
+ *
+ * An app generally takes a moment, perhaps at the start of a new frame, to
+ * examine any events that have occured since the last time and process or
+ * ignore them. This is generally done by calling SDL_PollEvent() in a loop
+ * until it returns false (or, if using the main callbacks, events are
+ * provided one at a time in calls to SDL_AppEvent() before the next call to
+ * SDL_AppIterate(); in this scenario, the app does not call SDL_PollEvent()
+ * at all).
+ *
+ * There is other forms of control, too: SDL_PeepEvents() has more
+ * functionality at the cost of more complexity, and SDL_WaitEvent() can block
+ * the process until something interesting happens, which might be beneficial
+ * for certain types of programs on low-power hardware. One may also call
+ * SDL_AddEventWatch() to set a callback when new events arrive.
+ *
+ * The app is free to generate their own events, too: SDL_PushEvent allows the
+ * app to put events onto the queue for later retrieval; SDL_RegisterEvents
+ * can guarantee that these events have a type that isn't in use by other
+ * parts of the system.
+ */
+
+#ifndef SDL_events_h_
+#define SDL_events_h_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* General keyboard/mouse/pen state definitions */
+
+/**
+ * The types of events that can be delivered.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_EventType
+{
+ SDL_EVENT_FIRST = 0, /**< Unused (do not remove) */
+
+ /* Application events */
+ SDL_EVENT_QUIT = 0x100, /**< User-requested quit */
+
+ /* These application events have special meaning on iOS and Android, see README-ios.md and README-android.md for details */
+ SDL_EVENT_TERMINATING, /**< The application is being terminated by the OS. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationWillTerminate()
+ Called on Android in onDestroy()
+ */
+ SDL_EVENT_LOW_MEMORY, /**< The application is low on memory, free memory if possible. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationDidReceiveMemoryWarning()
+ Called on Android in onTrimMemory()
+ */
+ SDL_EVENT_WILL_ENTER_BACKGROUND, /**< The application is about to enter the background. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationWillResignActive()
+ Called on Android in onPause()
+ */
+ SDL_EVENT_DID_ENTER_BACKGROUND, /**< The application did enter the background and may not get CPU for some time. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationDidEnterBackground()
+ Called on Android in onPause()
+ */
+ SDL_EVENT_WILL_ENTER_FOREGROUND, /**< The application is about to enter the foreground. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationWillEnterForeground()
+ Called on Android in onResume()
+ */
+ SDL_EVENT_DID_ENTER_FOREGROUND, /**< The application is now interactive. This event must be handled in a callback set with SDL_AddEventWatch().
+ Called on iOS in applicationDidBecomeActive()
+ Called on Android in onResume()
+ */
+
+ SDL_EVENT_LOCALE_CHANGED, /**< The user's locale preferences have changed. */
+
+ SDL_EVENT_SYSTEM_THEME_CHANGED, /**< The system theme changed */
+
+ /* Display events */
+ /* 0x150 was SDL_DISPLAYEVENT, reserve the number for sdl2-compat */
+ SDL_EVENT_DISPLAY_ORIENTATION = 0x151, /**< Display orientation has changed to data1 */
+ SDL_EVENT_DISPLAY_ADDED, /**< Display has been added to the system */
+ SDL_EVENT_DISPLAY_REMOVED, /**< Display has been removed from the system */
+ SDL_EVENT_DISPLAY_MOVED, /**< Display has changed position */
+ SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED, /**< Display has changed desktop mode */
+ SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, /**< Display has changed current mode */
+ SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED, /**< Display has changed content scale */
+ SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION,
+ SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED,
+
+ /* Window events */
+ /* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */
+ /* 0x201 was SDL_SYSWMEVENT, reserve the number for sdl2-compat */
+ SDL_EVENT_WINDOW_SHOWN = 0x202, /**< Window has been shown */
+ SDL_EVENT_WINDOW_HIDDEN, /**< Window has been hidden */
+ SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event */
+ SDL_EVENT_WINDOW_MOVED, /**< Window has been moved to data1, data2 */
+ SDL_EVENT_WINDOW_RESIZED, /**< Window has been resized to data1xdata2 */
+ SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,/**< The pixel size of the window has changed to data1xdata2 */
+ SDL_EVENT_WINDOW_METAL_VIEW_RESIZED,/**< The pixel size of a Metal view associated with the window has changed */
+ SDL_EVENT_WINDOW_MINIMIZED, /**< Window has been minimized */
+ SDL_EVENT_WINDOW_MAXIMIZED, /**< Window has been maximized */
+ SDL_EVENT_WINDOW_RESTORED, /**< Window has been restored to normal size and position */
+ SDL_EVENT_WINDOW_MOUSE_ENTER, /**< Window has gained mouse focus */
+ SDL_EVENT_WINDOW_MOUSE_LEAVE, /**< Window has lost mouse focus */
+ SDL_EVENT_WINDOW_FOCUS_GAINED, /**< Window has gained keyboard focus */
+ SDL_EVENT_WINDOW_FOCUS_LOST, /**< Window has lost keyboard focus */
+ SDL_EVENT_WINDOW_CLOSE_REQUESTED, /**< The window manager requests that the window be closed */
+ SDL_EVENT_WINDOW_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL */
+ SDL_EVENT_WINDOW_ICCPROF_CHANGED, /**< The ICC profile of the window's display has changed */
+ SDL_EVENT_WINDOW_DISPLAY_CHANGED, /**< Window has been moved to display data1 */
+ SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED, /**< Window display scale has been changed */
+ SDL_EVENT_WINDOW_SAFE_AREA_CHANGED, /**< The window safe area has been changed */
+ SDL_EVENT_WINDOW_OCCLUDED, /**< The window has been occluded */
+ SDL_EVENT_WINDOW_ENTER_FULLSCREEN, /**< The window has entered fullscreen mode */
+ SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, /**< The window has left fullscreen mode */
+ SDL_EVENT_WINDOW_DESTROYED, /**< The window with the associated ID is being or has been destroyed. If this message is being handled
+ in an event watcher, the window handle is still valid and can still be used to retrieve any properties
+ associated with the window. Otherwise, the handle has already been destroyed and all resources
+ associated with it are invalid */
+ SDL_EVENT_WINDOW_HDR_STATE_CHANGED, /**< Window HDR properties have changed */
+ SDL_EVENT_WINDOW_FIRST = SDL_EVENT_WINDOW_SHOWN,
+ SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
+
+ /* Keyboard events */
+ SDL_EVENT_KEY_DOWN = 0x300, /**< Key pressed */
+ SDL_EVENT_KEY_UP, /**< Key released */
+ SDL_EVENT_TEXT_EDITING, /**< Keyboard text editing (composition) */
+ SDL_EVENT_TEXT_INPUT, /**< Keyboard text input */
+ SDL_EVENT_KEYMAP_CHANGED, /**< Keymap changed due to a system event such as an
+ input language or keyboard layout change. */
+ SDL_EVENT_KEYBOARD_ADDED, /**< A new keyboard has been inserted into the system */
+ SDL_EVENT_KEYBOARD_REMOVED, /**< A keyboard has been removed */
+ SDL_EVENT_TEXT_EDITING_CANDIDATES, /**< Keyboard text editing candidates */
+
+ /* Mouse events */
+ SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */
+ SDL_EVENT_MOUSE_BUTTON_DOWN, /**< Mouse button pressed */
+ SDL_EVENT_MOUSE_BUTTON_UP, /**< Mouse button released */
+ SDL_EVENT_MOUSE_WHEEL, /**< Mouse wheel motion */
+ SDL_EVENT_MOUSE_ADDED, /**< A new mouse has been inserted into the system */
+ SDL_EVENT_MOUSE_REMOVED, /**< A mouse has been removed */
+
+ /* Joystick events */
+ SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */
+ SDL_EVENT_JOYSTICK_BALL_MOTION, /**< Joystick trackball motion */
+ SDL_EVENT_JOYSTICK_HAT_MOTION, /**< Joystick hat position change */
+ SDL_EVENT_JOYSTICK_BUTTON_DOWN, /**< Joystick button pressed */
+ SDL_EVENT_JOYSTICK_BUTTON_UP, /**< Joystick button released */
+ SDL_EVENT_JOYSTICK_ADDED, /**< A new joystick has been inserted into the system */
+ SDL_EVENT_JOYSTICK_REMOVED, /**< An opened joystick has been removed */
+ SDL_EVENT_JOYSTICK_BATTERY_UPDATED, /**< Joystick battery level change */
+ SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, /**< Joystick update is complete */
+
+ /* Gamepad events */
+ SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650, /**< Gamepad axis motion */
+ SDL_EVENT_GAMEPAD_BUTTON_DOWN, /**< Gamepad button pressed */
+ SDL_EVENT_GAMEPAD_BUTTON_UP, /**< Gamepad button released */
+ SDL_EVENT_GAMEPAD_ADDED, /**< A new gamepad has been inserted into the system */
+ SDL_EVENT_GAMEPAD_REMOVED, /**< A gamepad has been removed */
+ SDL_EVENT_GAMEPAD_REMAPPED, /**< The gamepad mapping was updated */
+ SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN, /**< Gamepad touchpad was touched */
+ SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, /**< Gamepad touchpad finger was moved */
+ SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */
+ SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */
+ SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete */
+ SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED, /**< Gamepad Steam handle has changed */
+
+ /* Touch events */
+ SDL_EVENT_FINGER_DOWN = 0x700,
+ SDL_EVENT_FINGER_UP,
+ SDL_EVENT_FINGER_MOTION,
+ SDL_EVENT_FINGER_CANCELED,
+
+ /* 0x800, 0x801, and 0x802 were the Gesture events from SDL2. Do not reuse these values! sdl2-compat needs them! */
+
+ /* Clipboard events */
+ SDL_EVENT_CLIPBOARD_UPDATE = 0x900, /**< The clipboard or primary selection changed */
+
+ /* Drag and drop events */
+ SDL_EVENT_DROP_FILE = 0x1000, /**< The system requests a file open */
+ SDL_EVENT_DROP_TEXT, /**< text/plain drag-and-drop event */
+ SDL_EVENT_DROP_BEGIN, /**< A new set of drops is beginning (NULL filename) */
+ SDL_EVENT_DROP_COMPLETE, /**< Current set of drops is now complete (NULL filename) */
+ SDL_EVENT_DROP_POSITION, /**< Position while moving over the window */
+
+ /* Audio hotplug events */
+ SDL_EVENT_AUDIO_DEVICE_ADDED = 0x1100, /**< A new audio device is available */
+ SDL_EVENT_AUDIO_DEVICE_REMOVED, /**< An audio device has been removed. */
+ SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED, /**< An audio device's format has been changed by the system. */
+
+ /* Sensor events */
+ SDL_EVENT_SENSOR_UPDATE = 0x1200, /**< A sensor was updated */
+
+ /* Pressure-sensitive pen events */
+ SDL_EVENT_PEN_PROXIMITY_IN = 0x1300, /**< Pressure-sensitive pen has become available */
+ SDL_EVENT_PEN_PROXIMITY_OUT, /**< Pressure-sensitive pen has become unavailable */
+ SDL_EVENT_PEN_DOWN, /**< Pressure-sensitive pen touched drawing surface */
+ SDL_EVENT_PEN_UP, /**< Pressure-sensitive pen stopped touching drawing surface */
+ SDL_EVENT_PEN_BUTTON_DOWN, /**< Pressure-sensitive pen button pressed */
+ SDL_EVENT_PEN_BUTTON_UP, /**< Pressure-sensitive pen button released */
+ SDL_EVENT_PEN_MOTION, /**< Pressure-sensitive pen is moving on the tablet */
+ SDL_EVENT_PEN_AXIS, /**< Pressure-sensitive pen angle/pressure/etc changed */
+
+ /* Camera hotplug events */
+ SDL_EVENT_CAMERA_DEVICE_ADDED = 0x1400, /**< A new camera device is available */
+ SDL_EVENT_CAMERA_DEVICE_REMOVED, /**< A camera device has been removed. */
+ SDL_EVENT_CAMERA_DEVICE_APPROVED, /**< A camera device has been approved for use by the user. */
+ SDL_EVENT_CAMERA_DEVICE_DENIED, /**< A camera device has been denied for use by the user. */
+
+ /* Render events */
+ SDL_EVENT_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
+ SDL_EVENT_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
+ SDL_EVENT_RENDER_DEVICE_LOST, /**< The device has been lost and can't be recovered. */
+
+ /* Reserved events for private platforms */
+ SDL_EVENT_PRIVATE0 = 0x4000,
+ SDL_EVENT_PRIVATE1,
+ SDL_EVENT_PRIVATE2,
+ SDL_EVENT_PRIVATE3,
+
+ /* Internal events */
+ SDL_EVENT_POLL_SENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */
+
+ /** Events SDL_EVENT_USER through SDL_EVENT_LAST are for your use,
+ * and should be allocated with SDL_RegisterEvents()
+ */
+ SDL_EVENT_USER = 0x8000,
+
+ /**
+ * This last event is only for bounding internal arrays
+ */
+ SDL_EVENT_LAST = 0xFFFF,
+
+ /* This just makes sure the enum is the size of Uint32 */
+ SDL_EVENT_ENUM_PADDING = 0x7FFFFFFF
+
+} SDL_EventType;
+
+/**
+ * Fields shared by every event
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_CommonEvent
+{
+ Uint32 type; /**< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+} SDL_CommonEvent;
+
+/**
+ * Display state change event data (event.display.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_DisplayEvent
+{
+ SDL_EventType type; /**< SDL_DISPLAYEVENT_* */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_DisplayID displayID;/**< The associated display */
+ Sint32 data1; /**< event dependent data */
+ Sint32 data2; /**< event dependent data */
+} SDL_DisplayEvent;
+
+/**
+ * Window state change event data (event.window.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_WindowEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_WINDOW_* */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The associated window */
+ Sint32 data1; /**< event dependent data */
+ Sint32 data2; /**< event dependent data */
+} SDL_WindowEvent;
+
+/**
+ * Keyboard device event structure (event.kdevice.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_KeyboardDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_KEYBOARD_ADDED or SDL_EVENT_KEYBOARD_REMOVED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_KeyboardID which; /**< The keyboard instance id */
+} SDL_KeyboardDeviceEvent;
+
+/**
+ * Keyboard button event structure (event.key.*)
+ *
+ * The `key` is the base SDL_Keycode generated by pressing the `scancode`
+ * using the current keyboard layout, applying any options specified in
+ * SDL_HINT_KEYCODE_OPTIONS. You can get the SDL_Keycode corresponding to the
+ * event scancode and modifiers directly from the keyboard layout, bypassing
+ * SDL_HINT_KEYCODE_OPTIONS, by calling SDL_GetKeyFromScancode().
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetKeyFromScancode
+ * \sa SDL_HINT_KEYCODE_OPTIONS
+ */
+typedef struct SDL_KeyboardEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_KEY_DOWN or SDL_EVENT_KEY_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with keyboard focus, if any */
+ SDL_KeyboardID which; /**< The keyboard instance id, or 0 if unknown or virtual */
+ SDL_Scancode scancode; /**< SDL physical key code */
+ SDL_Keycode key; /**< SDL virtual key code */
+ SDL_Keymod mod; /**< current key modifiers */
+ Uint16 raw; /**< The platform dependent scancode for this event */
+ bool down; /**< true if the key is pressed */
+ bool repeat; /**< true if this is a key repeat */
+} SDL_KeyboardEvent;
+
+/**
+ * Keyboard text editing event structure (event.edit.*)
+ *
+ * The start cursor is the position, in UTF-8 characters, where new typing
+ * will be inserted into the editing text. The length is the number of UTF-8
+ * characters that will be replaced by new typing.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_TextEditingEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_TEXT_EDITING */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with keyboard focus, if any */
+ const char *text; /**< The editing text */
+ Sint32 start; /**< The start cursor of selected editing text, or -1 if not set */
+ Sint32 length; /**< The length of selected editing text, or -1 if not set */
+} SDL_TextEditingEvent;
+
+/**
+ * Keyboard IME candidates event structure (event.edit_candidates.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_TextEditingCandidatesEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_TEXT_EDITING_CANDIDATES */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with keyboard focus, if any */
+ const char * const *candidates; /**< The list of candidates, or NULL if there are no candidates available */
+ Sint32 num_candidates; /**< The number of strings in `candidates` */
+ Sint32 selected_candidate; /**< The index of the selected candidate, or -1 if no candidate is selected */
+ bool horizontal; /**< true if the list is horizontal, false if it's vertical */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_TextEditingCandidatesEvent;
+
+/**
+ * Keyboard text input event structure (event.text.*)
+ *
+ * This event will never be delivered unless text input is enabled by calling
+ * SDL_StartTextInput(). Text input is disabled by default!
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_StartTextInput
+ * \sa SDL_StopTextInput
+ */
+typedef struct SDL_TextInputEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_TEXT_INPUT */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with keyboard focus, if any */
+ const char *text; /**< The input text, UTF-8 encoded */
+} SDL_TextInputEvent;
+
+/**
+ * Mouse device event structure (event.mdevice.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_MouseDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_MOUSE_ADDED or SDL_EVENT_MOUSE_REMOVED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_MouseID which; /**< The mouse instance id */
+} SDL_MouseDeviceEvent;
+
+/**
+ * Mouse motion event structure (event.motion.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_MouseMotionEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_MOUSE_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with mouse focus, if any */
+ SDL_MouseID which; /**< The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0 */
+ SDL_MouseButtonFlags state; /**< The current button state */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+ float xrel; /**< The relative motion in the X direction */
+ float yrel; /**< The relative motion in the Y direction */
+} SDL_MouseMotionEvent;
+
+/**
+ * Mouse button event structure (event.button.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_MouseButtonEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_MOUSE_BUTTON_DOWN or SDL_EVENT_MOUSE_BUTTON_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with mouse focus, if any */
+ SDL_MouseID which; /**< The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0 */
+ Uint8 button; /**< The mouse button index */
+ bool down; /**< true if the button is pressed */
+ Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */
+ Uint8 padding;
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+} SDL_MouseButtonEvent;
+
+/**
+ * Mouse wheel event structure (event.wheel.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_MouseWheelEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_MOUSE_WHEEL */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with mouse focus, if any */
+ SDL_MouseID which; /**< The mouse instance id in relative mode or 0 */
+ float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
+ float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
+ SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
+ float mouse_x; /**< X coordinate, relative to window */
+ float mouse_y; /**< Y coordinate, relative to window */
+ Sint32 integer_x; /**< The amount scrolled horizontally, accumulated to whole scroll "ticks" (added in 3.2.12) */
+ Sint32 integer_y; /**< The amount scrolled vertically, accumulated to whole scroll "ticks" (added in 3.2.12) */
+} SDL_MouseWheelEvent;
+
+/**
+ * Joystick axis motion event structure (event.jaxis.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_JoyAxisEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_AXIS_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 axis; /**< The joystick axis index */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 value; /**< The axis value (range: -32768 to 32767) */
+ Uint16 padding4;
+} SDL_JoyAxisEvent;
+
+/**
+ * Joystick trackball motion event structure (event.jball.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_JoyBallEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_BALL_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 ball; /**< The joystick trackball index */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 xrel; /**< The relative motion in the X direction */
+ Sint16 yrel; /**< The relative motion in the Y direction */
+} SDL_JoyBallEvent;
+
+/**
+ * Joystick hat position change event structure (event.jhat.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_JoyHatEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_HAT_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 hat; /**< The joystick hat index */
+ Uint8 value; /**< The hat position value.
+ * \sa SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP
+ * \sa SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT
+ * \sa SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN
+ *
+ * Note that zero means the POV is centered.
+ */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_JoyHatEvent;
+
+/**
+ * Joystick button event structure (event.jbutton.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_JoyButtonEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_BUTTON_DOWN or SDL_EVENT_JOYSTICK_BUTTON_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 button; /**< The joystick button index */
+ bool down; /**< true if the button is pressed */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_JoyButtonEvent;
+
+/**
+ * Joystick device event structure (event.jdevice.*)
+ *
+ * SDL will send JOYSTICK_ADDED events for devices that are already plugged in
+ * during SDL_Init.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadDeviceEvent
+ */
+typedef struct SDL_JoyDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_ADDED or SDL_EVENT_JOYSTICK_REMOVED or SDL_EVENT_JOYSTICK_UPDATE_COMPLETE */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+} SDL_JoyDeviceEvent;
+
+/**
+ * Joystick battery level change event structure (event.jbattery.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_JoyBatteryEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_JOYSTICK_BATTERY_UPDATED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ SDL_PowerState state; /**< The joystick battery state */
+ int percent; /**< The joystick battery percent charge remaining */
+} SDL_JoyBatteryEvent;
+
+/**
+ * Gamepad axis motion event structure (event.gaxis.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GamepadAxisEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_GAMEPAD_AXIS_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 axis; /**< The gamepad axis (SDL_GamepadAxis) */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 value; /**< The axis value (range: -32768 to 32767) */
+ Uint16 padding4;
+} SDL_GamepadAxisEvent;
+
+
+/**
+ * Gamepad button event structure (event.gbutton.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GamepadButtonEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_GAMEPAD_BUTTON_DOWN or SDL_EVENT_GAMEPAD_BUTTON_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Uint8 button; /**< The gamepad button (SDL_GamepadButton) */
+ bool down; /**< true if the button is pressed */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_GamepadButtonEvent;
+
+
+/**
+ * Gamepad device event structure (event.gdevice.*)
+ *
+ * Joysticks that are supported gamepads receive both an SDL_JoyDeviceEvent
+ * and an SDL_GamepadDeviceEvent.
+ *
+ * SDL will send GAMEPAD_ADDED events for joysticks that are already plugged
+ * in during SDL_Init() and are recognized as gamepads. It will also send
+ * events for joysticks that get gamepad mappings at runtime.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_JoyDeviceEvent
+ */
+typedef struct SDL_GamepadDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_GAMEPAD_ADDED, SDL_EVENT_GAMEPAD_REMOVED, or SDL_EVENT_GAMEPAD_REMAPPED, SDL_EVENT_GAMEPAD_UPDATE_COMPLETE or SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+} SDL_GamepadDeviceEvent;
+
+/**
+ * Gamepad touchpad event structure (event.gtouchpad.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GamepadTouchpadEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN or SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION or SDL_EVENT_GAMEPAD_TOUCHPAD_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Sint32 touchpad; /**< The index of the touchpad */
+ Sint32 finger; /**< The index of the finger on the touchpad */
+ float x; /**< Normalized in the range 0...1 with 0 being on the left */
+ float y; /**< Normalized in the range 0...1 with 0 being at the top */
+ float pressure; /**< Normalized in the range 0...1 */
+} SDL_GamepadTouchpadEvent;
+
+/**
+ * Gamepad sensor event structure (event.gsensor.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GamepadSensorEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_GAMEPAD_SENSOR_UPDATE */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_JoystickID which; /**< The joystick instance id */
+ Sint32 sensor; /**< The type of the sensor, one of the values of SDL_SensorType */
+ float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */
+ Uint64 sensor_timestamp; /**< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock */
+} SDL_GamepadSensorEvent;
+
+/**
+ * Audio device event structure (event.adevice.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_AudioDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_AUDIO_DEVICE_ADDED, or SDL_EVENT_AUDIO_DEVICE_REMOVED, or SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_AudioDeviceID which; /**< SDL_AudioDeviceID for the device being added or removed or changing */
+ bool recording; /**< false if a playback device, true if a recording device. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_AudioDeviceEvent;
+
+/**
+ * Camera device event structure (event.cdevice.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_CameraDeviceEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_CAMERA_DEVICE_ADDED, SDL_EVENT_CAMERA_DEVICE_REMOVED, SDL_EVENT_CAMERA_DEVICE_APPROVED, SDL_EVENT_CAMERA_DEVICE_DENIED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_CameraID which; /**< SDL_CameraID for the device being added or removed or changing */
+} SDL_CameraDeviceEvent;
+
+
+/**
+ * Renderer event structure (event.render.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_RenderEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_RENDER_TARGETS_RESET, SDL_EVENT_RENDER_DEVICE_RESET, SDL_EVENT_RENDER_DEVICE_LOST */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window containing the renderer in question. */
+} SDL_RenderEvent;
+
+
+/**
+ * Touch finger event structure (event.tfinger.*)
+ *
+ * Coordinates in this event are normalized. `x` and `y` are normalized to a
+ * range between 0.0f and 1.0f, relative to the window, so (0,0) is the top
+ * left and (1,1) is the bottom right. Delta coordinates `dx` and `dy` are
+ * normalized in the ranges of -1.0f (traversed all the way from the bottom or
+ * right to all the way up or left) to 1.0f (traversed all the way from the
+ * top or left to all the way down or right).
+ *
+ * Note that while the coordinates are _normalized_, they are not _clamped_,
+ * which means in some circumstances you can get a value outside of this
+ * range. For example, a renderer using logical presentation might give a
+ * negative value when the touch is in the letterboxing. Some platforms might
+ * report a touch outside of the window, which will also be outside of the
+ * range.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_TouchFingerEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_FINGER_DOWN, SDL_EVENT_FINGER_UP, SDL_EVENT_FINGER_MOTION, or SDL_EVENT_FINGER_CANCELED */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_TouchID touchID; /**< The touch device id */
+ SDL_FingerID fingerID;
+ float x; /**< Normalized in the range 0...1 */
+ float y; /**< Normalized in the range 0...1 */
+ float dx; /**< Normalized in the range -1...1 */
+ float dy; /**< Normalized in the range -1...1 */
+ float pressure; /**< Normalized in the range 0...1 */
+ SDL_WindowID windowID; /**< The window underneath the finger, if any */
+} SDL_TouchFingerEvent;
+
+/**
+ * Pressure-sensitive pen proximity event structure (event.pmotion.*)
+ *
+ * When a pen becomes visible to the system (it is close enough to a tablet,
+ * etc), SDL will send an SDL_EVENT_PEN_PROXIMITY_IN event with the new pen's
+ * ID. This ID is valid until the pen leaves proximity again (has been removed
+ * from the tablet's area, the tablet has been unplugged, etc). If the same
+ * pen reenters proximity again, it will be given a new ID.
+ *
+ * Note that "proximity" means "close enough for the tablet to know the tool
+ * is there." The pen touching and lifting off from the tablet while not
+ * leaving the area are handled by SDL_EVENT_PEN_DOWN and SDL_EVENT_PEN_UP.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_PenProximityEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_PEN_PROXIMITY_IN or SDL_EVENT_PEN_PROXIMITY_OUT */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with pen focus, if any */
+ SDL_PenID which; /**< The pen instance id */
+} SDL_PenProximityEvent;
+
+/**
+ * Pressure-sensitive pen motion event structure (event.pmotion.*)
+ *
+ * Depending on the hardware, you may get motion events when the pen is not
+ * touching a tablet, for tracking a pen even when it isn't drawing. You
+ * should listen for SDL_EVENT_PEN_DOWN and SDL_EVENT_PEN_UP events, or check
+ * `pen_state & SDL_PEN_INPUT_DOWN` to decide if a pen is "drawing" when
+ * dealing with pen motion.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_PenMotionEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_PEN_MOTION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with pen focus, if any */
+ SDL_PenID which; /**< The pen instance id */
+ SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+} SDL_PenMotionEvent;
+
+/**
+ * Pressure-sensitive pen touched event structure (event.ptouch.*)
+ *
+ * These events come when a pen touches a surface (a tablet, etc), or lifts
+ * off from one.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_PenTouchEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_PEN_DOWN or SDL_EVENT_PEN_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with pen focus, if any */
+ SDL_PenID which; /**< The pen instance id */
+ SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+ bool eraser; /**< true if eraser end is used (not all pens support this). */
+ bool down; /**< true if the pen is touching or false if the pen is lifted off */
+} SDL_PenTouchEvent;
+
+/**
+ * Pressure-sensitive pen button event structure (event.pbutton.*)
+ *
+ * This is for buttons on the pen itself that the user might click. The pen
+ * itself pressing down to draw triggers a SDL_EVENT_PEN_DOWN event instead.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_PenButtonEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_PEN_BUTTON_DOWN or SDL_EVENT_PEN_BUTTON_UP */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with mouse focus, if any */
+ SDL_PenID which; /**< The pen instance id */
+ SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+ Uint8 button; /**< The pen button index (first button is 1). */
+ bool down; /**< true if the button is pressed */
+} SDL_PenButtonEvent;
+
+/**
+ * Pressure-sensitive pen pressure / angle event structure (event.paxis.*)
+ *
+ * You might get some of these events even if the pen isn't touching the
+ * tablet.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_PenAxisEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_PEN_AXIS */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window with pen focus, if any */
+ SDL_PenID which; /**< The pen instance id */
+ SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+ SDL_PenAxis axis; /**< Axis that has changed */
+ float value; /**< New value of axis */
+} SDL_PenAxisEvent;
+
+/**
+ * An event used to drop text or request a file open by the system
+ * (event.drop.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_DropEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_DROP_BEGIN or SDL_EVENT_DROP_FILE or SDL_EVENT_DROP_TEXT or SDL_EVENT_DROP_COMPLETE or SDL_EVENT_DROP_POSITION */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The window that was dropped on, if any */
+ float x; /**< X coordinate, relative to window (not on begin) */
+ float y; /**< Y coordinate, relative to window (not on begin) */
+ const char *source; /**< The source app that sent this drop event, or NULL if that isn't available */
+ const char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
+} SDL_DropEvent;
+
+/**
+ * An event triggered when the clipboard contents have changed
+ * (event.clipboard.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_ClipboardEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_CLIPBOARD_UPDATE */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ bool owner; /**< are we owning the clipboard (internal update) */
+ Sint32 num_mime_types; /**< number of mime types */
+ const char **mime_types; /**< current mime types */
+} SDL_ClipboardEvent;
+
+/**
+ * Sensor event structure (event.sensor.*)
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_SensorEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_SENSOR_UPDATE */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_SensorID which; /**< The instance ID of the sensor */
+ float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_GetSensorData() */
+ Uint64 sensor_timestamp; /**< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock */
+} SDL_SensorEvent;
+
+/**
+ * The "quit requested" event
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_QuitEvent
+{
+ SDL_EventType type; /**< SDL_EVENT_QUIT */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+} SDL_QuitEvent;
+
+/**
+ * A user-defined event type (event.user.*)
+ *
+ * This event is unique; it is never created by SDL, but only by the
+ * application. The event can be pushed onto the event queue using
+ * SDL_PushEvent(). The contents of the structure members are completely up to
+ * the programmer; the only requirement is that '''type''' is a value obtained
+ * from SDL_RegisterEvents().
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_UserEvent
+{
+ Uint32 type; /**< SDL_EVENT_USER through SDL_EVENT_LAST-1, Uint32 because these are not in the SDL_EventType enumeration */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ SDL_WindowID windowID; /**< The associated window if any */
+ Sint32 code; /**< User defined event code */
+ void *data1; /**< User defined data pointer */
+ void *data2; /**< User defined data pointer */
+} SDL_UserEvent;
+
+
+/**
+ * The structure for all events in SDL.
+ *
+ * The SDL_Event structure is the core of all event handling in SDL. SDL_Event
+ * is a union of all event structures used in SDL.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef union SDL_Event
+{
+ Uint32 type; /**< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration */
+ SDL_CommonEvent common; /**< Common event data */
+ SDL_DisplayEvent display; /**< Display event data */
+ SDL_WindowEvent window; /**< Window event data */
+ SDL_KeyboardDeviceEvent kdevice; /**< Keyboard device change event data */
+ SDL_KeyboardEvent key; /**< Keyboard event data */
+ SDL_TextEditingEvent edit; /**< Text editing event data */
+ SDL_TextEditingCandidatesEvent edit_candidates; /**< Text editing candidates event data */
+ SDL_TextInputEvent text; /**< Text input event data */
+ SDL_MouseDeviceEvent mdevice; /**< Mouse device change event data */
+ SDL_MouseMotionEvent motion; /**< Mouse motion event data */
+ SDL_MouseButtonEvent button; /**< Mouse button event data */
+ SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
+ SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
+ SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
+ SDL_JoyBallEvent jball; /**< Joystick ball event data */
+ SDL_JoyHatEvent jhat; /**< Joystick hat event data */
+ SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
+ SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */
+ SDL_GamepadDeviceEvent gdevice; /**< Gamepad device event data */
+ SDL_GamepadAxisEvent gaxis; /**< Gamepad axis event data */
+ SDL_GamepadButtonEvent gbutton; /**< Gamepad button event data */
+ SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */
+ SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor event data */
+ SDL_AudioDeviceEvent adevice; /**< Audio device event data */
+ SDL_CameraDeviceEvent cdevice; /**< Camera device event data */
+ SDL_SensorEvent sensor; /**< Sensor event data */
+ SDL_QuitEvent quit; /**< Quit request event data */
+ SDL_UserEvent user; /**< Custom event data */
+ SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
+ SDL_PenProximityEvent pproximity; /**< Pen proximity event data */
+ SDL_PenTouchEvent ptouch; /**< Pen tip touching event data */
+ SDL_PenMotionEvent pmotion; /**< Pen motion event data */
+ SDL_PenButtonEvent pbutton; /**< Pen button event data */
+ SDL_PenAxisEvent paxis; /**< Pen axis event data */
+ SDL_RenderEvent render; /**< Render event data */
+ SDL_DropEvent drop; /**< Drag and drop event data */
+ SDL_ClipboardEvent clipboard; /**< Clipboard event data */
+
+ /* This is necessary for ABI compatibility between Visual C++ and GCC.
+ Visual C++ will respect the push pack pragma and use 52 bytes (size of
+ SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit
+ architectures) for this union, and GCC will use the alignment of the
+ largest datatype within the union, which is 8 bytes on 64-bit
+ architectures.
+
+ So... we'll add padding to force the size to be the same for both.
+
+ On architectures where pointers are 16 bytes, this needs rounding up to
+ the next multiple of 16, 64, and on architectures where pointers are
+ even larger the size of SDL_UserEvent will dominate as being 3 pointers.
+ */
+ Uint8 padding[128];
+} SDL_Event;
+
+/* Make sure we haven't broken binary compatibility */
+SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding));
+
+
+/* Function prototypes */
+
+/**
+ * Pump the event loop, gathering events from the input devices.
+ *
+ * This function updates the event queue and internal input device state.
+ *
+ * SDL_PumpEvents() gathers all the pending input information from devices and
+ * places it in the event queue. Without calls to SDL_PumpEvents() no events
+ * would ever be placed on the queue. Often the need for calls to
+ * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and
+ * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not
+ * polling or waiting for events (e.g. you are filtering them), then you must
+ * call SDL_PumpEvents() to force an event queue update.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PollEvent
+ * \sa SDL_WaitEvent
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PumpEvents(void);
+
+/* @{ */
+
+/**
+ * The type of action to request from SDL_PeepEvents().
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_EventAction
+{
+ SDL_ADDEVENT, /**< Add events to the back of the queue. */
+ SDL_PEEKEVENT, /**< Check but don't remove events from the queue front. */
+ SDL_GETEVENT /**< Retrieve/remove events from the front of the queue. */
+} SDL_EventAction;
+
+/**
+ * Check the event queue for messages and optionally return them.
+ *
+ * `action` may be any of the following:
+ *
+ * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the
+ * event queue.
+ * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue,
+ * within the specified minimum and maximum type, will be returned to the
+ * caller and will _not_ be removed from the queue. If you pass NULL for
+ * `events`, then `numevents` is ignored and the total number of matching
+ * events will be returned.
+ * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue,
+ * within the specified minimum and maximum type, will be returned to the
+ * caller and will be removed from the queue.
+ *
+ * You may have to call SDL_PumpEvents() before calling this function.
+ * Otherwise, the events may not be ready to be filtered when you call
+ * SDL_PeepEvents().
+ *
+ * \param events destination buffer for the retrieved events, may be NULL to
+ * leave the events in the queue and return the number of events
+ * that would have been stored.
+ * \param numevents if action is SDL_ADDEVENT, the number of events to add
+ * back to the event queue; if action is SDL_PEEKEVENT or
+ * SDL_GETEVENT, the maximum number of events to retrieve.
+ * \param action action to take; see [Remarks](#remarks) for details.
+ * \param minType minimum value of the event type to be considered;
+ * SDL_EVENT_FIRST is a safe choice.
+ * \param maxType maximum value of the event type to be considered;
+ * SDL_EVENT_LAST is a safe choice.
+ * \returns the number of events actually stored or -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PollEvent
+ * \sa SDL_PumpEvents
+ * \sa SDL_PushEvent
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event *events, int numevents, SDL_EventAction action, Uint32 minType, Uint32 maxType);
+/* @} */
+
+/**
+ * Check for the existence of a certain event type in the event queue.
+ *
+ * If you need to check for a range of event types, use SDL_HasEvents()
+ * instead.
+ *
+ * \param type the type of event to be queried; see SDL_EventType for details.
+ * \returns true if events matching `type` are present, or false if events
+ * matching `type` are not present.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasEvents
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasEvent(Uint32 type);
+
+
+/**
+ * Check for the existence of certain event types in the event queue.
+ *
+ * If you need to check for a single event type, use SDL_HasEvent() instead.
+ *
+ * \param minType the low end of event type to be queried, inclusive; see
+ * SDL_EventType for details.
+ * \param maxType the high end of event type to be queried, inclusive; see
+ * SDL_EventType for details.
+ * \returns true if events with type >= `minType` and <= `maxType` are
+ * present, or false if not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasEvents
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType);
+
+/**
+ * Clear events of a specific type from the event queue.
+ *
+ * This will unconditionally remove any events from the queue that match
+ * `type`. If you need to remove a range of event types, use SDL_FlushEvents()
+ * instead.
+ *
+ * It's also normal to just ignore events you don't care about in your event
+ * loop without calling this function.
+ *
+ * This function only affects currently queued events. If you want to make
+ * sure that all pending OS events are flushed, you can call SDL_PumpEvents()
+ * on the main thread immediately before the flush call.
+ *
+ * If you have user events with custom data that needs to be freed, you should
+ * use SDL_PeepEvents() to remove and clean up those events before calling
+ * this function.
+ *
+ * \param type the type of event to be cleared; see SDL_EventType for details.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_FlushEvents
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type);
+
+/**
+ * Clear events of a range of types from the event queue.
+ *
+ * This will unconditionally remove any events from the queue that are in the
+ * range of `minType` to `maxType`, inclusive. If you need to remove a single
+ * event type, use SDL_FlushEvent() instead.
+ *
+ * It's also normal to just ignore events you don't care about in your event
+ * loop without calling this function.
+ *
+ * This function only affects currently queued events. If you want to make
+ * sure that all pending OS events are flushed, you can call SDL_PumpEvents()
+ * on the main thread immediately before the flush call.
+ *
+ * \param minType the low end of event type to be cleared, inclusive; see
+ * SDL_EventType for details.
+ * \param maxType the high end of event type to be cleared, inclusive; see
+ * SDL_EventType for details.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_FlushEvent
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
+
+/**
+ * Poll for currently pending events.
+ *
+ * If `event` is not NULL, the next event is removed from the queue and stored
+ * in the SDL_Event structure pointed to by `event`. The 1 returned refers to
+ * this event, immediately stored in the SDL Event structure -- not an event
+ * to follow.
+ *
+ * If `event` is NULL, it simply returns 1 if there is an event in the queue,
+ * but will not remove it from the queue.
+ *
+ * As this function may implicitly call SDL_PumpEvents(), you can only call
+ * this function in the thread that set the video mode.
+ *
+ * SDL_PollEvent() is the favored way of receiving system events since it can
+ * be done from the main loop and does not suspend the main loop while waiting
+ * on an event to be posted.
+ *
+ * The common practice is to fully process the event queue once every frame,
+ * usually as a first step before updating the game's state:
+ *
+ * ```c
+ * while (game_is_still_running) {
+ * SDL_Event event;
+ * while (SDL_PollEvent(&event)) { // poll until all events are handled!
+ * // decide what to do with this event.
+ * }
+ *
+ * // update game state, draw the current frame
+ * }
+ * ```
+ *
+ * \param event the SDL_Event structure to be filled with the next event from
+ * the queue, or NULL.
+ * \returns true if this got an event or false if there are none available.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PushEvent
+ * \sa SDL_WaitEvent
+ * \sa SDL_WaitEventTimeout
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PollEvent(SDL_Event *event);
+
+/**
+ * Wait indefinitely for the next available event.
+ *
+ * If `event` is not NULL, the next event is removed from the queue and stored
+ * in the SDL_Event structure pointed to by `event`.
+ *
+ * As this function may implicitly call SDL_PumpEvents(), you can only call
+ * this function in the thread that initialized the video subsystem.
+ *
+ * \param event the SDL_Event structure to be filled in with the next event
+ * from the queue, or NULL.
+ * \returns true on success or false if there was an error while waiting for
+ * events; call SDL_GetError() for more information.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PollEvent
+ * \sa SDL_PushEvent
+ * \sa SDL_WaitEventTimeout
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitEvent(SDL_Event *event);
+
+/**
+ * Wait until the specified timeout (in milliseconds) for the next available
+ * event.
+ *
+ * If `event` is not NULL, the next event is removed from the queue and stored
+ * in the SDL_Event structure pointed to by `event`.
+ *
+ * As this function may implicitly call SDL_PumpEvents(), you can only call
+ * this function in the thread that initialized the video subsystem.
+ *
+ * The timeout is not guaranteed, the actual wait time could be longer due to
+ * system scheduling.
+ *
+ * \param event the SDL_Event structure to be filled in with the next event
+ * from the queue, or NULL.
+ * \param timeoutMS the maximum number of milliseconds to wait for the next
+ * available event.
+ * \returns true if this got an event or false if the timeout elapsed without
+ * any events available.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PollEvent
+ * \sa SDL_PushEvent
+ * \sa SDL_WaitEvent
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS);
+
+/**
+ * Add an event to the event queue.
+ *
+ * The event queue can actually be used as a two way communication channel.
+ * Not only can events be read from the queue, but the user can also push
+ * their own events onto it. `event` is a pointer to the event structure you
+ * wish to push onto the queue. The event is copied into the queue, and the
+ * caller may dispose of the memory pointed to after SDL_PushEvent() returns.
+ *
+ * Note: Pushing device input events onto the queue doesn't modify the state
+ * of the device within SDL.
+ *
+ * Note: Events pushed onto the queue with SDL_PushEvent() get passed through
+ * the event filter but events added with SDL_PeepEvents() do not.
+ *
+ * For pushing application-specific events, please use SDL_RegisterEvents() to
+ * get an event type that does not conflict with other code that also wants
+ * its own custom event types.
+ *
+ * \param event the SDL_Event to be added to the queue.
+ * \returns true on success, false if the event was filtered or on failure;
+ * call SDL_GetError() for more information. A common reason for
+ * error is the event queue being full.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PeepEvents
+ * \sa SDL_PollEvent
+ * \sa SDL_RegisterEvents
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PushEvent(SDL_Event *event);
+
+/**
+ * A function pointer used for callbacks that watch the event queue.
+ *
+ * \param userdata what was passed as `userdata` to SDL_SetEventFilter() or
+ * SDL_AddEventWatch, etc.
+ * \param event the event that triggered the callback.
+ * \returns true to permit event to be added to the queue, and false to
+ * disallow it. When used with SDL_AddEventWatch, the return value is
+ * ignored.
+ *
+ * \threadsafety SDL may call this callback at any time from any thread; the
+ * application is responsible for locking resources the callback
+ * touches that need to be protected.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetEventFilter
+ * \sa SDL_AddEventWatch
+ */
+typedef bool (SDLCALL *SDL_EventFilter)(void *userdata, SDL_Event *event);
+
+/**
+ * Set up a filter to process all events before they are added to the internal
+ * event queue.
+ *
+ * If you just want to see events without modifying them or preventing them
+ * from being queued, you should use SDL_AddEventWatch() instead.
+ *
+ * If the filter function returns true when called, then the event will be
+ * added to the internal queue. If it returns false, then the event will be
+ * dropped from the queue, but the internal state will still be updated. This
+ * allows selective filtering of dynamically arriving events.
+ *
+ * **WARNING**: Be very careful of what you do in the event filter function,
+ * as it may run in a different thread!
+ *
+ * On platforms that support it, if the quit event is generated by an
+ * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the
+ * application at the next event poll.
+ *
+ * Note: Disabled events never make it to the event filter function; see
+ * SDL_SetEventEnabled().
+ *
+ * Note: Events pushed onto the queue with SDL_PushEvent() get passed through
+ * the event filter, but events pushed onto the queue with SDL_PeepEvents() do
+ * not.
+ *
+ * \param filter an SDL_EventFilter function to call when an event happens.
+ * \param userdata a pointer that is passed to `filter`.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddEventWatch
+ * \sa SDL_SetEventEnabled
+ * \sa SDL_GetEventFilter
+ * \sa SDL_PeepEvents
+ * \sa SDL_PushEvent
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, void *userdata);
+
+/**
+ * Query the current event filter.
+ *
+ * This function can be used to "chain" filters, by saving the existing filter
+ * before replacing it with a function that will call that saved filter.
+ *
+ * \param filter the current callback function will be stored here.
+ * \param userdata the pointer that is passed to the current event filter will
+ * be stored here.
+ * \returns true on success or false if there is no event filter set.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetEventFilter
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata);
+
+/**
+ * Add a callback to be triggered when an event is added to the event queue.
+ *
+ * `filter` will be called when an event happens, and its return value is
+ * ignored.
+ *
+ * **WARNING**: Be very careful of what you do in the event filter function,
+ * as it may run in a different thread!
+ *
+ * If the quit event is generated by a signal (e.g. SIGINT), it will bypass
+ * the internal queue and be delivered to the watch callback immediately, and
+ * arrive at the next event poll.
+ *
+ * Note: the callback is called for events posted by the user through
+ * SDL_PushEvent(), but not for disabled events, nor for events by a filter
+ * callback set with SDL_SetEventFilter(), nor for events posted by the user
+ * through SDL_PeepEvents().
+ *
+ * \param filter an SDL_EventFilter function to call when an event happens.
+ * \param userdata a pointer that is passed to `filter`.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RemoveEventWatch
+ * \sa SDL_SetEventFilter
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, void *userdata);
+
+/**
+ * Remove an event watch callback added with SDL_AddEventWatch().
+ *
+ * This function takes the same input as SDL_AddEventWatch() to identify and
+ * delete the corresponding callback.
+ *
+ * \param filter the function originally passed to SDL_AddEventWatch().
+ * \param userdata the pointer originally passed to SDL_AddEventWatch().
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddEventWatch
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_RemoveEventWatch(SDL_EventFilter filter, void *userdata);
+
+/**
+ * Run a specific filter function on the current event queue, removing any
+ * events for which the filter returns false.
+ *
+ * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(),
+ * this function does not change the filter permanently, it only uses the
+ * supplied filter until this function returns.
+ *
+ * \param filter the SDL_EventFilter function to call when an event happens.
+ * \param userdata a pointer that is passed to `filter`.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetEventFilter
+ * \sa SDL_SetEventFilter
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, void *userdata);
+
+/**
+ * Set the state of processing events by type.
+ *
+ * \param type the type of event; see SDL_EventType for details.
+ * \param enabled whether to process the event or not.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_EventEnabled
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetEventEnabled(Uint32 type, bool enabled);
+
+/**
+ * Query the state of processing events by type.
+ *
+ * \param type the type of event; see SDL_EventType for details.
+ * \returns true if the event is being processed, false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetEventEnabled
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_EventEnabled(Uint32 type);
+
+/**
+ * Allocate a set of user-defined events, and return the beginning event
+ * number for that set of events.
+ *
+ * \param numevents the number of events to be allocated.
+ * \returns the beginning event number, or 0 if numevents is invalid or if
+ * there are not enough user-defined events left.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PushEvent
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);
+
+/**
+ * Get window associated with an event.
+ *
+ * \param event an event containing a `windowID`.
+ * \returns the associated window on success or NULL if there is none.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PollEvent
+ * \sa SDL_WaitEvent
+ * \sa SDL_WaitEventTimeout
+ */
+extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromEvent(const SDL_Event *event);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_events_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_filesystem.h b/vendored/SDL/include/SDL3/SDL_filesystem.h
new file mode 100644
index 0000000..af3ca27
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_filesystem.h
@@ -0,0 +1,503 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryFilesystem
+ *
+ * SDL offers an API for examining and manipulating the system's filesystem.
+ * This covers most things one would need to do with directories, except for
+ * actual file I/O (which is covered by [CategoryIOStream](CategoryIOStream)
+ * and [CategoryAsyncIO](CategoryAsyncIO) instead).
+ *
+ * There are functions to answer necessary path questions:
+ *
+ * - Where is my app's data? SDL_GetBasePath().
+ * - Where can I safely write files? SDL_GetPrefPath().
+ * - Where are paths like Downloads, Desktop, Music? SDL_GetUserFolder().
+ * - What is this thing at this location? SDL_GetPathInfo().
+ * - What items live in this folder? SDL_EnumerateDirectory().
+ * - What items live in this folder by wildcard? SDL_GlobDirectory().
+ * - What is my current working directory? SDL_GetCurrentDirectory().
+ *
+ * SDL also offers functions to manipulate the directory tree: renaming,
+ * removing, copying files.
+ */
+
+#ifndef SDL_filesystem_h_
+#define SDL_filesystem_h_
+
+#include
+#include
+
+#include
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get the directory where the application was run from.
+ *
+ * SDL caches the result of this call internally, but the first call to this
+ * function is not necessarily fast, so plan accordingly.
+ *
+ * **macOS and iOS Specific Functionality**: If the application is in a ".app"
+ * bundle, this function returns the Resource directory (e.g.
+ * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding
+ * a property to the Info.plist file. Adding a string key with the name
+ * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the
+ * behaviour.
+ *
+ * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an
+ * application in /Applications/SDLApp/MyApp.app):
+ *
+ * - `resource`: bundle resource directory (the default). For example:
+ * `/Applications/SDLApp/MyApp.app/Contents/Resources`
+ * - `bundle`: the Bundle directory. For example:
+ * `/Applications/SDLApp/MyApp.app/`
+ * - `parent`: the containing directory of the bundle. For example:
+ * `/Applications/SDLApp/`
+ *
+ * **Nintendo 3DS Specific Functionality**: This function returns "romfs"
+ * directory of the application as it is uncommon to store resources outside
+ * the executable. As such it is not a writable directory.
+ *
+ * The returned path is guaranteed to end with a path separator ('\\' on
+ * Windows, '/' on most other platforms).
+ *
+ * \returns an absolute path in UTF-8 encoding to the application data
+ * directory. NULL will be returned on error or when the platform
+ * doesn't implement this functionality, call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetPrefPath
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetBasePath(void);
+
+/**
+ * Get the user-and-app-specific path where files can be written.
+ *
+ * Get the "pref dir". This is meant to be where users can write personal
+ * files (preferences and save games, etc) that are specific to your
+ * application. This directory is unique per user, per application.
+ *
+ * This function will decide the appropriate location in the native
+ * filesystem, create the directory if necessary, and return a string of the
+ * absolute path to the directory in UTF-8 encoding.
+ *
+ * On Windows, the string might look like:
+ *
+ * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\`
+ *
+ * On Linux, the string might look like:
+ *
+ * `/home/bob/.local/share/My Program Name/`
+ *
+ * On macOS, the string might look like:
+ *
+ * `/Users/bob/Library/Application Support/My Program Name/`
+ *
+ * You should assume the path returned by this function is the only safe place
+ * to write files (and that SDL_GetBasePath(), while it might be writable, or
+ * even the parent of the returned path, isn't where you should be writing
+ * things).
+ *
+ * Both the org and app strings may become part of a directory name, so please
+ * follow these rules:
+ *
+ * - Try to use the same org string (_including case-sensitivity_) for all
+ * your applications that use this function.
+ * - Always use a unique app string for each one, and make sure it never
+ * changes for an app once you've decided on it.
+ * - Unicode characters are legal, as long as they are UTF-8 encoded, but...
+ * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game
+ * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient.
+ *
+ * The returned path is guaranteed to end with a path separator ('\\' on
+ * Windows, '/' on most other platforms).
+ *
+ * \param org the name of your organization.
+ * \param app the name of your application.
+ * \returns a UTF-8 string of the user directory in platform-dependent
+ * notation. NULL if there's a problem (creating directory failed,
+ * etc.). This should be freed with SDL_free() when it is no longer
+ * needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetBasePath
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetPrefPath(const char *org, const char *app);
+
+/**
+ * The type of the OS-provided default folder for a specific purpose.
+ *
+ * Note that the Trash folder isn't included here, because trashing files
+ * usually involves extra OS-specific functionality to remember the file's
+ * original location.
+ *
+ * The folders supported per platform are:
+ *
+ * | | Windows | macOS/iOS | tvOS | Unix (XDG) | Haiku | Emscripten |
+ * | ----------- | ------- | --------- | ---- | ---------- | ----- | ---------- |
+ * | HOME | X | X | | X | X | X |
+ * | DESKTOP | X | X | | X | X | |
+ * | DOCUMENTS | X | X | | X | | |
+ * | DOWNLOADS | Vista+ | X | | X | | |
+ * | MUSIC | X | X | | X | | |
+ * | PICTURES | X | X | | X | | |
+ * | PUBLICSHARE | | X | | X | | |
+ * | SAVEDGAMES | Vista+ | | | | | |
+ * | SCREENSHOTS | Vista+ | | | | | |
+ * | TEMPLATES | X | X | | X | | |
+ * | VIDEOS | X | X* | | X | | |
+ *
+ * Note that on macOS/iOS, the Videos folder is called "Movies".
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetUserFolder
+ */
+typedef enum SDL_Folder
+{
+ SDL_FOLDER_HOME, /**< The folder which contains all of the current user's data, preferences, and documents. It usually contains most of the other folders. If a requested folder does not exist, the home folder can be considered a safe fallback to store a user's documents. */
+ SDL_FOLDER_DESKTOP, /**< The folder of files that are displayed on the desktop. Note that the existence of a desktop folder does not guarantee that the system does show icons on its desktop; certain GNU/Linux distros with a graphical environment may not have desktop icons. */
+ SDL_FOLDER_DOCUMENTS, /**< User document files, possibly application-specific. This is a good place to save a user's projects. */
+ SDL_FOLDER_DOWNLOADS, /**< Standard folder for user files downloaded from the internet. */
+ SDL_FOLDER_MUSIC, /**< Music files that can be played using a standard music player (mp3, ogg...). */
+ SDL_FOLDER_PICTURES, /**< Image files that can be displayed using a standard viewer (png, jpg...). */
+ SDL_FOLDER_PUBLICSHARE, /**< Files that are meant to be shared with other users on the same computer. */
+ SDL_FOLDER_SAVEDGAMES, /**< Save files for games. */
+ SDL_FOLDER_SCREENSHOTS, /**< Application screenshots. */
+ SDL_FOLDER_TEMPLATES, /**< Template files to be used when the user requests the desktop environment to create a new file in a certain folder, such as "New Text File.txt". Any file in the Templates folder can be used as a starting point for a new file. */
+ SDL_FOLDER_VIDEOS, /**< Video files that can be played using a standard video player (mp4, webm...). */
+ SDL_FOLDER_COUNT /**< Total number of types in this enum, not a folder type by itself. */
+} SDL_Folder;
+
+/**
+ * Finds the most suitable user folder for a specific purpose.
+ *
+ * Many OSes provide certain standard folders for certain purposes, such as
+ * storing pictures, music or videos for a certain user. This function gives
+ * the path for many of those special locations.
+ *
+ * This function is specifically for _user_ folders, which are meant for the
+ * user to access and manage. For application-specific folders, meant to hold
+ * data for the application to manage, see SDL_GetBasePath() and
+ * SDL_GetPrefPath().
+ *
+ * The returned path is guaranteed to end with a path separator ('\\' on
+ * Windows, '/' on most other platforms).
+ *
+ * If NULL is returned, the error may be obtained with SDL_GetError().
+ *
+ * \param folder the type of folder to find.
+ * \returns either a null-terminated C string containing the full path to the
+ * folder, or NULL if an error happened.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetUserFolder(SDL_Folder folder);
+
+
+/* Abstract filesystem interface */
+
+/**
+ * Types of filesystem entries.
+ *
+ * Note that there may be other sorts of items on a filesystem: devices,
+ * symlinks, named pipes, etc. They are currently reported as
+ * SDL_PATHTYPE_OTHER.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_PathInfo
+ */
+typedef enum SDL_PathType
+{
+ SDL_PATHTYPE_NONE, /**< path does not exist */
+ SDL_PATHTYPE_FILE, /**< a normal file */
+ SDL_PATHTYPE_DIRECTORY, /**< a directory */
+ SDL_PATHTYPE_OTHER /**< something completely different like a device node (not a symlink, those are always followed) */
+} SDL_PathType;
+
+/**
+ * Information about a path on the filesystem.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetPathInfo
+ * \sa SDL_GetStoragePathInfo
+ */
+typedef struct SDL_PathInfo
+{
+ SDL_PathType type; /**< the path type */
+ Uint64 size; /**< the file size in bytes */
+ SDL_Time create_time; /**< the time when the path was created */
+ SDL_Time modify_time; /**< the last time the path was modified */
+ SDL_Time access_time; /**< the last time the path was read */
+} SDL_PathInfo;
+
+/**
+ * Flags for path matching.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_GlobDirectory
+ * \sa SDL_GlobStorageDirectory
+ */
+typedef Uint32 SDL_GlobFlags;
+
+#define SDL_GLOB_CASEINSENSITIVE (1u << 0)
+
+/**
+ * Create a directory, and any missing parent directories.
+ *
+ * This reports success if `path` already exists as a directory.
+ *
+ * If parent directories are missing, it will also create them. Note that if
+ * this fails, it will not remove any parent directories it already made.
+ *
+ * \param path the path of the directory to create.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CreateDirectory(const char *path);
+
+/**
+ * Possible results from an enumeration callback.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_EnumerateDirectoryCallback
+ */
+typedef enum SDL_EnumerationResult
+{
+ SDL_ENUM_CONTINUE, /**< Value that requests that enumeration continue. */
+ SDL_ENUM_SUCCESS, /**< Value that requests that enumeration stop, successfully. */
+ SDL_ENUM_FAILURE /**< Value that requests that enumeration stop, as a failure. */
+} SDL_EnumerationResult;
+
+/**
+ * Callback for directory enumeration.
+ *
+ * Enumeration of directory entries will continue until either all entries
+ * have been provided to the callback, or the callback has requested a stop
+ * through its return value.
+ *
+ * Returning SDL_ENUM_CONTINUE will let enumeration proceed, calling the
+ * callback with further entries. SDL_ENUM_SUCCESS and SDL_ENUM_FAILURE will
+ * terminate the enumeration early, and dictate the return value of the
+ * enumeration function itself.
+ *
+ * `dirname` is guaranteed to end with a path separator ('\\' on Windows, '/'
+ * on most other platforms).
+ *
+ * \param userdata an app-controlled pointer that is passed to the callback.
+ * \param dirname the directory that is being enumerated.
+ * \param fname the next entry in the enumeration.
+ * \returns how the enumeration should proceed.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_EnumerateDirectory
+ */
+typedef SDL_EnumerationResult (SDLCALL *SDL_EnumerateDirectoryCallback)(void *userdata, const char *dirname, const char *fname);
+
+/**
+ * Enumerate a directory through a callback function.
+ *
+ * This function provides every directory entry through an app-provided
+ * callback, called once for each directory entry, until all results have been
+ * provided or the callback returns either SDL_ENUM_SUCCESS or
+ * SDL_ENUM_FAILURE.
+ *
+ * This will return false if there was a system problem in general, or if a
+ * callback returns SDL_ENUM_FAILURE. A successful return means a callback
+ * returned SDL_ENUM_SUCCESS to halt enumeration, or all directory entries
+ * were enumerated.
+ *
+ * \param path the path of the directory to enumerate.
+ * \param callback a function that is called for each entry in the directory.
+ * \param userdata a pointer that is passed to `callback`.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback callback, void *userdata);
+
+/**
+ * Remove a file or an empty directory.
+ *
+ * Directories that are not empty will fail; this function will not recursely
+ * delete directory trees.
+ *
+ * \param path the path to remove from the filesystem.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RemovePath(const char *path);
+
+/**
+ * Rename a file or directory.
+ *
+ * If the file at `newpath` already exists, it will replaced.
+ *
+ * Note that this will not copy files across filesystems/drives/volumes, as
+ * that is a much more complicated (and possibly time-consuming) operation.
+ *
+ * Which is to say, if this function fails, SDL_CopyFile() to a temporary file
+ * in the same directory as `newpath`, then SDL_RenamePath() from the
+ * temporary file to `newpath` and SDL_RemovePath() on `oldpath` might work
+ * for files. Renaming a non-empty directory across filesystems is
+ * dramatically more complex, however.
+ *
+ * \param oldpath the old path.
+ * \param newpath the new path.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RenamePath(const char *oldpath, const char *newpath);
+
+/**
+ * Copy a file.
+ *
+ * If the file at `newpath` already exists, it will be overwritten with the
+ * contents of the file at `oldpath`.
+ *
+ * This function will block until the copy is complete, which might be a
+ * significant time for large files on slow disks. On some platforms, the copy
+ * can be handed off to the OS itself, but on others SDL might just open both
+ * paths, and read from one and write to the other.
+ *
+ * Note that this is not an atomic operation! If something tries to read from
+ * `newpath` while the copy is in progress, it will see an incomplete copy of
+ * the data, and if the calling thread terminates (or the power goes out)
+ * during the copy, `newpath`'s previous contents will be gone, replaced with
+ * an incomplete copy of the data. To avoid this risk, it is recommended that
+ * the app copy to a temporary file in the same directory as `newpath`, and if
+ * the copy is successful, use SDL_RenamePath() to replace `newpath` with the
+ * temporary file. This will ensure that reads of `newpath` will either see a
+ * complete copy of the data, or it will see the pre-copy state of `newpath`.
+ *
+ * This function attempts to synchronize the newly-copied data to disk before
+ * returning, if the platform allows it, so that the renaming trick will not
+ * have a problem in a system crash or power failure, where the file could be
+ * renamed but the contents never made it from the system file cache to the
+ * physical disk.
+ *
+ * If the copy fails for any reason, the state of `newpath` is undefined. It
+ * might be half a copy, it might be the untouched data of what was already
+ * there, or it might be a zero-byte file, etc.
+ *
+ * \param oldpath the old path.
+ * \param newpath the new path.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CopyFile(const char *oldpath, const char *newpath);
+
+/**
+ * Get information about a filesystem path.
+ *
+ * \param path the path to query.
+ * \param info a pointer filled in with information about the path, or NULL to
+ * check for the existence of a file.
+ * \returns true on success or false if the file doesn't exist, or another
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetPathInfo(const char *path, SDL_PathInfo *info);
+
+/**
+ * Enumerate a directory tree, filtered by pattern, and return a list.
+ *
+ * Files are filtered out if they don't match the string in `pattern`, which
+ * may contain wildcard characters '\*' (match everything) and '?' (match one
+ * character). If pattern is NULL, no filtering is done and all results are
+ * returned. Subdirectories are permitted, and are specified with a path
+ * separator of '/'. Wildcard characters '\*' and '?' never match a path
+ * separator.
+ *
+ * `flags` may be set to SDL_GLOB_CASEINSENSITIVE to make the pattern matching
+ * case-insensitive.
+ *
+ * The returned array is always NULL-terminated, for your iterating
+ * convenience, but if `count` is non-NULL, on return it will contain the
+ * number of items in the array, not counting the NULL terminator.
+ *
+ * \param path the path of the directory to enumerate.
+ * \param pattern the pattern that files in the directory must match. Can be
+ * NULL.
+ * \param flags `SDL_GLOB_*` bitflags that affect this search.
+ * \param count on return, will be set to the number of items in the returned
+ * array. Can be NULL.
+ * \returns an array of strings on success or NULL on failure; call
+ * SDL_GetError() for more information. This is a single allocation
+ * that should be freed with SDL_free() when it is no longer needed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC char ** SDLCALL SDL_GlobDirectory(const char *path, const char *pattern, SDL_GlobFlags flags, int *count);
+
+/**
+ * Get what the system believes is the "current working directory."
+ *
+ * For systems without a concept of a current working directory, this will
+ * still attempt to provide something reasonable.
+ *
+ * SDL does not provide a means to _change_ the current working directory; for
+ * platforms without this concept, this would cause surprises with file access
+ * outside of SDL.
+ *
+ * The returned path is guaranteed to end with a path separator ('\\' on
+ * Windows, '/' on most other platforms).
+ *
+ * \returns a UTF-8 string of the current working directory in
+ * platform-dependent notation. NULL if there's a problem. This
+ * should be freed with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetCurrentDirectory(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_filesystem_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_gamepad.h b/vendored/SDL/include/SDL3/SDL_gamepad.h
new file mode 100644
index 0000000..99f8b65
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_gamepad.h
@@ -0,0 +1,1509 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryGamepad
+ *
+ * SDL provides a low-level joystick API, which just treats joysticks as an
+ * arbitrary pile of buttons, axes, and hat switches. If you're planning to
+ * write your own control configuration screen, this can give you a lot of
+ * flexibility, but that's a lot of work, and most things that we consider
+ * "joysticks" now are actually console-style gamepads. So SDL provides the
+ * gamepad API on top of the lower-level joystick functionality.
+ *
+ * The difference between a joystick and a gamepad is that a gamepad tells you
+ * _where_ a button or axis is on the device. You don't speak to gamepads in
+ * terms of arbitrary numbers like "button 3" or "axis 2" but in standard
+ * locations: the d-pad, the shoulder buttons, triggers, A/B/X/Y (or
+ * X/O/Square/Triangle, if you will).
+ *
+ * One turns a joystick into a gamepad by providing a magic configuration
+ * string, which tells SDL the details of a specific device: when you see this
+ * specific hardware, if button 2 gets pressed, this is actually D-Pad Up,
+ * etc.
+ *
+ * SDL has many popular controllers configured out of the box, and users can
+ * add their own controller details through an environment variable if it's
+ * otherwise unknown to SDL.
+ *
+ * In order to use these functions, SDL_Init() must have been called with the
+ * SDL_INIT_GAMEPAD flag. This causes SDL to scan the system for gamepads, and
+ * load appropriate drivers.
+ *
+ * If you would like to receive gamepad updates while the application is in
+ * the background, you should set the following hint before calling
+ * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
+ *
+ * Gamepads support various optional features such as rumble, color LEDs,
+ * touchpad, gyro, etc. The support for these features varies depending on the
+ * controller and OS support available. You can check for LED and rumble
+ * capabilities at runtime by calling SDL_GetGamepadProperties() and checking
+ * the various capability properties. You can check for touchpad by calling
+ * SDL_GetNumGamepadTouchpads() and check for gyro and accelerometer by
+ * calling SDL_GamepadHasSensor().
+ *
+ * By default SDL will try to use the most capable driver available, but you
+ * can tune which OS drivers to use with the various joystick hints in
+ * SDL_hints.h.
+ *
+ * Your application should always support gamepad hotplugging. On some
+ * platforms like Xbox, Steam Deck, etc., this is a requirement for
+ * certification. On other platforms, like macOS and Windows when using
+ * Windows.Gaming.Input, controllers may not be available at startup and will
+ * come in at some point after you've started processing events.
+ */
+
+#ifndef SDL_gamepad_h_
+#define SDL_gamepad_h_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The structure used to identify an SDL gamepad
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_Gamepad SDL_Gamepad;
+
+/**
+ * Standard gamepad types.
+ *
+ * This type does not necessarily map to first-party controllers from
+ * Microsoft/Sony/Nintendo; in many cases, third-party controllers can report
+ * as these, either because they were designed for a specific console, or they
+ * simply most closely match that console's controllers (does it have A/B/X/Y
+ * buttons or X/O/Square/Triangle? Does it have a touchpad? etc).
+ */
+typedef enum SDL_GamepadType
+{
+ SDL_GAMEPAD_TYPE_UNKNOWN = 0,
+ SDL_GAMEPAD_TYPE_STANDARD,
+ SDL_GAMEPAD_TYPE_XBOX360,
+ SDL_GAMEPAD_TYPE_XBOXONE,
+ SDL_GAMEPAD_TYPE_PS3,
+ SDL_GAMEPAD_TYPE_PS4,
+ SDL_GAMEPAD_TYPE_PS5,
+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO,
+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT,
+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT,
+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR,
+ SDL_GAMEPAD_TYPE_COUNT
+} SDL_GamepadType;
+
+/**
+ * The list of buttons available on a gamepad
+ *
+ * For controllers that use a diamond pattern for the face buttons, the
+ * south/east/west/north buttons below correspond to the locations in the
+ * diamond pattern. For Xbox controllers, this would be A/B/X/Y, for Nintendo
+ * Switch controllers, this would be B/A/Y/X, for PlayStation controllers this
+ * would be Cross/Circle/Square/Triangle.
+ *
+ * For controllers that don't use a diamond pattern for the face buttons, the
+ * south/east/west/north buttons indicate the buttons labeled A, B, C, D, or
+ * 1, 2, 3, 4, or for controllers that aren't labeled, they are the primary,
+ * secondary, etc. buttons.
+ *
+ * The activate action is often the south button and the cancel action is
+ * often the east button, but in some regions this is reversed, so your game
+ * should allow remapping actions based on user preferences.
+ *
+ * You can query the labels for the face buttons using
+ * SDL_GetGamepadButtonLabel()
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_GamepadButton
+{
+ SDL_GAMEPAD_BUTTON_INVALID = -1,
+ SDL_GAMEPAD_BUTTON_SOUTH, /**< Bottom face button (e.g. Xbox A button) */
+ SDL_GAMEPAD_BUTTON_EAST, /**< Right face button (e.g. Xbox B button) */
+ SDL_GAMEPAD_BUTTON_WEST, /**< Left face button (e.g. Xbox X button) */
+ SDL_GAMEPAD_BUTTON_NORTH, /**< Top face button (e.g. Xbox Y button) */
+ SDL_GAMEPAD_BUTTON_BACK,
+ SDL_GAMEPAD_BUTTON_GUIDE,
+ SDL_GAMEPAD_BUTTON_START,
+ SDL_GAMEPAD_BUTTON_LEFT_STICK,
+ SDL_GAMEPAD_BUTTON_RIGHT_STICK,
+ SDL_GAMEPAD_BUTTON_LEFT_SHOULDER,
+ SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER,
+ SDL_GAMEPAD_BUTTON_DPAD_UP,
+ SDL_GAMEPAD_BUTTON_DPAD_DOWN,
+ SDL_GAMEPAD_BUTTON_DPAD_LEFT,
+ SDL_GAMEPAD_BUTTON_DPAD_RIGHT,
+ SDL_GAMEPAD_BUTTON_MISC1, /**< Additional button (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button, Google Stadia capture button) */
+ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, /**< Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) */
+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /**< Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) */
+ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /**< Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) */
+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /**< Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) */
+ SDL_GAMEPAD_BUTTON_TOUCHPAD, /**< PS4/PS5 touchpad button */
+ SDL_GAMEPAD_BUTTON_MISC2, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_MISC3, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_MISC4, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_MISC5, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_MISC6, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_COUNT
+} SDL_GamepadButton;
+
+/**
+ * The set of gamepad button labels
+ *
+ * This isn't a complete set, just the face buttons to make it easy to show
+ * button prompts.
+ *
+ * For a complete set, you should look at the button and gamepad type and have
+ * a set of symbols that work well with your art style.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_GamepadButtonLabel
+{
+ SDL_GAMEPAD_BUTTON_LABEL_UNKNOWN,
+ SDL_GAMEPAD_BUTTON_LABEL_A,
+ SDL_GAMEPAD_BUTTON_LABEL_B,
+ SDL_GAMEPAD_BUTTON_LABEL_X,
+ SDL_GAMEPAD_BUTTON_LABEL_Y,
+ SDL_GAMEPAD_BUTTON_LABEL_CROSS,
+ SDL_GAMEPAD_BUTTON_LABEL_CIRCLE,
+ SDL_GAMEPAD_BUTTON_LABEL_SQUARE,
+ SDL_GAMEPAD_BUTTON_LABEL_TRIANGLE
+} SDL_GamepadButtonLabel;
+
+/**
+ * The list of axes available on a gamepad
+ *
+ * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to
+ * SDL_JOYSTICK_AXIS_MAX, and are centered within ~8000 of zero, though
+ * advanced UI will allow users to set or autodetect the dead zone, which
+ * varies between gamepads.
+ *
+ * Trigger axis values range from 0 (released) to SDL_JOYSTICK_AXIS_MAX (fully
+ * pressed) when reported by SDL_GetGamepadAxis(). Note that this is not the
+ * same range that will be reported by the lower-level SDL_GetJoystickAxis().
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_GamepadAxis
+{
+ SDL_GAMEPAD_AXIS_INVALID = -1,
+ SDL_GAMEPAD_AXIS_LEFTX,
+ SDL_GAMEPAD_AXIS_LEFTY,
+ SDL_GAMEPAD_AXIS_RIGHTX,
+ SDL_GAMEPAD_AXIS_RIGHTY,
+ SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
+ SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,
+ SDL_GAMEPAD_AXIS_COUNT
+} SDL_GamepadAxis;
+
+/**
+ * Types of gamepad control bindings.
+ *
+ * A gamepad is a collection of bindings that map arbitrary joystick buttons,
+ * axes and hat switches to specific positions on a generic console-style
+ * gamepad. This enum is used as part of SDL_GamepadBinding to specify those
+ * mappings.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_GamepadBindingType
+{
+ SDL_GAMEPAD_BINDTYPE_NONE = 0,
+ SDL_GAMEPAD_BINDTYPE_BUTTON,
+ SDL_GAMEPAD_BINDTYPE_AXIS,
+ SDL_GAMEPAD_BINDTYPE_HAT
+} SDL_GamepadBindingType;
+
+/**
+ * A mapping between one joystick input to a gamepad control.
+ *
+ * A gamepad has a collection of several bindings, to say, for example, when
+ * joystick button number 5 is pressed, that should be treated like the
+ * gamepad's "start" button.
+ *
+ * SDL has these bindings built-in for many popular controllers, and can add
+ * more with a simple text string. Those strings are parsed into a collection
+ * of these structs to make it easier to operate on the data.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadBindings
+ */
+typedef struct SDL_GamepadBinding
+{
+ SDL_GamepadBindingType input_type;
+ union
+ {
+ int button;
+
+ struct
+ {
+ int axis;
+ int axis_min;
+ int axis_max;
+ } axis;
+
+ struct
+ {
+ int hat;
+ int hat_mask;
+ } hat;
+
+ } input;
+
+ SDL_GamepadBindingType output_type;
+ union
+ {
+ SDL_GamepadButton button;
+
+ struct
+ {
+ SDL_GamepadAxis axis;
+ int axis_min;
+ int axis_max;
+ } axis;
+
+ } output;
+} SDL_GamepadBinding;
+
+
+/**
+ * Add support for gamepads that SDL is unaware of or change the binding of an
+ * existing gamepad.
+ *
+ * The mapping string has the format "GUID,name,mapping", where GUID is the
+ * string value from SDL_GUIDToString(), name is the human readable string for
+ * the device and mappings are gamepad mappings to joystick ones. Under
+ * Windows there is a reserved GUID of "xinput" that covers all XInput
+ * devices. The mapping format for joystick is:
+ *
+ * - `bX`: a joystick button, index X
+ * - `hX.Y`: hat X with value Y
+ * - `aX`: axis X of the joystick
+ *
+ * Buttons can be used as a gamepad axes and vice versa.
+ *
+ * If a device with this GUID is already plugged in, SDL will generate an
+ * SDL_EVENT_GAMEPAD_ADDED event.
+ *
+ * This string shows an example of a valid mapping for a gamepad:
+ *
+ * ```c
+ * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"
+ * ```
+ *
+ * \param mapping the mapping string.
+ * \returns 1 if a new mapping is added, 0 if an existing mapping is updated,
+ * -1 on failure; call SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddGamepadMappingsFromFile
+ * \sa SDL_AddGamepadMappingsFromIO
+ * \sa SDL_GetGamepadMapping
+ * \sa SDL_GetGamepadMappingForGUID
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG_FILE
+ * \sa SDL_EVENT_GAMEPAD_ADDED
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
+
+/**
+ * Load a set of gamepad mappings from an SDL_IOStream.
+ *
+ * You can call this function several times, if needed, to load different
+ * database files.
+ *
+ * If a new mapping is loaded for an already known gamepad GUID, the later
+ * version will overwrite the one currently loaded.
+ *
+ * Any new mappings for already plugged in controllers will generate
+ * SDL_EVENT_GAMEPAD_ADDED events.
+ *
+ * Mappings not belonging to the current platform or with no platform field
+ * specified will be ignored (i.e. mappings for Linux will be ignored in
+ * Windows, etc).
+ *
+ * This function will load the text database entirely in memory before
+ * processing it, so take this into consideration if you are in a memory
+ * constrained environment.
+ *
+ * \param src the data stream for the mappings to be added.
+ * \param closeio if true, calls SDL_CloseIO() on `src` before returning, even
+ * in the case of an error.
+ * \returns the number of mappings added or -1 on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddGamepadMapping
+ * \sa SDL_AddGamepadMappingsFromFile
+ * \sa SDL_GetGamepadMapping
+ * \sa SDL_GetGamepadMappingForGUID
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG_FILE
+ * \sa SDL_EVENT_GAMEPAD_ADDED
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromIO(SDL_IOStream *src, bool closeio);
+
+/**
+ * Load a set of gamepad mappings from a file.
+ *
+ * You can call this function several times, if needed, to load different
+ * database files.
+ *
+ * If a new mapping is loaded for an already known gamepad GUID, the later
+ * version will overwrite the one currently loaded.
+ *
+ * Any new mappings for already plugged in controllers will generate
+ * SDL_EVENT_GAMEPAD_ADDED events.
+ *
+ * Mappings not belonging to the current platform or with no platform field
+ * specified will be ignored (i.e. mappings for Linux will be ignored in
+ * Windows, etc).
+ *
+ * \param file the mappings file to load.
+ * \returns the number of mappings added or -1 on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddGamepadMapping
+ * \sa SDL_AddGamepadMappingsFromIO
+ * \sa SDL_GetGamepadMapping
+ * \sa SDL_GetGamepadMappingForGUID
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG
+ * \sa SDL_HINT_GAMECONTROLLERCONFIG_FILE
+ * \sa SDL_EVENT_GAMEPAD_ADDED
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromFile(const char *file);
+
+/**
+ * Reinitialize the SDL mapping database to its initial state.
+ *
+ * This will generate gamepad events as needed if device mappings change.
+ *
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ReloadGamepadMappings(void);
+
+/**
+ * Get the current gamepad mappings.
+ *
+ * \param count a pointer filled in with the number of mappings returned, can
+ * be NULL.
+ * \returns an array of the mapping strings, NULL-terminated, or NULL on
+ * failure; call SDL_GetError() for more information. This is a
+ * single allocation that should be freed with SDL_free() when it is
+ * no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count);
+
+/**
+ * Get the gamepad mapping string for a given GUID.
+ *
+ * \param guid a structure containing the GUID for which a mapping is desired.
+ * \returns a mapping string or NULL on failure; call SDL_GetError() for more
+ * information. This should be freed with SDL_free() when it is no
+ * longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetJoystickGUIDForID
+ * \sa SDL_GetJoystickGUID
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_GUID guid);
+
+/**
+ * Get the current mapping of a gamepad.
+ *
+ * Details about mappings are discussed with SDL_AddGamepadMapping().
+ *
+ * \param gamepad the gamepad you want to get the current mapping for.
+ * \returns a string that has the gamepad's mapping or NULL if no mapping is
+ * available; call SDL_GetError() for more information. This should
+ * be freed with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddGamepadMapping
+ * \sa SDL_GetGamepadMappingForID
+ * \sa SDL_GetGamepadMappingForGUID
+ * \sa SDL_SetGamepadMapping
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad);
+
+/**
+ * Set the current mapping of a joystick or gamepad.
+ *
+ * Details about mappings are discussed with SDL_AddGamepadMapping().
+ *
+ * \param instance_id the joystick instance ID.
+ * \param mapping the mapping to use for this device, or NULL to clear the
+ * mapping.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddGamepadMapping
+ * \sa SDL_GetGamepadMapping
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadMapping(SDL_JoystickID instance_id, const char *mapping);
+
+/**
+ * Return whether a gamepad is currently connected.
+ *
+ * \returns true if a gamepad is connected, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HasGamepad(void);
+
+/**
+ * Get a list of currently connected gamepads.
+ *
+ * \param count a pointer filled in with the number of gamepads returned, may
+ * be NULL.
+ * \returns a 0 terminated array of joystick instance IDs or NULL on failure;
+ * call SDL_GetError() for more information. This should be freed
+ * with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HasGamepad
+ * \sa SDL_OpenGamepad
+ */
+extern SDL_DECLSPEC SDL_JoystickID * SDLCALL SDL_GetGamepads(int *count);
+
+/**
+ * Check if the given joystick is supported by the gamepad interface.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns true if the given joystick is supported by the gamepad interface,
+ * false if it isn't or it's an invalid index.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetJoysticks
+ * \sa SDL_OpenGamepad
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsGamepad(SDL_JoystickID instance_id);
+
+/**
+ * Get the implementation dependent name of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the name of the selected gamepad. If no name can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadName
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadNameForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the implementation dependent path of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the path of the selected gamepad. If no path can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadPath
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadPathForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the player index of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the player index of a gamepad, or -1 if it's not available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadPlayerIndex
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetGamepadPlayerIndexForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the implementation-dependent GUID of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the GUID of the selected gamepad. If called on an invalid index,
+ * this function returns a zero GUID.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GUIDToString
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_GetGamepadGUIDForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the USB vendor ID of a gamepad, if available.
+ *
+ * This can be called before any gamepads are opened. If the vendor ID isn't
+ * available this function returns 0.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the USB vendor ID of the selected gamepad. If called on an invalid
+ * index, this function returns zero.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadVendor
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadVendorForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the USB product ID of a gamepad, if available.
+ *
+ * This can be called before any gamepads are opened. If the product ID isn't
+ * available this function returns 0.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the USB product ID of the selected gamepad. If called on an
+ * invalid index, this function returns zero.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadProduct
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the product version of a gamepad, if available.
+ *
+ * This can be called before any gamepads are opened. If the product version
+ * isn't available this function returns 0.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the product version of the selected gamepad. If called on an
+ * invalid index, this function returns zero.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadProductVersion
+ * \sa SDL_GetGamepads
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductVersionForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the type of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the gamepad type.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadType
+ * \sa SDL_GetGamepads
+ * \sa SDL_GetRealGamepadTypeForID
+ */
+extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the type of a gamepad, ignoring any mapping override.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the gamepad type.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadTypeForID
+ * \sa SDL_GetGamepads
+ * \sa SDL_GetRealGamepadType
+ */
+extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadTypeForID(SDL_JoystickID instance_id);
+
+/**
+ * Get the mapping of a gamepad.
+ *
+ * This can be called before any gamepads are opened.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns the mapping string. Returns NULL if no mapping is available. This
+ * should be freed with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepads
+ * \sa SDL_GetGamepadMapping
+ */
+extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID instance_id);
+
+/**
+ * Open a gamepad for use.
+ *
+ * \param instance_id the joystick instance ID.
+ * \returns a gamepad identifier or NULL if an error occurred; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseGamepad
+ * \sa SDL_IsGamepad
+ */
+extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_OpenGamepad(SDL_JoystickID instance_id);
+
+/**
+ * Get the SDL_Gamepad associated with a joystick instance ID, if it has been
+ * opened.
+ *
+ * \param instance_id the joystick instance ID of the gamepad.
+ * \returns an SDL_Gamepad on success or NULL on failure or if it hasn't been
+ * opened yet; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_GetGamepadFromID(SDL_JoystickID instance_id);
+
+/**
+ * Get the SDL_Gamepad associated with a player index.
+ *
+ * \param player_index the player index, which different from the instance ID.
+ * \returns the SDL_Gamepad associated with a player index.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadPlayerIndex
+ * \sa SDL_SetGamepadPlayerIndex
+ */
+extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_GetGamepadFromPlayerIndex(int player_index);
+
+/**
+ * Get the properties associated with an opened gamepad.
+ *
+ * These properties are shared with the underlying joystick object.
+ *
+ * The following read-only properties are provided by SDL:
+ *
+ * - `SDL_PROP_GAMEPAD_CAP_MONO_LED_BOOLEAN`: true if this gamepad has an LED
+ * that has adjustable brightness
+ * - `SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN`: true if this gamepad has an LED
+ * that has adjustable color
+ * - `SDL_PROP_GAMEPAD_CAP_PLAYER_LED_BOOLEAN`: true if this gamepad has a
+ * player LED
+ * - `SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN`: true if this gamepad has
+ * left/right rumble
+ * - `SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN`: true if this gamepad has
+ * simple trigger rumble
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ * \returns a valid property ID on success or 0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGamepadProperties(SDL_Gamepad *gamepad);
+
+#define SDL_PROP_GAMEPAD_CAP_MONO_LED_BOOLEAN SDL_PROP_JOYSTICK_CAP_MONO_LED_BOOLEAN
+#define SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN
+#define SDL_PROP_GAMEPAD_CAP_PLAYER_LED_BOOLEAN SDL_PROP_JOYSTICK_CAP_PLAYER_LED_BOOLEAN
+#define SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN
+#define SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN
+
+/**
+ * Get the instance ID of an opened gamepad.
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ * \returns the instance ID of the specified gamepad on success or 0 on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_GetGamepadID(SDL_Gamepad *gamepad);
+
+/**
+ * Get the implementation-dependent name for an opened gamepad.
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ * \returns the implementation dependent name for the gamepad, or NULL if
+ * there is no name or the identifier passed is invalid.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadNameForID
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad);
+
+/**
+ * Get the implementation-dependent path for an opened gamepad.
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ * \returns the implementation dependent path for the gamepad, or NULL if
+ * there is no path or the identifier passed is invalid.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadPathForID
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadPath(SDL_Gamepad *gamepad);
+
+/**
+ * Get the type of an opened gamepad.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the gamepad type, or SDL_GAMEPAD_TYPE_UNKNOWN if it's not
+ * available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadTypeForID
+ */
+extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadType(SDL_Gamepad *gamepad);
+
+/**
+ * Get the type of an opened gamepad, ignoring any mapping override.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the gamepad type, or SDL_GAMEPAD_TYPE_UNKNOWN if it's not
+ * available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetRealGamepadTypeForID
+ */
+extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadType(SDL_Gamepad *gamepad);
+
+/**
+ * Get the player index of an opened gamepad.
+ *
+ * For XInput gamepads this returns the XInput user index.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the player index for gamepad, or -1 if it's not available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGamepadPlayerIndex
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetGamepadPlayerIndex(SDL_Gamepad *gamepad);
+
+/**
+ * Set the player index of an opened gamepad.
+ *
+ * \param gamepad the gamepad object to adjust.
+ * \param player_index player index to assign to this gamepad, or -1 to clear
+ * the player index and turn off player LEDs.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadPlayerIndex
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadPlayerIndex(SDL_Gamepad *gamepad, int player_index);
+
+/**
+ * Get the USB vendor ID of an opened gamepad, if available.
+ *
+ * If the vendor ID isn't available this function returns 0.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the USB vendor ID, or zero if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadVendorForID
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadVendor(SDL_Gamepad *gamepad);
+
+/**
+ * Get the USB product ID of an opened gamepad, if available.
+ *
+ * If the product ID isn't available this function returns 0.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the USB product ID, or zero if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadProductForID
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProduct(SDL_Gamepad *gamepad);
+
+/**
+ * Get the product version of an opened gamepad, if available.
+ *
+ * If the product version isn't available this function returns 0.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the USB product version, or zero if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadProductVersionForID
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductVersion(SDL_Gamepad *gamepad);
+
+/**
+ * Get the firmware version of an opened gamepad, if available.
+ *
+ * If the firmware version isn't available this function returns 0.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the gamepad firmware version, or zero if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadFirmwareVersion(SDL_Gamepad *gamepad);
+
+/**
+ * Get the serial number of an opened gamepad, if available.
+ *
+ * Returns the serial number of the gamepad, or NULL if it is not available.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the serial number, or NULL if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadSerial(SDL_Gamepad *gamepad);
+
+/**
+ * Get the Steam Input handle of an opened gamepad, if available.
+ *
+ * Returns an InputHandle_t for the gamepad that can be used with Steam Input
+ * API: https://partner.steamgames.com/doc/api/ISteamInput
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the gamepad handle, or 0 if unavailable.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC Uint64 SDLCALL SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad);
+
+/**
+ * Get the connection state of a gamepad.
+ *
+ * \param gamepad the gamepad object to query.
+ * \returns the connection state on success or
+ * `SDL_JOYSTICK_CONNECTION_INVALID` on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_JoystickConnectionState SDLCALL SDL_GetGamepadConnectionState(SDL_Gamepad *gamepad);
+
+/**
+ * Get the battery state of a gamepad.
+ *
+ * You should never take a battery status as absolute truth. Batteries
+ * (especially failing batteries) are delicate hardware, and the values
+ * reported here are best estimates based on what that hardware reports. It's
+ * not uncommon for older batteries to lose stored power much faster than it
+ * reports, or completely drain when reporting it has 20 percent left, etc.
+ *
+ * \param gamepad the gamepad object to query.
+ * \param percent a pointer filled in with the percentage of battery life
+ * left, between 0 and 100, or NULL to ignore. This will be
+ * filled in with -1 we can't determine a value or there is no
+ * battery.
+ * \returns the current battery state.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_PowerState SDLCALL SDL_GetGamepadPowerInfo(SDL_Gamepad *gamepad, int *percent);
+
+/**
+ * Check if a gamepad has been opened and is currently connected.
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ * \returns true if the gamepad has been opened and is currently connected, or
+ * false if not.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadConnected(SDL_Gamepad *gamepad);
+
+/**
+ * Get the underlying joystick from a gamepad.
+ *
+ * This function will give you a SDL_Joystick object, which allows you to use
+ * the SDL_Joystick functions with a SDL_Gamepad object. This would be useful
+ * for getting a joystick's position at any given time, even if it hasn't
+ * moved (moving it would produce an event, which would have the axis' value).
+ *
+ * The pointer returned is owned by the SDL_Gamepad. You should not call
+ * SDL_CloseJoystick() on it, for example, since doing so will likely cause
+ * SDL to crash.
+ *
+ * \param gamepad the gamepad object that you want to get a joystick from.
+ * \returns an SDL_Joystick object, or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_Joystick * SDLCALL SDL_GetGamepadJoystick(SDL_Gamepad *gamepad);
+
+/**
+ * Set the state of gamepad event processing.
+ *
+ * If gamepad events are disabled, you must call SDL_UpdateGamepads() yourself
+ * and check the state of the gamepad when you want gamepad information.
+ *
+ * \param enabled whether to process gamepad events or not.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadEventsEnabled
+ * \sa SDL_UpdateGamepads
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGamepadEventsEnabled(bool enabled);
+
+/**
+ * Query the state of gamepad event processing.
+ *
+ * If gamepad events are disabled, you must call SDL_UpdateGamepads() yourself
+ * and check the state of the gamepad when you want gamepad information.
+ *
+ * \returns true if gamepad events are being processed, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGamepadEventsEnabled
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadEventsEnabled(void);
+
+/**
+ * Get the SDL joystick layer bindings for a gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \param count a pointer filled in with the number of bindings returned.
+ * \returns a NULL terminated array of pointers to bindings or NULL on
+ * failure; call SDL_GetError() for more information. This is a
+ * single allocation that should be freed with SDL_free() when it is
+ * no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_GamepadBinding ** SDLCALL SDL_GetGamepadBindings(SDL_Gamepad *gamepad, int *count);
+
+/**
+ * Manually pump gamepad updates if not using the loop.
+ *
+ * This function is called automatically by the event loop if events are
+ * enabled. Under such circumstances, it will not be necessary to call this
+ * function.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UpdateGamepads(void);
+
+/**
+ * Convert a string into SDL_GamepadType enum.
+ *
+ * This function is called internally to translate SDL_Gamepad mapping strings
+ * for the underlying joystick device into the consistent SDL_Gamepad mapping.
+ * You do not normally need to call this function unless you are parsing
+ * SDL_Gamepad mappings in your own code.
+ *
+ * \param str string representing a SDL_GamepadType type.
+ * \returns the SDL_GamepadType enum corresponding to the input string, or
+ * `SDL_GAMEPAD_TYPE_UNKNOWN` if no match was found.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadStringForType
+ */
+extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeFromString(const char *str);
+
+/**
+ * Convert from an SDL_GamepadType enum to a string.
+ *
+ * \param type an enum value for a given SDL_GamepadType.
+ * \returns a string for the given type, or NULL if an invalid type is
+ * specified. The string returned is of the format used by
+ * SDL_Gamepad mapping strings.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadTypeFromString
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForType(SDL_GamepadType type);
+
+/**
+ * Convert a string into SDL_GamepadAxis enum.
+ *
+ * This function is called internally to translate SDL_Gamepad mapping strings
+ * for the underlying joystick device into the consistent SDL_Gamepad mapping.
+ * You do not normally need to call this function unless you are parsing
+ * SDL_Gamepad mappings in your own code.
+ *
+ * Note specially that "righttrigger" and "lefttrigger" map to
+ * `SDL_GAMEPAD_AXIS_RIGHT_TRIGGER` and `SDL_GAMEPAD_AXIS_LEFT_TRIGGER`,
+ * respectively.
+ *
+ * \param str string representing a SDL_Gamepad axis.
+ * \returns the SDL_GamepadAxis enum corresponding to the input string, or
+ * `SDL_GAMEPAD_AXIS_INVALID` if no match was found.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadStringForAxis
+ */
+extern SDL_DECLSPEC SDL_GamepadAxis SDLCALL SDL_GetGamepadAxisFromString(const char *str);
+
+/**
+ * Convert from an SDL_GamepadAxis enum to a string.
+ *
+ * \param axis an enum value for a given SDL_GamepadAxis.
+ * \returns a string for the given axis, or NULL if an invalid axis is
+ * specified. The string returned is of the format used by
+ * SDL_Gamepad mapping strings.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadAxisFromString
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForAxis(SDL_GamepadAxis axis);
+
+/**
+ * Query whether a gamepad has a given axis.
+ *
+ * This merely reports whether the gamepad's mapping defined this axis, as
+ * that is all the information SDL has about the physical device.
+ *
+ * \param gamepad a gamepad.
+ * \param axis an axis enum value (an SDL_GamepadAxis value).
+ * \returns true if the gamepad has this axis, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadHasButton
+ * \sa SDL_GetGamepadAxis
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis);
+
+/**
+ * Get the current state of an axis control on a gamepad.
+ *
+ * The axis indices start at index 0.
+ *
+ * For thumbsticks, the state is a value ranging from -32768 (up/left) to
+ * 32767 (down/right).
+ *
+ * Triggers range from 0 when released to 32767 when fully pressed, and never
+ * return a negative value. Note that this differs from the value reported by
+ * the lower-level SDL_GetJoystickAxis(), which normally uses the full range.
+ *
+ * \param gamepad a gamepad.
+ * \param axis an axis index (one of the SDL_GamepadAxis values).
+ * \returns axis state (including 0) on success or 0 (also) on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadHasAxis
+ * \sa SDL_GetGamepadButton
+ */
+extern SDL_DECLSPEC Sint16 SDLCALL SDL_GetGamepadAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis);
+
+/**
+ * Convert a string into an SDL_GamepadButton enum.
+ *
+ * This function is called internally to translate SDL_Gamepad mapping strings
+ * for the underlying joystick device into the consistent SDL_Gamepad mapping.
+ * You do not normally need to call this function unless you are parsing
+ * SDL_Gamepad mappings in your own code.
+ *
+ * \param str string representing a SDL_Gamepad axis.
+ * \returns the SDL_GamepadButton enum corresponding to the input string, or
+ * `SDL_GAMEPAD_BUTTON_INVALID` if no match was found.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadStringForButton
+ */
+extern SDL_DECLSPEC SDL_GamepadButton SDLCALL SDL_GetGamepadButtonFromString(const char *str);
+
+/**
+ * Convert from an SDL_GamepadButton enum to a string.
+ *
+ * \param button an enum value for a given SDL_GamepadButton.
+ * \returns a string for the given button, or NULL if an invalid button is
+ * specified. The string returned is of the format used by
+ * SDL_Gamepad mapping strings.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadButtonFromString
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForButton(SDL_GamepadButton button);
+
+/**
+ * Query whether a gamepad has a given button.
+ *
+ * This merely reports whether the gamepad's mapping defined this button, as
+ * that is all the information SDL has about the physical device.
+ *
+ * \param gamepad a gamepad.
+ * \param button a button enum value (an SDL_GamepadButton value).
+ * \returns true if the gamepad has this button, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadHasAxis
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasButton(SDL_Gamepad *gamepad, SDL_GamepadButton button);
+
+/**
+ * Get the current state of a button on a gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \param button a button index (one of the SDL_GamepadButton values).
+ * \returns true if the button is pressed, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadHasButton
+ * \sa SDL_GetGamepadAxis
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadButton(SDL_Gamepad *gamepad, SDL_GamepadButton button);
+
+/**
+ * Get the label of a button on a gamepad.
+ *
+ * \param type the type of gamepad to check.
+ * \param button a button index (one of the SDL_GamepadButton values).
+ * \returns the SDL_GamepadButtonLabel enum corresponding to the button label.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadButtonLabel
+ */
+extern SDL_DECLSPEC SDL_GamepadButtonLabel SDLCALL SDL_GetGamepadButtonLabelForType(SDL_GamepadType type, SDL_GamepadButton button);
+
+/**
+ * Get the label of a button on a gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \param button a button index (one of the SDL_GamepadButton values).
+ * \returns the SDL_GamepadButtonLabel enum corresponding to the button label.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadButtonLabelForType
+ */
+extern SDL_DECLSPEC SDL_GamepadButtonLabel SDLCALL SDL_GetGamepadButtonLabel(SDL_Gamepad *gamepad, SDL_GamepadButton button);
+
+/**
+ * Get the number of touchpads on a gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \returns number of touchpads.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetNumGamepadTouchpadFingers
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumGamepadTouchpads(SDL_Gamepad *gamepad);
+
+/**
+ * Get the number of supported simultaneous fingers on a touchpad on a game
+ * gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \param touchpad a touchpad.
+ * \returns number of supported simultaneous fingers.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadTouchpadFinger
+ * \sa SDL_GetNumGamepadTouchpads
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumGamepadTouchpadFingers(SDL_Gamepad *gamepad, int touchpad);
+
+/**
+ * Get the current state of a finger on a touchpad on a gamepad.
+ *
+ * \param gamepad a gamepad.
+ * \param touchpad a touchpad.
+ * \param finger a finger.
+ * \param down a pointer filled with true if the finger is down, false
+ * otherwise, may be NULL.
+ * \param x a pointer filled with the x position, normalized 0 to 1, with the
+ * origin in the upper left, may be NULL.
+ * \param y a pointer filled with the y position, normalized 0 to 1, with the
+ * origin in the upper left, may be NULL.
+ * \param pressure a pointer filled with pressure value, may be NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetNumGamepadTouchpadFingers
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadTouchpadFinger(SDL_Gamepad *gamepad, int touchpad, int finger, bool *down, float *x, float *y, float *pressure);
+
+/**
+ * Return whether a gamepad has a particular sensor.
+ *
+ * \param gamepad the gamepad to query.
+ * \param type the type of sensor to query.
+ * \returns true if the sensor exists, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadSensorData
+ * \sa SDL_GetGamepadSensorDataRate
+ * \sa SDL_SetGamepadSensorEnabled
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasSensor(SDL_Gamepad *gamepad, SDL_SensorType type);
+
+/**
+ * Set whether data reporting for a gamepad sensor is enabled.
+ *
+ * \param gamepad the gamepad to update.
+ * \param type the type of sensor to enable/disable.
+ * \param enabled whether data reporting should be enabled.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GamepadHasSensor
+ * \sa SDL_GamepadSensorEnabled
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadSensorEnabled(SDL_Gamepad *gamepad, SDL_SensorType type, bool enabled);
+
+/**
+ * Query whether sensor data reporting is enabled for a gamepad.
+ *
+ * \param gamepad the gamepad to query.
+ * \param type the type of sensor to query.
+ * \returns true if the sensor is enabled, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGamepadSensorEnabled
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GamepadSensorEnabled(SDL_Gamepad *gamepad, SDL_SensorType type);
+
+/**
+ * Get the data rate (number of events per second) of a gamepad sensor.
+ *
+ * \param gamepad the gamepad to query.
+ * \param type the type of sensor to query.
+ * \returns the data rate, or 0.0f if the data rate is not available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC float SDLCALL SDL_GetGamepadSensorDataRate(SDL_Gamepad *gamepad, SDL_SensorType type);
+
+/**
+ * Get the current state of a gamepad sensor.
+ *
+ * The number of values and interpretation of the data is sensor dependent.
+ * See SDL_sensor.h for the details for each type of sensor.
+ *
+ * \param gamepad the gamepad to query.
+ * \param type the type of sensor to query.
+ * \param data a pointer filled with the current sensor state.
+ * \param num_values the number of values to write to data.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadSensorData(SDL_Gamepad *gamepad, SDL_SensorType type, float *data, int num_values);
+
+/**
+ * Start a rumble effect on a gamepad.
+ *
+ * Each call to this function cancels any previous rumble effect, and calling
+ * it with 0 intensity stops any rumbling.
+ *
+ * This function requires you to process SDL events or call
+ * SDL_UpdateJoysticks() to update rumble state.
+ *
+ * \param gamepad the gamepad to vibrate.
+ * \param low_frequency_rumble the intensity of the low frequency (left)
+ * rumble motor, from 0 to 0xFFFF.
+ * \param high_frequency_rumble the intensity of the high frequency (right)
+ * rumble motor, from 0 to 0xFFFF.
+ * \param duration_ms the duration of the rumble effect, in milliseconds.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RumbleGamepad(SDL_Gamepad *gamepad, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
+/**
+ * Start a rumble effect in the gamepad's triggers.
+ *
+ * Each call to this function cancels any previous trigger rumble effect, and
+ * calling it with 0 intensity stops any rumbling.
+ *
+ * Note that this is rumbling of the _triggers_ and not the gamepad as a
+ * whole. This is currently only supported on Xbox One gamepads. If you want
+ * the (more common) whole-gamepad rumble, use SDL_RumbleGamepad() instead.
+ *
+ * This function requires you to process SDL events or call
+ * SDL_UpdateJoysticks() to update rumble state.
+ *
+ * \param gamepad the gamepad to vibrate.
+ * \param left_rumble the intensity of the left trigger rumble motor, from 0
+ * to 0xFFFF.
+ * \param right_rumble the intensity of the right trigger rumble motor, from 0
+ * to 0xFFFF.
+ * \param duration_ms the duration of the rumble effect, in milliseconds.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RumbleGamepad
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RumbleGamepadTriggers(SDL_Gamepad *gamepad, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms);
+
+/**
+ * Update a gamepad's LED color.
+ *
+ * An example of a joystick LED is the light on the back of a PlayStation 4's
+ * DualShock 4 controller.
+ *
+ * For gamepads with a single color LED, the maximum of the RGB values will be
+ * used as the LED brightness.
+ *
+ * \param gamepad the gamepad to update.
+ * \param red the intensity of the red LED.
+ * \param green the intensity of the green LED.
+ * \param blue the intensity of the blue LED.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadLED(SDL_Gamepad *gamepad, Uint8 red, Uint8 green, Uint8 blue);
+
+/**
+ * Send a gamepad specific effect packet.
+ *
+ * \param gamepad the gamepad to affect.
+ * \param data the data to send to the gamepad.
+ * \param size the size of the data to send to the gamepad.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SendGamepadEffect(SDL_Gamepad *gamepad, const void *data, int size);
+
+/**
+ * Close a gamepad previously opened with SDL_OpenGamepad().
+ *
+ * \param gamepad a gamepad identifier previously returned by
+ * SDL_OpenGamepad().
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenGamepad
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CloseGamepad(SDL_Gamepad *gamepad);
+
+/**
+ * Return the sfSymbolsName for a given button on a gamepad on Apple
+ * platforms.
+ *
+ * \param gamepad the gamepad to query.
+ * \param button a button on the gamepad.
+ * \returns the sfSymbolsName or NULL if the name can't be found.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadAppleSFSymbolsNameForAxis
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button);
+
+/**
+ * Return the sfSymbolsName for a given axis on a gamepad on Apple platforms.
+ *
+ * \param gamepad the gamepad to query.
+ * \param axis an axis on the gamepad.
+ * \returns the sfSymbolsName or NULL if the name can't be found.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGamepadAppleSFSymbolsNameForButton
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_gamepad_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_gpu.h b/vendored/SDL/include/SDL3/SDL_gpu.h
new file mode 100644
index 0000000..b616619
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_gpu.h
@@ -0,0 +1,4213 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: GPU */
+
+/**
+ * # CategoryGPU
+ *
+ * The GPU API offers a cross-platform way for apps to talk to modern graphics
+ * hardware. It offers both 3D graphics and compute support, in the style of
+ * Metal, Vulkan, and Direct3D 12.
+ *
+ * A basic workflow might be something like this:
+ *
+ * The app creates a GPU device with SDL_CreateGPUDevice(), and assigns it to
+ * a window with SDL_ClaimWindowForGPUDevice()--although strictly speaking you
+ * can render offscreen entirely, perhaps for image processing, and not use a
+ * window at all.
+ *
+ * Next, the app prepares static data (things that are created once and used
+ * over and over). For example:
+ *
+ * - Shaders (programs that run on the GPU): use SDL_CreateGPUShader().
+ * - Vertex buffers (arrays of geometry data) and other rendering data: use
+ * SDL_CreateGPUBuffer() and SDL_UploadToGPUBuffer().
+ * - Textures (images): use SDL_CreateGPUTexture() and
+ * SDL_UploadToGPUTexture().
+ * - Samplers (how textures should be read from): use SDL_CreateGPUSampler().
+ * - Render pipelines (precalculated rendering state): use
+ * SDL_CreateGPUGraphicsPipeline()
+ *
+ * To render, the app creates one or more command buffers, with
+ * SDL_AcquireGPUCommandBuffer(). Command buffers collect rendering
+ * instructions that will be submitted to the GPU in batch. Complex scenes can
+ * use multiple command buffers, maybe configured across multiple threads in
+ * parallel, as long as they are submitted in the correct order, but many apps
+ * will just need one command buffer per frame.
+ *
+ * Rendering can happen to a texture (what other APIs call a "render target")
+ * or it can happen to the swapchain texture (which is just a special texture
+ * that represents a window's contents). The app can use
+ * SDL_WaitAndAcquireGPUSwapchainTexture() to render to the window.
+ *
+ * Rendering actually happens in a Render Pass, which is encoded into a
+ * command buffer. One can encode multiple render passes (or alternate between
+ * render and compute passes) in a single command buffer, but many apps might
+ * simply need a single render pass in a single command buffer. Render Passes
+ * can render to up to four color textures and one depth texture
+ * simultaneously. If the set of textures being rendered to needs to change,
+ * the Render Pass must be ended and a new one must be begun.
+ *
+ * The app calls SDL_BeginGPURenderPass(). Then it sets states it needs for
+ * each draw:
+ *
+ * - SDL_BindGPUGraphicsPipeline()
+ * - SDL_SetGPUViewport()
+ * - SDL_BindGPUVertexBuffers()
+ * - SDL_BindGPUVertexSamplers()
+ * - etc
+ *
+ * Then, make the actual draw commands with these states:
+ *
+ * - SDL_DrawGPUPrimitives()
+ * - SDL_DrawGPUPrimitivesIndirect()
+ * - SDL_DrawGPUIndexedPrimitivesIndirect()
+ * - etc
+ *
+ * After all the drawing commands for a pass are complete, the app should call
+ * SDL_EndGPURenderPass(). Once a render pass ends all render-related state is
+ * reset.
+ *
+ * The app can begin new Render Passes and make new draws in the same command
+ * buffer until the entire scene is rendered.
+ *
+ * Once all of the render commands for the scene are complete, the app calls
+ * SDL_SubmitGPUCommandBuffer() to send it to the GPU for processing.
+ *
+ * If the app needs to read back data from texture or buffers, the API has an
+ * efficient way of doing this, provided that the app is willing to tolerate
+ * some latency. When the app uses SDL_DownloadFromGPUTexture() or
+ * SDL_DownloadFromGPUBuffer(), submitting the command buffer with
+ * SDL_SubmitGPUCommandBufferAndAcquireFence() will return a fence handle that
+ * the app can poll or wait on in a thread. Once the fence indicates that the
+ * command buffer is done processing, it is safe to read the downloaded data.
+ * Make sure to call SDL_ReleaseGPUFence() when done with the fence.
+ *
+ * The API also has "compute" support. The app calls SDL_BeginGPUComputePass()
+ * with compute-writeable textures and/or buffers, which can be written to in
+ * a compute shader. Then it sets states it needs for the compute dispatches:
+ *
+ * - SDL_BindGPUComputePipeline()
+ * - SDL_BindGPUComputeStorageBuffers()
+ * - SDL_BindGPUComputeStorageTextures()
+ *
+ * Then, dispatch compute work:
+ *
+ * - SDL_DispatchGPUCompute()
+ *
+ * For advanced users, this opens up powerful GPU-driven workflows.
+ *
+ * Graphics and compute pipelines require the use of shaders, which as
+ * mentioned above are small programs executed on the GPU. Each backend
+ * (Vulkan, Metal, D3D12) requires a different shader format. When the app
+ * creates the GPU device, the app lets the device know which shader formats
+ * the app can provide. It will then select the appropriate backend depending
+ * on the available shader formats and the backends available on the platform.
+ * When creating shaders, the app must provide the correct shader format for
+ * the selected backend. If you would like to learn more about why the API
+ * works this way, there is a detailed
+ * [blog post](https://moonside.games/posts/layers-all-the-way-down/)
+ * explaining this situation.
+ *
+ * It is optimal for apps to pre-compile the shader formats they might use,
+ * but for ease of use SDL provides a separate project,
+ * [SDL_shadercross](https://github.com/libsdl-org/SDL_shadercross)
+ * , for performing runtime shader cross-compilation. It also has a CLI
+ * interface for offline precompilation as well.
+ *
+ * This is an extremely quick overview that leaves out several important
+ * details. Already, though, one can see that GPU programming can be quite
+ * complex! If you just need simple 2D graphics, the
+ * [Render API](https://wiki.libsdl.org/SDL3/CategoryRender)
+ * is much easier to use but still hardware-accelerated. That said, even for
+ * 2D applications the performance benefits and expressiveness of the GPU API
+ * are significant.
+ *
+ * The GPU API targets a feature set with a wide range of hardware support and
+ * ease of portability. It is designed so that the app won't have to branch
+ * itself by querying feature support. If you need cutting-edge features with
+ * limited hardware support, this API is probably not for you.
+ *
+ * Examples demonstrating proper usage of this API can be found
+ * [here](https://github.com/TheSpydog/SDL_gpu_examples)
+ * .
+ *
+ * ## Performance considerations
+ *
+ * Here are some basic tips for maximizing your rendering performance.
+ *
+ * - Beginning a new render pass is relatively expensive. Use as few render
+ * passes as you can.
+ * - Minimize the amount of state changes. For example, binding a pipeline is
+ * relatively cheap, but doing it hundreds of times when you don't need to
+ * will slow the performance significantly.
+ * - Perform your data uploads as early as possible in the frame.
+ * - Don't churn resources. Creating and releasing resources is expensive.
+ * It's better to create what you need up front and cache it.
+ * - Don't use uniform buffers for large amounts of data (more than a matrix
+ * or so). Use a storage buffer instead.
+ * - Use cycling correctly. There is a detailed explanation of cycling further
+ * below.
+ * - Use culling techniques to minimize pixel writes. The less writing the GPU
+ * has to do the better. Culling can be a very advanced topic but even
+ * simple culling techniques can boost performance significantly.
+ *
+ * In general try to remember the golden rule of performance: doing things is
+ * more expensive than not doing things. Don't Touch The Driver!
+ *
+ * ## FAQ
+ *
+ * **Question: When are you adding more advanced features, like ray tracing or
+ * mesh shaders?**
+ *
+ * Answer: We don't have immediate plans to add more bleeding-edge features,
+ * but we certainly might in the future, when these features prove worthwhile,
+ * and reasonable to implement across several platforms and underlying APIs.
+ * So while these things are not in the "never" category, they are definitely
+ * not "near future" items either.
+ *
+ * **Question: Why is my shader not working?**
+ *
+ * Answer: A common oversight when using shaders is not properly laying out
+ * the shader resources/registers correctly. The GPU API is very strict with
+ * how it wants resources to be laid out and it's difficult for the API to
+ * automatically validate shaders to see if they have a compatible layout. See
+ * the documentation for SDL_CreateGPUShader() and
+ * SDL_CreateGPUComputePipeline() for information on the expected layout.
+ *
+ * Another common issue is not setting the correct number of samplers,
+ * textures, and buffers in SDL_GPUShaderCreateInfo. If possible use shader
+ * reflection to extract the required information from the shader
+ * automatically instead of manually filling in the struct's values.
+ *
+ * **Question: My application isn't performing very well. Is this the GPU
+ * API's fault?**
+ *
+ * Answer: No. Long answer: The GPU API is a relatively thin layer over the
+ * underlying graphics API. While it's possible that we have done something
+ * inefficiently, it's very unlikely especially if you are relatively
+ * inexperienced with GPU rendering. Please see the performance tips above and
+ * make sure you are following them. Additionally, tools like RenderDoc can be
+ * very helpful for diagnosing incorrect behavior and performance issues.
+ *
+ * ## System Requirements
+ *
+ * **Vulkan:** Supported on Windows, Linux, Nintendo Switch, and certain
+ * Android devices. Requires Vulkan 1.0 with the following extensions and
+ * device features:
+ *
+ * - `VK_KHR_swapchain`
+ * - `VK_KHR_maintenance1`
+ * - `independentBlend`
+ * - `imageCubeArray`
+ * - `depthClamp`
+ * - `shaderClipDistance`
+ * - `drawIndirectFirstInstance`
+ *
+ * **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
+ * Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level
+ * 11_1.
+ *
+ * **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
+ * requirements vary by operating system:
+ *
+ * - macOS requires an Apple Silicon or
+ * [Intel Mac2 family](https://developer.apple.com/documentation/metal/mtlfeatureset/mtlfeatureset_macos_gpufamily2_v1?language=objc)
+ * GPU
+ * - iOS/tvOS requires an A9 GPU or newer
+ * - iOS Simulator and tvOS Simulator are unsupported
+ *
+ * ## Uniform Data
+ *
+ * Uniforms are for passing data to shaders. The uniform data will be constant
+ * across all executions of the shader.
+ *
+ * There are 4 available uniform slots per shader stage (where the stages are
+ * vertex, fragment, and compute). Uniform data pushed to a slot on a stage
+ * keeps its value throughout the command buffer until you call the relevant
+ * Push function on that slot again.
+ *
+ * For example, you could write your vertex shaders to read a camera matrix
+ * from uniform binding slot 0, push the camera matrix at the start of the
+ * command buffer, and that data will be used for every subsequent draw call.
+ *
+ * It is valid to push uniform data during a render or compute pass.
+ *
+ * Uniforms are best for pushing small amounts of data. If you are pushing
+ * more than a matrix or two per call you should consider using a storage
+ * buffer instead.
+ *
+ * ## A Note On Cycling
+ *
+ * When using a command buffer, operations do not occur immediately - they
+ * occur some time after the command buffer is submitted.
+ *
+ * When a resource is used in a pending or active command buffer, it is
+ * considered to be "bound". When a resource is no longer used in any pending
+ * or active command buffers, it is considered to be "unbound".
+ *
+ * If data resources are bound, it is unspecified when that data will be
+ * unbound unless you acquire a fence when submitting the command buffer and
+ * wait on it. However, this doesn't mean you need to track resource usage
+ * manually.
+ *
+ * All of the functions and structs that involve writing to a resource have a
+ * "cycle" bool. SDL_GPUTransferBuffer, SDL_GPUBuffer, and SDL_GPUTexture all
+ * effectively function as ring buffers on internal resources. When cycle is
+ * true, if the resource is bound, the cycle rotates to the next unbound
+ * internal resource, or if none are available, a new one is created. This
+ * means you don't have to worry about complex state tracking and
+ * synchronization as long as cycling is correctly employed.
+ *
+ * For example: you can call SDL_MapGPUTransferBuffer(), write texture data,
+ * SDL_UnmapGPUTransferBuffer(), and then SDL_UploadToGPUTexture(). The next
+ * time you write texture data to the transfer buffer, if you set the cycle
+ * param to true, you don't have to worry about overwriting any data that is
+ * not yet uploaded.
+ *
+ * Another example: If you are using a texture in a render pass every frame,
+ * this can cause a data dependency between frames. If you set cycle to true
+ * in the SDL_GPUColorTargetInfo struct, you can prevent this data dependency.
+ *
+ * Cycling will never undefine already bound data. When cycling, all data in
+ * the resource is considered to be undefined for subsequent commands until
+ * that data is written again. You must take care not to read undefined data.
+ *
+ * Note that when cycling a texture, the entire texture will be cycled, even
+ * if only part of the texture is used in the call, so you must consider the
+ * entire texture to contain undefined data after cycling.
+ *
+ * You must also take care not to overwrite a section of data that has been
+ * referenced in a command without cycling first. It is OK to overwrite
+ * unreferenced data in a bound resource without cycling, but overwriting a
+ * section of data that has already been referenced will produce unexpected
+ * results.
+ */
+
+#ifndef SDL_gpu_h_
+#define SDL_gpu_h_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Type Declarations */
+
+/**
+ * An opaque handle representing the SDL_GPU context.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GPUDevice SDL_GPUDevice;
+
+/**
+ * An opaque handle representing a buffer.
+ *
+ * Used for vertices, indices, indirect draw commands, and general compute
+ * data.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUBuffer
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_DownloadFromGPUBuffer
+ * \sa SDL_CopyGPUBufferToBuffer
+ * \sa SDL_BindGPUVertexBuffers
+ * \sa SDL_BindGPUIndexBuffer
+ * \sa SDL_BindGPUVertexStorageBuffers
+ * \sa SDL_BindGPUFragmentStorageBuffers
+ * \sa SDL_DrawGPUPrimitivesIndirect
+ * \sa SDL_DrawGPUIndexedPrimitivesIndirect
+ * \sa SDL_BindGPUComputeStorageBuffers
+ * \sa SDL_DispatchGPUComputeIndirect
+ * \sa SDL_ReleaseGPUBuffer
+ */
+typedef struct SDL_GPUBuffer SDL_GPUBuffer;
+
+/**
+ * An opaque handle representing a transfer buffer.
+ *
+ * Used for transferring data to and from the device.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTransferBuffer
+ * \sa SDL_MapGPUTransferBuffer
+ * \sa SDL_UnmapGPUTransferBuffer
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUBuffer
+ * \sa SDL_DownloadFromGPUTexture
+ * \sa SDL_ReleaseGPUTransferBuffer
+ */
+typedef struct SDL_GPUTransferBuffer SDL_GPUTransferBuffer;
+
+/**
+ * An opaque handle representing a texture.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUTexture
+ * \sa SDL_CopyGPUTextureToTexture
+ * \sa SDL_BindGPUVertexSamplers
+ * \sa SDL_BindGPUVertexStorageTextures
+ * \sa SDL_BindGPUFragmentSamplers
+ * \sa SDL_BindGPUFragmentStorageTextures
+ * \sa SDL_BindGPUComputeStorageTextures
+ * \sa SDL_GenerateMipmapsForGPUTexture
+ * \sa SDL_BlitGPUTexture
+ * \sa SDL_ReleaseGPUTexture
+ */
+typedef struct SDL_GPUTexture SDL_GPUTexture;
+
+/**
+ * An opaque handle representing a sampler.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUSampler
+ * \sa SDL_BindGPUVertexSamplers
+ * \sa SDL_BindGPUFragmentSamplers
+ * \sa SDL_ReleaseGPUSampler
+ */
+typedef struct SDL_GPUSampler SDL_GPUSampler;
+
+/**
+ * An opaque handle representing a compiled shader object.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ * \sa SDL_CreateGPUGraphicsPipeline
+ * \sa SDL_ReleaseGPUShader
+ */
+typedef struct SDL_GPUShader SDL_GPUShader;
+
+/**
+ * An opaque handle representing a compute pipeline.
+ *
+ * Used during compute passes.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUComputePipeline
+ * \sa SDL_BindGPUComputePipeline
+ * \sa SDL_ReleaseGPUComputePipeline
+ */
+typedef struct SDL_GPUComputePipeline SDL_GPUComputePipeline;
+
+/**
+ * An opaque handle representing a graphics pipeline.
+ *
+ * Used during render passes.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ * \sa SDL_BindGPUGraphicsPipeline
+ * \sa SDL_ReleaseGPUGraphicsPipeline
+ */
+typedef struct SDL_GPUGraphicsPipeline SDL_GPUGraphicsPipeline;
+
+/**
+ * An opaque handle representing a command buffer.
+ *
+ * Most state is managed via command buffers. When setting state using a
+ * command buffer, that state is local to the command buffer.
+ *
+ * Commands only begin execution on the GPU once SDL_SubmitGPUCommandBuffer is
+ * called. Once the command buffer is submitted, it is no longer valid to use
+ * it.
+ *
+ * Command buffers are executed in submission order. If you submit command
+ * buffer A and then command buffer B all commands in A will begin executing
+ * before any command in B begins executing.
+ *
+ * In multi-threading scenarios, you should only access a command buffer on
+ * the thread you acquired it from.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_AcquireGPUCommandBuffer
+ * \sa SDL_SubmitGPUCommandBuffer
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ */
+typedef struct SDL_GPUCommandBuffer SDL_GPUCommandBuffer;
+
+/**
+ * An opaque handle representing a render pass.
+ *
+ * This handle is transient and should not be held or referenced after
+ * SDL_EndGPURenderPass is called.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPURenderPass
+ * \sa SDL_EndGPURenderPass
+ */
+typedef struct SDL_GPURenderPass SDL_GPURenderPass;
+
+/**
+ * An opaque handle representing a compute pass.
+ *
+ * This handle is transient and should not be held or referenced after
+ * SDL_EndGPUComputePass is called.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPUComputePass
+ * \sa SDL_EndGPUComputePass
+ */
+typedef struct SDL_GPUComputePass SDL_GPUComputePass;
+
+/**
+ * An opaque handle representing a copy pass.
+ *
+ * This handle is transient and should not be held or referenced after
+ * SDL_EndGPUCopyPass is called.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPUCopyPass
+ * \sa SDL_EndGPUCopyPass
+ */
+typedef struct SDL_GPUCopyPass SDL_GPUCopyPass;
+
+/**
+ * An opaque handle representing a fence.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ * \sa SDL_QueryGPUFence
+ * \sa SDL_WaitForGPUFences
+ * \sa SDL_ReleaseGPUFence
+ */
+typedef struct SDL_GPUFence SDL_GPUFence;
+
+/**
+ * Specifies the primitive topology of a graphics pipeline.
+ *
+ * If you are using POINTLIST you must include a point size output in the
+ * vertex shader.
+ *
+ * - For HLSL compiling to SPIRV you must decorate a float output with
+ * [[vk::builtin("PointSize")]].
+ * - For GLSL you must set the gl_PointSize builtin.
+ * - For MSL you must include a float output with the [[point_size]]
+ * decorator.
+ *
+ * Note that sized point topology is totally unsupported on D3D12. Any size
+ * other than 1 will be ignored. In general, you should avoid using point
+ * topology for both compatibility and performance reasons. You WILL regret
+ * using it.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUPrimitiveType
+{
+ SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, /**< A series of separate triangles. */
+ SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP, /**< A series of connected triangles. */
+ SDL_GPU_PRIMITIVETYPE_LINELIST, /**< A series of separate lines. */
+ SDL_GPU_PRIMITIVETYPE_LINESTRIP, /**< A series of connected lines. */
+ SDL_GPU_PRIMITIVETYPE_POINTLIST /**< A series of separate points. */
+} SDL_GPUPrimitiveType;
+
+/**
+ * Specifies how the contents of a texture attached to a render pass are
+ * treated at the beginning of the render pass.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPURenderPass
+ */
+typedef enum SDL_GPULoadOp
+{
+ SDL_GPU_LOADOP_LOAD, /**< The previous contents of the texture will be preserved. */
+ SDL_GPU_LOADOP_CLEAR, /**< The contents of the texture will be cleared to a color. */
+ SDL_GPU_LOADOP_DONT_CARE /**< The previous contents of the texture need not be preserved. The contents will be undefined. */
+} SDL_GPULoadOp;
+
+/**
+ * Specifies how the contents of a texture attached to a render pass are
+ * treated at the end of the render pass.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPURenderPass
+ */
+typedef enum SDL_GPUStoreOp
+{
+ SDL_GPU_STOREOP_STORE, /**< The contents generated during the render pass will be written to memory. */
+ SDL_GPU_STOREOP_DONT_CARE, /**< The contents generated during the render pass are not needed and may be discarded. The contents will be undefined. */
+ SDL_GPU_STOREOP_RESOLVE, /**< The multisample contents generated during the render pass will be resolved to a non-multisample texture. The contents in the multisample texture may then be discarded and will be undefined. */
+ SDL_GPU_STOREOP_RESOLVE_AND_STORE /**< The multisample contents generated during the render pass will be resolved to a non-multisample texture. The contents in the multisample texture will be written to memory. */
+} SDL_GPUStoreOp;
+
+/**
+ * Specifies the size of elements in an index buffer.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUIndexElementSize
+{
+ SDL_GPU_INDEXELEMENTSIZE_16BIT, /**< The index elements are 16-bit. */
+ SDL_GPU_INDEXELEMENTSIZE_32BIT /**< The index elements are 32-bit. */
+} SDL_GPUIndexElementSize;
+
+/**
+ * Specifies the pixel format of a texture.
+ *
+ * Texture format support varies depending on driver, hardware, and usage
+ * flags. In general, you should use SDL_GPUTextureSupportsFormat to query if
+ * a format is supported before using it. However, there are a few guaranteed
+ * formats.
+ *
+ * FIXME: Check universal support for 32-bit component formats FIXME: Check
+ * universal support for SIMULTANEOUS_READ_WRITE
+ *
+ * For SAMPLER usage, the following formats are universally supported:
+ *
+ * - R8G8B8A8_UNORM
+ * - B8G8R8A8_UNORM
+ * - R8_UNORM
+ * - R8_SNORM
+ * - R8G8_UNORM
+ * - R8G8_SNORM
+ * - R8G8B8A8_SNORM
+ * - R16_FLOAT
+ * - R16G16_FLOAT
+ * - R16G16B16A16_FLOAT
+ * - R32_FLOAT
+ * - R32G32_FLOAT
+ * - R32G32B32A32_FLOAT
+ * - R11G11B10_UFLOAT
+ * - R8G8B8A8_UNORM_SRGB
+ * - B8G8R8A8_UNORM_SRGB
+ * - D16_UNORM
+ *
+ * For COLOR_TARGET usage, the following formats are universally supported:
+ *
+ * - R8G8B8A8_UNORM
+ * - B8G8R8A8_UNORM
+ * - R8_UNORM
+ * - R16_FLOAT
+ * - R16G16_FLOAT
+ * - R16G16B16A16_FLOAT
+ * - R32_FLOAT
+ * - R32G32_FLOAT
+ * - R32G32B32A32_FLOAT
+ * - R8_UINT
+ * - R8G8_UINT
+ * - R8G8B8A8_UINT
+ * - R16_UINT
+ * - R16G16_UINT
+ * - R16G16B16A16_UINT
+ * - R8_INT
+ * - R8G8_INT
+ * - R8G8B8A8_INT
+ * - R16_INT
+ * - R16G16_INT
+ * - R16G16B16A16_INT
+ * - R8G8B8A8_UNORM_SRGB
+ * - B8G8R8A8_UNORM_SRGB
+ *
+ * For STORAGE usages, the following formats are universally supported:
+ *
+ * - R8G8B8A8_UNORM
+ * - R8G8B8A8_SNORM
+ * - R16G16B16A16_FLOAT
+ * - R32_FLOAT
+ * - R32G32_FLOAT
+ * - R32G32B32A32_FLOAT
+ * - R8G8B8A8_UINT
+ * - R16G16B16A16_UINT
+ * - R8G8B8A8_INT
+ * - R16G16B16A16_INT
+ *
+ * For DEPTH_STENCIL_TARGET usage, the following formats are universally
+ * supported:
+ *
+ * - D16_UNORM
+ * - Either (but not necessarily both!) D24_UNORM or D32_FLOAT
+ * - Either (but not necessarily both!) D24_UNORM_S8_UINT or D32_FLOAT_S8_UINT
+ *
+ * Unless D16_UNORM is sufficient for your purposes, always check which of
+ * D24/D32 is supported before creating a depth-stencil texture!
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ * \sa SDL_GPUTextureSupportsFormat
+ */
+typedef enum SDL_GPUTextureFormat
+{
+ SDL_GPU_TEXTUREFORMAT_INVALID,
+
+ /* Unsigned Normalized Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_A8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R8G8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R16_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R16G16_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM,
+ SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM,
+ SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM,
+ SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM,
+ SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM,
+ SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM,
+ /* Compressed Unsigned Normalized Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM,
+ SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM,
+ SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM,
+ SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM,
+ SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM,
+ SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM,
+ /* Compressed Signed Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT,
+ /* Compressed Unsigned Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT,
+ /* Signed Normalized Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R8_SNORM,
+ SDL_GPU_TEXTUREFORMAT_R8G8_SNORM,
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM,
+ SDL_GPU_TEXTUREFORMAT_R16_SNORM,
+ SDL_GPU_TEXTUREFORMAT_R16G16_SNORM,
+ SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM,
+ /* Signed Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R16_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_R32_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT,
+ /* Unsigned Float Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT,
+ /* Unsigned Integer Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R8_UINT,
+ SDL_GPU_TEXTUREFORMAT_R8G8_UINT,
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT,
+ SDL_GPU_TEXTUREFORMAT_R16_UINT,
+ SDL_GPU_TEXTUREFORMAT_R16G16_UINT,
+ SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT,
+ SDL_GPU_TEXTUREFORMAT_R32_UINT,
+ SDL_GPU_TEXTUREFORMAT_R32G32_UINT,
+ SDL_GPU_TEXTUREFORMAT_R32G32B32A32_UINT,
+ /* Signed Integer Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R8_INT,
+ SDL_GPU_TEXTUREFORMAT_R8G8_INT,
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT,
+ SDL_GPU_TEXTUREFORMAT_R16_INT,
+ SDL_GPU_TEXTUREFORMAT_R16G16_INT,
+ SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT,
+ SDL_GPU_TEXTUREFORMAT_R32_INT,
+ SDL_GPU_TEXTUREFORMAT_R32G32_INT,
+ SDL_GPU_TEXTUREFORMAT_R32G32B32A32_INT,
+ /* SRGB Unsigned Normalized Color Formats */
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB,
+ /* Compressed SRGB Unsigned Normalized Color Formats */
+ SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB,
+ /* Depth Formats */
+ SDL_GPU_TEXTUREFORMAT_D16_UNORM,
+ SDL_GPU_TEXTUREFORMAT_D24_UNORM,
+ SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT,
+ SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT,
+ /* Compressed ASTC Normalized Float Color Formats*/
+ SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM,
+ /* Compressed SRGB ASTC Normalized Float Color Formats*/
+ SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB,
+ /* Compressed ASTC Signed Float Color Formats*/
+ SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT,
+ SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT
+} SDL_GPUTextureFormat;
+
+/**
+ * Specifies how a texture is intended to be used by the client.
+ *
+ * A texture must have at least one usage flag. Note that some usage flag
+ * combinations are invalid.
+ *
+ * With regards to compute storage usage, READ | WRITE means that you can have
+ * shader A that only writes into the texture and shader B that only reads
+ * from the texture and bind the same texture to either shader respectively.
+ * SIMULTANEOUS means that you can do reads and writes within the same shader
+ * or compute pass. It also implies that atomic ops can be used, since those
+ * are read-modify-write operations. If you use SIMULTANEOUS, you are
+ * responsible for avoiding data races, as there is no data synchronization
+ * within a compute pass. Note that SIMULTANEOUS usage is only supported by a
+ * limited number of texture formats.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ */
+typedef Uint32 SDL_GPUTextureUsageFlags;
+
+#define SDL_GPU_TEXTUREUSAGE_SAMPLER (1u << 0) /**< Texture supports sampling. */
+#define SDL_GPU_TEXTUREUSAGE_COLOR_TARGET (1u << 1) /**< Texture is a color render target. */
+#define SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET (1u << 2) /**< Texture is a depth stencil target. */
+#define SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ (1u << 3) /**< Texture supports storage reads in graphics stages. */
+#define SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ (1u << 4) /**< Texture supports storage reads in the compute stage. */
+#define SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE (1u << 5) /**< Texture supports storage writes in the compute stage. */
+#define SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE (1u << 6) /**< Texture supports reads and writes in the same compute shader. This is NOT equivalent to READ | WRITE. */
+
+/**
+ * Specifies the type of a texture.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ */
+typedef enum SDL_GPUTextureType
+{
+ SDL_GPU_TEXTURETYPE_2D, /**< The texture is a 2-dimensional image. */
+ SDL_GPU_TEXTURETYPE_2D_ARRAY, /**< The texture is a 2-dimensional array image. */
+ SDL_GPU_TEXTURETYPE_3D, /**< The texture is a 3-dimensional image. */
+ SDL_GPU_TEXTURETYPE_CUBE, /**< The texture is a cube image. */
+ SDL_GPU_TEXTURETYPE_CUBE_ARRAY /**< The texture is a cube array image. */
+} SDL_GPUTextureType;
+
+/**
+ * Specifies the sample count of a texture.
+ *
+ * Used in multisampling. Note that this value only applies when the texture
+ * is used as a render target.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ * \sa SDL_GPUTextureSupportsSampleCount
+ */
+typedef enum SDL_GPUSampleCount
+{
+ SDL_GPU_SAMPLECOUNT_1, /**< No multisampling. */
+ SDL_GPU_SAMPLECOUNT_2, /**< MSAA 2x */
+ SDL_GPU_SAMPLECOUNT_4, /**< MSAA 4x */
+ SDL_GPU_SAMPLECOUNT_8 /**< MSAA 8x */
+} SDL_GPUSampleCount;
+
+
+/**
+ * Specifies the face of a cube map.
+ *
+ * Can be passed in as the layer field in texture-related structs.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_GPUCubeMapFace
+{
+ SDL_GPU_CUBEMAPFACE_POSITIVEX,
+ SDL_GPU_CUBEMAPFACE_NEGATIVEX,
+ SDL_GPU_CUBEMAPFACE_POSITIVEY,
+ SDL_GPU_CUBEMAPFACE_NEGATIVEY,
+ SDL_GPU_CUBEMAPFACE_POSITIVEZ,
+ SDL_GPU_CUBEMAPFACE_NEGATIVEZ
+} SDL_GPUCubeMapFace;
+
+/**
+ * Specifies how a buffer is intended to be used by the client.
+ *
+ * A buffer must have at least one usage flag. Note that some usage flag
+ * combinations are invalid.
+ *
+ * Unlike textures, READ | WRITE can be used for simultaneous read-write
+ * usage. The same data synchronization concerns as textures apply.
+ *
+ * If you use a STORAGE flag, the data in the buffer must respect std140
+ * layout conventions. In practical terms this means you must ensure that vec3
+ * and vec4 fields are 16-byte aligned.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUBuffer
+ */
+typedef Uint32 SDL_GPUBufferUsageFlags;
+
+#define SDL_GPU_BUFFERUSAGE_VERTEX (1u << 0) /**< Buffer is a vertex buffer. */
+#define SDL_GPU_BUFFERUSAGE_INDEX (1u << 1) /**< Buffer is an index buffer. */
+#define SDL_GPU_BUFFERUSAGE_INDIRECT (1u << 2) /**< Buffer is an indirect buffer. */
+#define SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ (1u << 3) /**< Buffer supports storage reads in graphics stages. */
+#define SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ (1u << 4) /**< Buffer supports storage reads in the compute stage. */
+#define SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE (1u << 5) /**< Buffer supports storage writes in the compute stage. */
+
+/**
+ * Specifies how a transfer buffer is intended to be used by the client.
+ *
+ * Note that mapping and copying FROM an upload transfer buffer or TO a
+ * download transfer buffer is undefined behavior.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTransferBuffer
+ */
+typedef enum SDL_GPUTransferBufferUsage
+{
+ SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
+ SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD
+} SDL_GPUTransferBufferUsage;
+
+/**
+ * Specifies which stage a shader program corresponds to.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+typedef enum SDL_GPUShaderStage
+{
+ SDL_GPU_SHADERSTAGE_VERTEX,
+ SDL_GPU_SHADERSTAGE_FRAGMENT
+} SDL_GPUShaderStage;
+
+/**
+ * Specifies the format of shader code.
+ *
+ * Each format corresponds to a specific backend that accepts it.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+typedef Uint32 SDL_GPUShaderFormat;
+
+#define SDL_GPU_SHADERFORMAT_INVALID 0
+#define SDL_GPU_SHADERFORMAT_PRIVATE (1u << 0) /**< Shaders for NDA'd platforms. */
+#define SDL_GPU_SHADERFORMAT_SPIRV (1u << 1) /**< SPIR-V shaders for Vulkan. */
+#define SDL_GPU_SHADERFORMAT_DXBC (1u << 2) /**< DXBC SM5_1 shaders for D3D12. */
+#define SDL_GPU_SHADERFORMAT_DXIL (1u << 3) /**< DXIL SM6_0 shaders for D3D12. */
+#define SDL_GPU_SHADERFORMAT_MSL (1u << 4) /**< MSL shaders for Metal. */
+#define SDL_GPU_SHADERFORMAT_METALLIB (1u << 5) /**< Precompiled metallib shaders for Metal. */
+
+/**
+ * Specifies the format of a vertex attribute.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUVertexElementFormat
+{
+ SDL_GPU_VERTEXELEMENTFORMAT_INVALID,
+
+ /* 32-bit Signed Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_INT,
+ SDL_GPU_VERTEXELEMENTFORMAT_INT2,
+ SDL_GPU_VERTEXELEMENTFORMAT_INT3,
+ SDL_GPU_VERTEXELEMENTFORMAT_INT4,
+
+ /* 32-bit Unsigned Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_UINT,
+ SDL_GPU_VERTEXELEMENTFORMAT_UINT2,
+ SDL_GPU_VERTEXELEMENTFORMAT_UINT3,
+ SDL_GPU_VERTEXELEMENTFORMAT_UINT4,
+
+ /* 32-bit Floats */
+ SDL_GPU_VERTEXELEMENTFORMAT_FLOAT,
+ SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
+ SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
+ SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
+
+ /* 8-bit Signed Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_BYTE2,
+ SDL_GPU_VERTEXELEMENTFORMAT_BYTE4,
+
+ /* 8-bit Unsigned Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2,
+ SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4,
+
+ /* 8-bit Signed Normalized */
+ SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM,
+ SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM,
+
+ /* 8-bit Unsigned Normalized */
+ SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM,
+ SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM,
+
+ /* 16-bit Signed Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_SHORT2,
+ SDL_GPU_VERTEXELEMENTFORMAT_SHORT4,
+
+ /* 16-bit Unsigned Integers */
+ SDL_GPU_VERTEXELEMENTFORMAT_USHORT2,
+ SDL_GPU_VERTEXELEMENTFORMAT_USHORT4,
+
+ /* 16-bit Signed Normalized */
+ SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM,
+ SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM,
+
+ /* 16-bit Unsigned Normalized */
+ SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM,
+ SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM,
+
+ /* 16-bit Floats */
+ SDL_GPU_VERTEXELEMENTFORMAT_HALF2,
+ SDL_GPU_VERTEXELEMENTFORMAT_HALF4
+} SDL_GPUVertexElementFormat;
+
+/**
+ * Specifies the rate at which vertex attributes are pulled from buffers.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUVertexInputRate
+{
+ SDL_GPU_VERTEXINPUTRATE_VERTEX, /**< Attribute addressing is a function of the vertex index. */
+ SDL_GPU_VERTEXINPUTRATE_INSTANCE /**< Attribute addressing is a function of the instance index. */
+} SDL_GPUVertexInputRate;
+
+/**
+ * Specifies the fill mode of the graphics pipeline.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUFillMode
+{
+ SDL_GPU_FILLMODE_FILL, /**< Polygons will be rendered via rasterization. */
+ SDL_GPU_FILLMODE_LINE /**< Polygon edges will be drawn as line segments. */
+} SDL_GPUFillMode;
+
+/**
+ * Specifies the facing direction in which triangle faces will be culled.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUCullMode
+{
+ SDL_GPU_CULLMODE_NONE, /**< No triangles are culled. */
+ SDL_GPU_CULLMODE_FRONT, /**< Front-facing triangles are culled. */
+ SDL_GPU_CULLMODE_BACK /**< Back-facing triangles are culled. */
+} SDL_GPUCullMode;
+
+/**
+ * Specifies the vertex winding that will cause a triangle to be determined to
+ * be front-facing.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUFrontFace
+{
+ SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, /**< A triangle with counter-clockwise vertex winding will be considered front-facing. */
+ SDL_GPU_FRONTFACE_CLOCKWISE /**< A triangle with clockwise vertex winding will be considered front-facing. */
+} SDL_GPUFrontFace;
+
+/**
+ * Specifies a comparison operator for depth, stencil and sampler operations.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUCompareOp
+{
+ SDL_GPU_COMPAREOP_INVALID,
+ SDL_GPU_COMPAREOP_NEVER, /**< The comparison always evaluates false. */
+ SDL_GPU_COMPAREOP_LESS, /**< The comparison evaluates reference < test. */
+ SDL_GPU_COMPAREOP_EQUAL, /**< The comparison evaluates reference == test. */
+ SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */
+ SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */
+ SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */
+ SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evalutes reference >= test. */
+ SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */
+} SDL_GPUCompareOp;
+
+/**
+ * Specifies what happens to a stored stencil value if stencil tests fail or
+ * pass.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUStencilOp
+{
+ SDL_GPU_STENCILOP_INVALID,
+ SDL_GPU_STENCILOP_KEEP, /**< Keeps the current value. */
+ SDL_GPU_STENCILOP_ZERO, /**< Sets the value to 0. */
+ SDL_GPU_STENCILOP_REPLACE, /**< Sets the value to reference. */
+ SDL_GPU_STENCILOP_INCREMENT_AND_CLAMP, /**< Increments the current value and clamps to the maximum value. */
+ SDL_GPU_STENCILOP_DECREMENT_AND_CLAMP, /**< Decrements the current value and clamps to 0. */
+ SDL_GPU_STENCILOP_INVERT, /**< Bitwise-inverts the current value. */
+ SDL_GPU_STENCILOP_INCREMENT_AND_WRAP, /**< Increments the current value and wraps back to 0. */
+ SDL_GPU_STENCILOP_DECREMENT_AND_WRAP /**< Decrements the current value and wraps to the maximum value. */
+} SDL_GPUStencilOp;
+
+/**
+ * Specifies the operator to be used when pixels in a render target are
+ * blended with existing pixels in the texture.
+ *
+ * The source color is the value written by the fragment shader. The
+ * destination color is the value currently existing in the texture.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUBlendOp
+{
+ SDL_GPU_BLENDOP_INVALID,
+ SDL_GPU_BLENDOP_ADD, /**< (source * source_factor) + (destination * destination_factor) */
+ SDL_GPU_BLENDOP_SUBTRACT, /**< (source * source_factor) - (destination * destination_factor) */
+ SDL_GPU_BLENDOP_REVERSE_SUBTRACT, /**< (destination * destination_factor) - (source * source_factor) */
+ SDL_GPU_BLENDOP_MIN, /**< min(source, destination) */
+ SDL_GPU_BLENDOP_MAX /**< max(source, destination) */
+} SDL_GPUBlendOp;
+
+/**
+ * Specifies a blending factor to be used when pixels in a render target are
+ * blended with existing pixels in the texture.
+ *
+ * The source color is the value written by the fragment shader. The
+ * destination color is the value currently existing in the texture.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef enum SDL_GPUBlendFactor
+{
+ SDL_GPU_BLENDFACTOR_INVALID,
+ SDL_GPU_BLENDFACTOR_ZERO, /**< 0 */
+ SDL_GPU_BLENDFACTOR_ONE, /**< 1 */
+ SDL_GPU_BLENDFACTOR_SRC_COLOR, /**< source color */
+ SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_COLOR, /**< 1 - source color */
+ SDL_GPU_BLENDFACTOR_DST_COLOR, /**< destination color */
+ SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_COLOR, /**< 1 - destination color */
+ SDL_GPU_BLENDFACTOR_SRC_ALPHA, /**< source alpha */
+ SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, /**< 1 - source alpha */
+ SDL_GPU_BLENDFACTOR_DST_ALPHA, /**< destination alpha */
+ SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_ALPHA, /**< 1 - destination alpha */
+ SDL_GPU_BLENDFACTOR_CONSTANT_COLOR, /**< blend constant */
+ SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR, /**< 1 - blend constant */
+ SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE /**< min(source alpha, 1 - destination alpha) */
+} SDL_GPUBlendFactor;
+
+/**
+ * Specifies which color components are written in a graphics pipeline.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ */
+typedef Uint8 SDL_GPUColorComponentFlags;
+
+#define SDL_GPU_COLORCOMPONENT_R (1u << 0) /**< the red component */
+#define SDL_GPU_COLORCOMPONENT_G (1u << 1) /**< the green component */
+#define SDL_GPU_COLORCOMPONENT_B (1u << 2) /**< the blue component */
+#define SDL_GPU_COLORCOMPONENT_A (1u << 3) /**< the alpha component */
+
+/**
+ * Specifies a filter operation used by a sampler.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUSampler
+ */
+typedef enum SDL_GPUFilter
+{
+ SDL_GPU_FILTER_NEAREST, /**< Point filtering. */
+ SDL_GPU_FILTER_LINEAR /**< Linear filtering. */
+} SDL_GPUFilter;
+
+/**
+ * Specifies a mipmap mode used by a sampler.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUSampler
+ */
+typedef enum SDL_GPUSamplerMipmapMode
+{
+ SDL_GPU_SAMPLERMIPMAPMODE_NEAREST, /**< Point filtering. */
+ SDL_GPU_SAMPLERMIPMAPMODE_LINEAR /**< Linear filtering. */
+} SDL_GPUSamplerMipmapMode;
+
+/**
+ * Specifies behavior of texture sampling when the coordinates exceed the 0-1
+ * range.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUSampler
+ */
+typedef enum SDL_GPUSamplerAddressMode
+{
+ SDL_GPU_SAMPLERADDRESSMODE_REPEAT, /**< Specifies that the coordinates will wrap around. */
+ SDL_GPU_SAMPLERADDRESSMODE_MIRRORED_REPEAT, /**< Specifies that the coordinates will wrap around mirrored. */
+ SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE /**< Specifies that the coordinates will clamp to the 0-1 range. */
+} SDL_GPUSamplerAddressMode;
+
+/**
+ * Specifies the timing that will be used to present swapchain textures to the
+ * OS.
+ *
+ * VSYNC mode will always be supported. IMMEDIATE and MAILBOX modes may not be
+ * supported on certain systems.
+ *
+ * It is recommended to query SDL_WindowSupportsGPUPresentMode after claiming
+ * the window if you wish to change the present mode to IMMEDIATE or MAILBOX.
+ *
+ * - VSYNC: Waits for vblank before presenting. No tearing is possible. If
+ * there is a pending image to present, the new image is enqueued for
+ * presentation. Disallows tearing at the cost of visual latency.
+ * - IMMEDIATE: Immediately presents. Lowest latency option, but tearing may
+ * occur.
+ * - MAILBOX: Waits for vblank before presenting. No tearing is possible. If
+ * there is a pending image to present, the pending image is replaced by the
+ * new image. Similar to VSYNC, but with reduced visual latency.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGPUSwapchainParameters
+ * \sa SDL_WindowSupportsGPUPresentMode
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ */
+typedef enum SDL_GPUPresentMode
+{
+ SDL_GPU_PRESENTMODE_VSYNC,
+ SDL_GPU_PRESENTMODE_IMMEDIATE,
+ SDL_GPU_PRESENTMODE_MAILBOX
+} SDL_GPUPresentMode;
+
+/**
+ * Specifies the texture format and colorspace of the swapchain textures.
+ *
+ * SDR will always be supported. Other compositions may not be supported on
+ * certain systems.
+ *
+ * It is recommended to query SDL_WindowSupportsGPUSwapchainComposition after
+ * claiming the window if you wish to change the swapchain composition from
+ * SDR.
+ *
+ * - SDR: B8G8R8A8 or R8G8B8A8 swapchain. Pixel values are in sRGB encoding.
+ * - SDR_LINEAR: B8G8R8A8_SRGB or R8G8B8A8_SRGB swapchain. Pixel values are
+ * stored in memory in sRGB encoding but accessed in shaders in "linear
+ * sRGB" encoding which is sRGB but with a linear transfer function.
+ * - HDR_EXTENDED_LINEAR: R16G16B16A16_FLOAT swapchain. Pixel values are in
+ * extended linear sRGB encoding and permits values outside of the [0, 1]
+ * range.
+ * - HDR10_ST2084: A2R10G10B10 or A2B10G10R10 swapchain. Pixel values are in
+ * BT.2020 ST2084 (PQ) encoding.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGPUSwapchainParameters
+ * \sa SDL_WindowSupportsGPUSwapchainComposition
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ */
+typedef enum SDL_GPUSwapchainComposition
+{
+ SDL_GPU_SWAPCHAINCOMPOSITION_SDR,
+ SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR,
+ SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR,
+ SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2084
+} SDL_GPUSwapchainComposition;
+
+/* Structures */
+
+/**
+ * A structure specifying a viewport.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetGPUViewport
+ */
+typedef struct SDL_GPUViewport
+{
+ float x; /**< The left offset of the viewport. */
+ float y; /**< The top offset of the viewport. */
+ float w; /**< The width of the viewport. */
+ float h; /**< The height of the viewport. */
+ float min_depth; /**< The minimum depth of the viewport. */
+ float max_depth; /**< The maximum depth of the viewport. */
+} SDL_GPUViewport;
+
+/**
+ * A structure specifying parameters related to transferring data to or from a
+ * texture.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUTexture
+ */
+typedef struct SDL_GPUTextureTransferInfo
+{
+ SDL_GPUTransferBuffer *transfer_buffer; /**< The transfer buffer used in the transfer operation. */
+ Uint32 offset; /**< The starting byte of the image data in the transfer buffer. */
+ Uint32 pixels_per_row; /**< The number of pixels from one row to the next. */
+ Uint32 rows_per_layer; /**< The number of rows from one layer/depth-slice to the next. */
+} SDL_GPUTextureTransferInfo;
+
+/**
+ * A structure specifying a location in a transfer buffer.
+ *
+ * Used when transferring buffer data to or from a transfer buffer.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_DownloadFromGPUBuffer
+ */
+typedef struct SDL_GPUTransferBufferLocation
+{
+ SDL_GPUTransferBuffer *transfer_buffer; /**< The transfer buffer used in the transfer operation. */
+ Uint32 offset; /**< The starting byte of the buffer data in the transfer buffer. */
+} SDL_GPUTransferBufferLocation;
+
+/**
+ * A structure specifying a location in a texture.
+ *
+ * Used when copying data from one texture to another.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CopyGPUTextureToTexture
+ */
+typedef struct SDL_GPUTextureLocation
+{
+ SDL_GPUTexture *texture; /**< The texture used in the copy operation. */
+ Uint32 mip_level; /**< The mip level index of the location. */
+ Uint32 layer; /**< The layer index of the location. */
+ Uint32 x; /**< The left offset of the location. */
+ Uint32 y; /**< The top offset of the location. */
+ Uint32 z; /**< The front offset of the location. */
+} SDL_GPUTextureLocation;
+
+/**
+ * A structure specifying a region of a texture.
+ *
+ * Used when transferring data to or from a texture.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUTexture
+ * \sa SDL_CreateGPUTexture
+ */
+typedef struct SDL_GPUTextureRegion
+{
+ SDL_GPUTexture *texture; /**< The texture used in the copy operation. */
+ Uint32 mip_level; /**< The mip level index to transfer. */
+ Uint32 layer; /**< The layer index to transfer. */
+ Uint32 x; /**< The left offset of the region. */
+ Uint32 y; /**< The top offset of the region. */
+ Uint32 z; /**< The front offset of the region. */
+ Uint32 w; /**< The width of the region. */
+ Uint32 h; /**< The height of the region. */
+ Uint32 d; /**< The depth of the region. */
+} SDL_GPUTextureRegion;
+
+/**
+ * A structure specifying a region of a texture used in the blit operation.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BlitGPUTexture
+ */
+typedef struct SDL_GPUBlitRegion
+{
+ SDL_GPUTexture *texture; /**< The texture. */
+ Uint32 mip_level; /**< The mip level index of the region. */
+ Uint32 layer_or_depth_plane; /**< The layer index or depth plane of the region. This value is treated as a layer index on 2D array and cube textures, and as a depth plane on 3D textures. */
+ Uint32 x; /**< The left offset of the region. */
+ Uint32 y; /**< The top offset of the region. */
+ Uint32 w; /**< The width of the region. */
+ Uint32 h; /**< The height of the region. */
+} SDL_GPUBlitRegion;
+
+/**
+ * A structure specifying a location in a buffer.
+ *
+ * Used when copying data between buffers.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CopyGPUBufferToBuffer
+ */
+typedef struct SDL_GPUBufferLocation
+{
+ SDL_GPUBuffer *buffer; /**< The buffer. */
+ Uint32 offset; /**< The starting byte within the buffer. */
+} SDL_GPUBufferLocation;
+
+/**
+ * A structure specifying a region of a buffer.
+ *
+ * Used when transferring data to or from buffers.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_DownloadFromGPUBuffer
+ */
+typedef struct SDL_GPUBufferRegion
+{
+ SDL_GPUBuffer *buffer; /**< The buffer. */
+ Uint32 offset; /**< The starting byte within the buffer. */
+ Uint32 size; /**< The size in bytes of the region. */
+} SDL_GPUBufferRegion;
+
+/**
+ * A structure specifying the parameters of an indirect draw command.
+ *
+ * Note that the `first_vertex` and `first_instance` parameters are NOT
+ * compatible with built-in vertex/instance ID variables in shaders (for
+ * example, SV_VertexID); GPU APIs and shader languages do not define these
+ * built-in variables consistently, so if your shader depends on them, the
+ * only way to keep behavior consistent and portable is to always pass 0 for
+ * the correlating parameter in the draw calls.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_DrawGPUPrimitivesIndirect
+ */
+typedef struct SDL_GPUIndirectDrawCommand
+{
+ Uint32 num_vertices; /**< The number of vertices to draw. */
+ Uint32 num_instances; /**< The number of instances to draw. */
+ Uint32 first_vertex; /**< The index of the first vertex to draw. */
+ Uint32 first_instance; /**< The ID of the first instance to draw. */
+} SDL_GPUIndirectDrawCommand;
+
+/**
+ * A structure specifying the parameters of an indexed indirect draw command.
+ *
+ * Note that the `first_vertex` and `first_instance` parameters are NOT
+ * compatible with built-in vertex/instance ID variables in shaders (for
+ * example, SV_VertexID); GPU APIs and shader languages do not define these
+ * built-in variables consistently, so if your shader depends on them, the
+ * only way to keep behavior consistent and portable is to always pass 0 for
+ * the correlating parameter in the draw calls.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_DrawGPUIndexedPrimitivesIndirect
+ */
+typedef struct SDL_GPUIndexedIndirectDrawCommand
+{
+ Uint32 num_indices; /**< The number of indices to draw per instance. */
+ Uint32 num_instances; /**< The number of instances to draw. */
+ Uint32 first_index; /**< The base index within the index buffer. */
+ Sint32 vertex_offset; /**< The value added to the vertex index before indexing into the vertex buffer. */
+ Uint32 first_instance; /**< The ID of the first instance to draw. */
+} SDL_GPUIndexedIndirectDrawCommand;
+
+/**
+ * A structure specifying the parameters of an indexed dispatch command.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_DispatchGPUComputeIndirect
+ */
+typedef struct SDL_GPUIndirectDispatchCommand
+{
+ Uint32 groupcount_x; /**< The number of local workgroups to dispatch in the X dimension. */
+ Uint32 groupcount_y; /**< The number of local workgroups to dispatch in the Y dimension. */
+ Uint32 groupcount_z; /**< The number of local workgroups to dispatch in the Z dimension. */
+} SDL_GPUIndirectDispatchCommand;
+
+/* State structures */
+
+/**
+ * A structure specifying the parameters of a sampler.
+ *
+ * Note that mip_lod_bias is a no-op for the Metal driver. For Metal, LOD bias
+ * must be applied via shader instead.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUSampler
+ * \sa SDL_GPUFilter
+ * \sa SDL_GPUSamplerMipmapMode
+ * \sa SDL_GPUSamplerAddressMode
+ * \sa SDL_GPUCompareOp
+ */
+typedef struct SDL_GPUSamplerCreateInfo
+{
+ SDL_GPUFilter min_filter; /**< The minification filter to apply to lookups. */
+ SDL_GPUFilter mag_filter; /**< The magnification filter to apply to lookups. */
+ SDL_GPUSamplerMipmapMode mipmap_mode; /**< The mipmap filter to apply to lookups. */
+ SDL_GPUSamplerAddressMode address_mode_u; /**< The addressing mode for U coordinates outside [0, 1). */
+ SDL_GPUSamplerAddressMode address_mode_v; /**< The addressing mode for V coordinates outside [0, 1). */
+ SDL_GPUSamplerAddressMode address_mode_w; /**< The addressing mode for W coordinates outside [0, 1). */
+ float mip_lod_bias; /**< The bias to be added to mipmap LOD calculation. */
+ float max_anisotropy; /**< The anisotropy value clamp used by the sampler. If enable_anisotropy is false, this is ignored. */
+ SDL_GPUCompareOp compare_op; /**< The comparison operator to apply to fetched data before filtering. */
+ float min_lod; /**< Clamps the minimum of the computed LOD value. */
+ float max_lod; /**< Clamps the maximum of the computed LOD value. */
+ bool enable_anisotropy; /**< true to enable anisotropic filtering. */
+ bool enable_compare; /**< true to enable comparison against a reference value during lookups. */
+ Uint8 padding1;
+ Uint8 padding2;
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUSamplerCreateInfo;
+
+/**
+ * A structure specifying the parameters of vertex buffers used in a graphics
+ * pipeline.
+ *
+ * When you call SDL_BindGPUVertexBuffers, you specify the binding slots of
+ * the vertex buffers. For example if you called SDL_BindGPUVertexBuffers with
+ * a first_slot of 2 and num_bindings of 3, the binding slots 2, 3, 4 would be
+ * used by the vertex buffers you pass in.
+ *
+ * Vertex attributes are linked to buffers via the buffer_slot field of
+ * SDL_GPUVertexAttribute. For example, if an attribute has a buffer_slot of
+ * 0, then that attribute belongs to the vertex buffer bound at slot 0.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUVertexAttribute
+ * \sa SDL_GPUVertexInputRate
+ */
+typedef struct SDL_GPUVertexBufferDescription
+{
+ Uint32 slot; /**< The binding slot of the vertex buffer. */
+ Uint32 pitch; /**< The byte pitch between consecutive elements of the vertex buffer. */
+ SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */
+ Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */
+} SDL_GPUVertexBufferDescription;
+
+/**
+ * A structure specifying a vertex attribute.
+ *
+ * All vertex attribute locations provided to an SDL_GPUVertexInputState must
+ * be unique.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUVertexBufferDescription
+ * \sa SDL_GPUVertexInputState
+ * \sa SDL_GPUVertexElementFormat
+ */
+typedef struct SDL_GPUVertexAttribute
+{
+ Uint32 location; /**< The shader input location index. */
+ Uint32 buffer_slot; /**< The binding slot of the associated vertex buffer. */
+ SDL_GPUVertexElementFormat format; /**< The size and type of the attribute data. */
+ Uint32 offset; /**< The byte offset of this attribute relative to the start of the vertex element. */
+} SDL_GPUVertexAttribute;
+
+/**
+ * A structure specifying the parameters of a graphics pipeline vertex input
+ * state.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineCreateInfo
+ * \sa SDL_GPUVertexBufferDescription
+ * \sa SDL_GPUVertexAttribute
+ */
+typedef struct SDL_GPUVertexInputState
+{
+ const SDL_GPUVertexBufferDescription *vertex_buffer_descriptions; /**< A pointer to an array of vertex buffer descriptions. */
+ Uint32 num_vertex_buffers; /**< The number of vertex buffer descriptions in the above array. */
+ const SDL_GPUVertexAttribute *vertex_attributes; /**< A pointer to an array of vertex attribute descriptions. */
+ Uint32 num_vertex_attributes; /**< The number of vertex attribute descriptions in the above array. */
+} SDL_GPUVertexInputState;
+
+/**
+ * A structure specifying the stencil operation state of a graphics pipeline.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUDepthStencilState
+ */
+typedef struct SDL_GPUStencilOpState
+{
+ SDL_GPUStencilOp fail_op; /**< The action performed on samples that fail the stencil test. */
+ SDL_GPUStencilOp pass_op; /**< The action performed on samples that pass the depth and stencil tests. */
+ SDL_GPUStencilOp depth_fail_op; /**< The action performed on samples that pass the stencil test and fail the depth test. */
+ SDL_GPUCompareOp compare_op; /**< The comparison operator used in the stencil test. */
+} SDL_GPUStencilOpState;
+
+/**
+ * A structure specifying the blend state of a color target.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUColorTargetDescription
+ */
+typedef struct SDL_GPUColorTargetBlendState
+{
+ SDL_GPUBlendFactor src_color_blendfactor; /**< The value to be multiplied by the source RGB value. */
+ SDL_GPUBlendFactor dst_color_blendfactor; /**< The value to be multiplied by the destination RGB value. */
+ SDL_GPUBlendOp color_blend_op; /**< The blend operation for the RGB components. */
+ SDL_GPUBlendFactor src_alpha_blendfactor; /**< The value to be multiplied by the source alpha. */
+ SDL_GPUBlendFactor dst_alpha_blendfactor; /**< The value to be multiplied by the destination alpha. */
+ SDL_GPUBlendOp alpha_blend_op; /**< The blend operation for the alpha component. */
+ SDL_GPUColorComponentFlags color_write_mask; /**< A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false. */
+ bool enable_blend; /**< Whether blending is enabled for the color target. */
+ bool enable_color_write_mask; /**< Whether the color write mask is enabled. */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_GPUColorTargetBlendState;
+
+
+/**
+ * A structure specifying code and metadata for creating a shader object.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+typedef struct SDL_GPUShaderCreateInfo
+{
+ size_t code_size; /**< The size in bytes of the code pointed to. */
+ const Uint8 *code; /**< A pointer to shader code. */
+ const char *entrypoint; /**< A pointer to a null-terminated UTF-8 string specifying the entry point function name for the shader. */
+ SDL_GPUShaderFormat format; /**< The format of the shader code. */
+ SDL_GPUShaderStage stage; /**< The stage the shader program corresponds to. */
+ Uint32 num_samplers; /**< The number of samplers defined in the shader. */
+ Uint32 num_storage_textures; /**< The number of storage textures defined in the shader. */
+ Uint32 num_storage_buffers; /**< The number of storage buffers defined in the shader. */
+ Uint32 num_uniform_buffers; /**< The number of uniform buffers defined in the shader. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUShaderCreateInfo;
+
+/**
+ * A structure specifying the parameters of a texture.
+ *
+ * Usage flags can be bitwise OR'd together for combinations of usages. Note
+ * that certain usage combinations are invalid, for example SAMPLER and
+ * GRAPHICS_STORAGE.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ * \sa SDL_GPUTextureType
+ * \sa SDL_GPUTextureFormat
+ * \sa SDL_GPUTextureUsageFlags
+ * \sa SDL_GPUSampleCount
+ */
+typedef struct SDL_GPUTextureCreateInfo
+{
+ SDL_GPUTextureType type; /**< The base dimensionality of the texture. */
+ SDL_GPUTextureFormat format; /**< The pixel format of the texture. */
+ SDL_GPUTextureUsageFlags usage; /**< How the texture is intended to be used by the client. */
+ Uint32 width; /**< The width of the texture. */
+ Uint32 height; /**< The height of the texture. */
+ Uint32 layer_count_or_depth; /**< The layer count or depth of the texture. This value is treated as a layer count on 2D array textures, and as a depth value on 3D textures. */
+ Uint32 num_levels; /**< The number of mip levels in the texture. */
+ SDL_GPUSampleCount sample_count; /**< The number of samples per texel. Only applies if the texture is used as a render target. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUTextureCreateInfo;
+
+/**
+ * A structure specifying the parameters of a buffer.
+ *
+ * Usage flags can be bitwise OR'd together for combinations of usages. Note
+ * that certain combinations are invalid, for example VERTEX and INDEX.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUBuffer
+ * \sa SDL_GPUBufferUsageFlags
+ */
+typedef struct SDL_GPUBufferCreateInfo
+{
+ SDL_GPUBufferUsageFlags usage; /**< How the buffer is intended to be used by the client. */
+ Uint32 size; /**< The size in bytes of the buffer. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUBufferCreateInfo;
+
+/**
+ * A structure specifying the parameters of a transfer buffer.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTransferBuffer
+ */
+typedef struct SDL_GPUTransferBufferCreateInfo
+{
+ SDL_GPUTransferBufferUsage usage; /**< How the transfer buffer is intended to be used by the client. */
+ Uint32 size; /**< The size in bytes of the transfer buffer. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUTransferBufferCreateInfo;
+
+/* Pipeline state structures */
+
+/**
+ * A structure specifying the parameters of the graphics pipeline rasterizer
+ * state.
+ *
+ * Note that SDL_GPU_FILLMODE_LINE is not supported on many Android devices.
+ * For those devices, the fill mode will automatically fall back to FILL.
+ *
+ * Also note that the D3D12 driver will enable depth clamping even if
+ * enable_depth_clip is true. If you need this clamp+clip behavior, consider
+ * enabling depth clip and then manually clamping depth in your fragment
+ * shaders on Metal and Vulkan.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineCreateInfo
+ */
+typedef struct SDL_GPURasterizerState
+{
+ SDL_GPUFillMode fill_mode; /**< Whether polygons will be filled in or drawn as lines. */
+ SDL_GPUCullMode cull_mode; /**< The facing direction in which triangles will be culled. */
+ SDL_GPUFrontFace front_face; /**< The vertex winding that will cause a triangle to be determined as front-facing. */
+ float depth_bias_constant_factor; /**< A scalar factor controlling the depth value added to each fragment. */
+ float depth_bias_clamp; /**< The maximum depth bias of a fragment. */
+ float depth_bias_slope_factor; /**< A scalar factor applied to a fragment's slope in depth calculations. */
+ bool enable_depth_bias; /**< true to bias fragment depth values. */
+ bool enable_depth_clip; /**< true to enable depth clip, false to enable depth clamp. */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_GPURasterizerState;
+
+/**
+ * A structure specifying the parameters of the graphics pipeline multisample
+ * state.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineCreateInfo
+ */
+typedef struct SDL_GPUMultisampleState
+{
+ SDL_GPUSampleCount sample_count; /**< The number of samples to be used in rasterization. */
+ Uint32 sample_mask; /**< Reserved for future use. Must be set to 0. */
+ bool enable_mask; /**< Reserved for future use. Must be set to false. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUMultisampleState;
+
+/**
+ * A structure specifying the parameters of the graphics pipeline depth
+ * stencil state.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineCreateInfo
+ */
+typedef struct SDL_GPUDepthStencilState
+{
+ SDL_GPUCompareOp compare_op; /**< The comparison operator used for depth testing. */
+ SDL_GPUStencilOpState back_stencil_state; /**< The stencil op state for back-facing triangles. */
+ SDL_GPUStencilOpState front_stencil_state; /**< The stencil op state for front-facing triangles. */
+ Uint8 compare_mask; /**< Selects the bits of the stencil values participating in the stencil test. */
+ Uint8 write_mask; /**< Selects the bits of the stencil values updated by the stencil test. */
+ bool enable_depth_test; /**< true enables the depth test. */
+ bool enable_depth_write; /**< true enables depth writes. Depth writes are always disabled when enable_depth_test is false. */
+ bool enable_stencil_test; /**< true enables the stencil test. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUDepthStencilState;
+
+/**
+ * A structure specifying the parameters of color targets used in a graphics
+ * pipeline.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineTargetInfo
+ */
+typedef struct SDL_GPUColorTargetDescription
+{
+ SDL_GPUTextureFormat format; /**< The pixel format of the texture to be used as a color target. */
+ SDL_GPUColorTargetBlendState blend_state; /**< The blend state to be used for the color target. */
+} SDL_GPUColorTargetDescription;
+
+/**
+ * A structure specifying the descriptions of render targets used in a
+ * graphics pipeline.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPUGraphicsPipelineCreateInfo
+ * \sa SDL_GPUColorTargetDescription
+ * \sa SDL_GPUTextureFormat
+ */
+typedef struct SDL_GPUGraphicsPipelineTargetInfo
+{
+ const SDL_GPUColorTargetDescription *color_target_descriptions; /**< A pointer to an array of color target descriptions. */
+ Uint32 num_color_targets; /**< The number of color target descriptions in the above array. */
+ SDL_GPUTextureFormat depth_stencil_format; /**< The pixel format of the depth-stencil target. Ignored if has_depth_stencil_target is false. */
+ bool has_depth_stencil_target; /**< true specifies that the pipeline uses a depth-stencil target. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUGraphicsPipelineTargetInfo;
+
+/**
+ * A structure specifying the parameters of a graphics pipeline state.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ * \sa SDL_GPUShader
+ * \sa SDL_GPUVertexInputState
+ * \sa SDL_GPUPrimitiveType
+ * \sa SDL_GPURasterizerState
+ * \sa SDL_GPUMultisampleState
+ * \sa SDL_GPUDepthStencilState
+ * \sa SDL_GPUGraphicsPipelineTargetInfo
+ */
+typedef struct SDL_GPUGraphicsPipelineCreateInfo
+{
+ SDL_GPUShader *vertex_shader; /**< The vertex shader used by the graphics pipeline. */
+ SDL_GPUShader *fragment_shader; /**< The fragment shader used by the graphics pipeline. */
+ SDL_GPUVertexInputState vertex_input_state; /**< The vertex layout of the graphics pipeline. */
+ SDL_GPUPrimitiveType primitive_type; /**< The primitive topology of the graphics pipeline. */
+ SDL_GPURasterizerState rasterizer_state; /**< The rasterizer state of the graphics pipeline. */
+ SDL_GPUMultisampleState multisample_state; /**< The multisample state of the graphics pipeline. */
+ SDL_GPUDepthStencilState depth_stencil_state; /**< The depth-stencil state of the graphics pipeline. */
+ SDL_GPUGraphicsPipelineTargetInfo target_info; /**< Formats and blend modes for the render targets of the graphics pipeline. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUGraphicsPipelineCreateInfo;
+
+/**
+ * A structure specifying the parameters of a compute pipeline state.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUComputePipeline
+ * \sa SDL_GPUShaderFormat
+ */
+typedef struct SDL_GPUComputePipelineCreateInfo
+{
+ size_t code_size; /**< The size in bytes of the compute shader code pointed to. */
+ const Uint8 *code; /**< A pointer to compute shader code. */
+ const char *entrypoint; /**< A pointer to a null-terminated UTF-8 string specifying the entry point function name for the shader. */
+ SDL_GPUShaderFormat format; /**< The format of the compute shader code. */
+ Uint32 num_samplers; /**< The number of samplers defined in the shader. */
+ Uint32 num_readonly_storage_textures; /**< The number of readonly storage textures defined in the shader. */
+ Uint32 num_readonly_storage_buffers; /**< The number of readonly storage buffers defined in the shader. */
+ Uint32 num_readwrite_storage_textures; /**< The number of read-write storage textures defined in the shader. */
+ Uint32 num_readwrite_storage_buffers; /**< The number of read-write storage buffers defined in the shader. */
+ Uint32 num_uniform_buffers; /**< The number of uniform buffers defined in the shader. */
+ Uint32 threadcount_x; /**< The number of threads in the X dimension. This should match the value in the shader. */
+ Uint32 threadcount_y; /**< The number of threads in the Y dimension. This should match the value in the shader. */
+ Uint32 threadcount_z; /**< The number of threads in the Z dimension. This should match the value in the shader. */
+
+ SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
+} SDL_GPUComputePipelineCreateInfo;
+
+/**
+ * A structure specifying the parameters of a color target used by a render
+ * pass.
+ *
+ * The load_op field determines what is done with the texture at the beginning
+ * of the render pass.
+ *
+ * - LOAD: Loads the data currently in the texture. Not recommended for
+ * multisample textures as it requires significant memory bandwidth.
+ * - CLEAR: Clears the texture to a single color.
+ * - DONT_CARE: The driver will do whatever it wants with the texture memory.
+ * This is a good option if you know that every single pixel will be touched
+ * in the render pass.
+ *
+ * The store_op field determines what is done with the color results of the
+ * render pass.
+ *
+ * - STORE: Stores the results of the render pass in the texture. Not
+ * recommended for multisample textures as it requires significant memory
+ * bandwidth.
+ * - DONT_CARE: The driver will do whatever it wants with the texture memory.
+ * This is often a good option for depth/stencil textures.
+ * - RESOLVE: Resolves a multisample texture into resolve_texture, which must
+ * have a sample count of 1. Then the driver may discard the multisample
+ * texture memory. This is the most performant method of resolving a
+ * multisample target.
+ * - RESOLVE_AND_STORE: Resolves a multisample texture into the
+ * resolve_texture, which must have a sample count of 1. Then the driver
+ * stores the multisample texture's contents. Not recommended as it requires
+ * significant memory bandwidth.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPURenderPass
+ */
+typedef struct SDL_GPUColorTargetInfo
+{
+ SDL_GPUTexture *texture; /**< The texture that will be used as a color target by a render pass. */
+ Uint32 mip_level; /**< The mip level to use as a color target. */
+ Uint32 layer_or_depth_plane; /**< The layer index or depth plane to use as a color target. This value is treated as a layer index on 2D array and cube textures, and as a depth plane on 3D textures. */
+ SDL_FColor clear_color; /**< The color to clear the color target to at the start of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */
+ SDL_GPULoadOp load_op; /**< What is done with the contents of the color target at the beginning of the render pass. */
+ SDL_GPUStoreOp store_op; /**< What is done with the results of the render pass. */
+ SDL_GPUTexture *resolve_texture; /**< The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used. */
+ Uint32 resolve_mip_level; /**< The mip level of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used. */
+ Uint32 resolve_layer; /**< The layer index of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used. */
+ bool cycle; /**< true cycles the texture if the texture is bound and load_op is not LOAD */
+ bool cycle_resolve_texture; /**< true cycles the resolve texture if the resolve texture is bound. Ignored if a RESOLVE* store_op is not used. */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_GPUColorTargetInfo;
+
+/**
+ * A structure specifying the parameters of a depth-stencil target used by a
+ * render pass.
+ *
+ * The load_op field determines what is done with the depth contents of the
+ * texture at the beginning of the render pass.
+ *
+ * - LOAD: Loads the depth values currently in the texture.
+ * - CLEAR: Clears the texture to a single depth.
+ * - DONT_CARE: The driver will do whatever it wants with the memory. This is
+ * a good option if you know that every single pixel will be touched in the
+ * render pass.
+ *
+ * The store_op field determines what is done with the depth results of the
+ * render pass.
+ *
+ * - STORE: Stores the depth results in the texture.
+ * - DONT_CARE: The driver will do whatever it wants with the depth results.
+ * This is often a good option for depth/stencil textures that don't need to
+ * be reused again.
+ *
+ * The stencil_load_op field determines what is done with the stencil contents
+ * of the texture at the beginning of the render pass.
+ *
+ * - LOAD: Loads the stencil values currently in the texture.
+ * - CLEAR: Clears the stencil values to a single value.
+ * - DONT_CARE: The driver will do whatever it wants with the memory. This is
+ * a good option if you know that every single pixel will be touched in the
+ * render pass.
+ *
+ * The stencil_store_op field determines what is done with the stencil results
+ * of the render pass.
+ *
+ * - STORE: Stores the stencil results in the texture.
+ * - DONT_CARE: The driver will do whatever it wants with the stencil results.
+ * This is often a good option for depth/stencil textures that don't need to
+ * be reused again.
+ *
+ * Note that depth/stencil targets do not support multisample resolves.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPURenderPass
+ */
+typedef struct SDL_GPUDepthStencilTargetInfo
+{
+ SDL_GPUTexture *texture; /**< The texture that will be used as the depth stencil target by the render pass. */
+ float clear_depth; /**< The value to clear the depth component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */
+ SDL_GPULoadOp load_op; /**< What is done with the depth contents at the beginning of the render pass. */
+ SDL_GPUStoreOp store_op; /**< What is done with the depth results of the render pass. */
+ SDL_GPULoadOp stencil_load_op; /**< What is done with the stencil contents at the beginning of the render pass. */
+ SDL_GPUStoreOp stencil_store_op; /**< What is done with the stencil results of the render pass. */
+ bool cycle; /**< true cycles the texture if the texture is bound and any load ops are not LOAD */
+ Uint8 clear_stencil; /**< The value to clear the stencil component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_GPUDepthStencilTargetInfo;
+
+/**
+ * A structure containing parameters for a blit command.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BlitGPUTexture
+ */
+typedef struct SDL_GPUBlitInfo {
+ SDL_GPUBlitRegion source; /**< The source region for the blit. */
+ SDL_GPUBlitRegion destination; /**< The destination region for the blit. */
+ SDL_GPULoadOp load_op; /**< What is done with the contents of the destination before the blit. */
+ SDL_FColor clear_color; /**< The color to clear the destination region to before the blit. Ignored if load_op is not SDL_GPU_LOADOP_CLEAR. */
+ SDL_FlipMode flip_mode; /**< The flip mode for the source region. */
+ SDL_GPUFilter filter; /**< The filter mode used when blitting. */
+ bool cycle; /**< true cycles the destination texture if it is already bound. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUBlitInfo;
+
+/* Binding structs */
+
+/**
+ * A structure specifying parameters in a buffer binding call.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindGPUVertexBuffers
+ * \sa SDL_BindGPUIndexBuffer
+ */
+typedef struct SDL_GPUBufferBinding
+{
+ SDL_GPUBuffer *buffer; /**< The buffer to bind. Must have been created with SDL_GPU_BUFFERUSAGE_VERTEX for SDL_BindGPUVertexBuffers, or SDL_GPU_BUFFERUSAGE_INDEX for SDL_BindGPUIndexBuffer. */
+ Uint32 offset; /**< The starting byte of the data to bind in the buffer. */
+} SDL_GPUBufferBinding;
+
+/**
+ * A structure specifying parameters in a sampler binding call.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindGPUVertexSamplers
+ * \sa SDL_BindGPUFragmentSamplers
+ */
+typedef struct SDL_GPUTextureSamplerBinding
+{
+ SDL_GPUTexture *texture; /**< The texture to bind. Must have been created with SDL_GPU_TEXTUREUSAGE_SAMPLER. */
+ SDL_GPUSampler *sampler; /**< The sampler to bind. */
+} SDL_GPUTextureSamplerBinding;
+
+/**
+ * A structure specifying parameters related to binding buffers in a compute
+ * pass.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPUComputePass
+ */
+typedef struct SDL_GPUStorageBufferReadWriteBinding
+{
+ SDL_GPUBuffer *buffer; /**< The buffer to bind. Must have been created with SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE. */
+ bool cycle; /**< true cycles the buffer if it is already bound. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUStorageBufferReadWriteBinding;
+
+/**
+ * A structure specifying parameters related to binding textures in a compute
+ * pass.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_BeginGPUComputePass
+ */
+typedef struct SDL_GPUStorageTextureReadWriteBinding
+{
+ SDL_GPUTexture *texture; /**< The texture to bind. Must have been created with SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE or SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE. */
+ Uint32 mip_level; /**< The mip level index to bind. */
+ Uint32 layer; /**< The layer index to bind. */
+ bool cycle; /**< true cycles the texture if it is already bound. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+} SDL_GPUStorageTextureReadWriteBinding;
+
+/* Functions */
+
+/* Device */
+
+/**
+ * Checks for GPU runtime support.
+ *
+ * \param format_flags a bitflag indicating which shader formats the app is
+ * able to provide.
+ * \param name the preferred GPU driver, or NULL to let SDL pick the optimal
+ * driver.
+ * \returns true if supported, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GPUSupportsShaderFormats(
+ SDL_GPUShaderFormat format_flags,
+ const char *name);
+
+/**
+ * Checks for GPU runtime support.
+ *
+ * \param props the properties to use.
+ * \returns true if supported, false otherwise.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUDeviceWithProperties
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GPUSupportsProperties(
+ SDL_PropertiesID props);
+
+/**
+ * Creates a GPU context.
+ *
+ * \param format_flags a bitflag indicating which shader formats the app is
+ * able to provide.
+ * \param debug_mode enable debug mode properties and validations.
+ * \param name the preferred GPU driver, or NULL to let SDL pick the optimal
+ * driver.
+ * \returns a GPU context on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGPUShaderFormats
+ * \sa SDL_GetGPUDeviceDriver
+ * \sa SDL_DestroyGPUDevice
+ * \sa SDL_GPUSupportsShaderFormats
+ */
+extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
+ SDL_GPUShaderFormat format_flags,
+ bool debug_mode,
+ const char *name);
+
+/**
+ * Creates a GPU context.
+ *
+ * These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN`: enable debug mode
+ * properties and validations, defaults to true.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN`: enable to prefer
+ * energy efficiency over maximum GPU performance, defaults to false.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING`: the name of the GPU driver to
+ * use, if a specific one is desired.
+ *
+ * These are the current shader format properties:
+ *
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN`: The app is able to
+ * provide shaders for an NDA platform.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN`: The app is able to
+ * provide SPIR-V shaders if applicable.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN`: The app is able to
+ * provide DXBC shaders if applicable
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN`: The app is able to
+ * provide DXIL shaders if applicable.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN`: The app is able to
+ * provide MSL shaders if applicable.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN`: The app is able to
+ * provide Metal shader libraries if applicable.
+ *
+ * With the D3D12 renderer:
+ *
+ * - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING`: the prefix to
+ * use for all vertex semantics, default is "TEXCOORD".
+ *
+ * \param props the properties to use.
+ * \returns a GPU context on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGPUShaderFormats
+ * \sa SDL_GetGPUDeviceDriver
+ * \sa SDL_DestroyGPUDevice
+ * \sa SDL_GPUSupportsProperties
+ */
+extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDeviceWithProperties(
+ SDL_PropertiesID props);
+
+#define SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN "SDL.gpu.device.create.debugmode"
+#define SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN "SDL.gpu.device.create.preferlowpower"
+#define SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING "SDL.gpu.device.create.name"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN "SDL.gpu.device.create.shaders.private"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN "SDL.gpu.device.create.shaders.spirv"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN "SDL.gpu.device.create.shaders.dxbc"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN "SDL.gpu.device.create.shaders.dxil"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN "SDL.gpu.device.create.shaders.msl"
+#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN "SDL.gpu.device.create.shaders.metallib"
+#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING "SDL.gpu.device.create.d3d12.semantic"
+
+/**
+ * Destroys a GPU context previously returned by SDL_CreateGPUDevice.
+ *
+ * \param device a GPU Context to destroy.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUDevice
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DestroyGPUDevice(SDL_GPUDevice *device);
+
+/**
+ * Get the number of GPU drivers compiled into SDL.
+ *
+ * \returns the number of built in GPU drivers.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetGPUDriver
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumGPUDrivers(void);
+
+/**
+ * Get the name of a built in GPU driver.
+ *
+ * The GPU drivers are presented in the order in which they are normally
+ * checked during initialization.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "vulkan",
+ * "metal" or "direct3d12". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \param index the index of a GPU driver.
+ * \returns the name of the GPU driver with the given **index**.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetNumGPUDrivers
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDriver(int index);
+
+/**
+ * Returns the name of the backend used to create this GPU context.
+ *
+ * \param device a GPU context to query.
+ * \returns the name of the device's driver, or NULL on error.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDeviceDriver(SDL_GPUDevice *device);
+
+/**
+ * Returns the supported shader formats for this GPU context.
+ *
+ * \param device a GPU context to query.
+ * \returns a bitflag indicating which shader formats the driver is able to
+ * consume.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_GPUShaderFormat SDLCALL SDL_GetGPUShaderFormats(SDL_GPUDevice *device);
+
+/* State Creation */
+
+/**
+ * Creates a pipeline object to be used in a compute workflow.
+ *
+ * Shader resource bindings must be authored to follow a particular order
+ * depending on the shader format.
+ *
+ * For SPIR-V shaders, use the following resource sets:
+ *
+ * - 0: Sampled textures, followed by read-only storage textures, followed by
+ * read-only storage buffers
+ * - 1: Read-write storage textures, followed by read-write storage buffers
+ * - 2: Uniform buffers
+ *
+ * For DXBC and DXIL shaders, use the following register order:
+ *
+ * - (t[n], space0): Sampled textures, followed by read-only storage textures,
+ * followed by read-only storage buffers
+ * - (u[n], space1): Read-write storage textures, followed by read-write
+ * storage buffers
+ * - (b[n], space2): Uniform buffers
+ *
+ * For MSL/metallib, use the following order:
+ *
+ * - [[buffer]]: Uniform buffers, followed by read-only storage buffers,
+ * followed by read-write storage buffers
+ * - [[texture]]: Sampled textures, followed by read-only storage textures,
+ * followed by read-write storage textures
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING`: a name that can be
+ * displayed in debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the compute pipeline to
+ * create.
+ * \returns a compute pipeline object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindGPUComputePipeline
+ * \sa SDL_ReleaseGPUComputePipeline
+ */
+extern SDL_DECLSPEC SDL_GPUComputePipeline * SDLCALL SDL_CreateGPUComputePipeline(
+ SDL_GPUDevice *device,
+ const SDL_GPUComputePipelineCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING "SDL.gpu.computepipeline.create.name"
+
+/**
+ * Creates a pipeline object to be used in a graphics workflow.
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING`: a name that can be
+ * displayed in debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the graphics pipeline to
+ * create.
+ * \returns a graphics pipeline object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ * \sa SDL_BindGPUGraphicsPipeline
+ * \sa SDL_ReleaseGPUGraphicsPipeline
+ */
+extern SDL_DECLSPEC SDL_GPUGraphicsPipeline * SDLCALL SDL_CreateGPUGraphicsPipeline(
+ SDL_GPUDevice *device,
+ const SDL_GPUGraphicsPipelineCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING "SDL.gpu.graphicspipeline.create.name"
+
+/**
+ * Creates a sampler object to be used when binding textures in a graphics
+ * workflow.
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING`: a name that can be displayed
+ * in debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the sampler to create.
+ * \returns a sampler object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_BindGPUVertexSamplers
+ * \sa SDL_BindGPUFragmentSamplers
+ * \sa SDL_ReleaseGPUSampler
+ */
+extern SDL_DECLSPEC SDL_GPUSampler * SDLCALL SDL_CreateGPUSampler(
+ SDL_GPUDevice *device,
+ const SDL_GPUSamplerCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING "SDL.gpu.sampler.create.name"
+
+/**
+ * Creates a shader to be used when creating a graphics pipeline.
+ *
+ * Shader resource bindings must be authored to follow a particular order
+ * depending on the shader format.
+ *
+ * For SPIR-V shaders, use the following resource sets:
+ *
+ * For vertex shaders:
+ *
+ * - 0: Sampled textures, followed by storage textures, followed by storage
+ * buffers
+ * - 1: Uniform buffers
+ *
+ * For fragment shaders:
+ *
+ * - 2: Sampled textures, followed by storage textures, followed by storage
+ * buffers
+ * - 3: Uniform buffers
+ *
+ * For DXBC and DXIL shaders, use the following register order:
+ *
+ * For vertex shaders:
+ *
+ * - (t[n], space0): Sampled textures, followed by storage textures, followed
+ * by storage buffers
+ * - (s[n], space0): Samplers with indices corresponding to the sampled
+ * textures
+ * - (b[n], space1): Uniform buffers
+ *
+ * For pixel shaders:
+ *
+ * - (t[n], space2): Sampled textures, followed by storage textures, followed
+ * by storage buffers
+ * - (s[n], space2): Samplers with indices corresponding to the sampled
+ * textures
+ * - (b[n], space3): Uniform buffers
+ *
+ * For MSL/metallib, use the following order:
+ *
+ * - [[texture]]: Sampled textures, followed by storage textures
+ * - [[sampler]]: Samplers with indices corresponding to the sampled textures
+ * - [[buffer]]: Uniform buffers, followed by storage buffers. Vertex buffer 0
+ * is bound at [[buffer(14)]], vertex buffer 1 at [[buffer(15)]], and so on.
+ * Rather than manually authoring vertex buffer indices, use the
+ * [[stage_in]] attribute which will automatically use the vertex input
+ * information from the SDL_GPUGraphicsPipeline.
+ *
+ * Shader semantics other than system-value semantics do not matter in D3D12
+ * and for ease of use the SDL implementation assumes that non system-value
+ * semantics will all be TEXCOORD. If you are using HLSL as the shader source
+ * language, your vertex semantics should start at TEXCOORD0 and increment
+ * like so: TEXCOORD1, TEXCOORD2, etc. If you wish to change the semantic
+ * prefix to something other than TEXCOORD you can use
+ * SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING with
+ * SDL_CreateGPUDeviceWithProperties().
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_SHADER_CREATE_NAME_STRING`: a name that can be displayed in
+ * debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the shader to create.
+ * \returns a shader object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUGraphicsPipeline
+ * \sa SDL_ReleaseGPUShader
+ */
+extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_CreateGPUShader(
+ SDL_GPUDevice *device,
+ const SDL_GPUShaderCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_SHADER_CREATE_NAME_STRING "SDL.gpu.shader.create.name"
+
+/**
+ * Creates a texture object to be used in graphics or compute workflows.
+ *
+ * The contents of this texture are undefined until data is written to the
+ * texture.
+ *
+ * Note that certain combinations of usage flags are invalid. For example, a
+ * texture cannot have both the SAMPLER and GRAPHICS_STORAGE_READ flags.
+ *
+ * If you request a sample count higher than the hardware supports, the
+ * implementation will automatically fall back to the highest available sample
+ * count.
+ *
+ * There are optional properties that can be provided through
+ * SDL_GPUTextureCreateInfo's `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT`: (Direct3D 12 only) if
+ * the texture usage is SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, clear the texture
+ * to a color with this red intensity. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT`: (Direct3D 12 only) if
+ * the texture usage is SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, clear the texture
+ * to a color with this green intensity. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT`: (Direct3D 12 only) if
+ * the texture usage is SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, clear the texture
+ * to a color with this blue intensity. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT`: (Direct3D 12 only) if
+ * the texture usage is SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, clear the texture
+ * to a color with this alpha intensity. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT`: (Direct3D 12 only)
+ * if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, clear
+ * the texture to a depth of this value. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER`: (Direct3D 12
+ * only) if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET,
+ * clear the texture to a stencil of this Uint8 value. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING`: a name that can be displayed
+ * in debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the texture to create.
+ * \returns a texture object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUTexture
+ * \sa SDL_BindGPUVertexSamplers
+ * \sa SDL_BindGPUVertexStorageTextures
+ * \sa SDL_BindGPUFragmentSamplers
+ * \sa SDL_BindGPUFragmentStorageTextures
+ * \sa SDL_BindGPUComputeStorageTextures
+ * \sa SDL_BlitGPUTexture
+ * \sa SDL_ReleaseGPUTexture
+ * \sa SDL_GPUTextureSupportsFormat
+ */
+extern SDL_DECLSPEC SDL_GPUTexture * SDLCALL SDL_CreateGPUTexture(
+ SDL_GPUDevice *device,
+ const SDL_GPUTextureCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT "SDL.gpu.texture.create.d3d12.clear.r"
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT "SDL.gpu.texture.create.d3d12.clear.g"
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT "SDL.gpu.texture.create.d3d12.clear.b"
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT "SDL.gpu.texture.create.d3d12.clear.a"
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT "SDL.gpu.texture.create.d3d12.clear.depth"
+#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER "SDL.gpu.texture.create.d3d12.clear.stencil"
+#define SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING "SDL.gpu.texture.create.name"
+
+/**
+ * Creates a buffer object to be used in graphics or compute workflows.
+ *
+ * The contents of this buffer are undefined until data is written to the
+ * buffer.
+ *
+ * Note that certain combinations of usage flags are invalid. For example, a
+ * buffer cannot have both the VERTEX and INDEX flags.
+ *
+ * If you use a STORAGE flag, the data in the buffer must respect std140
+ * layout conventions. In practical terms this means you must ensure that vec3
+ * and vec4 fields are 16-byte aligned.
+ *
+ * For better understanding of underlying concepts and memory management with
+ * SDL GPU API, you may refer
+ * [this blog post](https://moonside.games/posts/sdl-gpu-concepts-cycling/)
+ * .
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING`: a name that can be displayed in
+ * debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the buffer to create.
+ * \returns a buffer object on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_DownloadFromGPUBuffer
+ * \sa SDL_CopyGPUBufferToBuffer
+ * \sa SDL_BindGPUVertexBuffers
+ * \sa SDL_BindGPUIndexBuffer
+ * \sa SDL_BindGPUVertexStorageBuffers
+ * \sa SDL_BindGPUFragmentStorageBuffers
+ * \sa SDL_DrawGPUPrimitivesIndirect
+ * \sa SDL_DrawGPUIndexedPrimitivesIndirect
+ * \sa SDL_BindGPUComputeStorageBuffers
+ * \sa SDL_DispatchGPUComputeIndirect
+ * \sa SDL_ReleaseGPUBuffer
+ */
+extern SDL_DECLSPEC SDL_GPUBuffer * SDLCALL SDL_CreateGPUBuffer(
+ SDL_GPUDevice *device,
+ const SDL_GPUBufferCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING "SDL.gpu.buffer.create.name"
+
+/**
+ * Creates a transfer buffer to be used when uploading to or downloading from
+ * graphics resources.
+ *
+ * Download buffers can be particularly expensive to create, so it is good
+ * practice to reuse them if data will be downloaded regularly.
+ *
+ * There are optional properties that can be provided through `props`. These
+ * are the supported properties:
+ *
+ * - `SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING`: a name that can be
+ * displayed in debugging tools.
+ *
+ * \param device a GPU Context.
+ * \param createinfo a struct describing the state of the transfer buffer to
+ * create.
+ * \returns a transfer buffer on success, or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUBuffer
+ * \sa SDL_DownloadFromGPUBuffer
+ * \sa SDL_UploadToGPUTexture
+ * \sa SDL_DownloadFromGPUTexture
+ * \sa SDL_ReleaseGPUTransferBuffer
+ */
+extern SDL_DECLSPEC SDL_GPUTransferBuffer * SDLCALL SDL_CreateGPUTransferBuffer(
+ SDL_GPUDevice *device,
+ const SDL_GPUTransferBufferCreateInfo *createinfo);
+
+#define SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING "SDL.gpu.transferbuffer.create.name"
+
+/* Debug Naming */
+
+/**
+ * Sets an arbitrary string constant to label a buffer.
+ *
+ * You should use SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING with
+ * SDL_CreateGPUBuffer instead of this function to avoid thread safety issues.
+ *
+ * \param device a GPU Context.
+ * \param buffer a buffer to attach the name to.
+ * \param text a UTF-8 string constant to mark as the name of the buffer.
+ *
+ * \threadsafety This function is not thread safe, you must make sure the
+ * buffer is not simultaneously used by any other thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUBuffer
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUBufferName(
+ SDL_GPUDevice *device,
+ SDL_GPUBuffer *buffer,
+ const char *text);
+
+/**
+ * Sets an arbitrary string constant to label a texture.
+ *
+ * You should use SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING with
+ * SDL_CreateGPUTexture instead of this function to avoid thread safety
+ * issues.
+ *
+ * \param device a GPU Context.
+ * \param texture a texture to attach the name to.
+ * \param text a UTF-8 string constant to mark as the name of the texture.
+ *
+ * \threadsafety This function is not thread safe, you must make sure the
+ * texture is not simultaneously used by any other thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUTexture
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUTextureName(
+ SDL_GPUDevice *device,
+ SDL_GPUTexture *texture,
+ const char *text);
+
+/**
+ * Inserts an arbitrary string label into the command buffer callstream.
+ *
+ * Useful for debugging.
+ *
+ * \param command_buffer a command buffer.
+ * \param text a UTF-8 string constant to insert as the label.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
+ SDL_GPUCommandBuffer *command_buffer,
+ const char *text);
+
+/**
+ * Begins a debug group with an arbitary name.
+ *
+ * Used for denoting groups of calls when viewing the command buffer
+ * callstream in a graphics debugging tool.
+ *
+ * Each call to SDL_PushGPUDebugGroup must have a corresponding call to
+ * SDL_PopGPUDebugGroup.
+ *
+ * On some backends (e.g. Metal), pushing a debug group during a
+ * render/blit/compute pass will create a group that is scoped to the native
+ * pass rather than the command buffer. For best results, if you push a debug
+ * group during a pass, always pop it in the same pass.
+ *
+ * \param command_buffer a command buffer.
+ * \param name a UTF-8 string constant that names the group.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PopGPUDebugGroup
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PushGPUDebugGroup(
+ SDL_GPUCommandBuffer *command_buffer,
+ const char *name);
+
+/**
+ * Ends the most-recently pushed debug group.
+ *
+ * \param command_buffer a command buffer.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PushGPUDebugGroup
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PopGPUDebugGroup(
+ SDL_GPUCommandBuffer *command_buffer);
+
+/* Disposal */
+
+/**
+ * Frees the given texture as soon as it is safe to do so.
+ *
+ * You must not reference the texture after calling this function.
+ *
+ * \param device a GPU context.
+ * \param texture a texture to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUTexture(
+ SDL_GPUDevice *device,
+ SDL_GPUTexture *texture);
+
+/**
+ * Frees the given sampler as soon as it is safe to do so.
+ *
+ * You must not reference the sampler after calling this function.
+ *
+ * \param device a GPU context.
+ * \param sampler a sampler to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUSampler(
+ SDL_GPUDevice *device,
+ SDL_GPUSampler *sampler);
+
+/**
+ * Frees the given buffer as soon as it is safe to do so.
+ *
+ * You must not reference the buffer after calling this function.
+ *
+ * \param device a GPU context.
+ * \param buffer a buffer to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUBuffer(
+ SDL_GPUDevice *device,
+ SDL_GPUBuffer *buffer);
+
+/**
+ * Frees the given transfer buffer as soon as it is safe to do so.
+ *
+ * You must not reference the transfer buffer after calling this function.
+ *
+ * \param device a GPU context.
+ * \param transfer_buffer a transfer buffer to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUTransferBuffer(
+ SDL_GPUDevice *device,
+ SDL_GPUTransferBuffer *transfer_buffer);
+
+/**
+ * Frees the given compute pipeline as soon as it is safe to do so.
+ *
+ * You must not reference the compute pipeline after calling this function.
+ *
+ * \param device a GPU context.
+ * \param compute_pipeline a compute pipeline to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUComputePipeline(
+ SDL_GPUDevice *device,
+ SDL_GPUComputePipeline *compute_pipeline);
+
+/**
+ * Frees the given shader as soon as it is safe to do so.
+ *
+ * You must not reference the shader after calling this function.
+ *
+ * \param device a GPU context.
+ * \param shader a shader to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUShader(
+ SDL_GPUDevice *device,
+ SDL_GPUShader *shader);
+
+/**
+ * Frees the given graphics pipeline as soon as it is safe to do so.
+ *
+ * You must not reference the graphics pipeline after calling this function.
+ *
+ * \param device a GPU context.
+ * \param graphics_pipeline a graphics pipeline to be destroyed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUGraphicsPipeline(
+ SDL_GPUDevice *device,
+ SDL_GPUGraphicsPipeline *graphics_pipeline);
+
+/**
+ * Acquire a command buffer.
+ *
+ * This command buffer is managed by the implementation and should not be
+ * freed by the user. The command buffer may only be used on the thread it was
+ * acquired on. The command buffer should be submitted on the thread it was
+ * acquired on.
+ *
+ * It is valid to acquire multiple command buffers on the same thread at once.
+ * In fact a common design pattern is to acquire two command buffers per frame
+ * where one is dedicated to render and compute passes and the other is
+ * dedicated to copy passes and other preparatory work such as generating
+ * mipmaps. Interleaving commands between the two command buffers reduces the
+ * total amount of passes overall which improves rendering performance.
+ *
+ * \param device a GPU context.
+ * \returns a command buffer, or NULL on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBuffer
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ */
+extern SDL_DECLSPEC SDL_GPUCommandBuffer * SDLCALL SDL_AcquireGPUCommandBuffer(
+ SDL_GPUDevice *device);
+
+/* Uniform Data */
+
+/**
+ * Pushes data to a vertex uniform slot on the command buffer.
+ *
+ * Subsequent draw calls will use this uniform data.
+ *
+ * The data being pushed must respect std140 layout conventions. In practical
+ * terms this means you must ensure that vec3 and vec4 fields are 16-byte
+ * aligned.
+ *
+ * \param command_buffer a command buffer.
+ * \param slot_index the vertex uniform slot to push data to.
+ * \param data client data to write.
+ * \param length the length of the data to write.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PushGPUVertexUniformData(
+ SDL_GPUCommandBuffer *command_buffer,
+ Uint32 slot_index,
+ const void *data,
+ Uint32 length);
+
+/**
+ * Pushes data to a fragment uniform slot on the command buffer.
+ *
+ * Subsequent draw calls will use this uniform data.
+ *
+ * The data being pushed must respect std140 layout conventions. In practical
+ * terms this means you must ensure that vec3 and vec4 fields are 16-byte
+ * aligned.
+ *
+ * \param command_buffer a command buffer.
+ * \param slot_index the fragment uniform slot to push data to.
+ * \param data client data to write.
+ * \param length the length of the data to write.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PushGPUFragmentUniformData(
+ SDL_GPUCommandBuffer *command_buffer,
+ Uint32 slot_index,
+ const void *data,
+ Uint32 length);
+
+/**
+ * Pushes data to a uniform slot on the command buffer.
+ *
+ * Subsequent draw calls will use this uniform data.
+ *
+ * The data being pushed must respect std140 layout conventions. In practical
+ * terms this means you must ensure that vec3 and vec4 fields are 16-byte
+ * aligned.
+ *
+ * \param command_buffer a command buffer.
+ * \param slot_index the uniform slot to push data to.
+ * \param data client data to write.
+ * \param length the length of the data to write.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_PushGPUComputeUniformData(
+ SDL_GPUCommandBuffer *command_buffer,
+ Uint32 slot_index,
+ const void *data,
+ Uint32 length);
+
+/* Graphics State */
+
+/**
+ * Begins a render pass on a command buffer.
+ *
+ * A render pass consists of a set of texture subresources (or depth slices in
+ * the 3D texture case) which will be rendered to during the render pass,
+ * along with corresponding clear values and load/store operations. All
+ * operations related to graphics pipelines must take place inside of a render
+ * pass. A default viewport and scissor state are automatically set when this
+ * is called. You cannot begin another render pass, or begin a compute pass or
+ * copy pass until you have ended the render pass.
+ *
+ * \param command_buffer a command buffer.
+ * \param color_target_infos an array of texture subresources with
+ * corresponding clear values and load/store ops.
+ * \param num_color_targets the number of color targets in the
+ * color_target_infos array.
+ * \param depth_stencil_target_info a texture subresource with corresponding
+ * clear value and load/store ops, may be
+ * NULL.
+ * \returns a render pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_EndGPURenderPass
+ */
+extern SDL_DECLSPEC SDL_GPURenderPass * SDLCALL SDL_BeginGPURenderPass(
+ SDL_GPUCommandBuffer *command_buffer,
+ const SDL_GPUColorTargetInfo *color_target_infos,
+ Uint32 num_color_targets,
+ const SDL_GPUDepthStencilTargetInfo *depth_stencil_target_info);
+
+/**
+ * Binds a graphics pipeline on a render pass to be used in rendering.
+ *
+ * A graphics pipeline must be bound before making any draw calls.
+ *
+ * \param render_pass a render pass handle.
+ * \param graphics_pipeline the graphics pipeline to bind.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUGraphicsPipeline(
+ SDL_GPURenderPass *render_pass,
+ SDL_GPUGraphicsPipeline *graphics_pipeline);
+
+/**
+ * Sets the current viewport state on a command buffer.
+ *
+ * \param render_pass a render pass handle.
+ * \param viewport the viewport to set.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUViewport(
+ SDL_GPURenderPass *render_pass,
+ const SDL_GPUViewport *viewport);
+
+/**
+ * Sets the current scissor state on a command buffer.
+ *
+ * \param render_pass a render pass handle.
+ * \param scissor the scissor area to set.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUScissor(
+ SDL_GPURenderPass *render_pass,
+ const SDL_Rect *scissor);
+
+/**
+ * Sets the current blend constants on a command buffer.
+ *
+ * \param render_pass a render pass handle.
+ * \param blend_constants the blend constant color.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GPU_BLENDFACTOR_CONSTANT_COLOR
+ * \sa SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUBlendConstants(
+ SDL_GPURenderPass *render_pass,
+ SDL_FColor blend_constants);
+
+/**
+ * Sets the current stencil reference value on a command buffer.
+ *
+ * \param render_pass a render pass handle.
+ * \param reference the stencil reference value to set.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_SetGPUStencilReference(
+ SDL_GPURenderPass *render_pass,
+ Uint8 reference);
+
+/**
+ * Binds vertex buffers on a command buffer for use with subsequent draw
+ * calls.
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the vertex buffer slot to begin binding from.
+ * \param bindings an array of SDL_GPUBufferBinding structs containing vertex
+ * buffers and offset values.
+ * \param num_bindings the number of bindings in the bindings array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUVertexBuffers(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ const SDL_GPUBufferBinding *bindings,
+ Uint32 num_bindings);
+
+/**
+ * Binds an index buffer on a command buffer for use with subsequent draw
+ * calls.
+ *
+ * \param render_pass a render pass handle.
+ * \param binding a pointer to a struct containing an index buffer and offset.
+ * \param index_element_size whether the index values in the buffer are 16- or
+ * 32-bit.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUIndexBuffer(
+ SDL_GPURenderPass *render_pass,
+ const SDL_GPUBufferBinding *binding,
+ SDL_GPUIndexElementSize index_element_size);
+
+/**
+ * Binds texture-sampler pairs for use on the vertex shader.
+ *
+ * The textures must have been created with SDL_GPU_TEXTUREUSAGE_SAMPLER.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the vertex sampler slot to begin binding from.
+ * \param texture_sampler_bindings an array of texture-sampler binding
+ * structs.
+ * \param num_bindings the number of texture-sampler pairs to bind from the
+ * array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUVertexSamplers(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage textures for use on the vertex shader.
+ *
+ * These textures must have been created with
+ * SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the vertex storage texture slot to begin binding from.
+ * \param storage_textures an array of storage textures.
+ * \param num_bindings the number of storage texture to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUVertexStorageTextures(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ SDL_GPUTexture *const *storage_textures,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage buffers for use on the vertex shader.
+ *
+ * These buffers must have been created with
+ * SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the vertex storage buffer slot to begin binding from.
+ * \param storage_buffers an array of buffers.
+ * \param num_bindings the number of buffers to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUVertexStorageBuffers(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ SDL_GPUBuffer *const *storage_buffers,
+ Uint32 num_bindings);
+
+/**
+ * Binds texture-sampler pairs for use on the fragment shader.
+ *
+ * The textures must have been created with SDL_GPU_TEXTUREUSAGE_SAMPLER.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the fragment sampler slot to begin binding from.
+ * \param texture_sampler_bindings an array of texture-sampler binding
+ * structs.
+ * \param num_bindings the number of texture-sampler pairs to bind from the
+ * array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUFragmentSamplers(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage textures for use on the fragment shader.
+ *
+ * These textures must have been created with
+ * SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the fragment storage texture slot to begin binding from.
+ * \param storage_textures an array of storage textures.
+ * \param num_bindings the number of storage textures to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUFragmentStorageTextures(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ SDL_GPUTexture *const *storage_textures,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage buffers for use on the fragment shader.
+ *
+ * These buffers must have been created with
+ * SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param render_pass a render pass handle.
+ * \param first_slot the fragment storage buffer slot to begin binding from.
+ * \param storage_buffers an array of storage buffers.
+ * \param num_bindings the number of storage buffers to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUFragmentStorageBuffers(
+ SDL_GPURenderPass *render_pass,
+ Uint32 first_slot,
+ SDL_GPUBuffer *const *storage_buffers,
+ Uint32 num_bindings);
+
+/* Drawing */
+
+/**
+ * Draws data using bound graphics state with an index buffer and instancing
+ * enabled.
+ *
+ * You must not call this function before binding a graphics pipeline.
+ *
+ * Note that the `first_vertex` and `first_instance` parameters are NOT
+ * compatible with built-in vertex/instance ID variables in shaders (for
+ * example, SV_VertexID); GPU APIs and shader languages do not define these
+ * built-in variables consistently, so if your shader depends on them, the
+ * only way to keep behavior consistent and portable is to always pass 0 for
+ * the correlating parameter in the draw calls.
+ *
+ * \param render_pass a render pass handle.
+ * \param num_indices the number of indices to draw per instance.
+ * \param num_instances the number of instances to draw.
+ * \param first_index the starting index within the index buffer.
+ * \param vertex_offset value added to vertex index before indexing into the
+ * vertex buffer.
+ * \param first_instance the ID of the first instance to draw.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DrawGPUIndexedPrimitives(
+ SDL_GPURenderPass *render_pass,
+ Uint32 num_indices,
+ Uint32 num_instances,
+ Uint32 first_index,
+ Sint32 vertex_offset,
+ Uint32 first_instance);
+
+/**
+ * Draws data using bound graphics state.
+ *
+ * You must not call this function before binding a graphics pipeline.
+ *
+ * Note that the `first_vertex` and `first_instance` parameters are NOT
+ * compatible with built-in vertex/instance ID variables in shaders (for
+ * example, SV_VertexID); GPU APIs and shader languages do not define these
+ * built-in variables consistently, so if your shader depends on them, the
+ * only way to keep behavior consistent and portable is to always pass 0 for
+ * the correlating parameter in the draw calls.
+ *
+ * \param render_pass a render pass handle.
+ * \param num_vertices the number of vertices to draw.
+ * \param num_instances the number of instances that will be drawn.
+ * \param first_vertex the index of the first vertex to draw.
+ * \param first_instance the ID of the first instance to draw.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DrawGPUPrimitives(
+ SDL_GPURenderPass *render_pass,
+ Uint32 num_vertices,
+ Uint32 num_instances,
+ Uint32 first_vertex,
+ Uint32 first_instance);
+
+/**
+ * Draws data using bound graphics state and with draw parameters set from a
+ * buffer.
+ *
+ * The buffer must consist of tightly-packed draw parameter sets that each
+ * match the layout of SDL_GPUIndirectDrawCommand. You must not call this
+ * function before binding a graphics pipeline.
+ *
+ * \param render_pass a render pass handle.
+ * \param buffer a buffer containing draw parameters.
+ * \param offset the offset to start reading from the draw buffer.
+ * \param draw_count the number of draw parameter sets that should be read
+ * from the draw buffer.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DrawGPUPrimitivesIndirect(
+ SDL_GPURenderPass *render_pass,
+ SDL_GPUBuffer *buffer,
+ Uint32 offset,
+ Uint32 draw_count);
+
+/**
+ * Draws data using bound graphics state with an index buffer enabled and with
+ * draw parameters set from a buffer.
+ *
+ * The buffer must consist of tightly-packed draw parameter sets that each
+ * match the layout of SDL_GPUIndexedIndirectDrawCommand. You must not call
+ * this function before binding a graphics pipeline.
+ *
+ * \param render_pass a render pass handle.
+ * \param buffer a buffer containing draw parameters.
+ * \param offset the offset to start reading from the draw buffer.
+ * \param draw_count the number of draw parameter sets that should be read
+ * from the draw buffer.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DrawGPUIndexedPrimitivesIndirect(
+ SDL_GPURenderPass *render_pass,
+ SDL_GPUBuffer *buffer,
+ Uint32 offset,
+ Uint32 draw_count);
+
+/**
+ * Ends the given render pass.
+ *
+ * All bound graphics state on the render pass command buffer is unset. The
+ * render pass handle is now invalid.
+ *
+ * \param render_pass a render pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_EndGPURenderPass(
+ SDL_GPURenderPass *render_pass);
+
+/* Compute Pass */
+
+/**
+ * Begins a compute pass on a command buffer.
+ *
+ * A compute pass is defined by a set of texture subresources and buffers that
+ * may be written to by compute pipelines. These textures and buffers must
+ * have been created with the COMPUTE_STORAGE_WRITE bit or the
+ * COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE bit. If you do not create a texture
+ * with COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE, you must not read from the
+ * texture in the compute pass. All operations related to compute pipelines
+ * must take place inside of a compute pass. You must not begin another
+ * compute pass, or a render pass or copy pass before ending the compute pass.
+ *
+ * A VERY IMPORTANT NOTE - Reads and writes in compute passes are NOT
+ * implicitly synchronized. This means you may cause data races by both
+ * reading and writing a resource region in a compute pass, or by writing
+ * multiple times to a resource region. If your compute work depends on
+ * reading the completed output from a previous dispatch, you MUST end the
+ * current compute pass and begin a new one before you can safely access the
+ * data. Otherwise you will receive unexpected results. Reading and writing a
+ * texture in the same compute pass is only supported by specific texture
+ * formats. Make sure you check the format support!
+ *
+ * \param command_buffer a command buffer.
+ * \param storage_texture_bindings an array of writeable storage texture
+ * binding structs.
+ * \param num_storage_texture_bindings the number of storage textures to bind
+ * from the array.
+ * \param storage_buffer_bindings an array of writeable storage buffer binding
+ * structs.
+ * \param num_storage_buffer_bindings the number of storage buffers to bind
+ * from the array.
+ * \returns a compute pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_EndGPUComputePass
+ */
+extern SDL_DECLSPEC SDL_GPUComputePass * SDLCALL SDL_BeginGPUComputePass(
+ SDL_GPUCommandBuffer *command_buffer,
+ const SDL_GPUStorageTextureReadWriteBinding *storage_texture_bindings,
+ Uint32 num_storage_texture_bindings,
+ const SDL_GPUStorageBufferReadWriteBinding *storage_buffer_bindings,
+ Uint32 num_storage_buffer_bindings);
+
+/**
+ * Binds a compute pipeline on a command buffer for use in compute dispatch.
+ *
+ * \param compute_pass a compute pass handle.
+ * \param compute_pipeline a compute pipeline to bind.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUComputePipeline(
+ SDL_GPUComputePass *compute_pass,
+ SDL_GPUComputePipeline *compute_pipeline);
+
+/**
+ * Binds texture-sampler pairs for use on the compute shader.
+ *
+ * The textures must have been created with SDL_GPU_TEXTUREUSAGE_SAMPLER.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param compute_pass a compute pass handle.
+ * \param first_slot the compute sampler slot to begin binding from.
+ * \param texture_sampler_bindings an array of texture-sampler binding
+ * structs.
+ * \param num_bindings the number of texture-sampler bindings to bind from the
+ * array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUComputeSamplers(
+ SDL_GPUComputePass *compute_pass,
+ Uint32 first_slot,
+ const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage textures as readonly for use on the compute pipeline.
+ *
+ * These textures must have been created with
+ * SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param compute_pass a compute pass handle.
+ * \param first_slot the compute storage texture slot to begin binding from.
+ * \param storage_textures an array of storage textures.
+ * \param num_bindings the number of storage textures to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUComputeStorageTextures(
+ SDL_GPUComputePass *compute_pass,
+ Uint32 first_slot,
+ SDL_GPUTexture *const *storage_textures,
+ Uint32 num_bindings);
+
+/**
+ * Binds storage buffers as readonly for use on the compute pipeline.
+ *
+ * These buffers must have been created with
+ * SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ.
+ *
+ * Be sure your shader is set up according to the requirements documented in
+ * SDL_CreateGPUShader().
+ *
+ * \param compute_pass a compute pass handle.
+ * \param first_slot the compute storage buffer slot to begin binding from.
+ * \param storage_buffers an array of storage buffer binding structs.
+ * \param num_bindings the number of storage buffers to bind from the array.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateGPUShader
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BindGPUComputeStorageBuffers(
+ SDL_GPUComputePass *compute_pass,
+ Uint32 first_slot,
+ SDL_GPUBuffer *const *storage_buffers,
+ Uint32 num_bindings);
+
+/**
+ * Dispatches compute work.
+ *
+ * You must not call this function before binding a compute pipeline.
+ *
+ * A VERY IMPORTANT NOTE If you dispatch multiple times in a compute pass, and
+ * the dispatches write to the same resource region as each other, there is no
+ * guarantee of which order the writes will occur. If the write order matters,
+ * you MUST end the compute pass and begin another one.
+ *
+ * \param compute_pass a compute pass handle.
+ * \param groupcount_x number of local workgroups to dispatch in the X
+ * dimension.
+ * \param groupcount_y number of local workgroups to dispatch in the Y
+ * dimension.
+ * \param groupcount_z number of local workgroups to dispatch in the Z
+ * dimension.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DispatchGPUCompute(
+ SDL_GPUComputePass *compute_pass,
+ Uint32 groupcount_x,
+ Uint32 groupcount_y,
+ Uint32 groupcount_z);
+
+/**
+ * Dispatches compute work with parameters set from a buffer.
+ *
+ * The buffer layout should match the layout of
+ * SDL_GPUIndirectDispatchCommand. You must not call this function before
+ * binding a compute pipeline.
+ *
+ * A VERY IMPORTANT NOTE If you dispatch multiple times in a compute pass, and
+ * the dispatches write to the same resource region as each other, there is no
+ * guarantee of which order the writes will occur. If the write order matters,
+ * you MUST end the compute pass and begin another one.
+ *
+ * \param compute_pass a compute pass handle.
+ * \param buffer a buffer containing dispatch parameters.
+ * \param offset the offset to start reading from the dispatch buffer.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DispatchGPUComputeIndirect(
+ SDL_GPUComputePass *compute_pass,
+ SDL_GPUBuffer *buffer,
+ Uint32 offset);
+
+/**
+ * Ends the current compute pass.
+ *
+ * All bound compute state on the command buffer is unset. The compute pass
+ * handle is now invalid.
+ *
+ * \param compute_pass a compute pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_EndGPUComputePass(
+ SDL_GPUComputePass *compute_pass);
+
+/* TransferBuffer Data */
+
+/**
+ * Maps a transfer buffer into application address space.
+ *
+ * You must unmap the transfer buffer before encoding upload commands. The
+ * memory is owned by the graphics driver - do NOT call SDL_free() on the
+ * returned pointer.
+ *
+ * \param device a GPU context.
+ * \param transfer_buffer a transfer buffer.
+ * \param cycle if true, cycles the transfer buffer if it is already bound.
+ * \returns the address of the mapped transfer buffer memory, or NULL on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void * SDLCALL SDL_MapGPUTransferBuffer(
+ SDL_GPUDevice *device,
+ SDL_GPUTransferBuffer *transfer_buffer,
+ bool cycle);
+
+/**
+ * Unmaps a previously mapped transfer buffer.
+ *
+ * \param device a GPU context.
+ * \param transfer_buffer a previously mapped transfer buffer.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UnmapGPUTransferBuffer(
+ SDL_GPUDevice *device,
+ SDL_GPUTransferBuffer *transfer_buffer);
+
+/* Copy Pass */
+
+/**
+ * Begins a copy pass on a command buffer.
+ *
+ * All operations related to copying to or from buffers or textures take place
+ * inside a copy pass. You must not begin another copy pass, or a render pass
+ * or compute pass before ending the copy pass.
+ *
+ * \param command_buffer a command buffer.
+ * \returns a copy pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_GPUCopyPass * SDLCALL SDL_BeginGPUCopyPass(
+ SDL_GPUCommandBuffer *command_buffer);
+
+/**
+ * Uploads data from a transfer buffer to a texture.
+ *
+ * The upload occurs on the GPU timeline. You may assume that the upload has
+ * finished in subsequent commands.
+ *
+ * You must align the data in the transfer buffer to a multiple of the texel
+ * size of the texture format.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source the source transfer buffer with image layout information.
+ * \param destination the destination texture region.
+ * \param cycle if true, cycles the texture if the texture is bound, otherwise
+ * overwrites the data.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UploadToGPUTexture(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUTextureTransferInfo *source,
+ const SDL_GPUTextureRegion *destination,
+ bool cycle);
+
+/**
+ * Uploads data from a transfer buffer to a buffer.
+ *
+ * The upload occurs on the GPU timeline. You may assume that the upload has
+ * finished in subsequent commands.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source the source transfer buffer with offset.
+ * \param destination the destination buffer with offset and size.
+ * \param cycle if true, cycles the buffer if it is already bound, otherwise
+ * overwrites the data.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_UploadToGPUBuffer(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUTransferBufferLocation *source,
+ const SDL_GPUBufferRegion *destination,
+ bool cycle);
+
+/**
+ * Performs a texture-to-texture copy.
+ *
+ * This copy occurs on the GPU timeline. You may assume the copy has finished
+ * in subsequent commands.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source a source texture region.
+ * \param destination a destination texture region.
+ * \param w the width of the region to copy.
+ * \param h the height of the region to copy.
+ * \param d the depth of the region to copy.
+ * \param cycle if true, cycles the destination texture if the destination
+ * texture is bound, otherwise overwrites the data.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CopyGPUTextureToTexture(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUTextureLocation *source,
+ const SDL_GPUTextureLocation *destination,
+ Uint32 w,
+ Uint32 h,
+ Uint32 d,
+ bool cycle);
+
+/**
+ * Performs a buffer-to-buffer copy.
+ *
+ * This copy occurs on the GPU timeline. You may assume the copy has finished
+ * in subsequent commands.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source the buffer and offset to copy from.
+ * \param destination the buffer and offset to copy to.
+ * \param size the length of the buffer to copy.
+ * \param cycle if true, cycles the destination buffer if it is already bound,
+ * otherwise overwrites the data.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CopyGPUBufferToBuffer(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUBufferLocation *source,
+ const SDL_GPUBufferLocation *destination,
+ Uint32 size,
+ bool cycle);
+
+/**
+ * Copies data from a texture to a transfer buffer on the GPU timeline.
+ *
+ * This data is not guaranteed to be copied until the command buffer fence is
+ * signaled.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source the source texture region.
+ * \param destination the destination transfer buffer with image layout
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DownloadFromGPUTexture(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUTextureRegion *source,
+ const SDL_GPUTextureTransferInfo *destination);
+
+/**
+ * Copies data from a buffer to a transfer buffer on the GPU timeline.
+ *
+ * This data is not guaranteed to be copied until the command buffer fence is
+ * signaled.
+ *
+ * \param copy_pass a copy pass handle.
+ * \param source the source buffer with offset and size.
+ * \param destination the destination transfer buffer with offset.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DownloadFromGPUBuffer(
+ SDL_GPUCopyPass *copy_pass,
+ const SDL_GPUBufferRegion *source,
+ const SDL_GPUTransferBufferLocation *destination);
+
+/**
+ * Ends the current copy pass.
+ *
+ * \param copy_pass a copy pass handle.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_EndGPUCopyPass(
+ SDL_GPUCopyPass *copy_pass);
+
+/**
+ * Generates mipmaps for the given texture.
+ *
+ * This function must not be called inside of any pass.
+ *
+ * \param command_buffer a command_buffer.
+ * \param texture a texture with more than 1 mip level.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_GenerateMipmapsForGPUTexture(
+ SDL_GPUCommandBuffer *command_buffer,
+ SDL_GPUTexture *texture);
+
+/**
+ * Blits from a source texture region to a destination texture region.
+ *
+ * This function must not be called inside of any pass.
+ *
+ * \param command_buffer a command buffer.
+ * \param info the blit info struct containing the blit parameters.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_BlitGPUTexture(
+ SDL_GPUCommandBuffer *command_buffer,
+ const SDL_GPUBlitInfo *info);
+
+/* Submission/Presentation */
+
+/**
+ * Determines whether a swapchain composition is supported by the window.
+ *
+ * The window must be claimed before calling this function.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window.
+ * \param swapchain_composition the swapchain composition to check.
+ * \returns true if supported, false if unsupported.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClaimWindowForGPUDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WindowSupportsGPUSwapchainComposition(
+ SDL_GPUDevice *device,
+ SDL_Window *window,
+ SDL_GPUSwapchainComposition swapchain_composition);
+
+/**
+ * Determines whether a presentation mode is supported by the window.
+ *
+ * The window must be claimed before calling this function.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window.
+ * \param present_mode the presentation mode to check.
+ * \returns true if supported, false if unsupported.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClaimWindowForGPUDevice
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WindowSupportsGPUPresentMode(
+ SDL_GPUDevice *device,
+ SDL_Window *window,
+ SDL_GPUPresentMode present_mode);
+
+/**
+ * Claims a window, creating a swapchain structure for it.
+ *
+ * This must be called before SDL_AcquireGPUSwapchainTexture is called using
+ * the window. You should only call this function from the thread that created
+ * the window.
+ *
+ * The swapchain will be created with SDL_GPU_SWAPCHAINCOMPOSITION_SDR and
+ * SDL_GPU_PRESENTMODE_VSYNC. If you want to have different swapchain
+ * parameters, you must call SDL_SetGPUSwapchainParameters after claiming the
+ * window.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window.
+ * \returns true on success, or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called from the thread that
+ * created the window.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_ReleaseWindowFromGPUDevice
+ * \sa SDL_WindowSupportsGPUPresentMode
+ * \sa SDL_WindowSupportsGPUSwapchainComposition
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ClaimWindowForGPUDevice(
+ SDL_GPUDevice *device,
+ SDL_Window *window);
+
+/**
+ * Unclaims a window, destroying its swapchain structure.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window that has been claimed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClaimWindowForGPUDevice
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseWindowFromGPUDevice(
+ SDL_GPUDevice *device,
+ SDL_Window *window);
+
+/**
+ * Changes the swapchain parameters for the given claimed window.
+ *
+ * This function will fail if the requested present mode or swapchain
+ * composition are unsupported by the device. Check if the parameters are
+ * supported via SDL_WindowSupportsGPUPresentMode /
+ * SDL_WindowSupportsGPUSwapchainComposition prior to calling this function.
+ *
+ * SDL_GPU_PRESENTMODE_VSYNC with SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always
+ * supported.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window that has been claimed.
+ * \param swapchain_composition the desired composition of the swapchain.
+ * \param present_mode the desired present mode for the swapchain.
+ * \returns true if successful, false on error; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WindowSupportsGPUPresentMode
+ * \sa SDL_WindowSupportsGPUSwapchainComposition
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGPUSwapchainParameters(
+ SDL_GPUDevice *device,
+ SDL_Window *window,
+ SDL_GPUSwapchainComposition swapchain_composition,
+ SDL_GPUPresentMode present_mode);
+
+/**
+ * Configures the maximum allowed number of frames in flight.
+ *
+ * The default value when the device is created is 2. This means that after
+ * you have submitted 2 frames for presentation, if the GPU has not finished
+ * working on the first frame, SDL_AcquireGPUSwapchainTexture() will fill the
+ * swapchain texture pointer with NULL, and
+ * SDL_WaitAndAcquireGPUSwapchainTexture() will block.
+ *
+ * Higher values increase throughput at the expense of visual latency. Lower
+ * values decrease visual latency at the expense of throughput.
+ *
+ * Note that calling this function will stall and flush the command queue to
+ * prevent synchronization issues.
+ *
+ * The minimum value of allowed frames in flight is 1, and the maximum is 3.
+ *
+ * \param device a GPU context.
+ * \param allowed_frames_in_flight the maximum number of frames that can be
+ * pending on the GPU.
+ * \returns true if successful, false on error; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetGPUAllowedFramesInFlight(
+ SDL_GPUDevice *device,
+ Uint32 allowed_frames_in_flight);
+
+/**
+ * Obtains the texture format of the swapchain for the given window.
+ *
+ * Note that this format can change if the swapchain parameters change.
+ *
+ * \param device a GPU context.
+ * \param window an SDL_Window that has been claimed.
+ * \returns the texture format of the swapchain.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUSwapchainTextureFormat(
+ SDL_GPUDevice *device,
+ SDL_Window *window);
+
+/**
+ * Acquire a texture to use in presentation.
+ *
+ * When a swapchain texture is acquired on a command buffer, it will
+ * automatically be submitted for presentation when the command buffer is
+ * submitted. The swapchain texture should only be referenced by the command
+ * buffer used to acquire it.
+ *
+ * This function will fill the swapchain texture handle with NULL if too many
+ * frames are in flight. This is not an error.
+ *
+ * If you use this function, it is possible to create a situation where many
+ * command buffers are allocated while the rendering context waits for the GPU
+ * to catch up, which will cause memory usage to grow. You should use
+ * SDL_WaitAndAcquireGPUSwapchainTexture() unless you know what you are doing
+ * with timing.
+ *
+ * The swapchain texture is managed by the implementation and must not be
+ * freed by the user. You MUST NOT call this function from any thread other
+ * than the one that created the window.
+ *
+ * \param command_buffer a command buffer.
+ * \param window a window that has been claimed.
+ * \param swapchain_texture a pointer filled in with a swapchain texture
+ * handle.
+ * \param swapchain_texture_width a pointer filled in with the swapchain
+ * texture width, may be NULL.
+ * \param swapchain_texture_height a pointer filled in with the swapchain
+ * texture height, may be NULL.
+ * \returns true on success, false on error; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called from the thread that
+ * created the window.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ClaimWindowForGPUDevice
+ * \sa SDL_SubmitGPUCommandBuffer
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ * \sa SDL_CancelGPUCommandBuffer
+ * \sa SDL_GetWindowSizeInPixels
+ * \sa SDL_WaitForGPUSwapchain
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_SetGPUAllowedFramesInFlight
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_AcquireGPUSwapchainTexture(
+ SDL_GPUCommandBuffer *command_buffer,
+ SDL_Window *window,
+ SDL_GPUTexture **swapchain_texture,
+ Uint32 *swapchain_texture_width,
+ Uint32 *swapchain_texture_height);
+
+/**
+ * Blocks the thread until a swapchain texture is available to be acquired.
+ *
+ * \param device a GPU context.
+ * \param window a window that has been claimed.
+ * \returns true on success, false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called from the thread that
+ * created the window.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AcquireGPUSwapchainTexture
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_SetGPUAllowedFramesInFlight
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUSwapchain(
+ SDL_GPUDevice *device,
+ SDL_Window *window);
+
+/**
+ * Blocks the thread until a swapchain texture is available to be acquired,
+ * and then acquires it.
+ *
+ * When a swapchain texture is acquired on a command buffer, it will
+ * automatically be submitted for presentation when the command buffer is
+ * submitted. The swapchain texture should only be referenced by the command
+ * buffer used to acquire it. It is an error to call
+ * SDL_CancelGPUCommandBuffer() after a swapchain texture is acquired.
+ *
+ * This function can fill the swapchain texture handle with NULL in certain
+ * cases, for example if the window is minimized. This is not an error. You
+ * should always make sure to check whether the pointer is NULL before
+ * actually using it.
+ *
+ * The swapchain texture is managed by the implementation and must not be
+ * freed by the user. You MUST NOT call this function from any thread other
+ * than the one that created the window.
+ *
+ * The swapchain texture is write-only and cannot be used as a sampler or for
+ * another reading operation.
+ *
+ * \param command_buffer a command buffer.
+ * \param window a window that has been claimed.
+ * \param swapchain_texture a pointer filled in with a swapchain texture
+ * handle.
+ * \param swapchain_texture_width a pointer filled in with the swapchain
+ * texture width, may be NULL.
+ * \param swapchain_texture_height a pointer filled in with the swapchain
+ * texture height, may be NULL.
+ * \returns true on success, false on error; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should only be called from the thread that
+ * created the window.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBuffer
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ * \sa SDL_AcquireGPUSwapchainTexture
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitAndAcquireGPUSwapchainTexture(
+ SDL_GPUCommandBuffer *command_buffer,
+ SDL_Window *window,
+ SDL_GPUTexture **swapchain_texture,
+ Uint32 *swapchain_texture_width,
+ Uint32 *swapchain_texture_height);
+
+/**
+ * Submits a command buffer so its commands can be processed on the GPU.
+ *
+ * It is invalid to use the command buffer after this is called.
+ *
+ * This must be called from the thread the command buffer was acquired on.
+ *
+ * All commands in the submission are guaranteed to begin executing before any
+ * command in a subsequent submission begins executing.
+ *
+ * \param command_buffer a command buffer.
+ * \returns true on success, false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AcquireGPUCommandBuffer
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_AcquireGPUSwapchainTexture
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SubmitGPUCommandBuffer(
+ SDL_GPUCommandBuffer *command_buffer);
+
+/**
+ * Submits a command buffer so its commands can be processed on the GPU, and
+ * acquires a fence associated with the command buffer.
+ *
+ * You must release this fence when it is no longer needed or it will cause a
+ * leak. It is invalid to use the command buffer after this is called.
+ *
+ * This must be called from the thread the command buffer was acquired on.
+ *
+ * All commands in the submission are guaranteed to begin executing before any
+ * command in a subsequent submission begins executing.
+ *
+ * \param command_buffer a command buffer.
+ * \returns a fence associated with the command buffer, or NULL on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AcquireGPUCommandBuffer
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_AcquireGPUSwapchainTexture
+ * \sa SDL_SubmitGPUCommandBuffer
+ * \sa SDL_ReleaseGPUFence
+ */
+extern SDL_DECLSPEC SDL_GPUFence * SDLCALL SDL_SubmitGPUCommandBufferAndAcquireFence(
+ SDL_GPUCommandBuffer *command_buffer);
+
+/**
+ * Cancels a command buffer.
+ *
+ * None of the enqueued commands are executed.
+ *
+ * It is an error to call this function after a swapchain texture has been
+ * acquired.
+ *
+ * This must be called from the thread the command buffer was acquired on.
+ *
+ * You must not reference the command buffer after calling this function.
+ *
+ * \param command_buffer a command buffer.
+ * \returns true on success, false on error; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WaitAndAcquireGPUSwapchainTexture
+ * \sa SDL_AcquireGPUCommandBuffer
+ * \sa SDL_AcquireGPUSwapchainTexture
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_CancelGPUCommandBuffer(
+ SDL_GPUCommandBuffer *command_buffer);
+
+/**
+ * Blocks the thread until the GPU is completely idle.
+ *
+ * \param device a GPU context.
+ * \returns true on success, false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_WaitForGPUFences
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUIdle(
+ SDL_GPUDevice *device);
+
+/**
+ * Blocks the thread until the given fences are signaled.
+ *
+ * \param device a GPU context.
+ * \param wait_all if 0, wait for any fence to be signaled, if 1, wait for all
+ * fences to be signaled.
+ * \param fences an array of fences to wait on.
+ * \param num_fences the number of fences in the fences array.
+ * \returns true on success, false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ * \sa SDL_WaitForGPUIdle
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUFences(
+ SDL_GPUDevice *device,
+ bool wait_all,
+ SDL_GPUFence *const *fences,
+ Uint32 num_fences);
+
+/**
+ * Checks the status of a fence.
+ *
+ * \param device a GPU context.
+ * \param fence a fence.
+ * \returns true if the fence is signaled, false if it is not.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_QueryGPUFence(
+ SDL_GPUDevice *device,
+ SDL_GPUFence *fence);
+
+/**
+ * Releases a fence obtained from SDL_SubmitGPUCommandBufferAndAcquireFence.
+ *
+ * You must not reference the fence after calling this function.
+ *
+ * \param device a GPU context.
+ * \param fence a fence.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SubmitGPUCommandBufferAndAcquireFence
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ReleaseGPUFence(
+ SDL_GPUDevice *device,
+ SDL_GPUFence *fence);
+
+/* Format Info */
+
+/**
+ * Obtains the texel block size for a texture format.
+ *
+ * \param format the texture format you want to know the texel size of.
+ * \returns the texel block size of the texture format.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_UploadToGPUTexture
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_GPUTextureFormatTexelBlockSize(
+ SDL_GPUTextureFormat format);
+
+/**
+ * Determines whether a texture format is supported for a given type and
+ * usage.
+ *
+ * \param device a GPU context.
+ * \param format the texture format to check.
+ * \param type the type of texture (2D, 3D, Cube).
+ * \param usage a bitmask of all usage scenarios to check.
+ * \returns whether the texture format is supported for this type and usage.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GPUTextureSupportsFormat(
+ SDL_GPUDevice *device,
+ SDL_GPUTextureFormat format,
+ SDL_GPUTextureType type,
+ SDL_GPUTextureUsageFlags usage);
+
+/**
+ * Determines if a sample count for a texture format is supported.
+ *
+ * \param device a GPU context.
+ * \param format the texture format to check.
+ * \param sample_count the sample count to check.
+ * \returns whether the sample count is supported for this texture format.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GPUTextureSupportsSampleCount(
+ SDL_GPUDevice *device,
+ SDL_GPUTextureFormat format,
+ SDL_GPUSampleCount sample_count);
+
+/**
+ * Calculate the size in bytes of a texture format with dimensions.
+ *
+ * \param format a texture format.
+ * \param width width in pixels.
+ * \param height height in pixels.
+ * \param depth_or_layer_count depth for 3D textures or layer count otherwise.
+ * \returns the size of a texture with this format and dimensions.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_CalculateGPUTextureFormatSize(
+ SDL_GPUTextureFormat format,
+ Uint32 width,
+ Uint32 height,
+ Uint32 depth_or_layer_count);
+
+#ifdef SDL_PLATFORM_GDK
+
+/**
+ * Call this to suspend GPU operation on Xbox when you receive the
+ * SDL_EVENT_DID_ENTER_BACKGROUND event.
+ *
+ * Do NOT call any SDL_GPU functions after calling this function! This must
+ * also be called before calling SDL_GDKSuspendComplete.
+ *
+ * \param device a GPU context.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddEventWatch
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendGPU(SDL_GPUDevice *device);
+
+/**
+ * Call this to resume GPU operation on Xbox when you receive the
+ * SDL_EVENT_WILL_ENTER_FOREGROUND event.
+ *
+ * When resuming, this function MUST be called before calling any other
+ * SDL_GPU functions.
+ *
+ * \param device a GPU context.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddEventWatch
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
+
+#endif /* SDL_PLATFORM_GDK */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include
+
+#endif /* SDL_gpu_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_guid.h b/vendored/SDL/include/SDL3/SDL_guid.h
new file mode 100644
index 0000000..312c42c
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_guid.h
@@ -0,0 +1,106 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: GUID */
+
+/**
+ * # CategoryGUID
+ *
+ * A GUID is a 128-bit value that represents something that is uniquely
+ * identifiable by this value: "globally unique."
+ *
+ * SDL provides functions to convert a GUID to/from a string.
+ */
+
+#ifndef SDL_guid_h_
+#define SDL_guid_h_
+
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An SDL_GUID is a 128-bit identifier for an input device that identifies
+ * that device across runs of SDL programs on the same platform.
+ *
+ * If the device is detached and then re-attached to a different port, or if
+ * the base system is rebooted, the device should still report the same GUID.
+ *
+ * GUIDs are as precise as possible but are not guaranteed to distinguish
+ * physically distinct but equivalent devices. For example, two game
+ * controllers from the same vendor with the same product ID and revision may
+ * have the same GUID.
+ *
+ * GUIDs may be platform-dependent (i.e., the same device may report different
+ * GUIDs on different operating systems).
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_GUID {
+ Uint8 data[16];
+} SDL_GUID;
+
+/* Function prototypes */
+
+/**
+ * Get an ASCII string representation for a given SDL_GUID.
+ *
+ * \param guid the SDL_GUID you wish to convert to string.
+ * \param pszGUID buffer in which to write the ASCII string.
+ * \param cbGUID the size of pszGUID, should be at least 33 bytes.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_StringToGUID
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID);
+
+/**
+ * Convert a GUID string into a SDL_GUID structure.
+ *
+ * Performs no error checking. If this function is given a string containing
+ * an invalid GUID, the function will silently succeed, but the GUID generated
+ * will not be useful.
+ *
+ * \param pchGUID string containing an ASCII representation of a GUID.
+ * \returns a SDL_GUID structure.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GUIDToString
+ */
+extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_StringToGUID(const char *pchGUID);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_guid_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_haptic.h b/vendored/SDL/include/SDL3/SDL_haptic.h
new file mode 100644
index 0000000..a45335b
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_haptic.h
@@ -0,0 +1,1441 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryHaptic
+ *
+ * The SDL haptic subsystem manages haptic (force feedback) devices.
+ *
+ * The basic usage is as follows:
+ *
+ * - Initialize the subsystem (SDL_INIT_HAPTIC).
+ * - Open a haptic device.
+ * - SDL_OpenHaptic() to open from index.
+ * - SDL_OpenHapticFromJoystick() to open from an existing joystick.
+ * - Create an effect (SDL_HapticEffect).
+ * - Upload the effect with SDL_CreateHapticEffect().
+ * - Run the effect with SDL_RunHapticEffect().
+ * - (optional) Free the effect with SDL_DestroyHapticEffect().
+ * - Close the haptic device with SDL_CloseHaptic().
+ *
+ * Simple rumble example:
+ *
+ * ```c
+ * SDL_Haptic *haptic = NULL;
+ *
+ * // Open the device
+ * SDL_HapticID *haptics = SDL_GetHaptics(NULL);
+ * if (haptics) {
+ * haptic = SDL_OpenHaptic(haptics[0]);
+ * SDL_free(haptics);
+ * }
+ * if (haptic == NULL)
+ * return;
+ *
+ * // Initialize simple rumble
+ * if (!SDL_InitHapticRumble(haptic))
+ * return;
+ *
+ * // Play effect at 50% strength for 2 seconds
+ * if (!SDL_PlayHapticRumble(haptic, 0.5, 2000))
+ * return;
+ * SDL_Delay(2000);
+ *
+ * // Clean up
+ * SDL_CloseHaptic(haptic);
+ * ```
+ *
+ * Complete example:
+ *
+ * ```c
+ * bool test_haptic(SDL_Joystick *joystick)
+ * {
+ * SDL_Haptic *haptic;
+ * SDL_HapticEffect effect;
+ * int effect_id;
+ *
+ * // Open the device
+ * haptic = SDL_OpenHapticFromJoystick(joystick);
+ * if (haptic == NULL) return false; // Most likely joystick isn't haptic
+ *
+ * // See if it can do sine waves
+ * if ((SDL_GetHapticFeatures(haptic) & SDL_HAPTIC_SINE)==0) {
+ * SDL_CloseHaptic(haptic); // No sine effect
+ * return false;
+ * }
+ *
+ * // Create the effect
+ * SDL_memset(&effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
+ * effect.type = SDL_HAPTIC_SINE;
+ * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
+ * effect.periodic.direction.dir[0] = 18000; // Force comes from south
+ * effect.periodic.period = 1000; // 1000 ms
+ * effect.periodic.magnitude = 20000; // 20000/32767 strength
+ * effect.periodic.length = 5000; // 5 seconds long
+ * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength
+ * effect.periodic.fade_length = 1000; // Takes 1 second to fade away
+ *
+ * // Upload the effect
+ * effect_id = SDL_CreateHapticEffect(haptic, &effect);
+ *
+ * // Test the effect
+ * SDL_RunHapticEffect(haptic, effect_id, 1);
+ * SDL_Delay(5000); // Wait for the effect to finish
+ *
+ * // We destroy the effect, although closing the device also does this
+ * SDL_DestroyHapticEffect(haptic, effect_id);
+ *
+ * // Close the device
+ * SDL_CloseHaptic(haptic);
+ *
+ * return true; // Success
+ * }
+ * ```
+ *
+ * Note that the SDL haptic subsystem is not thread-safe.
+ */
+
+
+#ifndef SDL_haptic_h_
+#define SDL_haptic_h_
+
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* FIXME:
+ *
+ * At the moment the magnitude variables are mixed between signed/unsigned, and
+ * it is also not made clear that ALL of those variables expect a max of 0x7FFF.
+ *
+ * Some platforms may have higher precision than that (Linux FF, Windows XInput)
+ * so we should fix the inconsistency in favor of higher possible precision,
+ * adjusting for platforms that use different scales.
+ * -flibit
+ */
+
+/**
+ * The haptic structure used to identify an SDL haptic.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenHaptic
+ * \sa SDL_OpenHapticFromJoystick
+ * \sa SDL_CloseHaptic
+ */
+typedef struct SDL_Haptic SDL_Haptic;
+
+
+/**
+ * \name Haptic features
+ *
+ * Different haptic features a device can have.
+ */
+/* @{ */
+
+/**
+ * \name Haptic effects
+ */
+/* @{ */
+
+/**
+ * Constant effect supported.
+ *
+ * Constant haptic effect.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticCondition
+ */
+#define SDL_HAPTIC_CONSTANT (1u<<0)
+
+/**
+ * Sine wave effect supported.
+ *
+ * Periodic haptic effect that simulates sine waves.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticPeriodic
+ */
+#define SDL_HAPTIC_SINE (1u<<1)
+
+/**
+ * Square wave effect supported.
+ *
+ * Periodic haptic effect that simulates square waves.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticPeriodic
+ */
+#define SDL_HAPTIC_SQUARE (1u<<2)
+
+/**
+ * Triangle wave effect supported.
+ *
+ * Periodic haptic effect that simulates triangular waves.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticPeriodic
+ */
+#define SDL_HAPTIC_TRIANGLE (1u<<3)
+
+/**
+ * Sawtoothup wave effect supported.
+ *
+ * Periodic haptic effect that simulates saw tooth up waves.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticPeriodic
+ */
+#define SDL_HAPTIC_SAWTOOTHUP (1u<<4)
+
+/**
+ * Sawtoothdown wave effect supported.
+ *
+ * Periodic haptic effect that simulates saw tooth down waves.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticPeriodic
+ */
+#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5)
+
+/**
+ * Ramp effect supported.
+ *
+ * Ramp haptic effect.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticRamp
+ */
+#define SDL_HAPTIC_RAMP (1u<<6)
+
+/**
+ * Spring effect supported - uses axes position.
+ *
+ * Condition haptic effect that simulates a spring. Effect is based on the
+ * axes position.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticCondition
+ */
+#define SDL_HAPTIC_SPRING (1u<<7)
+
+/**
+ * Damper effect supported - uses axes velocity.
+ *
+ * Condition haptic effect that simulates dampening. Effect is based on the
+ * axes velocity.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticCondition
+ */
+#define SDL_HAPTIC_DAMPER (1u<<8)
+
+/**
+ * Inertia effect supported - uses axes acceleration.
+ *
+ * Condition haptic effect that simulates inertia. Effect is based on the axes
+ * acceleration.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticCondition
+ */
+#define SDL_HAPTIC_INERTIA (1u<<9)
+
+/**
+ * Friction effect supported - uses axes movement.
+ *
+ * Condition haptic effect that simulates friction. Effect is based on the
+ * axes movement.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticCondition
+ */
+#define SDL_HAPTIC_FRICTION (1u<<10)
+
+/**
+ * Left/Right effect supported.
+ *
+ * Haptic effect for direct control over high/low frequency motors.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticLeftRight
+ */
+#define SDL_HAPTIC_LEFTRIGHT (1u<<11)
+
+/**
+ * Reserved for future use.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_HAPTIC_RESERVED1 (1u<<12)
+
+/**
+ * Reserved for future use.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_HAPTIC_RESERVED2 (1u<<13)
+
+/**
+ * Reserved for future use.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_HAPTIC_RESERVED3 (1u<<14)
+
+/**
+ * Custom effect is supported.
+ *
+ * User defined custom haptic effect.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_HAPTIC_CUSTOM (1u<<15)
+
+/* @} *//* Haptic effects */
+
+/* These last few are features the device has, not effects */
+
+/**
+ * Device can set global gain.
+ *
+ * Device supports setting the global gain.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetHapticGain
+ */
+#define SDL_HAPTIC_GAIN (1u<<16)
+
+/**
+ * Device can set autocenter.
+ *
+ * Device supports setting autocenter.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetHapticAutocenter
+ */
+#define SDL_HAPTIC_AUTOCENTER (1u<<17)
+
+/**
+ * Device can be queried for effect status.
+ *
+ * Device supports querying effect status.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticEffectStatus
+ */
+#define SDL_HAPTIC_STATUS (1u<<18)
+
+/**
+ * Device can be paused.
+ *
+ * Devices supports being paused.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_PauseHaptic
+ * \sa SDL_ResumeHaptic
+ */
+#define SDL_HAPTIC_PAUSE (1u<<19)
+
+
+/**
+ * \name Direction encodings
+ */
+/* @{ */
+
+/**
+ * Uses polar coordinates for the direction.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticDirection
+ */
+#define SDL_HAPTIC_POLAR 0
+
+/**
+ * Uses cartesian coordinates for the direction.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticDirection
+ */
+#define SDL_HAPTIC_CARTESIAN 1
+
+/**
+ * Uses spherical coordinates for the direction.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticDirection
+ */
+#define SDL_HAPTIC_SPHERICAL 2
+
+/**
+ * Use this value to play an effect on the steering wheel axis.
+ *
+ * This provides better compatibility across platforms and devices as SDL will
+ * guess the correct axis.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticDirection
+ */
+#define SDL_HAPTIC_STEERING_AXIS 3
+
+/* @} *//* Direction encodings */
+
+/* @} *//* Haptic features */
+
+/*
+ * Misc defines.
+ */
+
+/**
+ * Used to play a device an infinite number of times.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_RunHapticEffect
+ */
+#define SDL_HAPTIC_INFINITY 4294967295U
+
+
+/**
+ * Structure that represents a haptic direction.
+ *
+ * This is the direction where the force comes from, instead of the direction
+ * in which the force is exerted.
+ *
+ * Directions can be specified by:
+ *
+ * - SDL_HAPTIC_POLAR : Specified by polar coordinates.
+ * - SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates.
+ * - SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates.
+ *
+ * Cardinal directions of the haptic device are relative to the positioning of
+ * the device. North is considered to be away from the user.
+ *
+ * The following diagram represents the cardinal directions:
+ *
+ * ```
+ * .--.
+ * |__| .-------.
+ * |=.| |.-----.|
+ * |--| || ||
+ * | | |'-----'|
+ * |__|~')_____('
+ * [ COMPUTER ]
+ *
+ *
+ * North (0,-1)
+ * ^
+ * |
+ * |
+ * (-1,0) West <----[ HAPTIC ]----> East (1,0)
+ * |
+ * |
+ * v
+ * South (0,1)
+ *
+ *
+ * [ USER ]
+ * \|||/
+ * (o o)
+ * ---ooO-(_)-Ooo---
+ * ```
+ *
+ * If type is SDL_HAPTIC_POLAR, direction is encoded by hundredths of a degree
+ * starting north and turning clockwise. SDL_HAPTIC_POLAR only uses the first
+ * `dir` parameter. The cardinal directions would be:
+ *
+ * - North: 0 (0 degrees)
+ * - East: 9000 (90 degrees)
+ * - South: 18000 (180 degrees)
+ * - West: 27000 (270 degrees)
+ *
+ * If type is SDL_HAPTIC_CARTESIAN, direction is encoded by three positions (X
+ * axis, Y axis and Z axis (with 3 axes)). SDL_HAPTIC_CARTESIAN uses the first
+ * three `dir` parameters. The cardinal directions would be:
+ *
+ * - North: 0,-1, 0
+ * - East: 1, 0, 0
+ * - South: 0, 1, 0
+ * - West: -1, 0, 0
+ *
+ * The Z axis represents the height of the effect if supported, otherwise it's
+ * unused. In cartesian encoding (1, 2) would be the same as (2, 4), you can
+ * use any multiple you want, only the direction matters.
+ *
+ * If type is SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. The
+ * first two `dir` parameters are used. The `dir` parameters are as follows
+ * (all values are in hundredths of degrees):
+ *
+ * - Degrees from (1, 0) rotated towards (0, 1).
+ * - Degrees towards (0, 0, 1) (device needs at least 3 axes).
+ *
+ * Example of force coming from the south with all encodings (force coming
+ * from the south means the user will have to pull the stick to counteract):
+ *
+ * ```c
+ * SDL_HapticDirection direction;
+ *
+ * // Cartesian directions
+ * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding.
+ * direction.dir[0] = 0; // X position
+ * direction.dir[1] = 1; // Y position
+ * // Assuming the device has 2 axes, we don't need to specify third parameter.
+ *
+ * // Polar directions
+ * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
+ * direction.dir[0] = 18000; // Polar only uses first parameter
+ *
+ * // Spherical coordinates
+ * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding
+ * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters.
+ * ```
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_POLAR
+ * \sa SDL_HAPTIC_CARTESIAN
+ * \sa SDL_HAPTIC_SPHERICAL
+ * \sa SDL_HAPTIC_STEERING_AXIS
+ * \sa SDL_HapticEffect
+ * \sa SDL_GetNumHapticAxes
+ */
+typedef struct SDL_HapticDirection
+{
+ Uint8 type; /**< The type of encoding. */
+ Sint32 dir[3]; /**< The encoded direction. */
+} SDL_HapticDirection;
+
+
+/**
+ * A structure containing a template for a Constant effect.
+ *
+ * This struct is exclusively for the SDL_HAPTIC_CONSTANT effect.
+ *
+ * A constant effect applies a constant force in the specified direction to
+ * the joystick.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_CONSTANT
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticConstant
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_CONSTANT */
+ SDL_HapticDirection direction; /**< Direction of the effect. */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect. */
+ Uint16 delay; /**< Delay before starting the effect. */
+
+ /* Trigger */
+ Uint16 button; /**< Button that triggers the effect. */
+ Uint16 interval; /**< How soon it can be triggered again after button. */
+
+ /* Constant */
+ Sint16 level; /**< Strength of the constant effect. */
+
+ /* Envelope */
+ Uint16 attack_length; /**< Duration of the attack. */
+ Uint16 attack_level; /**< Level at the start of the attack. */
+ Uint16 fade_length; /**< Duration of the fade. */
+ Uint16 fade_level; /**< Level at the end of the fade. */
+} SDL_HapticConstant;
+
+/**
+ * A structure containing a template for a Periodic effect.
+ *
+ * The struct handles the following effects:
+ *
+ * - SDL_HAPTIC_SINE
+ * - SDL_HAPTIC_SQUARE
+ * - SDL_HAPTIC_TRIANGLE
+ * - SDL_HAPTIC_SAWTOOTHUP
+ * - SDL_HAPTIC_SAWTOOTHDOWN
+ *
+ * A periodic effect consists in a wave-shaped effect that repeats itself over
+ * time. The type determines the shape of the wave and the parameters
+ * determine the dimensions of the wave.
+ *
+ * Phase is given by hundredth of a degree meaning that giving the phase a
+ * value of 9000 will displace it 25% of its period. Here are sample values:
+ *
+ * - 0: No phase displacement.
+ * - 9000: Displaced 25% of its period.
+ * - 18000: Displaced 50% of its period.
+ * - 27000: Displaced 75% of its period.
+ * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred.
+ *
+ * Examples:
+ *
+ * ```
+ * SDL_HAPTIC_SINE
+ * __ __ __ __
+ * / \ / \ / \ /
+ * / \__/ \__/ \__/
+ *
+ * SDL_HAPTIC_SQUARE
+ * __ __ __ __ __
+ * | | | | | | | | | |
+ * | |__| |__| |__| |__| |
+ *
+ * SDL_HAPTIC_TRIANGLE
+ * /\ /\ /\ /\ /\
+ * / \ / \ / \ / \ /
+ * / \/ \/ \/ \/
+ *
+ * SDL_HAPTIC_SAWTOOTHUP
+ * /| /| /| /| /| /| /|
+ * / | / | / | / | / | / | / |
+ * / |/ |/ |/ |/ |/ |/ |
+ *
+ * SDL_HAPTIC_SAWTOOTHDOWN
+ * \ |\ |\ |\ |\ |\ |\ |
+ * \ | \ | \ | \ | \ | \ | \ |
+ * \| \| \| \| \| \| \|
+ * ```
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_SINE
+ * \sa SDL_HAPTIC_SQUARE
+ * \sa SDL_HAPTIC_TRIANGLE
+ * \sa SDL_HAPTIC_SAWTOOTHUP
+ * \sa SDL_HAPTIC_SAWTOOTHDOWN
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticPeriodic
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_SINE, SDL_HAPTIC_SQUARE
+ SDL_HAPTIC_TRIANGLE, SDL_HAPTIC_SAWTOOTHUP or
+ SDL_HAPTIC_SAWTOOTHDOWN */
+ SDL_HapticDirection direction; /**< Direction of the effect. */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect. */
+ Uint16 delay; /**< Delay before starting the effect. */
+
+ /* Trigger */
+ Uint16 button; /**< Button that triggers the effect. */
+ Uint16 interval; /**< How soon it can be triggered again after button. */
+
+ /* Periodic */
+ Uint16 period; /**< Period of the wave. */
+ Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */
+ Sint16 offset; /**< Mean value of the wave. */
+ Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */
+
+ /* Envelope */
+ Uint16 attack_length; /**< Duration of the attack. */
+ Uint16 attack_level; /**< Level at the start of the attack. */
+ Uint16 fade_length; /**< Duration of the fade. */
+ Uint16 fade_level; /**< Level at the end of the fade. */
+} SDL_HapticPeriodic;
+
+/**
+ * A structure containing a template for a Condition effect.
+ *
+ * The struct handles the following effects:
+ *
+ * - SDL_HAPTIC_SPRING: Effect based on axes position.
+ * - SDL_HAPTIC_DAMPER: Effect based on axes velocity.
+ * - SDL_HAPTIC_INERTIA: Effect based on axes acceleration.
+ * - SDL_HAPTIC_FRICTION: Effect based on axes movement.
+ *
+ * Direction is handled by condition internals instead of a direction member.
+ * The condition effect specific members have three parameters. The first
+ * refers to the X axis, the second refers to the Y axis and the third refers
+ * to the Z axis. The right terms refer to the positive side of the axis and
+ * the left terms refer to the negative side of the axis. Please refer to the
+ * SDL_HapticDirection diagram for which side is positive and which is
+ * negative.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticDirection
+ * \sa SDL_HAPTIC_SPRING
+ * \sa SDL_HAPTIC_DAMPER
+ * \sa SDL_HAPTIC_INERTIA
+ * \sa SDL_HAPTIC_FRICTION
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticCondition
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER,
+ SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION */
+ SDL_HapticDirection direction; /**< Direction of the effect. */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect. */
+ Uint16 delay; /**< Delay before starting the effect. */
+
+ /* Trigger */
+ Uint16 button; /**< Button that triggers the effect. */
+ Uint16 interval; /**< How soon it can be triggered again after button. */
+
+ /* Condition */
+ Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */
+ Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */
+ Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */
+ Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */
+ Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */
+ Sint16 center[3]; /**< Position of the dead zone. */
+} SDL_HapticCondition;
+
+/**
+ * A structure containing a template for a Ramp effect.
+ *
+ * This struct is exclusively for the SDL_HAPTIC_RAMP effect.
+ *
+ * The ramp effect starts at start strength and ends at end strength. It
+ * augments in linear fashion. If you use attack and fade with a ramp the
+ * effects get added to the ramp effect making the effect become quadratic
+ * instead of linear.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_RAMP
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticRamp
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_RAMP */
+ SDL_HapticDirection direction; /**< Direction of the effect. */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect. */
+ Uint16 delay; /**< Delay before starting the effect. */
+
+ /* Trigger */
+ Uint16 button; /**< Button that triggers the effect. */
+ Uint16 interval; /**< How soon it can be triggered again after button. */
+
+ /* Ramp */
+ Sint16 start; /**< Beginning strength level. */
+ Sint16 end; /**< Ending strength level. */
+
+ /* Envelope */
+ Uint16 attack_length; /**< Duration of the attack. */
+ Uint16 attack_level; /**< Level at the start of the attack. */
+ Uint16 fade_length; /**< Duration of the fade. */
+ Uint16 fade_level; /**< Level at the end of the fade. */
+} SDL_HapticRamp;
+
+/**
+ * A structure containing a template for a Left/Right effect.
+ *
+ * This struct is exclusively for the SDL_HAPTIC_LEFTRIGHT effect.
+ *
+ * The Left/Right effect is used to explicitly control the large and small
+ * motors, commonly found in modern game controllers. The small (right) motor
+ * is high frequency, and the large (left) motor is low frequency.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_LEFTRIGHT
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticLeftRight
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_LEFTRIGHT */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect in milliseconds. */
+
+ /* Rumble */
+ Uint16 large_magnitude; /**< Control of the large controller motor. */
+ Uint16 small_magnitude; /**< Control of the small controller motor. */
+} SDL_HapticLeftRight;
+
+/**
+ * A structure containing a template for the SDL_HAPTIC_CUSTOM effect.
+ *
+ * This struct is exclusively for the SDL_HAPTIC_CUSTOM effect.
+ *
+ * A custom force feedback effect is much like a periodic effect, where the
+ * application can define its exact shape. You will have to allocate the data
+ * yourself. Data should consist of channels * samples Uint16 samples.
+ *
+ * If channels is one, the effect is rotated using the defined direction.
+ * Otherwise it uses the samples in data for the different axes.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HAPTIC_CUSTOM
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticCustom
+{
+ /* Header */
+ Uint16 type; /**< SDL_HAPTIC_CUSTOM */
+ SDL_HapticDirection direction; /**< Direction of the effect. */
+
+ /* Replay */
+ Uint32 length; /**< Duration of the effect. */
+ Uint16 delay; /**< Delay before starting the effect. */
+
+ /* Trigger */
+ Uint16 button; /**< Button that triggers the effect. */
+ Uint16 interval; /**< How soon it can be triggered again after button. */
+
+ /* Custom */
+ Uint8 channels; /**< Axes to use, minimum of one. */
+ Uint16 period; /**< Sample periods. */
+ Uint16 samples; /**< Amount of samples. */
+ Uint16 *data; /**< Should contain channels*samples items. */
+
+ /* Envelope */
+ Uint16 attack_length; /**< Duration of the attack. */
+ Uint16 attack_level; /**< Level at the start of the attack. */
+ Uint16 fade_length; /**< Duration of the fade. */
+ Uint16 fade_level; /**< Level at the end of the fade. */
+} SDL_HapticCustom;
+
+/**
+ * The generic template for any haptic effect.
+ *
+ * All values max at 32767 (0x7FFF). Signed values also can be negative. Time
+ * values unless specified otherwise are in milliseconds.
+ *
+ * You can also pass SDL_HAPTIC_INFINITY to length instead of a 0-32767 value.
+ * Neither delay, interval, attack_length nor fade_length support
+ * SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends.
+ *
+ * Additionally, the SDL_HAPTIC_RAMP effect does not support a duration of
+ * SDL_HAPTIC_INFINITY.
+ *
+ * Button triggers may not be supported on all devices, it is advised to not
+ * use them if possible. Buttons start at index 1 instead of index 0 like the
+ * joystick.
+ *
+ * If both attack_length and fade_level are 0, the envelope is not used,
+ * otherwise both values are used.
+ *
+ * Common parts:
+ *
+ * ```c
+ * // Replay - All effects have this
+ * Uint32 length; // Duration of effect (ms).
+ * Uint16 delay; // Delay before starting effect.
+ *
+ * // Trigger - All effects have this
+ * Uint16 button; // Button that triggers effect.
+ * Uint16 interval; // How soon before effect can be triggered again.
+ *
+ * // Envelope - All effects except condition effects have this
+ * Uint16 attack_length; // Duration of the attack (ms).
+ * Uint16 attack_level; // Level at the start of the attack.
+ * Uint16 fade_length; // Duration of the fade out (ms).
+ * Uint16 fade_level; // Level at the end of the fade.
+ * ```
+ *
+ * Here we have an example of a constant effect evolution in time:
+ *
+ * ```
+ * Strength
+ * ^
+ * |
+ * | effect level --> _________________
+ * | / \
+ * | / \
+ * | / \
+ * | / \
+ * | attack_level --> | \
+ * | | | <--- fade_level
+ * |
+ * +--------------------------------------------------> Time
+ * [--] [---]
+ * attack_length fade_length
+ *
+ * [------------------][-----------------------]
+ * delay length
+ * ```
+ *
+ * Note either the attack_level or the fade_level may be above the actual
+ * effect level.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticConstant
+ * \sa SDL_HapticPeriodic
+ * \sa SDL_HapticCondition
+ * \sa SDL_HapticRamp
+ * \sa SDL_HapticLeftRight
+ * \sa SDL_HapticCustom
+ */
+typedef union SDL_HapticEffect
+{
+ /* Common for all force feedback effects */
+ Uint16 type; /**< Effect type. */
+ SDL_HapticConstant constant; /**< Constant effect. */
+ SDL_HapticPeriodic periodic; /**< Periodic effect. */
+ SDL_HapticCondition condition; /**< Condition effect. */
+ SDL_HapticRamp ramp; /**< Ramp effect. */
+ SDL_HapticLeftRight leftright; /**< Left/Right effect. */
+ SDL_HapticCustom custom; /**< Custom effect. */
+} SDL_HapticEffect;
+
+/**
+ * This is a unique ID for a haptic device for the time it is connected to the
+ * system, and is never reused for the lifetime of the application.
+ *
+ * If the haptic device is disconnected and reconnected, it will get a new ID.
+ *
+ * The value 0 is an invalid ID.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef Uint32 SDL_HapticID;
+
+
+/* Function prototypes */
+
+/**
+ * Get a list of currently connected haptic devices.
+ *
+ * \param count a pointer filled in with the number of haptic devices
+ * returned, may be NULL.
+ * \returns a 0 terminated array of haptic device instance IDs or NULL on
+ * failure; call SDL_GetError() for more information. This should be
+ * freed with SDL_free() when it is no longer needed.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenHaptic
+ */
+extern SDL_DECLSPEC SDL_HapticID * SDLCALL SDL_GetHaptics(int *count);
+
+/**
+ * Get the implementation dependent name of a haptic device.
+ *
+ * This can be called before any haptic devices are opened.
+ *
+ * \param instance_id the haptic device instance ID.
+ * \returns the name of the selected haptic device. If no name can be found,
+ * this function returns NULL; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticName
+ * \sa SDL_OpenHaptic
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetHapticNameForID(SDL_HapticID instance_id);
+
+/**
+ * Open a haptic device for use.
+ *
+ * The index passed as an argument refers to the N'th haptic device on this
+ * system.
+ *
+ * When opening a haptic device, its gain will be set to maximum and
+ * autocenter will be disabled. To modify these values use SDL_SetHapticGain()
+ * and SDL_SetHapticAutocenter().
+ *
+ * \param instance_id the haptic device instance ID.
+ * \returns the device identifier or NULL on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseHaptic
+ * \sa SDL_GetHaptics
+ * \sa SDL_OpenHapticFromJoystick
+ * \sa SDL_OpenHapticFromMouse
+ * \sa SDL_SetHapticAutocenter
+ * \sa SDL_SetHapticGain
+ */
+extern SDL_DECLSPEC SDL_Haptic * SDLCALL SDL_OpenHaptic(SDL_HapticID instance_id);
+
+
+/**
+ * Get the SDL_Haptic associated with an instance ID, if it has been opened.
+ *
+ * \param instance_id the instance ID to get the SDL_Haptic for.
+ * \returns an SDL_Haptic on success or NULL on failure or if it hasn't been
+ * opened yet; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_Haptic * SDLCALL SDL_GetHapticFromID(SDL_HapticID instance_id);
+
+/**
+ * Get the instance ID of an opened haptic device.
+ *
+ * \param haptic the SDL_Haptic device to query.
+ * \returns the instance ID of the specified haptic device on success or 0 on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_HapticID SDLCALL SDL_GetHapticID(SDL_Haptic *haptic);
+
+/**
+ * Get the implementation dependent name of a haptic device.
+ *
+ * \param haptic the SDL_Haptic obtained from SDL_OpenJoystick().
+ * \returns the name of the selected haptic device. If no name can be found,
+ * this function returns NULL; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticNameForID
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetHapticName(SDL_Haptic *haptic);
+
+/**
+ * Query whether or not the current mouse has haptic capabilities.
+ *
+ * \returns true if the mouse is haptic or false if it isn't.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenHapticFromMouse
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsMouseHaptic(void);
+
+/**
+ * Try to open a haptic device from the current mouse.
+ *
+ * \returns the haptic device identifier or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseHaptic
+ * \sa SDL_IsMouseHaptic
+ */
+extern SDL_DECLSPEC SDL_Haptic * SDLCALL SDL_OpenHapticFromMouse(void);
+
+/**
+ * Query if a joystick has haptic features.
+ *
+ * \param joystick the SDL_Joystick to test for haptic capabilities.
+ * \returns true if the joystick is haptic or false if it isn't.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenHapticFromJoystick
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsJoystickHaptic(SDL_Joystick *joystick);
+
+/**
+ * Open a haptic device for use from a joystick device.
+ *
+ * You must still close the haptic device separately. It will not be closed
+ * with the joystick.
+ *
+ * When opened from a joystick you should first close the haptic device before
+ * closing the joystick device. If not, on some implementations the haptic
+ * device will also get unallocated and you'll be unable to use force feedback
+ * on that device.
+ *
+ * \param joystick the SDL_Joystick to create a haptic device from.
+ * \returns a valid haptic device identifier on success or NULL on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CloseHaptic
+ * \sa SDL_IsJoystickHaptic
+ */
+extern SDL_DECLSPEC SDL_Haptic * SDLCALL SDL_OpenHapticFromJoystick(SDL_Joystick *joystick);
+
+/**
+ * Close a haptic device previously opened with SDL_OpenHaptic().
+ *
+ * \param haptic the SDL_Haptic device to close.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_OpenHaptic
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_CloseHaptic(SDL_Haptic *haptic);
+
+/**
+ * Get the number of effects a haptic device can store.
+ *
+ * On some platforms this isn't fully supported, and therefore is an
+ * approximation. Always check to see if your created effect was actually
+ * created and do not rely solely on SDL_GetMaxHapticEffects().
+ *
+ * \param haptic the SDL_Haptic device to query.
+ * \returns the number of effects the haptic device can store or a negative
+ * error code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetMaxHapticEffectsPlaying
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetMaxHapticEffects(SDL_Haptic *haptic);
+
+/**
+ * Get the number of effects a haptic device can play at the same time.
+ *
+ * This is not supported on all platforms, but will always return a value.
+ *
+ * \param haptic the SDL_Haptic device to query maximum playing effects.
+ * \returns the number of effects the haptic device can play at the same time
+ * or -1 on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetMaxHapticEffects
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetMaxHapticEffectsPlaying(SDL_Haptic *haptic);
+
+/**
+ * Get the haptic device's supported features in bitwise manner.
+ *
+ * \param haptic the SDL_Haptic device to query.
+ * \returns a list of supported haptic features in bitwise manner (OR'd), or 0
+ * on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_HapticEffectSupported
+ * \sa SDL_GetMaxHapticEffects
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetHapticFeatures(SDL_Haptic *haptic);
+
+/**
+ * Get the number of haptic axes the device has.
+ *
+ * The number of haptic axes might be useful if working with the
+ * SDL_HapticDirection effect.
+ *
+ * \param haptic the SDL_Haptic device to query.
+ * \returns the number of axes on success or -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetNumHapticAxes(SDL_Haptic *haptic);
+
+/**
+ * Check to see if an effect is supported by a haptic device.
+ *
+ * \param haptic the SDL_Haptic device to query.
+ * \param effect the desired effect to query.
+ * \returns true if the effect is supported or false if it isn't.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateHapticEffect
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HapticEffectSupported(SDL_Haptic *haptic, const SDL_HapticEffect *effect);
+
+/**
+ * Create a new haptic effect on a specified device.
+ *
+ * \param haptic an SDL_Haptic device to create the effect on.
+ * \param effect an SDL_HapticEffect structure containing the properties of
+ * the effect to create.
+ * \returns the ID of the effect on success or -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_DestroyHapticEffect
+ * \sa SDL_RunHapticEffect
+ * \sa SDL_UpdateHapticEffect
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_CreateHapticEffect(SDL_Haptic *haptic, const SDL_HapticEffect *effect);
+
+/**
+ * Update the properties of an effect.
+ *
+ * Can be used dynamically, although behavior when dynamically changing
+ * direction may be strange. Specifically the effect may re-upload itself and
+ * start playing from the start. You also cannot change the type either when
+ * running SDL_UpdateHapticEffect().
+ *
+ * \param haptic the SDL_Haptic device that has the effect.
+ * \param effect the identifier of the effect to update.
+ * \param data an SDL_HapticEffect structure containing the new effect
+ * properties to use.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateHapticEffect
+ * \sa SDL_RunHapticEffect
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_UpdateHapticEffect(SDL_Haptic *haptic, int effect, const SDL_HapticEffect *data);
+
+/**
+ * Run the haptic effect on its associated haptic device.
+ *
+ * To repeat the effect over and over indefinitely, set `iterations` to
+ * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make
+ * one instance of the effect last indefinitely (so the effect does not fade),
+ * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY`
+ * instead.
+ *
+ * \param haptic the SDL_Haptic device to run the effect on.
+ * \param effect the ID of the haptic effect to run.
+ * \param iterations the number of iterations to run the effect; use
+ * `SDL_HAPTIC_INFINITY` to repeat forever.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticEffectStatus
+ * \sa SDL_StopHapticEffect
+ * \sa SDL_StopHapticEffects
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RunHapticEffect(SDL_Haptic *haptic, int effect, Uint32 iterations);
+
+/**
+ * Stop the haptic effect on its associated haptic device.
+ *
+ * \param haptic the SDL_Haptic device to stop the effect on.
+ * \param effect the ID of the haptic effect to stop.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RunHapticEffect
+ * \sa SDL_StopHapticEffects
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticEffect(SDL_Haptic *haptic, int effect);
+
+/**
+ * Destroy a haptic effect on the device.
+ *
+ * This will stop the effect if it's running. Effects are automatically
+ * destroyed when the device is closed.
+ *
+ * \param haptic the SDL_Haptic device to destroy the effect on.
+ * \param effect the ID of the haptic effect to destroy.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_CreateHapticEffect
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_DestroyHapticEffect(SDL_Haptic *haptic, int effect);
+
+/**
+ * Get the status of the current effect on the specified haptic device.
+ *
+ * Device must support the SDL_HAPTIC_STATUS feature.
+ *
+ * \param haptic the SDL_Haptic device to query for the effect status on.
+ * \param effect the ID of the haptic effect to query its status.
+ * \returns true if it is playing, false if it isn't playing or haptic status
+ * isn't supported.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetHapticEffectStatus(SDL_Haptic *haptic, int effect);
+
+/**
+ * Set the global gain of the specified haptic device.
+ *
+ * Device must support the SDL_HAPTIC_GAIN feature.
+ *
+ * The user may specify the maximum gain by setting the environment variable
+ * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to
+ * SDL_SetHapticGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the
+ * maximum.
+ *
+ * \param haptic the SDL_Haptic device to set the gain on.
+ * \param gain value to set the gain to, should be between 0 and 100 (0 -
+ * 100).
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetHapticGain(SDL_Haptic *haptic, int gain);
+
+/**
+ * Set the global autocenter of the device.
+ *
+ * Autocenter should be between 0 and 100. Setting it to 0 will disable
+ * autocentering.
+ *
+ * Device must support the SDL_HAPTIC_AUTOCENTER feature.
+ *
+ * \param haptic the SDL_Haptic device to set autocentering on.
+ * \param autocenter value to set autocenter to (0-100).
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHapticFeatures
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetHapticAutocenter(SDL_Haptic *haptic, int autocenter);
+
+/**
+ * Pause a haptic device.
+ *
+ * Device must support the `SDL_HAPTIC_PAUSE` feature. Call SDL_ResumeHaptic()
+ * to resume playback.
+ *
+ * Do not modify the effects nor add new ones while the device is paused. That
+ * can cause all sorts of weird errors.
+ *
+ * \param haptic the SDL_Haptic device to pause.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ResumeHaptic
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PauseHaptic(SDL_Haptic *haptic);
+
+/**
+ * Resume a haptic device.
+ *
+ * Call to unpause after SDL_PauseHaptic().
+ *
+ * \param haptic the SDL_Haptic device to unpause.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PauseHaptic
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ResumeHaptic(SDL_Haptic *haptic);
+
+/**
+ * Stop all the currently playing effects on a haptic device.
+ *
+ * \param haptic the SDL_Haptic device to stop.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RunHapticEffect
+ * \sa SDL_StopHapticEffects
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticEffects(SDL_Haptic *haptic);
+
+/**
+ * Check whether rumble is supported on a haptic device.
+ *
+ * \param haptic haptic device to check for rumble support.
+ * \returns true if the effect is supported or false if it isn't.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_InitHapticRumble
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_HapticRumbleSupported(SDL_Haptic *haptic);
+
+/**
+ * Initialize a haptic device for simple rumble playback.
+ *
+ * \param haptic the haptic device to initialize for simple rumble playback.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PlayHapticRumble
+ * \sa SDL_StopHapticRumble
+ * \sa SDL_HapticRumbleSupported
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_InitHapticRumble(SDL_Haptic *haptic);
+
+/**
+ * Run a simple rumble effect on a haptic device.
+ *
+ * \param haptic the haptic device to play the rumble effect on.
+ * \param strength strength of the rumble to play as a 0-1 float value.
+ * \param length length of the rumble to play in milliseconds.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_InitHapticRumble
+ * \sa SDL_StopHapticRumble
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PlayHapticRumble(SDL_Haptic *haptic, float strength, Uint32 length);
+
+/**
+ * Stop the simple rumble on a haptic device.
+ *
+ * \param haptic the haptic device to stop the rumble effect on.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_PlayHapticRumble
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticRumble(SDL_Haptic *haptic);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_haptic_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_hidapi.h b/vendored/SDL/include/SDL3/SDL_hidapi.h
new file mode 100644
index 0000000..131b037
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_hidapi.h
@@ -0,0 +1,552 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: HIDAPI */
+
+/**
+ * # CategoryHIDAPI
+ *
+ * Header file for SDL HIDAPI functions.
+ *
+ * This is an adaptation of the original HIDAPI interface by Alan Ott, and
+ * includes source code licensed under the following license:
+ *
+ * ```
+ * HIDAPI - Multi-Platform library for
+ * communication with HID devices.
+ *
+ * Copyright 2009, Alan Ott, Signal 11 Software.
+ * All Rights Reserved.
+ *
+ * This software may be used by anyone for any reason so
+ * long as the copyright notice in the source files
+ * remains intact.
+ * ```
+ *
+ * (Note that this license is the same as item three of SDL's zlib license, so
+ * it adds no new requirements on the user.)
+ *
+ * If you would like a version of SDL without this code, you can build SDL
+ * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for
+ * example on iOS or tvOS to avoid a dependency on the CoreBluetooth
+ * framework.
+ */
+
+#ifndef SDL_hidapi_h_
+#define SDL_hidapi_h_
+
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An opaque handle representing an open HID device.
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_hid_device SDL_hid_device;
+
+/**
+ * HID underlying bus types.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_hid_bus_type {
+ /** Unknown bus type */
+ SDL_HID_API_BUS_UNKNOWN = 0x00,
+
+ /** USB bus
+ Specifications:
+ https://usb.org/hid */
+ SDL_HID_API_BUS_USB = 0x01,
+
+ /** Bluetooth or Bluetooth LE bus
+ Specifications:
+ https://www.bluetooth.com/specifications/specs/human-interface-device-profile-1-1-1/
+ https://www.bluetooth.com/specifications/specs/hid-service-1-0/
+ https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/ */
+ SDL_HID_API_BUS_BLUETOOTH = 0x02,
+
+ /** I2C bus
+ Specifications:
+ https://docs.microsoft.com/previous-versions/windows/hardware/design/dn642101(v=vs.85) */
+ SDL_HID_API_BUS_I2C = 0x03,
+
+ /** SPI bus
+ Specifications:
+ https://www.microsoft.com/download/details.aspx?id=103325 */
+ SDL_HID_API_BUS_SPI = 0x04
+
+} SDL_hid_bus_type;
+
+/** hidapi info structure */
+
+/**
+ * Information about a connected HID device
+ *
+ * \since This struct is available since SDL 3.2.0.
+ */
+typedef struct SDL_hid_device_info
+{
+ /** Platform-specific device path */
+ char *path;
+ /** Device Vendor ID */
+ unsigned short vendor_id;
+ /** Device Product ID */
+ unsigned short product_id;
+ /** Serial Number */
+ wchar_t *serial_number;
+ /** Device Release Number in binary-coded decimal,
+ also known as Device Version Number */
+ unsigned short release_number;
+ /** Manufacturer String */
+ wchar_t *manufacturer_string;
+ /** Product string */
+ wchar_t *product_string;
+ /** Usage Page for this Device/Interface
+ (Windows/Mac/hidraw only) */
+ unsigned short usage_page;
+ /** Usage for this Device/Interface
+ (Windows/Mac/hidraw only) */
+ unsigned short usage;
+ /** The USB interface which this logical device
+ represents.
+
+ Valid only if the device is a USB HID device.
+ Set to -1 in all other cases.
+ */
+ int interface_number;
+
+ /** Additional information about the USB interface.
+ Valid on libusb and Android implementations. */
+ int interface_class;
+ int interface_subclass;
+ int interface_protocol;
+
+ /** Underlying bus type */
+ SDL_hid_bus_type bus_type;
+
+ /** Pointer to the next device */
+ struct SDL_hid_device_info *next;
+
+} SDL_hid_device_info;
+
+
+/**
+ * Initialize the HIDAPI library.
+ *
+ * This function initializes the HIDAPI library. Calling it is not strictly
+ * necessary, as it will be called automatically by SDL_hid_enumerate() and
+ * any of the SDL_hid_open_*() functions if it is needed. This function should
+ * be called at the beginning of execution however, if there is a chance of
+ * HIDAPI handles being opened by different threads simultaneously.
+ *
+ * Each call to this function should have a matching call to SDL_hid_exit()
+ *
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_hid_exit
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_init(void);
+
+/**
+ * Finalize the HIDAPI library.
+ *
+ * This function frees all of the static data associated with HIDAPI. It
+ * should be called at the end of execution to avoid memory leaks.
+ *
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_hid_init
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_exit(void);
+
+/**
+ * Check to see if devices may have been added or removed.
+ *
+ * Enumerating the HID devices is an expensive operation, so you can call this
+ * to see if there have been any system device changes since the last call to
+ * this function. A change in the counter returned doesn't necessarily mean
+ * that anything has changed, but you can call SDL_hid_enumerate() to get an
+ * updated device list.
+ *
+ * Calling this function for the first time may cause a thread or other system
+ * resource to be allocated to track device change notifications.
+ *
+ * \returns a change counter that is incremented with each potential device
+ * change, or 0 if device change detection isn't available.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_hid_enumerate
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void);
+
+/**
+ * Enumerate the HID Devices.
+ *
+ * This function returns a linked list of all the HID devices attached to the
+ * system which match vendor_id and product_id. If `vendor_id` is set to 0
+ * then any vendor matches. If `product_id` is set to 0 then any product
+ * matches. If `vendor_id` and `product_id` are both set to 0, then all HID
+ * devices will be returned.
+ *
+ * By default SDL will only enumerate controllers, to reduce risk of hanging
+ * or crashing on bad drivers, but SDL_HINT_HIDAPI_ENUMERATE_ONLY_CONTROLLERS
+ * can be set to "0" to enumerate all HID devices.
+ *
+ * \param vendor_id the Vendor ID (VID) of the types of device to open, or 0
+ * to match any vendor.
+ * \param product_id the Product ID (PID) of the types of device to open, or 0
+ * to match any product.
+ * \returns a pointer to a linked list of type SDL_hid_device_info, containing
+ * information about the HID devices attached to the system, or NULL
+ * in the case of failure. Free this linked list by calling
+ * SDL_hid_free_enumeration().
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_hid_device_change_count
+ */
+extern SDL_DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id);
+
+/**
+ * Free an enumeration linked list.
+ *
+ * This function frees a linked list created by SDL_hid_enumerate().
+ *
+ * \param devs pointer to a list of struct_device returned from
+ * SDL_hid_enumerate().
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs);
+
+/**
+ * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally
+ * a serial number.
+ *
+ * If `serial_number` is NULL, the first device with the specified VID and PID
+ * is opened.
+ *
+ * \param vendor_id the Vendor ID (VID) of the device to open.
+ * \param product_id the Product ID (PID) of the device to open.
+ * \param serial_number the Serial Number of the device to open (Optionally
+ * NULL).
+ * \returns a pointer to a SDL_hid_device object on success or NULL on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number);
+
+/**
+ * Open a HID device by its path name.
+ *
+ * The path name be determined by calling SDL_hid_enumerate(), or a
+ * platform-specific path name can be used (eg: /dev/hidraw0 on Linux).
+ *
+ * \param path the path name of the device to open.
+ * \returns a pointer to a SDL_hid_device object on success or NULL on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path);
+
+/**
+ * Write an Output report to a HID device.
+ *
+ * The first byte of `data` must contain the Report ID. For devices which only
+ * support a single report, this must be set to 0x0. The remaining bytes
+ * contain the report data. Since the Report ID is mandatory, calls to
+ * SDL_hid_write() will always contain one more byte than the report contains.
+ * For example, if a hid report is 16 bytes long, 17 bytes must be passed to
+ * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report),
+ * followed by the report data (16 bytes). In this example, the length passed
+ * in would be 17.
+ *
+ * SDL_hid_write() will send the data on the first OUT endpoint, if one
+ * exists. If it does not, it will send the data through the Control Endpoint
+ * (Endpoint 0).
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data the data to send, including the report number as the first
+ * byte.
+ * \param length the length in bytes of the data to send.
+ * \returns the actual number of bytes written and -1 on on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length);
+
+/**
+ * Read an Input report from a HID device with timeout.
+ *
+ * Input reports are returned to the host through the INTERRUPT IN endpoint.
+ * The first byte will contain the Report number if the device uses numbered
+ * reports.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data a buffer to put the read data into.
+ * \param length the number of bytes to read. For devices with multiple
+ * reports, make sure to read an extra byte for the report
+ * number.
+ * \param milliseconds timeout in milliseconds or -1 for blocking wait.
+ * \returns the actual number of bytes read and -1 on on failure; call
+ * SDL_GetError() for more information. If no packet was available to
+ * be read within the timeout period, this function returns 0.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds);
+
+/**
+ * Read an Input report from a HID device.
+ *
+ * Input reports are returned to the host through the INTERRUPT IN endpoint.
+ * The first byte will contain the Report number if the device uses numbered
+ * reports.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data a buffer to put the read data into.
+ * \param length the number of bytes to read. For devices with multiple
+ * reports, make sure to read an extra byte for the report
+ * number.
+ * \returns the actual number of bytes read and -1 on failure; call
+ * SDL_GetError() for more information. If no packet was available to
+ * be read and the handle is in non-blocking mode, this function
+ * returns 0.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length);
+
+/**
+ * Set the device handle to be non-blocking.
+ *
+ * In non-blocking mode calls to SDL_hid_read() will return immediately with a
+ * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read()
+ * will wait (block) until there is data to read before returning.
+ *
+ * Nonblocking can be turned on and off at any time.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param nonblock enable or not the nonblocking reads - 1 to enable
+ * nonblocking - 0 to disable nonblocking.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock);
+
+/**
+ * Send a Feature report to the device.
+ *
+ * Feature reports are sent over the Control endpoint as a Set_Report
+ * transfer. The first byte of `data` must contain the Report ID. For devices
+ * which only support a single report, this must be set to 0x0. The remaining
+ * bytes contain the report data. Since the Report ID is mandatory, calls to
+ * SDL_hid_send_feature_report() will always contain one more byte than the
+ * report contains. For example, if a hid report is 16 bytes long, 17 bytes
+ * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for
+ * devices which do not use numbered reports), followed by the report data (16
+ * bytes). In this example, the length passed in would be 17.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data the data to send, including the report number as the first
+ * byte.
+ * \param length the length in bytes of the data to send, including the report
+ * number.
+ * \returns the actual number of bytes written and -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length);
+
+/**
+ * Get a feature report from a HID device.
+ *
+ * Set the first byte of `data` to the Report ID of the report to be read.
+ * Make sure to allow space for this extra byte in `data`. Upon return, the
+ * first byte will still contain the Report ID, and the report data will start
+ * in data[1].
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data a buffer to put the read data into, including the Report ID.
+ * Set the first byte of `data` to the Report ID of the report to
+ * be read, or set it to zero if your device does not use numbered
+ * reports.
+ * \param length the number of bytes to read, including an extra byte for the
+ * report ID. The buffer can be longer than the actual report.
+ * \returns the number of bytes read plus one for the report ID (which is
+ * still in the first byte), or -1 on on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length);
+
+/**
+ * Get an input report from a HID device.
+ *
+ * Set the first byte of `data` to the Report ID of the report to be read.
+ * Make sure to allow space for this extra byte in `data`. Upon return, the
+ * first byte will still contain the Report ID, and the report data will start
+ * in data[1].
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param data a buffer to put the read data into, including the Report ID.
+ * Set the first byte of `data` to the Report ID of the report to
+ * be read, or set it to zero if your device does not use numbered
+ * reports.
+ * \param length the number of bytes to read, including an extra byte for the
+ * report ID. The buffer can be longer than the actual report.
+ * \returns the number of bytes read plus one for the report ID (which is
+ * still in the first byte), or -1 on on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_input_report(SDL_hid_device *dev, unsigned char *data, size_t length);
+
+/**
+ * Close a HID device.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_close(SDL_hid_device *dev);
+
+/**
+ * Get The Manufacturer String from a HID device.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param string a wide string buffer to put the data into.
+ * \param maxlen the length of the buffer in multiples of wchar_t.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
+
+/**
+ * Get The Product String from a HID device.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param string a wide string buffer to put the data into.
+ * \param maxlen the length of the buffer in multiples of wchar_t.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
+
+/**
+ * Get The Serial Number String from a HID device.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param string a wide string buffer to put the data into.
+ * \param maxlen the length of the buffer in multiples of wchar_t.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
+
+/**
+ * Get a string from a HID device, based on its string index.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param string_index the index of the string to get.
+ * \param string a wide string buffer to put the data into.
+ * \param maxlen the length of the buffer in multiples of wchar_t.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen);
+
+/**
+ * Get the device info from a HID device.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \returns a pointer to the SDL_hid_device_info for this hid_device or NULL
+ * on failure; call SDL_GetError() for more information. This struct
+ * is valid until the device is closed with SDL_hid_close().
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_get_device_info(SDL_hid_device *dev);
+
+/**
+ * Get a report descriptor from a HID device.
+ *
+ * User has to provide a preallocated buffer where descriptor will be copied
+ * to. The recommended size for a preallocated buffer is 4096 bytes.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \param buf the buffer to copy descriptor into.
+ * \param buf_size the size of the buffer in bytes.
+ * \returns the number of bytes actually copied or -1 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_hid_get_report_descriptor(SDL_hid_device *dev, unsigned char *buf, size_t buf_size);
+
+/**
+ * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers.
+ *
+ * \param active true to start the scan, false to stop the scan.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_hid_ble_scan(bool active);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_hidapi_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_hints.h b/vendored/SDL/include/SDL3/SDL_hints.h
new file mode 100644
index 0000000..a081535
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_hints.h
@@ -0,0 +1,4486 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryHints
+ *
+ * This file contains functions to set and get configuration hints, as well as
+ * listing each of them alphabetically.
+ *
+ * The convention for naming hints is SDL_HINT_X, where "SDL_X" is the
+ * environment variable that can be used to override the default.
+ *
+ * In general these hints are just that - they may or may not be supported or
+ * applicable on any given platform, but they provide a way for an application
+ * or user to give the library a hint as to how they would like the library to
+ * work.
+ */
+
+#ifndef SDL_hints_h_
+#define SDL_hints_h_
+
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Specify the behavior of Alt+Tab while the keyboard is grabbed.
+ *
+ * By default, SDL emulates Alt+Tab functionality while the keyboard is
+ * grabbed and your window is full-screen. This prevents the user from getting
+ * stuck in your application if you've enabled keyboard grab.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will not handle Alt+Tab. Your application is responsible for
+ * handling Alt+Tab while the keyboard is grabbed.
+ * - "1": SDL will minimize your window when Alt+Tab is pressed (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
+
+/**
+ * A variable to control whether the SDL activity is allowed to be re-created.
+ *
+ * If this hint is true, the activity can be recreated on demand by the OS,
+ * and Java static data and C++ static data remain with their current values.
+ * If this hint is false, then SDL will call exit() when you return from your
+ * main function and the application will be terminated and then started fresh
+ * each time.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The application starts fresh at each launch. (default)
+ * - "1": The application activity can be recreated by the OS.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY "SDL_ANDROID_ALLOW_RECREATE_ACTIVITY"
+
+/**
+ * A variable to control whether the event loop will block itself when the app
+ * is paused.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Non blocking.
+ * - "1": Blocking. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE"
+
+/**
+ * A variable to control whether low latency audio should be enabled.
+ *
+ * Some devices have poor quality output when this is enabled, but this is
+ * usually an improvement in audio latency.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Low latency audio is not enabled.
+ * - "1": Low latency audio is enabled. (default)
+ *
+ * This hint should be set before SDL audio is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ANDROID_LOW_LATENCY_AUDIO "SDL_ANDROID_LOW_LATENCY_AUDIO"
+
+/**
+ * A variable to control whether we trap the Android back button to handle it
+ * manually.
+ *
+ * This is necessary for the right mouse button to work on some Android
+ * devices, or to be able to trap the back button for use in your code
+ * reliably. If this hint is true, the back button will show up as an
+ * SDL_EVENT_KEY_DOWN / SDL_EVENT_KEY_UP pair with a keycode of
+ * SDL_SCANCODE_AC_BACK.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Back button will be handled as usual for system. (default)
+ * - "1": Back button will be trapped, allowing you to handle the key press
+ * manually. (This will also let right mouse click work on systems where the
+ * right mouse button functions as back.)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
+
+/**
+ * A variable setting the app ID string.
+ *
+ * This string is used by desktop compositors to identify and group windows
+ * together, as well as match applications with associated desktop settings
+ * and icons.
+ *
+ * This will override SDL_PROP_APP_METADATA_IDENTIFIER_STRING, if set by the
+ * application.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_APP_ID "SDL_APP_ID"
+
+/**
+ * A variable setting the application name.
+ *
+ * This hint lets you specify the application name sent to the OS when
+ * required. For example, this will often appear in volume control applets for
+ * audio streams, and in lists of applications which are inhibiting the
+ * screensaver. You should use a string that describes your program ("My Game
+ * 2: The Revenge")
+ *
+ * This will override SDL_PROP_APP_METADATA_NAME_STRING, if set by the
+ * application.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_APP_NAME "SDL_APP_NAME"
+
+/**
+ * A variable controlling whether controllers used with the Apple TV generate
+ * UI events.
+ *
+ * When UI events are generated by controller input, the app will be
+ * backgrounded when the Apple TV remote's menu button is pressed, and when
+ * the pause or B buttons on gamepads are pressed.
+ *
+ * More information about properly making use of controllers for the Apple TV
+ * can be found here:
+ * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Controller input does not generate UI events. (default)
+ * - "1": Controller input generates UI events.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS"
+
+/**
+ * A variable controlling whether the Apple TV remote's joystick axes will
+ * automatically match the rotation of the remote.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Remote orientation does not affect joystick axes. (default)
+ * - "1": Joystick axes are based on the orientation of the remote.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
+
+/**
+ * Specify the default ALSA audio device name.
+ *
+ * This variable is a specific audio device to open when the "default" audio
+ * device is used.
+ *
+ * This hint will be ignored when opening the default playback device if
+ * SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE is set, or when opening the
+ * default recording device if SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE is
+ * set.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE
+ */
+#define SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE "SDL_AUDIO_ALSA_DEFAULT_DEVICE"
+
+/**
+ * Specify the default ALSA audio playback device name.
+ *
+ * This variable is a specific audio device to open for playback, when the
+ * "default" audio device is used.
+ *
+ * If this hint isn't set, SDL will check SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ * before choosing a reasonable default.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ */
+#define SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE "SDL_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE"
+
+/**
+ * Specify the default ALSA audio recording device name.
+ *
+ * This variable is a specific audio device to open for recording, when the
+ * "default" audio device is used.
+ *
+ * If this hint isn't set, SDL will check SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ * before choosing a reasonable default.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ */
+#define SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE "SDL_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE"
+
+/**
+ * A variable controlling the audio category on iOS and macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "ambient": Use the AVAudioSessionCategoryAmbient audio category, will be
+ * muted by the phone mute switch (default)
+ * - "playback": Use the AVAudioSessionCategoryPlayback category.
+ *
+ * For more information, see Apple's documentation:
+ * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY"
+
+/**
+ * A variable controlling the default audio channel count.
+ *
+ * If the application doesn't specify the audio channel count when opening the
+ * device, this hint can be used to specify a default channel count that will
+ * be used. This defaults to "1" for recording and "2" for playback devices.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_CHANNELS "SDL_AUDIO_CHANNELS"
+
+/**
+ * Specify an application icon name for an audio device.
+ *
+ * Some audio backends (such as Pulseaudio and Pipewire) allow you to set an
+ * XDG icon name for your application. Among other things, this icon might
+ * show up in a system control panel that lets the user adjust the volume on
+ * specific audio streams instead of using one giant master volume slider.
+ * Note that this is unrelated to the icon used by the windowing system, which
+ * may be set with SDL_SetWindowIcon (or via desktop file on Wayland).
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default, "applications-games", which is likely to be installed. See
+ * https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ * and
+ * https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
+ * for the relevant XDG icon specs.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DEVICE_APP_ICON_NAME "SDL_AUDIO_DEVICE_APP_ICON_NAME"
+
+/**
+ * A variable controlling device buffer size.
+ *
+ * This hint is an integer > 0, that represents the size of the device's
+ * buffer in sample frames (stereo audio data in 16-bit format is 4 bytes per
+ * sample frame, for example).
+ *
+ * SDL3 generally decides this value on behalf of the app, but if for some
+ * reason the app needs to dictate this (because they want either lower
+ * latency or higher throughput AND ARE WILLING TO DEAL WITH what that might
+ * require of the app), they can specify it.
+ *
+ * SDL will try to accommodate this value, but there is no promise you'll get
+ * the buffer size requested. Many platforms won't honor this request at all,
+ * or might adjust it.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES "SDL_AUDIO_DEVICE_SAMPLE_FRAMES"
+
+/**
+ * Specify an audio stream name for an audio device.
+ *
+ * Some audio backends (such as PulseAudio) allow you to describe your audio
+ * stream. Among other things, this description might show up in a system
+ * control panel that lets the user adjust the volume on specific audio
+ * streams instead of using one giant master volume slider.
+ *
+ * This hints lets you transmit that information to the OS. The contents of
+ * this hint are used while opening an audio device. You should use a string
+ * that describes your what your program is playing ("audio stream" is
+ * probably sufficient in many cases, but this could be useful for something
+ * like "team chat" if you have a headset playing VoIP audio separately).
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "audio stream" or something similar.
+ *
+ * Note that while this talks about audio streams, this is an OS-level
+ * concept, so it applies to a physical audio device in this case, and not an
+ * SDL_AudioStream, nor an SDL logical audio device.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME"
+
+/**
+ * Specify an application role for an audio device.
+ *
+ * Some audio backends (such as Pipewire) allow you to describe the role of
+ * your audio stream. Among other things, this description might show up in a
+ * system control panel or software for displaying and manipulating media
+ * playback/recording graphs.
+ *
+ * This hints lets you transmit that information to the OS. The contents of
+ * this hint are used while opening an audio device. You should use a string
+ * that describes your what your program is playing (Game, Music, Movie,
+ * etc...).
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "Game" or something similar.
+ *
+ * Note that while this talks about audio streams, this is an OS-level
+ * concept, so it applies to a physical audio device in this case, and not an
+ * SDL_AudioStream, nor an SDL logical audio device.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE"
+
+/**
+ * Specify the input file when recording audio using the disk audio driver.
+ *
+ * This defaults to "sdlaudio-in.raw"
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DISK_INPUT_FILE "SDL_AUDIO_DISK_INPUT_FILE"
+
+/**
+ * Specify the output file when playing audio using the disk audio driver.
+ *
+ * This defaults to "sdlaudio.raw"
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DISK_OUTPUT_FILE "SDL_AUDIO_DISK_OUTPUT_FILE"
+
+/**
+ * A variable controlling the audio rate when using the disk audio driver.
+ *
+ * The disk audio driver normally simulates real-time for the audio rate that
+ * was specified, but you can use this variable to adjust this rate higher or
+ * lower down to 0. The default value is "1.0".
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DISK_TIMESCALE "SDL_AUDIO_DISK_TIMESCALE"
+
+/**
+ * A variable that specifies an audio backend to use.
+ *
+ * By default, SDL will try all available audio backends in a reasonable order
+ * until it finds one that can work, but this hint allows the app or user to
+ * force a specific driver, such as "pipewire" if, say, you are on PulseAudio
+ * but want to try talking to the lower level instead.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DRIVER "SDL_AUDIO_DRIVER"
+
+/**
+ * A variable controlling the audio rate when using the dummy audio driver.
+ *
+ * The dummy audio driver normally simulates real-time for the audio rate that
+ * was specified, but you can use this variable to adjust this rate higher or
+ * lower down to 0. The default value is "1.0".
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_DUMMY_TIMESCALE "SDL_AUDIO_DUMMY_TIMESCALE"
+
+/**
+ * A variable controlling the default audio format.
+ *
+ * If the application doesn't specify the audio format when opening the
+ * device, this hint can be used to specify a default format that will be
+ * used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "U8": Unsigned 8-bit audio
+ * - "S8": Signed 8-bit audio
+ * - "S16LE": Signed 16-bit little-endian audio
+ * - "S16BE": Signed 16-bit big-endian audio
+ * - "S16": Signed 16-bit native-endian audio (default)
+ * - "S32LE": Signed 32-bit little-endian audio
+ * - "S32BE": Signed 32-bit big-endian audio
+ * - "S32": Signed 32-bit native-endian audio
+ * - "F32LE": Floating point little-endian audio
+ * - "F32BE": Floating point big-endian audio
+ * - "F32": Floating point native-endian audio
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_FORMAT "SDL_AUDIO_FORMAT"
+
+/**
+ * A variable controlling the default audio frequency.
+ *
+ * If the application doesn't specify the audio frequency when opening the
+ * device, this hint can be used to specify a default frequency that will be
+ * used. This defaults to "44100".
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_FREQUENCY "SDL_AUDIO_FREQUENCY"
+
+/**
+ * A variable that causes SDL to not ignore audio "monitors".
+ *
+ * This is currently only used by the PulseAudio driver.
+ *
+ * By default, SDL ignores audio devices that aren't associated with physical
+ * hardware. Changing this hint to "1" will expose anything SDL sees that
+ * appears to be an audio source or sink. This will add "devices" to the list
+ * that the user probably doesn't want or need, but it can be useful in
+ * scenarios where you want to hook up SDL to some sort of virtual device,
+ * etc.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Audio monitor devices will be ignored. (default)
+ * - "1": Audio monitor devices will show up in the device list.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS"
+
+/**
+ * A variable controlling whether SDL updates joystick state when getting
+ * input events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": You'll call SDL_UpdateJoysticks() manually.
+ * - "1": SDL will automatically call SDL_UpdateJoysticks(). (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUTO_UPDATE_JOYSTICKS "SDL_AUTO_UPDATE_JOYSTICKS"
+
+/**
+ * A variable controlling whether SDL updates sensor state when getting input
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": You'll call SDL_UpdateSensors() manually.
+ * - "1": SDL will automatically call SDL_UpdateSensors(). (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_AUTO_UPDATE_SENSORS "SDL_AUTO_UPDATE_SENSORS"
+
+/**
+ * Prevent SDL from using version 4 of the bitmap header when saving BMPs.
+ *
+ * The bitmap header version 4 is required for proper alpha channel support
+ * and SDL will use it when required. Should this not be desired, this hint
+ * can force the use of the 40 byte header version which is supported
+ * everywhere.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Surfaces with a colorkey or an alpha channel are saved to a 32-bit
+ * BMP file with an alpha mask. SDL will use the bitmap header version 4 and
+ * set the alpha mask accordingly. (default)
+ * - "1": Surfaces with a colorkey or an alpha channel are saved to a 32-bit
+ * BMP file without an alpha mask. The alpha channel data will be in the
+ * file, but applications are going to ignore it.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
+
+/**
+ * A variable that decides what camera backend to use.
+ *
+ * By default, SDL will try all available camera backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app or
+ * user to force a specific target, such as "directshow" if, say, you are on
+ * Windows Media Foundations but want to try DirectShow instead.
+ *
+ * The default value is unset, in which case SDL will try to figure out the
+ * best camera backend on your behalf. This hint needs to be set before
+ * SDL_Init() is called to be useful.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_CAMERA_DRIVER "SDL_CAMERA_DRIVER"
+
+/**
+ * A variable that limits what CPU features are available.
+ *
+ * By default, SDL marks all features the current CPU supports as available.
+ * This hint allows to limit these to a subset.
+ *
+ * When the hint is unset, or empty, SDL will enable all detected CPU
+ * features.
+ *
+ * The variable can be set to a comma separated list containing the following
+ * items:
+ *
+ * - "all"
+ * - "altivec"
+ * - "sse"
+ * - "sse2"
+ * - "sse3"
+ * - "sse41"
+ * - "sse42"
+ * - "avx"
+ * - "avx2"
+ * - "avx512f"
+ * - "arm-simd"
+ * - "neon"
+ * - "lsx"
+ * - "lasx"
+ *
+ * The items can be prefixed by '+'/'-' to add/remove features.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_CPU_FEATURE_MASK "SDL_CPU_FEATURE_MASK"
+
+/**
+ * A variable controlling whether DirectInput should be used for controllers.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable DirectInput detection.
+ * - "1": Enable DirectInput detection. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_DIRECTINPUT "SDL_JOYSTICK_DIRECTINPUT"
+
+/**
+ * A variable that specifies a dialog backend to use.
+ *
+ * By default, SDL will try all available dialog backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app or
+ * user to force a specific target.
+ *
+ * If the specified target does not exist or is not available, the
+ * dialog-related function calls will fail.
+ *
+ * This hint currently only applies to platforms using the generic "Unix"
+ * dialog implementation, but may be extended to more platforms in the future.
+ * Note that some Unix and Unix-like platforms have their own implementation,
+ * such as macOS and Haiku.
+ *
+ * The variable can be set to the following values:
+ *
+ * - NULL: Select automatically (default, all platforms)
+ * - "portal": Use XDG Portals through DBus (Unix only)
+ * - "zenity": Use the Zenity program (Unix only)
+ *
+ * More options may be added in the future.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_FILE_DIALOG_DRIVER "SDL_FILE_DIALOG_DRIVER"
+
+/**
+ * Override for SDL_GetDisplayUsableBounds().
+ *
+ * If set, this hint will override the expected results for
+ * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want
+ * to do this, but this allows an embedded system to request that some of the
+ * screen be reserved for other uses when paired with a well-behaved
+ * application.
+ *
+ * The contents of this hint must be 4 comma-separated integers, the first is
+ * the bounds x, then y, width and height, in that order.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS"
+
+/**
+ * Disable giving back control to the browser automatically when running with
+ * asyncify.
+ *
+ * With -s ASYNCIFY, SDL calls emscripten_sleep during operations such as
+ * refreshing the screen or polling events.
+ *
+ * This hint only applies to the emscripten platform.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable emscripten_sleep calls (if you give back browser control
+ * manually or use asyncify for other purposes).
+ * - "1": Enable emscripten_sleep calls. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EMSCRIPTEN_ASYNCIFY "SDL_EMSCRIPTEN_ASYNCIFY"
+
+/**
+ * Specify the CSS selector used for the "default" window/canvas.
+ *
+ * This hint only applies to the emscripten platform.
+ *
+ * The default value is "#canvas"
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EMSCRIPTEN_CANVAS_SELECTOR "SDL_EMSCRIPTEN_CANVAS_SELECTOR"
+
+/**
+ * Override the binding element for keyboard inputs for Emscripten builds.
+ *
+ * This hint only applies to the emscripten platform.
+ *
+ * The variable can be one of:
+ *
+ * - "#window": the javascript window object (default)
+ * - "#document": the javascript document object
+ * - "#screen": the javascript window.screen object
+ * - "#canvas": the WebGL canvas element
+ * - "#none": Don't bind anything at all
+ * - any other string without a leading # sign applies to the element on the
+ * page with that ID.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
+
+/**
+ * A variable that controls whether the on-screen keyboard should be shown
+ * when text input is active.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "auto": The on-screen keyboard will be shown if there is no physical
+ * keyboard attached. (default)
+ * - "0": Do not show the on-screen keyboard.
+ * - "1": Show the on-screen keyboard, if available.
+ *
+ * This hint must be set before SDL_StartTextInput() is called
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD"
+
+/**
+ * A variable containing a list of evdev devices to use if udev is not
+ * available.
+ *
+ * The list of devices is in the form:
+ *
+ * deviceclass:path[,deviceclass:path[,...]]
+ *
+ * where device class is an integer representing the SDL_UDEV_deviceclass and
+ * path is the full path to the event device.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EVDEV_DEVICES "SDL_EVDEV_DEVICES"
+
+/**
+ * A variable controlling verbosity of the logging of SDL events pushed onto
+ * the internal queue.
+ *
+ * The variable can be set to the following values, from least to most
+ * verbose:
+ *
+ * - "0": Don't log any events. (default)
+ * - "1": Log most events (other than the really spammy ones).
+ * - "2": Include mouse and finger motion events.
+ *
+ * This is generally meant to be used to debug SDL itself, but can be useful
+ * for application developers that need better visibility into what is going
+ * on in the event queue. Logged events are sent through SDL_Log(), which
+ * means by default they appear on stdout on most platforms or maybe
+ * OutputDebugString() on Windows, and can be funneled by the app with
+ * SDL_SetLogOutputFunction(), etc.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING"
+
+/**
+ * A variable controlling whether raising the window should be done more
+ * forcefully.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Honor the OS policy for raising windows. (default)
+ * - "1": Force the window to be raised, overriding any OS policy.
+ *
+ * At present, this is only an issue under MS Windows, which makes it nearly
+ * impossible to programmatically move a window to the foreground, for
+ * "security" reasons. See http://stackoverflow.com/a/34414846 for a
+ * discussion.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_FORCE_RAISEWINDOW "SDL_FORCE_RAISEWINDOW"
+
+/**
+ * A variable controlling how 3D acceleration is used to accelerate the SDL
+ * screen surface.
+ *
+ * SDL can try to accelerate the SDL screen surface by using streaming
+ * textures with a 3D rendering engine. This variable controls whether and how
+ * this is done.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable 3D acceleration
+ * - "1": Enable 3D acceleration, using the default renderer. (default)
+ * - "X": Enable 3D acceleration, using X where X is one of the valid
+ * rendering drivers. (e.g. "direct3d", "opengl", etc.)
+ *
+ * This hint should be set before calling SDL_GetWindowSurface()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION"
+
+/**
+ * A variable that lets you manually hint extra gamecontroller db entries.
+ *
+ * The variable should be newline delimited rows of gamecontroller config
+ * data, see SDL_gamepad.h
+ *
+ * You can update mappings after SDL is initialized with
+ * SDL_GetGamepadMappingForGUID() and SDL_AddGamepadMapping()
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG"
+
+/**
+ * A variable that lets you provide a file with extra gamecontroller db
+ * entries.
+ *
+ * The file should contain lines of gamecontroller config data, see
+ * SDL_gamepad.h
+ *
+ * You can update mappings after SDL is initialized with
+ * SDL_GetGamepadMappingForGUID() and SDL_AddGamepadMapping()
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE"
+
+/**
+ * A variable that overrides the automatic controller type detection.
+ *
+ * The variable should be comma separated entries, in the form: VID/PID=type
+ *
+ * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd
+ *
+ * This hint affects what low level protocol is used with the HIDAPI driver.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "Xbox360"
+ * - "XboxOne"
+ * - "PS3"
+ * - "PS4"
+ * - "PS5"
+ * - "SwitchPro"
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE"
+
+/**
+ * A variable containing a list of devices to skip when scanning for game
+ * controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * 0xAAAA/0xBBBB,0xCCCC/0xDDDD
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES"
+
+/**
+ * If set, all devices will be skipped when scanning for game controllers
+ * except for the ones listed in this variable.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * 0xAAAA/0xBBBB,0xCCCC/0xDDDD
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT"
+
+/**
+ * A variable that controls whether the device's built-in accelerometer and
+ * gyro should be used as sensors for gamepads.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Sensor fusion is disabled
+ * - "1": Sensor fusion is enabled for all controllers that lack sensors
+ *
+ * Or the variable can be a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * 0xAAAA/0xBBBB,0xCCCC/0xDDDD
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint should be set before a gamepad is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GAMECONTROLLER_SENSOR_FUSION "SDL_GAMECONTROLLER_SENSOR_FUSION"
+
+/**
+ * This variable sets the default text of the TextInput window on GDK
+ * platforms.
+ *
+ * This hint is available only if SDL_GDK_TEXTINPUT defined.
+ *
+ * This hint should be set before calling SDL_StartTextInput()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GDK_TEXTINPUT_DEFAULT_TEXT "SDL_GDK_TEXTINPUT_DEFAULT_TEXT"
+
+/**
+ * This variable sets the description of the TextInput window on GDK
+ * platforms.
+ *
+ * This hint is available only if SDL_GDK_TEXTINPUT defined.
+ *
+ * This hint should be set before calling SDL_StartTextInput()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GDK_TEXTINPUT_DESCRIPTION "SDL_GDK_TEXTINPUT_DESCRIPTION"
+
+/**
+ * This variable sets the maximum input length of the TextInput window on GDK
+ * platforms.
+ *
+ * The value must be a stringified integer, for example "10" to allow for up
+ * to 10 characters of text input.
+ *
+ * This hint is available only if SDL_GDK_TEXTINPUT defined.
+ *
+ * This hint should be set before calling SDL_StartTextInput()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GDK_TEXTINPUT_MAX_LENGTH "SDL_GDK_TEXTINPUT_MAX_LENGTH"
+
+/**
+ * This variable sets the input scope of the TextInput window on GDK
+ * platforms.
+ *
+ * Set this hint to change the XGameUiTextEntryInputScope value that will be
+ * passed to the window creation function. The value must be a stringified
+ * integer, for example "0" for XGameUiTextEntryInputScope::Default.
+ *
+ * This hint is available only if SDL_GDK_TEXTINPUT defined.
+ *
+ * This hint should be set before calling SDL_StartTextInput()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GDK_TEXTINPUT_SCOPE "SDL_GDK_TEXTINPUT_SCOPE"
+
+/**
+ * This variable sets the title of the TextInput window on GDK platforms.
+ *
+ * This hint is available only if SDL_GDK_TEXTINPUT defined.
+ *
+ * This hint should be set before calling SDL_StartTextInput()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GDK_TEXTINPUT_TITLE "SDL_GDK_TEXTINPUT_TITLE"
+
+/**
+ * A variable to control whether HIDAPI uses libusb for device access.
+ *
+ * By default libusb will only be used for a few devices that require direct
+ * USB access, and this can be controlled with
+ * SDL_HINT_HIDAPI_LIBUSB_WHITELIST.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI will not use libusb for device access.
+ * - "1": HIDAPI will use libusb for device access if available. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_HIDAPI_LIBUSB "SDL_HIDAPI_LIBUSB"
+
+/**
+ * A variable to control whether HIDAPI uses libusb only for whitelisted
+ * devices.
+ *
+ * By default libusb will only be used for a few devices that require direct
+ * USB access.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI will use libusb for all device access.
+ * - "1": HIDAPI will use libusb only for whitelisted devices. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_HIDAPI_LIBUSB_WHITELIST "SDL_HIDAPI_LIBUSB_WHITELIST"
+
+/**
+ * A variable to control whether HIDAPI uses udev for device detection.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI will poll for device changes.
+ * - "1": HIDAPI will use udev for device detection. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_HIDAPI_UDEV "SDL_HIDAPI_UDEV"
+
+/**
+ * A variable that specifies a GPU backend to use.
+ *
+ * By default, SDL will try all available GPU backends in a reasonable order
+ * until it finds one that can work, but this hint allows the app or user to
+ * force a specific target, such as "direct3d12" if, say, your hardware
+ * supports Vulkan but you want to try using D3D12 instead.
+ *
+ * This hint should be set before any GPU functions are called.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_GPU_DRIVER "SDL_GPU_DRIVER"
+
+/**
+ * A variable to control whether SDL_hid_enumerate() enumerates all HID
+ * devices or only controllers.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL_hid_enumerate() will enumerate all HID devices.
+ * - "1": SDL_hid_enumerate() will only enumerate controllers. (default)
+ *
+ * By default SDL will only enumerate controllers, to reduce risk of hanging
+ * or crashing on devices with bad drivers and avoiding macOS keyboard capture
+ * permission prompts.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_HIDAPI_ENUMERATE_ONLY_CONTROLLERS "SDL_HIDAPI_ENUMERATE_ONLY_CONTROLLERS"
+
+/**
+ * A variable containing a list of devices to ignore in SDL_hid_enumerate().
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * For example, to ignore the Shanwan DS3 controller and any Valve controller,
+ * you might use the string "0x2563/0x0523,0x28de/0x0000"
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_HIDAPI_IGNORE_DEVICES "SDL_HIDAPI_IGNORE_DEVICES"
+
+/**
+ * A variable describing what IME UI elements the application can display.
+ *
+ * By default IME UI is handled using native components by the OS where
+ * possible, however this can interfere with or not be visible when exclusive
+ * fullscreen mode is used.
+ *
+ * The variable can be set to a comma separated list containing the following
+ * items:
+ *
+ * - "none" or "0": The application can't render any IME elements, and native
+ * UI should be used. (default)
+ * - "composition": The application handles SDL_EVENT_TEXT_EDITING events and
+ * can render the composition text.
+ * - "candidates": The application handles SDL_EVENT_TEXT_EDITING_CANDIDATES
+ * and can render the candidate list.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_IME_IMPLEMENTED_UI "SDL_IME_IMPLEMENTED_UI"
+
+/**
+ * A variable controlling whether the home indicator bar on iPhone X should be
+ * hidden.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The indicator bar is not hidden. (default for windowed applications)
+ * - "1": The indicator bar is hidden and is shown when the screen is touched
+ * (useful for movie playback applications).
+ * - "2": The indicator bar is dim and the first swipe makes it visible and
+ * the second swipe performs the "home" action. (default for fullscreen
+ * applications)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR"
+
+/**
+ * A variable that lets you enable joystick (and gamecontroller) events even
+ * when your app is in the background.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable joystick & gamecontroller input events when the application
+ * is in the background. (default)
+ * - "1": Enable joystick & gamecontroller input events when the application
+ * is in the background.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
+
+/**
+ * A variable containing a list of arcade stick style controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES "SDL_JOYSTICK_ARCADESTICK_DEVICES"
+
+/**
+ * A variable containing a list of devices that are not arcade stick style
+ * controllers.
+ *
+ * This will override SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES and the built in
+ * device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES_EXCLUDED "SDL_JOYSTICK_ARCADESTICK_DEVICES_EXCLUDED"
+
+/**
+ * A variable containing a list of devices that should not be considered
+ * joysticks.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_BLACKLIST_DEVICES "SDL_JOYSTICK_BLACKLIST_DEVICES"
+
+/**
+ * A variable containing a list of devices that should be considered
+ * joysticks.
+ *
+ * This will override SDL_HINT_JOYSTICK_BLACKLIST_DEVICES and the built in
+ * device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_BLACKLIST_DEVICES_EXCLUDED "SDL_JOYSTICK_BLACKLIST_DEVICES_EXCLUDED"
+
+/**
+ * A variable containing a comma separated list of devices to open as
+ * joysticks.
+ *
+ * This variable is currently only used by the Linux joystick driver.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE"
+
+/**
+ * A variable controlling whether enhanced reports should be used for
+ * controllers when using the HIDAPI driver.
+ *
+ * Enhanced reports allow rumble and effects on Bluetooth PlayStation
+ * controllers and gyro on Nintendo Switch controllers, but break Windows
+ * DirectInput for other applications that don't use SDL.
+ *
+ * Once enhanced reports are enabled, they can't be disabled on PlayStation
+ * controllers without power cycling the controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": enhanced reports are not enabled.
+ * - "1": enhanced reports are enabled. (default)
+ * - "auto": enhanced features are advertised to the application, but SDL
+ * doesn't change the controller report mode unless the application uses
+ * them.
+ *
+ * This hint can be enabled anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ENHANCED_REPORTS "SDL_JOYSTICK_ENHANCED_REPORTS"
+
+/**
+ * A variable containing a list of flightstick style controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of @file, in which case the named file
+ * will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES "SDL_JOYSTICK_FLIGHTSTICK_DEVICES"
+
+/**
+ * A variable containing a list of devices that are not flightstick style
+ * controllers.
+ *
+ * This will override SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES and the built in
+ * device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED "SDL_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED"
+
+/**
+ * A variable controlling whether GameInput should be used for controller
+ * handling on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": GameInput is not used.
+ * - "1": GameInput is used.
+ *
+ * The default is "1" on GDK platforms, and "0" otherwise.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_GAMEINPUT "SDL_JOYSTICK_GAMEINPUT"
+
+/**
+ * A variable containing a list of devices known to have a GameCube form
+ * factor.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_GAMECUBE_DEVICES "SDL_JOYSTICK_GAMECUBE_DEVICES"
+
+/**
+ * A variable containing a list of devices known not to have a GameCube form
+ * factor.
+ *
+ * This will override SDL_HINT_JOYSTICK_GAMECUBE_DEVICES and the built in
+ * device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_GAMECUBE_DEVICES_EXCLUDED "SDL_JOYSTICK_GAMECUBE_DEVICES_EXCLUDED"
+
+/**
+ * A variable controlling whether the HIDAPI joystick drivers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI drivers are not used.
+ * - "1": HIDAPI drivers are used. (default)
+ *
+ * This variable is the default for all drivers, but can be overridden by the
+ * hints for specific drivers below.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI"
+
+/**
+ * A variable controlling whether Nintendo Switch Joy-Con controllers will be
+ * combined into a single Pro-like controller when using the HIDAPI driver.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Left and right Joy-Con controllers will not be combined and each
+ * will be a mini-gamepad.
+ * - "1": Left and right Joy-Con controllers will be combined into a single
+ * controller. (default)
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Nintendo GameCube
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE"
+
+/**
+ * A variable controlling whether rumble is used to implement the GameCube
+ * controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2).
+ *
+ * This is useful for applications that need full compatibility for things
+ * like ADSR envelopes. - Stop is implemented by setting low_frequency_rumble
+ * to 0 and high_frequency_rumble >0 - Rumble is both at any arbitrary value -
+ * StopHard is implemented by setting both low_frequency_rumble and
+ * high_frequency_rumble to 0
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Normal rumble behavior is behavior is used. (default)
+ * - "1": Proper GameCube controller rumble behavior is used.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Nintendo Switch
+ * Joy-Cons should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS"
+
+/**
+ * A variable controlling whether the Home button LED should be turned on when
+ * a Nintendo Switch Joy-Con controller is opened.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": home button LED is turned off
+ * - "1": home button LED is turned on
+ *
+ * By default the Home button LED state is not changed. This hint can also be
+ * set to a floating point value between 0.0 and 1.0 which controls the
+ * brightness of the Home button LED.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED "SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Amazon Luna
+ * controllers connected via Bluetooth should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Nintendo Online
+ * classic controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC "SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC"
+
+/**
+ * A variable controlling whether the HIDAPI driver for PS3 controllers should
+ * be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI on macOS, and "0" on
+ * other platforms.
+ *
+ * For official Sony driver (sixaxis.sys) use
+ * SDL_HINT_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER. See
+ * https://github.com/ViGEm/DsHidMini for an alternative driver on Windows.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS3 "SDL_JOYSTICK_HIDAPI_PS3"
+
+/**
+ * A variable controlling whether the Sony driver (sixaxis.sys) for PS3
+ * controllers (Sixaxis/DualShock 3) should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Sony driver (sixaxis.sys) is not used.
+ * - "1": Sony driver (sixaxis.sys) is used.
+ *
+ * The default value is 0.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER "SDL_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER"
+
+/**
+ * A variable controlling whether the HIDAPI driver for PS4 controllers should
+ * be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4"
+
+/**
+ * A variable controlling the update rate of the PS4 controller over Bluetooth
+ * when using the HIDAPI driver.
+ *
+ * This defaults to 4 ms, to match the behavior over USB, and to be more
+ * friendly to other Bluetooth devices and older Bluetooth hardware on the
+ * computer. It can be set to "1" (1000Hz), "2" (500Hz) and "4" (250Hz)
+ *
+ * This hint can be set anytime, but only takes effect when extended input
+ * reports are enabled.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4_REPORT_INTERVAL "SDL_JOYSTICK_HIDAPI_PS4_REPORT_INTERVAL"
+
+/**
+ * A variable controlling whether the HIDAPI driver for PS5 controllers should
+ * be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS5 "SDL_JOYSTICK_HIDAPI_PS5"
+
+/**
+ * A variable controlling whether the player LEDs should be lit to indicate
+ * which player is associated with a PS5 controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": player LEDs are not enabled.
+ * - "1": player LEDs are enabled. (default)
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED "SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED"
+
+/**
+ * A variable controlling whether the HIDAPI driver for NVIDIA SHIELD
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SHIELD "SDL_JOYSTICK_HIDAPI_SHIELD"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Google Stadia
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STADIA "SDL_JOYSTICK_HIDAPI_STADIA"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Bluetooth Steam
+ * Controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used. (default)
+ * - "1": HIDAPI driver is used for Steam Controllers, which requires
+ * Bluetooth access and may prompt the user for permission on iOS and
+ * Android.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM"
+
+/**
+ * A variable controlling whether the Steam button LED should be turned on
+ * when a Steam controller is opened.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Steam button LED is turned off.
+ * - "1": Steam button LED is turned on.
+ *
+ * By default the Steam button LED state is not changed. This hint can also be
+ * set to a floating point value between 0.0 and 1.0 which controls the
+ * brightness of the Steam button LED.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM_HOME_LED "SDL_JOYSTICK_HIDAPI_STEAM_HOME_LED"
+
+/**
+ * A variable controlling whether the HIDAPI driver for the Steam Deck builtin
+ * controller should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK "SDL_JOYSTICK_HIDAPI_STEAMDECK"
+
+/**
+ * A variable controlling whether the HIDAPI driver for HORI licensed Steam
+ * controllers should be used.
+ *
+ * This variable can be set to the following values: "0" - HIDAPI driver is
+ * not used "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM_HORI "SDL_JOYSTICK_HIDAPI_STEAM_HORI"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Nintendo Switch
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
+
+/**
+ * A variable controlling whether the Home button LED should be turned on when
+ * a Nintendo Switch Pro controller is opened.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Home button LED is turned off.
+ * - "1": Home button LED is turned on.
+ *
+ * By default the Home button LED state is not changed. This hint can also be
+ * set to a floating point value between 0.0 and 1.0 which controls the
+ * brightness of the Home button LED.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED"
+
+/**
+ * A variable controlling whether the player LEDs should be lit to indicate
+ * which player is associated with a Nintendo Switch controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Player LEDs are not enabled.
+ * - "1": Player LEDs are enabled. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED "SDL_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED"
+
+/**
+ * A variable controlling whether Nintendo Switch Joy-Con controllers will be
+ * in vertical mode when using the HIDAPI driver.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Left and right Joy-Con controllers will not be in vertical mode.
+ * (default)
+ * - "1": Left and right Joy-Con controllers will be in vertical mode.
+ *
+ * This hint should be set before opening a Joy-Con controller.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS "SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Nintendo Wii and Wii U
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * This driver doesn't work with the dolphinbar, so the default is false for
+ * now.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_WII "SDL_JOYSTICK_HIDAPI_WII"
+
+/**
+ * A variable controlling whether the player LEDs should be lit to indicate
+ * which player is associated with a Wii controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Player LEDs are not enabled.
+ * - "1": Player LEDs are enabled. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED "SDL_JOYSTICK_HIDAPI_WII_PLAYER_LED"
+
+/**
+ * A variable controlling whether the HIDAPI driver for XBox controllers
+ * should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is "0" on Windows, otherwise the value of
+ * SDL_HINT_JOYSTICK_HIDAPI
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX"
+
+/**
+ * A variable controlling whether the HIDAPI driver for XBox 360 controllers
+ * should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 "SDL_JOYSTICK_HIDAPI_XBOX_360"
+
+/**
+ * A variable controlling whether the player LEDs should be lit to indicate
+ * which player is associated with an Xbox 360 controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Player LEDs are not enabled.
+ * - "1": Player LEDs are enabled. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED "SDL_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED"
+
+/**
+ * A variable controlling whether the HIDAPI driver for XBox 360 wireless
+ * controllers should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX_360
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS "SDL_JOYSTICK_HIDAPI_XBOX_360_WIRELESS"
+
+/**
+ * A variable controlling whether the HIDAPI driver for XBox One controllers
+ * should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI driver is not used.
+ * - "1": HIDAPI driver is used.
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE "SDL_JOYSTICK_HIDAPI_XBOX_ONE"
+
+/**
+ * A variable controlling whether the Home button LED should be turned on when
+ * an Xbox One controller is opened.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Home button LED is turned off.
+ * - "1": Home button LED is turned on.
+ *
+ * By default the Home button LED state is not changed. This hint can also be
+ * set to a floating point value between 0.0 and 1.0 which controls the
+ * brightness of the Home button LED. The default brightness is 0.4.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED "SDL_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED"
+
+/**
+ * A variable controlling whether IOKit should be used for controller
+ * handling.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": IOKit is not used.
+ * - "1": IOKit is used. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_IOKIT "SDL_JOYSTICK_IOKIT"
+
+/**
+ * A variable controlling whether to use the classic /dev/input/js* joystick
+ * interface or the newer /dev/input/event* joystick interface on Linux.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use /dev/input/event* (default)
+ * - "1": Use /dev/input/js*
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_LINUX_CLASSIC "SDL_JOYSTICK_LINUX_CLASSIC"
+
+/**
+ * A variable controlling whether joysticks on Linux adhere to their
+ * HID-defined deadzones or return unfiltered values.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Return unfiltered joystick axis values. (default)
+ * - "1": Return axis values with deadzones taken into account.
+ *
+ * This hint should be set before a controller is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_LINUX_DEADZONES "SDL_JOYSTICK_LINUX_DEADZONES"
+
+/**
+ * A variable controlling whether joysticks on Linux will always treat 'hat'
+ * axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking
+ * whether they may be analog.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Only map hat axis inputs to digital hat outputs if the input axes
+ * appear to actually be digital. (default)
+ * - "1": Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as
+ * digital hats.
+ *
+ * This hint should be set before a controller is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_LINUX_DIGITAL_HATS "SDL_JOYSTICK_LINUX_DIGITAL_HATS"
+
+/**
+ * A variable controlling whether digital hats on Linux will apply deadzones
+ * to their underlying input axes or use unfiltered values.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Return digital hat values based on unfiltered input axis values.
+ * - "1": Return digital hat values with deadzones on the input axes taken
+ * into account. (default)
+ *
+ * This hint should be set before a controller is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_LINUX_HAT_DEADZONES "SDL_JOYSTICK_LINUX_HAT_DEADZONES"
+
+/**
+ * A variable controlling whether GCController should be used for controller
+ * handling.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": GCController is not used.
+ * - "1": GCController is used. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_MFI "SDL_JOYSTICK_MFI"
+
+/**
+ * A variable controlling whether the RAWINPUT joystick drivers should be used
+ * for better handling XInput-capable devices.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": RAWINPUT drivers are not used. (default)
+ * - "1": RAWINPUT drivers are used.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT"
+
+/**
+ * A variable controlling whether the RAWINPUT driver should pull correlated
+ * data from XInput.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": RAWINPUT driver will only use data from raw input APIs.
+ * - "1": RAWINPUT driver will also pull data from XInput and
+ * Windows.Gaming.Input, providing better trigger axes, guide button
+ * presses, and rumble support for Xbox controllers. (default)
+ *
+ * This hint should be set before a gamepad is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT "SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT"
+
+/**
+ * A variable controlling whether the ROG Chakram mice should show up as
+ * joysticks.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": ROG Chakram mice do not show up as joysticks. (default)
+ * - "1": ROG Chakram mice show up as joysticks.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ROG_CHAKRAM "SDL_JOYSTICK_ROG_CHAKRAM"
+
+/**
+ * A variable controlling whether a separate thread should be used for
+ * handling joystick detection and raw input messages on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": A separate thread is not used.
+ * - "1": A separate thread is used for handling raw input messages. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD"
+
+/**
+ * A variable containing a list of throttle style controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_THROTTLE_DEVICES "SDL_JOYSTICK_THROTTLE_DEVICES"
+
+/**
+ * A variable containing a list of devices that are not throttle style
+ * controllers.
+ *
+ * This will override SDL_HINT_JOYSTICK_THROTTLE_DEVICES and the built in
+ * device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_THROTTLE_DEVICES_EXCLUDED "SDL_JOYSTICK_THROTTLE_DEVICES_EXCLUDED"
+
+/**
+ * A variable controlling whether Windows.Gaming.Input should be used for
+ * controller handling.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": WGI is not used.
+ * - "1": WGI is used. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_WGI "SDL_JOYSTICK_WGI"
+
+/**
+ * A variable containing a list of wheel style controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_WHEEL_DEVICES "SDL_JOYSTICK_WHEEL_DEVICES"
+
+/**
+ * A variable containing a list of devices that are not wheel style
+ * controllers.
+ *
+ * This will override SDL_HINT_JOYSTICK_WHEEL_DEVICES and the built in device
+ * list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_WHEEL_DEVICES_EXCLUDED "SDL_JOYSTICK_WHEEL_DEVICES_EXCLUDED"
+
+/**
+ * A variable containing a list of devices known to have all axes centered at
+ * zero.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint should be set before a controller is opened.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_JOYSTICK_ZERO_CENTERED_DEVICES "SDL_JOYSTICK_ZERO_CENTERED_DEVICES"
+
+/**
+ * A variable containing a list of devices and their desired number of haptic
+ * (force feedback) enabled axis.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form plus the number of desired axes, e.g.
+ *
+ * `0xAAAA/0xBBBB/1,0xCCCC/0xDDDD/3`
+ *
+ * This hint supports a "wildcard" device that will set the number of haptic
+ * axes on all initialized haptic devices which were not defined explicitly in
+ * this hint.
+ *
+ * `0xFFFF/0xFFFF/1`
+ *
+ * This hint should be set before a controller is opened. The number of haptic
+ * axes won't exceed the number of real axes found on the device.
+ *
+ * \since This hint is available since SDL 3.2.5.
+ */
+#define SDL_HINT_JOYSTICK_HAPTIC_AXES "SDL_JOYSTICK_HAPTIC_AXES"
+
+/**
+ * A variable that controls keycode representation in keyboard events.
+ *
+ * This variable is a comma separated set of options for translating keycodes
+ * in events:
+ *
+ * - "none": Keycode options are cleared, this overrides other options.
+ * - "hide_numpad": The numpad keysyms will be translated into their
+ * non-numpad versions based on the current NumLock state. For example,
+ * SDLK_KP_4 would become SDLK_4 if SDL_KMOD_NUM is set in the event
+ * modifiers, and SDLK_LEFT if it is unset.
+ * - "french_numbers": The number row on French keyboards is inverted, so
+ * pressing the 1 key would yield the keycode SDLK_1, or '1', instead of
+ * SDLK_AMPERSAND, or '&'
+ * - "latin_letters": For keyboards using non-Latin letters, such as Russian
+ * or Thai, the letter keys generate keycodes as though it had an en_US
+ * layout. e.g. pressing the key associated with SDL_SCANCODE_A on a Russian
+ * keyboard would yield 'a' instead of a Cyrillic letter.
+ *
+ * The default value for this hint is "french_numbers,latin_letters"
+ *
+ * Some platforms like Emscripten only provide modified keycodes and the
+ * options are not used.
+ *
+ * These options do not affect the return value of SDL_GetKeyFromScancode() or
+ * SDL_GetScancodeFromKey(), they just apply to the keycode included in key
+ * events.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_KEYCODE_OPTIONS "SDL_KEYCODE_OPTIONS"
+
+/**
+ * A variable that controls what KMSDRM device to use.
+ *
+ * SDL might open something like "/dev/dri/cardNN" to access KMSDRM
+ * functionality, where "NN" is a device index number. SDL makes a guess at
+ * the best index to use (usually zero), but the app or user can set this hint
+ * to a number between 0 and 99 to force selection.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_KMSDRM_DEVICE_INDEX "SDL_KMSDRM_DEVICE_INDEX"
+
+/**
+ * A variable that controls whether SDL requires DRM master access in order to
+ * initialize the KMSDRM video backend.
+ *
+ * The DRM subsystem has a concept of a "DRM master" which is a DRM client
+ * that has the ability to set planes, set cursor, etc. When SDL is DRM
+ * master, it can draw to the screen using the SDL rendering APIs. Without DRM
+ * master, SDL is still able to process input and query attributes of attached
+ * displays, but it cannot change display state or draw to the screen
+ * directly.
+ *
+ * In some cases, it can be useful to have the KMSDRM backend even if it
+ * cannot be used for rendering. An app may want to use SDL for input
+ * processing while using another rendering API (such as an MMAL overlay on
+ * Raspberry Pi) or using its own code to render to DRM overlays that SDL
+ * doesn't support.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will allow usage of the KMSDRM backend without DRM master.
+ * - "1": SDL Will require DRM master to use the KMSDRM backend. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER"
+
+/**
+ * A variable controlling the default SDL log levels.
+ *
+ * This variable is a comma separated set of category=level tokens that define
+ * the default logging levels for SDL applications.
+ *
+ * The category can be a numeric category, one of "app", "error", "assert",
+ * "system", "audio", "video", "render", "input", "test", or `*` for any
+ * unspecified category.
+ *
+ * The level can be a numeric level, one of "verbose", "debug", "info",
+ * "warn", "error", "critical", or "quiet" to disable that category.
+ *
+ * You can omit the category if you want to set the logging level for all
+ * categories.
+ *
+ * If this hint isn't set, the default log levels are equivalent to:
+ *
+ * `app=info,assert=warn,test=verbose,*=error`
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_LOGGING "SDL_LOGGING"
+
+/**
+ * A variable controlling whether to force the application to become the
+ * foreground process when launched on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The application is brought to the foreground when launched.
+ * (default)
+ * - "1": The application may remain in the background when launched.
+ *
+ * This hint needs to be set before SDL_Init().
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP"
+
+/**
+ * A variable that determines whether Ctrl+Click should generate a right-click
+ * event on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Ctrl+Click does not generate a right mouse button click event.
+ * (default)
+ * - "1": Ctrl+Click generated a right mouse button click event.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK"
+
+/**
+ * A variable controlling whether dispatching OpenGL context updates should
+ * block the dispatching thread until the main thread finishes processing on
+ * macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Dispatching OpenGL context updates will block the dispatching thread
+ * until the main thread finishes processing. (default)
+ * - "1": Dispatching OpenGL context updates will allow the dispatching thread
+ * to continue execution.
+ *
+ * Generally you want the default, but if you have OpenGL code in a background
+ * thread on a Mac, and the main thread hangs because it's waiting for that
+ * background thread, but that background thread is also hanging because it's
+ * waiting for the main thread to do an update, this might fix your issue.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH "SDL_MAC_OPENGL_ASYNC_DISPATCH"
+
+/**
+ * A variable controlling whether the Option key on macOS should be remapped
+ * to act as the Alt key.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "none": The Option key is not remapped to Alt. (default)
+ * - "only_left": Only the left Option key is remapped to Alt.
+ * - "only_right": Only the right Option key is remapped to Alt.
+ * - "both": Both Option keys are remapped to Alt.
+ *
+ * This will prevent the triggering of key compositions that rely on the
+ * Option key, but will still send the Alt modifier for keyboard events. In
+ * the case that both Alt and Option are pressed, the Option key will be
+ * ignored. This is particularly useful for applications like terminal
+ * emulators and graphical user interfaces (GUIs) that rely on Alt key
+ * functionality for shortcuts or navigation. This does not apply to
+ * SDL_GetKeyFromScancode and only has an effect if IME is enabled.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAC_OPTION_AS_ALT "SDL_MAC_OPTION_AS_ALT"
+
+/**
+ * A variable controlling whether SDL_EVENT_MOUSE_WHEEL event values will have
+ * momentum on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The mouse wheel events will have no momentum. (default)
+ * - "1": The mouse wheel events will have momentum.
+ *
+ * This hint needs to be set before SDL_Init().
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAC_SCROLL_MOMENTUM "SDL_MAC_SCROLL_MOMENTUM"
+
+/**
+ * Request SDL_AppIterate() be called at a specific rate.
+ *
+ * If this is set to a number, it represents Hz, so "60" means try to iterate
+ * 60 times per second. "0" means to iterate as fast as possible. Negative
+ * values are illegal, but reserved, in case they are useful in a future
+ * revision of SDL.
+ *
+ * There are other strings that have special meaning. If set to "waitevent",
+ * SDL_AppIterate will not be called until new event(s) have arrived (and been
+ * processed by SDL_AppEvent). This can be useful for apps that are completely
+ * idle except in response to input.
+ *
+ * On some platforms, or if you are using SDL_main instead of SDL_AppIterate,
+ * this hint is ignored. When the hint can be used, it is allowed to be
+ * changed at any time.
+ *
+ * This defaults to 0, and specifying NULL for the hint's value will restore
+ * the default.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MAIN_CALLBACK_RATE "SDL_MAIN_CALLBACK_RATE"
+
+/**
+ * A variable controlling whether the mouse is captured while mouse buttons
+ * are pressed.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The mouse is not captured while mouse buttons are pressed.
+ * - "1": The mouse is captured while mouse buttons are pressed.
+ *
+ * By default the mouse is captured while mouse buttons are pressed so if the
+ * mouse is dragged outside the window, the application continues to receive
+ * mouse events until the button is released.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE"
+
+/**
+ * A variable setting the double click radius, in pixels.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
+
+/**
+ * A variable setting the double click time, in milliseconds.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME"
+
+/**
+ * A variable setting which system cursor to use as the default cursor.
+ *
+ * This should be an integer corresponding to the SDL_SystemCursor enum. The
+ * default value is zero (SDL_SYSTEM_CURSOR_DEFAULT).
+ *
+ * This hint needs to be set before SDL_Init().
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_DEFAULT_SYSTEM_CURSOR "SDL_MOUSE_DEFAULT_SYSTEM_CURSOR"
+
+/**
+ * A variable controlling whether warping a hidden mouse cursor will activate
+ * relative mouse mode.
+ *
+ * When this hint is set, the mouse cursor is hidden, and multiple warps to
+ * the window center occur within a short time period, SDL will emulate mouse
+ * warps using relative mouse mode. This can provide smoother and more
+ * reliable mouse motion for some older games, which continuously calculate
+ * the distance travelled by the mouse pointer and warp it back to the center
+ * of the window, rather than using relative mouse motion.
+ *
+ * Note that relative mouse mode may have different mouse acceleration
+ * behavior than pointer warps.
+ *
+ * If your application needs to repeatedly warp the hidden mouse cursor at a
+ * high-frequency for other purposes, it should disable this hint.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Attempts to warp the mouse will always be made.
+ * - "1": Some mouse warps will be emulated by forcing relative mouse mode.
+ * (default)
+ *
+ * If not set, this is automatically enabled unless an application uses
+ * relative mouse mode directly.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE "SDL_MOUSE_EMULATE_WARP_WITH_RELATIVE"
+
+/**
+ * Allow mouse click events when clicking to focus an SDL window.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Ignore mouse clicks that activate a window. (default)
+ * - "1": Generate events for mouse clicks that activate a window.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH"
+
+/**
+ * A variable setting the speed scale for mouse motion, in floating point,
+ * when the mouse is not in relative mode.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE"
+
+/**
+ * A variable controlling whether relative mouse mode constrains the mouse to
+ * the center of the window.
+ *
+ * Constraining to the center of the window works better for FPS games and
+ * when the application is running over RDP. Constraining to the whole window
+ * works better for 2D games and increases the chance that the mouse will be
+ * in the correct position when using high DPI mice.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Relative mouse mode constrains the mouse to the window.
+ * - "1": Relative mouse mode constrains the mouse to the center of the
+ * window. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_RELATIVE_MODE_CENTER "SDL_MOUSE_RELATIVE_MODE_CENTER"
+
+/**
+ * A variable setting the scale for mouse motion, in floating point, when the
+ * mouse is in relative mode.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE"
+
+/**
+ * A variable controlling whether the system mouse acceleration curve is used
+ * for relative mouse motion.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Relative mouse motion will be unscaled. (default)
+ * - "1": Relative mouse motion will be scaled using the system mouse
+ * acceleration curve.
+ *
+ * If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will be applied after
+ * system speed scale.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE "SDL_MOUSE_RELATIVE_SYSTEM_SCALE"
+
+/**
+ * A variable controlling whether a motion event should be generated for mouse
+ * warping in relative mode.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Warping the mouse will not generate a motion event in relative mode
+ * - "1": Warping the mouse will generate a motion event in relative mode
+ *
+ * By default warping the mouse will not generate motion events in relative
+ * mode. This avoids the application having to filter out large relative
+ * motion due to warping.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION"
+
+/**
+ * A variable controlling whether the hardware cursor stays visible when
+ * relative mode is active.
+ *
+ * This variable can be set to the following values:
+ *
+ * - "0": The cursor will be hidden while relative mode is active (default)
+ * - "1": The cursor will remain visible while relative mode is active
+ *
+ * Note that for systems without raw hardware inputs, relative mode is
+ * implemented using warping, so the hardware cursor will visibly warp between
+ * frames if this is enabled on those systems.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE "SDL_MOUSE_RELATIVE_CURSOR_VISIBLE"
+
+/**
+ * A variable controlling whether mouse events should generate synthetic touch
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Mouse events will not generate touch events. (default for desktop
+ * platforms)
+ * - "1": Mouse events will generate touch events. (default for mobile
+ * platforms, such as Android and iOS)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS"
+
+/**
+ * A variable controlling whether the keyboard should be muted on the console.
+ *
+ * Normally the keyboard is muted while SDL applications are running so that
+ * keyboard input doesn't show up as key strokes on the console. This hint
+ * allows you to turn that off for debugging purposes.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Allow keystrokes to go through to the console.
+ * - "1": Mute keyboard input so it doesn't show up on the console. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_MUTE_CONSOLE_KEYBOARD "SDL_MUTE_CONSOLE_KEYBOARD"
+
+/**
+ * Tell SDL not to catch the SIGINT or SIGTERM signals on POSIX platforms.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will install a SIGINT and SIGTERM handler, and when it catches a
+ * signal, convert it into an SDL_EVENT_QUIT event. (default)
+ * - "1": SDL will not install a signal handler at all.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS"
+
+/**
+ * Specify the OpenGL library to load.
+ *
+ * This hint should be set before creating an OpenGL window or creating an
+ * OpenGL context. If this hint isn't set, SDL will choose a reasonable
+ * default.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_OPENGL_LIBRARY "SDL_OPENGL_LIBRARY"
+
+/**
+ * Specify the EGL library to load.
+ *
+ * This hint should be set before creating an OpenGL window or creating an
+ * OpenGL context. This hint is only considered if SDL is using EGL to manage
+ * OpenGL contexts. If this hint isn't set, SDL will choose a reasonable
+ * default.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_EGL_LIBRARY "SDL_EGL_LIBRARY"
+
+/**
+ * A variable controlling what driver to use for OpenGL ES contexts.
+ *
+ * On some platforms, currently Windows and X11, OpenGL drivers may support
+ * creating contexts with an OpenGL ES profile. By default SDL uses these
+ * profiles, when available, otherwise it attempts to load an OpenGL ES
+ * library, e.g. that provided by the ANGLE project. This variable controls
+ * whether SDL follows this default behaviour or will always load an OpenGL ES
+ * library.
+ *
+ * Circumstances where this is useful include - Testing an app with a
+ * particular OpenGL ES implementation, e.g ANGLE, or emulator, e.g. those
+ * from ARM, Imagination or Qualcomm. - Resolving OpenGL ES function addresses
+ * at link time by linking with the OpenGL ES library instead of querying them
+ * at run time with SDL_GL_GetProcAddress().
+ *
+ * Caution: for an application to work with the default behaviour across
+ * different OpenGL drivers it must query the OpenGL ES function addresses at
+ * run time using SDL_GL_GetProcAddress().
+ *
+ * This variable is ignored on most platforms because OpenGL ES is native or
+ * not supported.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use ES profile of OpenGL, if available. (default)
+ * - "1": Load OpenGL ES library using the default library names.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER"
+
+/**
+ * Mechanism to specify openvr_api library location
+ *
+ * By default, when using the OpenVR driver, it will search for the API
+ * library in the current folder. But, if you wish to use a system API you can
+ * specify that by using this hint. This should be the full or relative path
+ * to a .dll on Windows or .so on Linux.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_OPENVR_LIBRARY "SDL_OPENVR_LIBRARY"
+
+/**
+ * A variable controlling which orientations are allowed on iOS/Android.
+ *
+ * In some circumstances it is necessary to be able to explicitly control
+ * which UI orientations are allowed.
+ *
+ * This variable is a space delimited list of the following values:
+ *
+ * - "LandscapeLeft"
+ * - "LandscapeRight"
+ * - "Portrait"
+ * - "PortraitUpsideDown"
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ORIENTATIONS "SDL_ORIENTATIONS"
+
+/**
+ * A variable controlling the use of a sentinel event when polling the event
+ * queue.
+ *
+ * When polling for events, SDL_PumpEvents is used to gather new events from
+ * devices. If a device keeps producing new events between calls to
+ * SDL_PumpEvents, a poll loop will become stuck until the new events stop.
+ * This is most noticeable when moving a high frequency mouse.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable poll sentinels.
+ * - "1": Enable poll sentinels. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL"
+
+/**
+ * Override for SDL_GetPreferredLocales().
+ *
+ * If set, this will be favored over anything the OS might report for the
+ * user's preferred locales. Changing this hint at runtime will not generate a
+ * SDL_EVENT_LOCALE_CHANGED event (but if you can change the hint, you can
+ * push your own event, if you want).
+ *
+ * The format of this hint is a comma-separated list of language and locale,
+ * combined with an underscore, as is a common format: "en_GB". Locale is
+ * optional: "en". So you might have a list like this: "en_GB,jp,es_PT"
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES"
+
+/**
+ * A variable that decides whether to send SDL_EVENT_QUIT when closing the
+ * last window.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will not send an SDL_EVENT_QUIT event when the last window is
+ * requesting to close. Note that in this case, there are still other
+ * legitimate reasons one might get an SDL_EVENT_QUIT event: choosing "Quit"
+ * from the macOS menu bar, sending a SIGINT (ctrl-c) on Unix, etc.
+ * - "1": SDL will send a quit event when the last window is requesting to
+ * close. (default)
+ *
+ * If there is at least one active system tray icon, SDL_EVENT_QUIT will
+ * instead be sent when both the last window will be closed and the last tray
+ * icon will be destroyed.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE"
+
+/**
+ * A variable controlling whether the Direct3D device is initialized for
+ * thread-safe operations.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Thread-safety is not enabled. (default)
+ * - "1": Thread-safety is enabled.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE"
+
+/**
+ * A variable controlling whether to enable Direct3D 11+'s Debug Layer.
+ *
+ * This variable does not have any effect on the Direct3D 9 based renderer.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable Debug Layer use. (default)
+ * - "1": Enable Debug Layer use.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG"
+
+/**
+ * A variable controlling whether to enable Vulkan Validation Layers.
+ *
+ * This variable can be set to the following values:
+ *
+ * - "0": Disable Validation Layer use
+ * - "1": Enable Validation Layer use
+ *
+ * By default, SDL does not use Vulkan Validation Layers.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_VULKAN_DEBUG "SDL_RENDER_VULKAN_DEBUG"
+
+/**
+ * A variable controlling whether to create the GPU device in debug mode.
+ *
+ * This variable can be set to the following values:
+ *
+ * - "0": Disable debug mode use (default)
+ * - "1": Enable debug mode use
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_GPU_DEBUG "SDL_RENDER_GPU_DEBUG"
+
+/**
+ * A variable controlling whether to prefer a low-power GPU on multi-GPU
+ * systems.
+ *
+ * This variable can be set to the following values:
+ *
+ * - "0": Prefer high-performance GPU (default)
+ * - "1": Prefer low-power GPU
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_GPU_LOW_POWER "SDL_RENDER_GPU_LOW_POWER"
+
+/**
+ * A variable specifying which render driver to use.
+ *
+ * If the application doesn't pick a specific renderer to use, this variable
+ * specifies the name of the preferred renderer. If the preferred renderer
+ * can't be initialized, creating a renderer will fail.
+ *
+ * This variable is case insensitive and can be set to the following values:
+ *
+ * - "direct3d"
+ * - "direct3d11"
+ * - "direct3d12"
+ * - "opengl"
+ * - "opengles2"
+ * - "opengles"
+ * - "metal"
+ * - "vulkan"
+ * - "gpu"
+ * - "software"
+ *
+ * This hint accepts a comma-separated list of driver names, and each will be
+ * tried in the order listed when creating a renderer until one succeeds or
+ * all of them fail.
+ *
+ * The default varies by platform, but it's the first one in the list that is
+ * available on the current platform.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER"
+
+/**
+ * A variable controlling how the 2D render API renders lines.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use the default line drawing method (Bresenham's line algorithm)
+ * - "1": Use the driver point API using Bresenham's line algorithm (correct,
+ * draws many points)
+ * - "2": Use the driver line API (occasionally misses line endpoints based on
+ * hardware driver quirks
+ * - "3": Use the driver geometry API (correct, draws thicker diagonal lines)
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD"
+
+/**
+ * A variable controlling whether the Metal render driver select low power
+ * device over default one.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use the preferred OS device. (default)
+ * - "1": Select a low power device.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE"
+
+/**
+ * A variable controlling whether updates to the SDL screen surface should be
+ * synchronized with the vertical refresh, to avoid tearing.
+ *
+ * This hint overrides the application preference when creating a renderer.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable vsync. (default)
+ * - "1": Enable vsync.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
+
+/**
+ * A variable to control whether the return key on the soft keyboard should
+ * hide the soft keyboard on Android and iOS.
+ *
+ * This hint sets the default value of SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The return key will be handled as a key event. (default)
+ * - "1": The return key will hide the keyboard.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME"
+
+/**
+ * A variable containing a list of ROG gamepad capable mice.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ *
+ * \sa SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED
+ */
+#define SDL_HINT_ROG_GAMEPAD_MICE "SDL_ROG_GAMEPAD_MICE"
+
+/**
+ * A variable containing a list of devices that are not ROG gamepad capable
+ * mice.
+ *
+ * This will override SDL_HINT_ROG_GAMEPAD_MICE and the built in device list.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs in
+ * hexadecimal form, e.g.
+ *
+ * `0xAAAA/0xBBBB,0xCCCC/0xDDDD`
+ *
+ * The variable can also take the form of "@file", in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED "SDL_ROG_GAMEPAD_MICE_EXCLUDED"
+
+/**
+ * A variable controlling which Dispmanx layer to use on a Raspberry PI.
+ *
+ * Also known as Z-order. The variable can take a negative or positive value.
+ * The default is 10000.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER"
+
+/**
+ * Specify an "activity name" for screensaver inhibition.
+ *
+ * Some platforms, notably Linux desktops, list the applications which are
+ * inhibiting the screensaver or other power-saving features.
+ *
+ * This hint lets you specify the "activity name" sent to the OS when
+ * SDL_DisableScreenSaver() is used (or the screensaver is automatically
+ * disabled). The contents of this hint are used when the screensaver is
+ * disabled. You should use a string that describes what your program is doing
+ * (and, therefore, why the screensaver is disabled). For example, "Playing a
+ * game" or "Watching a video".
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "Playing a game" or something similar.
+ *
+ * This hint should be set before calling SDL_DisableScreenSaver()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME "SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME"
+
+/**
+ * A variable controlling whether SDL calls dbus_shutdown() on quit.
+ *
+ * This is useful as a debug tool to validate memory leaks, but shouldn't ever
+ * be set in production applications, as other libraries used by the
+ * application might use dbus under the hood and this can cause crashes if
+ * they continue after SDL_Quit().
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will not call dbus_shutdown() on quit. (default)
+ * - "1": SDL will call dbus_shutdown() on quit.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_SHUTDOWN_DBUS_ON_QUIT "SDL_SHUTDOWN_DBUS_ON_QUIT"
+
+/**
+ * A variable that specifies a backend to use for title storage.
+ *
+ * By default, SDL will try all available storage backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app or
+ * user to force a specific target, such as "pc" if, say, you are on Steam but
+ * want to avoid SteamRemoteStorage for title data.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_STORAGE_TITLE_DRIVER "SDL_STORAGE_TITLE_DRIVER"
+
+/**
+ * A variable that specifies a backend to use for user storage.
+ *
+ * By default, SDL will try all available storage backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app or
+ * user to force a specific target, such as "pc" if, say, you are on Steam but
+ * want to avoid SteamRemoteStorage for user data.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_STORAGE_USER_DRIVER "SDL_STORAGE_USER_DRIVER"
+
+/**
+ * Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as
+ * realtime.
+ *
+ * On some platforms, like Linux, a realtime priority thread may be subject to
+ * restrictions that require special handling by the application. This hint
+ * exists to let SDL know that the app is prepared to handle said
+ * restrictions.
+ *
+ * On Linux, SDL will apply the following configuration to any thread that
+ * becomes realtime:
+ *
+ * - The SCHED_RESET_ON_FORK bit will be set on the scheduling policy,
+ * - An RLIMIT_RTTIME budget will be configured to the rtkit specified limit.
+ * - Exceeding this limit will result in the kernel sending SIGKILL to the
+ * app, refer to the man pages for more information.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": default platform specific behaviour
+ * - "1": Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling
+ * policy
+ *
+ * This hint should be set before calling SDL_SetCurrentThreadPriority()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL "SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL"
+
+/**
+ * A string specifying additional information to use with
+ * SDL_SetCurrentThreadPriority.
+ *
+ * By default SDL_SetCurrentThreadPriority will make appropriate system
+ * changes in order to apply a thread priority. For example on systems using
+ * pthreads the scheduler policy is changed automatically to a policy that
+ * works well with a given priority. Code which has specific requirements can
+ * override SDL's default behavior with this hint.
+ *
+ * pthread hint values are "current", "other", "fifo" and "rr". Currently no
+ * other platform hint values are defined but may be in the future.
+ *
+ * On Linux, the kernel may send SIGKILL to realtime tasks which exceed the
+ * distro configured execution budget for rtkit. This budget can be queried
+ * through RLIMIT_RTTIME after calling SDL_SetCurrentThreadPriority().
+ *
+ * This hint should be set before calling SDL_SetCurrentThreadPriority()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_THREAD_PRIORITY_POLICY "SDL_THREAD_PRIORITY_POLICY"
+
+/**
+ * A variable that controls the timer resolution, in milliseconds.
+ *
+ * The higher resolution the timer, the more frequently the CPU services timer
+ * interrupts, and the more precise delays are, but this takes up power and
+ * CPU time. This hint is only used on Windows.
+ *
+ * See this blog post for more information:
+ * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/
+ *
+ * The default value is "1".
+ *
+ * If this variable is set to "0", the system timer resolution is not set.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION"
+
+/**
+ * A variable controlling whether touch events should generate synthetic mouse
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Touch events will not generate mouse events.
+ * - "1": Touch events will generate mouse events. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS"
+
+/**
+ * A variable controlling whether trackpads should be treated as touch
+ * devices.
+ *
+ * On macOS (and possibly other platforms in the future), SDL will report
+ * touches on a trackpad as mouse input, which is generally what users expect
+ * from this device; however, these are often actually full multitouch-capable
+ * touch devices, so it might be preferable to some apps to treat them as
+ * such.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Trackpad will send mouse events. (default)
+ * - "1": Trackpad will send touch events.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_TRACKPAD_IS_TOUCH_ONLY "SDL_TRACKPAD_IS_TOUCH_ONLY"
+
+/**
+ * A variable controlling whether the Android / tvOS remotes should be listed
+ * as joystick devices, instead of sending keyboard events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Remotes send enter/escape/arrow key events.
+ * - "1": Remotes are available as 2 axis, 2 button joysticks. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
+
+/**
+ * A variable controlling whether the screensaver is enabled.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable screensaver. (default)
+ * - "1": Enable screensaver.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER"
+
+/**
+ * A comma separated list containing the names of the displays that SDL should
+ * sort to the front of the display list.
+ *
+ * When this hint is set, displays with matching name strings will be
+ * prioritized in the list of displays, as exposed by calling
+ * SDL_GetDisplays(), with the first listed becoming the primary display. The
+ * naming convention can vary depending on the environment, but it is usually
+ * a connector name (e.g. 'DP-1', 'DP-2', 'HDMI-A-1',etc...).
+ *
+ * On Wayland and X11 desktops, the connector names associated with displays
+ * can typically be found by using the `xrandr` utility.
+ *
+ * This hint is currently supported on the following drivers:
+ *
+ * - KMSDRM (kmsdrm)
+ * - Wayland (wayland)
+ * - X11 (x11)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_DISPLAY_PRIORITY "SDL_VIDEO_DISPLAY_PRIORITY"
+
+/**
+ * Tell the video driver that we only want a double buffer.
+ *
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that
+ * wastes no CPU time on waiting for vsync after issuing a flip, but
+ * introduces a frame of latency. On the other hand, using a double buffer
+ * scheme instead is recommended for cases where low latency is an important
+ * factor because we save a whole frame of latency.
+ *
+ * We do so by waiting for vsync immediately after issuing a flip, usually
+ * just after eglSwapBuffers call in the backend's *_SwapWindow function.
+ *
+ * This hint is currently supported on the following drivers:
+ *
+ * - Raspberry Pi (raspberrypi)
+ * - Wayland (wayland)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER"
+
+/**
+ * A variable that specifies a video backend to use.
+ *
+ * By default, SDL will try all available video backends in a reasonable order
+ * until it finds one that can work, but this hint allows the app or user to
+ * force a specific target, such as "x11" if, say, you are on Wayland but want
+ * to try talking to the X server instead.
+ *
+ * This hint accepts a comma-separated list of driver names, and each will be
+ * tried in the order listed during init, until one succeeds or all of them
+ * fail.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_DRIVER "SDL_VIDEO_DRIVER"
+
+/**
+ * A variable controlling whether the dummy video driver saves output frames.
+ *
+ * - "0": Video frames are not saved to disk. (default)
+ * - "1": Video frames are saved to files in the format "SDL_windowX-Y.bmp",
+ * where X is the window ID, and Y is the frame number.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_DUMMY_SAVE_FRAMES "SDL_VIDEO_DUMMY_SAVE_FRAMES"
+
+/**
+ * If eglGetPlatformDisplay fails, fall back to calling eglGetDisplay.
+ *
+ * The variable can be set to one of the following values:
+ *
+ * - "0": Do not fall back to eglGetDisplay.
+ * - "1": Fall back to eglGetDisplay if eglGetPlatformDisplay fails. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_EGL_ALLOW_GETDISPLAY_FALLBACK "SDL_VIDEO_EGL_ALLOW_GETDISPLAY_FALLBACK"
+
+/**
+ * A variable controlling whether the OpenGL context should be created with
+ * EGL.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use platform-specific GL context creation API (GLX, WGL, CGL, etc).
+ * (default)
+ * - "1": Use EGL
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_FORCE_EGL "SDL_VIDEO_FORCE_EGL"
+
+/**
+ * A variable that specifies the policy for fullscreen Spaces on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable Spaces support (FULLSCREEN_DESKTOP won't use them and
+ * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" button on their
+ * titlebars).
+ * - "1": Enable Spaces support (FULLSCREEN_DESKTOP will use them and
+ * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" button on their
+ * titlebars). (default)
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES"
+
+/**
+ * A variable that specifies the menu visibility when a window is fullscreen
+ * in Spaces on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The menu will be hidden when the window is in a fullscreen space,
+ * and not accessible by moving the mouse to the top of the screen.
+ * - "1": The menu will be accessible when the window is in a fullscreen
+ * space.
+ * - "auto": The menu will be hidden if fullscreen mode was toggled on
+ * programmatically via `SDL_SetWindowFullscreen()`, and accessible if
+ * fullscreen was entered via the "fullscreen" button on the window title
+ * bar. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_MAC_FULLSCREEN_MENU_VISIBILITY "SDL_VIDEO_MAC_FULLSCREEN_MENU_VISIBILITY"
+
+/**
+ * A variable controlling whether fullscreen windows are minimized when they
+ * lose focus.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Fullscreen windows will not be minimized when they lose focus.
+ * (default)
+ * - "1": Fullscreen windows are minimized when they lose focus.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS"
+
+/**
+ * A variable controlling whether the offscreen video driver saves output
+ * frames.
+ *
+ * This only saves frames that are generated using software rendering, not
+ * accelerated OpenGL rendering.
+ *
+ * - "0": Video frames are not saved to disk. (default)
+ * - "1": Video frames are saved to files in the format "SDL_windowX-Y.bmp",
+ * where X is the window ID, and Y is the frame number.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_OFFSCREEN_SAVE_FRAMES "SDL_VIDEO_OFFSCREEN_SAVE_FRAMES"
+
+/**
+ * A variable controlling whether all window operations will block until
+ * complete.
+ *
+ * Window systems that run asynchronously may not have the results of window
+ * operations that resize or move the window applied immediately upon the
+ * return of the requesting function. Setting this hint will cause such
+ * operations to block after every call until the pending operation has
+ * completed. Setting this to '1' is the equivalent of calling
+ * SDL_SyncWindow() after every function call.
+ *
+ * Be aware that amount of time spent blocking while waiting for window
+ * operations to complete can be quite lengthy, as animations may have to
+ * complete, which can take upwards of multiple seconds in some cases.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Window operations are non-blocking. (default)
+ * - "1": Window operations will block until completed.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_SYNC_WINDOW_OPERATIONS "SDL_VIDEO_SYNC_WINDOW_OPERATIONS"
+
+/**
+ * A variable controlling whether the libdecor Wayland backend is allowed to
+ * be used.
+ *
+ * libdecor is used over xdg-shell when xdg-decoration protocol is
+ * unavailable.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": libdecor use is disabled.
+ * - "1": libdecor use is enabled. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR"
+
+/**
+ * A variable controlling whether video mode emulation is enabled under
+ * Wayland.
+ *
+ * When this hint is set, a standard set of emulated CVT video modes will be
+ * exposed for use by the application. If it is disabled, the only modes
+ * exposed will be the logical desktop size and, in the case of a scaled
+ * desktop, the native display resolution.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Video mode emulation is disabled.
+ * - "1": Video mode emulation is enabled. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION "SDL_VIDEO_WAYLAND_MODE_EMULATION"
+
+/**
+ * A variable controlling how modes with a non-native aspect ratio are
+ * displayed under Wayland.
+ *
+ * When this hint is set, the requested scaling will be used when displaying
+ * fullscreen video modes that don't match the display's native aspect ratio.
+ * This is contingent on compositor viewport support.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "aspect" - Video modes will be displayed scaled, in their proper aspect
+ * ratio, with black bars.
+ * - "stretch" - Video modes will be scaled to fill the entire display.
+ * (default)
+ * - "none" - Video modes will be displayed as 1:1 with no scaling.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_MODE_SCALING "SDL_VIDEO_WAYLAND_MODE_SCALING"
+
+/**
+ * A variable controlling whether the libdecor Wayland backend is preferred
+ * over native decorations.
+ *
+ * When this hint is set, libdecor will be used to provide window decorations,
+ * even if xdg-decoration is available. (Note that, by default, libdecor will
+ * use xdg-decoration itself if available).
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": libdecor is enabled only if server-side decorations are unavailable.
+ * (default)
+ * - "1": libdecor is always enabled if available.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR"
+
+/**
+ * A variable forcing non-DPI-aware Wayland windows to output at 1:1 scaling.
+ *
+ * This must be set before initializing the video subsystem.
+ *
+ * When this hint is set, Wayland windows that are not flagged as being
+ * DPI-aware will be output with scaling designed to force 1:1 pixel mapping.
+ *
+ * This is intended to allow legacy applications to be displayed without
+ * desktop scaling being applied, and has issues with certain display
+ * configurations, as this forces the window to behave in a way that Wayland
+ * desktops were not designed to accommodate:
+ *
+ * - Rounding errors can result with odd window sizes and/or desktop scales,
+ * which can cause the window contents to appear slightly blurry.
+ * - Positioning the window may be imprecise due to unit conversions and
+ * rounding.
+ * - The window may be unusably small on scaled desktops.
+ * - The window may jump in size when moving between displays of different
+ * scale factors.
+ * - Displays may appear to overlap when using a multi-monitor setup with
+ * scaling enabled.
+ * - Possible loss of cursor precision due to the logical size of the window
+ * being reduced.
+ *
+ * New applications should be designed with proper DPI awareness handling
+ * instead of enabling this.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Windows will be scaled normally.
+ * - "1": Windows will be forced to scale to achieve 1:1 output.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY "SDL_VIDEO_WAYLAND_SCALE_TO_DISPLAY"
+
+/**
+ * A variable specifying which shader compiler to preload when using the
+ * Chrome ANGLE binaries.
+ *
+ * SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It can
+ * use two different sets of binaries, those compiled by the user from source
+ * or those provided by the Chrome browser. In the later case, these binaries
+ * require that SDL loads a DLL providing the shader compiler.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "d3dcompiler_46.dll" - best for Vista or later. (default)
+ * - "d3dcompiler_43.dll" - for XP support.
+ * - "none" - do not load any library, useful if you compiled ANGLE from
+ * source and included the compiler in your binaries.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER"
+
+/**
+ * A variable controlling whether SDL should call XSelectInput() to enable
+ * input events on X11 windows wrapped by SDL windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Don't call XSelectInput(), assuming the native window code has done
+ * it already.
+ * - "1": Call XSelectInput() to enable input events. (default)
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.10.
+ */
+#define SDL_HINT_VIDEO_X11_EXTERNAL_WINDOW_INPUT "SDL_VIDEO_X11_EXTERNAL_WINDOW_INPUT"
+
+/**
+ * A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint
+ * should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable _NET_WM_BYPASS_COMPOSITOR.
+ * - "1": Enable _NET_WM_BYPASS_COMPOSITOR. (default)
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
+
+/**
+ * A variable controlling whether the X11 _NET_WM_PING protocol should be
+ * supported.
+ *
+ * By default SDL will use _NET_WM_PING, but for applications that know they
+ * will not always be able to respond to ping requests in a timely manner they
+ * can turn it off to avoid the window manager thinking the app is hung.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable _NET_WM_PING.
+ * - "1": Enable _NET_WM_PING. (default)
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING"
+
+/**
+ * A variable controlling whether SDL uses DirectColor visuals.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable DirectColor visuals.
+ * - "1": Enable DirectColor visuals. (default)
+ *
+ * This hint should be set before initializing the video subsystem.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_NODIRECTCOLOR "SDL_VIDEO_X11_NODIRECTCOLOR"
+
+/**
+ * A variable forcing the content scaling factor for X11 displays.
+ *
+ * The variable can be set to a floating point value in the range 1.0-10.0f
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_SCALING_FACTOR "SDL_VIDEO_X11_SCALING_FACTOR"
+
+/**
+ * A variable forcing the visual ID used for X11 display modes.
+ *
+ * This hint should be set before initializing the video subsystem.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_VISUALID "SDL_VIDEO_X11_VISUALID"
+
+/**
+ * A variable forcing the visual ID chosen for new X11 windows.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID"
+
+/**
+ * A variable controlling whether the X11 XRandR extension should be used.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable XRandR.
+ * - "1": Enable XRandR. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR"
+
+/**
+ * A variable controlling whether touch should be enabled on the back panel of
+ * the PlayStation Vita.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable touch on the back panel.
+ * - "1": Enable touch on the back panel. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_ENABLE_BACK_TOUCH "SDL_VITA_ENABLE_BACK_TOUCH"
+
+/**
+ * A variable controlling whether touch should be enabled on the front panel
+ * of the PlayStation Vita.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable touch on the front panel.
+ * - "1": Enable touch on the front panel. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_ENABLE_FRONT_TOUCH "SDL_VITA_ENABLE_FRONT_TOUCH"
+
+/**
+ * A variable controlling the module path on the PlayStation Vita.
+ *
+ * This hint defaults to "app0:module"
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_MODULE_PATH "SDL_VITA_MODULE_PATH"
+
+/**
+ * A variable controlling whether to perform PVR initialization on the
+ * PlayStation Vita.
+ *
+ * - "0": Skip PVR initialization.
+ * - "1": Perform the normal PVR initialization. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_PVR_INIT "SDL_VITA_PVR_INIT"
+
+/**
+ * A variable overriding the resolution reported on the PlayStation Vita.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "544": 544p (default)
+ * - "720": 725p for PSTV
+ * - "1080": 1088i for PSTV
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_RESOLUTION "SDL_VITA_RESOLUTION"
+
+/**
+ * A variable controlling whether OpenGL should be used instead of OpenGL ES
+ * on the PlayStation Vita.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use OpenGL ES. (default)
+ * - "1": Use OpenGL.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_PVR_OPENGL "SDL_VITA_PVR_OPENGL"
+
+/**
+ * A variable controlling which touchpad should generate synthetic mouse
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Only front touchpad should generate mouse events. (default)
+ * - "1": Only back touchpad should generate mouse events.
+ * - "2": Both touchpads should generate mouse events.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_VITA_TOUCH_MOUSE_DEVICE"
+
+/**
+ * A variable overriding the display index used in SDL_Vulkan_CreateSurface()
+ *
+ * The display index starts at 0, which is the default.
+ *
+ * This hint should be set before calling SDL_Vulkan_CreateSurface()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VULKAN_DISPLAY "SDL_VULKAN_DISPLAY"
+
+/**
+ * Specify the Vulkan library to load.
+ *
+ * This hint should be set before creating a Vulkan window or calling
+ * SDL_Vulkan_LoadLibrary().
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_VULKAN_LIBRARY "SDL_VULKAN_LIBRARY"
+
+/**
+ * A variable controlling how the fact chunk affects the loading of a WAVE
+ * file.
+ *
+ * The fact chunk stores information about the number of samples of a WAVE
+ * file. The Standards Update from Microsoft notes that this value can be used
+ * to 'determine the length of the data in seconds'. This is especially useful
+ * for compressed formats (for which this is a mandatory chunk) if they
+ * produce multiple sample frames per block and truncating the block is not
+ * allowed. The fact chunk can exactly specify how many sample frames there
+ * should be in this case.
+ *
+ * Unfortunately, most application seem to ignore the fact chunk and so SDL
+ * ignores it by default as well.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "truncate" - Use the number of samples to truncate the wave data if the
+ * fact chunk is present and valid.
+ * - "strict" - Like "truncate", but raise an error if the fact chunk is
+ * invalid, not present for non-PCM formats, or if the data chunk doesn't
+ * have that many samples.
+ * - "ignorezero" - Like "truncate", but ignore fact chunk if the number of
+ * samples is zero.
+ * - "ignore" - Ignore fact chunk entirely. (default)
+ *
+ * This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK"
+
+/**
+ * A variable controlling the maximum number of chunks in a WAVE file.
+ *
+ * This sets an upper bound on the number of chunks in a WAVE file to avoid
+ * wasting time on malformed or corrupt WAVE files. This defaults to "10000".
+ *
+ * This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WAVE_CHUNK_LIMIT "SDL_WAVE_CHUNK_LIMIT"
+
+/**
+ * A variable controlling how the size of the RIFF chunk affects the loading
+ * of a WAVE file.
+ *
+ * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE
+ * file) is not always reliable. In case the size is wrong, it's possible to
+ * just ignore it and step through the chunks until a fixed limit is reached.
+ *
+ * Note that files that have trailing data unrelated to the WAVE file or
+ * corrupt files may slow down the loading process without a reliable
+ * boundary. By default, SDL stops after 10000 chunks to prevent wasting time.
+ * Use SDL_HINT_WAVE_CHUNK_LIMIT to adjust this value.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "force" - Always use the RIFF chunk size as a boundary for the chunk
+ * search.
+ * - "ignorezero" - Like "force", but a zero size searches up to 4 GiB.
+ * (default)
+ * - "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB.
+ * - "maximum" - Search for chunks until the end of file. (not recommended)
+ *
+ * This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE"
+
+/**
+ * A variable controlling how a truncated WAVE file is handled.
+ *
+ * A WAVE file is considered truncated if any of the chunks are incomplete or
+ * the data chunk size is not a multiple of the block size. By default, SDL
+ * decodes until the first incomplete block, as most applications seem to do.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "verystrict" - Raise an error if the file is truncated.
+ * - "strict" - Like "verystrict", but the size of the RIFF chunk is ignored.
+ * - "dropframe" - Decode until the first incomplete sample frame.
+ * - "dropblock" - Decode until the first incomplete block. (default)
+ *
+ * This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION"
+
+/**
+ * A variable controlling whether the window is activated when the
+ * SDL_RaiseWindow function is called.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The window is not activated when the SDL_RaiseWindow function is
+ * called.
+ * - "1": The window is activated when the SDL_RaiseWindow function is called.
+ * (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED "SDL_WINDOW_ACTIVATE_WHEN_RAISED"
+
+/**
+ * A variable controlling whether the window is activated when the
+ * SDL_ShowWindow function is called.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The window is not activated when the SDL_ShowWindow function is
+ * called.
+ * - "1": The window is activated when the SDL_ShowWindow function is called.
+ * (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN "SDL_WINDOW_ACTIVATE_WHEN_SHOWN"
+
+/**
+ * If set to "0" then never set the top-most flag on an SDL Window even if the
+ * application requests it.
+ *
+ * This is a debugging aid for developers and not expected to be used by end
+ * users.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": don't allow topmost
+ * - "1": allow topmost (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOW_ALLOW_TOPMOST "SDL_WINDOW_ALLOW_TOPMOST"
+
+/**
+ * A variable controlling whether the window frame and title bar are
+ * interactive when the cursor is hidden.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The window frame is not interactive when the cursor is hidden (no
+ * move, resize, etc).
+ * - "1": The window frame is interactive when the cursor is hidden. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN"
+
+/**
+ * A variable controlling whether SDL generates window-close events for Alt+F4
+ * on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will only do normal key handling for Alt+F4.
+ * - "1": SDL will generate a window-close event when it sees Alt+F4.
+ * (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4 "SDL_WINDOWS_CLOSE_ON_ALT_F4"
+
+/**
+ * A variable controlling whether menus can be opened with their keyboard
+ * shortcut (Alt+mnemonic).
+ *
+ * If the mnemonics are enabled, then menus can be opened by pressing the Alt
+ * key and the corresponding mnemonic (for example, Alt+F opens the File
+ * menu). However, in case an invalid mnemonic is pressed, Windows makes an
+ * audible beep to convey that nothing happened. This is true even if the
+ * window has no menu at all!
+ *
+ * Because most SDL applications don't have menus, and some want to use the
+ * Alt key for other purposes, SDL disables mnemonics (and the beeping) by
+ * default.
+ *
+ * Note: This also affects keyboard events: with mnemonics enabled, when a
+ * menu is opened from the keyboard, you will not receive a KEYUP event for
+ * the mnemonic key, and *might* not receive one for Alt.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Alt+mnemonic does nothing, no beeping. (default)
+ * - "1": Alt+mnemonic opens menus, invalid mnemonics produce a beep.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS"
+
+/**
+ * A variable controlling whether the windows message loop is processed by
+ * SDL.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The window message loop is not run.
+ * - "1": The window message loop is processed in SDL_PumpEvents(). (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP"
+
+/**
+ * A variable controlling whether GameInput is used for raw keyboard and mouse
+ * on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": GameInput is not used for raw keyboard and mouse events.
+ * - "1": GameInput is used for raw keyboard and mouse events, if available.
+ * (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_GAMEINPUT "SDL_WINDOWS_GAMEINPUT"
+
+/**
+ * A variable controlling whether raw keyboard events are used on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The Windows message loop is used for keyboard events. (default)
+ * - "1": Low latency raw keyboard events are used.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_RAW_KEYBOARD "SDL_WINDOWS_RAW_KEYBOARD"
+
+/**
+ * A variable controlling whether SDL uses Kernel Semaphores on Windows.
+ *
+ * Kernel Semaphores are inter-process and require a context switch on every
+ * interaction. On Windows 8 and newer, the WaitOnAddress API is available.
+ * Using that and atomics to implement semaphores increases performance. SDL
+ * will fall back to Kernel Objects on older OS versions or if forced to by
+ * this hint.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use Atomics and WaitOnAddress API when available, otherwise fall
+ * back to Kernel Objects. (default)
+ * - "1": Force the use of Kernel Objects in all cases.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL"
+
+/**
+ * A variable to specify custom icon resource id from RC file on Windows
+ * platform.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON"
+
+/**
+ * A variable to specify custom icon resource id from RC file on Windows
+ * platform.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL"
+
+/**
+ * A variable controlling whether SDL uses the D3D9Ex API introduced in
+ * Windows Vista, instead of normal D3D9.
+ *
+ * Direct3D 9Ex contains changes to state management that can eliminate device
+ * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may
+ * require some changes to your application to cope with the new behavior, so
+ * this is disabled by default.
+ *
+ * For more information on Direct3D 9Ex, see:
+ *
+ * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex
+ * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Use the original Direct3D 9 API. (default)
+ * - "1": Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex
+ * is unavailable)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX"
+
+/**
+ * A variable controlling whether SDL will clear the window contents when the
+ * WM_ERASEBKGND message is received.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0"/"never": Never clear the window.
+ * - "1"/"initial": Clear the window when the first WM_ERASEBKGND event fires.
+ * (default)
+ * - "2"/"always": Clear the window on every WM_ERASEBKGND event.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_WINDOWS_ERASE_BACKGROUND_MODE "SDL_WINDOWS_ERASE_BACKGROUND_MODE"
+
+/**
+ * A variable controlling whether X11 windows are marked as override-redirect.
+ *
+ * If set, this _might_ increase framerate at the expense of the desktop not
+ * working as expected. Override-redirect windows aren't noticed by the window
+ * manager at all.
+ *
+ * You should probably only use this for fullscreen windows, and you probably
+ * shouldn't even use it for that. But it's here if you want to try!
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Do not mark the window as override-redirect. (default)
+ * - "1": Mark the window as override-redirect.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT"
+
+/**
+ * A variable specifying the type of an X11 window.
+ *
+ * During SDL_CreateWindow, SDL uses the _NET_WM_WINDOW_TYPE X11 property to
+ * report to the window manager the type of window it wants to create. This
+ * might be set to various things if SDL_WINDOW_TOOLTIP or
+ * SDL_WINDOW_POPUP_MENU, etc, were specified. For "normal" windows that
+ * haven't set a specific type, this hint can be used to specify a custom
+ * type. For example, a dock window might set this to
+ * "_NET_WM_WINDOW_TYPE_DOCK".
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE"
+
+/**
+ * Specify the XCB library to load for the X11 driver.
+ *
+ * The default is platform-specific, often "libX11-xcb.so.1".
+ *
+ * This hint should be set before initializing the video subsystem.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_X11_XCB_LIBRARY "SDL_X11_XCB_LIBRARY"
+
+/**
+ * A variable controlling whether XInput should be used for controller
+ * handling.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": XInput is not enabled.
+ * - "1": XInput is enabled. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
+
+/**
+ * A variable controlling response to SDL_assert failures.
+ *
+ * The variable can be set to the following case-sensitive values:
+ *
+ * - "abort": Program terminates immediately.
+ * - "break": Program triggers a debugger breakpoint.
+ * - "retry": Program reruns the SDL_assert's test again.
+ * - "ignore": Program continues on, ignoring this assertion failure this
+ * time.
+ * - "always_ignore": Program continues on, ignoring this assertion failure
+ * for the rest of the run.
+ *
+ * Note that SDL_SetAssertionHandler offers a programmatic means to deal with
+ * assertion failures through a callback, and this hint is largely intended to
+ * be used via environment variables by end users and automated tools.
+ *
+ * This hint should be set before an assertion failure is triggered and can be
+ * changed at any time.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_ASSERT "SDL_ASSERT"
+
+/**
+ * A variable controlling whether pen events should generate synthetic mouse
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Pen events will not generate mouse events.
+ * - "1": Pen events will generate mouse events. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_PEN_MOUSE_EVENTS "SDL_PEN_MOUSE_EVENTS"
+
+/**
+ * A variable controlling whether pen events should generate synthetic touch
+ * events.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Pen events will not generate touch events.
+ * - "1": Pen events will generate touch events. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.2.0.
+ */
+#define SDL_HINT_PEN_TOUCH_EVENTS "SDL_PEN_TOUCH_EVENTS"
+
+
+/**
+ * An enumeration of hint priorities.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_HintPriority
+{
+ SDL_HINT_DEFAULT,
+ SDL_HINT_NORMAL,
+ SDL_HINT_OVERRIDE
+} SDL_HintPriority;
+
+/**
+ * Set a hint with a specific priority.
+ *
+ * The priority controls the behavior when setting a hint that already has a
+ * value. Hints will replace existing hints of their priority and lower.
+ * Environment variables are considered to have override priority.
+ *
+ * \param name the hint to set.
+ * \param value the value of the hint variable.
+ * \param priority the SDL_HintPriority level for the hint.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHint
+ * \sa SDL_ResetHint
+ * \sa SDL_SetHint
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority);
+
+/**
+ * Set a hint with normal priority.
+ *
+ * Hints will not be set if there is an existing override hint or environment
+ * variable that takes precedence. You can use SDL_SetHintWithPriority() to
+ * set the hint with override priority instead.
+ *
+ * \param name the hint to set.
+ * \param value the value of the hint variable.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHint
+ * \sa SDL_ResetHint
+ * \sa SDL_SetHintWithPriority
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetHint(const char *name, const char *value);
+
+/**
+ * Reset a hint to the default value.
+ *
+ * This will reset a hint to the value of the environment variable, or NULL if
+ * the environment isn't set. Callbacks will be called normally with this
+ * change.
+ *
+ * \param name the hint to set.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetHint
+ * \sa SDL_ResetHints
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_ResetHint(const char *name);
+
+/**
+ * Reset all hints to the default values.
+ *
+ * This will reset all hints to the value of the associated environment
+ * variable, or NULL if the environment isn't set. Callbacks will be called
+ * normally with this change.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_ResetHint
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_ResetHints(void);
+
+/**
+ * Get the value of a hint.
+ *
+ * \param name the hint to query.
+ * \returns the string value of a hint or NULL if the hint isn't set.
+ *
+ * \threadsafety It is safe to call this function from any thread, however the
+ * return value only remains valid until the hint is changed; if
+ * another thread might do so, the app should supply locks
+ * and/or make a copy of the string. Note that using a hint
+ * callback instead is always thread-safe, as SDL holds a lock
+ * on the thread subsystem during the callback.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetHint
+ * \sa SDL_SetHintWithPriority
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
+
+/**
+ * Get the boolean value of a hint variable.
+ *
+ * \param name the name of the hint to get the boolean value from.
+ * \param default_value the value to return if the hint does not exist.
+ * \returns the boolean value of a hint or the provided default value if the
+ * hint does not exist.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetHint
+ * \sa SDL_SetHint
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_GetHintBoolean(const char *name, bool default_value);
+
+/**
+ * A callback used to send notifications of hint value changes.
+ *
+ * This is called an initial time during SDL_AddHintCallback with the hint's
+ * current value, and then again each time the hint's value changes.
+ *
+ * \param userdata what was passed as `userdata` to SDL_AddHintCallback().
+ * \param name what was passed as `name` to SDL_AddHintCallback().
+ * \param oldValue the previous hint value.
+ * \param newValue the new value hint is to be set to.
+ *
+ * \threadsafety This callback is fired from whatever thread is setting a new
+ * hint value. SDL holds a lock on the hint subsystem when
+ * calling this callback.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddHintCallback
+ */
+typedef void(SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
+
+/**
+ * Add a function to watch a particular hint.
+ *
+ * The callback function is called _during_ this function, to provide it an
+ * initial value, and again each time the hint's value changes.
+ *
+ * \param name the hint to watch.
+ * \param callback An SDL_HintCallback function that will be called when the
+ * hint value changes.
+ * \param userdata a pointer to pass to the callback function.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RemoveHintCallback
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata);
+
+/**
+ * Remove a function watching a particular hint.
+ *
+ * \param name the hint being watched.
+ * \param callback an SDL_HintCallback function that will be called when the
+ * hint value changes.
+ * \param userdata a pointer being passed to the callback function.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_AddHintCallback
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_RemoveHintCallback(const char *name,
+ SDL_HintCallback callback,
+ void *userdata);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_hints_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_init.h b/vendored/SDL/include/SDL3/SDL_init.h
new file mode 100644
index 0000000..27ebe4b
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_init.h
@@ -0,0 +1,497 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * # CategoryInit
+ *
+ * All SDL programs need to initialize the library before starting to work
+ * with it.
+ *
+ * Almost everything can simply call SDL_Init() near startup, with a handful
+ * of flags to specify subsystems to touch. These are here to make sure SDL
+ * does not even attempt to touch low-level pieces of the operating system
+ * that you don't intend to use. For example, you might be using SDL for video
+ * and input but chose an external library for audio, and in this case you
+ * would just need to leave off the `SDL_INIT_AUDIO` flag to make sure that
+ * external library has complete control.
+ *
+ * Most apps, when terminating, should call SDL_Quit(). This will clean up
+ * (nearly) everything that SDL might have allocated, and crucially, it'll
+ * make sure that the display's resolution is back to what the user expects if
+ * you had previously changed it for your game.
+ *
+ * SDL3 apps are strongly encouraged to call SDL_SetAppMetadata() at startup
+ * to fill in details about the program. This is completely optional, but it
+ * helps in small ways (we can provide an About dialog box for the macOS menu,
+ * we can name the app in the system's audio mixer, etc). Those that want to
+ * provide a _lot_ of information should look at the more-detailed
+ * SDL_SetAppMetadataProperty().
+ */
+
+#ifndef SDL_init_h_
+#define SDL_init_h_
+
+#include
+#include
+#include
+
+#include
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* As of version 0.5, SDL is loaded dynamically into the application */
+
+/**
+ * Initialization flags for SDL_Init and/or SDL_InitSubSystem
+ *
+ * These are the flags which may be passed to SDL_Init(). You should specify
+ * the subsystems which you will be using in your application.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_Init
+ * \sa SDL_Quit
+ * \sa SDL_InitSubSystem
+ * \sa SDL_QuitSubSystem
+ * \sa SDL_WasInit
+ */
+typedef Uint32 SDL_InitFlags;
+
+#define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */
+#define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */
+#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */
+#define SDL_INIT_HAPTIC 0x00001000u
+#define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
+#define SDL_INIT_EVENTS 0x00004000u
+#define SDL_INIT_SENSOR 0x00008000u /**< `SDL_INIT_SENSOR` implies `SDL_INIT_EVENTS` */
+#define SDL_INIT_CAMERA 0x00010000u /**< `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS` */
+
+/**
+ * Return values for optional main callbacks.
+ *
+ * Returning SDL_APP_SUCCESS or SDL_APP_FAILURE from SDL_AppInit,
+ * SDL_AppEvent, or SDL_AppIterate will terminate the program and report
+ * success/failure to the operating system. What that means is
+ * platform-dependent. On Unix, for example, on success, the process error
+ * code will be zero, and on failure it will be 1. This interface doesn't
+ * allow you to return specific exit codes, just whether there was an error
+ * generally or not.
+ *
+ * Returning SDL_APP_CONTINUE from these functions will let the app continue
+ * to run.
+ *
+ * See
+ * [Main callbacks in SDL3](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3)
+ * for complete details.
+ *
+ * \since This enum is available since SDL 3.2.0.
+ */
+typedef enum SDL_AppResult
+{
+ SDL_APP_CONTINUE, /**< Value that requests that the app continue from the main callbacks. */
+ SDL_APP_SUCCESS, /**< Value that requests termination with success from the main callbacks. */
+ SDL_APP_FAILURE /**< Value that requests termination with error from the main callbacks. */
+} SDL_AppResult;
+
+/**
+ * Function pointer typedef for SDL_AppInit.
+ *
+ * These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
+ * the scenes for apps using the optional main callbacks. Apps that want to
+ * use this should just implement SDL_AppInit directly.
+ *
+ * \param appstate a place where the app can optionally store a pointer for
+ * future use.
+ * \param argc the standard ANSI C main's argc; number of elements in `argv`.
+ * \param argv the standard ANSI C main's argv; array of command line
+ * arguments.
+ * \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
+ * terminate with success, SDL_APP_CONTINUE to continue.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef SDL_AppResult (SDLCALL *SDL_AppInit_func)(void **appstate, int argc, char *argv[]);
+
+/**
+ * Function pointer typedef for SDL_AppIterate.
+ *
+ * These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
+ * the scenes for apps using the optional main callbacks. Apps that want to
+ * use this should just implement SDL_AppIterate directly.
+ *
+ * \param appstate an optional pointer, provided by the app in SDL_AppInit.
+ * \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
+ * terminate with success, SDL_APP_CONTINUE to continue.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef SDL_AppResult (SDLCALL *SDL_AppIterate_func)(void *appstate);
+
+/**
+ * Function pointer typedef for SDL_AppEvent.
+ *
+ * These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
+ * the scenes for apps using the optional main callbacks. Apps that want to
+ * use this should just implement SDL_AppEvent directly.
+ *
+ * \param appstate an optional pointer, provided by the app in SDL_AppInit.
+ * \param event the new event for the app to examine.
+ * \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
+ * terminate with success, SDL_APP_CONTINUE to continue.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef SDL_AppResult (SDLCALL *SDL_AppEvent_func)(void *appstate, SDL_Event *event);
+
+/**
+ * Function pointer typedef for SDL_AppQuit.
+ *
+ * These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
+ * the scenes for apps using the optional main callbacks. Apps that want to
+ * use this should just implement SDL_AppEvent directly.
+ *
+ * \param appstate an optional pointer, provided by the app in SDL_AppInit.
+ * \param result the result code that terminated the app (success or failure).
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ */
+typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate, SDL_AppResult result);
+
+
+/**
+ * Initialize the SDL library.
+ *
+ * SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the
+ * two may be used interchangeably. Though for readability of your code
+ * SDL_InitSubSystem() might be preferred.
+ *
+ * The file I/O (for example: SDL_IOFromFile) and threading (SDL_CreateThread)
+ * subsystems are initialized by default. Message boxes
+ * (SDL_ShowSimpleMessageBox) also attempt to work without initializing the
+ * video subsystem, in hopes of being useful in showing an error dialog when
+ * SDL_Init fails. You must specifically initialize other subsystems if you
+ * use them in your application.
+ *
+ * Logging (such as SDL_Log) works without initialization, too.
+ *
+ * `flags` may be any of the following OR'd together:
+ *
+ * - `SDL_INIT_AUDIO`: audio subsystem; automatically initializes the events
+ * subsystem
+ * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events
+ * subsystem, should be initialized on the main thread.
+ * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the
+ * events subsystem
+ * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem
+ * - `SDL_INIT_GAMEPAD`: gamepad subsystem; automatically initializes the
+ * joystick subsystem
+ * - `SDL_INIT_EVENTS`: events subsystem
+ * - `SDL_INIT_SENSOR`: sensor subsystem; automatically initializes the events
+ * subsystem
+ * - `SDL_INIT_CAMERA`: camera subsystem; automatically initializes the events
+ * subsystem
+ *
+ * Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem()
+ * for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or
+ * call SDL_Quit() to force shutdown). If a subsystem is already loaded then
+ * this call will increase the ref-count and return.
+ *
+ * Consider reporting some basic metadata about your application before
+ * calling SDL_Init, using either SDL_SetAppMetadata() or
+ * SDL_SetAppMetadataProperty().
+ *
+ * \param flags subsystem initialization flags.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAppMetadata
+ * \sa SDL_SetAppMetadataProperty
+ * \sa SDL_InitSubSystem
+ * \sa SDL_Quit
+ * \sa SDL_SetMainReady
+ * \sa SDL_WasInit
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_Init(SDL_InitFlags flags);
+
+/**
+ * Compatibility function to initialize the SDL library.
+ *
+ * This function and SDL_Init() are interchangeable.
+ *
+ * \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_Init
+ * \sa SDL_Quit
+ * \sa SDL_QuitSubSystem
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_InitSubSystem(SDL_InitFlags flags);
+
+/**
+ * Shut down specific SDL subsystems.
+ *
+ * You still need to call SDL_Quit() even if you close all open subsystems
+ * with SDL_QuitSubSystem().
+ *
+ * \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_InitSubSystem
+ * \sa SDL_Quit
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_QuitSubSystem(SDL_InitFlags flags);
+
+/**
+ * Get a mask of the specified subsystems which are currently initialized.
+ *
+ * \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
+ * \returns a mask of all initialized subsystems if `flags` is 0, otherwise it
+ * returns the initialization status of the specified subsystems.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_Init
+ * \sa SDL_InitSubSystem
+ */
+extern SDL_DECLSPEC SDL_InitFlags SDLCALL SDL_WasInit(SDL_InitFlags flags);
+
+/**
+ * Clean up all initialized subsystems.
+ *
+ * You should call this function even if you have already shutdown each
+ * initialized subsystem with SDL_QuitSubSystem(). It is safe to call this
+ * function even in the case of errors in initialization.
+ *
+ * You can use this function with atexit() to ensure that it is run when your
+ * application is shutdown, but it is not wise to do this from a library or
+ * other dynamically loaded code.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_Init
+ * \sa SDL_QuitSubSystem
+ */
+extern SDL_DECLSPEC void SDLCALL SDL_Quit(void);
+
+/**
+ * Return whether this is the main thread.
+ *
+ * On Apple platforms, the main thread is the thread that runs your program's
+ * main() entry point. On other platforms, the main thread is the one that
+ * calls SDL_Init(SDL_INIT_VIDEO), which should usually be the one that runs
+ * your program's main() entry point. If you are using the main callbacks,
+ * SDL_AppInit(), SDL_AppIterate(), and SDL_AppQuit() are all called on the
+ * main thread.
+ *
+ * \returns true if this thread is the main thread, or false otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_RunOnMainThread
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_IsMainThread(void);
+
+/**
+ * Callback run on the main thread.
+ *
+ * \param userdata an app-controlled pointer that is passed to the callback.
+ *
+ * \since This datatype is available since SDL 3.2.0.
+ *
+ * \sa SDL_RunOnMainThread
+ */
+typedef void (SDLCALL *SDL_MainThreadCallback)(void *userdata);
+
+/**
+ * Call a function on the main thread during event processing.
+ *
+ * If this is called on the main thread, the callback is executed immediately.
+ * If this is called on another thread, this callback is queued for execution
+ * on the main thread during event processing.
+ *
+ * Be careful of deadlocks when using this functionality. You should not have
+ * the main thread wait for the current thread while this function is being
+ * called with `wait_complete` true.
+ *
+ * \param callback the callback to call on the main thread.
+ * \param userdata a pointer that is passed to `callback`.
+ * \param wait_complete true to wait for the callback to complete, false to
+ * return immediately.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_IsMainThread
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_RunOnMainThread(SDL_MainThreadCallback callback, void *userdata, bool wait_complete);
+
+/**
+ * Specify basic metadata about your app.
+ *
+ * You can optionally provide metadata about your app to SDL. This is not
+ * required, but strongly encouraged.
+ *
+ * There are several locations where SDL can make use of metadata (an "About"
+ * box in the macOS menu bar, the name of the app can be shown on some audio
+ * mixers, etc). Any piece of metadata can be left as NULL, if a specific
+ * detail doesn't make sense for the app.
+ *
+ * This function should be called as early as possible, before SDL_Init.
+ * Multiple calls to this function are allowed, but various state might not
+ * change once it has been set up with a previous call to this function.
+ *
+ * Passing a NULL removes any previous metadata.
+ *
+ * This is a simplified interface for the most important information. You can
+ * supply significantly more detailed metadata with
+ * SDL_SetAppMetadataProperty().
+ *
+ * \param appname The name of the application ("My Game 2: Bad Guy's
+ * Revenge!").
+ * \param appversion The version of the application ("1.0.0beta5" or a git
+ * hash, or whatever makes sense).
+ * \param appidentifier A unique string in reverse-domain format that
+ * identifies this app ("com.example.mygame2").
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAppMetadataProperty
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAppMetadata(const char *appname, const char *appversion, const char *appidentifier);
+
+/**
+ * Specify metadata about your app through a set of properties.
+ *
+ * You can optionally provide metadata about your app to SDL. This is not
+ * required, but strongly encouraged.
+ *
+ * There are several locations where SDL can make use of metadata (an "About"
+ * box in the macOS menu bar, the name of the app can be shown on some audio
+ * mixers, etc). Any piece of metadata can be left out, if a specific detail
+ * doesn't make sense for the app.
+ *
+ * This function should be called as early as possible, before SDL_Init.
+ * Multiple calls to this function are allowed, but various state might not
+ * change once it has been set up with a previous call to this function.
+ *
+ * Once set, this metadata can be read using SDL_GetAppMetadataProperty().
+ *
+ * These are the supported properties:
+ *
+ * - `SDL_PROP_APP_METADATA_NAME_STRING`: The human-readable name of the
+ * application, like "My Game 2: Bad Guy's Revenge!". This will show up
+ * anywhere the OS shows the name of the application separately from window
+ * titles, such as volume control applets, etc. This defaults to "SDL
+ * Application".
+ * - `SDL_PROP_APP_METADATA_VERSION_STRING`: The version of the app that is
+ * running; there are no rules on format, so "1.0.3beta2" and "April 22nd,
+ * 2024" and a git hash are all valid options. This has no default.
+ * - `SDL_PROP_APP_METADATA_IDENTIFIER_STRING`: A unique string that
+ * identifies this app. This must be in reverse-domain format, like
+ * "com.example.mygame2". This string is used by desktop compositors to
+ * identify and group windows together, as well as match applications with
+ * associated desktop settings and icons. If you plan to package your
+ * application in a container such as Flatpak, the app ID should match the
+ * name of your Flatpak container as well. This has no default.
+ * - `SDL_PROP_APP_METADATA_CREATOR_STRING`: The human-readable name of the
+ * creator/developer/maker of this app, like "MojoWorkshop, LLC"
+ * - `SDL_PROP_APP_METADATA_COPYRIGHT_STRING`: The human-readable copyright
+ * notice, like "Copyright (c) 2024 MojoWorkshop, LLC" or whatnot. Keep this
+ * to one line, don't paste a copy of a whole software license in here. This
+ * has no default.
+ * - `SDL_PROP_APP_METADATA_URL_STRING`: A URL to the app on the web. Maybe a
+ * product page, or a storefront, or even a GitHub repository, for user's
+ * further information This has no default.
+ * - `SDL_PROP_APP_METADATA_TYPE_STRING`: The type of application this is.
+ * Currently this string can be "game" for a video game, "mediaplayer" for a
+ * media player, or generically "application" if nothing else applies.
+ * Future versions of SDL might add new types. This defaults to
+ * "application".
+ *
+ * \param name the name of the metadata property to set.
+ * \param value the value of the property, or NULL to remove that property.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_GetAppMetadataProperty
+ * \sa SDL_SetAppMetadata
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetAppMetadataProperty(const char *name, const char *value);
+
+#define SDL_PROP_APP_METADATA_NAME_STRING "SDL.app.metadata.name"
+#define SDL_PROP_APP_METADATA_VERSION_STRING "SDL.app.metadata.version"
+#define SDL_PROP_APP_METADATA_IDENTIFIER_STRING "SDL.app.metadata.identifier"
+#define SDL_PROP_APP_METADATA_CREATOR_STRING "SDL.app.metadata.creator"
+#define SDL_PROP_APP_METADATA_COPYRIGHT_STRING "SDL.app.metadata.copyright"
+#define SDL_PROP_APP_METADATA_URL_STRING "SDL.app.metadata.url"
+#define SDL_PROP_APP_METADATA_TYPE_STRING "SDL.app.metadata.type"
+
+/**
+ * Get metadata about your app.
+ *
+ * This returns metadata previously set using SDL_SetAppMetadata() or
+ * SDL_SetAppMetadataProperty(). See SDL_SetAppMetadataProperty() for the list
+ * of available properties and their meanings.
+ *
+ * \param name the name of the metadata property to get.
+ * \returns the current value of the metadata property, or the default if it
+ * is not set, NULL for properties with no default.
+ *
+ * \threadsafety It is safe to call this function from any thread, although
+ * the string returned is not protected and could potentially be
+ * freed if you call SDL_SetAppMetadataProperty() to set that
+ * property from another thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAppMetadata
+ * \sa SDL_SetAppMetadataProperty
+ */
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetAppMetadataProperty(const char *name);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_init_h_ */
diff --git a/vendored/SDL/include/SDL3/SDL_intrin.h b/vendored/SDL/include/SDL3/SDL_intrin.h
new file mode 100644
index 0000000..bac6d7a
--- /dev/null
+++ b/vendored/SDL/include/SDL3/SDL_intrin.h
@@ -0,0 +1,407 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WIKI CATEGORY: Intrinsics */
+
+/**
+ * # CategoryIntrinsics
+ *
+ * SDL does some preprocessor gymnastics to determine if any CPU-specific
+ * compiler intrinsics are available, as this is not necessarily an easy thing
+ * to calculate, and sometimes depends on quirks of a system, versions of
+ * build tools, and other external forces.
+ *
+ * Apps including SDL's headers will be able to check consistent preprocessor
+ * definitions to decide if it's safe to use compiler intrinsics for a
+ * specific CPU architecture. This check only tells you that the compiler is
+ * capable of using those intrinsics; at runtime, you should still check if
+ * they are available on the current system with the
+ * [CPU info functions](https://wiki.libsdl.org/SDL3/CategoryCPUInfo)
+ * , such as SDL_HasSSE() or SDL_HasNEON(). Otherwise, the process might crash
+ * for using an unsupported CPU instruction.
+ *
+ * SDL only sets preprocessor defines for CPU intrinsics if they are
+ * supported, so apps should check with `#ifdef` and not `#if`.
+ *
+ * SDL will also include the appropriate instruction-set-specific support
+ * headers, so if SDL decides to define SDL_SSE2_INTRINSICS, it will also
+ * `#include ` as well.
+ */
+
+#ifndef SDL_intrin_h_
+#define SDL_intrin_h_
+
+#include
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_LASX_INTRINSICS
+ */
+#define SDL_LSX_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_LASX_INTRINSICS
+ */
+#define SDL_LASX_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports ARM NEON intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ * ``, ``, and ``, as appropriate.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_NEON_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports PowerPC Altivec intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_ALTIVEC_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel MMX intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE_INTRINSICS
+ */
+#define SDL_MMX_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel SSE intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE2_INTRINSICS
+ * \sa SDL_SSE3_INTRINSICS
+ * \sa SDL_SSE4_1_INTRINSICS
+ * \sa SDL_SSE4_2_INTRINSICS
+ */
+#define SDL_SSE_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel SSE2 intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE_INTRINSICS
+ * \sa SDL_SSE3_INTRINSICS
+ * \sa SDL_SSE4_1_INTRINSICS
+ * \sa SDL_SSE4_2_INTRINSICS
+ */
+#define SDL_SSE2_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel SSE3 intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE_INTRINSICS
+ * \sa SDL_SSE2_INTRINSICS
+ * \sa SDL_SSE4_1_INTRINSICS
+ * \sa SDL_SSE4_2_INTRINSICS
+ */
+#define SDL_SSE3_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel SSE4.1 intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE_INTRINSICS
+ * \sa SDL_SSE2_INTRINSICS
+ * \sa SDL_SSE3_INTRINSICS
+ * \sa SDL_SSE4_2_INTRINSICS
+ */
+#define SDL_SSE4_1_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel SSE4.2 intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_SSE_INTRINSICS
+ * \sa SDL_SSE2_INTRINSICS
+ * \sa SDL_SSE3_INTRINSICS
+ * \sa SDL_SSE4_1_INTRINSICS
+ */
+#define SDL_SSE4_2_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel AVX intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_AVX2_INTRINSICS
+ * \sa SDL_AVX512F_INTRINSICS
+ */
+#define SDL_AVX_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel AVX2 intrinsics.
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_AVX_INTRINSICS
+ * \sa SDL_AVX512F_INTRINSICS
+ */
+#define SDL_AVX2_INTRINSICS 1
+
+/**
+ * Defined if (and only if) the compiler supports Intel AVX-512F intrinsics.
+ *
+ * AVX-512F is also sometimes referred to as "AVX-512 Foundation."
+ *
+ * If this macro is defined, SDL will have already included ``
+ *
+ * \since This macro is available since SDL 3.2.0.
+ *
+ * \sa SDL_AVX_INTRINSICS
+ * \sa SDL_AVX2_INTRINSICS
+ */
+#define SDL_AVX512F_INTRINSICS 1
+#endif
+
+/* Need to do this here because intrin.h has C++ code in it */
+/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
+#ifdef __clang__
+/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
+ so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
+#ifndef __PRFCHWINTRIN_H
+#define __PRFCHWINTRIN_H
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_prefetch(void *__P)
+{
+ __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */);
+}
+#endif /* __PRFCHWINTRIN_H */
+#endif /* __clang__ */
+#include
+
+#elif defined(__MINGW64_VERSION_MAJOR)
+#include
+#if defined(__ARM_NEON) && !defined(SDL_DISABLE_NEON)
+# define SDL_NEON_INTRINSICS 1
+# include
+#endif
+
+#else
+/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC to have it included. */
+#if defined(__ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC)
+#define SDL_ALTIVEC_INTRINSICS 1
+#include
+#endif
+#ifndef SDL_DISABLE_NEON
+# ifdef __ARM_NEON
+# define SDL_NEON_INTRINSICS 1
+# include