diff --git a/Minecraft.Client/Windows64/4JLibs/.gitea/IMPLEMENTATION_GUIDE.md b/Minecraft.Client/Windows64/4JLibs/.gitea/IMPLEMENTATION_GUIDE.md
new file mode 100644
index 00000000..3701116d
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/.gitea/IMPLEMENTATION_GUIDE.md
@@ -0,0 +1,135 @@
+# 4JLibs implementation guide
+
+Whilst the library can be a direct replacement to the standard libraries shipped by the source leak, we can apply some enhancements to the original code
+
+Some functions were misimplemented due to the Windows library being a direct port off the Xbox 360 libraries, and because this platform was never supposed to see the light of day
+
+This guide will explain every change you can do in the source leak to improve it, like displaying save thumbnails, displaying save titles on the load menu and more
+
+## Save thumbnails
+
+#### The original code for displaying and saving thumbnails was broken for the Windows platform, either by poor ports or lack of care, in this section it will be explained how to enable this feature for the Windows platform using 4JLibs
+
+In the files ``ConsoleSaveFileOriginal.cpp`` and ``ConsoleSaveFileSplit.cpp`` there was a mistake when calling ``app.GetSaveThumbnail``
+
+To fix this issue, you need to replace the line of code:
+
+```cpp
+#if ( defined _XBOX || defined _DURANGO )
+```
+
+For:
+```cpp
+#if ( defined _XBOX || defined _DURANGO || defined _WINDOWS64 )
+```
+
+In the files ``Windows64_App.h`` and ``Windows64_App.cpp``, it is assumed that thumbnail capturing is broken, therefore the functions responsible for doing the capturing are empty, we need to fill them back up as follows:
+
+Below the implementation of:
+```cpp
+class CConsoleMinecraftApp : public CMinecraftApp
+{
+public:
+```
+
+You need to add the line:
+```cpp
+ImageFileBuffer m_ThumbnailBuffer;
+```
+
+Then, in ``Windows64_App.cpp``, you need to replace the empty implementations of ``CConsoleMinecraftApp::CaptureSaveThumbnail()`` and ``CConsoleMinecraftApp::GetSaveThumbnail`` with the following:
+```cpp
+void CConsoleMinecraftApp::CaptureSaveThumbnail()
+{
+ RenderManager.CaptureThumbnail(&m_ThumbnailBuffer);
+}
+void CConsoleMinecraftApp::GetSaveThumbnail(PBYTE *pbData,DWORD *pdwSize)
+{
+ if (m_ThumbnailBuffer.Allocated())
+ {
+ if (pbData)
+ {
+ *pbData = new BYTE[m_ThumbnailBuffer.GetBufferSize()];
+ *pdwSize = m_ThumbnailBuffer.GetBufferSize();
+ memcpy(*pbData, m_ThumbnailBuffer.GetBufferPointer(), *pdwSize);
+ }
+ m_ThumbnailBuffer.Release();
+ }
+}
+```
+
+These changes are enough to display the save thumbnails in the save selector, but we also need to fix the save data displayed in the actual load menu, which we will do as follows
+
+In the file ``UIScene_LoadMenu.cpp``, you need to replace the line:
+```cpp
+#if defined(__PS3__) || defined(__ORBIS__)|| defined(_DURANGO) || defined (__PSVITA__)
+```
+
+With:
+```cpp
+#if defined(__PS3__) || defined(__ORBIS__)|| defined(_DURANGO) || defined (__PSVITA__) || defined (_WINDOWS64)
+```
+
+Then, below that, there's the following chunk of code:
+```cpp
+#else // __ORBIS__
+ {
+ SceCesUcsContext Context;
+ sceCesUcsContextInit( &Context );
+ uint32_t utf8Len, utf16Len;
+ sceCesUtf8StrToUtf16Str(&Context, (uint8_t *)params->saveDetails->UTF8SaveFilename, srclen, &utf8Len, u16Message, dstlen, &utf16Len);
+ }
+#endif
+```
+
+You want to modify the ``#else`` conditional to be:
+```cpp
+#elif defined(__ORBIS__)
+```
+
+This way the Windows platform doesn't try accessing PS4 functions
+
+Then you want to comment/remove the following chunk of code:
+```cpp
+ if(params->saveDetails->pbThumbnailData)
+ {
+ m_pbThumbnailData = params->saveDetails->pbThumbnailData;
+ m_uiThumbnailSize = params->saveDetails->dwThumbnailSize;
+ m_bSaveThumbnailReady = true;
+ }
+ else
+```
+
+You can replace it for
+```cpp
+#ifndef _WINDOWS64
+ if(params->saveDetails->pbThumbnailData)
+ {
+ m_pbThumbnailData = params->saveDetails->pbThumbnailData;
+ m_uiThumbnailSize = params->saveDetails->dwThumbnailSize;
+ m_bSaveThumbnailReady = true;
+ }
+ else
+#endif
+```
+
+This is because, for a ``SAVE_DETAILS`` object, the thumbnail data is always pointing to valid memory (aka, it's always allocated)
+
+
+After all these changes, save titles and thumbnails should be properly displayed across the game
+
+## Renderer bugs/artifacts on newer Visual Studio versions
+
+In the file ``Windows64_Minecraft.cpp``, the depth stencil view descriptor is not null terminated which causes undefined behaviour
+
+In the case of newer compilers like Visual Studio 2022/2026, this causes the ``descDSView.Flags`` field to be filled with garbage data, and therefore causing visual glitches in game because the depth stencil fails to be created
+
+To fix this issue, below the line:
+```cpp
+D3D11_DEPTH_STENCIL_VIEW_DESC descDSView;
+```
+
+You need to fill the structure with zeros, you can do it like this:
+```cpp
+ZeroMemory(&descDSView, sizeof(descDSView));
+```
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/.gitignore b/Minecraft.Client/Windows64/4JLibs/.gitignore
new file mode 100644
index 00000000..03785b69
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/.gitignore
@@ -0,0 +1,13 @@
+4J_*/x64/
+Debug/
+ipch/
+
+# Misc
+*.sdf
+*.suo
+*.opensdf
+VS_*
+
+# Output Folders
+libs/
+inc/
diff --git a/Minecraft.Client/Windows64/4JLibs/4JLibs.sln b/Minecraft.Client/Windows64/4JLibs/4JLibs.sln
new file mode 100644
index 00000000..7f867b14
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4JLibs.sln
@@ -0,0 +1,152 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4J_Input", "4J_Input\4J_Input.vcxproj", "{A9125E77-A460-46FB-8EF3-2166F8657226}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4J_Profile", "4J_Profile\4J_Profile.vcxproj", "{C3833C67-05E4-4D6C-8707-22F95B6939E4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4J_Render", "4J_Render\4J_Render.vcxproj", "{22938163-5DDB-4D04-883B-07212EB99FAE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4J_Storage", "4J_Storage\4J_Storage.vcxproj", "{2E28BC2E-BF30-4C83-A4D8-C967DD409D70}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Headers", "Headers", "{1CB4373E-3F61-460C-B319-78C925BE3B8F}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\extraX64.h = Headers\extraX64.h
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4J_XTMS", "4J_XTMS\4J_XTMS.vcxproj", "{D0FDED0B-7704-4376-82DC-FF4377A7CD53}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows64", "Windows64", "{88DD56AD-CF4F-4E6B-97DB-E70340672774}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\Windows64\4J_Input.h = Headers\Windows64\4J_Input.h
+ Headers\Windows64\4J_Profile.h = Headers\Windows64\4J_Profile.h
+ Headers\Windows64\4J_Render.h = Headers\Windows64\4J_Render.h
+ Headers\Windows64\4J_Storage.h = Headers\Windows64\4J_Storage.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Durango", "Durango", "{A00BAB82-E24D-492C-881B-951BEACBE9AF}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\Durango\4J_Input.h = Headers\Durango\4J_Input.h
+ Headers\Durango\4J_Profile.h = Headers\Durango\4J_Profile.h
+ Headers\Durango\4J_Render.h = Headers\Durango\4J_Render.h
+ Headers\Durango\4J_Storage.h = Headers\Durango\4J_Storage.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Xbox", "Xbox", "{164C6036-01DB-4305-91D8-9121C5FA06EC}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\Xbox\4J_Input.h = Headers\Xbox\4J_Input.h
+ Headers\Xbox\4J_Profile.h = Headers\Xbox\4J_Profile.h
+ Headers\Xbox\4J_Render.h = Headers\Xbox\4J_Render.h
+ Headers\Xbox\4J_Storage.h = Headers\Xbox\4J_Storage.h
+ Headers\Xbox\4J_xtms.h = Headers\Xbox\4J_xtms.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PS3", "PS3", "{BCD14106-7AA2-457F-9162-7FEBBA403663}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\PS3\4J_Input.h = Headers\PS3\4J_Input.h
+ Headers\PS3\4J_Profile.h = Headers\PS3\4J_Profile.h
+ Headers\PS3\4J_Render.h = Headers\PS3\4J_Render.h
+ Headers\PS3\4J_Storage.h = Headers\PS3\4J_Storage.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Orbis", "Orbis", "{F4BBB877-E60B-4227-AF80-E91B8B1D2D06}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\Orbis\4J_Input.h = Headers\Orbis\4J_Input.h
+ Headers\Orbis\4J_Profile.h = Headers\Orbis\4J_Profile.h
+ Headers\Orbis\4J_Render.h = Headers\Orbis\4J_Render.h
+ Headers\Orbis\4J_Storage.h = Headers\Orbis\4J_Storage.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PSVita", "PSVita", "{88A465DA-D5B6-4A15-BC3F-C0BE5CFE64B2}"
+ ProjectSection(SolutionItems) = preProject
+ Headers\PSVita\4J_Input.h = Headers\PSVita\4J_Input.h
+ Headers\PSVita\4J_Profile.h = Headers\PSVita\4J_Profile.h
+ Headers\PSVita\4J_Render.h = Headers\PSVita\4J_Render.h
+ Headers\PSVita\4J_Storage.h = Headers\PSVita\4J_Storage.h
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ORBIS = Debug|ORBIS
+ Debug|PS3 = Debug|PS3
+ Debug|PSVita = Debug|PSVita
+ Debug|Windows64 = Debug|Windows64
+ Debug|Xbox 360 = Debug|Xbox 360
+ Release|ORBIS = Release|ORBIS
+ Release|PS3 = Release|PS3
+ Release|PSVita = Release|PSVita
+ Release|Windows64 = Release|Windows64
+ Release|Xbox 360 = Release|Xbox 360
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|ORBIS.ActiveCfg = Debug|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|PS3.ActiveCfg = Debug|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|PSVita.ActiveCfg = Debug|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|Windows64.ActiveCfg = Debug|x64
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|Windows64.Build.0 = Debug|x64
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Debug|Xbox 360.ActiveCfg = Debug|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|ORBIS.ActiveCfg = Release|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|PS3.ActiveCfg = Release|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|PSVita.ActiveCfg = Release|Win32
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|Windows64.ActiveCfg = Release|x64
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|Windows64.Build.0 = Release|x64
+ {A9125E77-A460-46FB-8EF3-2166F8657226}.Release|Xbox 360.ActiveCfg = Release|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|ORBIS.ActiveCfg = Debug|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|PS3.ActiveCfg = Debug|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|PSVita.ActiveCfg = Debug|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|Windows64.ActiveCfg = Debug|x64
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|Windows64.Build.0 = Debug|x64
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Debug|Xbox 360.ActiveCfg = Debug|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|ORBIS.ActiveCfg = Release|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|PS3.ActiveCfg = Release|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|PSVita.ActiveCfg = Release|Win32
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|Windows64.ActiveCfg = Release|x64
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|Windows64.Build.0 = Release|x64
+ {C3833C67-05E4-4D6C-8707-22F95B6939E4}.Release|Xbox 360.ActiveCfg = Release|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|ORBIS.ActiveCfg = Debug|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|PS3.ActiveCfg = Debug|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|PSVita.ActiveCfg = Debug|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|Windows64.ActiveCfg = Debug|x64
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|Windows64.Build.0 = Debug|x64
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Debug|Xbox 360.ActiveCfg = Debug|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|ORBIS.ActiveCfg = Release|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|PS3.ActiveCfg = Release|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|PSVita.ActiveCfg = Release|Win32
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|Windows64.ActiveCfg = Release|x64
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|Windows64.Build.0 = Release|x64
+ {22938163-5DDB-4D04-883B-07212EB99FAE}.Release|Xbox 360.ActiveCfg = Release|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|ORBIS.ActiveCfg = Debug|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|PS3.ActiveCfg = Debug|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|PSVita.ActiveCfg = Debug|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|Windows64.ActiveCfg = Debug|x64
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|Windows64.Build.0 = Debug|x64
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Debug|Xbox 360.ActiveCfg = Debug|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|ORBIS.ActiveCfg = Release|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|PS3.ActiveCfg = Release|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|PSVita.ActiveCfg = Release|Win32
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|Windows64.ActiveCfg = Release|x64
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|Windows64.Build.0 = Release|x64
+ {2E28BC2E-BF30-4C83-A4D8-C967DD409D70}.Release|Xbox 360.ActiveCfg = Release|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Debug|ORBIS.ActiveCfg = Debug|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Debug|PS3.ActiveCfg = Debug|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Debug|PSVita.ActiveCfg = Debug|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Debug|Windows64.ActiveCfg = Debug|x64
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Debug|Xbox 360.ActiveCfg = Debug|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Release|ORBIS.ActiveCfg = Release|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Release|PS3.ActiveCfg = Release|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Release|PSVita.ActiveCfg = Release|Win32
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Release|Windows64.ActiveCfg = Release|x64
+ {D0FDED0B-7704-4376-82DC-FF4377A7CD53}.Release|Xbox 360.ActiveCfg = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {88DD56AD-CF4F-4E6B-97DB-E70340672774} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ {A00BAB82-E24D-492C-881B-951BEACBE9AF} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ {164C6036-01DB-4305-91D8-9121C5FA06EC} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ {BCD14106-7AA2-457F-9162-7FEBBA403663} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ {F4BBB877-E60B-4227-AF80-E91B8B1D2D06} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ {88A465DA-D5B6-4A15-BC3F-C0BE5CFE64B2} = {1CB4373E-3F61-460C-B319-78C925BE3B8F}
+ EndGlobalSection
+EndGlobal
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj b/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj
new file mode 100644
index 00000000..36a6072e
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj
@@ -0,0 +1,265 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {A9125E77-A460-46FB-8EF3-2166F8657226}
+ Win32Proj
+ My4J_Input
+
+
+
+ StaticLibrary
+ true
+ v110
+ Unicode
+
+
+ StaticLibrary
+ true
+ v110
+ Unicode
+
+
+ StaticLibrary
+ false
+ v110
+ true
+ Unicode
+
+
+ StaticLibrary
+ false
+ v110
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(ProjectName)_d
+ $(SolutionDir)\libs\
+
+
+ $(ProjectName)_d
+
+
+ $(ProjectName)_r
+
+
+ $(ProjectName)_r
+ $(SolutionDir)\libs\
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ ../Headers;$(ProjectDir);%(AdditionalIncludeDirectories)
+ stdafx.h
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ Disabled
+ _WINDOWS64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../Headers/Windows64;../Headers;$(ProjectDir);$(ProjectDir)Windows64\vendor\SDL\include;%(AdditionalIncludeDirectories)
+ stdafx.h
+ MultiThreadedDebug
+ true
+ false
+ CompileAsCpp
+
+
+ Windows
+ true
+
+
+
+
+
+ Level3
+ Use
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ ../Headers;$(ProjectDir);%(AdditionalIncludeDirectories)
+ stdafx.h
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ Full
+ true
+ false
+ _WINDOWS64;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../Headers/Windows64;../Headers;$(ProjectDir);$(ProjectDir)Windows64\vendor\SDL\include;%(AdditionalIncludeDirectories)
+ stdafx.h
+ MultiThreaded
+ true
+ CompileAsCpp
+ Speed
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj.filters b/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj.filters
new file mode 100644
index 00000000..74305d53
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/4J_Input.vcxproj.filters
@@ -0,0 +1,318 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;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
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/4J_Input.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/4J_Input.cpp
new file mode 100644
index 00000000..e45197fd
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/4J_Input.cpp
@@ -0,0 +1,204 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "4J_Input.h"
+#include "INP_Keyboard.h"
+#include "INP_Main.h"
+
+C_4JInput InputManager;
+CKeyboard InternalKeyboard;
+
+void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ InternalInputManager.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC);
+}
+
+void C_4JInput::Tick(void)
+{
+ InternalInputManager.Tick();
+}
+
+void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
+{
+ InternalInputManager.SetDeadzoneAndMovementRange(uiDeadzone, uiMovementRangeMax);
+}
+
+void C_4JInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
+{
+ InternalInputManager.SetGameJoypadMaps(ucMap, ucAction, uiActionVal);
+}
+
+unsigned int C_4JInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
+{
+ return InternalInputManager.GetGameJoypadMaps(ucMap, ucAction);
+}
+
+void C_4JInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
+{
+ InternalInputManager.SetJoypadMapVal(iPad, ucMap);
+}
+
+unsigned char C_4JInput::GetJoypadMapVal(int iPad)
+{
+ return InternalInputManager.GetJoypadMapVal(iPad);
+}
+
+void C_4JInput::SetJoypadSensitivity(int iPad, float fSensitivity)
+{
+ InternalInputManager.SetJoypadSensitivity(iPad, fSensitivity);
+}
+
+unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
+{
+ return InternalInputManager.GetValue(iPad, ucAction, bRepeat);
+}
+
+bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonPressed(iPad, ucAction);
+}
+
+bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonReleased(iPad, ucAction);
+}
+
+bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonDown(iPad, ucAction);
+}
+
+void C_4JInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ InternalInputManager.SetJoypadStickAxisMap(iPad, uiFrom, uiTo);
+}
+
+void C_4JInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ InternalInputManager.SetJoypadStickTriggerMap(iPad, uiFrom, uiTo);
+}
+
+void C_4JInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
+{
+ InternalInputManager.SetKeyRepeatRate(fRepeatDelaySecs, fRepeatRateSecs);
+}
+
+void C_4JInput::SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam)
+{
+ InternalInputManager.SetDebugSequence(chSequenceA, Func, lpParam);
+}
+
+FLOAT C_4JInput::GetIdleSeconds(int iPad)
+{
+ return InternalInputManager.GetIdleSeconds(iPad);
+}
+
+bool C_4JInput::IsPadConnected(int iPad)
+{
+ return InternalInputManager.IsPadConnected(iPad);
+}
+
+void C_4JInput::SetSelectBackSwapped(bool swapped)
+{
+ InternalInputManager.SetSelectBackSwapped(swapped);
+}
+
+bool C_4JInput::IsSelectBackSwapped()
+{
+ return InternalInputManager.IsSelectBackSwapped();
+}
+
+float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_LX(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_LY(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_RX(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_RY(iPad, bCheckMenuDisplay);
+}
+
+unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadLTrigger(iPad, bCheckMenuDisplay);
+}
+
+unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadRTrigger(iPad, bCheckMenuDisplay);
+}
+
+void C_4JInput::SetMenuDisplayed(int iPad, bool bVal)
+{
+ InternalInputManager.SetMenuDisplayed(iPad, bVal);
+}
+
+EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode)
+{
+ return InternalKeyboard.RequestKeyboard(Title, Text, dwPad, uiMaxChars, Func, lpParam, eMode);
+}
+
+void C_4JInput::GetText(uint16_t *UTF16String)
+{
+ InternalKeyboard.GetText(UTF16String);
+}
+
+const char* C_4JInput::PollControllerType(int ipad) {
+ const char* GamepadType = InternalInputManager.GetGamepadType(ipad);
+
+ if (!GamepadType)
+ return "UNKNOWN";
+
+ if (strcmp(GamepadType, "SWITCH_PRO") == 0 ||
+ strcmp(GamepadType, "JOYCON_PAIR") == 0 ||
+ strcmp(GamepadType, "JOYCON_L") == 0 ||
+ strcmp(GamepadType, "JOYCON_R") == 0)
+ {
+ return "SWITCH";
+ }
+
+ return GamepadType; // str1k3r - if not one of the switch types, return the type itself
+}
+
+bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam)
+{
+ return true;
+}
+
+void C_4JInput::CancelQueuedVerifyStrings(int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) {}
+
+void C_4JInput::CancelAllVerifyInProgress(void) {}
+
+// bool C_4JInput::InputDetected(DWORD dwUserIndex,WCHAR *pwchInput) {}
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.cpp
new file mode 100644
index 00000000..804615c2
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.cpp
@@ -0,0 +1,134 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_ForceFeedback.h"
+
+void CForceFeedback::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ m_Effects = new FF_EFFECT[MAX_EFFECTS];
+ m_EffectC = 0;
+
+ LARGE_INTEGER qwTicksPerSec;
+ QueryPerformanceFrequency(&qwTicksPerSec);
+
+ m_TicksPerSecond = qwTicksPerSec.LowPart;
+ m_unkBool = 0;
+}
+
+void CForceFeedback::RumbleEnable(int iQuadrant, bool bRumbleEnabled) {}
+
+void CForceFeedback::CreateEffect(void)
+{
+ assert(m_EffectC < MAX_EFFECTS);
+
+ FF_EFFECT *pEffect = &m_Effects[m_EffectC];
+ pEffect->m_uiDurationMs = 5;
+ pEffect->m_uiMagnitude = 500;
+ pEffect->m_uiEffectType = 0;
+ pEffect->dword18 = 10;
+ pEffect->dword18 = 100;
+
+ m_EffectC++;
+}
+
+void CForceFeedback::AddEffectInstance(unsigned int uiEffect)
+{
+ FF_EFFECT_INSTANCE *pEffectInst = new FF_EFFECT_INSTANCE();
+ pEffectInst->m_Effect = &m_Effects[uiEffect];
+ pEffectInst->m_uiInst = 0;
+
+ m_EffectList.AddToTail(pEffectInst);
+}
+
+void CForceFeedback::SetEffectInstanceState(unsigned int uiEffectInstance, unsigned int uiState)
+{
+ int iCount = 0;
+ LinkedList::_LL_NODE *pNode;
+ for (pNode = m_EffectList.m_Head;; pNode = pNode->m_Next)
+ {
+ if ((iCount++) == uiEffectInstance)
+ break;
+ }
+ pNode->GetDataAs()->m_bIsActive = true;
+}
+
+void CForceFeedback::ProcessEventInstance(FF_EFFECT_INSTANCE *pEffectInst) {}
+
+void CForceFeedback::PauseEventInstance(FF_EFFECT_INSTANCE *pEffectInst) {}
+
+void CForceFeedback::AddRumble(unsigned int uiPad, WORD leftMotorSpeed, WORD rightMotorSpeed, float fSeconds)
+{
+ RUMBLE_EFFECT *pRumble = new RUMBLE_EFFECT();
+
+ LARGE_INTEGER qwCurrentTime;
+ QueryPerformanceCounter(&qwCurrentTime);
+
+ pRumble->m_TimeLeft = (m_TicksPerSecond * fSeconds) + qwCurrentTime.QuadPart;
+ pRumble->m_RumbleData.wLeftMotorSpeed = leftMotorSpeed;
+ pRumble->m_RumbleData.wRightMotorSpeed = rightMotorSpeed;
+ pRumble->m_Pad = uiPad;
+
+ m_RumbleList.AddToTail(pRumble);
+}
+
+void CForceFeedback::Tick(void)
+{
+ for (LinkedList::_LL_NODE *pEffectNode = m_EffectList.m_Head; pEffectNode; pEffectNode = pEffectNode->m_Next)
+ {
+ if (pEffectNode->GetDataAs()->m_bIsActive)
+ {
+ ProcessEventInstance(pEffectNode->GetDataAs());
+ }
+ }
+
+ LARGE_INTEGER qwCurrentTime;
+ QueryPerformanceCounter(&qwCurrentTime);
+
+ LinkedList::_LL_NODE *pRumbleNode = m_RumbleList.m_Head;
+ while (pRumbleNode)
+ {
+ if (pRumbleNode->GetDataAs()->m_TimeLeft <= qwCurrentTime.QuadPart)
+ {
+ RUMBLE_EFFECT *pRumble = pRumbleNode->GetDataAs();
+
+ pRumble->m_RumbleData.wLeftMotorSpeed = 0;
+ pRumble->m_RumbleData.wRightMotorSpeed = 0;
+
+ XInputSetState(pRumble->m_Pad, &pRumble->m_RumbleData);
+
+ m_RumbleList.RemoveNode(pRumbleNode);
+
+ LinkedList::_LL_NODE *pTemp = pRumbleNode;
+ pRumbleNode = pRumbleNode->m_Next;
+
+ delete pTemp->GetDataAs();
+ delete pTemp;
+ }
+ else
+ {
+ XInputSetState(pRumbleNode->GetDataAs()->m_Pad, &pRumbleNode->GetDataAs()->m_RumbleData);
+ pRumbleNode = pRumbleNode->m_Next;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.h
new file mode 100644
index 00000000..df75a474
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_ForceFeedback.h
@@ -0,0 +1,84 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "LinkedList.h"
+
+#define MAX_EFFECTS 10
+
+class CForceFeedback
+{
+public:
+ enum FF_PARAMS
+ {
+ FF_PARAMS_RAMP,
+ FF_PARAMS_PERIODIC
+ };
+
+ struct RUMBLE_EFFECT
+ {
+ DWORD m_Pad;
+ uint64_t m_TimeLeft;
+ XINPUT_VIBRATION m_RumbleData;
+ WORD unk;
+ };
+
+ struct FF_EFFECT
+ {
+ unsigned int m_uiEffectType;
+ unsigned int m_uiDurationMs;
+ BYTE gap8[4];
+ unsigned int m_uiMagnitude;
+ BYTE gap10[8];
+ DWORD dword18;
+ DWORD dword1C;
+ };
+
+ struct FF_EFFECT_INSTANCE
+ {
+ bool m_bIsActive;
+ unsigned int m_uiInst;
+ CForceFeedback::FF_EFFECT *m_Effect;
+ };
+
+ void Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC);
+ void RumbleEnable(int iQuadrant, bool bRumbleEnabled);
+ void CreateEffect(void);
+ void AddEffectInstance(unsigned int uiEffect);
+ void SetEffectInstanceState(unsigned int uiEffectInstance, unsigned int uiState);
+
+ void ProcessEventInstance(FF_EFFECT_INSTANCE *pEffectInst);
+ void PauseEventInstance(FF_EFFECT_INSTANCE *pEffectInst);
+
+ void AddRumble(unsigned int uiPad, WORD leftMotorSpeed, WORD rightMotorSpeed, float fSeconds);
+
+ void Tick(void);
+
+ LinkedList m_EffectList;
+ FF_EFFECT *m_Effects;
+ int m_EffectC;
+ LinkedList m_RumbleList;
+ float m_TicksPerSecond;
+ bool m_unkBool;
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.cpp
new file mode 100644
index 00000000..88591aeb
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.cpp
@@ -0,0 +1,46 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_Keyboard.h"
+
+void CKeyboard::Tick(void) {}
+
+EKeyboardResult CKeyboard::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode)
+{
+ ClearGlobalText();
+ SeedEditBox();
+ Func(lpParam, C_4JInput::EKeyboardMode_Numeric);
+
+ return EKeyboard_ResultAccept;
+}
+
+void CKeyboard::GetText(uint16_t *UTF16String)
+{
+ uint16_t *keyString = GetGlobalText();
+ for (unsigned int index = 0; keyString[index] && index < 0x200; index++)
+ {
+ UTF16String[index] = keyString[index];
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.h
new file mode 100644
index 00000000..f6e00de0
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Keyboard.h
@@ -0,0 +1,50 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "4J_Input.h"
+
+void ClearGlobalText();
+uint16_t *GetGlobalText();
+void SeedEditBox();
+
+class CKeyboard
+{
+public:
+ enum EKeyboardProcessState
+ {
+ };
+
+ struct SKeyboardInfo
+ {
+ };
+
+ void Tick(void);
+
+ EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode);
+ void GetText(uint16_t *UTF16String);
+
+ BYTE gap0[0x68];
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.cpp
new file mode 100644
index 00000000..63f0e632
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.cpp
@@ -0,0 +1,898 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_Main.h"
+#include "vendor\SDL\include\SDL3\SDL.h"
+
+CInput InternalInputManager;
+
+bool m_SelectBackSwapped = false;
+
+CInput::CInput()
+{
+ m_Keyboard = CKeyboard();
+
+ m_uiSigninJoypadMask = 0;
+ for (int i = 0; i < 4; ++i)
+ m_bIsMenuDisplayed[i] = 0;
+
+ if (!SDL_Init(SDL_INIT_GAMEPAD)) {
+ SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
+ assert(0);
+ }
+
+ InitTime();
+
+ m_fRepeatDelaySecs = 0.5f;
+ m_fRepeatRateSecs = 0.8f;
+ m_sDebugSequenceName = 0;
+ m_uiDebugSequenceIndex = 0;
+ m_pDebugSequenceFn = 0;
+}
+
+void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ assert(iInputStateC > 0);
+ assert(ucMapC > 0);
+ assert(ucActionC > 0);
+
+ ZeroMemory(m_Joypads, sizeof(m_Joypads));
+
+ m_ucInputStateC = iInputStateC;
+
+ m_iDeadzone = 0x2710;
+ m_iMovementRangeMax = 0x7FFF;
+
+ m_iEffectiveRange = m_iMovementRangeMax - m_iDeadzone;
+ m_iHalfRange = m_iEffectiveRange / 2;
+ m_fEffectiveRange = (float)m_iEffectiveRange;
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ m_Joypads[i].m_pGamepad = nullptr;
+ m_Joypads[i].m_ucInputStateIndex = -1;
+ m_Joypads[i].m_pfLeftThumbXAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbX;
+ m_Joypads[i].m_pfLeftThumbYAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbY;
+ m_Joypads[i].m_pfRightThumbXAxisMap = &m_Joypads[i].m_fNormalizedRightThumbX;
+ m_Joypads[i].m_pfRightThumbYAxisMap = &m_Joypads[i].m_fNormalizedRightThumbY;
+ m_Joypads[i].m_pucLeftTriggerAxisMap = &m_Joypads[i].m_ucLeftTriggerState;
+ m_Joypads[i].m_pucRightTriggerAxisMap = &m_Joypads[i].m_ucRightTriggerState;
+ m_Joypads[i].m_fSensitivity = 1.0f;
+ }
+
+ m_JoypadMap = (unsigned int **)operator new[](ucMapC * sizeof(int *));
+ for (int i = 0; i < ucMapC; i++)
+ {
+ m_JoypadMap[i] = (unsigned int *)operator new[](ucActionC * sizeof(int));
+ }
+
+ m_ucJoypadMapC = ucMapC;
+ m_ucJoypadMapActionC = ucActionC;
+ m_ucMenuActionC = ucMenuActionC;
+ m_bJoypadMapArrayIsSetup = false;
+}
+
+void CInput::Tick(void)
+{
+ HandleGamepadEvents();
+ UpdateJoypads();
+ m_Keyboard.Tick();
+}
+
+void CInput::SetJoypadValues(JOYPAD *pThisPad)
+{
+ SDL_Gamepad *pGamePad = pThisPad->m_pGamepad;
+
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) > (SDL_MAX_SINT16 / 2))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LT;
+ }
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) > (SDL_MAX_SINT16 / 2))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RT;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RB;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LB;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_SOUTH))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_A;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_EAST))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_B;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_WEST))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_X;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_NORTH))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_Y;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_START))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_START;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_BACK))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_BACK;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_LEFT_STICK))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LTHUMB;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_RIGHT_STICK))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RTHUMB;
+ }
+
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_UP))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_UP;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_DOWN))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_DOWN;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_LEFT))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_LEFT;
+ }
+ if (SDL_GetGamepadButton(pGamePad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT))
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_RIGHT;
+ }
+
+ // RY and LY are inverted, so we have to negate them.
+ // This does not apply to RX and LX.
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX) > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_RIGHT;
+ }
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX) < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_LEFT;
+ }
+
+ if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY) < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_DOWN;
+ }
+ if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY) > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_UP;
+ }
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX) > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_RIGHT;
+ }
+ if (SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX) < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_LEFT;
+ }
+
+ if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY) < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_DOWN;
+ }
+ if (-SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY) > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_UP;
+ }
+
+ pThisPad->m_ucLeftTriggerState = (unsigned char)(SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) >> 7);
+ pThisPad->m_ucRightTriggerState = (unsigned char)(SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) >> 7);
+
+ Sint16 sThumbRX = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTX);
+ if (sThumbRX <= m_iDeadzone)
+ {
+ if (sThumbRX >= -m_iDeadzone)
+ pThisPad->m_iRightThumbX = 0;
+ else
+ pThisPad->m_iRightThumbX = m_iDeadzone + sThumbRX;
+ }
+ else
+ {
+ pThisPad->m_iRightThumbX = sThumbRX - m_iDeadzone;
+ }
+
+ // RY and LY are inverted, so we have to negate them.
+ // We have to also keep in mind that the thumbstick shouldn't go over the integer limit
+ // then flip (Talking from experience :3)
+
+ // This does not apply to RX and LX.
+ Sint16 rawRY = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_RIGHTY);
+ if (rawRY < -SDL_MAX_SINT16) rawRY = -SDL_MAX_SINT16;
+ Sint16 sThumbRY = -rawRY;
+
+ if (sThumbRY <= m_iDeadzone)
+ {
+ if (sThumbRY >= -m_iDeadzone)
+ pThisPad->m_iRightThumbY = 0;
+ else
+ pThisPad->m_iRightThumbY = m_iDeadzone + sThumbRY;
+ }
+ else
+ {
+ pThisPad->m_iRightThumbY = sThumbRY - m_iDeadzone;
+ }
+
+ Sint16 sThumbLX = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTX);
+ if (sThumbLX <= m_iDeadzone)
+ {
+ if (sThumbLX >= -m_iDeadzone)
+ pThisPad->m_iLeftThumbX = 0;
+ else
+ pThisPad->m_iLeftThumbX = m_iDeadzone + sThumbLX;
+ }
+ else
+ {
+ pThisPad->m_iLeftThumbX = sThumbLX - m_iDeadzone;
+ }
+
+ Sint16 rawLY = SDL_GetGamepadAxis(pGamePad, SDL_GAMEPAD_AXIS_LEFTY);
+ if (rawLY < -SDL_MAX_SINT16) rawLY = -SDL_MAX_SINT16;
+ Sint16 sThumbLY = -rawLY;
+
+ if (sThumbLY <= m_iDeadzone)
+ {
+ if (sThumbLY >= -m_iDeadzone)
+ pThisPad->m_iLeftThumbY = 0;
+ else
+ pThisPad->m_iLeftThumbY = m_iDeadzone + sThumbLY;
+ }
+ else
+ {
+ pThisPad->m_iLeftThumbY = sThumbLY - m_iDeadzone;
+ }
+
+ //str1k3r - silly piebot this was duplicated, also make these floats :3
+ pThisPad->m_fNormalizedLeftThumbX = (float)pThisPad->m_iLeftThumbX / m_fEffectiveRange;
+ pThisPad->m_fNormalizedLeftThumbY = (float)pThisPad->m_iLeftThumbY / m_fEffectiveRange;
+ pThisPad->m_fNormalizedRightThumbX = (float)pThisPad->m_iRightThumbX / m_fEffectiveRange;
+ pThisPad->m_fNormalizedRightThumbY = (float)pThisPad->m_iRightThumbY / m_fEffectiveRange;
+}
+
+void CInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
+{
+ m_iDeadzone = uiDeadzone;
+ m_iMovementRangeMax = uiMovementRangeMax;
+ m_iEffectiveRange = uiMovementRangeMax - uiDeadzone;
+ m_iHalfRange = m_iEffectiveRange / 2;
+}
+
+void CInput::SetJoypadSensitivity(int iPad, float fSensitivity)
+{
+ m_Joypads[iPad].m_fSensitivity = fSensitivity;
+}
+
+void CInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
+{
+ assert(ucMap < m_ucJoypadMapC);
+ assert(ucAction < m_ucJoypadMapActionC);
+
+ m_JoypadMap[ucMap][ucAction] = uiActionVal;
+}
+
+unsigned int CInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
+{
+ assert(ucMap < m_ucJoypadMapC);
+ assert(ucAction < m_ucJoypadMapActionC);
+
+ return m_JoypadMap[ucMap][ucAction];
+}
+
+const char* CInput::GetGamepadType(int iPad)
+{
+ if (!m_Joypads[iPad].m_pGamepad)
+ {
+ return "UNKNOWN";
+ }
+
+ return GamepadTypeName(SDL_GetGamepadType(m_Joypads[iPad].m_pGamepad));
+}
+
+void CInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
+{
+ m_bJoypadMapArrayIsSetup = true;
+ m_Joypads[iPad].m_ucMappingValue = ucMap;
+}
+
+unsigned char CInput::GetJoypadMapVal(int iPad)
+{
+ return m_Joypads[iPad].m_ucMappingValue;
+}
+
+void CInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ float *pfTo = nullptr;
+
+ switch (uiTo)
+ {
+ case AXIS_MAP_LX:
+ pfTo = &m_Joypads[iPad].m_fNormalizedLeftThumbX;
+ break;
+ case AXIS_MAP_LY:
+ pfTo = &m_Joypads[iPad].m_fNormalizedLeftThumbY;
+ break;
+ case AXIS_MAP_RX:
+ pfTo = &m_Joypads[iPad].m_fNormalizedRightThumbX;
+ break;
+ case AXIS_MAP_RY:
+ pfTo = &m_Joypads[iPad].m_fNormalizedRightThumbY;
+ break;
+ }
+
+ switch (uiFrom)
+ {
+ case AXIS_MAP_LX:
+ m_Joypads[iPad].m_pfLeftThumbXAxisMap = pfTo;
+ break;
+ case AXIS_MAP_LY:
+ m_Joypads[iPad].m_pfLeftThumbYAxisMap = pfTo;
+ break;
+ case AXIS_MAP_RX:
+ m_Joypads[iPad].m_pfRightThumbXAxisMap = pfTo;
+ break;
+ case AXIS_MAP_RY:
+ m_Joypads[iPad].m_pfRightThumbYAxisMap = pfTo;
+ break;
+ }
+}
+
+void CInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ unsigned char *pucTo = nullptr;
+
+ switch (uiTo)
+ {
+ case TRIGGER_MAP_0:
+ pucTo = &m_Joypads[iPad].m_ucRightTriggerState;
+ break;
+ case TRIGGER_MAP_1:
+ pucTo = &m_Joypads[iPad].m_ucLeftTriggerState;
+ break;
+ }
+
+ switch (uiFrom)
+ {
+ case TRIGGER_MAP_0:
+ m_Joypads[iPad].m_pucRightTriggerAxisMap = pucTo;
+ break;
+ case TRIGGER_MAP_1:
+ m_Joypads[iPad].m_pucLeftTriggerAxisMap = pucTo;
+ break;
+ }
+}
+
+bool CInput::IsPadConnected(int iPad)
+{
+ return m_Joypads[iPad].m_bIsConnected;
+}
+
+void CInput::SetSelectBackSwapped(bool swapped)
+{
+ m_SelectBackSwapped = swapped;
+}
+
+bool CInput::IsSelectBackSwapped()
+{
+ return m_SelectBackSwapped;
+}
+
+void CInput::SetSigninJoypadMask(unsigned int mask)
+{
+ m_uiSigninJoypadMask = mask;
+}
+
+unsigned int CInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
+{
+ if (m_bIsMenuDisplayed[iPad] && ucAction > this->m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ unsigned char ucMap = this->m_Joypads[iPad].m_ucMappingValue;
+ unsigned int uiVal = this->m_JoypadMap[ucMap][ucAction] & this->m_Joypads[iPad].m_uiButtons;
+ if (!uiVal || !bRepeat)
+ {
+ return uiVal;
+ }
+
+ int iKeyVal = 0;
+ for (int iKey = this->m_JoypadMap[ucMap][ucAction]; (iKey & 1) == 0; iKey >>= 1)
+ {
+ iKeyVal++;
+ }
+
+ if (m_fRepeatDelaySecs <= m_Timers[iPad][iKeyVal].m_fTotalHoldTime || m_Timers[iPad][iKeyVal].m_bInitialPressHandled)
+ {
+ if (m_Timers[iPad][iKeyVal].m_fTotalHoldTime < m_fRepeatDelaySecs)
+ {
+ return 0;
+ }
+ else if (m_Timers[iPad][iKeyVal].m_fLastRepeatTime == 0.0f)
+ {
+ m_Timers[iPad][iKeyVal].m_fLastRepeatTime = m_fRepeatDelaySecs;
+ return uiVal;
+ }
+ else if ((m_Timers[iPad][iKeyVal].m_fTotalHoldTime - m_Timers[iPad][iKeyVal].m_fLastRepeatTime) <= m_fRepeatRateSecs)
+ {
+ return 0;
+ }
+ else
+ {
+ m_Timers[iPad][iKeyVal].m_fLastRepeatTime = m_Timers[iPad][iKeyVal].m_fLastRepeatTime + m_fRepeatRateSecs;
+ return uiVal;
+ }
+ }
+ else
+ {
+ m_Timers[iPad][iKeyVal].m_bInitialPressHandled = true;
+ return uiVal;
+ }
+}
+
+bool CInput::IsSet(int iPad, unsigned char ucAction)
+{
+ return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) &&
+ (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0;
+}
+
+bool CInput::ButtonPressed(int iPad, unsigned char ucAction)
+{
+ if (ucAction == 255)
+ {
+ return m_Joypads[iPad].m_uiButtonsPressed != 0;
+ }
+
+ if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsPressed) != 0;
+}
+
+bool CInput::ButtonReleased(int iPad, unsigned char ucAction)
+{
+ return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) &&
+ (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsReleased) != 0;
+}
+
+bool CInput::ButtonDown(int iPad, unsigned char ucAction)
+{
+ if (ucAction == 255)
+ {
+ return m_Joypads[iPad].m_uiButtons != 0;
+ }
+
+ if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0;
+}
+
+float CInput::GetJoypadStick_Menu_LX(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedLeftThumbX;
+}
+
+float CInput::GetJoypadStick_Menu_LY(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedLeftThumbY;
+}
+
+float CInput::GetJoypadStick_Menu_RX(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedRightThumbX;
+}
+
+float CInput::GetJoypadStick_Menu_RY(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedRightThumbY;
+}
+
+unsigned char CInput::GetJoypadLTrigger_Menu(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_ucLeftTriggerState;
+}
+
+unsigned char CInput::GetJoypadRTrigger_Menu(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_ucRightTriggerState;
+}
+
+float CInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfLeftThumbXAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfLeftThumbYAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfRightThumbXAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfRightThumbYAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+unsigned char CInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0;
+ }
+
+ return *m_Joypads[iPad].m_pucLeftTriggerAxisMap;
+}
+
+unsigned char CInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0;
+ }
+
+ return *m_Joypads[iPad].m_pucRightTriggerAxisMap;
+}
+
+void CInput::SetMenuDisplayed(int iPad, bool bVal)
+{
+ m_bIsMenuDisplayed[iPad] = bVal;
+}
+
+void CInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
+{
+ m_fRepeatDelaySecs = fRepeatDelaySecs;
+ m_fRepeatRateSecs = fRepeatRateSecs;
+}
+
+void CInput::SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam)
+{
+ int iLen = strlen(chSequenceA);
+
+ m_sDebugSequenceName = (char *)operator new[](iLen);
+ strcpy(m_sDebugSequenceName, chSequenceA);
+
+ m_pDebugSequenceFn = Func;
+ m_pDebugSequenceParam = lpParam;
+}
+
+FLOAT CInput::GetIdleSeconds(int iPad)
+{
+ LARGE_INTEGER qwDeltaTime;
+ QueryPerformanceCounter(&qwDeltaTime);
+
+ LARGE_INTEGER fElapsedTime = this->m_LastActivityTime[iPad];
+ uint64_t qwNewTime = qwDeltaTime.QuadPart - fElapsedTime.QuadPart;
+
+ return this->m_fTickToSeconds * (qwDeltaTime.LowPart - fElapsedTime.LowPart);
+}
+
+void CInput::HandleGamepadEvents()
+{
+ //str1k3r - writing/reading a global can make stuff stutter alot
+ SDL_Event localEvent;
+
+ while (SDL_PollEvent(&localEvent))
+ {
+ switch (localEvent.type)
+ {
+ case SDL_EVENT_GAMEPAD_ADDED:
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ if (!m_Joypads[i].m_pGamepad)
+ {
+ SDL_Gamepad *pad = SDL_OpenGamepad(localEvent.gdevice.which);
+
+ if (pad)
+ {
+ SDL_SetGamepadPlayerIndex(pad, i);
+ m_Joypads[i].m_pGamepad = pad;
+ m_Joypads[i].m_bIsConnected = true;
+ }
+
+ break;
+ }
+ }
+ break;
+ case SDL_EVENT_GAMEPAD_REMOVED:
+ {
+ int removedIndex = -1;
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ if (m_Joypads[i].m_pGamepad &&
+ SDL_GetGamepadID(m_Joypads[i].m_pGamepad) == localEvent.gdevice.which)
+ {
+ SDL_CloseGamepad(m_Joypads[i].m_pGamepad);
+ m_Joypads[i].m_pGamepad = nullptr;
+ m_Joypads[i].m_bIsConnected = false;
+ removedIndex = i;
+ break;
+ }
+ }
+
+ if (removedIndex == 0)
+ {
+ for (int i = 1; i < MAX_JOYPADS; i++)
+ {
+ //str1k3r - since we used to never set m_bIsConnected when a gamepad was added this never ran
+ if (m_Joypads[i].m_bIsConnected && m_Joypads[i].m_pGamepad)
+ {
+ ShiftGamepadData(0, i);
+ SDL_SetGamepadPlayerIndex(m_Joypads[0].m_pGamepad, 0);
+ ClearGamepadSlot(i);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+void CInput::ShiftGamepadData(int destIndex, int srcIndex)
+{
+ m_Joypads[destIndex] = m_Joypads[srcIndex];
+
+ m_Joypads[destIndex].m_pfLeftThumbXAxisMap = &m_Joypads[destIndex].m_fNormalizedLeftThumbX;
+ m_Joypads[destIndex].m_pfLeftThumbYAxisMap = &m_Joypads[destIndex].m_fNormalizedLeftThumbY;
+ m_Joypads[destIndex].m_pfRightThumbXAxisMap = &m_Joypads[destIndex].m_fNormalizedRightThumbX;
+ m_Joypads[destIndex].m_pfRightThumbYAxisMap = &m_Joypads[destIndex].m_fNormalizedRightThumbY;
+ m_Joypads[destIndex].m_pucLeftTriggerAxisMap = &m_Joypads[destIndex].m_ucLeftTriggerState;
+ m_Joypads[destIndex].m_pucRightTriggerAxisMap = &m_Joypads[destIndex].m_ucRightTriggerState;
+}
+
+void CInput::ClearGamepadSlot(int index)
+{
+ m_Joypads[index].m_pGamepad = nullptr;
+ m_Joypads[index].m_bIsConnected = false;
+ m_Joypads[index].m_uiButtons = 0;
+ m_Joypads[index].m_ucInputStateIndex = -1;
+ m_Joypads[index].m_ucLeftTriggerState = 0;
+ m_Joypads[index].m_ucRightTriggerState = 0;
+ m_Joypads[index].m_iRightThumbX = 0;
+ m_Joypads[index].m_iRightThumbY = 0;
+
+ m_Joypads[index].m_pfLeftThumbXAxisMap = &m_Joypads[index].m_fNormalizedLeftThumbX;
+ m_Joypads[index].m_pfLeftThumbYAxisMap = &m_Joypads[index].m_fNormalizedLeftThumbY;
+ m_Joypads[index].m_pfRightThumbXAxisMap = &m_Joypads[index].m_fNormalizedRightThumbX;
+ m_Joypads[index].m_pfRightThumbYAxisMap = &m_Joypads[index].m_fNormalizedRightThumbY;
+ m_Joypads[index].m_pucLeftTriggerAxisMap = &m_Joypads[index].m_ucLeftTriggerState;
+ m_Joypads[index].m_pucRightTriggerAxisMap = &m_Joypads[index].m_ucRightTriggerState;
+}
+
+bool CInput::UpdateJoypads()
+{
+ assert(m_bJoypadMapArrayIsSetup);
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ JOYPAD *pThisPad = &m_Joypads[i];
+
+ pThisPad->m_uiOldButtons = pThisPad->m_uiButtons;
+ pThisPad->m_uiButtons = 0;
+ pThisPad->m_iRightThumbY = 0;
+ pThisPad->m_iRightThumbX = 0;
+ pThisPad->m_iLeftThumbY = 0;
+ pThisPad->m_iLeftThumbX = 0;
+ pThisPad->m_ucLeftTriggerState = 0;
+ pThisPad->m_ucRightTriggerState = 0;
+ }
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ if (!m_Joypads[i].m_bIsDisabled)
+ {
+ JOYPAD *pThisPad = &m_Joypads[i];
+
+ bool bOldIsConnected = pThisPad->m_bIsConnected;
+
+ pThisPad->m_ucInputStateIndex = pThisPad->m_ucInputStateIndex++;
+ if (pThisPad->m_ucInputStateIndex == m_ucInputStateC)
+ {
+ pThisPad->m_ucInputStateIndex = 0;
+ }
+
+ pThisPad->m_bIsConnected = (pThisPad->m_pGamepad != nullptr);
+
+ bool bWasConnected = bOldIsConnected && !pThisPad->m_bIsConnected;
+ pThisPad->m_bWasConnected = bWasConnected;
+
+ bool bHasConnected = !bOldIsConnected && pThisPad->m_bIsConnected;
+ pThisPad->m_bHasConnected = bHasConnected;
+
+ if (pThisPad->m_bIsConnected)
+ {
+ SetJoypadValues(pThisPad);
+
+ pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons;
+ pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons;
+
+ for (int bit = 0; bit < 24; ++bit)
+ {
+ if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0)
+ {
+ GetStartTime(i, bit);
+ }
+ else if ((pThisPad->m_uiButtons & (1 << bit)) != 0)
+ {
+ UpdateTime(i, bit);
+ }
+ }
+ }
+ else if (pThisPad->m_bWasConnected)
+ {
+ ClearJoypadValues(pThisPad);
+ }
+
+ if (m_pDebugSequenceFn && (pThisPad->m_uiButtonsPressed & (_360_JOY_BUTTON_A | _360_JOY_BUTTON_B | _360_JOY_BUTTON_X | _360_JOY_BUTTON_Y |
+ _360_JOY_BUTTON_RB | _360_JOY_BUTTON_LB)) != 0)
+ {
+ char chSeq;
+
+ if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_A) == _360_JOY_BUTTON_A)
+ {
+ chSeq = 'A';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_B) == _360_JOY_BUTTON_B)
+ {
+ chSeq = 'B';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_X) == _360_JOY_BUTTON_X)
+ {
+ chSeq = 'X';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_Y) == _360_JOY_BUTTON_Y)
+ {
+ chSeq = 'Y';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_LB) == _360_JOY_BUTTON_LB)
+ {
+ chSeq = 'L';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_RB) == _360_JOY_BUTTON_RB)
+ {
+ chSeq = 'R';
+ }
+
+ if (m_sDebugSequenceName[m_uiDebugSequenceIndex] == chSeq)
+ {
+ if (!m_sDebugSequenceName[m_uiDebugSequenceIndex++])
+ {
+ m_uiDebugSequenceIndex = 0;
+ (m_pDebugSequenceFn)(m_pDebugSequenceParam);
+ }
+ }
+ else
+ {
+ m_uiDebugSequenceIndex = 0;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void CInput::ClearJoypadValues(JOYPAD *pThisPad)
+{
+ pThisPad->m_uiButtonsPressed = 0;
+ pThisPad->m_uiButtonsReleased = 0;
+ pThisPad->m_uiButtons = 0;
+ pThisPad->m_ucLeftTriggerState = 0;
+ pThisPad->m_ucRightTriggerState = 0;
+ pThisPad->m_iRightThumbX = 0;
+ pThisPad->m_iRightThumbY = 0;
+ pThisPad->m_iLeftThumbX = 0;
+ pThisPad->m_iLeftThumbY = 0;
+ pThisPad->m_iNormalizedLeftThumbX = 0;
+ pThisPad->m_iNormalizedLeftThumbY = 0;
+ pThisPad->m_iNormalizedRightThumbX = 0;
+ pThisPad->m_iNormalizedRightThumbY = 0;
+ pThisPad->m_fNormalizedLeftThumbX = 0.0f;
+ pThisPad->m_fNormalizedLeftThumbY = 0.0f;
+ pThisPad->m_fNormalizedRightThumbX = 0.0f;
+ pThisPad->m_fNormalizedRightThumbY = 0.0f;
+}
+
+void CInput::InitTime(void)
+{
+ LARGE_INTEGER qwTicksPerSec;
+ QueryPerformanceFrequency(&qwTicksPerSec);
+
+ m_fTickToSeconds = 1.0 / (float)(int)qwTicksPerSec.LowPart;
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ m_LastActivityTime[i].QuadPart = 0;
+ }
+}
+
+void CInput::GetStartTime(int iPad, int iKey)
+{
+ QueryPerformanceCounter(&m_Timers[iPad][iKey].m_qwStartTime);
+
+ m_Timers[iPad][iKey].m_qwTotalHoldTicks.QuadPart = 0;
+ m_Timers[iPad][iKey].m_fTotalHoldTime = 0;
+ m_Timers[iPad][iKey].m_fLastRepeatTime = 0;
+ m_Timers[iPad][iKey].m_bInitialPressHandled = false;
+
+ m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+}
+
+void CInput::UpdateTime(int iPad, int iKey)
+{
+ LARGE_INTEGER qwDeltaTime;
+ QueryPerformanceCounter(&qwDeltaTime);
+
+ uint64_t qwNewTime = qwDeltaTime.QuadPart - m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+ m_Timers[iPad][iKey].m_qwTotalHoldTicks.QuadPart += qwNewTime;
+
+ m_Timers[iPad][iKey].m_qwStartTime = qwDeltaTime;
+ m_Timers[iPad][iKey].m_fTotalHoldTime = m_Timers[iPad][iKey].m_fTotalHoldTime + (m_fTickToSeconds * qwNewTime);
+
+ m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.h
new file mode 100644
index 00000000..3a7e0277
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_Main.h
@@ -0,0 +1,210 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_ForceFeedback.h"
+#include "INP_Keyboard.h"
+#include "vendor\SDL\include\SDL3\SDL.h"
+
+#define MAX_JOYPADS 4
+
+class CInput
+{
+private:
+ const char* GamepadTypeName(SDL_GamepadType type)
+ {
+ switch (type)
+ {
+ case SDL_GAMEPAD_TYPE_UNKNOWN: return "UNKNOWN";
+ case SDL_GAMEPAD_TYPE_GAMECUBE: return "GAMECUBE";
+ case SDL_GAMEPAD_TYPE_STANDARD: return "STANDARD";
+ case SDL_GAMEPAD_TYPE_XBOX360: return "XBOX360";
+ case SDL_GAMEPAD_TYPE_XBOXONE: return "XBOXONE";
+ case SDL_GAMEPAD_TYPE_PS3: return "PS3";
+ case SDL_GAMEPAD_TYPE_PS4: return "PS4";
+ case SDL_GAMEPAD_TYPE_PS5: return "PS5";
+ case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO: return "SWITCH_PRO";
+ case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: return "JOYCON_L";
+ case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: return "JOYCON_R";
+ case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: return "JOYCON_PAIR";
+ default: return "UNKNOWN";
+ }
+ }
+public:
+ struct JOYPAD
+ {
+ bool m_bIsDisabled;
+ bool m_bIsConnected;
+ bool m_bWasConnected;
+ bool m_bHasConnected;
+
+ unsigned int m_uiButtons;
+ unsigned int m_uiOldButtons;
+ int m_uiButtonsPressed;
+ int m_uiButtonsReleased;
+
+ int m_iRightThumbX;
+ int m_iRightThumbY;
+ int m_iLeftThumbX;
+ int m_iLeftThumbY;
+
+ DWORD m_iNormalizedRightThumbX;
+ DWORD m_iNormalizedRightThumbY;
+ DWORD m_iNormalizedLeftThumbX;
+ DWORD m_iNormalizedLeftThumbY;
+
+ float m_fNormalizedRightThumbX;
+ float m_fNormalizedRightThumbY;
+ float m_fNormalizedLeftThumbX;
+ float m_fNormalizedLeftThumbY;
+
+ unsigned char m_ucLeftTriggerState;
+ unsigned char m_ucRightTriggerState;
+
+ float *m_pfLeftThumbXAxisMap;
+ float *m_pfLeftThumbYAxisMap;
+ float *m_pfRightThumbXAxisMap;
+ float *m_pfRightThumbYAxisMap;
+
+ float m_fSensitivity;
+
+ BYTE *m_pucLeftTriggerAxisMap;
+ BYTE *m_pucRightTriggerAxisMap;
+
+ unsigned char m_ucMappingValue;
+ unsigned char m_ucInputStateIndex;
+ SDL_Gamepad *m_pGamepad;
+ };
+
+ struct JOYPADS
+ {
+ };
+
+ struct TimeInfo
+ {
+ LARGE_INTEGER m_qwStartTime;
+ LARGE_INTEGER m_qwTotalHoldTicks;
+ float m_fTotalHoldTime;
+ float m_fLastRepeatTime;
+ bool m_bInitialPressHandled;
+ };
+
+ CInput();
+
+ void Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC);
+ void Tick(void);
+
+ void SetJoypadValues(JOYPAD *pThisPad);
+ void SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax);
+ void SetJoypadSensitivity(int iPad, float fSensitivity);
+
+ void SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal);
+ unsigned int GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction);
+ const char* GetGamepadType(int iPad);
+ void SetJoypadMapVal(int iPad, unsigned char ucMap);
+ unsigned char GetJoypadMapVal(int iPad);
+
+ void SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo);
+ void SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo);
+
+ bool IsPadConnected(int iPad);
+ void SetSelectBackSwapped(bool swapped);
+ bool IsSelectBackSwapped();
+ void SetSigninJoypadMask(unsigned int mask);
+ unsigned int GetValue(int iPad, unsigned char ucAction, bool bRepeat = false);
+ bool IsSet(int iPad, unsigned char ucAction);
+
+ bool ButtonPressed(int iPad, unsigned char ucAction = 255); // toggled
+ bool ButtonReleased(int iPad, unsigned char ucAction); // toggled
+ bool ButtonDown(int iPad, unsigned char ucAction = 255); // button held down
+
+ float GetJoypadStick_Menu_LX(unsigned char ucPad);
+ float GetJoypadStick_Menu_LY(unsigned char ucPad);
+ float GetJoypadStick_Menu_RX(unsigned char ucPad);
+ float GetJoypadStick_Menu_RY(unsigned char ucPad);
+ unsigned char GetJoypadLTrigger_Menu(unsigned char ucPad);
+ unsigned char GetJoypadRTrigger_Menu(unsigned char ucPad);
+
+ float GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay = true);
+ unsigned char GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay = true);
+ unsigned char GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay = true);
+
+ void SetMenuDisplayed(int iPad, bool bVal);
+
+ void SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs);
+ void SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam);
+ FLOAT GetIdleSeconds(int iPad);
+
+ void HandleGamepadEvents();
+ void ShiftGamepadData(int destIndex, int srcIndex);
+ void ClearGamepadSlot(int index);
+ bool UpdateJoypads(void);
+ void ClearJoypadValues(JOYPAD *pThisPad);
+
+ void InitTime(void);
+ void GetStartTime(int iPad, int iKey);
+ void UpdateTime(int iPad, int iKey);
+
+ BYTE gap0[16];
+
+ JOYPAD m_Joypads[MAX_JOYPADS];
+
+ int m_iDeadzone;
+ int m_iMovementRangeMax;
+ int m_iEffectiveRange;
+ int m_iHalfRange;
+ float m_fEffectiveRange;
+
+ unsigned char m_ucInputStateC;
+ unsigned char m_ucJoypadMapC;
+ unsigned char m_ucJoypadMapActionC;
+ unsigned char m_ucMenuActionC;
+
+ unsigned int **m_JoypadMap;
+
+ bool m_bJoypadMapArrayIsSetup;
+ unsigned int m_uiSigninJoypadMask;
+ bool m_bIsMenuDisplayed[MAX_JOYPADS];
+
+ CForceFeedback m_ForceFeedback;
+ CKeyboard m_Keyboard;
+
+ float m_fTickToSeconds;
+ float m_fRepeatDelaySecs;
+ float m_fRepeatRateSecs;
+
+ TimeInfo m_Timers[MAX_JOYPADS][24];
+ LARGE_INTEGER m_LastActivityTime[MAX_JOYPADS];
+
+ char *m_sDebugSequenceName;
+ unsigned int m_uiDebugSequenceIndex;
+ int (*m_pDebugSequenceFn)(void *);
+ LPVOID m_pDebugSequenceParam;
+};
+
+// Singleton
+extern CInput InternalInputManager;
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.cpp
new file mode 100644
index 00000000..cfc2ce14
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.cpp
@@ -0,0 +1,25 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_StringCheck.h"
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.h
new file mode 100644
index 00000000..604a3e9e
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/INP_StringCheck.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.cpp b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.cpp
new file mode 100644
index 00000000..796751cb
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.cpp
@@ -0,0 +1,126 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "LinkedList.h"
+
+LinkedList::LinkedList()
+{
+ this->m_NodeC = 0;
+ this->m_Head = nullptr;
+ this->m_Tail = nullptr;
+}
+
+void LinkedList::AddToHead(void *pvData)
+{
+ _LL_NODE *pNode = new _LL_NODE();
+ pNode->m_pvData = pvData;
+
+ if (!m_Tail)
+ {
+ m_Tail = pNode;
+ }
+
+ if (m_Head)
+ {
+ m_Head->m_Prev = pNode;
+ pNode->m_Next = m_Head;
+ }
+
+ m_Head = pNode;
+ m_NodeC++;
+}
+
+void LinkedList::AddToTail(void *pvData)
+{
+ _LL_NODE *pNode = new _LL_NODE();
+ pNode->m_pvData = pvData;
+
+ if (!m_Head)
+ {
+ m_Head = pNode;
+ }
+
+ if (m_Tail)
+ {
+ m_Tail->m_Next = pNode;
+ pNode->m_Prev = m_Tail;
+ }
+
+ pNode->m_Next = nullptr;
+ pNode->m_Prev = m_Tail;
+
+ m_Tail = pNode;
+ m_NodeC++;
+}
+
+void LinkedList::RemoveNode(_LL_NODE *pNodeToRemove)
+{
+ _LL_NODE *pCurrentNode;
+ for (pCurrentNode = m_Head; pCurrentNode != pNodeToRemove; pCurrentNode = pCurrentNode->m_Next)
+ {
+ ;
+ }
+
+ if (pCurrentNode == m_Head)
+ {
+ m_Head = m_Head->m_Next;
+ }
+ else
+ {
+ pCurrentNode->m_Prev->m_Next = pCurrentNode->m_Next;
+
+ if (pCurrentNode->m_Next)
+ {
+ pCurrentNode->m_Next->m_Prev = pCurrentNode->m_Prev;
+ }
+ }
+
+ m_NodeC--;
+}
+
+LinkedList::_LL_NODE *LinkedList::RemoveHeadNode()
+{
+ _LL_NODE *pHeadNode = m_Head;
+
+ if (m_NodeC > 0)
+ {
+ m_Head = m_Head->m_Next;
+ m_NodeC--;
+ }
+
+ return pHeadNode;
+}
+
+void LinkedList::ClearList()
+{
+ while (true)
+ {
+ _LL_NODE *pHeadNode = RemoveHeadNode();
+ if (!pHeadNode)
+ {
+ break;
+ }
+ delete pHeadNode;
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.h
new file mode 100644
index 00000000..1cfbf2ec
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/LinkedList.h
@@ -0,0 +1,52 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+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 Software.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+class LinkedList
+{
+public:
+ struct _LL_NODE
+ {
+ template
+ T *GetDataAs()
+ {
+ return (T *)m_pvData;
+ }
+
+ void *m_pvData;
+ _LL_NODE *m_Next;
+ _LL_NODE *m_Prev;
+ };
+
+ int m_NodeC;
+ _LL_NODE *m_Head;
+ _LL_NODE *m_Tail;
+
+ LinkedList();
+ void AddToHead(void *pvData);
+ void AddToTail(void *pvData);
+ void RemoveNode(_LL_NODE *pNodeToRemove);
+ _LL_NODE *RemoveHeadNode();
+ void ClearList();
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL.h
new file mode 100644
index 00000000..838c7b83
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.4.14
+ *
+ * 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
+#include
+
+#endif /* SDL_h_ */
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_assert.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_assert.h
new file mode 100644
index 00000000..e65836a0
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_assert.h
@@ -0,0 +1,705 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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(__MINGW32__)
+ #include
+ #define SDL_TriggerBreakpoint() __debugbreak()
+#elif defined(_MSC_VER) && defined(_M_IX86)
+ #define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
+#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(__TINYC__) || defined(__slimcc__)) && (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 constant that contains 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(SDL_FUNCTION)
+#if 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
+#endif
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro that reports the current file being compiled.
+ *
+ * This macro is only defined if it isn't already defined, so to override it
+ * (perhaps with something that doesn't provide path information at all, so
+ * build machine information doesn't leak into public binaries), apps can
+ * define this macro before including SDL.h or SDL_assert.h.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_FILE __FILE_NAME__
+
+#elif !defined(SDL_FILE)
+#ifdef __FILE_NAME__
+#define SDL_FILE __FILE_NAME__
+#else
+#define SDL_FILE __FILE__
+#endif
+#endif
+
+#ifdef SDL_WIKI_DOCUMENTATION_SECTION
+
+/**
+ * A macro that reports the current file being compiled, for use in
+ * assertions.
+ *
+ * This macro is only defined if it isn't already defined, so to override it
+ * (perhaps with something that doesn't provide path information at all, so
+ * build machine information doesn't leak into public binaries), apps can
+ * define this macro before including SDL_assert.h. For example, defining this
+ * to `""` will make sure no source path information is included in asserts.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ */
+#define SDL_ASSERT_FILE SDL_FILE
+
+#elif !defined(SDL_ASSERT_FILE)
+#define SDL_ASSERT_FILE SDL_FILE
+#endif
+
+
+/**
+ * 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) ? 1 : 0) 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 int would be,
+which presumably gets optimized out as unused.
+
+(The `? 1 : 0` is so this always dithers down to `sizeof (int)`...otherwise
+you'll have problems when bitfields are used as the condition, since the
+compiler will error out on the sizeof.)
+
+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) && !defined(__clang__) /* 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, and still checks syntax even when disabled.
+ *
+ * \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) ? 1 : 0); } 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 = { false, 0, #condition, NULL, 0, NULL, NULL }; \
+ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_ASSERT_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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_asyncio.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_asyncio.h
new file mode 100644
index 00000000..3c894d69
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_asyncio.h
@@ -0,0 +1,550 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_atomic.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_atomic.h
new file mode 100644
index 00000000..40521c1d
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_atomic.h
@@ -0,0 +1,692 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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 SDL_HAS_BUILTIN(__atomic_signal_fence) || (defined(__GNUC__) && (__GNUC__ >= 5))
+#define SDL_CompilerBarrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
+#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
+/* We don't unlock here to avoid possible infinite recursion */
+#define SDL_CompilerBarrier() \
+{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_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 SDL_HAS_BUILTIN(__atomic_thread_fence) || (defined(__GNUC__) && (__GNUC__ >= 5))
+#define SDL_MemoryBarrierRelease() __atomic_thread_fence(__ATOMIC_RELEASE)
+#define SDL_MemoryBarrierAcquire() __atomic_thread_fence(__ATOMIC_ACQUIRE)
+#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 ishld" : : : "memory")
+#elif defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
+#include
+#define SDL_MemoryBarrierRelease() __dmb(_ARM64_BARRIER_ISH)
+#define SDL_MemoryBarrierAcquire() __dmb(_ARM64_BARRIER_ISHLD)
+#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__)) && !defined(__arm64ec__)
+ #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);
+
+/**
+ * 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_AtomicU32 variable to be modified.
+ * \param v the desired value to add or subtract.
+ * \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.4.0.
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v);
+
+/**
+ * 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_audio.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_audio.h
new file mode 100644
index 00000000..1e1af26d
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_audio.h
@@ -0,0 +1,2370 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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; the
+ * stream will buffer data as needed.
+ * - 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.
+ *
+ * **WARNING**: this function will work with SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK
+ * and SDL_AUDIO_DEVICE_DEFAULT_RECORDING, returning the current default
+ * physical devices' names. However, as the default device may change at any
+ * time, it is likely better to show a generic name to the user, like "System
+ * default audio device" or perhaps "default [currently %s]". Do not store
+ * this name to disk to reidentify the device in a later run of the program,
+ * as the default might change in general, and the string will be the name of
+ * a specific device and not the abstract system default.
+ *
+ * \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(). If the other
+ * end of the stream's format has never been set (the audio stream was created
+ * with a NULL audio spec), this function will set it to match the device
+ * end's format.
+ *
+ * \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 logical 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.
+ *
+ * Note that `src_spec` or `dst_spec` may be NULL, but any attempts to
+ * put or get data from an audio stream will fail until it has valid
+ * specs assigned to both ends of the stream. Specs can be assigned later
+ * through SDL_SetAudioStreamFormat(), or binding the stream to an audio
+ * device (which will set the format of only the input or output,
+ * depending on what kind of device the stream was bound to).
+ *
+ * \param src_spec the format details of the input audio. May be NULL.
+ * \param dst_spec the format details of the output audio. May be NULL.
+ * \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.
+ *
+ * The application can hang any data it wants here, but the following
+ * properties are understood by SDL:
+ *
+ * - `SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN`: if true (the default), the
+ * stream be automatically cleaned up when the audio subsystem quits. If set
+ * to false, the streams will persist beyond that. This property is ignored
+ * for streams created through SDL_OpenAudioDeviceStream(), and will always
+ * be cleaned up. Streams that are not cleaned up will still be unbound from
+ * devices when the audio subsystem quits. This property was added in SDL
+ * 3.4.0.
+ *
+ * \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);
+
+#define SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN "SDL.audiostream.auto_cleanup"
+
+
+/**
+ * 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.
+ *
+ * `src_spec` and `dst_spec` may each be NULL; a NULL spec signals not to
+ * change the current format for that side of the stream.
+ *
+ * \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.0f will play the audio faster, and at a
+ * higher pitch. A value less than 1.0f will play the audio slower, and at a
+ * lower pitch. 1.0f means play at normal speed.
+ *
+ * This is applied during SDL_GetAudioStreamData, and can be continuously
+ * changed to create various effects.
+ *
+ * \param stream the stream on which 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
+ * different thread at the same time, though!
+ *
+ * \since This function is available since SDL 3.2.0.
+ *
+ * \sa SDL_SetAudioStreamOutputChannelMap
+ */
+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 is 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);
+
+/**
+ * A callback that fires for completed SDL_PutAudioStreamDataNoCopy() data.
+ *
+ * When using SDL_PutAudioStreamDataNoCopy() to provide data to an
+ * SDL_AudioStream, it's not safe to dispose of the data until the stream has
+ * completely consumed it. Often times it's difficult to know exactly when
+ * this has happened.
+ *
+ * This callback fires once when the stream no longer needs the buffer,
+ * allowing the app to easily free or reuse it.
+ *
+ * \param userdata an opaque pointer provided by the app for their personal
+ * use.
+ * \param buf the pointer provided to SDL_PutAudioStreamDataNoCopy().
+ * \param buflen the size of buffer, in bytes, provided to
+ * SDL_PutAudioStreamDataNoCopy().
+ *
+ * \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.4.0.
+ *
+ * \sa SDL_SetAudioStreamGetCallback
+ * \sa SDL_SetAudioStreamPutCallback
+ */
+typedef void (SDLCALL *SDL_AudioStreamDataCompleteCallback)(void *userdata, const void *buf, int buflen);
+
+/**
+ * Add external data to an audio stream without copying it.
+ *
+ * Unlike SDL_PutAudioStreamData(), this function does not make a copy of the
+ * provided data, instead storing the provided pointer. This means that the
+ * put operation does not need to allocate and copy the data, but the original
+ * data must remain available until the stream is done with it, either by
+ * being read from the stream in its entirety, or a call to
+ * SDL_ClearAudioStream() or SDL_DestroyAudioStream().
+ *
+ * The 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.
+ *
+ * An optional callback may be provided, which is called when the stream no
+ * longer needs the data. Once this callback fires, the stream will not access
+ * the data again. This callback will fire for any reason the data is no
+ * longer needed, including clearing or destroying the stream.
+ *
+ * Note that there is still an allocation to store tracking information, so
+ * this function is more efficient for larger blocks of data. If you're
+ * planning to put a few samples at a time, it will be more efficient to use
+ * SDL_PutAudioStreamData(), which allocates and buffers in blocks.
+ *
+ * \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 add to the stream.
+ * \param callback the callback function to call when the data is no longer
+ * needed by the stream. May be NULL.
+ * \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.
+ *
+ * \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.4.0.
+ *
+ * \sa SDL_ClearAudioStream
+ * \sa SDL_FlushAudioStream
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_GetAudioStreamQueued
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamDataNoCopy(SDL_AudioStream *stream, const void *buf, int len, SDL_AudioStreamDataCompleteCallback callback, void *userdata);
+
+/**
+ * Add data to the stream with each channel in a separate array.
+ *
+ * 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.
+ *
+ * The data will be interleaved and queued. Note that SDL_AudioStream only
+ * operates on interleaved data, so this is simply a convenience function for
+ * easily queueing data from sources that provide separate arrays. There is no
+ * equivalent function to retrieve planar data.
+ *
+ * The arrays in `channel_buffers` are ordered as they are to be interleaved;
+ * the first array will be the first sample in the interleaved data. Any
+ * individual array may be NULL; in this case, silence will be interleaved for
+ * that channel.
+ *
+ * `num_channels` specifies how many arrays are in `channel_buffers`. This can
+ * be used as a safety to prevent overflow, in case the stream format has
+ * changed elsewhere. If more channels are specified than the current input
+ * spec, they are ignored. If less channels are specified, the missing arrays
+ * are treated as if they are NULL (silence is written to those channels). If
+ * the count is -1, SDL will assume the array count matches the current input
+ * spec.
+ *
+ * Note that `num_samples` is the number of _samples per array_. This can also
+ * be thought of as the number of _sample frames_ to be queued. A value of 1
+ * with stereo arrays will queue two samples to the stream. This is different
+ * than SDL_PutAudioStreamData, which wants the size of a single array in
+ * bytes.
+ *
+ * \param stream the stream the audio data is being added to.
+ * \param channel_buffers a pointer to an array of arrays, one array per
+ * channel.
+ * \param num_channels the number of arrays in `channel_buffers` or -1.
+ * \param num_samples the number of _samples_ per array 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.4.0.
+ *
+ * \sa SDL_ClearAudioStream
+ * \sa SDL_FlushAudioStream
+ * \sa SDL_GetAudioStreamData
+ * \sa SDL_GetAudioStreamQueued
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamPlanarData(SDL_AudioStream *stream, const void * const *channel_buffers, int num_channels, int num_samples);
+
+/**
+ * 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.
+ *
+ * SDL_OpenAudioDeviceStream opens audio devices in a paused state, so this
+ * function call is required for audio playback to begin on such devices.
+ *
+ * \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.
+ *
+ * Do not call SDL_DestroyAudioStream() on `stream` during this callback.
+ *
+ * \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().
+ *
+ * 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_begin_code.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_begin_code.h
new file mode 100644
index 00000000..4f3fe2d9
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_begin_code.h
@@ -0,0 +1,553 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.4.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)
+
+/**
+ * A macro to specify data alignment.
+ *
+ * This informs the compiler that a given datatype or variable must be aligned
+ * to a specific byte count.
+ *
+ * For example:
+ *
+ * ```c
+ * // make sure this is struct is aligned to 16 bytes for SIMD access.
+ * typedef struct {
+ * float x, y, z, w;
+ * } SDL_ALIGNED(16) MySIMDAlignedData;
+ *
+ * // make sure this one field in a struct is aligned to 16 bytes for SIMD access.
+ * typedef struct {
+ * SomeStuff stuff;
+ * float SDL_ALIGNED(16) position[4];
+ * SomeOtherStuff other_stuff;
+ * } MyStruct;
+ *
+ * // make sure this variable is aligned to 32 bytes.
+ * int SDL_ALIGNED(32) myval = 0;
+ * ```
+ *
+ * Alignment is only guaranteed for things the compiler places: local
+ * variables on the stack and global/static variables. To dynamically allocate
+ * something that respects this alignment, use SDL_aligned_alloc() or some
+ * other mechanism.
+ *
+ * On compilers without alignment support, this macro is defined to an invalid
+ * symbol, to make it clear that the current compiler is likely to generate
+ * incorrect code when it sees this macro.
+ *
+ * \param x the byte count to align to, so the data's address will be a
+ * multiple of this value.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ */
+#define SDL_ALIGNED(x) __attribute__((aligned(x)))
+
+/* end of wiki documentation section. */
+#endif
+
+/* `restrict` is from C99, but __restrict works with both Visual Studio and GCC. */
+#ifndef SDL_RESTRICT
+# if defined(restrict) || ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)))
+# define SDL_RESTRICT restrict
+# elif defined(_MSC_VER) || defined(__GNUC__) || defined(__clang__)
+# define SDL_RESTRICT __restrict
+# else
+# define SDL_RESTRICT
+# endif
+#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
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#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
+#if defined(__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 /* __MACH__ */
+
+#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 */
+
+#ifndef SDL_ALIGNED
+#if defined(__clang__) || defined(__GNUC__)
+#define SDL_ALIGNED(x) __attribute__((aligned(x)))
+#elif defined(_MSC_VER)
+#define SDL_ALIGNED(x) __declspec(align(x))
+#elif defined(__cplusplus) && (__cplusplus >= 201103L)
+#define SDL_ALIGNED(x) alignas(x)
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#define SDL_ALIGNED(x) _Alignas(x)
+#else
+#define SDL_ALIGNED(x) PLEASE_DEFINE_SDL_ALIGNED
+#endif
+#endif /* SDL_ALIGNED not defined */
+
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_bits.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_bits.h
new file mode 100644
index 00000000..d3310ab1
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_bits.h
@@ -0,0 +1,146 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.
+ *
+ * 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_blendmode.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_blendmode.h
new file mode 100644
index 00000000..84cf622c
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_blendmode.h
@@ -0,0 +1,202 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_camera.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_camera.h
new file mode 100644
index 00000000..220acd1b
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_camera.h
@@ -0,0 +1,535 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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 denominator ((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;
+
+/**
+ * The current state of a request for camera access.
+ *
+ * \since This enum is available since SDL 3.4.0.
+ *
+ * \sa SDL_GetCameraPermissionState
+ */
+typedef enum SDL_CameraPermissionState
+{
+ SDL_CAMERA_PERMISSION_STATE_DENIED = -1,
+ SDL_CAMERA_PERMISSION_STATE_PENDING,
+ SDL_CAMERA_PERMISSION_STATE_APPROVED
+} SDL_CameraPermissionState;
+
+
+/**
+ * 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 SDL_CAMERA_PERMISSION_STATE_PENDING if waiting for user response,
+ * SDL_CAMERA_PERMISSION_STATE_APPROVED if the camera is approved for use, and
+ * SDL_CAMERA_PERMISSION_STATE_DENIED 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 an SDL_CameraPermissionState value indicating if access is
+ * granted, or `SDL_CAMERA_PERMISSION_STATE_PENDING` if the decision
+ * is still pending.
+ *
+ * \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 SDL_CameraPermissionState 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_clipboard.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_clipboard.h
new file mode 100644
index 00000000..487f9746
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_clipboard.h
@@ -0,0 +1,331 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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 function returns an empty string if there is 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 function returns an empty string if there is 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 the 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 the length to 0 will cause zero length data to be sent
+ * to the "receiver", which should be able to handle this. 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
+ * when new data is set.
+ *
+ * \param userdata a pointer to the 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. SDL copies
+ * the given list.
+ * \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 *const *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 the 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.
+ * \returns true if data exists in the 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_close_code.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_close_code.h
new file mode 100644
index 00000000..ad9daa6d
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_close_code.h
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_copying.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_copying.h
new file mode 100644
index 00000000..dd9dbc7e
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_copying.h
@@ -0,0 +1,22 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_cpuinfo.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_cpuinfo.h
new file mode 100644
index 00000000..5669c237
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_cpuinfo.h
@@ -0,0 +1,374 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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);
+
+/**
+ * Report the size of a page of memory.
+ *
+ * Different platforms might have different memory page sizes. In current
+ * times, 4 kilobytes is not unusual, but newer systems are moving to larger
+ * page sizes, and esoteric platforms might have any unexpected size.
+ *
+ * Note that this function can return 0, which means SDL can't determine the
+ * page size on this platform. It will _not_ set an error string to be
+ * retrieved with SDL_GetError() in this case! In this case, defaulting to
+ * 4096 is often a reasonable option.
+ *
+ * \returns the size of a single page of memory, in bytes, or 0 if SDL can't
+ * determine this information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.4.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetSystemPageSize(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_cpuinfo_h_ */
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dialog.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dialog.h
new file mode 100644
index 00000000..1e01347b
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dialog.h
@@ -0,0 +1,343 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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. See the
+ * [`SDL_DialogFileFilter`](SDL_DialogFileFilter#code-examples)
+ * documentation for examples]. 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dlopennote.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dlopennote.h
new file mode 100644
index 00000000..299435a5
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_dlopennote.h
@@ -0,0 +1,234 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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: DlopenNotes */
+
+/**
+ * # CategoryDlopenNotes
+ *
+ * This header allows you to annotate your code so external tools know about
+ * dynamic shared library dependencies.
+ *
+ * If you determine that your toolchain doesn't support dlopen notes, you can
+ * disable this feature by defining `SDL_DISABLE_DLOPEN_NOTES`. You can use
+ * this CMake snippet to check for support:
+ *
+ * ```cmake
+ * include(CheckCSourceCompiles)
+ * find_package(SDL3 REQUIRED CONFIG COMPONENTS Headers)
+ * list(APPEND CMAKE_REQUIRED_LIBRARIES SDL3::Headers)
+ * check_c_source_compiles([==[
+ * #include
+ * SDL_ELF_NOTE_DLOPEN("sdl-video",
+ * "Support for video through SDL",
+ * SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+ * "libSDL-1.2.so.0", "libSDL-2.0.so.0", "libSDL3.so.0"
+ * )
+ * int main(int argc, char *argv[]) {
+ * return argc + argv[0][1];
+ * }
+ * ]==] COMPILER_SUPPORTS_SDL_ELF_NOTE_DLOPEN)
+ * if(NOT COMPILER_SUPPORTS_SDL_ELF_NOTE_DLOPEN)
+ * add_compile_definitions(-DSDL_DISABLE_DLOPEN_NOTE)
+ * endif()
+ * ```
+ */
+
+#ifndef SDL_dlopennote_h
+#define SDL_dlopennote_h
+
+/**
+ * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared
+ * library dependency is optional.
+ *
+ * Optional functionality uses the dependency, the binary will work and the
+ * dependency is only needed for full-featured installations.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ *
+ * \sa SDL_ELF_NOTE_DLOPEN
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED
+ */
+#define SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested"
+
+/**
+ * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared
+ * library dependency is recommended.
+ *
+ * Important functionality needs the dependency, the binary will work but in
+ * most cases the dependency should be provided.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ *
+ * \sa SDL_ELF_NOTE_DLOPEN
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED
+ */
+#define SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended"
+
+/**
+ * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared
+ * library dependency is required.
+ *
+ * Core functionality needs the dependency, the binary will not work if it
+ * cannot be found.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ *
+ * \sa SDL_ELF_NOTE_DLOPEN
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED
+ */
+#define SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required"
+
+
+#if !defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_ANDROID)
+/* The dlopen note functionality isn't used on this platform */
+#ifndef SDL_DISABLE_DLOPEN_NOTES
+#define SDL_DISABLE_DLOPEN_NOTES
+#endif
+#elif defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 1))
+/* gcc < 3.1 too old */
+#ifndef SDL_DISABLE_DLOPEN_NOTES
+#define SDL_DISABLE_DLOPEN_NOTES
+#endif
+#endif /* SDL_PLATFORM_UNIX || SDL_PLATFORM_ANDROID */
+
+#if defined(__ELF__) && !defined(SDL_DISABLE_DLOPEN_NOTES)
+
+#include
+
+#define SDL_ELF_NOTE_DLOPEN_VENDOR "FDO"
+#define SDL_ELF_NOTE_DLOPEN_TYPE 0x407c0c0aU
+
+#define SDL_ELF_NOTE_INTERNAL2(json, variable_name) \
+ __attribute__((aligned(4), used, section(".note.dlopen"))) \
+ static const struct { \
+ struct { \
+ Uint32 n_namesz; \
+ Uint32 n_descsz; \
+ Uint32 n_type; \
+ } nhdr; \
+ char name[4]; \
+ __attribute__((aligned(4))) char dlopen_json[sizeof(json)]; \
+ } variable_name = { \
+ { \
+ sizeof(SDL_ELF_NOTE_DLOPEN_VENDOR), \
+ sizeof(json), \
+ SDL_ELF_NOTE_DLOPEN_TYPE \
+ }, \
+ SDL_ELF_NOTE_DLOPEN_VENDOR, \
+ json \
+ }
+
+#define SDL_ELF_NOTE_INTERNAL(json, variable_name) \
+ SDL_ELF_NOTE_INTERNAL2(json, variable_name)
+
+#define SDL_DLNOTE_JSON_ARRAY1(N1) "[\"" N1 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY2(N1,N2) "[\"" N1 "\",\"" N2 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY3(N1,N2,N3) "[\"" N1 "\",\"" N2 "\",\"" N3 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY4(N1,N2,N3,N4) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY5(N1,N2,N3,N4,N5) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY6(N1,N2,N3,N4,N5,N6) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY7(N1,N2,N3,N4,N5,N6,N7) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY8(N1,N2,N3,N4,N5,N6,N7,N8) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\",\"" N8 "\"]"
+#define SDL_DLNOTE_JSON_ARRAY_GET(N1,N2,N3,N4,N5,N6,N7,N8,NAME,...) NAME
+#define SDL_DLNOTE_JSON_ARRAY(...) \
+ SDL_DLNOTE_JSON_ARRAY_GET( \
+ __VA_ARGS__, \
+ SDL_DLNOTE_JSON_ARRAY8, \
+ SDL_DLNOTE_JSON_ARRAY7, \
+ SDL_DLNOTE_JSON_ARRAY6, \
+ SDL_DLNOTE_JSON_ARRAY5, \
+ SDL_DLNOTE_JSON_ARRAY4, \
+ SDL_DLNOTE_JSON_ARRAY3, \
+ SDL_DLNOTE_JSON_ARRAY2, \
+ SDL_DLNOTE_JSON_ARRAY1 \
+ )(__VA_ARGS__)
+
+/* Create "unique" variable name using __LINE__,
+ * so creating multiple elf notes on the same line is not supported
+ */
+#define SDL_DLNOTE_JOIN2(A,B) A##B
+#define SDL_DLNOTE_JOIN(A,B) SDL_DLNOTE_JOIN2(A,B)
+#define SDL_DLNOTE_UNIQUE_NAME SDL_DLNOTE_JOIN(s_SDL_dlopen_note_, __LINE__)
+
+/**
+ * Add a note that your application has dynamic shared library dependencies.
+ *
+ * You can do this by adding the following to the global scope:
+ *
+ * ```c
+ * SDL_ELF_NOTE_DLOPEN(
+ * "png",
+ * "Support for loading PNG images using libpng (required for APNG)",
+ * SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
+ * "libpng12.so.0"
+ * )
+ * ```
+ *
+ * A trailing semicolon is not needed.
+ *
+ * Or if you support multiple versions of a library, you can list them:
+ *
+ * ```c
+ * // Our app supports SDL1, SDL2, and SDL3 by dynamically loading them
+ * SDL_ELF_NOTE_DLOPEN(
+ * "SDL",
+ * "Create windows through SDL video backend",
+ * SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED
+ * "libSDL-1.2.so.0", "libSDL2-2.0.so.0", "libSDL3.so.0"
+ * )
+ * ```
+ *
+ * This macro is not available for compilers that do not support variadic
+ * macro's.
+ *
+ * \since This macro is available since SDL 3.4.0.
+ *
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED
+ * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED
+ */
+#define SDL_ELF_NOTE_DLOPEN(feature, description, priority, ...) \
+ SDL_ELF_NOTE_INTERNAL( \
+ "[{\"feature\":\"" feature \
+ "\",\"description\":\"" description \
+ "\",\"priority\":\"" priority \
+ "\",\"soname\":" SDL_DLNOTE_JSON_ARRAY(__VA_ARGS__) "}]", \
+ SDL_DLNOTE_UNIQUE_NAME);
+
+#elif defined(__GNUC__) && __GNUC__ < 3
+
+#define SDL_ELF_NOTE_DLOPEN(args...)
+
+#elif defined(_MSC_VER) && _MSC_VER < 1400
+
+/* Variadic macros are not supported */
+
+#else
+
+#define SDL_ELF_NOTE_DLOPEN(...)
+
+#endif
+
+#endif /* SDL_dlopennote_h */
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_egl.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_egl.h
new file mode 100644
index 00000000..1371c4d0
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_egl.h
@@ -0,0 +1,2355 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_endian.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_endian.h
new file mode 100644
index 00000000..69f097ed
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_endian.h
@@ -0,0 +1,645 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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. */
+#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
+#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) || defined(__GLIBC__)
+#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 /* SDL_WIKI_DOCUMENTATION_SECTION */
+#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": "=abcd"(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 Uint64 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_error.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_error.h
new file mode 100644
index 00000000..3453818c
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_error.h
@@ -0,0 +1,226 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_events.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_events.h
new file mode 100644
index 00000000..312623e6
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_events.h
@@ -0,0 +1,1645 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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 occurred 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_USABLE_BOUNDS_CHANGED, /**< Display has changed usable bounds */
+ SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION,
+ SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_USABLE_BOUNDS_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.
+ data1 is 1 for live-resize expose events, 0 otherwise. */
+ 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 */
+ SDL_EVENT_SCREEN_KEYBOARD_SHOWN, /**< The on-screen keyboard has been shown */
+ SDL_EVENT_SCREEN_KEYBOARD_HIDDEN, /**< The on-screen keyboard has been hidden */
+
+ /* 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,
+
+ /* Pinch events */
+ SDL_EVENT_PINCH_BEGIN = 0x710, /**< Pinch gesture started */
+ SDL_EVENT_PINCH_UPDATE, /**< Pinch gesture updated */
+ SDL_EVENT_PINCH_END, /**< Pinch gesture ended */
+
+ /* 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 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_EVENT_DISPLAY_* */
+ 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, SDL_PEN_MOUSEID for pen 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.*)
+ *
+ * Note that SDL will send a SDL_EVENT_AUDIO_DEVICE_ADDED event for every
+ * device it discovers during initialization. After that, this event will only
+ * arrive when a device is hotplugged during the program's run.
+ *
+ * \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;
+
+/**
+ * Pinch event structure (event.pinch.*)
+ */
+typedef struct SDL_PinchFingerEvent
+{
+ SDL_EventType type; /**< ::SDL_EVENT_PINCH_BEGIN or ::SDL_EVENT_PINCH_UPDATE or ::SDL_EVENT_PINCH_END */
+ Uint32 reserved;
+ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
+ float scale; /**< The scale change since the last SDL_EVENT_PINCH_UPDATE. Scale < 1 is "zoom out". Scale > 1 is "zoom in". */
+ SDL_WindowID windowID; /**< The window underneath the finger, if any */
+} SDL_PinchFingerEvent;
+
+/**
+ * Pressure-sensitive pen proximity event structure (event.pproximity.*)
+ *
+ * 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.
+ *
+ * Not all platforms have a window associated with the pen during proximity
+ * events. Some wait until motion/button/etc events to offer this info.
+ *
+ * \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, 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_PinchFingerEvent pinch; /**< Pinch 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_static_cast(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`.
+ *
+ * If `event` is NULL, it simply returns true 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 initialized the video subsystem.
+ *
+ * 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
+ * }
+ * ```
+ *
+ * Note that Windows (and possibly other platforms) has a quirk about how it
+ * handles events while dragging/resizing a window, which can cause this
+ * function to block for significant amounts of time. Technical explanations
+ * and solutions are discussed on the wiki:
+ *
+ * https://wiki.libsdl.org/SDL3/AppFreezeDuringDrag
+ *
+ * \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! The exception is handling of
+ * SDL_EVENT_WINDOW_EXPOSED, which is guaranteed to be sent from the OS on the
+ * main thread and you are expected to redraw your window in response to this
+ * event.
+ *
+ * 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 a 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);
+
+/**
+ * Generate an English description of an event.
+ *
+ * This will fill `buf` with a null-terminated string that might look
+ * something like this:
+ *
+ * ```
+ * SDL_EVENT_MOUSE_MOTION (timestamp=1140256324 windowid=2 which=0 state=0 x=492.99 y=139.09 xrel=52 yrel=6)
+ * ```
+ *
+ * The exact format of the string is not guaranteed; it is intended for
+ * logging purposes, to be read by a human, and not parsed by a computer.
+ *
+ * The returned value follows the same rules as SDL_snprintf(): `buf` will
+ * always be NULL-terminated (unless `buflen` is zero), and will be truncated
+ * if `buflen` is too small. The return code is the number of bytes needed for
+ * the complete string, not counting the NULL-terminator, whether the string
+ * was truncated or not. Unlike SDL_snprintf(), though, this function never
+ * returns -1.
+ *
+ * \param event an event to describe. May be NULL.
+ * \param buf the buffer to fill with the description string. May be NULL.
+ * \param buflen the maximum bytes that can be written to `buf`.
+ * \returns number of bytes needed for the full string, not counting the
+ * null-terminator byte.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.4.0.
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_events_h_ */
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_filesystem.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_filesystem.h
new file mode 100644
index 00000000..3a077a09
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_filesystem.h
@@ -0,0 +1,537 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/`
+ *
+ * **Android Specific Functionality**: This function returns "./", which
+ * allows filesystem operations to use internal storage and the asset system.
+ *
+ * **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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * Due to historical mistakes, `org` is allowed to be NULL or "". In such
+ * cases, SDL will omit the org subdirectory, including on platforms where it
+ * shouldn't, and including on platforms where this would make your app fail
+ * certification for an app store. New apps should definitely specify a real
+ * string for `org`.
+ *
+ * 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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_GetUserFolder(SDL_Folder folder);
+
+
+/* Abstract filesystem interface */
+
+/**
+ * Types of filesystem entries.
+ *
+ * Note that there may be other sorts of items on a filesystem: devices, 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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \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_RemovePath(const char *path);
+
+/**
+ * Rename a file or directory.
+ *
+ * If the file at `newpath` already exists, it will be 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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread, but this
+ * operation is not atomic, so the app might need to protect
+ * access to specific paths from other threads if appropriate.
+ *
+ * \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.
+ *
+ * Symlinks, on filesystems that support them, are always followed, so you
+ * will always get information on what the symlink eventually points to, and
+ * not the symlink itself.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \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_GetCurrentDirectory(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include
+
+#endif /* SDL_filesystem_h_ */
diff --git a/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gamepad.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gamepad.h
new file mode 100644
index 00000000..9c88a770
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gamepad.h
@@ -0,0 +1,1656 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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're using SDL gamepad support in a Steam game, you must call
+ * SteamAPI_InitEx() before calling SDL_Init().
+ *
+ * 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_GAMECUBE,
+ 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 GameCube controllers this
+ * would be A/X/B/Y, 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, Steam Controller QAM 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, DualSense Edge RB button, Right Joy-Con SR button, Steam Controller R4 button) */
+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /**< Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3, DualSense Edge LB button, Left Joy-Con SL button, Steam Controller L4 button) */
+ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /**< Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2, DualSense Edge right Fn button, Right Joy-Con SL button, Steam Controller R5 button) */
+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /**< Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4, DualSense Edge left Fn button, Left Joy-Con SR button, Steam Controller L5 button) */
+ SDL_GAMEPAD_BUTTON_TOUCHPAD, /**< PS4/PS5 touchpad button */
+ SDL_GAMEPAD_BUTTON_MISC2, /**< Additional button */
+ SDL_GAMEPAD_BUTTON_MISC3, /**< Additional button (e.g. Nintendo GameCube left trigger click) */
+ SDL_GAMEPAD_BUTTON_MISC4, /**< Additional button (e.g. Nintendo GameCube right trigger click) */
+ 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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * Note that for invalid gamepads or axes, this will return 0. Zero is also a
+ * valid value in normal operation; usually it means a centered axis.
+ *
+ * \param gamepad a gamepad.
+ * \param axis an axis index (one of the SDL_GamepadAxis values).
+ * \returns axis state.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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 button.
+ * \returns the SDL_GamepadButton enum corresponding to the input string, or
+ * `SDL_GAMEPAD_BUTTON_INVALID` if no match was found.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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 the remarks in SDL_SensorType for 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.
+ *
+ * \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_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.
+ *
+ * \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_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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \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_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.
+ *
+ * \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_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().
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gpu.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gpu.h
new file mode 100644
index 00000000..603ca92a
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_gpu.h
@@ -0,0 +1,4608 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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](https://renderdoc.org/)
+ * can be very helpful for diagnosing incorrect behavior and performance
+ * issues.
+ *
+ * ## System Requirements
+ *
+ * ### Vulkan
+ *
+ * SDL driver name: "vulkan" (for use in SDL_CreateGPUDevice() and
+ * SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING)
+ *
+ * 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`
+ * - `sampleRateShading`
+ *
+ * You can remove some of these requirements to increase compatibility with
+ * Android devices by using these properties when creating the GPU device with
+ * SDL_CreateGPUDeviceWithProperties():
+ *
+ * - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN
+ * - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN
+ * - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN
+ * - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN
+ *
+ * ### D3D12
+ *
+ * SDL driver name: "direct3d12"
+ *
+ * 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_0 and
+ * Resource Binding Tier 2 or above.
+ *
+ * You can remove the Tier 2 resource binding requirement to support Intel
+ * Haswell and Broadwell GPUs by using this property when creating the GPU
+ * device with SDL_CreateGPUDeviceWithProperties():
+ *
+ * - SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN
+ *
+ * ### Metal
+ *
+ * SDL driver name: "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
+ *
+ * ## Coordinate System
+ *
+ * The GPU API uses a left-handed coordinate system, following the convention
+ * of D3D12 and Metal. Specifically:
+ *
+ * - **Normalized Device Coordinates:** The lower-left corner has an x,y
+ * coordinate of `(-1.0, -1.0)`. The upper-right corner is `(1.0, 1.0)`. Z
+ * values range from `[0.0, 1.0]` where 0 is the near plane.
+ * - **Viewport Coordinates:** The top-left corner has an x,y coordinate of
+ * `(0, 0)` and extends to the bottom-right corner at `(viewportWidth,
+ * viewportHeight)`. +Y is down.
+ * - **Texture Coordinates:** The top-left corner has an x,y coordinate of
+ * `(0, 0)` and extends to the bottom-right corner at `(1.0, 1.0)`. +Y is
+ * down.
+ *
+ * If the backend driver differs from this convention (e.g. Vulkan, which has
+ * an NDC that assumes +Y is down), SDL will automatically convert the
+ * coordinate system behind the scenes, so you don't need to perform any
+ * coordinate flipping logic in your shaders.
+ *
+ * ## 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.
+ *
+ * ## Debugging
+ *
+ * At some point of your GPU journey, you will probably encounter issues that
+ * are not traceable with regular debugger - for example, your code compiles
+ * but you get an empty screen, or your shader fails in runtime.
+ *
+ * For debugging such cases, there are tools that allow visually inspecting
+ * the whole GPU frame, every drawcall, every bound resource, memory buffers,
+ * etc. They are the following, per platform:
+ *
+ * * For Windows/Linux, use
+ * [RenderDoc](https://renderdoc.org/)
+ * * For MacOS (Metal), use Xcode built-in debugger (Open XCode, go to Debug >
+ * Debug Executable..., select your application, set "GPU Frame Capture" to
+ * "Metal" in scheme "Options" window, run your app, and click the small
+ * Metal icon on the bottom to capture a frame)
+ *
+ * Aside from that, you may want to enable additional debug layers to receive
+ * more detailed error messages, based on your GPU backend:
+ *
+ * * For D3D12, the debug layer is an optional feature that can be installed
+ * via "Windows Settings -> System -> Optional features" and adding the
+ * "Graphics Tools" optional feature.
+ * * For Vulkan, you will need to install Vulkan SDK on Windows, and on Linux,
+ * you usually have some sort of `vulkan-validation-layers` system package
+ * that should be installed.
+ * * For Metal, it should be enough just to run the application from XCode to
+ * receive detailed errors or warnings in the output.
+ *
+ * Don't hesitate to use tools as RenderDoc when encountering runtime issues
+ * or unexpected output on screen, quick GPU frame inspection can usually help
+ * you fix the majority of such problems.
+ */
+
+#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 combining SAMPLER with STORAGE_READ flags is 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.
+ *
+ * If a buffer has multiple read usages, this may lead to a performance penalty
+ * due to more conservative memory barriers, but it also may not necessarily affect the performance.
+ *
+ * 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 evaluates 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.
+ *
+ * If either of `pixels_per_row` or `rows_per_layer` is zero, then width and
+ * height of passed SDL_GPUTextureRegion to SDL_UploadToGPUTexture or
+ * SDL_DownloadFromGPUTexture are used as default values respectively and data
+ * is considered to be tightly packed.
+ *
+ * **WARNING**: On some older/integrated hardware, Direct3D 12 requires
+ * texture data row pitch to be 256 byte aligned, and offsets to be aligned to
+ * 512 bytes. If they are not, SDL will make a temporary copy of the data that
+ * is properly aligned, but this adds overhead to the transfer process. Apps
+ * can avoid this by aligning their data appropriately, or using a different
+ * GPU backend than Direct3D 12.
+ *
+ * \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 size of a single element + the offset between elements. */
+ 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
+ * \sa SDL_GPUBlendFactor
+ * \sa SDL_GPUBlendOp
+ * \sa SDL_GPUColorComponentFlags
+ */
+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
+ * \sa SDL_GPUShaderFormat
+ * \sa SDL_GPUShaderStage
+ */
+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. */
+ bool enable_alpha_to_coverage; /**< true enables the alpha-to-coverage feature. */
+ 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
+ * \sa SDL_FColor
+ */
+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.
+ *
+ * Due to ABI limitations, depth textures with more than 255 layers are not
+ * supported.
+ *
+ * \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 mip_level; /**< The mip level to use as the depth stencil target. */
+ Uint8 layer; /**< The layer index to use as the depth stencil target. */
+} 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
+ * \sa SDL_GPUTexture
+ * \sa SDL_GPUSampler
+ */
+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.
+ *
+ * The GPU driver name can be one of the following:
+ *
+ * - "vulkan": [Vulkan](CategoryGPU#vulkan)
+ * - "direct3d12": [D3D12](CategoryGPU#d3d12)
+ * - "metal": [Metal](CategoryGPU#metal)
+ * - NULL: let SDL pick the optimal driver
+ *
+ * \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_CreateGPUDeviceWithProperties
+ * \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_VERBOSE_BOOLEAN`: enable to automatically log
+ * useful debug information on device creation, defaults to true.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING`: the name of the GPU driver to
+ * use, if a specific one is desired.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN`: Enable Vulkan
+ * device feature shaderClipDistance. If disabled, clip distances are not
+ * supported in shader code: gl_ClipDistance[] built-ins of GLSL,
+ * SV_ClipDistance0/1 semantics of HLSL and [[clip_distance]] attribute of
+ * Metal. Disabling optional features allows the application to run on some
+ * older Android devices. Defaults to true.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN`: Enable
+ * Vulkan device feature depthClamp. If disabled, there is no depth clamp
+ * support and enable_depth_clip in SDL_GPURasterizerState must always be
+ * set to true. Disabling optional features allows the application to run on
+ * some older Android devices. Defaults to true.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN`:
+ * Enable Vulkan device feature drawIndirectFirstInstance. If disabled, the
+ * argument first_instance of SDL_GPUIndirectDrawCommand must be set to
+ * zero. Disabling optional features allows the application to run on some
+ * older Android devices. Defaults to true.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN`: Enable Vulkan
+ * device feature samplerAnisotropy. If disabled, enable_anisotropy of
+ * SDL_GPUSamplerCreateInfo must be set to false. Disabling optional
+ * features allows the application to run on some older Android devices.
+ * Defaults to true.
+ *
+ * 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 backend:
+ *
+ * - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING`: the prefix to
+ * use for all vertex semantics, default is "TEXCOORD".
+ * - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN`: By
+ * default, Resourcing Binding Tier 2 is required for D3D12 support.
+ * However, an application can set this property to true to enable Tier 1
+ * support, if (and only if) the application uses 8 or fewer storage
+ * resources across all shader stages. As of writing, this property is
+ * useful for targeting Intel Haswell and Broadwell GPUs; other hardware
+ * either supports Tier 2 Resource Binding or does not support D3D12 in any
+ * capacity. Defaults to false.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_VERSION_NUMBER`: Certain
+ * feature checks are only possible on Windows 11 by default. By setting
+ * this alongside `SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_PATH_STRING`
+ * and vendoring D3D12Core.dll from the D3D12 Agility SDK, you can make
+ * those feature checks possible on older platforms. The version you provide
+ * must match the one given in the DLL.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_PATH_STRING`: Certain
+ * feature checks are only possible on Windows 11 by default. By setting
+ * this alongside
+ * `SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_VERSION_NUMBER` and
+ * vendoring D3D12Core.dll from the D3D12 Agility SDK, you can make those
+ * feature checks possible on older platforms. The path you provide must be
+ * relative to the executable path of your app. Be sure not to put the DLL
+ * in the same directory as the exe; Microsoft strongly advises against
+ * this!
+ *
+ * With the Vulkan backend:
+ *
+ * - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_REQUIRE_HARDWARE_ACCELERATION_BOOLEAN`:
+ * By default, Vulkan device enumeration includes drivers of all types,
+ * including software renderers (for example, the Lavapipe Mesa driver).
+ * This can be useful if your application _requires_ SDL_GPU, but if you can
+ * provide your own fallback renderer (for example, an OpenGL renderer) this
+ * property can be set to true. Defaults to false.
+ * - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER`: a pointer to an
+ * SDL_GPUVulkanOptions structure to be processed during device creation.
+ * This allows configuring a variety of Vulkan-specific options such as
+ * increasing the API version and opting into extensions aside from the
+ * minimal set SDL requires.
+ *
+ * With the Metal backend: -
+ * `SDL_PROP_GPU_DEVICE_CREATE_METAL_ALLOW_MACFAMILY1_BOOLEAN`: By default,
+ * macOS support requires what Apple calls "MTLGPUFamilyMac2" hardware or
+ * newer. However, an application can set this property to true to enable
+ * support for "MTLGPUFamilyMac1" hardware, if (and only if) the application
+ * does not write to sRGB textures. (For history's sake: MacFamily1 also does
+ * not support indirect command buffers, MSAA depth resolve, and stencil
+ * resolve/feedback, but these are not exposed features in SDL_GPU.)
+ *
+ * \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_VERBOSE_BOOLEAN "SDL.gpu.device.create.verbose"
+#define SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING "SDL.gpu.device.create.name"
+#define SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN "SDL.gpu.device.create.feature.clip_distance"
+#define SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN "SDL.gpu.device.create.feature.depth_clamping"
+#define SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN "SDL.gpu.device.create.feature.indirect_draw_first_instance"
+#define SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN "SDL.gpu.device.create.feature.anisotropy"
+#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_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN "SDL.gpu.device.create.d3d12.allowtier1resourcebinding"
+#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING "SDL.gpu.device.create.d3d12.semantic"
+#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_VERSION_NUMBER "SDL.gpu.device.create.d3d12.agility_sdk_version"
+#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_AGILITY_SDK_PATH_STRING "SDL.gpu.device.create.d3d12.agility_sdk_path"
+#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_REQUIRE_HARDWARE_ACCELERATION_BOOLEAN "SDL.gpu.device.create.vulkan.requirehardwareacceleration"
+#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER "SDL.gpu.device.create.vulkan.options"
+#define SDL_PROP_GPU_DEVICE_CREATE_METAL_ALLOW_MACFAMILY1_BOOLEAN "SDL.gpu.device.create.metal.allowmacfamily1"
+
+
+/**
+ * A structure specifying additional options when using Vulkan.
+ *
+ * When no such structure is provided, SDL will use Vulkan API version 1.0 and
+ * a minimal set of features. The requested API version influences how the
+ * feature_list is processed by SDL. When requesting API version 1.0, the
+ * feature_list is ignored. Only the vulkan_10_physical_device_features and
+ * the extension lists are used. When requesting API version 1.1, the
+ * feature_list is scanned for feature structures introduced in Vulkan 1.1.
+ * When requesting Vulkan 1.2 or higher, the feature_list is additionally
+ * scanned for compound feature structs such as
+ * VkPhysicalDeviceVulkan11Features. The device and instance extension lists,
+ * as well as vulkan_10_physical_device_features, are always processed.
+ *
+ * \since This struct is available since SDL 3.4.0.
+ */
+typedef struct SDL_GPUVulkanOptions
+{
+ Uint32 vulkan_api_version; /**< The Vulkan API version to request for the instance. Use Vulkan's VK_MAKE_VERSION or VK_MAKE_API_VERSION. */
+ void *feature_list; /**< Pointer to the first element of a chain of Vulkan feature structs. (Requires API version 1.1 or higher.)*/
+ void *vulkan_10_physical_device_features; /**< Pointer to a VkPhysicalDeviceFeatures struct to enable additional Vulkan 1.0 features. */
+ Uint32 device_extension_count; /**< Number of additional device extensions to require. */
+ const char **device_extension_names; /**< Pointer to a list of additional device extensions to require. */
+ Uint32 instance_extension_count; /**< Number of additional instance extensions to require. */
+ const char **instance_extension_names; /**< Pointer to a list of additional instance extensions to require. */
+} SDL_GPUVulkanOptions;
+
+/**
+ * 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);
+
+/**
+ * Get the properties associated with a GPU device.
+ *
+ * All properties are optional and may differ between GPU backends and SDL
+ * versions.
+ *
+ * The following properties are provided by SDL:
+ *
+ * `SDL_PROP_GPU_DEVICE_NAME_STRING`: Contains the name of the underlying
+ * device as reported by the system driver. This string has no standardized
+ * format, is highly inconsistent between hardware devices and drivers, and is
+ * able to change at any time. Do not attempt to parse this string as it is
+ * bound to fail at some point in the future when system drivers are updated,
+ * new hardware devices are introduced, or when SDL adds new GPU backends or
+ * modifies existing ones.
+ *
+ * Strings that have been found in the wild include:
+ *
+ * - GTX 970
+ * - GeForce GTX 970
+ * - NVIDIA GeForce GTX 970
+ * - Microsoft Direct3D12 (NVIDIA GeForce GTX 970)
+ * - NVIDIA Graphics Device
+ * - GeForce GPU
+ * - P106-100
+ * - AMD 15D8:C9
+ * - AMD Custom GPU 0405
+ * - AMD Radeon (TM) Graphics
+ * - ASUS Radeon RX 470 Series
+ * - Intel(R) Arc(tm) A380 Graphics (DG2)
+ * - Virtio-GPU Venus (NVIDIA TITAN V)
+ * - SwiftShader Device (LLVM 16.0.0)
+ * - llvmpipe (LLVM 15.0.4, 256 bits)
+ * - Microsoft Basic Render Driver
+ * - unknown device
+ *
+ * The above list shows that the same device can have different formats, the
+ * vendor name may or may not appear in the string, the included vendor name
+ * may not be the vendor of the chipset on the device, some manufacturers
+ * include pseudo-legal marks while others don't, some devices may not use a
+ * marketing name in the string, the device string may be wrapped by the name
+ * of a translation interface, the device may be emulated in software, or the
+ * string may contain generic text that does not identify the device at all.
+ *
+ * `SDL_PROP_GPU_DEVICE_DRIVER_NAME_STRING`: Contains the self-reported name
+ * of the underlying system driver.
+ *
+ * Strings that have been found in the wild include:
+ *
+ * - Intel Corporation
+ * - Intel open-source Mesa driver
+ * - Qualcomm Technologies Inc. Adreno Vulkan Driver
+ * - MoltenVK
+ * - Mali-G715
+ * - venus
+ *
+ * `SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING`: Contains the self-reported
+ * version of the underlying system driver. This is a relatively short version
+ * string in an unspecified format. If SDL_PROP_GPU_DEVICE_DRIVER_INFO_STRING
+ * is available then that property should be preferred over this one as it may
+ * contain additional information that is useful for identifying the exact
+ * driver version used.
+ *
+ * Strings that have been found in the wild include:
+ *
+ * - 53.0.0
+ * - 0.405.2463
+ * - 32.0.15.6614
+ *
+ * `SDL_PROP_GPU_DEVICE_DRIVER_INFO_STRING`: Contains the detailed version
+ * information of the underlying system driver as reported by the driver. This
+ * is an arbitrary string with no standardized format and it may contain
+ * newlines. This property should be preferred over
+ * SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING if it is available as it usually
+ * contains the same information but in a format that is easier to read.
+ *
+ * Strings that have been found in the wild include:
+ *
+ * - 101.6559
+ * - 1.2.11
+ * - Mesa 21.2.2 (LLVM 12.0.1)
+ * - Mesa 22.2.0-devel (git-f226222 2022-04-14 impish-oibaf-ppa)
+ * - v1.r53p0-00eac0.824c4f31403fb1fbf8ee1042422c2129
+ *
+ * This string has also been observed to be a multiline string (which has a
+ * trailing newline):
+ *
+ * ```
+ * Driver Build: 85da404, I46ff5fc46f, 1606794520
+ * Date: 11/30/20
+ * Compiler Version: EV031.31.04.01
+ * Driver Branch: promo490_3_Google
+ * ```
+ *
+ * \param device a GPU context 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.4.0.
+ */
+extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGPUDeviceProperties(SDL_GPUDevice *device);
+
+#define SDL_PROP_GPU_DEVICE_NAME_STRING "SDL.gpu.device.name"
+#define SDL_PROP_GPU_DEVICE_DRIVER_NAME_STRING "SDL.gpu.device.driver_name"
+#define SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING "SDL.gpu.device.driver_version"
+#define SDL_PROP_GPU_DEVICE_DRIVER_INFO_STRING "SDL.gpu.device.driver_info"
+
+
+/* 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, either via SDL_UploadToGPUTexture or by performing a render or
+ * compute pass with this texture as a target.
+ *
+ * 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_BeginGPURenderPass
+ * \sa SDL_BeginGPUComputePass
+ * \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.
+ *
+ * On Direct3D 12, using SDL_InsertGPUDebugLabel requires
+ * WinPixEventRuntime.dll to be in your PATH or in the same directory as your
+ * executable. See
+ * [here](https://devblogs.microsoft.com/pix/winpixeventruntime/)
+ * for instructions on how to obtain it.
+ *
+ * \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 arbitrary 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 Direct3D 12, using SDL_PushGPUDebugGroup requires WinPixEventRuntime.dll
+ * to be in your PATH or in the same directory as your executable. See
+ * [here](https://devblogs.microsoft.com/pix/winpixeventruntime/)
+ * for instructions on how to obtain it.
+ *
+ * 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.
+ *
+ * On Direct3D 12, using SDL_PopGPUDebugGroup requires WinPixEventRuntime.dll
+ * to be in your PATH or in the same directory as your executable. See
+ * [here](https://devblogs.microsoft.com/pix/winpixeventruntime/)
+ * for instructions on how to obtain it.
+ *
+ * \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 in this command buffer 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.
+ *
+ * For detailed information about accessing uniform data from a shader, please
+ * refer to SDL_CreateGPUShader.
+ *
+ * \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 in this command buffer 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 in this command buffer 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.
+ *
+ * Using SDL_GPU_LOADOP_LOAD before any contents have been written to the
+ * texture subresource will result in undefined behavior. SDL_GPU_LOADOP_CLEAR
+ * will set the contents of the texture subresource to a single value before
+ * any rendering is performed. It's fine to do an empty render pass using
+ * SDL_GPU_STOREOP_STORE to clear a texture, but in general it's better to
+ * think of clearing not as an independent operation but as something that's
+ * done as the beginning of a 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_CreateGPUComputePipeline().
+ *
+ * \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_CreateGPUComputePipeline
+ */
+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_CreateGPUComputePipeline().
+ *
+ * \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_CreateGPUComputePipeline
+ */
+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_CreateGPUComputePipeline().
+ *
+ * \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_CreateGPUComputePipeline
+ */
+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.
+ *
+ * \sa SDL_EndGPUCopyPass
+ */
+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.
+ *
+ * This function does not support copying between depth and color textures.
+ * For those, copy the texture to a buffer and then to the destination
+ * texture.
+ *
+ * \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 is 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. This NULL pointer should not be
+ * passed back into SDL. Instead, it should be considered as an indication to
+ * wait until the swapchain is available.
+ *
+ * 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);
+
+/**
+ * Get the SDL pixel format corresponding to a GPU texture format.
+ *
+ * \param format a texture format.
+ * \returns the corresponding pixel format, or SDL_PIXELFORMAT_UNKNOWN if
+ * there is no corresponding pixel format.
+ *
+ * \since This function is available since SDL 3.4.0.
+ */
+extern SDL_DECLSPEC SDL_PixelFormat SDLCALL SDL_GetPixelFormatFromGPUTextureFormat(SDL_GPUTextureFormat format);
+
+/**
+ * Get the GPU texture format corresponding to an SDL pixel format.
+ *
+ * \param format a pixel format.
+ * \returns the corresponding GPU texture format, or
+ * SDL_GPU_TEXTUREFORMAT_INVALID if there is no corresponding GPU
+ * texture format.
+ *
+ * \since This function is available since SDL 3.4.0.
+ */
+extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUTextureFormatFromPixelFormat(SDL_PixelFormat format);
+
+#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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_guid.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_guid.h
new file mode 100644
index 00000000..cf9df31c
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_guid.h
@@ -0,0 +1,106 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_haptic.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_haptic.h
new file mode 100644
index 00000000..ef91904a
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_haptic.h
@@ -0,0 +1,1461 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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;
+ * SDL_HapticEffectID 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;
+
+/*
+ * 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
+
+
+/**
+ * \name Haptic features
+ *
+ * Different haptic features a device can have.
+ */
+/* @{ */
+
+/**
+ * \name Haptic effects
+ */
+/* @{ */
+
+/**
+ * Type of haptic effect.
+ */
+typedef Uint16 SDL_HapticEffectType;
+
+/**
+ * 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
+ */
+/* @{ */
+
+/**
+ * Type of coordinates used for haptic direction.
+ */
+typedef Uint8 SDL_HapticDirectionType;
+
+/**
+ * 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 */
+
+
+/**
+ * ID for haptic effects.
+ *
+ * This is -1 if the ID is invalid.
+ *
+ * \sa SDL_CreateHapticEffect
+ */
+typedef int SDL_HapticEffectID;
+
+
+/**
+ * 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
+{
+ SDL_HapticDirectionType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 */
+ SDL_HapticEffectType 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 SDL_HapticEffectID 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, SDL_HapticEffectID 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, SDL_HapticEffectID 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, SDL_HapticEffectID 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, SDL_HapticEffectID 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, SDL_HapticEffectID 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_StopHapticEffect
+ */
+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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hidapi.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hidapi.h
new file mode 100644
index 00000000..90e574c4
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hidapi.h
@@ -0,0 +1,571 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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
+
+#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);
+
+/**
+ * Get the properties associated with an SDL_hid_device.
+ *
+ * The following read-only properties are provided by SDL:
+ *
+ * - `SDL_PROP_HIDAPI_LIBUSB_DEVICE_HANDLE_POINTER`: the libusb_device_handle
+ * associated with the device, if it was opened using libusb.
+ *
+ * \param dev a device handle returned from SDL_hid_open().
+ * \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.4.0.
+ */
+extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_hid_get_properties(SDL_hid_device *dev);
+
+#define SDL_PROP_HIDAPI_LIBUSB_DEVICE_HANDLE_POINTER "SDL.hidapi.libusb.device.handle"
+
+/**
+ * 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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hints.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hints.h
new file mode 100644
index 00000000..7844f84c
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_hints.h
@@ -0,0 +1,5001 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.
+ *
+ * For Windows WASAPI audio, the following roles are supported, and map to
+ * `AUDIO_STREAM_CATEGORY`:
+ *
+ * - "Other" (default)
+ * - "Communications" - Real-time communications, such as VOIP or chat
+ * - "Game" - Game audio
+ * - "GameChat" - Game chat audio, similar to "Communications" except that
+ * this will not attenuate other audio streams
+ * - "Movie" - Music or sound with dialog
+ * - "Media" - Music or sound without dialog
+ *
+ * Android's AAudio target supports this hint as of SDL 3.4.4. Android does
+ * not support the exact same options as WASAPI, but for portability, will
+ * attempt to map these same strings to the `aaudio_usage_t` constants. For
+ * example, "Movie" and "Media" will both map to `AAUDIO_USAGE_MEDIA`, etc.
+ *
+ * If your application applies its own echo cancellation, gain control, and
+ * noise reduction it should also set SDL_HINT_AUDIO_DEVICE_RAW_STREAM.
+ *
+ * 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 whether this audio device should do audio processing.
+ *
+ * Some operating systems perform echo cancellation, gain control, and noise
+ * reduction as needed. If your application already handles these, you can set
+ * this hint to prevent the OS from doing additional audio processing.
+ *
+ * This corresponds to the WASAPI audio option `AUDCLNT_STREAMOPTIONS_RAW`.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": audio processing can be done by the OS. (default)
+ * - "1": audio processing is done by the application.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_AUDIO_DEVICE_RAW_STREAM "SDL_AUDIO_DEVICE_RAW_STREAM"
+
+/**
+ * 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 the enabled features to be limited 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"
+
+/**
+ * Set the level of checking for invalid parameters passed to SDL functions.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "1": Enable fast parameter error checking, e.g. quick NULL checks, etc.
+ * - "2": Enable full parameter error checking, e.g. validating objects are
+ * the correct type, etc. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_INVALID_PARAM_CHECKS "SDL_INVALID_PARAM_CHECKS"
+
+/**
+ * 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.
+ *
+ * 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
+ * - "#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 that controls whether the Steam on-screen keyboard should be
+ * shown when text input is active.
+ *
+ * Steam will set this hint via environment variable for games launched in Big
+ * Picture mode. To override this you should call SDL_SetHintWithPriority()
+ * with priority `SDL_HINT_OVERRIDE`.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Do not show the Steam on-screen keyboard.
+ * - "1": Show the Steam on-screen keyboard.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.4.12.
+ */
+#define SDL_HINT_ENABLE_STEAM_SCREEN_KEYBOARD "SDL_ENABLE_STEAM_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 for GameCube adapters.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": HIDAPI will not use libusb for GameCube adapters.
+ * - "1": HIDAPI will use libusb for GameCube adapters if available. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_HIDAPI_LIBUSB_GAMECUBE "SDL_HIDAPI_LIBUSB_GAMECUBE"
+
+/**
+ * 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 and later
+ * 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 controlling whether GameInput should be used for handling
+ * GIP devices that require raw report processing, but aren't supported
+ * by HIDRAW, such as Xbox One Guitars.
+ *
+ * Note that this is only supported with GameInput 3 or newer.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": GameInput is not used to handle raw GIP devices.
+ * - "1": GameInput is used.
+ *
+ * The default is "1" when using GameInput 3 or newer, and is "0" otherwise.
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.4.4.
+ */
+#define SDL_HINT_JOYSTICK_GAMEINPUT_RAW "SDL_JOYSTICK_GAMEINPUT_RAW"
+
+/**
+ * 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.
+ *
+ * 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_STEAM_HORI "SDL_JOYSTICK_HIDAPI_STEAM_HORI"
+
+/**
+ * A variable controlling whether the HIDAPI driver for some Logitech wheels
+ * 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_LG4FF "SDL_JOYSTICK_HIDAPI_LG4FF"
+
+/**
+ * A variable controlling whether the HIDAPI driver for 8BitDo 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_8BITDO "SDL_JOYSTICK_HIDAPI_8BITDO"
+
+/**
+ * A variable controlling whether the HIDAPI driver for SInput controllers
+ * should be used.
+ *
+ * More info - https://github.com/HandHeldLegend/SInput-HID
+ *
+ * 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SINPUT "SDL_JOYSTICK_HIDAPI_SINPUT"
+
+/**
+ * A variable controlling whether the HIDAPI driver for ZUIKI 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_ZUIKI "SDL_JOYSTICK_HIDAPI_ZUIKI"
+
+/**
+ * A variable controlling whether the HIDAPI driver for Flydigi 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_FLYDIGI "SDL_JOYSTICK_HIDAPI_FLYDIGI"
+
+/**
+ * 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 the HIDAPI driver for Nintendo Switch 2
+ * 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.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH2 "SDL_JOYSTICK_HIDAPI_SWITCH2"
+
+/**
+ * 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 the new HIDAPI driver for wired Xbox One
+ * (GIP) 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_ONE.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_GIP "SDL_JOYSTICK_HIDAPI_GIP"
+
+/**
+ * A variable controlling whether the new HIDAPI driver for wired Xbox One
+ * (GIP) controllers should reset the controller if it can't get the metadata
+ * from the controller.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Assume this is a generic controller.
+ * - "1": Reset the controller to get metadata.
+ *
+ * By default the controller is reset. This is so we can properly detect
+ * the controller type.
+ *
+ * This hint should be set before initializing joysticks and gamepads.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_GIP_RESET_FOR_METADATA "SDL_JOYSTICK_HIDAPI_GIP_RESET_FOR_METADATA"
+
+/**
+ * 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. (default)
+ * - "1": WGI is used.
+ *
+ * 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 English
+ * QWERTY 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 that controls whether KMSDRM will use "atomic" functionality.
+ *
+ * The KMSDRM backend can use atomic commits, if both DRM_CLIENT_CAP_ATOMIC
+ * and DRM_CLIENT_CAP_UNIVERSAL_PLANES is supported by the system. As of SDL
+ * 3.4.0, it will favor this functionality, but in case this doesn't work well
+ * on a given system or other surprises, this hint can be used to disable it.
+ *
+ * This hint can not enable the functionality if it isn't available.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will not use the KMSDRM "atomic" functionality.
+ * - "1": SDL will allow usage of the KMSDRM "atomic" functionality. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_KMSDRM_ATOMIC "SDL_KMSDRM_ATOMIC"
+
+/**
+ * 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`
+ *
+ * If the `DEBUG_INVOCATION` environment variable is set to "1", the default
+ * log levels are equivalent to:
+ *
+ * `assert=warn,test=verbose,*=debug`
+ *
+ * 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"
+
+/**
+ * A variable controlling whether holding down a key will repeat the pressed
+ * key or open the accents menu on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Holding a key will repeat the pressed key.
+ * - "1": Holding a key will open the accents menu for that key. (default)
+ *
+ * This hint needs to be set before SDL_Init().
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_MAC_PRESS_AND_HOLD "SDL_MAC_PRESS_AND_HOLD"
+
+/**
+ * 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 doesn't have to be an integer value. For example, "59.94" won't be
+ * rounded to an integer rate; the digits after the decimal are actually
+ * respected.
+ *
+ * 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 setting whether we should scale cursors by the current display
+ * scale.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Cursors will not change size based on the display content scale.
+ * (default)
+ * - "1": Cursors will automatically match the display content scale (e.g. a
+ * 2x sized cursor will be used when the window is on a monitor with 200%
+ * scale). This is currently implemented on Windows.
+ *
+ * This hint needs to be set before creating cursors.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_MOUSE_DPI_SCALE_CURSORS "SDL_MOUSE_DPI_SCALE_CURSORS"
+
+/**
+ * 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 traveled 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"
+
+/**
+ * A variable controlling whether to force an sRGB-capable OpenGL context.
+ *
+ * At OpenGL context creation time, some platforms can request an sRGB-capable
+ * context. However, sometimes any form of the request can cause surprising
+ * results on some drivers, platforms, and hardware. Usually the surprise is
+ * in the form of rendering that is either a little darker or a little
+ * brighter than intended.
+ *
+ * This hint allows the user to override the app's sRGB requests and either
+ * force a specific value, or avoid requesting anything at all, depending on
+ * what makes things work correctly for their system.
+ *
+ * This is meant as a fail-safe; apps should probably not explicitly set this,
+ * and most users should not, either.
+ *
+ * Note that some platforms cannot make this request at all, and on all
+ * platforms this request can be denied by the operating system.
+ *
+ * In addition to attempting to obtain the type of sRGB-capable OpenGL context
+ * requested by this hint, SDL will try to force the state of
+ * GL_FRAMEBUFFER_SRGB on the new context, if appropriate.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Force a request for an OpenGL context that is _not_ sRGB-capable.
+ * - "1": Force a request for an OpenGL context that _is_ sRGB-capable.
+ * - "skip": Don't make any request for an sRGB-capable context (don't specify
+ * the attribute at all during context creation time).
+ * - any other string is undefined behavior.
+ *
+ * If unset, or set to an empty string, SDL will make a request using the
+ * value the app specified with the SDL_GL_FRAMEBUFFER_SRGB_CAPABLE attribute.
+ *
+ * This hint should be set before an OpenGL context is created.
+ *
+ * \since This hint is available since SDL 3.4.2.
+ */
+#define SDL_HINT_OPENGL_FORCE_SRGB_FRAMEBUFFER "SDL_OPENGL_FORCE_SRGB_FRAMEBUFFER"
+
+/**
+ * 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 use the Direct3D 11 WARP software
+ * rasterizer.
+ *
+ * For more information, see:
+ * https://learn.microsoft.com/en-us/windows/win32/direct3darticles/directx-warp
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Disable WARP rasterizer. (default)
+ * - "1": Enable WARP rasterizer.
+ *
+ * This hint should be set before creating a renderer.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_RENDER_DIRECT3D11_WARP "SDL_RENDER_DIRECT3D11_WARP"
+
+/**
+ * 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 the width of the PS2's framebuffer in pixels.
+ *
+ * By default, the variable is "640".
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_PS2_GS_WIDTH "SDL_PS2_GS_WIDTH"
+
+/**
+ * A variable controlling the height of the PS2's framebuffer in pixels.
+ *
+ * By default, the variable is "448".
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_PS2_GS_HEIGHT "SDL_PS2_GS_HEIGHT"
+
+/**
+ * A variable controlling whether the signal is interlaced or progressive.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Image is interlaced. (default)
+ * - "1": Image is progressive.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_PS2_GS_PROGRESSIVE "SDL_PS2_GS_PROGRESSIVE"
+
+/**
+ * A variable controlling the video mode of the console.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "": Console-native. (default)
+ * - "NTSC": 60hz region.
+ * - "PAL": 50hz region.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_PS2_GS_MODE "SDL_PS2_GS_MODE"
+
+/**
+ * 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 desktops, the connector names associated with displays can be
+ * found in the `name` property of the info output from `wayland-info -i
+ * wl_output`. On X11 desktops, the `xrandr` utility can be used to retrieve
+ * the connector names associated with displays.
+ *
+ * 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 indicating whether the metal layer drawable size should be
+ * updated for the SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED event on macOS.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": the metal layer drawable size will not be updated on the
+ * SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED event.
+ * - "1": the metal layer drawable size will be updated on the
+ * SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED event. (default)
+ *
+ * This hint should be set before SDL_Metal_CreateView called.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_VIDEO_METAL_AUTO_RESIZE_DRAWABLE "SDL_VIDEO_METAL_AUTO_RESIZE_DRAWABLE"
+
+/**
+ * A variable controlling whether SDL will attempt to automatically set the
+ * destination display to a mode most closely matching that of the previous
+ * display if an exclusive fullscreen window is moved onto it.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": SDL will not attempt to automatically set a matching mode on the
+ * destination display. If an exclusive fullscreen window is moved to a new
+ * display, the window will become fullscreen desktop.
+ * - "1": SDL will attempt to automatically set a mode on the destination
+ * display that most closely matches the mode of the display that the
+ * exclusive fullscreen window was previously on. (default)
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_VIDEO_MATCH_EXCLUSIVE_MODE_ON_MOVE "SDL_VIDEO_MATCH_EXCLUSIVE_MODE_ON_MOVE"
+
+/**
+ * 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.
+ * - "1": Fullscreen windows are minimized when they lose focus.
+ * - "auto": Fullscreen windows are minimized when they lose focus if they use
+ * exclusive fullscreen modes, so the desktop video mode is restored.
+ * (default)
+ *
+ * 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 the X Synchronization Extension is enabled.
+ *
+ * If set, this can result in smoother window resizing when rendering using
+ * OpenGL, however, there are some conditions:
+ *
+ * - It is only activated on windows created with the `SDL_WINDOW_OPENGL` flag
+ * (windows using an SDL OpenGL renderer have this automatically set).
+ * - When activated, presentation must be done with `SDL_GL_SwapWindow()`
+ * (`SDL_RenderPresent()` calls this internally for OpenGL renderers as well).
+ *
+ * Enabling this and presenting via an external mechanism will result in sync
+ * requests not being acked, and hangs and other odd window behavior may result.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": The X Synchronization Extension is disabled. (default)
+ * - "1": The X Synchronization Extension is enabled.
+ *
+ * This hint should be set before creating a window.
+ *
+ * \since This hint is available since SDL 3.4.10.
+ */
+#define SDL_HINT_VIDEO_X11_ENABLE_XSYNC_EXT "SDL_VIDEO_X11_ENABLE_XSYNC_EXT"
+
+/**
+ * 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. (default)
+ * - "1": GameInput is used for raw keyboard and mouse events, if available.
+ *
+ * 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 or not the RIDEV_NOHOTKEYS flag is set when
+ * enabling Windows raw keyboard events.
+ *
+ * This blocks any hotkeys that have been registered by applications from
+ * having any effect beyond generating raw WM_INPUT events.
+ *
+ * This flag does not affect system-hotkeys like ALT-TAB or CTRL-ALT-DEL, but
+ * does affect the Windows Logo key since it is a userland hotkey registered
+ * by explorer.exe.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": Hotkeys are not excluded. (default)
+ * - "1": Hotkeys are excluded.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.4.0.
+ */
+#define SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS "SDL_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS"
+
+/**
+ * A variable controlling whether the RIDEV_INPUTSINK flag is set when
+ * enabling Windows raw keyboard events.
+ *
+ * This enables the window to still receive input even if not in foreground.
+ *
+ * Focused windows that receive text input will still prevent input events from triggering.
+ *
+ * - "0": Input is not received when not in focus or foreground. (default)
+ * - "1": Input will be received even when not in focus or foreground.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.4.4.
+ */
+#define SDL_HINT_WINDOWS_RAW_KEYBOARD_INPUTSINK "SDL_WINDOWS_RAW_KEYBOARD_INPUTSINK"
+
+/**
+ * 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.
+ *
+ * \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. In the
+ * initial call, the current value is in both `oldValue` and `newValue`.
+ *
+ * \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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_init.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_init.h
new file mode 100644
index 00000000..d75ccc31
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_init.h
@@ -0,0 +1,507 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \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.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \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.
+ *
+ * \threadsafety This function is not thread safe.
+ *
+ * \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.
+ *
+ * \threadsafety This function is not thread safe.
+ *
+ * \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.
+ *
+ * \threadsafety This function should only be called on the main thread.
+ *
+ * \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/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_intrin.h b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_intrin.h
new file mode 100644
index 00000000..a2e96808
--- /dev/null
+++ b/Minecraft.Client/Windows64/4JLibs/4J_Input/Windows64/vendor/SDL/include/SDL3/SDL_intrin.h
@@ -0,0 +1,410 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 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 `